2025-07-03 11:15:00 +02:00
|
|
|
import { ServerBlockNoteEditor } from '@blocknote/server-util';
|
2024-12-15 00:03:13 +01:00
|
|
|
import request from 'supertest';
|
2025-07-02 16:39:46 +02:00
|
|
|
import { describe, expect, test, vi } from 'vitest';
|
2025-07-03 11:15:00 +02:00
|
|
|
import * as Y from 'yjs';
|
2024-12-15 00:03:13 +01:00
|
|
|
|
2025-07-02 16:39:46 +02:00
|
|
|
vi.mock('../src/env', async (importOriginal) => {
|
2024-12-15 00:03:13 +01:00
|
|
|
return {
|
2025-07-02 16:39:46 +02:00
|
|
|
...(await importOriginal()),
|
|
|
|
|
COLLABORATION_SERVER_ORIGIN: 'http://localhost:3000',
|
2024-12-15 00:03:13 +01:00
|
|
|
Y_PROVIDER_API_KEY: 'yprovider-api-key',
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
2025-07-02 16:39:46 +02:00
|
|
|
import { initApp } from '@/servers';
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
Y_PROVIDER_API_KEY as apiKey,
|
|
|
|
|
COLLABORATION_SERVER_ORIGIN as origin,
|
|
|
|
|
} from '../src/env';
|
2024-12-15 00:03:13 +01:00
|
|
|
|
2025-07-02 16:39:46 +02:00
|
|
|
console.error = vi.fn();
|
|
|
|
|
|
2024-12-15 00:03:13 +01:00
|
|
|
describe('Server Tests', () => {
|
2025-07-04 11:57:06 +02:00
|
|
|
test('POST /api/convert with incorrect API key should responds with 401', async () => {
|
2025-07-03 11:15:00 +02:00
|
|
|
const app = initApp();
|
2024-12-15 00:03:13 +01:00
|
|
|
|
2025-07-02 16:39:46 +02:00
|
|
|
const response = await request(app)
|
2025-06-27 14:19:53 +02:00
|
|
|
.post('/api/convert')
|
2024-12-15 00:03:13 +01:00
|
|
|
.set('Origin', origin)
|
|
|
|
|
.set('Authorization', 'wrong-api-key');
|
|
|
|
|
|
2025-07-04 11:57:06 +02:00
|
|
|
expect(response.status).toBe(401);
|
2025-07-02 16:39:46 +02:00
|
|
|
expect(response.body).toStrictEqual({
|
|
|
|
|
error: 'Forbidden: Invalid API Key',
|
|
|
|
|
});
|
2024-12-15 00:03:13 +01:00
|
|
|
});
|
|
|
|
|
|
2025-06-27 14:19:53 +02:00
|
|
|
test('POST /api/convert with a Bearer token', async () => {
|
2025-07-03 11:15:00 +02:00
|
|
|
const app = initApp();
|
2025-07-02 16:39:46 +02:00
|
|
|
|
|
|
|
|
const response = await request(app)
|
2025-06-27 14:19:53 +02:00
|
|
|
.post('/api/convert')
|
2024-12-15 00:03:13 +01:00
|
|
|
.set('Origin', origin)
|
|
|
|
|
.set('Authorization', 'Bearer test-secret-api-key');
|
|
|
|
|
|
|
|
|
|
// Warning: Changing the authorization header to Bearer token format will break backend compatibility with this microservice.
|
2025-07-04 11:57:06 +02:00
|
|
|
expect(response.status).toBe(401);
|
2025-07-02 16:39:46 +02:00
|
|
|
expect(response.body).toStrictEqual({
|
|
|
|
|
error: 'Forbidden: Invalid API Key',
|
|
|
|
|
});
|
2024-12-15 00:03:13 +01:00
|
|
|
});
|
|
|
|
|
|
2025-06-27 14:19:53 +02:00
|
|
|
test('POST /api/convert with missing body param content', async () => {
|
2025-07-03 11:15:00 +02:00
|
|
|
const app = initApp();
|
2025-07-02 16:39:46 +02:00
|
|
|
|
|
|
|
|
const response = await request(app)
|
2025-06-27 14:19:53 +02:00
|
|
|
.post('/api/convert')
|
2024-12-15 00:03:13 +01:00
|
|
|
.set('Origin', origin)
|
2025-07-02 16:39:46 +02:00
|
|
|
.set('Authorization', apiKey);
|
2024-12-15 00:03:13 +01:00
|
|
|
|
|
|
|
|
expect(response.status).toBe(400);
|
2025-07-02 16:39:46 +02:00
|
|
|
expect(response.body).toStrictEqual({
|
|
|
|
|
error: 'Invalid request: missing content',
|
|
|
|
|
});
|
2024-12-15 00:03:13 +01:00
|
|
|
});
|
|
|
|
|
|
2025-06-27 14:19:53 +02:00
|
|
|
test('POST /api/convert with body param content being an empty string', async () => {
|
2025-07-03 11:15:00 +02:00
|
|
|
const app = initApp();
|
2025-07-02 16:39:46 +02:00
|
|
|
|
|
|
|
|
const response = await request(app)
|
2025-06-27 14:19:53 +02:00
|
|
|
.post('/api/convert')
|
2024-12-15 00:03:13 +01:00
|
|
|
.set('Origin', origin)
|
2025-07-02 16:39:46 +02:00
|
|
|
.set('Authorization', apiKey)
|
2024-12-15 00:03:13 +01:00
|
|
|
.send({
|
|
|
|
|
content: '',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(400);
|
2025-07-02 16:39:46 +02:00
|
|
|
expect(response.body).toStrictEqual({
|
|
|
|
|
error: 'Invalid request: missing content',
|
|
|
|
|
});
|
2024-12-15 00:03:13 +01:00
|
|
|
});
|
2025-07-03 11:15:00 +02:00
|
|
|
|
|
|
|
|
test('POST /api/convert with correct content', async () => {
|
|
|
|
|
const app = initApp();
|
|
|
|
|
|
|
|
|
|
const document = [
|
|
|
|
|
'# Example document',
|
|
|
|
|
'',
|
|
|
|
|
'Lorem ipsum dolor sit amet.',
|
|
|
|
|
'',
|
|
|
|
|
].join('\n');
|
|
|
|
|
|
|
|
|
|
const response = await request(app)
|
|
|
|
|
.post('/api/convert')
|
|
|
|
|
.set('Origin', origin)
|
|
|
|
|
.set('Authorization', apiKey)
|
|
|
|
|
.send({
|
|
|
|
|
content: document,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
|
expect(response.body).toStrictEqual({
|
|
|
|
|
content: expect.any(String),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const editor = ServerBlockNoteEditor.create();
|
|
|
|
|
const doc = new Y.Doc();
|
|
|
|
|
Y.applyUpdate(doc, Buffer.from(response.body.content, 'base64'));
|
|
|
|
|
const blocks = editor.yDocToBlocks(doc, 'document-store');
|
|
|
|
|
|
|
|
|
|
expect(blocks).toStrictEqual([
|
|
|
|
|
{
|
|
|
|
|
children: [],
|
|
|
|
|
content: [
|
|
|
|
|
{
|
|
|
|
|
styles: {},
|
|
|
|
|
text: 'Example document',
|
|
|
|
|
type: 'text',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
id: expect.any(String),
|
|
|
|
|
props: {
|
|
|
|
|
backgroundColor: 'default',
|
|
|
|
|
isToggleable: false,
|
|
|
|
|
level: 1,
|
|
|
|
|
textAlignment: 'left',
|
|
|
|
|
textColor: 'default',
|
|
|
|
|
},
|
|
|
|
|
type: 'heading',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
children: [],
|
|
|
|
|
content: [
|
|
|
|
|
{
|
|
|
|
|
styles: {},
|
|
|
|
|
text: 'Lorem ipsum dolor sit amet.',
|
|
|
|
|
type: 'text',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
id: expect.any(String),
|
|
|
|
|
props: {
|
|
|
|
|
backgroundColor: 'default',
|
|
|
|
|
textAlignment: 'left',
|
|
|
|
|
textColor: 'default',
|
|
|
|
|
},
|
|
|
|
|
type: 'paragraph',
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
});
|
2024-12-15 00:03:13 +01:00
|
|
|
});
|