Skip to content

Commit

Permalink
feat: add pagination support for get playlist
Browse files Browse the repository at this point in the history
  • Loading branch information
sumitkolhe committed Mar 30, 2024
1 parent fb018cc commit 152d5ca
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 20 deletions.
30 changes: 26 additions & 4 deletions src/modules/playlists/controllers/playlist.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,21 @@ export class PlaylistController implements Routes {
type: 'string',
example: 'https://www.jiosaavn.com/featured/its-indie-english/AMoxtXyKHoU_',
default: 'https://www.jiosaavn.com/featured/its-indie-english/AMoxtXyKHoU_'
})
}),
page: z.string().pipe(z.coerce.number()).optional().openapi({
title: 'Page Number',
description: 'The page number of the songs to retrieve from the playlist',
type: 'integer',
example: 0,
default: 0
}),
limit: z.string().pipe(z.coerce.number()).optional().openapi({
title: 'Limit',
description: 'Number of songs to retrieve per page',
type: 'integer',
example: 10,
default: 10
})
})
},
responses: {
Expand All @@ -68,15 +82,23 @@ export class PlaylistController implements Routes {
}
}),
async (ctx) => {
const { id, link } = ctx.req.valid('query')
const { id, link, page, limit } = ctx.req.valid('query')

if (!link && !id) {
return ctx.json({ success: false, message: 'Either playlist ID or link is required' }, 400)
}

const response = link
? await this.playlistService.getPlaylistByLink(link)
: await this.playlistService.getPlaylistById(id!)
? await this.playlistService.getPlaylistByLink({
token: link,
page: page || 0,
limit: limit || 10
})
: await this.playlistService.getPlaylistById({
id: id!,
page: page || 0,
limit: limit || 10
})

return ctx.json({ success: true, data: response })
}
Expand Down
15 changes: 10 additions & 5 deletions src/modules/playlists/services/playlist.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { GetPlaylistByIdUseCase, GetPlaylistByLinkUseCase } from '#modules/playlists/use-cases'
import {
type GetPlaylistByIdArgs,
GetPlaylistByIdUseCase,
type GetPlaylistByLinkArgs,
GetPlaylistByLinkUseCase
} from '#modules/playlists/use-cases'

export class PlaylistService {
private readonly getPlaylistByIdUseCase: GetPlaylistByIdUseCase
Expand All @@ -9,11 +14,11 @@ export class PlaylistService {
this.getPlaylistByLinkUseCase = new GetPlaylistByLinkUseCase()
}

getPlaylistById = (playlistId: string) => {
return this.getPlaylistByIdUseCase.execute(playlistId)
getPlaylistById = (args: GetPlaylistByIdArgs) => {
return this.getPlaylistByIdUseCase.execute(args)
}

getPlaylistByLink = (token: string) => {
return this.getPlaylistByLinkUseCase.execute(token)
getPlaylistByLink = (args: GetPlaylistByLinkArgs) => {
return this.getPlaylistByLinkUseCase.execute(args)
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { beforeAll, describe, expect, test } from 'vitest'
import { GetAlbumByIdUseCase } from '#modules/albums/use-cases'
import { GetPlaylistByIdUseCase } from '#modules/playlists/use-cases'

describe('GetAlbumById', () => {
let getAlbumByIdUseCase: GetAlbumByIdUseCase
let getPlaylistByIdUseCase: GetPlaylistByIdUseCase

beforeAll(() => {
getAlbumByIdUseCase = new GetAlbumByIdUseCase()
getPlaylistByIdUseCase = new GetPlaylistByIdUseCase()
})

test('should get album by id and return an album', async () => {
const album = await getAlbumByIdUseCase.execute('23241654')
const album = await getPlaylistByIdUseCase.execute({
id: '159470188',
page: 1,
limit: 5
})

expect(album).toMatchSnapshot({
playCount: expect.any(Number),
songCount: expect.any(Number),
songs: album.songs.map((song) => ({
...song,
playCount: expect.any(Number)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,29 @@ import { useFetch } from '#common/helpers'
import { Endpoints } from '#common/constants'
import { createPlaylistPayload } from '#modules/playlists/helpers'

export class GetPlaylistByIdUseCase implements IUseCase<string, z.infer<typeof PlaylistModel>> {
export interface GetPlaylistByIdArgs {
id: string
limit: number
page: number
}

export class GetPlaylistByIdUseCase implements IUseCase<GetPlaylistByIdArgs, z.infer<typeof PlaylistModel>> {
constructor() {}

async execute(id: string) {
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>(Endpoints.playlists.id, { listid: id })
async execute({ id, limit, page }: GetPlaylistByIdArgs) {
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>(Endpoints.playlists.id, {
listid: id,
n: limit,
p: page
})

if (!response) throw new HTTPException(404, { message: 'playlist not found' })

return createPlaylistPayload(response)
const playlist = createPlaylistPayload(response)
return {
...playlist,
songCount: playlist.songs?.length || 0,
songs: playlist.songs?.slice(0, limit) || []
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@ import { useFetch } from '#common/helpers'
import { Endpoints } from '#common/constants'
import { createPlaylistPayload } from '#modules/playlists/helpers'

export class GetPlaylistByLinkUseCase implements IUseCase<string, z.infer<typeof PlaylistModel>> {
export interface GetPlaylistByLinkArgs {
token: string
limit: number
page: number
}

export class GetPlaylistByLinkUseCase implements IUseCase<GetPlaylistByLinkArgs, z.infer<typeof PlaylistModel>> {
constructor() {}

async execute(token: string) {
async execute({ token, limit, page }: GetPlaylistByLinkArgs) {
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>(Endpoints.albums.link, {
token,
n: limit,
p: page,
type: 'playlist'
})

if (!response) throw new HTTPException(404, { message: 'playlist not found' })

return createPlaylistPayload(response)
const playlist = createPlaylistPayload(response)

return {
...playlist,
songCount: playlist.songs?.length,
songs: playlist.songs?.slice(0, limit) || []
}
}
}

0 comments on commit 152d5ca

Please sign in to comment.