Skip to content

Commit

Permalink
refactor(modules/artists): remove deprecated methods from `repository…
Browse files Browse the repository at this point in the history
…` and implement overloads in `service`
  • Loading branch information
Mnigos committed Apr 4, 2024
1 parent 0e68177 commit db3d199
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 294 deletions.
162 changes: 14 additions & 148 deletions src/modules/artists/artists.repository.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ import { Test } from '@nestjs/testing'

import { ArtistsRepository } from './artists.repository'

import { ImagesRepository } from '@modules/images'
import {
artistEntitiesMock,
artistEntityMock,
artistMock,
imagesMock,
sdkArtistMock,
sdkArtistsMock,
} from '@common/mocks'
import { SpotifyArtistsService } from '@modules/spotify/artists'

describe('ArtistsRepository', () => {
let artistsRepository: ArtistsRepository
let imagesRepository: ImagesRepository
let spotifyArtistsService: SpotifyArtistsService

beforeEach(async () => {
const module = await Test.createTestingModule({
Expand All @@ -29,25 +24,10 @@ describe('ArtistsRepository', () => {
createEntityManager: vi.fn(),
},
},
{
provide: ImagesRepository,
useValue: {
findOrCreateImages: vi.fn(),
},
},
{
provide: SpotifyArtistsService,
useValue: {
getArtist: vi.fn(),
getArtists: vi.fn(),
},
},
],
}).compile()

artistsRepository = module.get(ArtistsRepository)
imagesRepository = module.get(ImagesRepository)
spotifyArtistsService = module.get(SpotifyArtistsService)
})

test('should be defined', () => {
Expand All @@ -60,6 +40,7 @@ describe('ArtistsRepository', () => {
.mockResolvedValue(artistEntitiesMock)

expect(await artistsRepository.findArtists()).toEqual(artistEntitiesMock)

expect(findSpy).toHaveBeenCalled()
})

Expand All @@ -71,6 +52,7 @@ describe('ArtistsRepository', () => {
expect(
await artistsRepository.findArtistByExternalId(artistMock.id)
).toEqual(artistEntityMock)

expect(findOneSpy).toHaveBeenCalledWith({
where: { externalId: artistMock.id },
})
Expand All @@ -84,6 +66,7 @@ describe('ArtistsRepository', () => {
expect(await artistsRepository.findArtistById(artistMock.id)).toEqual(
artistEntityMock
)

expect(findOneSpy).toHaveBeenCalledWith({
where: { id: artistMock.id },
})
Expand All @@ -97,6 +80,7 @@ describe('ArtistsRepository', () => {
expect(await artistsRepository.findArtistByName(artistMock.name)).toEqual(
artistEntityMock
)

expect(findOneSpy).toHaveBeenCalledWith({
where: { name: artistMock.name },
})
Expand All @@ -110,148 +94,30 @@ describe('ArtistsRepository', () => {
expect(
await artistsRepository.findArtistsByExternalIds([artistMock.id])
).toEqual(artistEntitiesMock)

expect(findSpy).toHaveBeenCalledWith({
where: { externalId: In([artistMock.id]) },
})
})

test('should create artist', async () => {
const createImageSpy = vi
.spyOn(imagesRepository, 'findOrCreateImages')
.mockResolvedValue(imagesMock)
const createSpy = vi
.spyOn(artistsRepository, 'create')
.mockReturnValue(artistEntityMock)
const saveSpy = vi
.spyOn(artistsRepository, 'save')
.mockResolvedValue(artistEntityMock)

expect(await artistsRepository.createArtist(sdkArtistMock)).toEqual(
artistEntityMock
)
expect(createImageSpy).toHaveBeenCalledWith(imagesMock)
expect(
await artistsRepository.createArtist({
...sdkArtistMock,
externalId: sdkArtistMock.id,
followers: sdkArtistMock.followers.total,
images: imagesMock,
})
).toEqual(artistEntityMock)

expect(createSpy).toHaveBeenCalled()
expect(saveSpy).toHaveBeenCalledWith(artistEntityMock)
})

describe('findOrCreateArtist', () => {
test('should find artist', async () => {
const findArtistByExternalId = vi
.spyOn(artistsRepository, 'findArtistByExternalId')
.mockResolvedValue(artistEntityMock)
const createArtistSpy = vi.spyOn(artistsRepository, 'createArtist')

expect(await artistsRepository.findOrCreateArtist(sdkArtistMock)).toEqual(
artistEntityMock
)
expect(findArtistByExternalId).toHaveBeenCalledWith(sdkArtistMock.id)
expect(createArtistSpy).not.toHaveBeenCalled()
})

test('should create artist', async () => {
const findArtistByExternalId = vi
.spyOn(artistsRepository, 'findArtistByExternalId')
.mockResolvedValue(null)
const createArtistSpy = vi
.spyOn(artistsRepository, 'createArtist')
.mockResolvedValue(artistEntityMock)

expect(await artistsRepository.findOrCreateArtist(sdkArtistMock)).toEqual(
artistEntityMock
)
expect(findArtistByExternalId).toHaveBeenCalledWith(sdkArtistMock.id)
expect(createArtistSpy).toHaveBeenCalledWith(sdkArtistMock)
})
})

test('should find or create artists', async () => {
const findOrCreateArtistSpy = vi
.spyOn(artistsRepository, 'findOrCreateArtist')
.mockResolvedValue(artistEntityMock)

expect(await artistsRepository.findOrCreateArtists(sdkArtistsMock)).toEqual(
artistEntitiesMock
)
expect(findOrCreateArtistSpy).toHaveBeenCalledWith(sdkArtistMock)
})

describe('findOrCreateArtistByExternalId', () => {
test('should find artist by id', async () => {
const findArtistByExternalId = vi
.spyOn(artistsRepository, 'findArtistByExternalId')
.mockResolvedValue(artistEntityMock)
const getArtistSpy = vi
.spyOn(spotifyArtistsService, 'getArtist')
.mockResolvedValue(sdkArtistMock)
const createArtistSpy = vi.spyOn(artistsRepository, 'createArtist')

expect(
await artistsRepository.findOrCreateArtistFromExternalId(
sdkArtistMock.id
)
).toEqual(artistEntityMock)
expect(findArtistByExternalId).toHaveBeenCalledWith(sdkArtistMock.id)
expect(getArtistSpy).not.toHaveBeenCalled()
expect(createArtistSpy).not.toHaveBeenCalled()
})

test('should create artist by id', async () => {
const findArtistByExternalId = vi
.spyOn(artistsRepository, 'findArtistByExternalId')
.mockResolvedValue(null)
const getArtistSpy = vi
.spyOn(spotifyArtistsService, 'getArtist')
.mockResolvedValue(sdkArtistMock)
const createArtistSpy = vi
.spyOn(artistsRepository, 'createArtist')
.mockResolvedValue(artistEntityMock)

expect(
await artistsRepository.findOrCreateArtistFromExternalId(
sdkArtistMock.id
)
).toEqual(artistEntityMock)
expect(findArtistByExternalId).toHaveBeenCalledWith(sdkArtistMock.id)
expect(getArtistSpy).toHaveBeenCalledWith(sdkArtistMock.id, false)
expect(createArtistSpy).toHaveBeenCalledWith(sdkArtistMock)
})
})

describe('findOrCreateArtistsByExternalIds', () => {
const ids = sdkArtistsMock.map(artist => artist.id)

test('should find artists by external ids', async () => {
const findArtistsByExternalIds = vi
.spyOn(artistsRepository, 'findArtistsByExternalIds')
.mockResolvedValue(artistEntitiesMock)
const getArtistsSpy = vi.spyOn(spotifyArtistsService, 'getArtists')
const createArtistSpy = vi.spyOn(artistsRepository, 'createArtist')

expect(
await artistsRepository.findOrCreateArtistsFromExternalIds(ids)
).toEqual(artistEntitiesMock)
expect(findArtistsByExternalIds).toHaveBeenCalledWith(ids)
expect(createArtistSpy).not.toHaveBeenCalled()
expect(getArtistsSpy).not.toHaveBeenCalled()
})

test('should create artists by external ids', async () => {
const findArtistsByExternalIds = vi
.spyOn(artistsRepository, 'findArtistsByExternalIds')
.mockResolvedValue([])
const getArtistsSpy = vi
.spyOn(spotifyArtistsService, 'getArtists')
.mockResolvedValue(sdkArtistsMock)
const createArtistSpy = vi
.spyOn(artistsRepository, 'createArtist')
.mockResolvedValue(artistEntityMock)

expect(
await artistsRepository.findOrCreateArtistsFromExternalIds(ids)
).toEqual(artistEntitiesMock)
expect(findArtistsByExternalIds).toHaveBeenCalledWith(ids)
expect(getArtistsSpy).toHaveBeenCalledWith(ids, false)
expect(createArtistSpy).toHaveBeenCalledWith(sdkArtistMock)
})
})
})
76 changes: 3 additions & 73 deletions src/modules/artists/artists.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,9 @@ import { Injectable } from '@nestjs/common'
import { Artist } from './artist.entity'
import { CreateArtist } from './dtos'

import { ImagesRepository } from '@modules/images'
import { SpotifyArtistsService } from '@modules/spotify/artists'

@Injectable()
export class ArtistsRepository extends Repository<Artist> {
constructor(
private readonly dataSource: DataSource,
private readonly imagesRepository: ImagesRepository,
private readonly spotifyArtistsService: SpotifyArtistsService
) {
constructor(private readonly dataSource: DataSource) {
super(Artist, dataSource.createEntityManager())
}

Expand All @@ -37,72 +30,9 @@ export class ArtistsRepository extends Repository<Artist> {
return this.find({ where: { externalId: In(externalIds) } })
}

async createArtist({
images,
id,
followers,
external_urls: { spotify: href },
...newArtist
}: CreateArtist) {
const imageEntities = await this.imagesRepository.findOrCreateImages(images)

const artistEntity = this.create({
...newArtist,
href,
followers: followers?.total ?? 0,
externalId: id,
images: imageEntities,
})
async createArtist(artistToCreate: CreateArtist) {
const artistEntity = this.create(artistToCreate)

return this.save(artistEntity)
}

async findOrCreateArtist(artistToCreate: CreateArtist) {
const foundArtist = await this.findArtistByExternalId(artistToCreate.id)

if (foundArtist) return foundArtist

return this.createArtist(artistToCreate)
}

findOrCreateArtists(artistsToCreate: CreateArtist[]) {
return Promise.all(
artistsToCreate.map(newArtist => this.findOrCreateArtist(newArtist))
)
}

async findOrCreateArtistFromExternalId(externalId: string) {
const foundArtist = await this.findArtistByExternalId(externalId)

if (foundArtist) return foundArtist

const artistToCreate = await this.spotifyArtistsService.getArtist(
externalId,
false
)

return this.createArtist(artistToCreate)
}

async findOrCreateArtistsFromExternalIds(externalIds: string[]) {
const foundArtists = await this.findArtistsByExternalIds(externalIds)

const artistIdsToCreate = externalIds.filter(
externalId =>
!foundArtists.some(artist => artist.externalId === externalId)
)

if (artistIdsToCreate.length === 0) return foundArtists

const artistsToCreate = await this.spotifyArtistsService.getArtists(
artistIdsToCreate,
false
)

const newArtists = await Promise.all(
artistsToCreate.map(artist => this.createArtist(artist))
)

return [...foundArtists, ...newArtists]
}
}
Loading

0 comments on commit db3d199

Please sign in to comment.