feat(server): add compatibility field (#4022)

This commit is contained in:
Alex Yang
2023-08-29 16:30:59 -05:00
committed by GitHub
parent e3b105f1cd
commit 71b195d9a9
4 changed files with 74 additions and 62 deletions

View File

@@ -1,13 +1,13 @@
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import pkg from '../package.json' assert { type: 'json' };
@Controller('/') @Controller('/')
export class AppController { export class AppController {
@Get() @Get()
hello() { info() {
const version = AFFiNE.version;
return { return {
message: `AFFiNE GraphQL server: ${pkg.version}`, compatibility: version,
message: `AFFiNE ${version} Server`,
}; };
} }
} }

View File

@@ -1,4 +1,4 @@
import type { INestApplication, LoggerService } from '@nestjs/common'; import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client'; import { PrismaClient } from '@prisma/client';
// @ts-expect-error graphql-upload is not typed // @ts-expect-error graphql-upload is not typed
@@ -10,28 +10,6 @@ import type { TokenType } from '../modules/auth';
import type { UserType } from '../modules/users'; import type { UserType } from '../modules/users';
import type { InvitationType, WorkspaceType } from '../modules/workspaces'; import type { InvitationType, WorkspaceType } from '../modules/workspaces';
export class NestDebugLogger implements LoggerService {
log(message: string): any {
console.log(message);
}
error(message: string, trace: string): any {
console.error(message, trace);
}
warn(message: string): any {
console.warn(message);
}
debug(message: string): any {
console.debug(message);
}
verbose(message: string): any {
console.log(message);
}
}
const gql = '/graphql'; const gql = '/graphql';
async function signUp( async function signUp(

View File

@@ -3,10 +3,9 @@ import {
createRandomUser, createRandomUser,
deleteUser, deleteUser,
getLoginCookie, getLoginCookie,
loginUser,
} from '@affine-test/kit/utils/cloud'; } from '@affine-test/kit/utils/cloud';
import { openHomePage } from '@affine-test/kit/utils/load-page';
import { waitEditorLoad } from '@affine-test/kit/utils/page-logic'; import { waitEditorLoad } from '@affine-test/kit/utils/page-logic';
import { clickSideBarCurrentWorkspaceBanner } from '@affine-test/kit/utils/sidebar';
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
let user: { let user: {
@@ -25,38 +24,21 @@ test.afterEach(async () => {
await deleteUser(user.email); await deleteUser(user.email);
}); });
test('server exist', async ({ page }) => { test('server exist', async () => {
await openHomePage(page);
await waitEditorLoad(page);
const json = await (await fetch('http://localhost:3010')).json(); const json = await (await fetch('http://localhost:3010')).json();
expect(json.message).toMatch(/^AFFiNE GraphQL server/); expect(json.compatibility).toMatch(/[0-9]+\.[0-9]+\.[0-9]+(-[a-z]+)?/);
}); });
test('enable cloud success', async ({ page, context }) => { test('enable cloud success', async ({ page, context }) => {
await page.goto('http://localhost:8080'); await loginUser(page, user, {
await page.waitForSelector('v-line'); beforeLogin: async () => {
expect(await getLoginCookie(context)).toBeUndefined();
await clickSideBarCurrentWorkspaceBanner(page); },
await page.getByTestId('cloud-signin-button').click({ afterLogin: async () => {
delay: 200, expect(await getLoginCookie(context)).toBeTruthy();
await page.reload();
await waitEditorLoad(page);
expect(await getLoginCookie(context)).toBeTruthy();
},
}); });
await page.getByPlaceholder('Enter your email address').type(user.email, {
delay: 50,
});
await page.getByTestId('continue-login-button').click({
delay: 200,
});
await page.getByTestId('sign-in-with-password').click({
delay: 200,
});
await page.getByTestId('password-input').type('123456', {
delay: 50,
});
expect(await getLoginCookie(context)).toBeUndefined();
await page.getByTestId('sign-in-button').click();
await page.waitForTimeout(1000);
await page.reload();
await waitEditorLoad(page);
expect(await getLoginCookie(context)).toBeTruthy();
}); });

View File

@@ -1,6 +1,10 @@
import { openHomePage } from '@affine-test/kit/utils/load-page';
import { waitEditorLoad } from '@affine-test/kit/utils/page-logic';
import { clickSideBarCurrentWorkspaceBanner } from '@affine-test/kit/utils/sidebar';
import { faker } from '@faker-js/faker'; import { faker } from '@faker-js/faker';
import { hash } from '@node-rs/argon2'; import { hash } from '@node-rs/argon2';
import type { BrowserContext, Cookie } from '@playwright/test'; import type { BrowserContext, Cookie, Page } from '@playwright/test';
import { z } from 'zod';
export async function getLoginCookie( export async function getLoginCookie(
context: BrowserContext context: BrowserContext
@@ -10,12 +14,20 @@ export async function getLoginCookie(
); );
} }
export async function createRandomUser() { const cloudUserSchema = z.object({
name: z.string(),
email: z.string().email(),
password: z.string(),
});
export type CloudUser = z.infer<typeof cloudUserSchema>;
export async function createRandomUser(): Promise<CloudUser> {
const user = { const user = {
name: faker.internet.userName(), name: faker.internet.userName(),
email: faker.internet.email().toLowerCase(), email: faker.internet.email().toLowerCase(),
password: '123456', password: '123456',
}; } satisfies CloudUser;
const { const {
PrismaClient, PrismaClient,
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -31,11 +43,13 @@ export async function createRandomUser() {
}); });
await client.$disconnect(); await client.$disconnect();
return client.user.findUnique({ const result = await client.user.findUnique({
where: { where: {
email: user.email, email: user.email,
}, },
}); });
cloudUserSchema.parse(result);
return result;
} }
export async function deleteUser(email: string) { export async function deleteUser(email: string) {
@@ -52,3 +66,41 @@ export async function deleteUser(email: string) {
}); });
await client.$disconnect(); await client.$disconnect();
} }
export async function loginUser(
page: Page,
user: CloudUser,
config?: {
beforeLogin?: () => Promise<void>;
afterLogin?: () => Promise<void>;
}
) {
await openHomePage(page);
await waitEditorLoad(page);
await clickSideBarCurrentWorkspaceBanner(page);
await page.getByTestId('cloud-signin-button').click({
delay: 200,
});
await page.getByPlaceholder('Enter your email address').type(user.email, {
delay: 50,
});
await page.getByTestId('continue-login-button').click({
delay: 200,
});
await page.getByTestId('sign-in-with-password').click({
delay: 200,
});
await page.getByTestId('password-input').type('123456', {
delay: 50,
});
if (config?.beforeLogin) {
await config.beforeLogin();
}
await page.waitForTimeout(200);
await page.getByTestId('sign-in-button').click();
await page.waitForTimeout(200);
if (config?.afterLogin) {
await config.afterLogin();
}
}