Skip to content
This repository has been archived by the owner on Jan 22, 2023. It is now read-only.

[SOUL-72] Remove user handle and platform name handle form DB #170

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion factories/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export const platformEntity = Factory.define<
return {
id: sequence,
name: `TEST_PLATFORM_${sequence}`,
nameHandle: `test_platform_${sequence}#${sequence}`,
createdAt: new Date('1995-12-17T03:24:00'),
updatedAt: new Date('1995-12-18T03:24:00'),
isVerified: true,
Expand Down
1 change: 0 additions & 1 deletion factories/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const userEntity = Factory.define<User>(({ sequence }) => {
return {
id: sequence,
username: `test-user-${sequence}`,
userHandle: `test-user-${sequence}#${sequence}`,
email: `TEST_USER_${sequence}@EMAIL.COM`,
isActive: true,
createdAt: new Date('1995-12-17T03:24:00'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
Warnings:

- You are about to drop the column `name_handle` on the `platforms` table. All the data in the column will be lost.
- You are about to drop the column `user_handle` on the `users` table. All the data in the column will be lost.

*/
-- DropIndex
DROP INDEX `IDX_9a4647eddfb970ff1db96fd2e5` ON `platforms`;

-- DropIndex
DROP INDEX `IDX_7408d3a73b446527a875a312d4` ON `users`;

-- AlterTable
ALTER TABLE `platforms` DROP COLUMN `name_handle`;

-- AlterTable
ALTER TABLE `users` DROP COLUMN `user_handle`;
2 changes: 0 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ model PlatformUser {
model Platform {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
nameHandle String? @unique(map: "IDX_9a4647eddfb970ff1db96fd2e5") @map("name_handle") @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(6)
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamp(6)
isVerified Boolean @default(false) @map("is_verified") @db.TinyInt
Expand Down Expand Up @@ -88,7 +87,6 @@ model UserConnection {
model User {
id Int @id @default(autoincrement())
username String @unique(map: "IDX_fe0bb3f6520ee0469504521e71") @db.VarChar(255)
userHandle String? @unique(map: "IDX_7408d3a73b446527a875a312d4") @map("user_handle") @db.VarChar(255)
email String @unique(map: "IDX_97672ac88f789774dd47f7c8be") @db.VarChar(255)
isActive Boolean @default(false) @map("is_active") @db.TinyInt
hashedPassword String @map("hashed_password") @db.VarChar(255)
Expand Down
6 changes: 2 additions & 4 deletions src/activity/activity.processor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ describe(ActivityProcessor, () => {
const fromUser = factories.userEntity.build({
id: 1,
username: 'FROM_USER',
userHandle: 'FROM_USER#1',
});
const toUser = factories.userEntity.build({
id: 2,
username: 'TO_USER',
userHandle: 'TO_USER#2',
});

beforeEach(async () => {
Expand Down Expand Up @@ -63,14 +61,14 @@ describe(ActivityProcessor, () => {
from_user: {
id: fromUser.id,
username: fromUser.username,
user_handle: fromUser.userHandle,
user_handle: expect.any(String),
bio: fromUser.bio,
display_name: fromUser.displayName,
},
to_user: {
id: toUser.id,
username: toUser.username,
user_handle: toUser.userHandle,
user_handle: expect.any(String),
bio: toUser.bio,
display_name: toUser.displayName,
},
Expand Down
12 changes: 2 additions & 10 deletions src/activity/activity.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@ describe(ActivityService, () => {
describe('sendFollowActivity()', () => {
it('sends follow activity', async () => {
const fromUser = factories.userEntity.build();
const toUser = factories.userEntity.build({
id: 2,
username: 'TO_USER',
userHandle: 'TO_USER#2',
});
const toUser = factories.userEntity.build({ id: 2, username: 'TO_USER' });
const result = await service.sendFollowActivity({ fromUser, toUser });
expect(result).toBe(true);

Expand All @@ -49,11 +45,7 @@ describe(ActivityService, () => {
addToQueue.mockRejectedValueOnce(new Error('TEST_ERROR'));
const result = await service.sendFollowActivity({
fromUser: factories.userEntity.build(),
toUser: factories.userEntity.build({
id: 2,
username: 'TO_USER',
userHandle: 'TO_USER#2',
}),
toUser: factories.userEntity.build({ id: 2, username: 'TO_USER' }),
});
expect(result).toBe(false);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ describe('PlatformsService - Users', () => {
async () => await service.findOnePlatformUser(platform.id, user.id),
).rejects.toThrow(
new PlatformUserNotFoundException({
username: user.userHandle,
platformName: platform.nameHandle,
username: user.username,
platformName: platform.name,
}),
);
});
Expand Down
40 changes: 23 additions & 17 deletions src/platforms/platforms.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { PrismaService } from 'src/prisma/prisma.service';

import * as api from './serializers/api.dto';
import * as exceptions from './exceptions';
import { FindAllPlatformResponseEntity } from './serializers/api-responses.entity';
import {
CreatePlatformResponseEntity,
FindAllPlatformResponseEntity,
} from './serializers/api-responses.entity';

const NUM_ADMIN_ROLES_ALLOWED_PER_USER = 5;

Expand All @@ -19,7 +22,10 @@ export class PlatformsService {
private prismaService: PrismaService,
) {}

async create(createPlatformDto: api.CreatePlatformDto, userId: number) {
async create(
createPlatformDto: api.CreatePlatformDto,
userId: number,
): Promise<CreatePlatformResponseEntity> {
await this.isNewAdminPermittedOrThrow(userId);

// TODO: Should wrap entire operation in transaction
Expand All @@ -37,24 +43,18 @@ export class PlatformsService {
},
});

const updatedPlatform = await this.prismaService.platform.update({
where: { id: savedPlatform.id },
data: {
nameHandle: this.getPlatformHandle(
createPlatformDto.name,
savedPlatform.id,
),
},
});

await this.prismaService.platformUser.create({
data: {
platformId: updatedPlatform.id,
platformId: savedPlatform.id,
userId: userId,
roles: [UserRole.Admin, UserRole.Member],
},
});
return updatedPlatform;
return {
...savedPlatform,
nameHandle: this.getPlatformHandle(savedPlatform.name, savedPlatform.id),
redirectUris: savedPlatform.redirectUris as string[],
};
}

async findAll(queryParams: api.FindAllPlatformsQueryParamDto) {
Expand Down Expand Up @@ -109,7 +109,13 @@ export class PlatformsService {
});

return {
platforms: platformUsers.map((platformUser) => platformUser.platform),
platforms: platformUsers.map((platformUser) => ({
...platformUser.platform,
nameHandle: this.getPlatformHandle(
platformUser.platform.name,
platformUser.platformId,
),
})),
totalCount,
};
}
Expand Down Expand Up @@ -275,8 +281,8 @@ export class PlatformsService {

if (!platformUser)
throw new exceptions.PlatformUserNotFoundException({
platformName: platform.nameHandle,
username: user.userHandle,
platformName: platform.name,
username: user.username,
});

return platformUser;
Expand Down
51 changes: 33 additions & 18 deletions src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import {
DuplicateUsernameException,
DuplicateUserEmailException,
} from './exceptions';
import {
CreateUserResponseEntity,
FindAllUserResponseEntity,
UpdateUserResponseEntity,
} from './serializers/api-responses.entity';

@Injectable()
export class UsersService {
Expand All @@ -32,7 +37,9 @@ export class UsersService {
private prismaService: PrismaService,
) {}

async create(createUserDto: CreateUserDto): Promise<User> {
async create(
createUserDto: CreateUserDto,
): Promise<CreateUserResponseEntity> {
const hashedPassword = await bcrypt.hash(
createUserDto.password,
await bcrypt.genSalt(),
Expand All @@ -43,7 +50,6 @@ export class UsersService {
username: createUserDto.username,
});

// TODO: Should be wrapped in a transaction
const savedUser = await this.prismaService.user.create({
data: {
hashedPassword,
Expand All @@ -55,19 +61,17 @@ export class UsersService {
},
});

const updatedUser = await this.prismaService.user.update({
where: { id: savedUser.id },
data: {
userHandle: this.getUserHandle(savedUser.username, savedUser.id),
},
});

await this.generateCodeAndSendEmail(savedUser, 'confirmation');

return updatedUser;
return {
...savedUser,
userHandle: this.getUserHandle(savedUser.username, savedUser.id),
};
}

async findAll(queryParams: FindAllUsersQueryParamDto) {
async findAll(
queryParams: FindAllUsersQueryParamDto,
): Promise<FindAllUserResponseEntity> {
const query = queryParams.q;
const users = await this.prismaService.user.findMany({
skip: (queryParams.page - 1) * queryParams.numItemsPerPage,
Expand All @@ -83,13 +87,19 @@ export class UsersService {
},
});

return { users, totalCount };
return {
users: users.map((user) => ({
...user,
userHandle: this.getUserHandle(user.username, user.id),
})),
totalCount,
};
}

async findOne(id: number) {
const user = await this.prismaService.user.findUnique({ where: { id } });
if (!user) throw new UserNotFoundException({ id });
return user;
return { ...user, userHandle: this.getUserHandle(user.username, user.id) };
}

async findOneByEmail(email: string) {
Expand All @@ -100,7 +110,10 @@ export class UsersService {
return user;
}

async update(id: number, updateUserDto: UpdateUserDto) {
async update(
id: number,
updateUserDto: UpdateUserDto,
): Promise<UpdateUserResponseEntity> {
const user = await this.findOne(id);

await this.throwOnDuplicate({
Expand All @@ -109,18 +122,20 @@ export class UsersService {
id,
});

return await this.prismaService.user.update({
const updatedUser = await this.prismaService.user.update({
where: { id: user.id },
data: {
bio: updateUserDto.bio,
displayName: updateUserDto.displayName,
username: updateUserDto.username,
email: updateUserDto.email,
...(updateUserDto.username && {
userHandle: this.getUserHandle(updateUserDto.username, user.id),
}),
},
});

return {
...updatedUser,
userHandle: this.getUserHandle(updatedUser.username, updatedUser.id),
};
}

async remove(id: number) {
Expand Down
4 changes: 0 additions & 4 deletions test-e2e/platform.e2e-spec/platforms.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ describe('PlatformsController (e2e)', () => {
factories.platformEntity.build({
id: 2,
name: 'TEST_PLATFORM_2',
nameHandle: 'test_platform_2#2',
isVerified: false,
platformCategoryId: null,
}),
Expand Down Expand Up @@ -305,14 +304,12 @@ describe('PlatformsController (e2e)', () => {
const platformTwo = factories.platformEntity.build({
id: 2,
name: 'TEST_PLATFORM_2',
nameHandle: 'test_platform_2#2',
isVerified: false,
platformCategoryId: null,
});
const platformThree = factories.platformEntity.build({
id: 3,
name: 'TEST_PLATFORM_3',
nameHandle: 'TEST_PLATFORM_3#3',
isVerified: false,
platformCategoryId: null,
});
Expand Down Expand Up @@ -489,7 +486,6 @@ describe('PlatformsController (e2e)', () => {
const adminPlatform = factories.platformEntity.build({
id: 2,
name: 'ADMIN_PLATFORM',
nameHandle: 'admin_platform#2',
isVerified: false,
platformCategoryId: null,
redirectUris: ['https://www.example.com'],
Expand Down