214 lines
5.8 KiB
PHP
214 lines
5.8 KiB
PHP
<?php
|
|
|
|
use App\Models\Label;
|
|
use App\Models\User;
|
|
|
|
test('authenticated users can create a label', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$labelData = [
|
|
'name' => 'Important',
|
|
'color' => 'blue',
|
|
];
|
|
|
|
$response = $this->actingAs($user)->post(route('labels.store'), $labelData);
|
|
|
|
$response->assertRedirect(route('labels.index'));
|
|
|
|
$this->assertDatabaseHas('labels', [
|
|
'user_id' => $user->id,
|
|
'name' => 'Important',
|
|
'color' => 'blue',
|
|
]);
|
|
});
|
|
|
|
test('label name is required', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$response = $this->actingAs($user)->postJson(route('labels.store'), [
|
|
'color' => 'blue',
|
|
]);
|
|
|
|
$response->assertUnprocessable();
|
|
$response->assertJsonValidationErrors(['name']);
|
|
});
|
|
|
|
test('label color is required', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$response = $this->actingAs($user)->postJson(route('labels.store'), [
|
|
'name' => 'Important',
|
|
]);
|
|
|
|
$response->assertUnprocessable();
|
|
$response->assertJsonValidationErrors(['color']);
|
|
});
|
|
|
|
test('label color must be valid', function () {
|
|
$user = User::factory()->create();
|
|
|
|
$response = $this->actingAs($user)->postJson(route('labels.store'), [
|
|
'name' => 'Important',
|
|
'color' => 'invalid-color',
|
|
]);
|
|
|
|
$response->assertUnprocessable();
|
|
$response->assertJsonValidationErrors(['color']);
|
|
});
|
|
|
|
test('label names are unique per user', function () {
|
|
$user = User::factory()->create();
|
|
|
|
Label::factory()->create([
|
|
'user_id' => $user->id,
|
|
'name' => 'Urgent',
|
|
]);
|
|
|
|
$response = $this->actingAs($user)->postJson(route('labels.store'), [
|
|
'name' => 'Urgent',
|
|
'color' => 'red',
|
|
]);
|
|
|
|
$response->assertUnprocessable();
|
|
$response->assertJsonValidationErrors(['name']);
|
|
});
|
|
|
|
test('different users can have labels with the same name', function () {
|
|
$user1 = User::factory()->create();
|
|
$user2 = User::factory()->create();
|
|
|
|
Label::factory()->create([
|
|
'user_id' => $user1->id,
|
|
'name' => 'Important',
|
|
]);
|
|
|
|
$response = $this->actingAs($user2)->post(route('labels.store'), [
|
|
'name' => 'Important',
|
|
'color' => 'blue',
|
|
]);
|
|
|
|
$response->assertRedirect(route('labels.index'));
|
|
|
|
$this->assertDatabaseHas('labels', [
|
|
'user_id' => $user2->id,
|
|
'name' => 'Important',
|
|
'color' => 'blue',
|
|
]);
|
|
});
|
|
|
|
test('authenticated users can update their own label', function () {
|
|
$user = User::factory()->create();
|
|
$label = Label::factory()->create(['user_id' => $user->id]);
|
|
|
|
$updateData = [
|
|
'name' => 'Updated Name',
|
|
'color' => 'green',
|
|
];
|
|
|
|
$response = $this->actingAs($user)->patch(
|
|
route('labels.update', $label),
|
|
$updateData
|
|
);
|
|
|
|
$response->assertRedirect(route('labels.index'));
|
|
|
|
$this->assertDatabaseHas('labels', [
|
|
'id' => $label->id,
|
|
'name' => 'Updated Name',
|
|
'color' => 'green',
|
|
]);
|
|
});
|
|
|
|
test('users cannot update labels they do not own', function () {
|
|
$user = User::factory()->create();
|
|
$otherUser = User::factory()->create();
|
|
$label = Label::factory()->create(['user_id' => $otherUser->id]);
|
|
|
|
$response = $this->actingAs($user)->patch(
|
|
route('labels.update', $label),
|
|
[
|
|
'name' => 'Updated Name',
|
|
'color' => 'green',
|
|
]
|
|
);
|
|
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('authenticated users can delete their own label', function () {
|
|
$user = User::factory()->create();
|
|
$label = Label::factory()->create(['user_id' => $user->id]);
|
|
|
|
$response = $this->actingAs($user)->delete(route('labels.destroy', $label));
|
|
|
|
$response->assertRedirect(route('labels.index'));
|
|
|
|
$this->assertSoftDeleted('labels', [
|
|
'id' => $label->id,
|
|
]);
|
|
});
|
|
|
|
test('users cannot delete labels they do not own', function () {
|
|
$user = User::factory()->create();
|
|
$otherUser = User::factory()->create();
|
|
$label = Label::factory()->create(['user_id' => $otherUser->id]);
|
|
|
|
$response = $this->actingAs($user)->delete(route('labels.destroy', $label));
|
|
|
|
$response->assertForbidden();
|
|
|
|
$this->assertDatabaseHas('labels', [
|
|
'id' => $label->id,
|
|
'deleted_at' => null,
|
|
]);
|
|
});
|
|
|
|
test('guests cannot access label management', function () {
|
|
$response = $this->postJson(route('labels.store'), []);
|
|
$response->assertUnauthorized();
|
|
});
|
|
|
|
test('creating a label with the same name as a deleted label creates a new one', function () {
|
|
$user = User::factory()->create();
|
|
$label = Label::factory()->create([
|
|
'user_id' => $user->id,
|
|
'name' => 'Wedding',
|
|
'color' => 'blue',
|
|
]);
|
|
$originalId = $label->id;
|
|
|
|
$this->actingAs($user)->delete(route('labels.destroy', $label));
|
|
|
|
$this->assertSoftDeleted('labels', ['id' => $originalId]);
|
|
|
|
$response = $this->actingAs($user)->postJson(route('labels.store'), [
|
|
'name' => 'Wedding',
|
|
'color' => 'teal',
|
|
]);
|
|
|
|
$response->assertCreated();
|
|
|
|
$newLabel = Label::where('user_id', $user->id)
|
|
->where('name', 'Wedding')
|
|
->whereNull('deleted_at')
|
|
->first();
|
|
|
|
expect($newLabel)->not->toBeNull();
|
|
expect($newLabel->id)->not->toBe($originalId);
|
|
expect($newLabel->color)->toBe('teal');
|
|
|
|
$this->assertSoftDeleted('labels', ['id' => $originalId]);
|
|
});
|
|
|
|
test('labels index returns the standard label field set', function () {
|
|
$user = User::factory()->create();
|
|
Label::factory()->create(['user_id' => $user->id]);
|
|
|
|
$response = $this->actingAs($user)->withoutVite()->get(route('labels.index'));
|
|
|
|
$props = $response->viewData('page')['props'];
|
|
|
|
expect(array_keys($props['labels'][0]))
|
|
->toEqualCanonicalizing(['id', 'user_id', 'name', 'color', 'created_at', 'updated_at', 'deleted_at']);
|
|
});
|