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

fix: Mapping completion criteria #769

Merged
merged 3 commits into from
Aug 30, 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
3 changes: 2 additions & 1 deletion spec/mocks/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ export function toResultTPItem(
total_supply: 0,
price: '0',
beneficiary: constants.AddressZero,
isMappingComplete: !!catalystItem?.mappings,
isMappingComplete:
!!curation?.is_mapping_complete || !!itemAttributes.mappings,
content_hash: null,
catalyst_content_hash: catalystItem
? (catalystItem as any)?.merkleProof.entityHash
Expand Down
8 changes: 5 additions & 3 deletions src/Collection/Collection.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,19 +206,21 @@ export class Collection extends Model<CollectionAttributes> {
* Builds the statement to check if the collection requires the mapping migration to be completed.
* The item migration will be required to be completed if:
* - The collection has items and any of its items don't have a migration.
* - The collection has items with migrations but there are items that weren't approved and uploaded.
* - The collection has items with mappings but there are items that weren't approved and uploaded.
*/
static isMappingCompleteTableStatement() {
return SQL`SELECT NOT EXISTS
(SELECT mappings_info.is_mapping_complete FROM
(SELECT DISTINCT ON (items.id) items.id, item_curations.updated_at, item_curations.is_mapping_complete
(SELECT DISTINCT ON (items.id) items.id, item_curations.updated_at, item_curations.is_mapping_complete, items.mappings
FROM ${raw(Item.tableName)} items
LEFT JOIN ${raw(
ItemCuration.tableName
)} item_curations ON items.id = item_curations.item_id
WHERE items.collection_id = collections.id
ORDER BY items.id, item_curations.updated_at DESC) mappings_info
WHERE mappings_info.is_mapping_complete = false OR mappings_info.is_mapping_complete IS NULL)
WHERE mappings_info.is_mapping_complete = false
OR (mappings_info.is_mapping_complete IS NULL AND mappings_info.updated_at IS NOT NULL AND mappings_info.mappings IS NOT NULL)
OR mappings_info.mappings IS NULL)
OR NOT EXISTS (SELECT 1 FROM ${raw(
Item.tableName
)} items WHERE items.collection_id = collections.id)`
Expand Down
33 changes: 20 additions & 13 deletions src/Item/Item.router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ describe('Item router', () => {
dbTPItemNotPublished = {
...dbTPItem,
id: uuidv4(),
beneficiary: '',
urn_suffix: '',
urn_suffix: '23',
}
dbTPItemPublished = {
...dbTPItem,
Expand Down Expand Up @@ -243,6 +242,7 @@ describe('Item router', () => {
let dbTPItemNotPublishedMock: ThirdPartyItemAttributes

beforeEach(() => {
dbItemCuration.is_mapping_complete = false
dbTPItemNotPublishedMock = {
...dbTPItemNotPublished,
urn_suffix: '2',
Expand All @@ -268,6 +268,7 @@ describe('Item router', () => {
;(peerAPI.fetchWearables as jest.Mock).mockResolvedValueOnce([tpWearable])
url = '/items'
})

it('should return all the items that are published with URN and the ones that are not without it', () => {
return server
.get(buildURL(url))
Expand All @@ -285,12 +286,14 @@ describe('Item router', () => {
resultingTPItem,
{
...resultTPItemNotPublished,
price: '0',
urn: buildTPItemURN(
dbTPCollectionMock.third_party_id,
dbTPCollectionMock.urn_suffix,
dbTPItemNotPublishedMock.urn_suffix!
),
isMappingComplete: false,
blockchain_item_id: '2',
},
{ ...resultTPItemPublished, is_published: true },
],
Expand Down Expand Up @@ -585,9 +588,6 @@ describe('Item router', () => {
;(Collection.findByIds as jest.Mock).mockResolvedValueOnce([
dbTPCollectionMock,
])
;(ItemCuration.findByCollectionId as jest.Mock).mockResolvedValueOnce([
dbItemCuration,
])
;(collectionAPI.buildItemId as jest.Mock).mockImplementation(
(contractAddress, tokenId) => contractAddress + '-' + tokenId
)
Expand All @@ -602,7 +602,8 @@ describe('Item router', () => {
resultingTPItem = toResultTPItem(
dbTPItem,
dbTPCollectionMock,
tpWearableWithMappings
tpWearableWithMappings,
dbItemCuration
)
;(peerAPI.fetchWearables as jest.Mock).mockResolvedValueOnce([
tpWearableWithMappings,
Expand All @@ -611,8 +612,12 @@ describe('Item router', () => {

describe('and the mapping status filter is applied', () => {
beforeEach(() => {
dbItemCuration = { ...dbItemCuration, is_mapping_complete: false }
;(ItemCuration.findByCollectionId as jest.Mock).mockResolvedValueOnce(
[dbItemCuration]
)
;(Item.findByCollectionIdAndStatus as jest.Mock).mockResolvedValueOnce(
[dbTPItem, dbTPItemPublished, dbTPItemNotPublished]
[dbTPItem, dbTPItemPublished]
)
url = `/collections/${dbTPCollectionMock.id}/items`
})
Expand All @@ -628,10 +633,9 @@ describe('Item router', () => {
data: [
{
...resultingTPItem,
isMappingComplete: true,
isMappingComplete: false,
},
{ ...resultTPItemPublished, is_published: true },
resultTPItemNotPublished,
],
ok: true,
})
Expand All @@ -653,10 +657,13 @@ describe('Item router', () => {

describe('and there are not filters applied', () => {
beforeEach(() => {
dbItemCuration = { ...dbItemCuration, is_mapping_complete: true }
;(ItemCuration.findByCollectionId as jest.Mock).mockResolvedValueOnce(
[dbItemCuration]
)
;(Item.findByCollectionIds as jest.Mock).mockResolvedValueOnce([
dbTPItem,
dbTPItemPublished,
dbTPItemNotPublished,
])
url = `/collections/${dbTPCollectionMock.id}/items`
})
Expand All @@ -669,12 +676,12 @@ describe('Item router', () => {
.then((response: any) => {
expect(response.body).toEqual({
data: [
resultingTPItem,
{
...resultingTPItem,
...resultTPItemPublished,
is_published: true,
isMappingComplete: true,
},
{ ...resultTPItemPublished, is_published: true },
resultTPItemNotPublished,
],
ok: true,
})
Expand Down
22 changes: 11 additions & 11 deletions src/ethereum/api/Bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,12 @@ export class Bridge {
)

const collection = dbTPCollectionsIndex[item.collection_id!]
if (itemCuration || catalystItem) {
fullItem = Bridge.mergeTPItem(
item,
collection as ThirdPartyCollectionAttributes,
catalystItem,
itemCuration
)
} else {
fullItem = Bridge.toFullItem(item, collection)
}
fullItem = Bridge.mergeTPItem(
item,
collection as ThirdPartyCollectionAttributes,
catalystItem,
itemCuration
)

fullItems.push(fullItem)
}
Expand Down Expand Up @@ -182,6 +178,7 @@ export class Bridge {
dbCollection.urn_suffix,
dbItem.urn_suffix!
)

return {
...Bridge.toFullItem(dbItem),
// The total supply for TP items will be 0 as they won't be minted.
Expand All @@ -197,7 +194,10 @@ export class Bridge {
is_published: !!catalystItem || !!lastItemCuration,
// For now, items are always approved. Rejecting (or disabling) items will be done at the record level, for all collections that apply.
is_approved: !!catalystItem,
isMappingComplete: !!catalystItem?.mappings,
// The mapping is complete if it was a curation and it was marked as complete or if doesn't and has mappings
isMappingComplete: lastItemCuration
? !!lastItemCuration?.is_mapping_complete
: !!dbItem.mappings,
content_hash: null,
catalyst_content_hash: catalystItem
? (catalystItem as any).merkleProof.entityHash
Expand Down
Loading