Added import system

This commit is contained in:
Constantin Graf
2024-03-05 19:19:07 +01:00
parent e8912650c0
commit 0ed5d14817
29 changed files with 946 additions and 4 deletions

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Endpoint\Api\V1;
use App\Models\Organization;
use App\Service\Import\ImportService;
use Laravel\Passport\Passport;
use Mockery\MockInterface;
class ImportEndpointTest extends ApiEndpointTestAbstract
{
public function test_import_fails_if_user_does_not_have_permission()
{
// Arrange
$data = $this->createUserWithPermission([
]);
Passport::actingAs($data->user);
// Act
$response = $this->postJson(route('api.v1.import', ['organization' => $data->organization->id]), [
'type' => 'toggl_time_entries',
'data' => 'some data',
'options' => [],
]);
// Assert
$response->assertStatus(403);
}
public function test_import_calls_import_service_if_user_has_permission(): void
{
// Arrange
$user = $this->createUserWithPermission([
'import',
]);
$this->mock(ImportService::class, function (MockInterface $mock) use (&$user): void {
$mock->shouldReceive('import')
->withArgs(function (Organization $organization, string $importerType, string $data, array $options) use (&$user): bool {
return $organization->is($user->organization) && $importerType === 'toggl_time_entries' && $data === 'some data' && $options === [];
})
->once();
});
Passport::actingAs($user->user);
// Act
$response = $this->postJson(route('api.v1.import.import', ['organization' => $user->organization->id]), [
'type' => 'toggl_time_entries',
'data' => 'some data',
'options' => [],
]);
// Assert
$response->assertStatus(200);
}
}

View File

@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service\Import;
use App\Models\Project;
use App\Models\User;
use App\Service\Import\ImportDatabaseHelper;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ImportDatabaseHelperTest extends TestCase
{
use RefreshDatabase;
public function test_get_key_attach_to_existing_returns_key_for_identifier_without_creating_model(): void
{
// Arrange
$user = User::factory()->create();
$helper = new ImportDatabaseHelper(User::class, ['email'], true);
// Act
$key = $helper->getKey([
'email' => $user->email,
], [
'name' => 'Test',
]);
// Assert
$this->assertSame($user->getKey(), $key);
}
public function test_get_key_attach_to_existing_creates_model_if_not_existing(): void
{
// Arrange
$helper = new ImportDatabaseHelper(User::class, ['email'], true);
// Act
$key = $helper->getKey([
'email' => 'test@mail.test',
], [
'name' => 'Test',
]);
// Assert
$this->assertNotNull($key);
$this->assertDatabaseHas(User::class, [
'email' => 'test@mail.test',
'name' => 'Test',
]);
}
public function test_get_key_not_attach_to_existing_returns_key_for_identifier_without_creating_model(): void
{
// Arrange
$project = Project::factory()->create();
$helper = new ImportDatabaseHelper(Project::class, ['name', 'organization_id'], false);
// Act
$key = $helper->getKey([
'name' => $project->name,
'organization_id' => $project->organization_id,
], [
'color' => '#000000',
]);
// Assert
$this->assertNotSame($project->getKey(), $key);
}
}

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service\Import\Importer;
use App\Models\Project;
use App\Models\Tag;
use App\Models\Task;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ImporterTestAbstract extends TestCase
{
use RefreshDatabase;
/**
* @return object{user1: User, project1: Project, project2: Project, tag1: Tag}
*/
protected function checkTestScenarioAfterImportExcludingTimeEntries(): object
{
$users = User::all();
$this->assertCount(2, $users);
$user1 = $users->firstWhere('name', 'Peter Tester');
$this->assertNotNull($user1);
$this->assertSame(null, $user1->password);
$this->assertSame('Peter Tester', $user1->name);
$this->assertSame('peter.test@email.test', $user1->email);
$projects = Project::all();
$this->assertCount(2, $projects);
$project1 = $projects->firstWhere('name', 'Project without Client');
$this->assertNotNull($project1);
$project2 = $projects->firstWhere('name', 'Project for Big Company');
$this->assertNotNull($project2);
$tasks = Task::all();
$this->assertCount(1, $tasks);
$task1 = $tasks->firstWhere('name', 'Task 1');
$this->assertNotNull($task1);
$this->assertSame($project2->getKey(), $task1->project_id);
$tags = Tag::all();
$this->assertCount(1, $tags);
$tag1 = $tags->firstWhere('name', 'Development');
$this->assertNotNull($tag1);
return (object) [
'user1' => $user1,
'project1' => $project1,
'project2' => $project2,
'tag1' => $tag1,
];
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service\Import\Importer;
use App\Models\Organization;
use App\Models\TimeEntry;
use App\Service\Import\Importers\TogglTimeEntriesImporter;
class TogglTimeEntriesImporterTest extends ImporterTestAbstract
{
public function test_import_of_test_file_succeeds(): void
{
// Arrange
$organization = Organization::factory()->create();
$importer = new TogglTimeEntriesImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/toggl_import_test_1.csv'));
// Act
$importer->importData($data, []);
// Assert
$this->checkTestScenarioAfterImportExcludingTimeEntries();
}
public function test_import_of_test_file_twice_succeeds(): void
{
// Arrange
$organization = Organization::factory()->create();
$importer = new TogglTimeEntriesImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/toggl_import_test_1.csv'));
$importer->importData($data, []);
$importer = new TogglTimeEntriesImporter();
$importer->init($organization);
// Act
$importer->importData($data, []);
// Assert
$testScenario = $this->checkTestScenarioAfterImportExcludingTimeEntries();
$timeEntries = TimeEntry::all();
$this->assertCount(4, $timeEntries);
$timeEntry1 = $timeEntries->firstWhere('description', '');
$this->assertNotNull($timeEntry1);
$this->assertSame('', $timeEntry1->description);
$this->assertSame('2024-03-04 10:23:52', $timeEntry1->start->toDateTimeString());
$this->assertSame('2024-03-04 10:23:52', $timeEntry1->end->toDateTimeString());
$this->assertFalse($timeEntry1->billable);
$this->assertSame([$testScenario->tag1->getKey()], $timeEntry1->tags);
$timeEntry2 = $timeEntries->firstWhere('description', 'Working hard');
$this->assertNotNull($timeEntry2);
$this->assertSame('Working hard', $timeEntry2->description);
$this->assertSame('2024-03-04 10:23:00', $timeEntry2->start->toDateTimeString());
$this->assertSame('2024-03-04 11:23:01', $timeEntry2->end->toDateTimeString());
$this->assertTrue($timeEntry2->billable);
$this->assertSame([], $timeEntry2->tags);
}
}