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

152 refator adapters #156

Merged
merged 2 commits into from
Jan 29, 2024
Merged
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
30 changes: 30 additions & 0 deletions src/common/adapters/adapters.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Global, Module } from '@nestjs/common'

import { ArtistsAdapter } from './artists.adapter'
import { AudioFeaturesAdapter } from './audio-features.adapter'
import { DevicesAdapter } from './devices.adapter'
import { GenresAdapter } from './genres.adapter'
import { PageAdapter } from './page.adapter'
import { TracksAdapter } from './tracks.adapter'
import { PlaybackStateAdapter } from './playback-state.adapter'
import { ProfileAdapter } from './profile.adapter'
import { SecretDataAdapter } from './secret-data.adapter'
import { AdaptersService } from './adapters.service'

@Global()
@Module({
providers: [
ArtistsAdapter,
TracksAdapter,
AudioFeaturesAdapter,
DevicesAdapter,
GenresAdapter,
PageAdapter,
PlaybackStateAdapter,
ProfileAdapter,
SecretDataAdapter,
AdaptersService,
],
exports: [AdaptersService],
})
export class AdaptersModule {}
26 changes: 26 additions & 0 deletions src/common/adapters/adapters.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Injectable } from '@nestjs/common'

import { AudioFeaturesAdapter } from './audio-features.adapter'
import { DevicesAdapter } from './devices.adapter'
import { GenresAdapter } from './genres.adapter'
import { PageAdapter } from './page.adapter'
import { TracksAdapter } from './tracks.adapter'
import { PlaybackStateAdapter } from './playback-state.adapter'
import { ProfileAdapter } from './profile.adapter'
import { ArtistsAdapter } from './artists.adapter'
import { SecretDataAdapter } from './secret-data.adapter'

@Injectable()
export class AdaptersService {
constructor(

Check warning on line 15 in src/common/adapters/adapters.service.ts

View check run for this annotation

Codecov / codecov/patch

src/common/adapters/adapters.service.ts#L15

Added line #L15 was not covered by tests
readonly artists: ArtistsAdapter,
readonly tracks: TracksAdapter,
readonly audioFeatures: AudioFeaturesAdapter,
readonly devices: DevicesAdapter,
readonly genres: GenresAdapter,
readonly page: PageAdapter,
readonly playbackState: PlaybackStateAdapter,
readonly profile: ProfileAdapter,
readonly secretData: SecretDataAdapter
) {}
}

Check warning on line 26 in src/common/adapters/adapters.service.ts

View check run for this annotation

Codecov / codecov/patch

src/common/adapters/adapters.service.ts#L25-L26

Added lines #L25 - L26 were not covered by tests
67 changes: 45 additions & 22 deletions src/common/adapters/artists.adapter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,54 @@
import { Test } from '@nestjs/testing'

import { ArtistsAdapter } from './artists.adapter'
import { PageAdapter } from './page.adapter'

import {
spotifyArtistMock,
artistMock,
spotifyArtistsMock,
artistsMock,
spotifyResponseWithOffsetMockFactory,
} from '../mocks'
sdkArtistMock,
pageMockFactory,
sdkSimplifiedArtistMock,
simplifiedArtistMock,
} from '@common/mocks'

import {
adaptArtist,
adaptArtists,
adaptPaginatedArtists,
} from './artists.adapter'

