Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

105 implement saving user to database #106

Merged
merged 18 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
8 changes: 5 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ name: CI

on:
push:
branches: [main]
branches:
- 'main'
- '*/*'
pull_request:
branches: [main]

branches:
- '**'
workflow_dispatch:

jobs:
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
"test:e2e:watch": "jest --config jest-e2e.config.ts --watch",
"stryker": "stryker run",
"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli",
"migration:run": "npm run typeorm -- migration:run -d ./src/config/typeorm.config.ts",
"migration:generate": "npm run typeorm -- migration:generate -d ./src/config/typeorm.config.ts ./src/migrations/migration",
"migration:run": "npm run typeorm -- migration:run -d ./src/config/database/typeorm.config.ts",
"migration:generate": "npm run typeorm -- migration:generate -d ./src/config/database/typeorm.config.ts ./src/migrations/migration",
"migration:create": "npm run typeorm -- migration:create ./src/migrations/migration",
"migration:revert": "npm run typeorm -- migration:revert -d ./src/config/typeorm.config.ts",
"migration:revert": "npm run typeorm -- migration:revert -d ./src/config/database/typeorm.config.ts",
"prepare": "husky install"
},
"sideEffects": false,
Expand Down
6 changes: 6 additions & 0 deletions src/common/adapters/profile.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export const adaptProfile = ({
email,
images,
country,
product,
type,
uri,
external_urls: { spotify: href },
followers,
}: SpotifyProfile): FormattedProfile => ({
Expand All @@ -15,5 +18,8 @@ export const adaptProfile = ({
images,
country,
href,
product,
type,
uri,
followers: followers.total,
})
20 changes: 20 additions & 0 deletions src/common/mocks/image.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { SpotifyImage } from '../types/spotify'

import { Image } from '@modules/images'

export const spotifyImageMock: SpotifyImage = {
height: 300,
url: 'https://i.scdn.co/image/ab67616d00001e023f1900e26ff44e8821bd8350',
width: 300,
}

export const imageMock: Image = {
id: '123',
...spotifyImageMock,
}

export const spotifyImagesMock = Array.from(
{ length: 3 },
() => spotifyImageMock
)
export const imagesMock = Array.from({ length: 3 }, () => imageMock)
2 changes: 2 additions & 0 deletions src/common/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from './playback-state.mock'
export * from './genres.mock'
export * from './audio-features.mock'
export * from './spotify-response.mock'
export * from './image.mock'
export * from './user.mock'
15 changes: 15 additions & 0 deletions src/common/mocks/profile.mock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { FormattedProfile, SpotifyProfile } from '../types/spotify'

import { imagesMock } from './image.mock'

import { Profile } from '@modules/profiles'

export const spotifyProfileMock: SpotifyProfile = {
country: 'US',
display_name: 'Spotify User',
Expand Down Expand Up @@ -46,6 +50,9 @@ export const formattedProfileMock: FormattedProfile = {
displayName: 'Spotify User',
email: '[email protected]',
followers: 0,
product: 'premium',
type: 'user',
uri: 'spotify:user:spotify-user',
id: 'spotify-user',
href: 'https://open.spotify.com/user/spotify-user',
images: [
Expand All @@ -66,3 +73,11 @@ export const formattedProfileMock: FormattedProfile = {
},
],
}

export const profileMock: Profile = {
...formattedProfileMock,
id: '1',
images: imagesMock,
}

export const profilesMock = Array.from({ length: 3 }, () => profileMock)
11 changes: 11 additions & 0 deletions src/common/mocks/user.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { profileMock } from './profile.mock'

import { User } from '@modules/users'

export const userMock: User = {
id: '1',
refreshToken: 'refreshToken',
profile: profileMock,
}

export const usersMock = Array.from({ length: 3 }, () => userMock)
3 changes: 3 additions & 0 deletions src/common/types/spotify/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export interface FormattedProfile {
country?: string
email?: string
href: string
product?: string
type: string
uri: string
}

export interface SpotifyProfile {
Expand Down
7 changes: 5 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { NestFactory } from '@nestjs/core'
import { NestFactory, Reflector } from '@nestjs/core'
import { ConfigService } from '@nestjs/config'
import cookieParser from 'cookie-parser'
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'

import { Environment } from '@config/environment'
import { AppModule } from '@modules/app'
Expand All @@ -10,6 +11,7 @@ import { BEARER } from '@modules/auth/constants'

async function bootstrap() {
const app = await NestFactory.create(AppModule)
const reflector = app.get(Reflector)
const configService = app.get(ConfigService)

const documentConfig = new DocumentBuilder()
Expand Down Expand Up @@ -42,8 +44,9 @@ async function bootstrap() {
credentials: true,
})
app.use(cookieParser())
app.useGlobalPipes(new ValidationPipe())
app.useGlobalInterceptors(new ClassSerializerInterceptor(reflector))

await app.startAllMicroservices()
await app.listen(+configService.get(Environment.PORT) || 4000)
}
bootstrap()
51 changes: 51 additions & 0 deletions src/migrations/1697539455661-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class Migration1697539455661 implements MigrationInterface {
name = 'Migration1697539455661'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "image" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "height" integer NOT NULL, "width" integer NOT NULL, "url" character varying NOT NULL, CONSTRAINT "PK_d6db1ab4ee9ad9dbe86c64e4cc3" PRIMARY KEY ("id"))`
)
await queryRunner.query(
`CREATE TABLE "profile" ("id" character varying NOT NULL, "displayName" character varying NOT NULL, "followers" integer NOT NULL, "country" character varying, "email" character varying, "href" character varying NOT NULL, "product" character varying, "type" character varying NOT NULL, "uri" character varying NOT NULL, CONSTRAINT "PK_3dd8bfc97e4a77c70971591bdcb" PRIMARY KEY ("id"))`
)
await queryRunner.query(
`CREATE TABLE "user" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "refreshToken" character varying NOT NULL, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`
)
await queryRunner.query(
`CREATE TABLE "profile_images_image" ("profileId" character varying NOT NULL, "imageId" uuid NOT NULL, CONSTRAINT "PK_b41ff6ac84d6b21bbb4164b913a" PRIMARY KEY ("profileId", "imageId"))`
)
await queryRunner.query(
`CREATE INDEX "IDX_8520f204d1054799bbcb21023d" ON "profile_images_image" ("profileId") `
)
await queryRunner.query(
`CREATE INDEX "IDX_baf570df58dbd868515e33fc25" ON "profile_images_image" ("imageId") `
)
await queryRunner.query(
`ALTER TABLE "profile_images_image" ADD CONSTRAINT "FK_8520f204d1054799bbcb21023dd" FOREIGN KEY ("profileId") REFERENCES "profile"("id") ON DELETE CASCADE ON UPDATE CASCADE`
)
await queryRunner.query(
`ALTER TABLE "profile_images_image" ADD CONSTRAINT "FK_baf570df58dbd868515e33fc252" FOREIGN KEY ("imageId") REFERENCES "image"("id") ON DELETE CASCADE ON UPDATE CASCADE`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "profile_images_image" DROP CONSTRAINT "FK_baf570df58dbd868515e33fc252"`
)
await queryRunner.query(
`ALTER TABLE "profile_images_image" DROP CONSTRAINT "FK_8520f204d1054799bbcb21023dd"`
)
await queryRunner.query(
`DROP INDEX "public"."IDX_baf570df58dbd868515e33fc25"`
)
await queryRunner.query(
`DROP INDEX "public"."IDX_8520f204d1054799bbcb21023d"`
)
await queryRunner.query(`DROP TABLE "profile_images_image"`)
await queryRunner.query(`DROP TABLE "user"`)
await queryRunner.query(`DROP TABLE "profile"`)
await queryRunner.query(`DROP TABLE "image"`)
}
}
8 changes: 7 additions & 1 deletion src/modules/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ import { ConfigModule, ConfigService } from '@nestjs/config'
import { TypeOrmModule } from '@nestjs/typeorm'

import { environmentSchema } from '@config/environment'
import { typeorm } from '@config/database'
import { AuthModule } from '@modules/auth'
import { StatisticsModule } from '@modules/statistics'
import { PlayerModule } from '@modules/player'
import { typeorm } from '@config/database'
import { ImagesModule } from '@modules/images'
import { ProfilesModule } from '@modules/profiles'
import { UsersModule } from '@modules/users'

@Module({
imports: [
AuthModule,
StatisticsModule,
PlayerModule,
ImagesModule,
ProfilesModule,
UsersModule,
ConfigModule.forRoot({
isGlobal: true,
envFilePath: './.env',
Expand Down
Loading
Loading