import { describe } from 'mocha'; import { expect } from 'chai'; import { RoCrateTransformer } from '../../src/transformers/RoCrateTransformer'; import ResearchObjectTi from '../../src/ResearchObject-ti'; import { RoCrate, RoCrateGraph } from '../../src/RoCrate'; import { createCheckers } from 'ts-interface-checker'; import exampleNode from '../example-data/exampleNode.json'; import exampleRoCrate from '../example-data/exampleRoCrate.json'; import exampleNodeWithAuthors from '../example-data/exampleNodeWithAuthors.json'; import expectedJsonLd from '../example-data/exampleNodeToRoCrate.json'; import exampleRoCrateWithWorkflow from '../example-data/roCrateWithWorkflow.json'; import { CodeComponent, DataComponent, PdfComponent, ResearchObjectV1 } from '../../src/ResearchObject'; import { CreativeWork } from 'schema-dts'; const context = 'https://www.researchobject.org/ro-crate/1.1/context.jsonld'; const checkers = createCheckers(ResearchObjectTi); const transformer = new RoCrateTransformer(); describe('RoCrateTransformer', () => { it('Imports a simple valid RO-Crate object', () => { const roCrate = exampleRoCrate; const researchObject = transformer.importObject(roCrate); checkers.ResearchObjectV1.check(researchObject); }); // skipping due to lossy conversion, need to update spec to capture encoding it('Exports a simple valid ResearchObject to RO-Crate format', async () => { const researchObject = exampleNode; const roCrate = transformer.exportObject(researchObject); // Validate the output as JSON-LD // res = await compact(roCrate["@graph"], roCrate["@context"]); expect(roCrate).to.deep.equal(expectedJsonLd); }); it('Properly imports PDF components', () => { const roCrate = exampleRoCrate; const researchObject = transformer.importObject(roCrate) as ResearchObjectV1; const pdfComponent = researchObject.components.find((component) => component.type === 'pdf') as PdfComponent; expect(pdfComponent).to.not.be.undefined; expect(pdfComponent.payload.url).to.equal('https://example.com/example.pdf'); }); it('Properly imports code components', () => { const roCrate = exampleRoCrateWithWorkflow; const researchObject = transformer.importObject(roCrate) as ResearchObjectV1; const codeComponent = researchObject.components.find((component) => component.type === 'code') as CodeComponent; expect(codeComponent).to.not.be.undefined; expect(codeComponent.payload.url).to.equal('http://example.com/workflows/alignment'); }); it('Properly imports data components', () => { const roCrate = exampleRoCrate; const researchObject = transformer.importObject(roCrate) as ResearchObjectV1; const dataComponent = researchObject.components.find((component) => component.type === 'data') as DataComponent; expect(dataComponent).to.not.be.undefined; expect(dataComponent.payload.cid).to.equal('https://doi.org/10.5281/zenodo.1234567'); }); it('Properly exports PDF components', () => { const researchObject = exampleNode; const roCrate = transformer.exportObject(researchObject) as RoCrate; const pdfComponent = roCrate['@graph'].find( (item: RoCrateGraph) => typeof item !== 'string' && item['@type'] && item['@type'] === 'CreativeWork' && (item as CreativeWork).encodingFormat === 'application/pdf', ) as CreativeWork; expect(pdfComponent).to.not.be.undefined; expect(pdfComponent.url).to.equal( 'https://ipfs.io/ipfs/bafybeic3ach4ibambafznjsa3p446ghds3hp7742fkisldroe4wt6q5bsy', ); expect((pdfComponent as any)['/']).to.equal('bafybeic3ach4ibambafznjsa3p446ghds3hp7742fkisldroe4wt6q5bsy'); }); it('Properly exports code components', () => { const researchObject = exampleNode; const roCrate = transformer.exportObject(researchObject); const codeComponent = roCrate['@graph'].find( (item: RoCrateGraph) => typeof item !== 'string' && item['@type'] === 'SoftwareSourceCode' && item.encodingFormat === 'text/plain', ); expect(codeComponent).to.not.be.undefined; expect(codeComponent['/']).to.equal('bafybeibzxn2il4q7att4bf3lvrcc2peovcdokv3jsbzne5v6ad5tr6mi6i'); expect(codeComponent.url).to.equal( 'https://ipfs.io/ipfs/bafybeibzxn2il4q7att4bf3lvrcc2peovcdokv3jsbzne5v6ad5tr6mi6i', ); }); it('Properly exports data components', () => { const researchObject = exampleNode; const roCrate = transformer.exportObject(researchObject); const dataComponent = roCrate['@graph'].find( (item: RoCrateGraph) => typeof item !== 'string' && item['@type'] === 'Dataset' && item.encodingFormat === 'application/octet-stream', ); expect(dataComponent).to.not.be.undefined; expect(dataComponent.url).to.equal( 'https://ipfs.io/ipfs/bafybeigzwjr6xkcdy4b7rrtzbbpwq3isx3zaesfopnpr3bqld3uddc5k3m', ); expect(dataComponent['/']).to.equal('bafybeigzwjr6xkcdy4b7rrtzbbpwq3isx3zaesfopnpr3bqld3uddc5k3m'); }); it('Properly exports authors', () => { const researchObject = exampleNodeWithAuthors; const roCrate = transformer.exportObject(researchObject); // console.log("RO", roCrate); const authors = roCrate['@graph'].filter( (item: RoCrateGraph) => typeof item !== 'string' && item['@type'] === 'Person', ); expect(authors).to.not.be.undefined; expect(authors.length).to.equal(17); }); it('Properly handles CEDAR link', () => { const researchObject = exampleNodeWithAuthors; const roCrate = transformer.exportObject(researchObject); // console.log("RO", roCrate); const cedar = roCrate['@graph'].find( (item: RoCrateGraph) => typeof item !== 'string' && item['@type'] === 'Dataset' && item['@id'] == 'dd562a70-0bb9-4a07-8b00-c414bc8b9ad9' && item['schemaVersion'] && item['schemaVersion'].toString().length > 0, ); expect(cedar).to.not.be.undefined; }); it('Adds orcid.org prefix to author ids', () => { const researchObject = exampleNodeWithAuthors; const roCrate = transformer.exportObject(researchObject); // console.log("RO", roCrate); console.log('EXPORTED RO-CRATE', JSON.stringify(roCrate)); const authors = roCrate['@graph'].filter( (item: RoCrateGraph) => typeof item !== 'string' && item['@type'] === 'Person', ); expect(authors).to.not.be.undefined; expect(authors[0]['@id']).to.equal(`https://orcid.org/${researchObject.authors[0].orcid}`); }); });