2022-02-23 05:51:12 -08:00
|
|
|
/*
|
|
|
|
|
Unit tests for the Offer Use Case library.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Public npm libraries
|
2022-10-01 11:40:41 -07:00
|
|
|
import { assert } from 'chai'
|
|
|
|
|
import sinon from 'sinon'
|
2025-09-13 14:36:27 -04:00
|
|
|
import RetryQueue from '@chris.troutner/retry-queue'
|
2022-02-23 05:51:12 -08:00
|
|
|
|
|
|
|
|
// Local support libraries
|
|
|
|
|
// const testUtils = require('../../utils/test-utils')
|
|
|
|
|
|
|
|
|
|
// Unit under test (uut)
|
2022-10-01 12:15:40 -07:00
|
|
|
import OfferLib from '../../../src/use-cases/offer/index.js'
|
2022-10-01 11:40:26 -07:00
|
|
|
|
2022-10-01 12:15:40 -07:00
|
|
|
import OrderUseCase from '../../../src/use-cases/order.js'
|
|
|
|
|
import adapters from '../mocks/adapters/index.js'
|
2022-10-01 11:40:41 -07:00
|
|
|
import mockData from '../mocks/use-cases/offer-mock-data.js'
|
2022-02-23 05:51:12 -08:00
|
|
|
|
|
|
|
|
describe('#offer-use-case', () => {
|
|
|
|
|
let uut
|
|
|
|
|
let sandbox
|
|
|
|
|
|
|
|
|
|
before(async () => {
|
|
|
|
|
// Delete all previous users in the database.
|
|
|
|
|
// await testUtils.deleteAllUsers()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
sandbox = sinon.createSandbox()
|
|
|
|
|
|
2022-03-22 10:05:50 -07:00
|
|
|
const order = new OrderUseCase({ adapters })
|
|
|
|
|
uut = new OfferLib({ adapters, order })
|
2025-09-13 14:36:27 -04:00
|
|
|
uut.retryQueue = new RetryQueue({ retryPeriod: 1000, attempts: 1 })
|
2022-02-23 05:51:12 -08:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
afterEach(() => sandbox.restore())
|
|
|
|
|
|
|
|
|
|
describe('#constructor', () => {
|
|
|
|
|
it('should throw an error if adapters are not passed in', () => {
|
|
|
|
|
try {
|
|
|
|
|
uut = new OfferLib()
|
|
|
|
|
|
|
|
|
|
assert.fail('Unexpected code path')
|
|
|
|
|
console.log(uut) // linter
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(
|
|
|
|
|
err.message,
|
|
|
|
|
'Instance of adapters must be passed in when instantiating Offer Use Cases library.'
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should throw an error if order use cases are not passed in', () => {
|
|
|
|
|
try {
|
|
|
|
|
uut = new OfferLib({ adapters })
|
|
|
|
|
|
|
|
|
|
assert.fail('Unexpected code path')
|
|
|
|
|
console.log(uut) // linter
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(
|
|
|
|
|
err.message,
|
|
|
|
|
'Instance of Order Use Cases must be passed in when instantiating Offer Use Cases library.'
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
})
|
2022-02-23 05:51:12 -08:00
|
|
|
})
|
|
|
|
|
|
2022-03-21 09:53:58 -07:00
|
|
|
describe('#createOffer', () => {
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should handle error', async () => {
|
|
|
|
|
try {
|
|
|
|
|
await uut.createOffer()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.include(error.message, 'Cannot read properties of undefined')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should return false if offer already exist', async () => {
|
|
|
|
|
const offerObj = mockData.offerMockData
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
// sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').resolves(false)
|
|
|
|
|
sandbox.stub(uut, 'findOfferByTxid').resolves({})
|
|
|
|
|
|
|
|
|
|
const result = await uut.createOffer(offerObj)
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should return false if offer already processed', async () => {
|
|
|
|
|
const offerObj = mockData.offerMockData
|
|
|
|
|
uut.seenOffers.push(offerObj.data.nostrEventId)
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
|
|
|
|
|
const result = await uut.createOffer(offerObj)
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
|
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should return false for invalid utxo', async () => {
|
|
|
|
|
const offerObj = mockData.offerMockData
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
// sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').resolves(false)
|
|
|
|
|
sandbox.stub(uut, 'findOfferByTxid').throws(new Error('offer not found'))
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue').resolves(null)
|
|
|
|
|
|
|
|
|
|
const result = await uut.createOffer(offerObj)
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should create offer', async () => {
|
|
|
|
|
const tokenDataMock = mockData.simpleNftTokenData01
|
|
|
|
|
const offerObj = mockData.offerMockData
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
// sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').resolves(false)
|
|
|
|
|
sandbox.stub(uut, 'findOfferByTxid').throws(new Error('offer not found'))
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue')
|
|
|
|
|
.onCall(0).resolves({}) // Utxo Status call
|
|
|
|
|
.onCall(1).resolves(tokenDataMock) // Token Data call
|
|
|
|
|
.onCall(2).resolves(false) // detectNsfw call
|
|
|
|
|
|
|
|
|
|
const result = await uut.createOffer(offerObj)
|
|
|
|
|
assert.isTrue(result)
|
|
|
|
|
})
|
2022-03-09 09:37:17 -08:00
|
|
|
})
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
describe('#categorizeToken', () => {
|
|
|
|
|
it('should categorize an NFT', async () => {
|
|
|
|
|
// Mock dependencies
|
2022-09-13 13:40:01 -07:00
|
|
|
// sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.nftTokenData01)
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
const offerData = mockData.nftOffer01
|
2022-09-13 13:40:01 -07:00
|
|
|
const tokenData = mockData.nftTokenData01
|
2022-09-11 14:36:40 -07:00
|
|
|
|
2022-09-13 13:40:01 -07:00
|
|
|
const result = await uut.categorizeToken(offerData, tokenData)
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
assert.equal(result, 'nft')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should categorize a simple NFT', async () => {
|
|
|
|
|
// Mock dependencies
|
2022-09-13 13:40:01 -07:00
|
|
|
// sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.simpleNftTokenData01)
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
const offerData = mockData.simpleNftOffer01
|
2022-09-13 13:40:01 -07:00
|
|
|
const tokenData = mockData.simpleNftTokenData01
|
2022-09-11 14:36:40 -07:00
|
|
|
|
2022-09-13 13:40:01 -07:00
|
|
|
const result = await uut.categorizeToken(offerData, tokenData)
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
assert.equal(result, 'simple-nft')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should categorize a fungible token', async () => {
|
|
|
|
|
// Mock dependencies
|
2022-09-13 13:40:01 -07:00
|
|
|
// sandbox.stub(uut.adapters.wallet.bchWallet, 'getTokenData').resolves(mockData.fungibleTokenData01)
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
const offerData = mockData.fungibleOffer01
|
2022-09-13 13:40:01 -07:00
|
|
|
const tokenData = mockData.fungibleTokenData01
|
2022-09-11 14:36:40 -07:00
|
|
|
|
2022-09-13 13:40:01 -07:00
|
|
|
const result = await uut.categorizeToken(offerData, tokenData)
|
2022-09-11 14:36:40 -07:00
|
|
|
|
|
|
|
|
assert.equal(result, 'fungible')
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should unknow type', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
const offerData = mockData.fungibleOffer01
|
|
|
|
|
const tokenData = { genesisData: {} }
|
|
|
|
|
|
|
|
|
|
await uut.categorizeToken(offerData, tokenData)
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.include(error.message, 'Unknown token type:')
|
|
|
|
|
}
|
|
|
|
|
})
|
2022-09-11 14:36:40 -07:00
|
|
|
})
|
2022-10-02 07:18:17 -07:00
|
|
|
|
|
|
|
|
describe('#removeDuplicateOffers', () => {
|
|
|
|
|
it('should remove duplicate entries and return true', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([
|
2024-12-02 22:19:54 -04:00
|
|
|
{ p2wdbHash: 'a', remove: async () => { } },
|
|
|
|
|
{ p2wdbHash: 'a', remove: async () => { } },
|
|
|
|
|
{ p2wdbHash: 'b', remove: async () => { } }
|
2022-10-02 07:18:17 -07:00
|
|
|
])
|
|
|
|
|
// sandbox.stub(uut.OfferModel, 'remove').resolves()
|
|
|
|
|
|
|
|
|
|
const result = await uut.removeDuplicateOffers()
|
|
|
|
|
console.log('result: ', result)
|
|
|
|
|
|
|
|
|
|
assert.equal(result, true)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should return false if there are no duplicate entries', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([
|
2024-12-02 22:19:54 -04:00
|
|
|
{ p2wdbHash: 'a', remove: async () => { } },
|
|
|
|
|
{ p2wdbHash: 'b', remove: async () => { } }
|
2022-10-02 07:18:17 -07:00
|
|
|
])
|
|
|
|
|
// sandbox.stub(uut.OfferModel, 'remove').resolves()
|
|
|
|
|
|
|
|
|
|
const result = await uut.removeDuplicateOffers()
|
|
|
|
|
console.log('result: ', result)
|
|
|
|
|
|
|
|
|
|
assert.equal(result, false)
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').throws(new Error('test error'))
|
|
|
|
|
// sandbox.stub(uut.OfferModel, 'remove').resolves()
|
|
|
|
|
|
|
|
|
|
await uut.removeDuplicateOffers()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.equal(error.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#removeStaleOffers', () => {
|
|
|
|
|
it('remove offer with wrong utxoState', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([{ remove: async () => { } }])
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue').resolves(false)
|
|
|
|
|
|
|
|
|
|
await uut.removeStaleOffers()
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('remove offer with wrong txid', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([{ remove: async () => { } }])
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue').throws(new Error('txid needs to be a proper transaction ID'))
|
|
|
|
|
|
|
|
|
|
await uut.removeStaleOffers()
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('remove expired offer ', async () => {
|
|
|
|
|
const tsMock = new Date()
|
|
|
|
|
tsMock.setMonth(tsMock.getMonth() - 3)
|
|
|
|
|
|
|
|
|
|
const timestamp = tsMock.getTime()
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([{ timestamp, remove: async () => { } }])
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue').resolves(true)
|
|
|
|
|
|
|
|
|
|
await uut.removeStaleOffers()
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle axios error ', async () => {
|
|
|
|
|
const testErr = new Error()
|
|
|
|
|
testErr.isAxiosError = true
|
|
|
|
|
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([{ remove: async () => { } }])
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue').throws(testErr)
|
|
|
|
|
|
|
|
|
|
await uut.removeStaleOffers()
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error ', async () => {
|
|
|
|
|
try {
|
|
|
|
|
const testErr = new Error('unknow error')
|
|
|
|
|
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([{ remove: async () => { } }])
|
|
|
|
|
sandbox.stub(uut.retryQueue, 'addToQueue').throws(testErr)
|
|
|
|
|
|
|
|
|
|
await uut.removeStaleOffers()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.equal(error.message, 'unknow error')
|
|
|
|
|
}
|
|
|
|
|
})
|
2022-10-02 07:18:17 -07:00
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
describe('#findOfferByTxid', () => {
|
|
|
|
|
it('should throw an error if input is not provided', async () => {
|
|
|
|
|
try {
|
|
|
|
|
await uut.findOfferByTxid()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.equal(error.message, 'utxoTxid must be a string')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should throw an error if offer is not found', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'findOne').resolves(null)
|
|
|
|
|
|
|
|
|
|
await uut.findOfferByTxid('241c06bf61384b8623477e419bf4779edbcc7e3bc862f0f179a9ed2967069b87')
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.equal(error.message, 'offer not found')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should return offer', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'findOne').resolves(mockData.nftOffer01)
|
|
|
|
|
|
|
|
|
|
const result = await uut.findOfferByTxid('241c06bf61384b8623477e419bf4779edbcc7e3bc862f0f179a9ed2967069b87')
|
|
|
|
|
assert.isObject(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
describe('#detectNsfw', () => {
|
|
|
|
|
it('should return false for wrong cid format', async () => {
|
|
|
|
|
const result = await uut.detectNsfw({ mutableData: '' })
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should return true if nft boolean detected', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.axios, 'get').resolves({ data: { nsfw: true } })
|
|
|
|
|
|
|
|
|
|
const result = await uut.detectNsfw({ mutableData: 'ipfs://bafybeibqnsmmh6bkf2wwextetki4tly65z4r4qkrrpl5xwgvzdzjley6wm' })
|
|
|
|
|
assert.isTrue(result)
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should return true if nft string detected', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.axios, 'get').resolves({ data: { nsfw: 'true' } })
|
|
|
|
|
|
|
|
|
|
const result = await uut.detectNsfw({ mutableData: 'ipfs://bafybeibqnsmmh6bkf2wwextetki4tly65z4r4qkrrpl5xwgvzdzjley6wm' })
|
|
|
|
|
assert.isTrue(result)
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should return false if nfsw property does not exist', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.axios, 'get').resolves({ data: {} })
|
|
|
|
|
|
|
|
|
|
const result = await uut.detectNsfw({ mutableData: 'ipfs://bafybeibqnsmmh6bkf2wwextetki4tly65z4r4qkrrpl5xwgvzdzjley6wm' })
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-02 22:19:54 -04:00
|
|
|
it('should return false on error', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.axios, 'get').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
const result = await uut.detectNsfw({ mutableData: 'ipfs://bafybeibqnsmmh6bkf2wwextetki4tly65z4r4qkrrpl5xwgvzdzjley6wm' })
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should fetch alternative url', async () => {
|
|
|
|
|
// Mock dependencies and force desired code path.
|
|
|
|
|
sandbox.stub(uut.axios, 'get').onCall(0).throws(new Error())
|
|
|
|
|
.onCall(1).resolves({ data: { nsfw: true } })
|
|
|
|
|
|
|
|
|
|
const result = await uut.detectNsfw({ mutableData: 'ipfs://bafybeibqnsmmh6bkf2wwextetki4tly65z4r4qkrrpl5xwgvzdzjley6wm' })
|
|
|
|
|
assert.isTrue(result)
|
|
|
|
|
})
|
2024-12-02 22:19:54 -04:00
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#listOffers', () => {
|
|
|
|
|
it('should handle error', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
await uut.listOffers()
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should list orders', async () => {
|
|
|
|
|
const queryMock = {
|
|
|
|
|
sort () {
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
skip () {
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
limit () { return [] }
|
|
|
|
|
}
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').returns(queryMock)
|
|
|
|
|
|
|
|
|
|
const result = await uut.listOffers()
|
|
|
|
|
assert.isArray(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#listNftOffers', () => {
|
|
|
|
|
it('should handle error', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
await uut.listNftOffers()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2025-10-08 20:20:11 -04:00
|
|
|
it('should list offers', async () => {
|
2024-12-04 06:51:28 -04:00
|
|
|
const queryMock = {
|
|
|
|
|
sort () {
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
skip () {
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
limit () { return [] }
|
|
|
|
|
}
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').returns(queryMock)
|
|
|
|
|
|
|
|
|
|
const result = await uut.listNftOffers(1, true)
|
2025-10-08 20:20:11 -04:00
|
|
|
assert.isObject(result)
|
|
|
|
|
assert.property(result, 'data')
|
|
|
|
|
assert.property(result, 'pagination')
|
|
|
|
|
assert.isArray(result.data)
|
|
|
|
|
assert.isObject(result.pagination)
|
2024-12-04 06:51:28 -04:00
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#listFungibleOffers', () => {
|
|
|
|
|
it('should handle error', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
await uut.listFungibleOffers()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should list orders', async () => {
|
|
|
|
|
const queryMock = {
|
|
|
|
|
sort () {
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
skip () {
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
limit () { return [] }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').returns(queryMock)
|
|
|
|
|
|
|
|
|
|
const result = await uut.listFungibleOffers()
|
|
|
|
|
assert.isArray(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#takeOffer', () => {
|
|
|
|
|
it('should handle error if input is not provided', async () => {
|
|
|
|
|
try {
|
|
|
|
|
await uut.takeOffer()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'eventId must be a string')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error for wrong offer status', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').returns({ offerStatus: 'completed' })
|
|
|
|
|
|
|
|
|
|
await uut.takeOffer('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'offer status is not "posted", so offer is dead and can not be countered.')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error for invalid utxo', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').returns({ offerStatus: 'posted' })
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').returns(false)
|
|
|
|
|
|
|
|
|
|
await uut.takeOffer('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'UTXO does not exist. Aborting.')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should handle insufficient funds', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').returns({ offerStatus: 'posted' })
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').returns(true)
|
|
|
|
|
sandbox.stub(uut, 'ensureFunds').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
await uut.takeOffer('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error if counter offer cant be calculated', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').returns({ offerStatus: 'posted' })
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').returns(true)
|
|
|
|
|
sandbox.stub(uut, 'ensureFunds').resolves(true)
|
|
|
|
|
|
|
|
|
|
await uut.takeOffer('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'Could not calculate the amount of BCH to generate counter offer')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error if counter offer cant be calculated', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').returns({ offerStatus: 'posted' })
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').returns(true)
|
|
|
|
|
sandbox.stub(uut, 'ensureFunds').resolves(true)
|
|
|
|
|
|
|
|
|
|
await uut.takeOffer('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'Could not calculate the amount of BCH to generate counter offer')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should take offer', async () => {
|
|
|
|
|
// Mock data
|
|
|
|
|
const offerMock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
offerMock.remove = async () => { }
|
|
|
|
|
offerMock.offerStatus = 'posted'
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').returns(offerMock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').returns(true)
|
|
|
|
|
sandbox.stub(uut, 'ensureFunds').resolves(true)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet, 'moveBch').resolves({ sats: 1 })
|
|
|
|
|
|
|
|
|
|
await uut.takeOffer('eventId')
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2024-12-06 09:35:33 -08:00
|
|
|
describe('#ensureFunds', () => {
|
|
|
|
|
// it('should handle insufficient funds to use p2wdb', async () => {
|
|
|
|
|
// try {
|
|
|
|
|
// // Mock dependencies
|
|
|
|
|
// sandbox.stub(uut.adapters.p2wdb, 'checkForSufficientFunds').resolves(false)
|
|
|
|
|
//
|
|
|
|
|
// await uut.ensureFunds(mockData.offerMockData.data)
|
|
|
|
|
//
|
|
|
|
|
// assert.fail('Unexpected code path')
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
// assert.include(err.message, 'App wallet does not have funds for writing to the P2WDB')
|
|
|
|
|
// }
|
|
|
|
|
// })
|
2024-12-04 06:51:28 -04:00
|
|
|
|
|
|
|
|
it('should throw error if sats needed could no be able to calculated', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.adapters.p2wdb, 'checkForSufficientFunds').resolves(true)
|
|
|
|
|
|
|
|
|
|
// Mock Input
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.rateInBaseUnit = null
|
|
|
|
|
|
|
|
|
|
await uut.ensureFunds(mock)
|
|
|
|
|
|
|
|
|
|
assert.fail('Unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'Could not calculate sats needed!')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should throw error if app wallet does not have enough bch', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.adapters.p2wdb, 'checkForSufficientFunds').resolves(true)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'getBalance').resolves(0)
|
|
|
|
|
|
|
|
|
|
await uut.ensureFunds(mockData.offerMockData.data)
|
|
|
|
|
|
|
|
|
|
assert.fail('Unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'App wallet does not control enough BCH to purchase the tokens.')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should handle BUY offer', async () => {
|
|
|
|
|
try {
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.buyOrSell = 'buy'
|
|
|
|
|
|
|
|
|
|
await uut.ensureFunds(mock)
|
|
|
|
|
|
|
|
|
|
assert.fail('Unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'Buy offers are not supported yet.')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should return true', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.adapters.p2wdb, 'checkForSufficientFunds').resolves(true)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'getBalance').resolves(10 * 10 ** 6)
|
|
|
|
|
|
|
|
|
|
const result = await uut.ensureFunds(mockData.offerMockData.data)
|
|
|
|
|
assert.isTrue(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
describe('#findOfferByEvent', () => {
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should throw an error if hash is not provided', async () => {
|
|
|
|
|
try {
|
|
|
|
|
await uut.findOfferByEvent()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'nostrEventId must be a string')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should throw an error if order is not found!', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'findOne').resolves(null)
|
|
|
|
|
|
|
|
|
|
await uut.findOfferByEvent('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'offer not found')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should return offer by eventId', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'findOne').resolves({ toObject: () => { return { hash: 'hash' } } })
|
|
|
|
|
|
|
|
|
|
const result = await uut.findOfferByEvent('eventId')
|
|
|
|
|
assert.isObject(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
describe('#listOffersByAddress', () => {
|
|
|
|
|
it('should throw an error if order is not found!', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
await uut.listOffersByAddress('eventId')
|
|
|
|
|
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should return offer by eventId', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.OfferModel, 'find').resolves([])
|
|
|
|
|
|
|
|
|
|
const result = await uut.listOffersByAddress()
|
|
|
|
|
assert.isArray(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#flagOffer', () => {
|
|
|
|
|
it('should throw an error if input is not provided', async () => {
|
|
|
|
|
try {
|
|
|
|
|
await uut.flagOffer()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, '"data" property is required')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should throw an error if offer is not found!', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').resolves(null)
|
|
|
|
|
|
|
|
|
|
const input = {
|
|
|
|
|
data:
|
|
|
|
|
{
|
|
|
|
|
nostrEventId: 'eventId'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await uut.flagOffer(input)
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'not found in the database')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should flag offer', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut, 'findOfferByEvent').resolves({ flags: ['a', 'b', 'c'], save: () => { } })
|
|
|
|
|
|
|
|
|
|
const input = {
|
|
|
|
|
data:
|
|
|
|
|
{
|
|
|
|
|
nostrEventId: 'eventId'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const result = await uut.flagOffer(input)
|
|
|
|
|
assert.isTrue(result)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
describe('#loadOffers', () => {
|
|
|
|
|
it('should handle nostr error', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.adapters.nostr, 'read').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
await uut.loadOffers()
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'test error')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should skip internal function errors ', async () => {
|
|
|
|
|
// Mock dependencies
|
2025-09-13 14:36:27 -04:00
|
|
|
const nostrReadMock = [{ content: JSON.stringify(mockData.offerMockData) }]
|
|
|
|
|
sandbox.stub(uut.adapters.nostr, 'read').resolves(nostrReadMock)
|
2024-12-04 06:51:28 -04:00
|
|
|
|
|
|
|
|
await uut.loadOffers()
|
|
|
|
|
})
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should createOffer ', async () => {
|
|
|
|
|
mockData.offerMockData.data.dataType = 'offer'
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
const nostrReadMock = [{ content: JSON.stringify(mockData.offerMockData) }]
|
|
|
|
|
sandbox.stub(uut.adapters.nostr, 'read').resolves(nostrReadMock)
|
|
|
|
|
const spy = sandbox.stub(uut, 'createOffer').resolves(true)
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
await uut.loadOffers()
|
|
|
|
|
assert.isTrue(spy.calledOnce)
|
|
|
|
|
})
|
|
|
|
|
it('should accept counter Offer ', async () => {
|
|
|
|
|
mockData.offerMockData.data.dataType = 'counter-offer'
|
2024-12-04 06:51:28 -04:00
|
|
|
// Mock dependencies
|
2025-09-13 14:36:27 -04:00
|
|
|
const nostrReadMock = [{ content: JSON.stringify(mockData.offerMockData) }]
|
|
|
|
|
sandbox.stub(uut.adapters.nostr, 'read').resolves(nostrReadMock)
|
|
|
|
|
const spy = sandbox.stub(uut, 'acceptCounterOffer').resolves(true)
|
|
|
|
|
|
|
|
|
|
await uut.loadOffers()
|
|
|
|
|
assert.isTrue(spy.calledOnce)
|
|
|
|
|
})
|
2024-12-04 06:51:28 -04:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should skip error inside loop', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
const nostrReadMock = [{ content: '' }]
|
|
|
|
|
sandbox.stub(uut.adapters.nostr, 'read').resolves(nostrReadMock)
|
2024-12-04 06:51:28 -04:00
|
|
|
await uut.loadOffers()
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
describe('#acceptCounterOffer', () => {
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should return false if order already processed', async () => {
|
|
|
|
|
const offerObj = mockData.offerMockData
|
|
|
|
|
uut.seenOffers.push(offerObj.data.nostrEventId)
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer(offerObj)
|
|
|
|
|
assert.isFalse(result)
|
|
|
|
|
})
|
|
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should return if order is not found!', async () => {
|
|
|
|
|
// Mock dependencies
|
2025-09-13 14:36:27 -04:00
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer({ data: { /** .... */ } })
|
|
|
|
|
assert.equal(result, 'N/A')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should return if utxo cant be validated', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').throws(new Error('test error'))
|
|
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer({ data: { /** .... */ } })
|
|
|
|
|
assert.equal(result, 'N/A')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should handle axios error', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
const stubErr = new Error()
|
|
|
|
|
stubErr.isAxiosError = true
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').throws(stubErr)
|
|
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer({ data: { /** .... */ } })
|
|
|
|
|
assert.equal(result, 'N/A')
|
|
|
|
|
})
|
|
|
|
|
it('should return if utxo is invalid', async () => {
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet, 'utxoIsValid').resolves(false)
|
2024-12-04 06:51:28 -04:00
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer({ data: { /** .... */ } })
|
|
|
|
|
assert.equal(result, 'N/A')
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error if counter offer cant be calculated', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock Data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.rateInBaseUnit = null
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByEvent').resolves(mock)
|
2024-12-29 09:14:49 -08:00
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
2024-12-04 06:51:28 -04:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
const result = await uut.acceptCounterOffer({ data: {} })
|
2024-12-29 09:14:49 -08:00
|
|
|
console.log('result: ', result)
|
2024-12-04 06:51:28 -04:00
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'Could not calculate the amount of BCH offered in the Counter Offer')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error for wrong transaction output', async () => {
|
|
|
|
|
try {
|
2024-12-29 09:14:49 -08:00
|
|
|
// Mock Data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
2024-12-04 06:51:28 -04:00
|
|
|
|
2024-12-29 09:14:49 -08:00
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
2024-12-04 06:51:28 -04:00
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet.bchjs.BitcoinCash, 'toSatoshi').returns(0)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet, 'deseralizeTx').resolves(mockData.deserealizeTxMock)
|
|
|
|
|
|
2024-12-29 09:14:49 -08:00
|
|
|
await uut.acceptCounterOffer({ data: mock })
|
2024-12-04 06:51:28 -04:00
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'The Counter Offer has an output of ')
|
|
|
|
|
assert.include(err.message, 'which does not match the required')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2025-08-10 10:44:45 -07:00
|
|
|
it('should skip transactions that do not have an output for the operator', async () => {
|
|
|
|
|
// Mock data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.makerAddr = 'bitcoincash:qzy97glp47ut7tstm5g0tlrmkhk742795gkmyc7477' // Unknow Adress
|
|
|
|
|
mock.rateInBaseUnit = 0
|
|
|
|
|
mock.numTokens = 0
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet.bchjs.BitcoinCash, 'toSatoshi').returns(0)
|
|
|
|
|
|
|
|
|
|
sandbox.stub(uut.adapters.wallet, 'deseralizeTx').resolves(mockData.deserealizeTxMockNoOperatorOut)
|
|
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer({ data: { /** .... */ } })
|
|
|
|
|
assert.equal(result, 'N/A')
|
|
|
|
|
})
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should skip transactions if operator address does not match', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.makerAddr = mockData.deserealizeTxMockNoOperatorOut.vout[2].scriptPubKey.addresses[0]
|
|
|
|
|
mock.operatorAddress = 'bitcoincash:qzy97glp47ut7tstm5g0tlrmkhk742795gkmyc7477'
|
|
|
|
|
mock.rateInBaseUnit = 0
|
|
|
|
|
mock.numTokens = 0
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet.bchjs.BitcoinCash, 'toSatoshi').returns(0)
|
|
|
|
|
|
|
|
|
|
sandbox.stub(uut.adapters.wallet, 'deseralizeTx').resolves(mockData.deserealizeTxMock)
|
|
|
|
|
|
|
|
|
|
await uut.acceptCounterOffer({ data: {} })
|
|
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
assert.include(error.message, 'The Counter Offer has an output address of')
|
|
|
|
|
}
|
|
|
|
|
})
|
2025-08-10 10:44:45 -07:00
|
|
|
|
2024-12-04 06:51:28 -04:00
|
|
|
it('should handle error for wrong transaction output address', async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Mock data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.makerAddr = 'bitcoincash:qzy97glp47ut7tstm5g0tlrmkhk742795gkmyc7477' // Unknow Adress
|
|
|
|
|
mock.rateInBaseUnit = 0
|
|
|
|
|
mock.numTokens = 0
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByEvent').resolves(mock)
|
2024-12-29 09:14:49 -08:00
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
2024-12-04 06:51:28 -04:00
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet.bchjs.BitcoinCash, 'toSatoshi').returns(0)
|
|
|
|
|
|
|
|
|
|
sandbox.stub(uut.adapters.wallet, 'deseralizeTx').resolves(mockData.deserealizeTxMock)
|
|
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
await uut.acceptCounterOffer({ data: {} })
|
2024-12-04 06:51:28 -04:00
|
|
|
assert.fail('unexpected code path')
|
|
|
|
|
} catch (err) {
|
|
|
|
|
assert.include(err.message, 'The Counter Offer has an output address of')
|
|
|
|
|
assert.include(err.message, 'which does not match the Maker address')
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-12-29 09:14:49 -08:00
|
|
|
|
2025-09-13 14:36:27 -04:00
|
|
|
it('should handle error if operator sats to receive cant be calculated', async () => {
|
2024-12-04 06:51:28 -04:00
|
|
|
// Mock data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
2025-09-13 14:36:27 -04:00
|
|
|
mock.makerAddr = mockData.deserealizeTxMock.vout[2].scriptPubKey.addresses[0]
|
|
|
|
|
mock.operatorAddress = mockData.deserealizeTxMock.vout[3].scriptPubKey.addresses[0]
|
2024-12-04 06:51:28 -04:00
|
|
|
mock.rateInBaseUnit = 0
|
|
|
|
|
mock.numTokens = 0
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByEvent').resolves(mock)
|
2025-09-13 14:36:27 -04:00
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
2024-12-04 06:51:28 -04:00
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet.bchjs.BitcoinCash, 'toSatoshi').returns(0)
|
2025-09-13 14:36:27 -04:00
|
|
|
|
|
|
|
|
sandbox.stub(uut.adapters.wallet, 'deseralizeTx').resolves(mockData.deserealizeTxMock)
|
|
|
|
|
|
|
|
|
|
const result = await uut.acceptCounterOffer({ data: {} })
|
|
|
|
|
assert.equal(result, 'N/A')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('should return tx id', async () => {
|
|
|
|
|
// Mock data
|
|
|
|
|
const mock = Object.assign({}, mockData.offerMockData.data)
|
|
|
|
|
mock.makerAddr = mockData.deserealizeTxMock.vout[2].scriptPubKey.addresses[0]
|
|
|
|
|
mock.operatorAddress = mockData.deserealizeTxMock.vout[3].scriptPubKey.addresses[0]
|
|
|
|
|
mock.rateInBaseUnit = 0
|
|
|
|
|
mock.numTokens = 0
|
|
|
|
|
|
|
|
|
|
// Mock dependencies
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByEvent').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.orderUseCase, 'findOrderByUtxo').resolves(mock)
|
|
|
|
|
sandbox.stub(uut.adapters.wallet.bchWallet.bchjs.BitcoinCash, 'toSatoshi').onCall(0).returns(0).onCall(1).returns(1000)
|
|
|
|
|
sandbox.stub(uut.adapters.localdb.Users, 'findById').resolves({ mnemonic: 'test' })
|
2024-12-04 06:51:28 -04:00
|
|
|
sandbox.stub(uut.adapters.wallet, 'deseralizeTx').resolves(mockData.deserealizeTxMock)
|
|
|
|
|
|
|
|
|
|
//
|
2025-09-13 14:36:27 -04:00
|
|
|
const result = await uut.acceptCounterOffer({ data: {} })
|
2024-12-04 06:51:28 -04:00
|
|
|
assert.isString(result)
|
2025-09-13 14:36:27 -04:00
|
|
|
assert.notEqual('N/A')
|
2024-12-04 06:51:28 -04:00
|
|
|
})
|
|
|
|
|
})
|
2022-02-23 05:51:12 -08:00
|
|
|
})
|