Feature/adc/#50 users settings route (#89)

* #50 - migration 20221023123919_ + route settings

* #50 - migration 20221023123919_ + route settings

* #50 - settings creation at user creation + update migration

* changed settings acces from by id to userId

* deleting the user results in deleting it's associated userSettings row

* pr fixes + robot tests + other minor fixes

* removed useless comments

* added settings endpoint to /auth/me and automated creation to /register

* clean code before merge
This commit is contained in:
Amaury
2023-04-12 05:32:41 +03:00
committed by GitHub
parent e43a8fd111
commit a26efefd01
15 changed files with 278 additions and 16 deletions
+2 -3
View File
@@ -7,13 +7,11 @@ import { PrismaModule } from './prisma/prisma.module';
import { AuthModule } from './auth/auth.module';
import { SongModule } from './song/song.module';
import { LessonModule } from './lesson/lesson.module';
import { ArtistController } from './artist/artist.controller';
import { SettingsModule } from './settings/settings.module';
import { ArtistService } from './artist/artist.service';
import { GenreModule } from './genre/genre.module';
import { ArtistModule } from './artist/artist.module';
import { AlbumModule } from './album/album.module';
import { SearchController } from './search/search.controller';
import { SearchService } from './search/search.service';
import { SearchModule } from './search/search.module';
import { HistoryModule } from './history/history.module';
@@ -28,6 +26,7 @@ import { HistoryModule } from './history/history.module';
ArtistModule,
AlbumModule,
SearchModule,
SettingsModule,
HistoryModule,
],
controllers: [AppController],
+34 -1
View File
@@ -10,6 +10,8 @@ import {
HttpCode,
Put,
InternalServerErrorException,
Patch,
NotFoundException,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtAuthGuard } from './jwt-auth.guard';
@@ -28,6 +30,9 @@ import { User } from '../models/user';
import { JwtToken } from './models/jwt';
import { LoginDto } from './dto/login.dto';
import { Profile } from './dto/profile.dto';
import { Setting } from 'src/models/setting';
import { UpdateSettingDto } from 'src/settings/dto/update-setting.dto';
import { SettingsService } from 'src/settings/settings.service';
@ApiTags('auth')
@Controller('auth')
@@ -35,12 +40,15 @@ export class AuthController {
constructor(
private authService: AuthService,
private usersService: UsersService,
private settingsService: SettingsService,
) {}
@Post('register')
async register(@Body() registerDto: RegisterDto): Promise<void> {
try {
await this.usersService.createUser(registerDto);
await this.usersService.createUser(registerDto).then((user) => {
this.settingsService.createUserSetting(user.id);
});
} catch {
throw new BadRequestException();
}
@@ -105,4 +113,29 @@ export class AuthController {
deleteSelf(@Request() req: any): Promise<User> {
return this.usersService.deleteUser({ id: req.user.id });
}
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({description: 'Successfully edited settings', type: Setting})
@ApiUnauthorizedResponse({description: 'Invalid token'})
@Patch('me/settings')
udpateSettings(
@Request() req: any,
@Body() settingUserDto: UpdateSettingDto): Promise<Setting> {
return this.settingsService.updateUserSettings({
where: { userId: +req.user.id},
data: settingUserDto,
});
}
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({description: 'Successfully edited settings', type: Setting})
@ApiUnauthorizedResponse({description: 'Invalid token'})
@Get('me/settings')
async getSettings(@Request() req: any): Promise<Setting> {
const result = await this.settingsService.getUserSetting({ userId: +req.user.id });
if (!result) throw new NotFoundException();
return result;
}
}
+2
View File
@@ -8,11 +8,13 @@ import { JwtModule } from '@nestjs/jwt';
import { ConfigModule } from '@nestjs/config';
import { ConfigService } from '@nestjs/config';
import { JwtStrategy } from './jwt.strategy';
import { SettingsModule } from 'src/settings/settings.module';
@Module({
imports: [
ConfigModule,
UsersModule,
SettingsModule,
PassportModule,
JwtModule.registerAsync({
imports: [ConfigModule],
+24
View File
@@ -0,0 +1,24 @@
import { ApiProperty } from '@nestjs/swagger';
export class Setting {
@ApiProperty()
id: number;
@ApiProperty()
userId: number;
@ApiProperty()
pushNotification: boolean;
@ApiProperty()
emailNotification: boolean;
@ApiProperty()
trainingNotification: boolean;
@ApiProperty()
newSongNotification: boolean;
@ApiProperty()
recommendations: boolean;
@ApiProperty()
weeklyReport: boolean;
@ApiProperty()
leaderBoard: boolean;
@ApiProperty()
showActivity: boolean;
}
@@ -0,0 +1,20 @@
import { ApiProperty } from '@nestjs/swagger';
export class UpdateSettingDto {
@ApiProperty()
pushNotification?: boolean;
@ApiProperty()
emailNotification?: boolean;
@ApiProperty()
trainingNotification?: boolean;
@ApiProperty()
newSongNotification?: boolean;
@ApiProperty()
recommendations?: boolean;
@ApiProperty()
weeklyReport?: boolean;
@ApiProperty()
leaderBoard?: boolean;
@ApiProperty()
showActivity?: boolean;
}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SettingsController } from './settings.controller';
describe('SettingsController', () => {
let controller: SettingsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [SettingsController],
}).compile();
controller = module.get<SettingsController>(SettingsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
+10
View File
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { SettingsService } from './settings.service';
import { PrismaModule } from 'src/prisma/prisma.module';
@Module({
imports: [PrismaModule],
providers: [SettingsService],
exports: [SettingsService],
})
export class SettingsModule {}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SettingsService } from './settings.service';
describe('SettingsService', () => {
let service: SettingsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [SettingsService],
}).compile();
service = module.get<SettingsService>(SettingsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
+45
View File
@@ -0,0 +1,45 @@
import { Injectable } from '@nestjs/common';
import { Prisma, UserSettings } from '@prisma/client';
import { PrismaService } from 'src/prisma/prisma.service';
@Injectable()
export class SettingsService {
constructor(private prisma: PrismaService) {}
async getUserSetting(
settingWhereUniqueInput: Prisma.UserSettingsWhereUniqueInput,
): Promise<UserSettings | null> {
return this.prisma.userSettings.findUnique({
where: settingWhereUniqueInput,
});
}
async createUserSetting(userId: number): Promise<UserSettings> {
return this.prisma.userSettings.create({
data: {
user: {
connect: {
id: userId,
}
}
}
})
}
async updateUserSettings(params: {
where: Prisma.UserSettingsWhereUniqueInput;
data: Prisma.UserSettingsUpdateInput;
}): Promise<UserSettings> {
const { where, data } = params;
return this.prisma.userSettings.update({
data,
where,
});
}
async deleteUserSettings(where: Prisma.UserSettingsWhereUniqueInput): Promise<UserSettings> {
return this.prisma.userSettings.delete({
where,
});
}
}
+7 -2
View File
@@ -8,18 +8,23 @@ import {
NotFoundException,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { SettingsService } from 'src/settings/settings.service';
import { CreateUserDto } from './dto/create-user.dto';
import { ApiNotFoundResponse, ApiTags } from '@nestjs/swagger';
import { User } from 'src/models/user';
import { resolve } from 'path';
@ApiTags('users')
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
constructor(private readonly usersService: UsersService, private readonly settingsService: SettingsService) {}
@Post()
create(@Body() createUserDto: CreateUserDto): Promise<User> {
return this.usersService.createUser(createUserDto);
return this.usersService.createUser(createUserDto).then((user) => {
this.settingsService.createUserSetting(user.id);
return user;
}).catch((e) => e);
}
@Get()
+2 -1
View File
@@ -2,11 +2,12 @@ import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { PrismaModule } from 'src/prisma/prisma.module';
import { SettingsService } from 'src/settings/settings.service';
@Module({
imports: [PrismaModule],
controllers: [UsersController],
providers: [UsersService],
providers: [UsersService, SettingsService],
exports: [UsersService],
})
export class UsersModule {}