Skip to content

Commit

Permalink
feat: space limit is now fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
apsantiso committed Jul 17, 2024
1 parent b87275e commit 4b2c5f0
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const tableName = 'workspaces';
const newColumn = 'number_of_seats';

module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn(tableName, newColumn, {
type: Sequelize.INTEGER,
});
},

async down(queryInterface) {
await queryInterface.removeColumn(tableName, newColumn);
},
};
10 changes: 9 additions & 1 deletion src/modules/gateway/dto/initialize-workspace.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@ export class InitializeWorkspaceDto {
address?: string;

@ApiProperty({
example: '312321312',
example: 312321312,
description: 'Workspace max space in bytes',
})
@IsNotEmpty()
@IsNumber()
maxSpaceBytes: number;

@ApiProperty({
example: 20,
description: 'Workspace max number of users',
})
@IsNotEmpty()
@IsNumber()
numberOfSeats: number;
}
1 change: 1 addition & 0 deletions src/modules/gateway/gateway.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('Gateway Controller', () => {
ownerId: owner.uuid,
maxSpaceBytes: 1000000,
address: '123 Main St',
numberOfSeats: 20,
};

it('When workspace is created successfully, then return', async () => {
Expand Down
2 changes: 2 additions & 0 deletions src/modules/gateway/gateway.usecase.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('GatewayUseCases', () => {
ownerId: owner.uuid,
maxSpaceBytes,
address: workspaceAddress,
numberOfSeats: 20,
};

await expect(
Expand All @@ -79,6 +80,7 @@ describe('GatewayUseCases', () => {
ownerId: owner.uuid,
maxSpaceBytes,
address: workspaceAddress,
numberOfSeats: 20,
};
await expect(
service.initializeWorkspace(initializeWorkspaceDto),
Expand Down
4 changes: 3 additions & 1 deletion src/modules/gateway/gateway.usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ export class GatewayUseCases {
Logger.log(
`Initializing workspace with owner id: ${initializeWorkspaceDto.ownerId}`,
);
const { ownerId, maxSpaceBytes, address } = initializeWorkspaceDto;
const { ownerId, maxSpaceBytes, address, numberOfSeats } =
initializeWorkspaceDto;

return this.workspaceUseCases.initiateWorkspace(ownerId, maxSpaceBytes, {
address,
numberOfSeats,
});
}

Expand Down
1 change: 1 addition & 0 deletions src/modules/workspaces/attributes/workspace.attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface WorkspaceAttributes {
defaultTeamId: string;
workspaceUserId: string;
setupCompleted: boolean;
numberOfSeats: number;
rootFolderId?: string;
createdAt: Date;
updatedAt: Date;
Expand Down
7 changes: 7 additions & 0 deletions src/modules/workspaces/domains/workspaces.domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class Workspace implements WorkspaceAttributes {
defaultTeamId: string;
workspaceUserId: string;
setupCompleted: boolean;
numberOfSeats: number;
createdAt: Date;
updatedAt: Date;

Expand All @@ -27,6 +28,7 @@ export class Workspace implements WorkspaceAttributes {
workspaceUserId,
setupCompleted,
avatar,
numberOfSeats,
createdAt,
updatedAt,
}: WorkspaceAttributes) {
Expand All @@ -40,6 +42,7 @@ export class Workspace implements WorkspaceAttributes {
this.workspaceUserId = workspaceUserId;
this.setupCompleted = setupCompleted;
this.rootFolderId = rootFolderId;
this.numberOfSeats = numberOfSeats;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
Expand All @@ -56,6 +59,10 @@ export class Workspace implements WorkspaceAttributes {
return this.setupCompleted === true;
}

isWorkspaceFull(currentUsersCount: number) {
return this.numberOfSeats <= currentUsersCount;
}

isDefaultTeam(team: WorkspaceTeam) {
return this.defaultTeamId === team.id;
}
Expand Down
10 changes: 2 additions & 8 deletions src/modules/workspaces/dto/create-workspace-invite.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsPositive } from 'class-validator';
import { IsNotEmpty } from 'class-validator';
import { User } from '../../user/user.domain';
import { WorkspaceInvite } from '../domains/workspace-invite.domain';

Expand All @@ -11,13 +11,7 @@ export class CreateWorkspaceInviteDto {
@IsNotEmpty()
invitedUser: User['email'];

@ApiProperty({
example: '1073741824',
description: 'Space assigned to user in bytes',
})
@IsNotEmpty()
@IsPositive()
spaceLimit: WorkspaceInvite['spaceLimit'];
spaceLimit?: WorkspaceInvite['spaceLimit'];

@ApiProperty({
example: 'encrypted encryption key',
Expand Down
3 changes: 3 additions & 0 deletions src/modules/workspaces/models/workspace.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export class WorkspaceModel extends Model implements WorkspaceAttributes {
@Column(DataType.UUID)
rootFolderId?: string;

@Column(DataType.INTEGER)
numberOfSeats: number;

@HasOne(() => FolderModel, 'uuid')
rootFolder: FolderModel;

Expand Down
36 changes: 27 additions & 9 deletions src/modules/workspaces/workspaces.usecase.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ describe('WorkspacesUsecases', () => {
jest
.spyOn(service, 'getAssignableSpaceInWorkspace')
.mockResolvedValueOnce(6000000);

jest
.spyOn(service, 'getWorkspaceFixedStoragePerUser')
.mockResolvedValueOnce(1024);

jest.spyOn(configService, 'get').mockResolvedValueOnce('secret' as never);
jest
.spyOn(mailerService, 'sendWorkspaceUserExternalInvitation')
Expand All @@ -171,7 +176,6 @@ describe('WorkspacesUsecases', () => {
await expect(
service.inviteUserToWorkspace(user, 'workspace-id', {
invitedUser: '[email protected]',
spaceLimit: 1024,
encryptionKey: '',
encryptionAlgorithm: '',
}),
Expand Down Expand Up @@ -202,6 +206,10 @@ describe('WorkspacesUsecases', () => {
jest
.spyOn(service, 'getAssignableSpaceInWorkspace')
.mockResolvedValueOnce(6000000);
jest
.spyOn(service, 'getWorkspaceFixedStoragePerUser')
.mockResolvedValueOnce(1024);

jest
.spyOn(mailerService, 'sendWorkspaceUserInvitation')
.mockResolvedValueOnce(undefined);
Expand All @@ -210,7 +218,6 @@ describe('WorkspacesUsecases', () => {
await expect(
service.inviteUserToWorkspace(user, 'workspace-id', {
invitedUser: '[email protected]',
spaceLimit: 1024,
encryptionKey: '',
encryptionAlgorithm: '',
}),
Expand Down Expand Up @@ -401,6 +408,10 @@ describe('WorkspacesUsecases', () => {
.spyOn(workspaceRepository, 'findWorkspaceUser')
.mockResolvedValueOnce(null);

jest
.spyOn(service, 'getWorkspaceFixedStoragePerUser')
.mockResolvedValueOnce(50000);

await service.setupWorkspace(owner, 'workspace-id', {
name: 'Test Workspace',
encryptedMnemonic: 'encryptedMnemonic',
Expand Down Expand Up @@ -568,27 +579,34 @@ describe('WorkspacesUsecases', () => {
});

describe('isWorkspaceFull', () => {
const workspaceId = 'workspace-id';
it('When workspace has slots left, then workspace is not full', async () => {
const notFullWorkspace = newWorkspace({
attributes: { numberOfSeats: 10 },
});

jest
.spyOn(workspaceRepository, 'getWorkspaceUsersCount')
.mockResolvedValue(5);
jest
.spyOn(workspaceRepository, 'getWorkspaceInvitationsCount')
.mockResolvedValue(4);

const isFull = await service.isWorkspaceFull(workspaceId);
const isFull = await service.isWorkspaceFull(notFullWorkspace);
expect(isFull).toBe(false);
});
it('When workspace does not have slots left, then workspace is full', async () => {
const fullWorkspace = newWorkspace({
attributes: { numberOfSeats: 10 },
});

jest
.spyOn(workspaceRepository, 'getWorkspaceUsersCount')
.mockResolvedValue(10);
jest
.spyOn(workspaceRepository, 'getWorkspaceInvitationsCount')
.mockResolvedValue(0);

const isFull = await service.isWorkspaceFull(workspaceId);
const isFull = await service.isWorkspaceFull(fullWorkspace);
expect(isFull).toBe(true);
});
});
Expand Down Expand Up @@ -1347,15 +1365,15 @@ describe('WorkspacesUsecases', () => {
jest
.spyOn(workspaceRepository, 'getTotalSpaceLimitInWorkspaceUsers')
.mockResolvedValue(500000);
jest
/* jest
.spyOn(workspaceRepository, 'getSpaceLimitInInvitations')
.mockResolvedValue(200000);
.mockResolvedValue(200000); */

const assignableSpace = await service.getAssignableSpaceInWorkspace(
workspace,
workspaceDefaultUser,
);
expect(assignableSpace).toBe(300000);
expect(assignableSpace).toBe(500000);
});
});

Expand Down Expand Up @@ -3188,7 +3206,7 @@ describe('WorkspacesUsecases', () => {
describe('initiateWorkspace', () => {
const owner = newUser();
const maxSpaceBytes = 1000000;
const workspaceData = { address: '123 Main St' };
const workspaceData = { address: '123 Main St', numberOfSeats: 20 };

it('When owner does not exist, then it should throw', async () => {
jest.spyOn(userRepository, 'findByUuid').mockResolvedValueOnce(null);
Expand Down
Loading

0 comments on commit 4b2c5f0

Please sign in to comment.