From 9316bb422275387eda9fc141c15f4e843935c345 Mon Sep 17 00:00:00 2001 From: alt0 Date: Mon, 9 Jan 2023 18:53:15 +0800 Subject: [PATCH] test: add test case for affine --- .../provider/affine/__tests__/affine.spec.ts | 53 ++++++++++++++++ .../provider/affine/__tests__/mock-apis.ts | 19 ++++++ .../data-center/src/provider/affine/affine.ts | 60 +++++++++---------- .../src/provider/affine/apis/index.ts | 6 +- .../src/provider/affine/apis/token.ts | 8 ++- .../src/provider/affine/storage.ts | 1 + 6 files changed, 112 insertions(+), 35 deletions(-) create mode 100644 packages/data-center/src/provider/affine/__tests__/affine.spec.ts create mode 100644 packages/data-center/src/provider/affine/__tests__/mock-apis.ts create mode 100644 packages/data-center/src/provider/affine/storage.ts diff --git a/packages/data-center/src/provider/affine/__tests__/affine.spec.ts b/packages/data-center/src/provider/affine/__tests__/affine.spec.ts new file mode 100644 index 0000000000..46e735e955 --- /dev/null +++ b/packages/data-center/src/provider/affine/__tests__/affine.spec.ts @@ -0,0 +1,53 @@ +import { test, expect } from '@playwright/test'; +import { AffineProvider } from '../affine.js'; +import { Workspaces } from '../../../workspaces/index.js'; +import { apis } from './mock-apis.js'; +import 'fake-indexeddb/auto'; + +test.describe.serial('affine provider', async () => { + const workspaces = new Workspaces(); + const provider = new AffineProvider({ + workspaces: workspaces.createScope(), + apis, + }); + + await provider.auth(); + + const workspaceName = 'workspace-test'; + let workspaceId: string | undefined; + + test('create workspace', async () => { + const w = await provider.createWorkspace({ + name: workspaceName, + avatar: 'avatar-url-test', + }); + workspaceId = w?.room; + + expect(workspaces.workspaces.length).toEqual(1); + expect(workspaces.workspaces[0].name).toEqual(workspaceName); + }); + + // test('workspace list cache', async () => { + // const workspaces1 = new Workspaces(); + // const provider1 = new AffineProvider({ + // workspaces: workspaces1.createScope(), + // }); + // await provider1.loadWorkspaces(); + // expect(workspaces1.workspaces.length).toEqual(1); + // expect(workspaces1.workspaces[0].name).toEqual(workspaceName); + // expect(workspaces1.workspaces[0].id).toEqual(workspaceId); + // }); + + // test('update workspace', async () => { + // await provider.updateWorkspaceMeta(workspaceId!, { + // name: '1111', + // }); + // expect(workspaces.workspaces[0].name).toEqual('1111'); + // }); + + // test('delete workspace', async () => { + // expect(workspaces.workspaces.length).toEqual(1); + // await provider.deleteWorkspace(workspaces.workspaces[0].id); + // expect(workspaces.workspaces.length).toEqual(0); + // }); +}); diff --git a/packages/data-center/src/provider/affine/__tests__/mock-apis.ts b/packages/data-center/src/provider/affine/__tests__/mock-apis.ts new file mode 100644 index 0000000000..b05b9cd663 --- /dev/null +++ b/packages/data-center/src/provider/affine/__tests__/mock-apis.ts @@ -0,0 +1,19 @@ +import type { Apis, AccessTokenMessage } from '../apis'; + +const user: AccessTokenMessage = { + create_at: Date.now(), + exp: 100000000, + email: 'demo@demo.demo', + id: '123', + name: 'demo', + avatar_url: 'demo-avatar-url', +}; + +export const apis = { + signInWithGoogle: () => { + return Promise.resolve(user); + }, + createWorkspace: mate => { + return Promise.resolve({ id: 'test' }); + }, +} as Apis; diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts index d86c42f9fa..f2d99cb833 100644 --- a/packages/data-center/src/provider/affine/affine.ts +++ b/packages/data-center/src/provider/affine/affine.ts @@ -1,18 +1,16 @@ -import { BaseProvider } from '../base'; +import { BaseProvider } from '../base.js'; import type { ProviderConstructorParams } from '../base'; -import { User, Workspace as WS, WorkspaceMeta } from '../../types'; +import type { User, Workspace as WS, WorkspaceMeta } from '../../types'; import { Workspace } from '@blocksuite/store'; import { BlockSchema } from '@blocksuite/blocks/models'; import { applyUpdate } from 'yjs'; -import { token, Callback } from './apis'; -import { varStorage as storage } from 'lib0/storage'; +import { storage } from './storage.js'; import assert from 'assert'; -import { getAuthorizer } from './apis/token'; -import { WebsocketProvider } from './sync'; +import { WebsocketProvider } from './sync.js'; // import { IndexedDBProvider } from '../local/indexeddb'; -import { getDefaultHeadImgBlob } from '../../utils'; +import { getDefaultHeadImgBlob } from '../../utils/index.js'; import { getApis } from './apis/index.js'; -import type { Apis, WorkspaceDetail } from './apis'; +import type { Apis, WorkspaceDetail, Callback } from './apis'; export interface AffineProviderConstructorParams extends ProviderConstructorParams { @@ -23,8 +21,6 @@ export class AffineProvider extends BaseProvider { public id = 'affine'; private _workspacesCache: Map = new Map(); private _onTokenRefresh?: Callback = undefined; - private readonly _authorizer = getAuthorizer(); - private _user: User | undefined = undefined; private _wsMap: Map = new Map(); private _apis: Apis; // private _idbMap: Map = new Map(); @@ -36,29 +32,29 @@ export class AffineProvider extends BaseProvider { override async init() { this._onTokenRefresh = () => { - if (token.refresh) { - storage.setItem('token', token.refresh); + if (this._apis.token.refresh) { + storage.setItem('token', this._apis.token.refresh); } }; - token.onChange(this._onTokenRefresh); + this._apis.token.onChange(this._onTokenRefresh); // initial login token - if (token.isExpired) { + if (this._apis.token.isExpired) { try { const refreshToken = storage.getItem('token'); - await token.refreshToken(refreshToken); + await this._apis.token.refreshToken(refreshToken); - if (token.refresh) { - storage.set('token', token.refresh); + if (this._apis.token.refresh) { + storage.set('token', this._apis.token.refresh); } - assert(token.isLogin); + assert(this._apis.token.isLogin); } catch (_) { // this._logger('Authorization failed, fallback to local mode'); } } else { - storage.setItem('token', token.refresh); + storage.setItem('token', this._apis.token.refresh); } } @@ -91,7 +87,7 @@ export class AffineProvider extends BaseProvider { } override async loadWorkspaces() { - if (!token.isLogin) { + if (!this._apis.token.isLogin) { return []; } const workspacesList = await this._apis.getWorkspaces(); @@ -171,24 +167,26 @@ export class AffineProvider extends BaseProvider { override async auth() { const refreshToken = await storage.getItem('token'); if (refreshToken) { - await token.refreshToken(refreshToken); - if (token.isLogin && !token.isExpired) { + await this._apis.token.refreshToken(refreshToken); + if (this._apis.token.isLogin && !this._apis.token.isExpired) { // login success return; } } - const user = await this._authorizer[0]?.(); + const user = await this._apis.signInWithGoogle?.(); assert(user); - this._user = { - id: user.id, - name: user.name, - avatar: user.avatar_url, - email: user.email, - }; } public override async getUserInfo(): Promise { - return this._user; + const user = this._apis.token.user; + return user + ? { + id: user.id, + name: user.name, + avatar: user.avatar_url, + email: user.email, + } + : undefined; } public override async deleteWorkspace(id: string): Promise { @@ -265,7 +263,7 @@ export class AffineProvider extends BaseProvider { owner: undefined, isLocal: true, memberCount: 1, - provider: 'local', + provider: 'affine', }; if (!meta.avatar) { diff --git a/packages/data-center/src/provider/affine/apis/index.ts b/packages/data-center/src/provider/affine/apis/index.ts index 8c627519a0..21d0c8e737 100644 --- a/packages/data-center/src/provider/affine/apis/index.ts +++ b/packages/data-center/src/provider/affine/apis/index.ts @@ -1,15 +1,16 @@ -export { token } from './token.js'; +// export { token } from './token.js'; export type { Callback } from './token.js'; import { getAuthorizer } from './token.js'; import * as user from './user.js'; import * as workspace from './workspace.js'; +import { token } from './token.js'; export type Apis = typeof user & typeof workspace & { signInWithGoogle: ReturnType[0]; onAuthStateChanged: ReturnType[1]; - }; + } & { token: typeof token }; export const getApis = (): Apis => { const [signInWithGoogle, onAuthStateChanged] = getAuthorizer(); @@ -18,6 +19,7 @@ export const getApis = (): Apis => { ...workspace, signInWithGoogle, onAuthStateChanged, + token, }; }; diff --git a/packages/data-center/src/provider/affine/apis/token.ts b/packages/data-center/src/provider/affine/apis/token.ts index d7a2c34f87..3ab36adbf0 100644 --- a/packages/data-center/src/provider/affine/apis/token.ts +++ b/packages/data-center/src/provider/affine/apis/token.ts @@ -2,8 +2,8 @@ import { initializeApp } from 'firebase/app'; import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; import type { User } from 'firebase/auth'; -import { getLogger } from '../../../logger'; -import { bareClient } from './request'; +import { getLogger } from '../../../logger.js'; +import { bareClient } from './request.js'; export interface AccessTokenMessage { create_at: number; @@ -46,6 +46,10 @@ class Token { this._setToken(); // fill with default value } + get user() { + return this._user; + } + private _setToken(login?: LoginResponse) { this._accessToken = login?.token || ''; this._refreshToken = login?.refresh || ''; diff --git a/packages/data-center/src/provider/affine/storage.ts b/packages/data-center/src/provider/affine/storage.ts new file mode 100644 index 0000000000..4ac1b74697 --- /dev/null +++ b/packages/data-center/src/provider/affine/storage.ts @@ -0,0 +1 @@ +export { varStorage as storage } from 'lib0/storage';