Add stage 4: frontend lists view + enforce 100-list cap
API: GET /api/lists is now ordered alphabetically (COLLATE NOCASE) by title with no other option, and TodoListController rejects a create past 100 lists per owner with 409. New TodoListRepository::countForOwner. Frontend: HomeView replaces the placeholder with the user's lists (rendered in API order) and a create form (title + optional description). New Pinia lists store fetches and creates, re-fetching after a create so the new list sorts into place; it is reset on logout. Form disables and explains at 100 lists; create errors surface inline. Neutral .badge with a .badge--warn variant; dropped the unused .facts styles. Tests: alphabetical ordering and the 100-list cap. Suite: 17 passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,36 @@ final class TodoTest extends ApiTestCase
|
||||
self::assertSame($list['id'], $index['lists'][0]['id']);
|
||||
}
|
||||
|
||||
public function test_lists_come_back_alphabetically(): void
|
||||
{
|
||||
$auth = $this->authHeader();
|
||||
|
||||
foreach (['Banana', 'apple', 'Cherry'] as $title) {
|
||||
$this->request('POST', '/api/lists', ['title' => $title], $auth);
|
||||
}
|
||||
|
||||
$titles = array_column($this->decode($this->request('GET', '/api/lists', null, $auth))['lists'], 'title');
|
||||
self::assertSame(['apple', 'Banana', 'Cherry'], $titles);
|
||||
}
|
||||
|
||||
public function test_an_owner_cannot_exceed_100_lists(): void
|
||||
{
|
||||
$auth = $this->authHeader();
|
||||
|
||||
for ($i = 1; $i <= 100; $i++) {
|
||||
$response = $this->request('POST', '/api/lists', ['title' => "List {$i}"], $auth);
|
||||
self::assertSame(201, $response->getStatusCode(), "list {$i} should be created");
|
||||
}
|
||||
|
||||
$overflow = $this->request('POST', '/api/lists', ['title' => 'One too many'], $auth);
|
||||
self::assertSame(409, $overflow->getStatusCode());
|
||||
self::assertStringContainsString('100', $this->decode($overflow)['error']['message']);
|
||||
|
||||
// The cap is per owner, so a different user is unaffected.
|
||||
$other = $this->authHeader('roomy@example.com');
|
||||
self::assertSame(201, $this->request('POST', '/api/lists', ['title' => 'Fine'], $other)->getStatusCode());
|
||||
}
|
||||
|
||||
public function test_list_creation_validates_title(): void
|
||||
{
|
||||
$response = $this->request('POST', '/api/lists', ['description' => 'no title'], $this->authHeader());
|
||||
|
||||
Reference in New Issue
Block a user