initial commit

This commit is contained in:
2026-02-11 23:37:50 +01:00
commit 908cf42ad9
128 changed files with 17831 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
<?php
declare(strict_types=1);
namespace Tests\Feature;
use App\Models\Contact;
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ContactControllerTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->withoutMiddleware([
VerifyCsrfToken::class,
ValidateCsrfToken::class,
]);
}
public function testIndexDisplaysContacts(): void
{
$contacts = Contact::factory()->count(2)->create();
$response = $this->get(route('contacts.index'));
$response->assertOk();
$response->assertSee($contacts[0]->email);
$response->assertSee($contacts[1]->email);
}
public function testCreateDisplaysForm(): void
{
$response = $this->get(route('contacts.create'));
$response->assertOk();
$response->assertSee('New Contact');
}
public function testStoreCreatesContact(): void
{
$payload = [
'first_name' => 'Jane',
'last_name' => 'Doe',
'email' => 'jane@example.com',
];
$response = $this->post(route('contacts.store'), $payload);
$contact = Contact::query()->first();
$this->assertNotNull($contact);
$this->assertSame('jane@example.com', $contact->email);
$response->assertRedirect(route('contacts.show', $contact));
$this->assertDatabaseHas('contacts', ['email' => 'jane@example.com']);
}
public function testStoreRequiresEmail(): void
{
$response = $this->post(route('contacts.store'), [
'first_name' => 'Jane',
'last_name' => 'Doe',
]);
$response->assertSessionHasErrors('email');
$this->assertDatabaseCount('contacts', 0);
}
public function testShowDisplaysContact(): void
{
$contact = Contact::factory()->create([
'first_name' => 'Alex',
'last_name' => 'Novak',
'email' => 'alex@example.com',
]);
$response = $this->get(route('contacts.show', $contact));
$response->assertOk();
$response->assertSee('Alex');
$response->assertSee('Novak');
$response->assertSee('alex@example.com');
}
public function testEditDisplaysContact(): void
{
$contact = Contact::factory()->create([
'email' => 'editme@example.com',
]);
$response = $this->get(route('contacts.edit', $contact));
$response->assertOk();
$response->assertSee('Edit Contact');
$response->assertSee('editme@example.com');
}
public function testUpdatePersistsChanges(): void
{
$contact = Contact::factory()->create([
'email' => 'old@example.com',
]);
$response = $this->put(route('contacts.update', $contact), [
'first_name' => 'Lukas',
'last_name' => 'Svoboda',
'email' => 'new@example.com',
]);
$response->assertRedirect(route('contacts.show', $contact));
$this->assertDatabaseHas('contacts', [
'id' => $contact->id,
'first_name' => 'Lukas',
'last_name' => 'Svoboda',
'email' => 'new@example.com',
]);
}
public function testUpdateRequiresUniqueEmail(): void
{
$first = Contact::factory()->create(['email' => 'first@example.com']);
$second = Contact::factory()->create(['email' => 'second@example.com']);
$response = $this->put(route('contacts.update', $first), [
'first_name' => $first->first_name,
'last_name' => $first->last_name,
'email' => $second->email,
]);
$response->assertSessionHasErrors('email');
$this->assertDatabaseHas('contacts', ['email' => 'first@example.com']);
}
public function testUpdateAllowsSameEmailForCurrentContact(): void
{
$contact = Contact::factory()->create([
'email' => 'same@example.com',
]);
$response = $this->put(route('contacts.update', $contact), [
'first_name' => $contact->first_name,
'last_name' => $contact->last_name,
'email' => 'same@example.com',
]);
$response->assertRedirect(route('contacts.show', $contact));
$this->assertDatabaseHas('contacts', ['email' => 'same@example.com']);
}
public function testDestroyDeletesContact(): void
{
$contact = Contact::factory()->create();
$response = $this->delete(route('contacts.destroy', $contact));
$response->assertRedirect(route('contacts.index'));
$this->assertDatabaseMissing('contacts', ['id' => $contact->id]);
}
}

View File

@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace Tests\Feature;
use App\Jobs\ProcessImport;
use App\Models\ContactImport;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Ramsey\Uuid\Uuid;
use Tests\TestCase;
class ImportControllerTest extends TestCase
{
use RefreshDatabase;
public function testStoreQueuesImportAndRedirects(): void
{
Storage::fake('local');
Queue::fake();
$this->withoutMiddleware();
$file = UploadedFile::fake()->create(
'contacts.xml',
10,
'text/xml',
);
$response = $this->post(route('import.store'), [
'file' => $file,
]);
$response
->assertRedirect(route('import.index'))
->assertSessionHas('importUuid')
->assertSessionHas('status', 'Import queued.');
Queue::assertPushed(ProcessImport::class);
$this->assertDatabaseCount('contact_imports', 1);
}
public function testShowReturnsImport(): void
{
$contactImport = ContactImport::factory()->create();
$response = $this->getJson(route('api.imports.show', $contactImport->id));
$response
->assertOk()
->assertJson([
'id' => $contactImport->id,
'state' => $contactImport->state->value,
])
->assertJsonStructure([
'id',
'queue_at',
'started_at',
'finished_at',
'total_processed',
'errors',
'duplicates',
'state',
]);
}
public function testShowReturns404ForInvalidUuid(): void
{
$this->getJson('/api/imports/not-a-uuid')
->assertNotFound();
}
public function testShowReturns404ForMissingImport(): void
{
$this->getJson(route('api.imports.show', Uuid::uuid7()->toString()))
->assertNotFound();
}
}