fix(server): storage usage should be float rather than int (#4275)

This commit is contained in:
LongYinan
2023-09-07 22:15:33 -07:00
committed by GitHub
parent 0bc3d9ebf5
commit aa025b0d46
5 changed files with 127 additions and 19 deletions

View File

@@ -101,7 +101,7 @@ export class InvitationWorkspaceType {
@ObjectType()
export class WorkspaceBlobSizes {
@Field(() => Int)
@Field(() => Float)
size!: number;
}

View File

@@ -124,7 +124,7 @@ type InvitationWorkspaceType {
}
type WorkspaceBlobSizes {
size: Int!
size: Float!
}
type InvitationType {

View File

@@ -6,7 +6,7 @@ import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { hashSync } from '@node-rs/argon2';
import { User } from '@prisma/client';
import test from 'ava';
import ava, { TestFn } from 'ava';
import { Express } from 'express';
// @ts-expect-error graphql-upload is not typed
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
@@ -17,7 +17,9 @@ import { PrismaService } from '../prisma/service';
const gql = '/graphql';
let app: INestApplication;
const test = ava as TestFn<{
app: INestApplication;
}>;
class FakePrisma {
fakeUser: User = {
@@ -46,33 +48,33 @@ class FakePrisma {
}
}
test.beforeEach(async () => {
test.beforeEach(async t => {
const module = await Test.createTestingModule({
imports: [AppModule],
})
.overrideProvider(PrismaService)
.useClass(FakePrisma)
.compile();
app = module.createNestApplication({
t.context.app = module.createNestApplication({
cors: true,
bodyParser: true,
});
app.use(
t.context.app.use(
graphqlUploadExpress({
maxFileSize: 10 * 1024 * 1024,
maxFiles: 5,
})
);
await app.init();
await t.context.app.init();
});
test.afterEach(async () => {
await app.close();
test.afterEach(async t => {
await t.context.app.close();
});
test('should init app', async t => {
t.is(typeof app, 'object');
await request(app.getHttpServer())
t.is(typeof t.context.app, 'object');
await request(t.context.app.getHttpServer())
.post(gql)
.send({
query: `
@@ -83,9 +85,9 @@ test('should init app', async t => {
})
.expect(400);
const { token } = await createToken(app);
const { token } = await createToken(t.context.app);
await request(app.getHttpServer())
await request(t.context.app.getHttpServer())
.post(gql)
.auth(token, { type: 'bearer' })
.send({
@@ -102,8 +104,8 @@ test('should init app', async t => {
});
test('should find default user', async t => {
const { token } = await createToken(app);
await request(app.getHttpServer())
const { token } = await createToken(t.context.app);
await request(t.context.app.getHttpServer())
.post(gql)
.auth(token, { type: 'bearer' })
.send({
@@ -123,14 +125,14 @@ test('should find default user', async t => {
});
test('should be able to upload avatar', async t => {
const { token, id } = await createToken(app);
const { token, id } = await createToken(t.context.app);
const png = await Transformer.fromRgbaPixels(
Buffer.alloc(400 * 400 * 4).fill(255),
400,
400
).png();
await request(app.getHttpServer())
await request(t.context.app.getHttpServer())
.post(gql)
.auth(token, { type: 'bearer' })
.field(

View File

@@ -1,6 +1,9 @@
import { randomUUID } from 'node:crypto';
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import { hashSync } from '@node-rs/argon2';
import { PrismaClient, User } from '@prisma/client';
// @ts-expect-error graphql-upload is not typed
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
import request from 'supertest';
@@ -498,6 +501,33 @@ async function getInviteInfo(
return res.body.data.getInviteInfo;
}
export class FakePrisma {
fakeUser: User = {
id: randomUUID(),
name: 'Alex Yang',
avatarUrl: '',
email: 'alex.yang@example.org',
password: hashSync('123456'),
emailVerified: new Date(),
createdAt: new Date(),
};
get user() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const prisma = this;
return {
async findFirst() {
return prisma.fakeUser;
},
async findUnique() {
return this.findFirst();
},
async update() {
return this.findFirst();
},
};
}
}
export {
acceptInvite,
acceptInviteById,

View File

@@ -0,0 +1,76 @@
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import ava, { TestFn } from 'ava';
import { stub } from 'sinon';
import { AppModule } from '../app';
import { UsersService } from '../modules/users';
import { PermissionService } from '../modules/workspaces/permission';
import { WorkspaceResolver } from '../modules/workspaces/resolver';
import { PrismaService } from '../prisma';
import { StorageProvide } from '../storage';
import { FakePrisma } from './utils';
class FakePermission {
async tryCheck() {
return true;
}
async getWorkspaceOwner() {
return {
user: new FakePrisma().fakeUser,
};
}
}
const fakeUserService = {
getStorageQuotaById: stub(),
};
const test = ava as TestFn<{
app: INestApplication;
resolver: WorkspaceResolver;
}>;
test.beforeEach(async t => {
const module = await Test.createTestingModule({
imports: [AppModule],
})
.overrideProvider(PrismaService)
.useValue({
userWorkspacePermission: {
async findMany() {
return [];
},
},
})
.overrideProvider(PermissionService)
.useClass(FakePermission)
.overrideProvider(UsersService)
.useValue(fakeUserService)
.overrideProvider(StorageProvide)
.useValue({
blobsSize() {
return 1024 * 10;
},
})
.compile();
t.context.app = module.createNestApplication();
t.context.resolver = t.context.app.get(WorkspaceResolver);
await t.context.app.init();
});
test.afterEach(async t => {
await t.context.app.close();
});
test('should get blob size limit', async t => {
const { resolver } = t.context;
fakeUserService.getStorageQuotaById.returns(
Promise.resolve(100 * 1024 * 1024 * 1024)
);
const res = await resolver.checkBlobSize(new FakePrisma().fakeUser, '', 100);
t.not(res, false);
// @ts-expect-error
t.is(typeof res.size, 'number');
fakeUserService.getStorageQuotaById.reset();
});