import sinon from 'sinon'; import path from 'node:path'; import { promises as fsp } from 'node:fs'; import { expect } from 'chai'; import { randomUUID } from 'node:crypto'; import { CollectionModuleCodeFileWithUrl, CollectionModuleDefinitionRequest, } from '../../../domain/collection-modules/collection-module-definition'; import { readCollectionModuleDefinition } from '../read-collection-module-definition'; import { writeCollectionModuleDefinition } from '../write-collection-module-definition'; import { readAuthAndConfig } from '../../read-auth-and-config'; import { CollectionModuleConfig } from '../../../domain/collection-modules/collection-module-config'; import * as codeFileHelpers from '../code-file-helpers'; const fakeCreateCodeFilesSignedUrls = async (params: { codeFiles: T[]; collectionModuleKey: string; host: string; apiKey: string; operation: codeFileHelpers.S3Operation; }) => { const { codeFiles } = params; return codeFiles.map((codeFile) => { return { ...codeFile, signedUrl: 'https://fake-url.test/download?signed=true', }; }); }; const fakeAddContentToCodeFile = async (codeFile: CollectionModuleCodeFileWithUrl) => { const filePath = path.join( '.', 'test-modules', 'collection-modules', 'example_module', 'code', ...codeFile.pathSegments, ); const content = (await fsp.readFile(filePath)).toString(); return { ...codeFile, content, }; }; describe('writeCollectionModuleDefinition and readCollectionModuleDefinition', function () { const sandbox = sinon.createSandbox(); const tmpDirectory = path.join(__dirname, 'tmp'); let existingDefinition: CollectionModuleDefinitionRequest; let newDefinition: CollectionModuleDefinitionRequest; after(async function () { await fsp.rm(tmpDirectory, { recursive: true, force: true }); sandbox.verifyAndRestore(); }); before('Read and then write the same collection module definition', async function () { const exampleDefinitionDirectory = path.join('.', 'test-modules', 'collection-modules', 'example_module'); const newDefinitionDirectory = path.join(__dirname, 'tmp', 'test_writing_definition'); await fsp.mkdir(tmpDirectory); await fsp.mkdir(newDefinitionDirectory); const { apiKey, config } = readAuthAndConfig(exampleDefinitionDirectory); existingDefinition = await readCollectionModuleDefinition({ collectionModuleConfig: config as CollectionModuleConfig, directory: exampleDefinitionDirectory, }); sandbox.replace(codeFileHelpers, 'createCodeFilesSignedUrls', fakeCreateCodeFilesSignedUrls); sandbox.replace(codeFileHelpers, 'addContentToCodeFile', fakeAddContentToCodeFile); await writeCollectionModuleDefinition({ collectionModuleDefinition: { ...existingDefinition, collectionModuleDefinitionId: randomUUID(), organizationId: config.organizationId, collectionModuleName: 'Example Collection Module', }, directory: newDefinitionDirectory, host: 'https://fake-url.test', apiKey, liveVersion: false, }); newDefinition = await readCollectionModuleDefinition({ collectionModuleConfig: config as CollectionModuleConfig, directory: newDefinitionDirectory, }); }); it('the collection module key should remain unchanged', function () { expect(existingDefinition.collectionModuleKey).to.equal(newDefinition.collectionModuleKey); }); it('the code should remain unchanged', function () { for (const existingCodeFile of existingDefinition.codeFiles) { const newCodeFile = newDefinition.codeFiles.find( (file) => file.pathSegments.join('/') === existingCodeFile.pathSegments.join('/'), ); expect(newCodeFile?.content).to.equal(existingCodeFile.content); } }); it('the settings should remain unchanged', function () { expect(newDefinition.rootConfig.settings).to.deep.equal(existingDefinition.rootConfig.settings); }); it('the manual transactions should remain unchanged', function () { expect(newDefinition.rootConfig.manualTransactions).to.deep.equal(existingDefinition.rootConfig.manualTransactions); }); it('the manual transaction workflow schemas should remain unchanged', function () { for (const existingWorkflow of existingDefinition.workflows.manualTransactionWorkflows) { const newWorkflow = newDefinition.workflows.manualTransactionWorkflows.find( (t) => t.key === existingWorkflow.key, ); expect(newWorkflow?.schema).to.deep.equal(existingWorkflow.schema); } }); });