Added more imports

This commit is contained in:
Constantin Graf
2024-03-11 19:12:51 +01:00
parent 77e7a63b83
commit 66a1d8a38b
52 changed files with 1646 additions and 56 deletions

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Rules;
use App\Rules\ColorRule;
use Illuminate\Support\Facades\Validator;
use Tests\TestCase;
class ColorRuleTest extends TestCase
{
public function test_validation_passes_if_value_is_valid_color(): void
{
// Arrange
$validator = Validator::make([
'color' => '#ef5350',
], [
'color' => [new ColorRule()],
]);
// Act
$isValid = $validator->passes();
$messages = $validator->messages()->toArray();
// Assert
$this->assertTrue($isValid);
$this->assertArrayNotHasKey('color', $messages);
}
public function test_validation_fails_if_value_is_not_a_string(): void
{
// Arrange
$validator = Validator::make([
'color' => true,
], [
'color' => [new ColorRule()],
]);
// Act
$isValid = $validator->passes();
$messages = $validator->messages()->toArray();
// Assert
$this->assertFalse($isValid);
$this->assertEquals('The color field must be a string.', $messages['color'][0]);
}
public function test_validation_fails_if_value_is_not_a_valid_color(): void
{
// Arrange
$validator = Validator::make([
'color' => 'rgb(0,0,0)',
], [
'color' => [new ColorRule()],
]);
// Act
$isValid = $validator->passes();
$messages = $validator->messages()->toArray();
// Assert
$this->assertFalse($isValid);
$this->assertEquals('The color field must be a valid color.', $messages['color'][0]);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Tests\Unit\Service\Import;
use App\Models\Organization;
use App\Models\Project;
use App\Models\User;
use App\Service\Import\ImportDatabaseHelper;
@@ -74,4 +75,64 @@ class ImportDatabaseHelperTest extends TestCase
// Assert
$this->fail();
}
public function test_get_key_by_external_identifier_returns_key_for_external_identifier(): void
{
// Arrange
$organization = Organization::factory()->create();
$project = Project::factory()->forOrganization($organization)->create();
$externalIdentifier1 = '12345';
$externalIdentifier2 = '54321';
$helper = new ImportDatabaseHelper(Project::class, ['name', 'organization_id'], true);
$helper->getKey([
'name' => $project->name,
'organization_id' => $organization->getKey(),
], [
'color' => '#000000',
], $externalIdentifier1);
$helper->getKey([
'name' => 'Not existing project',
'organization_id' => $organization->getKey(),
], [
'color' => '#000000',
], $externalIdentifier2);
// Act
$key1 = $helper->getKeyByExternalIdentifier($externalIdentifier1);
$key2 = $helper->getKeyByExternalIdentifier($externalIdentifier2);
// Assert
$this->assertSame($project->getKey(), $key1);
$this->assertSame(Project::where('name', '=', 'Not existing project')->first()->getKey(), $key2);
}
public function test_get_external_ids_returns_all_external_ids_that_were_temporary_stored_via_get_key(): void
{
// Arrange
$organization = Organization::factory()->create();
$project = Project::factory()->forOrganization($organization)->create();
$externalIdentifier1 = '12345';
$externalIdentifier2 = '54321';
$helper = new ImportDatabaseHelper(Project::class, ['name', 'organization_id'], true);
$helper->getKey([
'name' => $project->name,
'organization_id' => $organization->getKey(),
], [
'color' => '#000000',
], $externalIdentifier1);
$helper->getKey([
'name' => 'Not existing project',
'organization_id' => $organization->getKey(),
], [
'color' => '#000000',
], $externalIdentifier2);
// Act
$externalKeys = $helper->getExternalIds();
// Assert
$this->assertCount(2, $externalKeys);
$this->assertContains($externalIdentifier1, $externalKeys);
$this->assertContains($externalIdentifier2, $externalKeys);
}
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service\Import\Importer;
use App\Models\Organization;
use App\Service\Import\Importers\ClockifyProjectsImporter;
class ClockifyProjectsImporterTest extends ImporterTestAbstract
{
public function test_import_of_test_file_succeeds(): void
{
// Arrange
$organization = Organization::factory()->create();
$importer = new ClockifyProjectsImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/clockify_projects_import_test_1.csv'));
// Act
$importer->importData($data, []);
// Assert
$this->checkTestScenarioProjectsOnlyAfterImport();
}
public function test_import_of_test_file_twice_succeeds(): void
{
// Arrange
$organization = Organization::factory()->create();
$importer = new ClockifyProjectsImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/clockify_projects_import_test_1.csv'));
$importer->importData($data, []);
$importer = new ClockifyProjectsImporter();
$importer->init($organization);
// Act
$importer->importData($data, []);
// Assert
$this->checkTestScenarioProjectsOnlyAfterImport();
}
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service\Import\Importer;
use App\Models\Organization;
use App\Models\TimeEntry;
use App\Service\Import\Importers\ClockifyTimeEntriesImporter;
class ClockifyTimeEntriesImporterTest extends ImporterTestAbstract
{
public function test_import_of_test_file_succeeds(): void
{
// Arrange
$organization = Organization::factory()->create();
$importer = new ClockifyTimeEntriesImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/clockify_time_entries_import_test_1.csv'));
// Act
$importer->importData($data, []);
// Assert
$testScenario = $this->checkTestScenarioAfterImportExcludingTimeEntries();
$timeEntries = TimeEntry::all();
$this->assertCount(2, $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(), $testScenario->tag2->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);
}
public function test_import_of_test_file_twice_succeeds(): void
{
// Arrange
$organization = Organization::factory()->create();
$importer = new ClockifyTimeEntriesImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/clockify_time_entries_import_test_1.csv'));
$importer->importData($data, []);
$importer = new ClockifyTimeEntriesImporter();
$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(), $testScenario->tag2->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);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Tests\Unit\Service\Import\Importer;
use App\Models\Client;
use App\Models\Project;
use App\Models\Tag;
use App\Models\Task;
@@ -16,7 +17,7 @@ class ImporterTestAbstract extends TestCase
use RefreshDatabase;
/**
* @return object{user1: User, project1: Project, project2: Project, tag1: Tag}
* @return object{user1: User, project1: Project, project2: Project, tag1: Tag, tag2: Tag}
*/
protected function checkTestScenarioAfterImportExcludingTimeEntries(): object
{
@@ -27,20 +28,27 @@ class ImporterTestAbstract extends TestCase
$this->assertSame(null, $user1->password);
$this->assertSame('Peter Tester', $user1->name);
$this->assertSame('peter.test@email.test', $user1->email);
$clients = Client::all();
$this->assertCount(1, $clients);
$client1 = $clients->firstWhere('name', 'Big Company');
$this->assertNotNull($client1);
$projects = Project::all();
$this->assertCount(2, $projects);
$project1 = $projects->firstWhere('name', 'Project without Client');
$this->assertNotNull($project1);
$this->assertNull($project1->client_id);
$project2 = $projects->firstWhere('name', 'Project for Big Company');
$this->assertNotNull($project2);
$this->assertSame($client1->getKey(), $project2->client_id);
$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);
$this->assertCount(2, $tags);
$tag1 = $tags->firstWhere('name', 'Development');
$tag2 = $tags->firstWhere('name', 'Backend');
$this->assertNotNull($tag1);
return (object) [
@@ -48,6 +56,44 @@ class ImporterTestAbstract extends TestCase
'project1' => $project1,
'project2' => $project2,
'tag1' => $tag1,
'tag2' => $tag2,
];
}
/**
* @return object{client1: Client, project1: Project, project2: Project, task1: Task}
*/
protected function checkTestScenarioProjectsOnlyAfterImport(): object
{
$clients = Client::all();
$this->assertCount(1, $clients);
$client1 = $clients->firstWhere('name', 'Big Company');
$this->assertNotNull($client1);
$projects = Project::all();
$this->assertCount(2, $projects);
$project1 = $projects->firstWhere('name', 'Project without Client');
$this->assertNotNull($project1);
$this->assertNull($project1->client_id);
$project2 = $projects->firstWhere('name', 'Project for Big Company');
$this->assertNotNull($project2);
$this->assertSame($client1->getKey(), $project2->client_id);
$tasks = Task::all();
$this->assertCount(3, $tasks);
$task1 = $tasks->firstWhere('name', 'Task 1');
$this->assertNotNull($task1);
$this->assertSame($project2->getKey(), $task1->project_id);
$task2 = $tasks->firstWhere('name', 'Task 2');
$this->assertNotNull($task2);
$this->assertSame($project2->getKey(), $task2->project_id);
$task3 = $tasks->firstWhere('name', 'Task 3');
$this->assertNotNull($task3);
$this->assertSame($project2->getKey(), $task3->project_id);
return (object) [
'client1' => $client1,
'project1' => $project1,
'project2' => $project2,
'task1' => $task1,
];
}
}

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Service\Import\Importer;
use App\Models\Organization;
use App\Service\Import\Importers\TogglDataImporter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Spatie\TemporaryDirectory\TemporaryDirectory;
use ZipArchive;
class TogglDataImporterTest extends ImporterTestAbstract
{
private function createTestZip(string $folder): string
{
$tempDir = TemporaryDirectory::make();
$zipPath = $tempDir->path('test.zip');
$zip = new ZipArchive();
$zip->open($zipPath, ZipArchive::CREATE);
foreach (Storage::disk('testfiles')->allFiles($folder) as $file) {
$zip->addFile(Storage::disk('testfiles')->path($file), Str::of($file)->after($folder.'/')->value());
}
$zip->close();
return $zipPath;
}
public function test_import_of_test_file_succeeds(): void
{
// Arrange
$zipPath = $this->createTestZip('toggl_data_import_test_1');
$organization = Organization::factory()->create();
$importer = new TogglDataImporter();
$importer->init($organization);
$data = file_get_contents($zipPath);
// Act
$importer->importData($data);
// Assert
$this->checkTestScenarioAfterImportExcludingTimeEntries();
}
public function test_import_of_test_file_twice_succeeds(): void
{
// Arrange
$zipPath = $this->createTestZip('toggl_data_import_test_1');
$organization = Organization::factory()->create();
$importer = new TogglDataImporter();
$importer->init($organization);
$data = file_get_contents($zipPath);
$importer->importData($data);
$importer = new TogglDataImporter();
$importer->init($organization);
// Act
$importer->importData($data);
// Assert
$this->checkTestScenarioAfterImportExcludingTimeEntries();
}
}

View File

@@ -16,13 +16,29 @@ class TogglTimeEntriesImporterTest extends ImporterTestAbstract
$organization = Organization::factory()->create();
$importer = new TogglTimeEntriesImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/toggl_import_test_1.csv'));
$data = file_get_contents(storage_path('tests/toggl_time_entries_import_test_1.csv'));
// Act
$importer->importData($data, []);
// Assert
$this->checkTestScenarioAfterImportExcludingTimeEntries();
$testScenario = $this->checkTestScenarioAfterImportExcludingTimeEntries();
$timeEntries = TimeEntry::all();
$this->assertCount(2, $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(), $testScenario->tag2->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);
}
public function test_import_of_test_file_twice_succeeds(): void
@@ -31,7 +47,7 @@ class TogglTimeEntriesImporterTest extends ImporterTestAbstract
$organization = Organization::factory()->create();
$importer = new TogglTimeEntriesImporter();
$importer->init($organization);
$data = file_get_contents(storage_path('tests/toggl_import_test_1.csv'));
$data = file_get_contents(storage_path('tests/toggl_time_entries_import_test_1.csv'));
$importer->importData($data, []);
$importer = new TogglTimeEntriesImporter();
$importer->init($organization);
@@ -49,7 +65,7 @@ class TogglTimeEntriesImporterTest extends ImporterTestAbstract
$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);
$this->assertSame([$testScenario->tag1->getKey(), $testScenario->tag2->getKey()], $timeEntry1->tags);
$timeEntry2 = $timeEntries->firstWhere('description', 'Working hard');
$this->assertNotNull($timeEntry2);
$this->assertSame('Working hard', $timeEntry2->description);