From ee97319495fe0eaefebafa45cef4e0e74e655fa9 Mon Sep 17 00:00:00 2001 From: Moritz Kirstein Date: Tue, 5 Mar 2024 12:15:51 +0100 Subject: [PATCH] Fix/trusted algorithms (#68) * refactor: move checkDidFiles to provider utils * fix: correctly continue resolving * test: add aquarius and provider mocks * test: add trusted algorithms unit test * chore: remove console log * chore: remove only from unit test --- src/utils/helpers/trusted-algorithms.ts | 25 ++------- src/utils/provider.ts | 18 +++++++ test/mocks/aquarius.ts | 17 ++++++ test/mocks/provider.ts | 8 +++ test/unit/NautilusService.test.ts | 8 +-- test/unit/Utils.test.ts | 72 +++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 25 deletions(-) create mode 100644 test/mocks/aquarius.ts create mode 100644 test/mocks/provider.ts create mode 100644 test/unit/Utils.test.ts diff --git a/src/utils/helpers/trusted-algorithms.ts b/src/utils/helpers/trusted-algorithms.ts index 73d877f..ed83e42 100644 --- a/src/utils/helpers/trusted-algorithms.ts +++ b/src/utils/helpers/trusted-algorithms.ts @@ -7,6 +7,7 @@ import { } from '@oceanprotocol/lib' import { getAsset } from '../aquarius' import { FileTypes, NautilusService, ServiceTypes } from '../../Nautilus' +import { checkDidFiles } from '../provider' // TODO replace hardcoded service index 0 with service id once supported by the stack async function getPublisherTrustedAlgorithms( @@ -30,7 +31,7 @@ async function getPublisherTrustedAlgorithms( throw new Error(`Asset ${asset.id} is not of type algorithm`) if (!asset.services?.[0]) throw new Error(`No service in ${asset.id}`) - const filesChecksum = await getFileDidInfo( + const filesChecksum = await checkDidFiles( asset?.id, asset?.services?.[0]?.id, asset?.services?.[0]?.serviceEndpoint @@ -53,30 +54,12 @@ async function getPublisherTrustedAlgorithms( return trustedAlgorithms } -async function getFileDidInfo( - did: string, - serviceId: string, - providerUrl: string -): Promise { - try { - const response = await ProviderInstance.checkDidFiles( - did, - serviceId, - providerUrl, - true - ) - return response - } catch (error) { - throw new Error(`[Initialize check file did] Error:' ${error}`) - } -} - export async function resolvePublisherTrustedAlgorithms( nautilusDDOServices: NautilusService[], metadataCacheUri: string ) { for (const service of nautilusDDOServices) { - if (service.addedPublisherTrustedAlgorithms?.length) continue + if (service.addedPublisherTrustedAlgorithms?.length < 1) continue const dids = service.addedPublisherTrustedAlgorithms.map( (asset) => asset.did @@ -88,7 +71,7 @@ export async function resolvePublisherTrustedAlgorithms( if (service.compute?.publisherTrustedAlgorithms?.length === 0) { service.compute.publisherTrustedAlgorithms = newPublisherTrustedAlgorithms - return + continue } newPublisherTrustedAlgorithms.forEach((algorithm) => { diff --git a/src/utils/provider.ts b/src/utils/provider.ts index 20a3577..1be82b5 100644 --- a/src/utils/provider.ts +++ b/src/utils/provider.ts @@ -48,6 +48,24 @@ export async function getEncryptedFiles( } } +export async function checkDidFiles( + did: string, + serviceId: string, + providerUrl: string +): Promise { + try { + const response = await ProviderInstance.checkDidFiles( + did, + serviceId, + providerUrl, + true + ) + return response + } catch (error) { + throw new Error(`[Initialize check file did] Error:' ${error}`) + } +} + export async function initializeProvider( asset: AssetWithAccessDetails, accountId: string, diff --git a/test/mocks/aquarius.ts b/test/mocks/aquarius.ts new file mode 100644 index 0000000..8aa364c --- /dev/null +++ b/test/mocks/aquarius.ts @@ -0,0 +1,17 @@ +import * as aquarius from '../../src/utils/aquarius' +import * as AquariusAsset from '../fixtures/AquariusAsset.json' +import sinon from 'sinon' + +const RETURNED_ASSET = AquariusAsset +const RETURNED_ASSET_ARRAY = [AquariusAsset, AquariusAsset] + +export function mockAquarius(): sinon.SinonMock { + const aquariusMock = sinon.mock(aquarius) + + aquariusMock.expects('getAsset').returns(Promise.resolve(RETURNED_ASSET)) + aquariusMock + .expects('getAssets') + .returns(Promise.resolve(RETURNED_ASSET_ARRAY)) + + return aquariusMock +} diff --git a/test/mocks/provider.ts b/test/mocks/provider.ts new file mode 100644 index 0000000..1405a49 --- /dev/null +++ b/test/mocks/provider.ts @@ -0,0 +1,8 @@ +import sinon from 'sinon' +import * as provider from '../../src/utils/provider' + +export function mockProvider(): sinon.SinonMock { + const providerMock = sinon.mock(provider) + + return providerMock +} diff --git a/test/unit/NautilusService.test.ts b/test/unit/NautilusService.test.ts index fadf2e7..f7bce83 100644 --- a/test/unit/NautilusService.test.ts +++ b/test/unit/NautilusService.test.ts @@ -1,10 +1,10 @@ import { expect } from 'chai' import sinon from 'sinon' 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 { expectThrowsAsync } from '../utils.test' +import { mockProvider } from '../mocks/provider' describe('NautilusService', () => { let providerMock: sinon.SinonMock @@ -14,11 +14,11 @@ describe('NautilusService', () => { const nftAddress = '0x1234NFT' const datatokenAddress = '0x1234DATATOKEN' - beforeEach(() => { - providerMock = sinon.mock(provider) + before(() => { + providerMock = mockProvider() }) - afterEach(() => { + after(() => { providerMock.restore() }) diff --git a/test/unit/Utils.test.ts b/test/unit/Utils.test.ts new file mode 100644 index 0000000..58dd732 --- /dev/null +++ b/test/unit/Utils.test.ts @@ -0,0 +1,72 @@ +import { Asset, LogLevel, LoggerInstance, getHash } from '@oceanprotocol/lib' +import { ServiceBuilder } from '../../src' +import { resolvePublisherTrustedAlgorithms } from '../../src/utils/helpers/trusted-algorithms' +import * as AquariusAsset from '../fixtures/AquariusAsset.json' +import { expect } from 'chai' +import sinon from 'sinon' +import { mockAquarius } from '../mocks/aquarius' +import { mockProvider } from '../mocks/provider' + +describe('Utils', () => { + let aquariusMock: sinon.SinonMock + let providerMock: sinon.SinonMock + + before(() => { + LoggerInstance.setLevel(LogLevel.Verbose) + aquariusMock = mockAquarius() + providerMock = mockProvider() + }) + + after(() => { + aquariusMock.restore() + providerMock.restore() + }) + + describe('Trusted Algorithms', async () => { + const containerChecksum = getHash( + AquariusAsset.metadata.algorithm.container.entrypoint + + AquariusAsset.metadata.algorithm.container.checksum + ) + const trustedAlgorithms = { + did: AquariusAsset.id, + filesChecksum: 'filesChecksum', + containerSectionChecksum: containerChecksum + } + + beforeEach(() => { + providerMock + .expects('checkDidFiles') + .returns( + Promise.resolve([ + { type: '', valid: true, checksum: trustedAlgorithms.filesChecksum } + ]) + ) + }) + + it('should resolve publisherTrustedAlgorithms correctly', async () => { + const serviceBuilder = new ServiceBuilder({ + aquariusAsset: AquariusAsset as Asset, + serviceId: AquariusAsset.services[0].id + }) + + const service = serviceBuilder + .addTrustedAlgorithms([ + { + did: AquariusAsset.id + } + ]) + .build() + + await resolvePublisherTrustedAlgorithms( + [service], + 'https://dummy.metadatacache' + ) + + expect(service) + .to.have.property('compute') + .to.have.property('publisherTrustedAlgorithms') + .to.have.lengthOf.above(0) + .to.deep.include(trustedAlgorithms) + }) + }) +})