merge: combine all features from both codebases - mobile dashboard + layer panel + notifications + shares + all fixes
This commit is contained in:
@@ -11,6 +11,7 @@ describe('Blocks API', () => {
|
||||
let db: SqliteAdapter;
|
||||
let drawingId: string;
|
||||
let createdBlockId: string;
|
||||
let authToken: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
db = new SqliteAdapter(':memory:');
|
||||
@@ -18,10 +19,18 @@ describe('Blocks API', () => {
|
||||
app = await createServer({ db, port: 0 });
|
||||
await app.ready();
|
||||
|
||||
const regRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/api/auth/register',
|
||||
payload: { email: 'admin-test@example.com', password: 'Password123!', name: 'Admin Test', role: 'admin' },
|
||||
});
|
||||
authToken = JSON.parse(regRes.body).session.token;
|
||||
|
||||
// Create project → drawing hierarchy
|
||||
const projRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/api/projects',
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Blocks Test Project' },
|
||||
});
|
||||
const projectId = JSON.parse(projRes.body).id;
|
||||
@@ -29,6 +38,7 @@ describe('Blocks API', () => {
|
||||
const drawRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/projects/${projectId}/drawings`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Blocks Test Drawing' },
|
||||
});
|
||||
drawingId = JSON.parse(drawRes.body).id;
|
||||
@@ -39,6 +49,18 @@ describe('Blocks API', () => {
|
||||
db.close();
|
||||
});
|
||||
|
||||
// ─── Auth Check ──────────────────────────────────────
|
||||
|
||||
describe('Authentication', () => {
|
||||
it('should return 401 without authorization header', async () => {
|
||||
const response = await app.inject({
|
||||
method: 'GET',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
});
|
||||
expect(response.statusCode).toBe(401);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Create ─────────────────────────────────────────
|
||||
|
||||
describe('POST /api/drawings/:drawingId/blocks', () => {
|
||||
@@ -46,6 +68,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Standard Table', category: 'Mobiliar', description: 'A standard round table' },
|
||||
});
|
||||
expect(response.statusCode).toBe(201);
|
||||
@@ -62,6 +85,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Minimal Block' },
|
||||
});
|
||||
expect(response.statusCode).toBe(201);
|
||||
@@ -76,6 +100,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { category: 'Test' },
|
||||
});
|
||||
expect(response.statusCode).toBe(400);
|
||||
@@ -87,6 +112,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: '' },
|
||||
});
|
||||
expect(response.statusCode).toBe(400);
|
||||
@@ -100,6 +126,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'GET',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
const body = JSON.parse(response.body);
|
||||
@@ -111,12 +138,14 @@ describe('Blocks API', () => {
|
||||
const projRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/api/projects',
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Empty Blocks Project' },
|
||||
});
|
||||
const projId = JSON.parse(projRes.body).id;
|
||||
const drawRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/projects/${projId}/drawings`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Empty Drawing' },
|
||||
});
|
||||
const emptyDrawId = JSON.parse(drawRes.body).id;
|
||||
@@ -124,6 +153,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'GET',
|
||||
url: `/api/drawings/${emptyDrawId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
const body = JSON.parse(response.body);
|
||||
@@ -139,6 +169,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'PATCH',
|
||||
url: `/api/blocks/${createdBlockId}`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'Updated Block Name' },
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
@@ -150,6 +181,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'PATCH',
|
||||
url: `/api/blocks/${createdBlockId}`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { category: 'Bühne', description: 'Stage equipment' },
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
@@ -162,6 +194,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'PATCH',
|
||||
url: `/api/blocks/${createdBlockId}`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { elements_json: '[{"type":"rect"}]' },
|
||||
});
|
||||
expect(response.statusCode).toBe(200);
|
||||
@@ -173,6 +206,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'PATCH',
|
||||
url: '/api/blocks/non-existent-id',
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'New Name' },
|
||||
});
|
||||
expect(response.statusCode).toBe(404);
|
||||
@@ -186,6 +220,7 @@ describe('Blocks API', () => {
|
||||
const createRes = await app.inject({
|
||||
method: 'POST',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
payload: { name: 'To Be Deleted' },
|
||||
});
|
||||
const blockId = JSON.parse(createRes.body).id;
|
||||
@@ -193,6 +228,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'DELETE',
|
||||
url: `/api/blocks/${blockId}`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
});
|
||||
expect(response.statusCode).toBe(204);
|
||||
|
||||
@@ -200,6 +236,7 @@ describe('Blocks API', () => {
|
||||
const listRes = await app.inject({
|
||||
method: 'GET',
|
||||
url: `/api/drawings/${drawingId}/blocks`,
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
});
|
||||
const blocks = JSON.parse(listRes.body);
|
||||
expect(blocks.find((b: any) => b.id === blockId)).toBeUndefined();
|
||||
@@ -209,6 +246,7 @@ describe('Blocks API', () => {
|
||||
const response = await app.inject({
|
||||
method: 'DELETE',
|
||||
url: '/api/blocks/non-existent-id',
|
||||
headers: { authorization: `Bearer ${authToken}` },
|
||||
});
|
||||
expect(response.statusCode).toBe(404);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user