chore(server): move server tests folder (#9614)

This commit is contained in:
forehalo
2025-01-10 02:38:10 +00:00
parent 8e8058a44c
commit 1b6f0e78c4
54 changed files with 166 additions and 186 deletions
@@ -0,0 +1,79 @@
import type { INestApplication } from '@nestjs/common';
import type { TestFn } from 'ava';
import ava from 'ava';
import request from 'supertest';
import { buildAppModule } from '../../app.module';
import { createTestingApp } from '../utils';
const gql = '/graphql';
const test = ava as TestFn<{
app: INestApplication;
}>;
test.before('start app', async t => {
// @ts-expect-error override
AFFiNE.flavor = {
type: 'graphql',
allinone: false,
graphql: true,
sync: false,
renderer: false,
} satisfies typeof AFFiNE.flavor;
const { app } = await createTestingApp({
imports: [buildAppModule()],
});
t.context.app = app;
});
test.after.always(async t => {
await t.context.app.close();
});
test('should init app', async t => {
await request(t.context.app.getHttpServer())
.post(gql)
.send({
query: `
query {
error
}
`,
})
.expect(400);
const response = await request(t.context.app.getHttpServer())
.post(gql)
.send({
query: `query {
serverConfig {
name
version
type
features
}
}`,
})
.expect(200);
const config = response.body.data.serverConfig;
t.is(config.type, 'Affine');
t.true(Array.isArray(config.features));
});
test('should return 404 for unknown path', async t => {
await request(t.context.app.getHttpServer()).get('/unknown').expect(404);
t.pass();
});
test('should be able to call apis', async t => {
const res = await request(t.context.app.getHttpServer())
.get('/info')
.expect(200);
t.is(res.body.flavor, 'graphql');
});
@@ -0,0 +1,39 @@
import type { INestApplication } from '@nestjs/common';
import type { TestFn } from 'ava';
import ava from 'ava';
import request from 'supertest';
import { buildAppModule } from '../../app.module';
import { createTestingApp } from '../utils';
const test = ava as TestFn<{
app: INestApplication;
}>;
test.before('start app', async t => {
// @ts-expect-error override
AFFiNE.flavor = {
type: 'renderer',
allinone: false,
graphql: false,
sync: false,
renderer: true,
} satisfies typeof AFFiNE.flavor;
const { app } = await createTestingApp({
imports: [buildAppModule()],
});
t.context.app = app;
});
test.after.always(async t => {
await t.context.app.close();
});
test('should init app', async t => {
const res = await request(t.context.app.getHttpServer())
.get('/info')
.expect(200);
t.is(res.body.flavor, 'renderer');
});
@@ -0,0 +1,205 @@
import { mkdirSync, writeFileSync } from 'node:fs';
import path from 'node:path';
import type { INestApplication } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import type { TestFn } from 'ava';
import ava from 'ava';
import request from 'supertest';
import { buildAppModule } from '../../app.module';
import { Config } from '../../base';
import { ServerService } from '../../core/config';
import { createTestingApp, initTestingDB } from '../utils';
const test = ava as TestFn<{
app: INestApplication;
db: PrismaClient;
}>;
const mobileUAString =
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36';
function initTestStaticFiles(staticPath: string) {
const files = {
'selfhost.html': `<!DOCTYPE html><html><body>AFFiNE</body><script src="main.a.js"/></html>`,
'main.a.js': `const name = 'affine'`,
'admin/selfhost.html': `<!DOCTYPE html><html><body>AFFiNE Admin</body><script src="/admin/main.b.js"/></html>`,
'admin/main.b.js': `const name = 'affine-admin'`,
'mobile/selfhost.html': `<!DOCTYPE html><html><body>AFFiNE mobile</body><script src="/mobile/main.c.js"/></html>`,
'mobile/main.c.js': `const name = 'affine-mobile'`,
};
for (const [filename, content] of Object.entries(files)) {
const filePath = path.join(staticPath, filename);
mkdirSync(path.dirname(filePath), { recursive: true });
writeFileSync(filePath, content);
}
}
test.before('init selfhost server', async t => {
// @ts-expect-error override
AFFiNE.isSelfhosted = true;
AFFiNE.flavor.renderer = true;
const { app } = await createTestingApp({
imports: [buildAppModule()],
});
t.context.app = app;
t.context.db = t.context.app.get(PrismaClient);
const config = app.get(Config);
const staticPath = path.join(config.projectRoot, 'static');
initTestStaticFiles(staticPath);
});
test.beforeEach(async t => {
await initTestingDB(t.context.db);
const server = t.context.app.get(ServerService);
// @ts-expect-error disable cache
server._initialized = false;
});
test.after.always(async t => {
await t.context.app.close();
});
test('do not allow visit index.html directly', async t => {
let res = await request(t.context.app.getHttpServer())
.get('/index.html')
.expect(302);
t.is(res.header.location, '');
res = await request(t.context.app.getHttpServer())
.get('/admin/index.html')
.expect(302);
t.is(res.header.location, '/admin');
res = await request(t.context.app.getHttpServer())
.get('/mobile/index.html')
.expect(302);
});
test('should always return static asset files', async t => {
let res = await request(t.context.app.getHttpServer())
.get('/main.a.js')
.expect(200);
t.is(res.text, "const name = 'affine'");
res = await request(t.context.app.getHttpServer())
.get('/main.b.js')
.expect(200);
t.is(res.text, "const name = 'affine-admin'");
res = await request(t.context.app.getHttpServer())
.get('/main.c.js')
.expect(200);
t.is(res.text, "const name = 'affine-mobile'");
await t.context.db.user.create({
data: {
name: 'test',
email: 'test@affine.pro',
},
});
res = await request(t.context.app.getHttpServer())
.get('/main.a.js')
.expect(200);
t.is(res.text, "const name = 'affine'");
res = await request(t.context.app.getHttpServer())
.get('/main.b.js')
.expect(200);
t.is(res.text, "const name = 'affine-admin'");
res = await request(t.context.app.getHttpServer())
.get('/main.c.js')
.expect(200);
t.is(res.text, "const name = 'affine-mobile'");
});
test('should be able to call apis', async t => {
const res = await request(t.context.app.getHttpServer())
.get('/info')
.expect(200);
t.is(res.body.flavor, 'allinone');
});
const blockedPages = [
'/',
'/workspace',
'/admin',
'/admin/',
'/admin/accounts',
];
test('should redirect to setup if server is not initialized', async t => {
for (const path of blockedPages) {
const res = await request(t.context.app.getHttpServer()).get(path);
t.is(res.status, 302, `Failed to redirect ${path}`);
t.is(res.header.location, '/admin/setup');
}
t.pass();
});
test('should allow visiting all pages if initialized', async t => {
await t.context.db.user.create({
data: {
name: 'test',
email: 'test@affine.pro',
},
});
for (const path of blockedPages) {
const res = await request(t.context.app.getHttpServer()).get(path);
t.is(res.status, 200, `Failed to visit ${path}`);
}
t.pass();
});
test('should allow visiting setup page if not initialized', async t => {
const res = await request(t.context.app.getHttpServer())
.get('/admin/setup')
.expect(200);
t.true(res.text.includes('AFFiNE Admin'));
});
test('should redirect to admin if initialized', async t => {
await t.context.db.user.create({
data: {
name: 'test',
email: 'test@affine.pro',
},
});
const res = await request(t.context.app.getHttpServer())
.get('/admin/setup')
.expect(302);
t.is(res.header.location, '/admin');
});
test('should return mobile assets if visited by mobile', async t => {
await t.context.db.user.create({
data: {
name: 'test',
email: 'test@affine.pro',
},
});
const res = await request(t.context.app.getHttpServer())
.get('/')
.set('user-agent', mobileUAString)
.expect(200);
t.true(res.text.includes('AFFiNE mobile'));
});
@@ -0,0 +1,39 @@
import type { INestApplication } from '@nestjs/common';
import type { TestFn } from 'ava';
import ava from 'ava';
import request from 'supertest';
import { buildAppModule } from '../../app.module';
import { createTestingApp } from '../utils';
const test = ava as TestFn<{
app: INestApplication;
}>;
test.before('start app', async t => {
// @ts-expect-error override
AFFiNE.flavor = {
type: 'sync',
allinone: false,
graphql: false,
sync: true,
renderer: false,
} satisfies typeof AFFiNE.flavor;
const { app } = await createTestingApp({
imports: [buildAppModule()],
});
t.context.app = app;
});
test.after.always(async t => {
await t.context.app.close();
});
test('should init app', async t => {
const res = await request(t.context.app.getHttpServer())
.get('/info')
.expect(200);
t.is(res.body.flavor, 'sync');
});