Skip to content

Commit

Permalink
feat: Get collection addresses (#609)
Browse files Browse the repository at this point in the history
* feat: Add itemTags param to filter collections by items tag

* feat: Add new route /addresses to get all collections addresses and add new param tag

* feat: Add tests

* feat:  Use tags in lowercase to filter without case sensitivity issues
  • Loading branch information
cyaiox committed Oct 6, 2022
1 parent 508612a commit 5b18f04
Show file tree
Hide file tree
Showing 3 changed files with 343 additions and 2 deletions.
20 changes: 19 additions & 1 deletion src/Collection/Collection.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type FindCollectionParams = {
sort?: CurationStatusSort
isPublished?: boolean
remoteIds?: CollectionAttributes['id'][]
itemTags?: string[]
}

export class Collection extends Model<CollectionAttributes> {
Expand Down Expand Up @@ -71,9 +72,16 @@ export class Collection extends Model<CollectionAttributes> {
address,
thirdPartyIds,
remoteIds,
itemTags,
}: Pick<
FindCollectionParams,
'q' | 'assignee' | 'status' | 'address' | 'thirdPartyIds' | 'remoteIds'
| 'q'
| 'assignee'
| 'status'
| 'address'
| 'thirdPartyIds'
| 'remoteIds'
| 'itemTags'
>) {
if (!q && !assignee && !status && !address && !thirdPartyIds?.length) {
return SQL``
Expand All @@ -100,6 +108,9 @@ export class Collection extends Model<CollectionAttributes> {
? SQL`collection_curations.assignee is NOT NULL AND collection_curations.status = ${CurationStatusFilter.PENDING}`
: SQL``
: undefined,
itemTags
? SQL`LOWER(items.data::json->>'tags')::jsonb ? ANY(${itemTags})`
: undefined,
].filter(Boolean)

if (!conditions.length) {
Expand Down Expand Up @@ -188,6 +199,13 @@ export class Collection extends Model<CollectionAttributes> {
)} cc ORDER BY cc.collection_id, cc.created_at DESC) collection_curations
ON collection_curations.collection_id = collections.id
`}
${
whereFilters.itemTags
? SQL`LEFT JOIN ${raw(
Item.tableName
)} items ON collections.id = items.collection_id`
: SQL``
}
${SQL`${this.getFindAllWhereStatement(whereFilters)}`}
${SQL`${this.getOrderByStatement(sort, whereFilters.remoteIds)}`}
LIMIT ${limit}
Expand Down
261 changes: 261 additions & 0 deletions src/Collection/Collection.router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,72 @@ describe('Collection router', () => {
limit,
thirdPartyIds: [],
remoteIds: [],
itemTags: undefined,
})
})
})
})

describe('and sending pagination params plus filtering with array tag options', () => {
let page: number,
limit: number,
baseUrl: string,
totalCollectionsFromDb: number,
q: string,
assignee: string,
status: string,
sort: string,
isPublished: string,
itemTag: string,
itemTag2: string
beforeEach(() => {
;(page = 1), (limit = 3)
assignee = '0x1234567890123456789012345678901234567890'
status = 'published'
sort = 'NAME_DESC'
isPublished = 'true'
q = 'collection name 1'
itemTag = 'TAG'
itemTag2 = 'TAG2'
totalCollectionsFromDb = 1
baseUrl = '/collections'
url = `${baseUrl}?limit=${limit}&page=${page}&assignee=${assignee}&status=${status}&sort=${sort}&is_published=${isPublished}&q=${q}&tag=${itemTag}&tag=${itemTag2}`
;(Collection.findAll as jest.Mock).mockResolvedValueOnce([
{ ...dbCollection, collection_count: totalCollectionsFromDb },
])
})
it('should respond with pagination data and should have call the findAll method with the right params', () => {
return server
.get(buildURL(url))
.set(createAuthHeaders('get', baseUrl))
.expect(200)
.then((response: any) => {
expect(response.body).toEqual({
data: {
total: totalCollectionsFromDb,
pages: totalCollectionsFromDb,
page,
limit,
results: [
{
...resultingCollectionAttributes,
urn: `urn:decentraland:mumbai:collections-v2:${dbCollection.contract_address}`,
},
],
},
ok: true,
})
expect(Collection.findAll).toHaveBeenCalledWith({
q,
assignee,
status,
sort,
isPublished: true,
offset: page - 1, // it's the offset
limit,
thirdPartyIds: [],
remoteIds: [],
itemTags: [itemTag.toLowerCase(), itemTag2.toLowerCase()],
})
})
})
Expand Down Expand Up @@ -2531,4 +2597,199 @@ describe('Collection router', () => {
})
})
})

describe('when retrieving all the collections addresses', () => {
beforeEach(() => {
;(isCommitteeMember as jest.Mock).mockResolvedValueOnce(true)
;(Collection.findByContractAddresses as jest.Mock).mockResolvedValueOnce(
[]
)
;(collectionAPI.fetchCollections as jest.Mock).mockResolvedValueOnce([])
thirdPartyAPIMock.fetchThirdParties.mockResolvedValueOnce([])
})

describe('and sending pagination params', () => {
let page: number, limit: number
let baseUrl: string
let totalCollectionsFromDb: number
beforeEach(() => {
;(page = 1), (limit = 3)
totalCollectionsFromDb = 1
baseUrl = '/addresses'
url = `${baseUrl}?limit=${limit}&page=${page}`
;(Collection.findAll as jest.Mock).mockResolvedValueOnce([
{ ...dbCollection, collection_count: totalCollectionsFromDb },
])
})
it('should respond with pagination data and should have call the findAll method with the params', () => {
return server
.get(buildURL(url))
.set(createAuthHeaders('get', baseUrl))
.expect(200)
.then((response: any) => {
expect(response.body).toEqual({
data: {
total: totalCollectionsFromDb,
pages: totalCollectionsFromDb,
page,
limit,
results: [resultingCollectionAttributes.contract_address],
},
ok: true,
})
expect(Collection.findAll).toHaveBeenCalledWith({
assignee: undefined,
isPublished: undefined,
q: undefined,
sort: undefined,
status: undefined,
limit,
offset: page - 1, // it's the offset,
thirdPartyIds: [],
remoteIds: [],
itemTags: undefined,
})
})
})
})

describe('and sending pagination params plus filtering options', () => {
let page: number,
limit: number,
baseUrl: string,
totalCollectionsFromDb: number,
q: string,
assignee: string,
status: string,
sort: string,
isPublished: string,
itemTag: string
beforeEach(() => {
;(page = 1), (limit = 3)
assignee = '0x1234567890123456789012345678901234567890'
status = 'published'
sort = 'NAME_DESC'
isPublished = 'true'
q = 'collection name 1'
itemTag = 'TAG'
totalCollectionsFromDb = 1
baseUrl = '/addresses'
url = `${baseUrl}?limit=${limit}&page=${page}&assignee=${assignee}&status=${status}&sort=${sort}&is_published=${isPublished}&q=${q}&tag=${itemTag}`
;(Collection.findAll as jest.Mock).mockResolvedValueOnce([
{ ...dbCollection, collection_count: totalCollectionsFromDb },
])
})
it('should respond with pagination data and should have call the findAll method with the right params', () => {
return server
.get(buildURL(url))
.set(createAuthHeaders('get', baseUrl))
.expect(200)
.then((response: any) => {
expect(response.body).toEqual({
data: {
total: totalCollectionsFromDb,
pages: totalCollectionsFromDb,
page,
limit,
results: [resultingCollectionAttributes.contract_address],
},
ok: true,
})
expect(Collection.findAll).toHaveBeenCalledWith({
q,
assignee,
status,
sort,
isPublished: true,
offset: page - 1, // it's the offset
limit,
thirdPartyIds: [],
remoteIds: [],
itemTags: [itemTag.toLowerCase()],
})
})
})
})

describe('and sending pagination params plus filtering with array tag options', () => {
let page: number,
limit: number,
baseUrl: string,
totalCollectionsFromDb: number,
q: string,
assignee: string,
status: string,
sort: string,
isPublished: string,
itemTag: string,
itemTag2: string
beforeEach(() => {
;(page = 1), (limit = 3)
assignee = '0x1234567890123456789012345678901234567890'
status = 'published'
sort = 'NAME_DESC'
isPublished = 'true'
q = 'collection name 1'
itemTag = 'TAG'
itemTag2 = 'TAG2'
totalCollectionsFromDb = 1
baseUrl = '/addresses'
url = `${baseUrl}?limit=${limit}&page=${page}&assignee=${assignee}&status=${status}&sort=${sort}&is_published=${isPublished}&q=${q}&tag=${itemTag}&tag=${itemTag2}`
;(Collection.findAll as jest.Mock).mockResolvedValueOnce([
{ ...dbCollection, collection_count: totalCollectionsFromDb },
])
})
it('should respond with pagination data and should have call the findAll method with the right params', () => {
return server
.get(buildURL(url))
.set(createAuthHeaders('get', baseUrl))
.expect(200)
.then((response: any) => {
expect(response.body).toEqual({
data: {
total: totalCollectionsFromDb,
pages: totalCollectionsFromDb,
page,
limit,
results: [resultingCollectionAttributes.contract_address],
},
ok: true,
})
expect(Collection.findAll).toHaveBeenCalledWith({
q,
assignee,
status,
sort,
isPublished: true,
offset: page - 1, // it's the offset
limit,
thirdPartyIds: [],
remoteIds: [],
itemTags: [itemTag.toLowerCase(), itemTag2.toLowerCase()],
})
})
})
})

describe('and not sending any pagination params ', () => {
beforeEach(() => {
url = `/addresses`
;(Collection.findAll as jest.Mock)
.mockResolvedValueOnce([dbCollection])
.mockResolvedValueOnce([])
})
it('should respond with all the collections addresses', () => {
return server
.get(buildURL(url))
.set(createAuthHeaders('get', url))
.expect(200)
.then((response: any) => {
expect(response.body).toEqual({
data: [resultingCollectionAttributes.contract_address],
ok: true,
})
})
})
})
})
})
Loading

0 comments on commit 5b18f04

Please sign in to comment.