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]); });