✨feature: Add projects homepage and support for adding new projects
This commit is contained in:
@@ -25,7 +25,6 @@ final class BoardApiTest extends IntegrationTestCase
|
||||
public function testBoardStateEndpointReturnsProjectState(): void
|
||||
{
|
||||
$projectId = $this->createProject();
|
||||
|
||||
$response = $this->callApi(
|
||||
'public/api/board-state.php',
|
||||
'GET',
|
||||
@@ -37,6 +36,36 @@ final class BoardApiTest extends IntegrationTestCase
|
||||
self::assertContains('trash', array_column($response['payload']['columns'], 'id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure create-project creates markdown storage and returns the new project state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateProjectEndpointCreatesProject(): void
|
||||
{
|
||||
$token = csrf_token();
|
||||
|
||||
$response = $this->callApi(
|
||||
'public/api/create-project.php',
|
||||
'POST',
|
||||
[],
|
||||
[
|
||||
'title' => 'Release Planning',
|
||||
'slug' => 'release-planning',
|
||||
'body' => 'Track launch work.',
|
||||
'_token' => $token,
|
||||
],
|
||||
['HTTP_X_CSRF_TOKEN' => $token]
|
||||
);
|
||||
|
||||
self::assertSame(200, $response['status']);
|
||||
self::assertTrue($response['payload']['success']);
|
||||
self::assertSame('release-planning', $response['payload']['state']['project']['id']);
|
||||
self::assertSame('/?project=release-planning', $response['payload']['state']['projectUrl']);
|
||||
self::assertContains('trash', array_column($response['payload']['state']['columns'], 'id'));
|
||||
self::assertFileExists($this->projectRoot . DIRECTORY_SEPARATOR . 'release-planning' . DIRECTORY_SEPARATOR . 'index.md');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure state-changing endpoints reject missing CSRF tokens.
|
||||
*
|
||||
|
||||
@@ -26,7 +26,6 @@ final class BoardServiceTest extends IntegrationTestCase
|
||||
{
|
||||
$projectId = $this->createProject();
|
||||
$service = new BoardService();
|
||||
|
||||
$state = $service->getBoardState($projectId);
|
||||
|
||||
self::assertSame(
|
||||
@@ -38,6 +37,27 @@ final class BoardServiceTest extends IntegrationTestCase
|
||||
self::assertSame('Demo Project', $state['project']['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure creating a project initializes markdown storage and default board state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateProjectBuildsInitialBoardState(): void
|
||||
{
|
||||
$service = new BoardService();
|
||||
|
||||
$state = $service->createProject('Release Planning', 'Track launch work.', 'release-planning');
|
||||
|
||||
self::assertSame('release-planning', $state['project']['id']);
|
||||
self::assertSame('Release Planning', $state['project']['title']);
|
||||
self::assertSame('Track launch work.', trim((string) $state['project']['body']));
|
||||
self::assertSame(
|
||||
['backlog', 'ready', 'in-progress', 'review', 'done', 'trash'],
|
||||
array_column($state['columns'], 'id')
|
||||
);
|
||||
self::assertFileExists($this->projectRoot . DIRECTORY_SEPARATOR . 'release-planning' . DIRECTORY_SEPARATOR . 'index.md');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a created task is persisted and returned in board state.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.describe('IronKanban smoke', () => {
|
||||
test('loads the project dashboard with cards and create form', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Choose a project or start a fresh one' })).toBeVisible();
|
||||
await expect(page.locator('#project-create-form')).toBeVisible();
|
||||
await expect(page.locator('.project-card')).toHaveCount(1);
|
||||
await expect(page.locator('.project-card h3')).toHaveText(['Demo Project']);
|
||||
});
|
||||
|
||||
test('loads the demo board and core UI sections', async ({ page }) => {
|
||||
await page.goto('/?project=demo-project');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user