Skip to content

Commit

Permalink
feat: Upsert items with the server's date
Browse files Browse the repository at this point in the history
  • Loading branch information
LautaroPetaccio committed Dec 1, 2021
1 parent fc3f481 commit 16e31a3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 33 deletions.
61 changes: 32 additions & 29 deletions src/Item/Item.router.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import supertest from 'supertest'
import { v4 as uuidv4 } from 'uuid'
import { Wallet } from 'ethers'
import { omit } from 'decentraland-commons/dist/utils'
import {
createAuthHeaders,
buildURL,
Expand Down Expand Up @@ -318,16 +319,18 @@ describe('Item router', () => {
jest.Mocked<typeof Item>

const mockUUID = '75e7da02-a727-48de-a4da-d0778395067b'
let itemToUpsert: Omit<ItemAttributes, 'created_at' | 'updated_at'>

beforeEach(() => {
url = `/items/${dbItem.id}`
itemToUpsert = omit(dbItem, ['created_at', 'updated_at'])
})

describe('and the param id is different from payload id', () => {
it('should fail with body and url ids do not match message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: { ...dbItem, id: mockUUID } })
.send({ item: { ...itemToUpsert, id: mockUUID } })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.badRequest)

Expand All @@ -341,12 +344,12 @@ describe('Item router', () => {

describe('and the user upserting is not authorized to do so', () => {
beforeEach(() => {
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, false)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, false)
})
it('should fail with unauthorized user message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: dbItem })
.send({ item: itemToUpsert })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.unauthorized)

Expand All @@ -360,14 +363,14 @@ describe('Item router', () => {

describe('and the collection provided in the payload does not exists in the db', () => {
beforeEach(() => {
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, true)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, true)
mockCollection.findOne.mockResolvedValueOnce(undefined)
})

it('should fail with collection not found message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: dbItem })
.send({ item: itemToUpsert })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.notFound)

Expand All @@ -382,7 +385,7 @@ describe('Item router', () => {
describe('and the collection provided in the payload does not belong to the address making the request', () => {
const differentEthAddress = '0xc6d2000a7a1ddca92941f4e2b41360fe4ee2abd8'
beforeEach(() => {
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, true)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, true)
mockCollection.findOne.mockResolvedValueOnce({
collection_id: dbItem.collection_id,
eth_address: differentEthAddress,
Expand All @@ -392,15 +395,15 @@ describe('Item router', () => {
it('should fail with unauthorized user message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: dbItem })
.send({ item: itemToUpsert })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.unauthorized)

expect(response.body).toEqual({
data: {
id: dbItem.id,
id: itemToUpsert.id,
eth_address: wallet.address,
collection_id: dbItem.collection_id,
collection_id: itemToUpsert.collection_id,
},
error:
"The new collection for the item isn't owned by the same owner.",
Expand All @@ -411,19 +414,19 @@ describe('Item router', () => {

describe('and the collection of the item is being changed', () => {
beforeEach(() => {
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, true)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, true)
})

it('should fail with cant change item collection message', async () => {
mockItem.findOne.mockResolvedValueOnce(dbItem)
mockItem.findOne.mockResolvedValueOnce(itemToUpsert)
mockCollection.findOne.mockResolvedValueOnce({
collection_id: dbItem.collection_id,
collection_id: itemToUpsert.collection_id,
eth_address: wallet.address,
})

const response = await server
.put(buildURL(url))
.send({ item: { ...dbItem, collection_id: mockUUID } })
.send({ item: { ...itemToUpsert, collection_id: mockUUID } })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.unauthorized)

Expand All @@ -437,9 +440,9 @@ describe('Item router', () => {

describe('when the collection given for the item is locked', () => {
beforeEach(() => {
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, true)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, true)
mockCollection.findOne.mockResolvedValueOnce({
collection_id: dbItem.collection_id,
collection_id: itemToUpsert.collection_id,
eth_address: wallet.address,
contract_address: Wallet.createRandom().address,
lock: new Date(),
Expand All @@ -455,13 +458,13 @@ describe('Item router', () => {
it('should fail with can not update locked collection items message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: { ...dbItem, name: 'new name' } })
.send({ item: { ...itemToUpsert, name: 'new name' } })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.locked)

expect(response.body).toEqual({
data: {
id: dbItem.id,
id: itemToUpsert.id,
},
error:
"The collection for the item is locked. The item can't be inserted or updated.",
Expand All @@ -474,10 +477,10 @@ describe('Item router', () => {
describe('when the collection given for the item is already published', () => {
beforeEach(() => {
dbItem.collection_id = collectionAttributesMock.id
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, true)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, true)
mockCollection.findOne.mockResolvedValueOnce({
...collectionAttributesMock,
collection_id: dbItem.collection_id,
collection_id: itemToUpsert.collection_id,
eth_address: wallet.address,
contract_address: Wallet.createRandom().address,
})
Expand All @@ -492,12 +495,12 @@ describe('Item router', () => {
it('should fail with can not add item to published collection message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: dbItem })
.send({ item: itemToUpsert })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.conflict)

expect(response.body).toEqual({
data: { id: dbItem.id },
data: { id: itemToUpsert.id },
error:
"The collection that contains this item has been already published. The item can't be inserted.",
ok: false,
Expand All @@ -507,18 +510,18 @@ describe('Item router', () => {

describe('and the item is being removed from the collection', () => {
beforeEach(() => {
mockItem.findOne.mockResolvedValueOnce(dbItem)
mockItem.findOne.mockResolvedValueOnce(itemToUpsert)
})

it('should fail with can not remove item from published collection message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: { ...dbItem, collection_id: null } })
.send({ item: { ...itemToUpsert, collection_id: null } })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.conflict)

expect(response.body).toEqual({
data: { id: dbItem.id },
data: { id: itemToUpsert.id },
error:
"The collection that contains this item has been already published. The item can't be deleted.",
ok: false,
Expand All @@ -534,13 +537,13 @@ describe('Item router', () => {
it('should fail with can not update items rarity message', async () => {
const response = await server
.put(buildURL(url))
.send({ item: { ...dbItem, rarity: ItemRarity.EPIC } })
.send({ item: { ...itemToUpsert, rarity: ItemRarity.EPIC } })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.conflict)

expect(response.body).toEqual({
data: {
id: dbItem.id,
id: itemToUpsert.id,
},
error:
"The collection that contains this item has been already published. The item can't be updated with a new rarity.",
Expand All @@ -552,9 +555,9 @@ describe('Item router', () => {

describe('and all the conditions for success are given', () => {
beforeEach(() => {
mockOwnableCanUpsert(Item, dbItem.id, wallet.address, true)
mockOwnableCanUpsert(Item, itemToUpsert.id, wallet.address, true)
mockCollection.findOne.mockResolvedValueOnce({
collection_id: dbItem.collection_id,
collection_id: itemToUpsert.collection_id,
eth_address: wallet.address,
contract_address: Wallet.createRandom().address,
})
Expand All @@ -566,7 +569,7 @@ describe('Item router', () => {
it('should respond with the upserted item', async () => {
const response = await server
.put(buildURL(url))
.send({ item: dbItem })
.send({ item: itemToUpsert })
.set(createAuthHeaders('put', url))
.expect(STATUS_CODES.ok)

Expand Down
4 changes: 0 additions & 4 deletions src/Item/Item.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export const itemSchema = Object.freeze({
additionalProperties: true,
},
content_hash: { type: ['string', 'null'] },
created_at: { type: 'string' },
updated_at: { type: 'string' },
},
additionalProperties: false,
required: [
Expand All @@ -44,8 +42,6 @@ export const itemSchema = Object.freeze({
'type',
'metrics',
'contents',
'created_at',
'updated_at',
],
})

Expand Down
3 changes: 3 additions & 0 deletions src/Item/Item.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ export class ItemService {

const dbItem = await Item.findOne<ItemAttributes>(item.id)
if (dbItem) {
item.updated_at = new Date()
this.checkItemIsMovedToAnotherCollection(item, dbItem)
} else {
item.created_at = new Date()
}

const collectionId = item.collection_id || dbItem?.collection_id
Expand Down

0 comments on commit 16e31a3

Please sign in to comment.