mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-consumer.git
synced 2026-09-22 09:12:03 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8cf903fb9 | ||
|
|
c7986d1986 |
@@ -48,6 +48,7 @@ class IpfsFilesAdapter {
|
||||
this.getFileMetadata = this.getFileMetadata.bind(this)
|
||||
this.getPins = this.getPins.bind(this)
|
||||
this.waitForRPCResponse = this.waitForRPCResponse.bind(this)
|
||||
this.pinClaim = this.pinClaim.bind(this)
|
||||
}
|
||||
|
||||
// This handler is triggered when RPC data comes in over IPFS.
|
||||
@@ -63,7 +64,7 @@ class IpfsFilesAdapter {
|
||||
this.rpcDataQueue.push(data)
|
||||
} catch (err) {
|
||||
console.error('Error in files/rpcHandler(): ', err)
|
||||
// Do not throw error. This is a top-level function.
|
||||
// Do not throw error. This is a top-level function.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ class IpfsFilesAdapter {
|
||||
|
||||
// Add names to the IPFS IDs for each provider.
|
||||
const initialServiceProviders =
|
||||
this.ipfs.ipfsCoordAdapter.state.ipfsFileProviders
|
||||
this.ipfs.ipfsCoordAdapter.state.ipfsFileProviders
|
||||
const serviceProviders = []
|
||||
for (let i = 0; i < initialServiceProviders.length; i++) {
|
||||
const thisProvider = initialServiceProviders[i]
|
||||
@@ -142,7 +143,7 @@ class IpfsFilesAdapter {
|
||||
// Throw an error if this IPFS node has not yet made a connection to a
|
||||
// wallet service provider.
|
||||
const selectedProvider =
|
||||
this.ipfs.ipfsCoordAdapter.state.selectedIpfsFileProvider
|
||||
this.ipfs.ipfsCoordAdapter.state.selectedIpfsFileProvider
|
||||
if (!selectedProvider) {
|
||||
throw new Error('No IPFS File Pin Service provider available yet.')
|
||||
}
|
||||
@@ -185,7 +186,7 @@ class IpfsFilesAdapter {
|
||||
// Throw an error if this IPFS node has not yet made a connection to a
|
||||
// wallet service provider.
|
||||
const selectedProvider =
|
||||
this.ipfs.ipfsCoordAdapter.state.selectedIpfsFileProvider
|
||||
this.ipfs.ipfsCoordAdapter.state.selectedIpfsFileProvider
|
||||
if (!selectedProvider) {
|
||||
throw new Error('No IPFS File Pin Service provider available yet.')
|
||||
}
|
||||
@@ -261,7 +262,7 @@ class IpfsFilesAdapter {
|
||||
|
||||
cnt++
|
||||
|
||||
// Exit if data was returned, or the window for a response expires.
|
||||
// Exit if data was returned, or the window for a response expires.
|
||||
} while (!dataFound && cnt < 10)
|
||||
// console.log(`dataFound: ${dataFound}, cnt: ${cnt}`)
|
||||
|
||||
@@ -271,6 +272,53 @@ class IpfsFilesAdapter {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async pinClaim (inObj = {}) {
|
||||
try {
|
||||
// Throw an error if this IPFS node has not yet made a connection to a
|
||||
// ipfs service provider.
|
||||
const selectedProvider =
|
||||
this.ipfs.ipfsCoordAdapter.state.selectedIpfsFileProvider
|
||||
if (!selectedProvider) {
|
||||
throw new Error('No IPFS File Provider Service is available yet. Try again in a few seconds.')
|
||||
}
|
||||
|
||||
const { proofOfBurnTxid, cid, claimTxid, filename, address } = inObj
|
||||
|
||||
const rpcData = {
|
||||
endpoint: 'pinClaim',
|
||||
proofOfBurnTxid,
|
||||
cid,
|
||||
claimTxid,
|
||||
filename,
|
||||
address
|
||||
}
|
||||
|
||||
// Generate a UUID for the call.
|
||||
const rpcId = this.uid()
|
||||
|
||||
// Generate a JSON RPC command.
|
||||
const cmd = this.jsonrpc.request(rpcId, 'file-pin', rpcData)
|
||||
const cmdStr = JSON.stringify(cmd)
|
||||
// console.log('cmdStr: ', cmdStr)
|
||||
|
||||
// Send the RPC command to selected wallet service.
|
||||
const thisNode = this.ipfs.ipfsCoordAdapter.ipfsCoord.thisNode
|
||||
await this.ipfs.ipfsCoordAdapter.ipfsCoord.useCases.peer.sendPrivateMessage(
|
||||
selectedProvider,
|
||||
cmdStr,
|
||||
thisNode
|
||||
)
|
||||
|
||||
// Wait for data to come back from the wallet service.
|
||||
const data = await this.waitForRPCResponse(rpcId)
|
||||
|
||||
return data
|
||||
} catch (err) {
|
||||
console.error('Error in pinClaim()')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// module.exports = P2wdbAdapter
|
||||
|
||||
@@ -41,6 +41,7 @@ class IpfsRESTControllerLib {
|
||||
this.getPins = this.getPins.bind(this)
|
||||
this.cid2json = this.cid2json.bind(this)
|
||||
this.downloadFile = this.downloadFile.bind(this)
|
||||
this.pinClaim = this.pinClaim.bind(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,6 +301,29 @@ class IpfsRESTControllerLib {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /ipfs/pin-claim Process pin claim.
|
||||
* @apiPermission public
|
||||
* @apiName PinClaim
|
||||
* @apiGroup REST IPFS
|
||||
* @apiDescription Process pin claim.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* curl -H "Content-Type: application/json" -X POST -d '{ "proofOfBurnTxid": "be4b63156c93f58ed311d403d9f756deda9abbc81d0fef8fbe5d769538b4261c", "cid": "bafybeied3zdwdiro7fqytyha2yfband4lwcrtozmf6shynylt3kexh26dq", "claimTxid": "c71e2f2cdf8658d90c61ac6183b8ffeeb359779807b317386044705d8352f0f2", "filename": "mutable-67ccefcca67097473e78ca10.json", "address": "bitcoincash:qqs2wrahl6azn9qdyrmp9ygeejqvzr8ruv7e9m30fr" }' http://localhost:5001/ipfs/pin-claim *
|
||||
*/
|
||||
async pinClaim (ctx) {
|
||||
try {
|
||||
const body = ctx.request.body
|
||||
|
||||
const result = await this.useCases.ipfs.pinClaim(body)
|
||||
|
||||
ctx.body = result
|
||||
} catch (err) {
|
||||
console.log('Error in ipfs/controller.js/cid2json(): ', err.message)
|
||||
this.handleError(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
// DRY error handler
|
||||
handleError (ctx, err) {
|
||||
// console.log('handleError() err.status: ', err.status)
|
||||
|
||||
@@ -62,7 +62,7 @@ class IpfsRouter {
|
||||
this.router.get('/file-info/:cid', this.ipfsRESTController.getFileInfo)
|
||||
this.router.get('/pins', this.ipfsRESTController.getPins)
|
||||
this.router.get('/cid2json/:cid', this.ipfsRESTController.cid2json)
|
||||
|
||||
this.router.post('/pin-claim', this.ipfsRESTController.pinClaim)
|
||||
// Attach the Controller routes to the Koa app.
|
||||
app.use(this.router.routes())
|
||||
app.use(this.router.allowedMethods())
|
||||
|
||||
@@ -37,6 +37,7 @@ class IpfsUseCases {
|
||||
this.getWritePrice = this.getWritePrice.bind(this)
|
||||
this.getCidMetadata = this.getCidMetadata.bind(this)
|
||||
this.cid2json = this.cid2json.bind(this)
|
||||
this.pinClaim = this.pinClaim.bind(this)
|
||||
|
||||
// State
|
||||
this.lastWritePriceUpdate = null // Used to periodically update write price.
|
||||
@@ -225,9 +226,11 @@ class IpfsUseCases {
|
||||
|
||||
// Throw an error if this is not a JSON file
|
||||
const filename = fileMetadata.filename
|
||||
|
||||
if (!filename.endsWith('.json')) {
|
||||
throw new Error(`CID ${cid} does not resolve to a JSON file.`)
|
||||
}
|
||||
|
||||
// Retrieve the CID content and store it in a Buffer.
|
||||
const helia = this.adapters.ipfs.ipfs
|
||||
const fileChunks = []
|
||||
@@ -281,6 +284,20 @@ class IpfsUseCases {
|
||||
}
|
||||
}
|
||||
|
||||
async pinClaim (inObj = {}) {
|
||||
try {
|
||||
// Throw an error if ipfs-bch-wallet-consumer can not communicate with the ipfs-file-pin-service.
|
||||
const metadata = await this.adapters.ipfsFiles.pinClaim(inObj)
|
||||
|
||||
return {
|
||||
success: metadata.success,
|
||||
message: metadata.message
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error in ipfs-use-cases.js/pinClaim(): ', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
// async downloadCid2 (inObj = {}) {
|
||||
// try {
|
||||
// const { cid } = inObj
|
||||
|
||||
@@ -248,4 +248,243 @@ describe('#IPFS REST API', () => {
|
||||
assert.property(ctx.body, 'thisNode')
|
||||
})
|
||||
})
|
||||
describe('#viewFile', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
// Force an error
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
sandbox.stub(uut.useCases.ipfs, 'downloadCid').throws(new Error('test error'))
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {}
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.viewFile(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
// console.log('err: ', err)
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.useCases.ipfs, 'downloadCid').resolves({ success: true, readStream: 'readStream' })
|
||||
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {
|
||||
ipfsCoord: {
|
||||
thisNode: {}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.viewFile(ctx)
|
||||
|
||||
assert.exists(ctx.body)
|
||||
})
|
||||
})
|
||||
describe('#downloadFile', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
// Force an error
|
||||
sandbox.stub(uut.useCases.ipfs, 'downloadCid').throws(new Error('test error'))
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {}
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.downloadFile(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
// console.log('err: ', err)
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.useCases.ipfs, 'downloadCid').resolves({ success: true, readStream: 'readStream' })
|
||||
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {
|
||||
ipfsCoord: {
|
||||
thisNode: {}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.downloadFile(ctx)
|
||||
|
||||
assert.exists(ctx.body)
|
||||
})
|
||||
})
|
||||
describe('#getService', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
// Force an error
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {}
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.getService(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
// console.log('err: ', err)
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'Cannot read properties of undefined')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
// Mock dependencies
|
||||
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {
|
||||
state: {
|
||||
selectedIpfsFileProvider: 'provider'
|
||||
}
|
||||
}
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.getService(ctx)
|
||||
|
||||
assert.isTrue(ctx.body.success)
|
||||
})
|
||||
})
|
||||
describe('#getFileInfo', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').throws(new Error('test error'))
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.getFileInfo(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
// console.log('err: ', err)
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ success: true, filename: 'filename' })
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.getFileInfo(ctx)
|
||||
|
||||
assert.isTrue(ctx.body.success)
|
||||
})
|
||||
})
|
||||
describe('#getPins', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getPins').throws(new Error('test error'))
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.getPins(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getPins').resolves({ success: true })
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.getPins(ctx)
|
||||
|
||||
assert.isTrue(ctx.body.success)
|
||||
})
|
||||
})
|
||||
describe('#cid2json', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
sandbox.stub(uut.useCases.ipfs, 'cid2json').throws(new Error('test error'))
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.cid2json(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
ctx.params = {
|
||||
cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy'
|
||||
}
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.useCases.ipfs, 'cid2json').resolves({ success: true })
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.cid2json(ctx)
|
||||
|
||||
assert.isTrue(ctx.body.success)
|
||||
})
|
||||
})
|
||||
describe('#pinClaim', () => {
|
||||
it('should return 422 status on biz logic error', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.useCases.ipfs, 'pinClaim').throws(new Error('test error'))
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.pinClaim(ctx)
|
||||
|
||||
assert.fail('Unexpected result')
|
||||
} catch (err) {
|
||||
assert.equal(err.status, 422)
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should return 200 status on success', async () => {
|
||||
// Mock dependencies
|
||||
sandbox.stub(uut.useCases.ipfs, 'pinClaim').resolves({ success: true })
|
||||
|
||||
ctx.request.body = {}
|
||||
|
||||
await uut.pinClaim(ctx)
|
||||
|
||||
assert.isTrue(ctx.body.success)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
/*
|
||||
Mocks for the Adapter library.
|
||||
*/
|
||||
|
||||
class BlockstoreMock {
|
||||
constructor () {
|
||||
this.get = async () => {}
|
||||
}
|
||||
}
|
||||
class FsMock {
|
||||
constructor () {
|
||||
this.ls = async function* () {
|
||||
yield { path: 'test.txt', cid: 'QmS4ghgMgfFvqPjB4WKXHaN15ZyT4K4JYZxY5X5x5x5x5' }
|
||||
}
|
||||
this.cat = async function* () {
|
||||
yield Buffer.from('test data')
|
||||
}
|
||||
}
|
||||
}
|
||||
class IpfsAdapter {
|
||||
constructor () {
|
||||
this.ipfs = {
|
||||
blockstore: new BlockstoreMock(),
|
||||
fs: new FsMock(),
|
||||
files: {
|
||||
stat: () => {}
|
||||
}
|
||||
@@ -34,7 +50,9 @@ class IpfsCoordAdapter {
|
||||
this.peerInputHandler = () => {}
|
||||
|
||||
this.state = {
|
||||
serviceProviders: []
|
||||
serviceProviders: [],
|
||||
serviceProvidersByType: '',
|
||||
selectedIpfsFileProvider:''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,5 +156,29 @@ class BchUseCaseMock {
|
||||
}
|
||||
}
|
||||
const bch = new BchUseCaseMock()
|
||||
const wallet = {
|
||||
bchWallet: bch
|
||||
|
||||
export default { ipfs, localdb, bch }
|
||||
}
|
||||
|
||||
const ipfsFiles = {
|
||||
pinClaim: () => {
|
||||
return {
|
||||
success: true,
|
||||
message: 'Pin claimed'
|
||||
}
|
||||
},
|
||||
getFileMetadata: () => {
|
||||
return {
|
||||
success: true,
|
||||
message: 'Files metadata'
|
||||
}
|
||||
},
|
||||
getPins: () => {
|
||||
return {
|
||||
success: true,
|
||||
message: 'Pins'
|
||||
}
|
||||
}
|
||||
}
|
||||
export default { ipfs, localdb, bch, wallet, ipfsFiles }
|
||||
|
||||
@@ -67,6 +67,28 @@ class UsageUseCaseMock {
|
||||
}
|
||||
}
|
||||
|
||||
class IpfsUseCaseMock {
|
||||
async downloadCid() {
|
||||
return {}
|
||||
}
|
||||
|
||||
async cid2json() {
|
||||
return {}
|
||||
}
|
||||
|
||||
async getCidMetadata() {
|
||||
return {}
|
||||
}
|
||||
|
||||
async getService() {
|
||||
return {}
|
||||
}
|
||||
|
||||
async pinClaim() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
class UseCasesMock {
|
||||
constuctor(localConfig = {}) {
|
||||
// this.user = new UserUseCaseMock(localConfig)
|
||||
@@ -77,6 +99,7 @@ class UseCasesMock {
|
||||
user = new UserUseCaseMock()
|
||||
bch = new BchUseCaseMock()
|
||||
usage = new UsageUseCaseMock()
|
||||
ipfs = new IpfsUseCaseMock()
|
||||
}
|
||||
|
||||
export default UseCasesMock;
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
Unit tests for the ipfs-use-cases.js file.
|
||||
*/
|
||||
|
||||
// Public npm libraries
|
||||
import { assert } from 'chai'
|
||||
|
||||
import sinon from 'sinon'
|
||||
|
||||
// Local support libraries
|
||||
// const testUtils = require('../../utils/test-utils')
|
||||
|
||||
// Unit under test (uut)
|
||||
import UseCases from '../../../src/use-cases/ipfs-use-cases.js'
|
||||
|
||||
import adapters from '../mocks/adapters/index.js'
|
||||
|
||||
describe('#ipfs-use-cases', () => {
|
||||
let uut
|
||||
let sandbox
|
||||
|
||||
before(async () => {
|
||||
// Delete all previous users in the database.
|
||||
// await testUtils.deleteAllUsers()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox()
|
||||
|
||||
uut = new UseCases({ adapters })
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {
|
||||
state: {
|
||||
selectedIpfsFileProvider: 'provider'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(() => sandbox.restore())
|
||||
|
||||
describe('#constructor', () => {
|
||||
it('should throw an error if adapters are not passed in', () => {
|
||||
try {
|
||||
uut = new UseCases()
|
||||
|
||||
assert.fail('Unexpected code path')
|
||||
|
||||
// This is here to prevent the linter from complaining.
|
||||
assert.isOk(uut)
|
||||
} catch (err) {
|
||||
assert.include(
|
||||
err.message,
|
||||
'Instance of adapters must be passed in when instantiating IPFS Use Cases library.'
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('#downloadCid', () => {
|
||||
it('should download a file from IPFS', async () => {
|
||||
sandbox.stub(uut, 'getCidMetadata').resolves('file.txt')
|
||||
|
||||
const result = await uut.downloadCid({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
|
||||
assert.property(result, 'filename')
|
||||
assert.property(result, 'readStream')
|
||||
})
|
||||
it('should handle directory-based CIDs', async () => {
|
||||
sandbox.stub(uut, 'getCidMetadata').resolves('file.txt')
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'ls').callsFake(async function * () {
|
||||
yield { path: 'dir1/test.txt', cid: 'QmS4ghgMgfFvqPjB4WKXHaN15ZyT4K4JYZxY5X5x5x5x5' }
|
||||
})
|
||||
const result = await uut.downloadCid({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
|
||||
assert.property(result, 'filename')
|
||||
assert.property(result, 'readStream')
|
||||
})
|
||||
it('should throw an error if cid is not provided ', async () => {
|
||||
try {
|
||||
await uut.downloadCid({})
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'CID is undefined')
|
||||
}
|
||||
})
|
||||
})
|
||||
describe('#getWritePrice', () => {
|
||||
it('should get price', async () => {
|
||||
const result = await uut.getWritePrice()
|
||||
assert.isNumber(result)
|
||||
})
|
||||
it('should handle undefined psffpp instance', async () => {
|
||||
uut.psffpp = null
|
||||
const result = await uut.getWritePrice()
|
||||
assert.isNumber(result)
|
||||
})
|
||||
|
||||
it('should handle error ', async () => {
|
||||
try {
|
||||
uut.psffpp = {
|
||||
getMcWritePrice: () => {
|
||||
throw new Error('test error')
|
||||
}
|
||||
}
|
||||
await uut.getWritePrice()
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'test error')
|
||||
}
|
||||
})
|
||||
})
|
||||
describe('#getCidMetadata', () => {
|
||||
it('should get cid metadata', async () => {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ success: true, fileMetadata: { dataPinned: true, filename: 'test.json' } })
|
||||
const result = await uut.getCidMetadata({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.isString(result)
|
||||
assert.equal(result, 'test.json')
|
||||
})
|
||||
|
||||
it('should handle error ', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').throws(new Error('test error'))
|
||||
await uut.getCidMetadata({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should handle non-success response from getFileMetadata', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ success: false, message: 'test error' })
|
||||
await uut.getCidMetadata({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'test error')
|
||||
}
|
||||
})
|
||||
})
|
||||
describe('#cid2json', () => {
|
||||
it('should get cid2json', async () => {
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {
|
||||
state: {
|
||||
selectedIpfsFileProvider: 'provider'
|
||||
}
|
||||
}
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ fileMetadata: { dataPinned: true, filename: 'test.json' } })
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'ls').callsFake(function * () {
|
||||
yield { name: 'test.json' }
|
||||
})
|
||||
sandbox.stub(JSON, 'parse').returns(true)
|
||||
const result = await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.isObject(result)
|
||||
assert.property(result, 'success')
|
||||
assert.property(result, 'json')
|
||||
})
|
||||
|
||||
it('should throw error if selectedIpfsFileProvider is not defined', async () => {
|
||||
try {
|
||||
uut.adapters.ipfs.ipfsCoordAdapter = {
|
||||
state: {
|
||||
selectedIpfsFileProvider: null
|
||||
}
|
||||
}
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'No IPFS File Provider Service is available yet. Try again in a few seconds')
|
||||
}
|
||||
})
|
||||
it('should throw error if file metadata cant be fetched', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ success: false })
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'Could not communicate with instance of ipfs-file-pin-service')
|
||||
}
|
||||
})
|
||||
it('should throw error if cid is not pinned', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ success: true, fileMetadata: { dataPinned: false } })
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'has not been pinned by ipfs-file-pin-service instance')
|
||||
}
|
||||
})
|
||||
it('should throw error if filename has no .json extension', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ success: true, fileMetadata: { dataPinned: true, filename: 'test' } })
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'does not resolve to a JSON file')
|
||||
}
|
||||
})
|
||||
it('should handle error if file cant be retrieved', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ fileMetadata: { dataPinned: true, filename: 'test.json' } })
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'cat').throws(new Error('test error'))
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'ls').callsFake(function * () {
|
||||
yield { name: 'test.json' }
|
||||
})
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should handle error if cid is a directory', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ fileMetadata: { dataPinned: true, filename: 'test.json' } })
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'cat')
|
||||
.onCall(0).throws(new Error('test error'))
|
||||
.onCall(1).callsFake(function * () {
|
||||
yield { name: 'test.json' }
|
||||
})
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'ls').callsFake(function * () {
|
||||
yield { name: 'test/directory/' }
|
||||
})
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'file does not resolve to a valid JSON file')
|
||||
}
|
||||
})
|
||||
it('should get content from cid/name.json format', async () => {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ fileMetadata: { dataPinned: true, filename: 'test.json' } })
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'cat')
|
||||
.onCall(0).throws(new Error('test error'))
|
||||
.onCall(1).callsFake(function * () {
|
||||
yield Buffer.from('{"test": "test"}')
|
||||
})
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'ls').callsFake(function * () {
|
||||
yield { name: 'test/directory/test.json' }
|
||||
})
|
||||
|
||||
const result = await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
assert.isObject(result)
|
||||
assert.property(result, 'success')
|
||||
assert.property(result, 'json')
|
||||
})
|
||||
it('should handle if content cant be parsed', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'getFileMetadata').resolves({ fileMetadata: { dataPinned: true, filename: 'test.json' } })
|
||||
sandbox.stub(uut.adapters.ipfs.ipfs.fs, 'ls').callsFake(function * () {
|
||||
yield { name: 'test.json' }
|
||||
})
|
||||
sandbox.stub(JSON, 'parse').throws(new Error())
|
||||
|
||||
await uut.cid2json({ cid: 'bafybeib2rphswe7clvclverw7xi7nejkpkh4mdfcurdmcgw7wcup7za6wy' })
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'not resolve to a valid JSON object')
|
||||
}
|
||||
})
|
||||
})
|
||||
describe('#pinClaim', () => {
|
||||
it('should process pinClaim', async () => {
|
||||
const result = await uut.pinClaim()
|
||||
assert.isObject(result)
|
||||
assert.property(result, 'success')
|
||||
assert.property(result, 'message')
|
||||
})
|
||||
|
||||
it('should handle error ', async () => {
|
||||
try {
|
||||
sandbox.stub(uut.adapters.ipfsFiles, 'pinClaim').throws(new Error('test error'))
|
||||
await uut.pinClaim()
|
||||
} catch (error) {
|
||||
assert.include(error.message, 'test error')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user