diff --git a/test/fixtures/AquariusAsset.json b/test/fixtures/AquariusAsset.json new file mode 100644 index 0000000..c6fab22 --- /dev/null +++ b/test/fixtures/AquariusAsset.json @@ -0,0 +1,178 @@ +{ + "@context": ["https://w3id.org/did/v1"], + "id": "did:op:c7ce4d1ceccb2131d6fbe80592d4d76301d108ee3f003161434f051b41317440", + "nftAddress": "0xC4CF12Fb38C8169CFCb249ED4A6Cc73f92F941c5", + "version": "4.1.0", + "chainId": 32456, + "metadata": { + "created": "2024-02-06T16:29:12Z", + "updated": "2024-02-06T16:29:12Z", + "type": "algorithm", + "name": "Test Algo", + "description": "A demo algo to test compute functionality", + "tags": [], + "author": "", + "license": "https://market.oceanprotocol.com/terms", + "additionalInformation": { + "termsAndConditions": true, + "gaiaXInformation": { + "termsAndConditions": [ + { + "url": "https://raw.githubusercontent.com/deltaDAO/mvg-portal/v4/content/pages/terms.md" + } + ], + "serviceSD": { + "url": "" + } + } + }, + "algorithm": { + "language": "js", + "version": "0.1", + "container": { + "entrypoint": "node $ALGO", + "image": "node", + "tag": "latest", + "checksum": "sha256:2cc34c90ae08e9a7447d01513af15a1f37193b04bc3a84a2c13ff3065665b3a0" + }, + "consumerParameters": [ + { + "name": "hometown", + "type": "text", + "label": "Hometown", + "required": true, + "description": "What is your hometown?", + "default": "Nowhere" + }, + { + "name": "age", + "type": "number", + "label": "Age", + "required": false, + "description": "Please fill your age", + "default": 0 + }, + { + "name": "developer", + "type": "boolean", + "label": "Developer", + "required": false, + "description": "Are you a developer?", + "default": false + }, + { + "name": "languagePreference", + "type": "select", + "label": "Language", + "required": false, + "description": "Do you like NodeJs or Python", + "default": "nodejs", + "options": [ + { + "nodejs": "I love NodeJs" + }, + { + "python": "I love Python" + } + ] + } + ] + } + }, + "services": [ + { + "id": "b5e60d603a03b285a3b8cb25a4995cc9b3db5723b489a14738d2ee0e11dcd3db", + "type": "compute", + "files": "0x042d889f8b1f31979444f2cded7f4ece2b34be2e19e0218e16ed63fdde426d56f6eac6400d837a20d476486b964e6d91942f2006143f8fb78bd5ea0c1a61be20fefc9a1f91a6bf00fae344dfcfeebdb2ff512a100962680cf3cb15925e27e1797a7d618d3b6e757c9af41e2df947087e246cf3945eb511af92b126b9ff7e4281906a3d1f66a4ee5f057a2e949308f603f060cd7954480055322a00b6b7b66322e3ddc794a647f0946b4aee4c4e7543a4994f50f904be7142a970a20fa1f1408c9cf3b2598f865b149525149c6879d888ce3546154148e111f9756c442d2469eaf87a9160208c64d929506ea45be25f4b6817fb9f96ea9cf856fcfa619e51627dc0fbc269041a9567b4e94bb0874a0c48da56efc226f0ad1a14ea878ee0c98e3251d2a0710e506f714baf967a7ef02110018bd11ba2d02e81da118aa1fc523c4a5ec6760f881a384cfea7f4eb9bf11fead26d9571ec80004f3286cfa2", + "datatokenAddress": "0xcc7E4619Edb66808693AD09Ad3481d75c94a6c8B", + "serviceEndpoint": "https://provider.dev.pontus-x.eu", + "timeout": 86400, + "compute": { + "allowRawAlgorithm": false, + "allowNetworkAccess": true, + "publisherTrustedAlgorithmPublishers": [], + "publisherTrustedAlgorithms": [] + }, + "consumerParameters": [ + { + "name": "hometown", + "type": "text", + "label": "Hometown", + "required": true, + "description": "What is your hometown?", + "default": "Nowhere" + }, + { + "name": "age", + "type": "number", + "label": "Age", + "required": false, + "description": "Please fill your age", + "default": 0 + }, + { + "name": "developer", + "type": "boolean", + "label": "Developer", + "required": false, + "description": "Are you a developer?", + "default": false + }, + { + "name": "languagePreference", + "type": "select", + "label": "Language", + "required": false, + "description": "Do you like NodeJs or Python", + "default": "nodejs", + "options": [ + { + "nodejs": "I love NodeJs" + }, + { + "python": "I love Python" + } + ] + } + ] + } + ], + "credentials": { + "allow": [], + "deny": [] + }, + "event": { + "tx": "0x2be6f9c50566780bd9d7491df76170fd32913361c1a76ef7d8f4b5c40a324474", + "block": 155914, + "from": "0x9c26685b6E8e2997d9aAf3f1a642f1b1b3dB9580", + "contract": "0xC4CF12Fb38C8169CFCb249ED4A6Cc73f92F941c5", + "datetime": "2024-02-06T16:29:16" + }, + "nft": { + "address": "0xC4CF12Fb38C8169CFCb249ED4A6Cc73f92F941c5", + "name": "GX Data NFT", + "symbol": "GX-NFT", + "state": 0, + "tokenURI": "data:application/json;base64,eyJuYW1lIjoiR1ggRGF0YSBORlQiLCJzeW1ib2wiOiJHWC1ORlQiLCJkZXNjcmlwdGlvbiI6IlRoaXMgTkZUIHJlcHJlc2VudHMgYW4gYXNzZXQgaW4gT2NlYW4gUHJvdG9jb2wgdjQgZWNvc3lzdGVtcy4iLCJleHRlcm5hbF91cmwiOiJodHRwczovL21pbmltYWwtZ2FpYS14LmV1L2Fzc2V0L2RpZDpvcDpjN2NlNGQxY2VjY2IyMTMxZDZmYmU4MDU5MmQ0ZDc2MzAxZDEwOGVlM2YwMDMxNjE0MzRmMDUxYjQxMzE3NDQwIiwiYmFja2dyb3VuZF9jb2xvciI6IjE0MTQxNCIsImltYWdlX2RhdGEiOiJkYXRhOmltYWdlL3N2Zyt4bWwsJTNDc3ZnIHZpZXdCb3g9JzAgMCA5OSA5OScgZmlsbD0ndW5kZWZpbmVkJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnJTNFJTNDcGF0aCBmaWxsPSclMjMwMDk3OTNmZicgZD0nTTAsOTlMMCwyNEM5LDIyIDE4LDIwIDI5LDIyQzM5LDIzIDUxLDI5IDYzLDMxQzc0LDMyIDg2LDI5IDk5LDI3TDk5LDk5WicvJTNFJTNDcGF0aCBmaWxsPSclMjMwMDhiYWFmZicgZD0nTTAsOTlMMCw1NUM3LDU0IDE1LDUzIDI4LDUxQzQwLDQ4IDU2LDQ0IDY5LDQ1QzgxLDQ1IDkwLDQ5IDk5LDU0TDk5LDk5WiclM0UlM0MvcGF0aCUzRSUzQ3BhdGggZmlsbD0nJTIzMDA0OTY3ZmYnIGQ9J00wLDk5TDAsNzNDMTEsNzMgMjMsNzMgMzQsNzVDNDQsNzYgNTQsNzggNjUsNzlDNzUsNzkgODcsNzYgOTksNzRMOTksOTlaJyUzRSUzQy9wYXRoJTNFJTNDL3N2ZyUzRSJ9", + "owner": "0x9c26685b6E8e2997d9aAf3f1a642f1b1b3dB9580", + "created": "2024-02-06T16:29:16" + }, + "datatokens": [ + { + "address": "0xcc7E4619Edb66808693AD09Ad3481d75c94a6c8B", + "name": "Access Token", + "symbol": "GXAT", + "serviceId": "b5e60d603a03b285a3b8cb25a4995cc9b3db5723b489a14738d2ee0e11dcd3db" + } + ], + "stats": { + "allocated": 0, + "orders": 4, + "price": { + "value": 0 + } + }, + "purgatory": { + "state": false + } +} diff --git a/test/unit/AssetBuilder.test.ts b/test/unit/AssetBuilder.test.ts index ded222e..c61ab5f 100644 --- a/test/unit/AssetBuilder.test.ts +++ b/test/unit/AssetBuilder.test.ts @@ -1,135 +1,123 @@ -// import { ZERO_ADDRESS } from '@oceanprotocol/lib' -// import assert from 'assert' -// import { AssetBuilder } from '../../src' -// import { -// algorithmMetadata, -// datasetService, -// fixedPricing -// } from '../fixtures/AssetConfig' -// import { datatokenParams } from '../fixtures/DatatokenParams' -// import { nftParams } from '../fixtures/NftCreateData' -// import { -// FileTypes, -// NautilusService, -// ServiceBuilder, -// ServiceTypes -// } from '../../src/Nautilus/Asset/Service' - -// describe('AssetBuilder', () => { -// it('builds asset.metadata correctly', async () => { -// const builder = new AssetBuilder() - -// const { type, name, author, description, license, algorithm } = -// algorithmMetadata - -// const asset = builder -// .setType(type) -// .setName(name) -// .setAuthor(author) -// .setDescription(description) -// .setLicense(license) -// .setAlgorithm(algorithm) -// .build() - -// assert.deepEqual( -// asset.ddo.metadata, -// algorithmMetadata, -// `asset.metadata does not equal the given input metadata` -// ) -// }) - -// it('builds asset.pricing correctly', async () => { -// const builder = new ServiceBuilder(ServiceTypes.ACCESS, FileTypes.URL) - -// const service = builder.setPricing(fixedPricing).build() - -// assert.deepEqual( -// service.pricing, -// fixedPricing, -// `asset.pricing does not equal the given input pricing schema` -// ) -// }) - -// it('builds asset.services correctly', async () => { -// const builder = new AssetBuilder() -// const service = datasetService as NautilusService< -// ServiceTypes.ACCESS, -// FileTypes.URL -// > - -// const asset = builder.addService(service).build() - -// assert.ok( -// asset.services.includes(service), -// `asset.services does not contain the given input service` -// ) -// }) - -// it('builds asset.datatokenCreateParams correctly', async () => { -// const builder = new AssetBuilder() - -// const { name, symbol, ...params } = datatokenParams - -// const asset = builder -// .setDatatokenData(params) -// .setDatatokenNameAndSymbol(name, symbol) -// .build() - -// assert.deepEqual( -// asset.datatokenCreateParams, -// datatokenParams, -// `asset.datatokenCreateParams does not equal the given input datatokenParams` -// ) -// }) - -// it('builds asset.nftCreateData correctly', async () => { -// const builder = new AssetBuilder() - -// const asset = builder.setNftData(nftParams).build() - -// assert.deepEqual( -// asset.nftCreateData, -// nftParams, -// `asset.nftCreateData does not equal the given input nftParams` -// ) -// }) - -// it('builds asset.owner correctly', async () => { -// const builder = new AssetBuilder() - -// const owner = 'owner' - -// const asset = builder.setOwner(owner).build() - -// assert.equal( -// asset.owner, -// owner, -// 'asset.owner does not match the given input owner' -// ) -// }) - -// it('builds with default values', async () => { -// const builder = new AssetBuilder() - -// const asset = builder.build() - -// const { nftCreateData, datatokenCreateParams } = asset - -// // Default NftCreateData -// assert.ok(typeof nftCreateData.name === 'string') -// assert.ok(typeof nftCreateData.symbol === 'string') -// assert.ok(typeof nftCreateData.templateIndex === 'number') -// assert.ok(typeof nftCreateData.tokenURI === 'string') -// assert.ok(typeof nftCreateData.transferable === 'boolean') - -// // Default DatatokenCreateParams -// assert.ok(typeof datatokenCreateParams.cap === 'string') -// assert.ok(typeof datatokenCreateParams.feeAmount === 'string') -// assert.ok(datatokenCreateParams.feeToken === ZERO_ADDRESS) -// assert.ok(datatokenCreateParams.mpFeeAddress === ZERO_ADDRESS) -// assert.ok(typeof datatokenCreateParams.templateIndex === 'number') -// // Datatoken name and symbol are undefined by default -// assert.ok(typeof datatokenCreateParams.name === 'undefined') -// assert.ok(typeof datatokenCreateParams.symbol === 'undefined') -// }) -// }) +import { expect } from 'chai' +import { AssetBuilder } from '../../src' +import { + FileTypes, + ServiceBuilder, + ServiceTypes +} from '../../src/Nautilus/Asset/Service' +import { algorithmMetadata, fixedPricing } from '../fixtures/AssetConfig' +import { nftParams } from '../fixtures/NftCreateData' +import * as AquariusAsset from '../fixtures/AquariusAsset.json' +import { Asset } from '@oceanprotocol/lib' + +describe('AssetBuilder', () => { + it('builds asset.metadata correctly', async () => { + const builder = new AssetBuilder() + + const { type, name, author, description, license, algorithm } = + algorithmMetadata + + const asset = builder + .setType(type) + .setName(name) + .setAuthor(author) + .setDescription(description) + .setLicense(license) + .setAlgorithm(algorithm) + .build() + + expect(asset.ddo.metadata).to.deep.equal(algorithmMetadata) + }) + + describe('when building from given aquariusAsset', async () => { + const aquariusAsset = AquariusAsset as Asset + const builder = new AssetBuilder(aquariusAsset) + const asset = builder.build() + const ddo = await asset.ddo.getDDO() + + it('builds asset metadata correctly from aquariusAsset', async () => { + // remove updated value, as it gets calculated with getDDO + delete ddo.metadata.updated + delete aquariusAsset.metadata.updated + + expect(ddo.metadata).to.deep.equal(aquariusAsset.metadata) + }) + + it('builds asset services correctly from aquariusAsset', async () => { + expect(ddo.services).to.deep.equal(aquariusAsset.services) + }) + }) + + it('builds asset.pricing correctly', async () => { + const builder = new ServiceBuilder({ + serviceType: ServiceTypes.ACCESS, + fileType: FileTypes.URL + }) + + const service = builder.setPricing(fixedPricing).build() + + expect(service.pricing).to.deep.equal(fixedPricing) + }) + + // TODO: move to service tests + // it('builds asset.datatokenCreateParams correctly', async () => { + // const builder = new AssetBuilder() + + // const { name, symbol, ...params } = datatokenParams + + // const asset = builder + + // .setDatatokenNameAndSymbol(name, symbol) + // .build() + + // assert.deepEqual( + // asset.datatokenCreateParams, + // datatokenParams, + // `asset.datatokenCreateParams does not equal the given input datatokenParams` + // ) + // }) + + it('builds asset.nftCreateData correctly', async () => { + const builder = new AssetBuilder() + + const asset = builder.setNftData(nftParams).build() + + expect(asset.nftCreateData).to.deep.equal(nftParams) + }) + + it('builds asset.owner correctly', async () => { + const builder = new AssetBuilder() + + const owner = 'owner' + + const asset = builder.setOwner(owner).build() + + expect(asset.owner).to.equal(owner) + }) + + it('builds with default nft values', async () => { + const builder = new AssetBuilder() + + const asset = builder.build() + + const { nftCreateData } = asset + + // Default NftCreateData + expect(nftCreateData.name).to.be.a('string') + expect(nftCreateData.symbol).to.be.a('string') + expect(nftCreateData.templateIndex).to.be.a('number') + expect(nftCreateData.tokenURI).to.be.a('string') + expect(nftCreateData.transferable).to.be.a('boolean') + + // TODO: move to service tests + // // Default DatatokenCreateParams + // assert.ok(typeof datatokenCreateParams.cap === 'string') + // assert.ok(typeof datatokenCreateParams.feeAmount === 'string') + // assert.ok(datatokenCreateParams.feeToken === ZERO_ADDRESS) + // assert.ok(datatokenCreateParams.mpFeeAddress === ZERO_ADDRESS) + // assert.ok(typeof datatokenCreateParams.templateIndex === 'number') + // // Datatoken name and symbol are undefined by default + // assert.ok(typeof datatokenCreateParams.name === 'undefined') + // assert.ok(typeof datatokenCreateParams.symbol === 'undefined') + }) +}) diff --git a/test/unit/NautilusDDO.test.ts b/test/unit/NautilusDDO.test.ts index 7d5a3e3..aff7768 100644 --- a/test/unit/NautilusDDO.test.ts +++ b/test/unit/NautilusDDO.test.ts @@ -169,7 +169,8 @@ describe('NautilusDDO', () => { 'nftAddress', 'chainId', 'metadata', - 'services' + 'services', + 'credentials' ) }) diff --git a/test/unit/NautilusService.test.ts b/test/unit/NautilusService.test.ts index 21c7cd5..fadf2e7 100644 --- a/test/unit/NautilusService.test.ts +++ b/test/unit/NautilusService.test.ts @@ -4,7 +4,6 @@ import { FileTypes, NautilusService, ServiceTypes, UrlFile } from '../../src' import * as provider from '../../src/utils/provider' import { datasetService } from '../fixtures/AssetConfig' import { getConsumerParameters } from '../fixtures/ConsumerParameters' -import { ProviderInstance } from '@oceanprotocol/lib' import { expectThrowsAsync } from '../utils.test' describe('NautilusService', () => { @@ -30,124 +29,129 @@ describe('NautilusService', () => { providerMock.expects('isValidProvider').returns(Promise.resolve(true)) }) - it('sets the id correctly if given', async () => { - const nautilusService = new NautilusService() - const preDefinedId = 'my-pre-defined-id' - nautilusService.id = preDefinedId - - const service = await nautilusService.getOceanService( - chainId, - nftAddress, - datatokenAddress - ) + describe('when it has no files', async () => { + it('throws an error', async () => { + const nautilusService = new NautilusService< + ServiceTypes, + FileTypes.URL + >() - expect(service.id).to.eq(preDefinedId) + await expectThrowsAsync(() => + nautilusService.getOceanService(chainId, nftAddress, datatokenAddress) + ) + }) }) - it('sets name and description correctly if given', async () => { - const nautilusService = new NautilusService() - const name = 'My Service Name' - const description = 'My Service Description' - nautilusService.name = name - nautilusService.description = description - - const service = await nautilusService.getOceanService( - chainId, - nftAddress, - datatokenAddress - ) + describe('when it has a valid files object', async () => { + let nautilusService: NautilusService + const encryptedFiles = '0xencryptedFilesString' + beforeEach(() => { + nautilusService = new NautilusService() + nautilusService.files = datasetService.files as UrlFile[] - expect(service.name).to.eq(name) - expect(service.description).to.eq(description) - }) + encryptedFilesExpectation.returns(Promise.resolve(encryptedFiles)) + providerMock + .expects('getFileInfo') + .returns(Promise.resolve([{ valid: true }])) + }) - it('sets consumerParameters correctly if given', async () => { - const { - textParameter, - numberParameter, - booleanParameter, - selectParameter - } = getConsumerParameters() - - const consumerParameters = [ - textParameter, - numberParameter, - booleanParameter, - selectParameter - ] - - const nautilusService = new NautilusService() - nautilusService.consumerParameters = consumerParameters - - const service = await nautilusService.getOceanService( - chainId, - nftAddress, - datatokenAddress - ) + it('sets the id correctly if given', async () => { + const preDefinedId = 'my-pre-defined-id' + nautilusService.id = preDefinedId - expect(service) - .to.have.property('consumerParameters') - .eq(consumerParameters) - }) + const service = await nautilusService.getOceanService( + chainId, + nftAddress, + datatokenAddress + ) - it('sets additionalInformation correctly if given', async () => { - const additionalInformation = { - customInfo: { - some: 'custom info' - } - } + expect(service.id).to.eq(preDefinedId) + }) - const nautilusService = new NautilusService() - nautilusService.additionalInformation = additionalInformation + it('sets name and description correctly if given', async () => { + const name = 'My Service Name' + const description = 'My Service Description' + nautilusService.name = name + nautilusService.description = description - const service = await nautilusService.getOceanService( - chainId, - nftAddress, - datatokenAddress - ) + const service = await nautilusService.getOceanService( + chainId, + nftAddress, + datatokenAddress + ) - expect(service) - .to.have.property('additionalInformation') - .eq(additionalInformation) - }) + expect(service.name).to.eq(name) + expect(service.description).to.eq(description) + }) - it('sets datatokenAddress correctly, when set via getOceanService', async () => { - const nautilusService = new NautilusService() + it('sets consumerParameters correctly if given', async () => { + const { + textParameter, + numberParameter, + booleanParameter, + selectParameter + } = getConsumerParameters() - const service = await nautilusService.getOceanService( - chainId, - nftAddress, - datatokenAddress - ) + const consumerParameters = [ + textParameter, + numberParameter, + booleanParameter, + selectParameter + ] - expect(service).to.have.property('datatokenAddress').eq(datatokenAddress) - }) + nautilusService.consumerParameters = consumerParameters + + const service = await nautilusService.getOceanService( + chainId, + nftAddress, + datatokenAddress + ) - it('throws an error if no datatokenAddress is provided', async () => { - const nautilusService = new NautilusService() + expect(service) + .to.have.property('consumerParameters') + .eq(consumerParameters) + }) - await expectThrowsAsync( - () => nautilusService.getOceanService(chainId, nftAddress), - /datatokenAddress is required/ - ) - }) + it('sets additionalInformation correctly if given', async () => { + const additionalInformation = { + customInfo: { + some: 'custom info' + } + } - describe('when it has a valid files object', async () => { - const encryptedFiles = '0xencryptedFilesString' - beforeEach(() => { - encryptedFilesExpectation.returns(Promise.resolve(encryptedFiles)) - providerMock - .expects('getFileInfo') - .returns(Promise.resolve([{ valid: true }])) + nautilusService.additionalInformation = additionalInformation + + const service = await nautilusService.getOceanService( + chainId, + nftAddress, + datatokenAddress + ) + + expect(service) + .to.have.property('additionalInformation') + .eq(additionalInformation) }) - it('correctly calls provider.encrypt', async () => { - const nautilusService = new NautilusService< - ServiceTypes, - FileTypes.URL - >() + it('sets datatokenAddress correctly, when set via getOceanService', async () => { + const service = await nautilusService.getOceanService( + chainId, + nftAddress, + datatokenAddress + ) - nautilusService.files = datasetService.files as UrlFile[] + expect(service) + .to.have.property('datatokenAddress') + .eq(datatokenAddress) + }) + + it('throws an error if no datatokenAddress is provided', async () => { + await expectThrowsAsync( + () => nautilusService.getOceanService(chainId, nftAddress), + /datatokenAddress is required/ + ) + }) + + it('correctly calls provider.encrypt', async () => { nautilusService.datatokenAddress = datatokenAddress nautilusService.serviceEndpoint = serviceEndpoint