test: improve coverage on affine api (#1727)

This commit is contained in:
Himself65
2023-03-28 12:42:40 -05:00
committed by GitHub
parent 751ad9716f
commit dbbc05e5f0
7 changed files with 119 additions and 48 deletions

View File

@@ -52,6 +52,12 @@ runs:
restore-keys: |
yarn-download-cache-
- name: Restore node_modules cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- name: Restore yarn install state
id: yarn-install-state-cache
uses: actions/cache@v3

View File

@@ -96,7 +96,6 @@ jobs:
name: Unit Test
runs-on: ubuntu-latest
environment: development
needs: [build]
services:
octobase:
image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest
@@ -111,11 +110,6 @@ jobs:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: artifact
path: ./apps/web/.next
- name: Unit Test
run: yarn run test:unit:coverage

View File

@@ -80,7 +80,11 @@ export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
const url = await blobs.get(id);
if (url) {
const blob = await fetch(url).then(res => res.blob());
await affineApis.uploadBlob(newWorkspaceId, blob);
await affineApis.uploadBlob(
newWorkspaceId,
await blob.arrayBuffer(),
blob.type
);
}
}
}

View File

@@ -38,6 +38,7 @@
},
"devDependencies": {
"@affine/cli": "workspace:*",
"@faker-js/faker": "^7.6.0",
"@istanbuljs/schema": "^0.1.3",
"@perfsee/sdk": "^1.5.1",
"@playwright/test": "^1.32.1",

View File

@@ -3,10 +3,12 @@
*/
import 'fake-indexeddb/auto';
import { readFile } from 'node:fs/promises';
import { MessageCode } from '@affine/env/constant';
import userA from '@affine-test/fixtures/userA.json';
import { assertExists } from '@blocksuite/global/utils';
import { Workspace } from '@blocksuite/store';
import { faker } from '@faker-js/faker';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import {
@@ -24,40 +26,36 @@ import {
let workspaceApis: ReturnType<typeof createWorkspaceApis>;
let affineAuth: ReturnType<typeof createAffineAuth>;
const mockUser = {
name: faker.name.fullName(),
email: faker.internet.email(),
password: faker.internet.password(),
};
beforeEach(() => {
// create a new user for each test, so that each test can be run independently
mockUser.name = faker.name.fullName();
mockUser.email = faker.internet.email();
mockUser.password = faker.internet.password();
});
beforeEach(() => {
affineAuth = createAffineAuth('http://localhost:3000/');
workspaceApis = createWorkspaceApis('http://localhost:3000/');
});
beforeEach(async () => {
let data;
// first step: try to log in
const response = await fetch('http://localhost:3000/api/user/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'DebugLoginUser',
email: userA.email,
password: userA.password,
}),
});
if (!response.ok) {
data = await fetch('http://localhost:3000/api/user/token', {
const data = await fetch('http://localhost:3000/api/user/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'DebugCreateUser',
...userA,
...mockUser,
}),
}).then(r => r.json());
setLoginStorage(data);
} else {
setLoginStorage((data = await response.json()));
}
loginResponseSchema.parse(data);
});
@@ -69,6 +67,18 @@ declare global {
}
}
async function createWorkspace(
workspaceApi: typeof workspaceApis
): Promise<string> {
const workspace = new Workspace({
id: faker.datatype.uuid(),
});
const binary = Workspace.Y.encodeStateAsUpdate(workspace.doc);
const data = await workspaceApi.createWorkspace(new Blob([binary]));
createWorkspaceResponseSchema.parse(data);
return data.id;
}
describe('api', () => {
test('failed', async () => {
workspaceApis = createWorkspaceApis('http://localhost:10086/404/');
@@ -100,12 +110,8 @@ describe('api', () => {
test(
'create workspace',
async () => {
const workspace = new Workspace({
id: 'test',
});
const binary = Workspace.Y.encodeStateAsUpdate(workspace.doc);
const data = await workspaceApis.createWorkspace(new Blob([binary]));
createWorkspaceResponseSchema.parse(data);
const id = await createWorkspace(workspaceApis);
expect(id).toBeTypeOf('string');
},
{
timeout: 30000,
@@ -115,13 +121,7 @@ describe('api', () => {
test(
'delete workspace',
async () => {
const workspace = new Workspace({
id: 'test',
});
const binary = Workspace.Y.encodeStateAsUpdate(workspace.doc);
const data = await workspaceApis.createWorkspace(new Blob([binary]));
createWorkspaceResponseSchema.parse(data);
const id = data.id;
const id = await createWorkspace(workspaceApis);
const response = await workspaceApis.deleteWorkspace({
id,
});
@@ -131,4 +131,58 @@ describe('api', () => {
timeout: 30000,
}
);
test('get workspaces', async () => {
const id = await createWorkspace(workspaceApis);
const response = await workspaceApis.getWorkspaces();
expect(response).toBeInstanceOf(Array);
expect(response.length).toBe(1);
expect(response[0].id).toBe(id);
});
test(
'blob',
async () => {
const workspace = new Workspace({
id: 'test',
});
const path = require.resolve('@affine-test/fixtures/smile.png');
const imageBuffer = await readFile(path);
const binary = Workspace.Y.encodeStateAsUpdate(workspace.doc);
const data = await workspaceApis.createWorkspace(new Blob([binary]));
createWorkspaceResponseSchema.parse(data);
const blobId = await workspaceApis.uploadBlob(
data.id,
imageBuffer,
'image/png'
);
expect(blobId).toBeTypeOf('string');
const arrayBuffer = await workspaceApis.getBlob(blobId);
expect(arrayBuffer).toBeInstanceOf(ArrayBuffer);
expect(arrayBuffer.byteLength).toEqual(imageBuffer.byteLength);
expect(Buffer.from(arrayBuffer)).toEqual(imageBuffer);
},
{
timeout: 30000,
}
);
test(
'workspace binary',
async () => {
const id = await createWorkspace(workspaceApis);
await workspaceApis.updateWorkspace({
id,
public: true,
});
const binary = await workspaceApis.downloadWorkspace(id, false);
const publicBinary = await workspaceApis.downloadWorkspace(id, true);
expect(binary).toBeInstanceOf(ArrayBuffer);
expect(publicBinary).toBeInstanceOf(ArrayBuffer);
expect(binary.byteLength).toEqual(publicBinary.byteLength);
},
{
timeout: 30000,
}
);
});

View File

@@ -295,22 +295,26 @@ export function createWorkspaceApis(prefixUrl = '/') {
throw new RequestError(MessageCode.acceptInvitingFailed, e);
});
},
uploadBlob: async (workspaceId: string, blob: Blob): Promise<string> => {
uploadBlob: async (
workspaceId: string,
arrayBuffer: ArrayBuffer,
type: string
): Promise<string> => {
const auth = getLoginStorage();
assertExists(auth);
return fetch(prefixUrl + 'api/blob', {
method: 'PUT',
body: blob,
body: arrayBuffer,
headers: {
'Content-Type': blob.type,
'Content-Type': type,
Authorization: auth.token,
},
}).then(r => r.text());
},
getBlob: async (params: { blobId: string }): Promise<ArrayBuffer> => {
getBlob: async (blobId: string): Promise<ArrayBuffer> => {
const auth = getLoginStorage();
assertExists(auth);
return fetch(prefixUrl + `api/blob/${params.blobId}`, {
return fetch(prefixUrl + `api/blob/${blobId}`, {
method: 'GET',
headers: {
Authorization: auth.token,

View File

@@ -2432,6 +2432,13 @@ __metadata:
languageName: node
linkType: hard
"@faker-js/faker@npm:^7.6.0":
version: 7.6.0
resolution: "@faker-js/faker@npm:7.6.0"
checksum: 942af6221774e8c98a0eb6bc75265e05fb81a941170377666c3439aab9495dd321d6beedc5406f07e6ad44262b3e43c20961f666d116ad150b78e7437dd1bb2b
languageName: node
linkType: hard
"@fal-works/esbuild-plugin-global-externals@npm:^2.1.2":
version: 2.1.2
resolution: "@fal-works/esbuild-plugin-global-externals@npm:2.1.2"
@@ -7328,6 +7335,7 @@ __metadata:
resolution: "AFFiNE@workspace:."
dependencies:
"@affine/cli": "workspace:*"
"@faker-js/faker": ^7.6.0
"@istanbuljs/schema": ^0.1.3
"@perfsee/sdk": ^1.5.1
"@playwright/test": ^1.32.1