feat: blob size api (#4060)

This commit is contained in:
DarkSky 2023-08-31 16:39:19 +08:00 committed by GitHub
parent cc00da9325
commit 0add43f8db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 335 additions and 295 deletions

489
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -89,6 +89,12 @@ export class InvitationWorkspaceType {
avatar!: string;
}
@ObjectType()
export class WorkspaceBlobSizes {
@Field(() => Int)
size!: number;
}
@ObjectType()
export class InvitationType {
@Field({ description: 'Workspace information' })
@ -581,6 +587,16 @@ export class WorkspaceResolver {
return this.storage.listBlobs(workspaceId);
}
@Query(() => WorkspaceBlobSizes)
async collectBlobSizes(
@CurrentUser() user: UserType,
@Args('workspaceId') workspaceId: string
) {
await this.permissionProvider.check(workspaceId, user.id);
return this.storage.blobsSize(workspaceId).then(size => ({ size }));
}
@Mutation(() => String)
async setBlob(
@CurrentUser() user: UserType,

View File

@ -123,6 +123,10 @@ type InvitationWorkspaceType {
avatar: String!
}
type WorkspaceBlobSizes {
size: Int!
}
type InvitationType {
"""Workspace information"""
workspace: InvitationWorkspaceType!
@ -149,6 +153,7 @@ type Query {
"""List blobs of workspace"""
listBlobs(workspaceId: String!): [String!]!
collectBlobSizes(workspaceId: String!): WorkspaceBlobSizes!
"""Get current user"""
currentUser: UserType!

View File

@ -330,6 +330,28 @@ async function listBlobs(
return res.body.data.listBlobs;
}
async function collectBlobSizes(
app: INestApplication,
token: string,
workspaceId: string
): Promise<number> {
const res = await request(app.getHttpServer())
.post(gql)
.auth(token, { type: 'bearer' })
.set({ 'x-request-id': 'test', 'x-operation-name': 'test' })
.send({
query: `
query {
collectBlobSizes(workspaceId: "${workspaceId}") {
size
}
}
`,
})
.expect(200);
return res.body.data.collectBlobSizes.size;
}
async function setBlob(
app: INestApplication,
token: string,
@ -424,6 +446,7 @@ async function getInviteInfo(
export {
acceptInvite,
acceptInviteById,
collectBlobSizes,
createTestApp,
createWorkspace,
currentUser,

View File

@ -9,7 +9,13 @@ import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import request from 'supertest';
import { AppModule } from '../app';
import { createWorkspace, listBlobs, setBlob, signUp } from './utils';
import {
collectBlobSizes,
createWorkspace,
listBlobs,
setBlob,
signUp,
} from './utils';
describe('Workspace Module - Blobs', () => {
let app: INestApplication;
@ -44,6 +50,33 @@ describe('Workspace Module - Blobs', () => {
await app.close();
});
it('should set blobs', async () => {
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
const workspace = await createWorkspace(app, u1.token.token);
const buffer1 = Buffer.from([0, 0]);
const hash1 = await setBlob(app, u1.token.token, workspace.id, buffer1);
const buffer2 = Buffer.from([0, 1]);
const hash2 = await setBlob(app, u1.token.token, workspace.id, buffer2);
const server = app.getHttpServer();
const response1 = await request(server)
.get(`/api/workspaces/${workspace.id}/blobs/${hash1}`)
.auth(u1.token.token, { type: 'bearer' })
.buffer();
deepEqual(response1.body, buffer1, 'failed to get blob');
const response2 = await request(server)
.get(`/api/workspaces/${workspace.id}/blobs/${hash2}`)
.auth(u1.token.token, { type: 'bearer' })
.buffer();
deepEqual(response2.body, buffer2, 'failed to get blob');
});
it('should list blobs', async () => {
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
@ -51,20 +84,28 @@ describe('Workspace Module - Blobs', () => {
const blobs = await listBlobs(app, u1.token.token, workspace.id);
ok(blobs.length === 0, 'failed to list blobs');
const buffer = Buffer.from([0, 0]);
const hash = await setBlob(app, u1.token.token, workspace.id, buffer);
const buffer1 = Buffer.from([0, 0]);
const hash1 = await setBlob(app, u1.token.token, workspace.id, buffer1);
const buffer2 = Buffer.from([0, 1]);
const hash2 = await setBlob(app, u1.token.token, workspace.id, buffer2);
const ret = await listBlobs(app, u1.token.token, workspace.id);
ok(ret.length === 1, 'failed to list blobs');
ok(ret[0] === hash, 'failed to list blobs');
const server = app.getHttpServer();
ok(ret.length === 2, 'failed to list blobs');
ok(ret[0] === hash1, 'failed to list blobs');
ok(ret[1] === hash2, 'failed to list blobs');
});
const token = u1.token.token;
const response = await request(server)
.get(`/api/workspaces/${workspace.id}/blobs/${hash}`)
.auth(token, { type: 'bearer' })
.buffer();
it('should calc blobs size', async () => {
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
deepEqual(response.body, buffer, 'failed to get blob');
const workspace = await createWorkspace(app, u1.token.token);
const buffer1 = Buffer.from([0, 0]);
await setBlob(app, u1.token.token, workspace.id, buffer1);
const buffer2 = Buffer.from([0, 1]);
await setBlob(app, u1.token.token, workspace.id, buffer2);
const size = await collectBlobSizes(app, u1.token.token, workspace.id);
ok(size === 4, 'failed to collect blob sizes');
});
});

View File

@ -0,0 +1,5 @@
query blobSizes($workspaceId: String!) {
collectBlobSizes(workspaceId: $workspaceId) {
size
}
}

View File

@ -40,6 +40,19 @@ mutation setBlob($workspaceId: String!, $blob: Upload!) {
}`,
};
export const blobSizesQuery = {
id: 'blobSizesQuery' as const,
operationName: 'blobSizes',
definitionName: 'collectBlobSizes',
containsFile: false,
query: `
query blobSizes($workspaceId: String!) {
collectBlobSizes(workspaceId: $workspaceId) {
size
}
}`,
};
export const changeEmailMutation = {
id: 'changeEmailMutation' as const,
operationName: 'changeEmail',

View File

@ -73,6 +73,15 @@ export type SetBlobMutationVariables = Exact<{
export type SetBlobMutation = { __typename?: 'Mutation'; setBlob: string };
export type BlobSizesQueryVariables = Exact<{
workspaceId: Scalars['String']['input'];
}>;
export type BlobSizesQuery = {
__typename?: 'Query';
collectBlobSizes: { __typename?: 'WorkspaceBlobSizes'; size: number };
};
export type ChangeEmailMutationVariables = Exact<{
id: Scalars['String']['input'];
newEmail: Scalars['String']['input'];
@ -434,6 +443,11 @@ export type Queries =
variables: ListBlobsQueryVariables;
response: ListBlobsQuery;
}
| {
name: 'blobSizesQuery';
variables: BlobSizesQueryVariables;
response: BlobSizesQuery;
}
| {
name: 'getCurrentUserQuery';
variables: GetCurrentUserQueryVariables;

0
scripts/bump-octobase.sh Normal file → Executable file
View File