describe('adaptArtists', () => {
test('should adapt artist', () => {
expect(adaptArtist(spotifyArtistMock)).toEqual(artistMock)
describe('ArtistsAdapter', () => {
let artistsAdapter: ArtistsAdapter

beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [ArtistsAdapter, PageAdapter],
}).compile()

artistsAdapter = module.get(ArtistsAdapter)
})

test('should be defined', () => {
expect(artistsAdapter).toBeDefined()
})

test('should adapt a single artist', () => {
expect(artistsAdapter.adapt(sdkArtistMock)).toEqual(artistMock)
})

test('should adapt a single simplified artist', () => {
expect(artistsAdapter.adapt(sdkSimplifiedArtistMock)).toEqual(
simplifiedArtistMock
)
})

test('should adapt an array of artists', () => {
expect(artistsAdapter.adapt([sdkArtistMock])).toEqual([artistMock])
})

test('should adapt artists', () => {
expect(adaptArtists(spotifyArtistsMock)).toEqual(artistsMock)
test('should adapt an array of simplified artists', () => {
expect(artistsAdapter.adapt([sdkSimplifiedArtistMock])).toEqual([
simplifiedArtistMock,
])
})

test('should adapt paginated artists', () => {
expect(
adaptPaginatedArtists(
spotifyResponseWithOffsetMockFactory(spotifyArtistsMock)
)
).toEqual(spotifyResponseWithOffsetMockFactory(artistsMock))
test('should adapt a paginated list of artists', () => {
expect(artistsAdapter.adapt(pageMockFactory([sdkArtistMock]))).toEqual(
pageMockFactory([artistMock])
)
})
})
102 changes: 60 additions & 42 deletions src/common/adapters/artists.adapter.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,62 @@
import { Injectable } from '@nestjs/common'
import { Page } from '@spotify/web-api-ts-sdk'

import { PageAdapter } from './page.adapter'

import {
Artist,
SpotifyArtist,
SpotifyResponseWithOffset,
SpotifyTrackArtist,
TrackArtist,
} from '../types/spotify'

import { adaptPaginated } from './paginated.adapter'

export const adaptArtist = ({
id,
name,
genres,
external_urls: { spotify: href },
images,
}: SpotifyArtist): Artist => ({
id,
name,
genres,
href,
images,
})

export const adaptArtists = (artists: SpotifyArtist[]): Artist[] =>
artists.map(artist => adaptArtist(artist))

export const adaptTrackArtist = ({
name,
id,
external_urls: { spotify: href },
}: SpotifyTrackArtist): TrackArtist => ({
name,
id,
href,
})

export const adaptTrackArtists = (
artists: SpotifyTrackArtist[]
): TrackArtist[] => artists.map(artist => adaptTrackArtist(artist))

export const adaptPaginatedArtists = (
data: SpotifyResponseWithOffset<SpotifyArtist>
) => adaptPaginated(data, adaptArtists)
SdkArtist,
SdkSimplifiedArtist,
SimplifiedArtist,
} from '@common/types/spotify'

@Injectable()
export class ArtistsAdapter {
constructor(private readonly pageAdapter: PageAdapter) {}

public adapt(data: SdkArtist[]): Artist[]
public adapt(data: SdkSimplifiedArtist[]): SimplifiedArtist[]
public adapt(data: SdkArtist): Artist
public adapt(data: SdkSimplifiedArtist): SimplifiedArtist
public adapt(data: Page<SdkArtist>): Page<Artist>

adapt(
data:
| SdkArtist
| SdkSimplifiedArtist
| (SdkArtist | SdkSimplifiedArtist)[]
| Page<SdkArtist>
) {
if (Array.isArray(data)) return this.adaptArtists(data)

if ('offset' in data) return this.adaptArtistsPage(data)

return this.adaptArtist(data)
}

adaptArtist = ({
name,
id,
external_urls: { spotify: href },
...rest
}: SdkArtist | SdkSimplifiedArtist): Artist | SimplifiedArtist => ({
id,
name,
href,
...('genres' in rest && {
genres: rest.genres,
images: rest.images,
popularity: rest.popularity,
}),
})

adaptArtists(
artists: (SdkArtist | SdkSimplifiedArtist)[]
): (Artist | SimplifiedArtist)[] {
return artists.map(artist => this.adaptArtist(artist))
}

adaptArtistsPage(data: Page<SdkArtist>) {
return this.pageAdapter.adapt(data, artists => this.adaptArtists(artists))
}
}
32 changes: 27 additions & 5 deletions src/common/adapters/audio-features.adapter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
import { spotifyAudioFeaturesMock, audioFeaturesMock } from '../mocks'
import { Test } from '@nestjs/testing'

import { adaptAudioFeatures } from './audio-features.adapter'
import { AudioFeaturesAdapter } from './audio-features.adapter'

describe('adaptAudioFeatures', () => {
test('should adapt audio features', () => {
expect(adaptAudioFeatures(spotifyAudioFeaturesMock)).toEqual(
import { audioFeaturesMock, sdkAudioFeaturesMock } from '@common/mocks'

describe('AudioFeaturesAdapter', () => {
let audioFeaturesAdapter: AudioFeaturesAdapter

beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [AudioFeaturesAdapter],
}).compile()

audioFeaturesAdapter = module.get(AudioFeaturesAdapter)
})

test('should be defined', () => {
expect(audioFeaturesAdapter).toBeDefined()
})

test('should adapt a single audio feature', () => {
expect(audioFeaturesAdapter.adapt(sdkAudioFeaturesMock)).toEqual(
audioFeaturesMock
)
})

test('should adapt an array of audio features', () => {
expect(audioFeaturesAdapter.adapt([sdkAudioFeaturesMock])).toEqual([
audioFeaturesMock,
])
})
})
75 changes: 45 additions & 30 deletions src/common/adapters/audio-features.adapter.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
import { SpotifyAudioFeatures, AudioFeatures } from '../types/spotify'
import { Injectable } from '@nestjs/common'

export const adaptAudioFeatures = ({
id,
track_href,
danceability,
acousticness,
instrumentalness,
speechiness,
liveness,
loudness,
energy,
tempo,
mode,
key,
valence,
}: SpotifyAudioFeatures): AudioFeatures => ({
id,
trackHref: track_href,
danceability,
acousticness,
instrumentalness,
speechiness,
liveness,
loudness,
energy,
tempo,
mode,
key,
valence,
})
import { AudioFeatures, SdkAudioFeatures } from '@common/types/spotify'

@Injectable()
export class AudioFeaturesAdapter {
public adapt(data: SdkAudioFeatures[]): AudioFeatures[]
public adapt(data: SdkAudioFeatures): AudioFeatures

adapt(data: SdkAudioFeatures | SdkAudioFeatures[]) {
if (Array.isArray(data))
return data.map(audioFeatures => this.adaptAudioFeatures(audioFeatures))

return this.adaptAudioFeatures(data)
}

adaptAudioFeatures = ({
id,
track_href,
danceability,
acousticness,
instrumentalness,
speechiness,
liveness,
loudness,
energy,
tempo,
mode,
key,
valence,
}: SdkAudioFeatures): AudioFeatures => ({
id,
trackHref: track_href,
danceability,
acousticness,
instrumentalness,
speechiness,
liveness,
loudness,
energy,
tempo,
mode,
key,
valence,
})
}
30 changes: 25 additions & 5 deletions src/common/adapters/devices.adapter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
import { spotifyDevicesMock, devicesMock } from '../mocks'
import { Test } from '@nestjs/testing'

import { adaptDevices } from './devices.adapter'
import { DevicesAdapter } from './devices.adapter'

describe('adaptDevices', () => {
test('should adapt devices', () => {
expect(adaptDevices(spotifyDevicesMock)).toEqual(devicesMock)
import { deviceMock, sdkDeviceMock } from '@common/mocks'

describe('DevicesAdapter', () => {
let devicesAdapter: DevicesAdapter

beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [DevicesAdapter],
}).compile()

devicesAdapter = module.get(DevicesAdapter)
})

test('should be defined', () => {
expect(devicesAdapter).toBeDefined()
})

test('should adapt a single device', () => {
expect(devicesAdapter.adapt(sdkDeviceMock)).toEqual(deviceMock)
})

test('should adapt an array of devices', () => {
expect(devicesAdapter.adapt([sdkDeviceMock])).toEqual([deviceMock])
})
})
Loading
Loading