diff --git a/packages/untp-test-suite/__tests__/interfaces/cli/testResultProcessor.test.ts b/packages/untp-test-suite/__tests__/interfaces/cli/testResultProcessor.test.ts index 91ea1df4..1b151be9 100644 --- a/packages/untp-test-suite/__tests__/interfaces/cli/testResultProcessor.test.ts +++ b/packages/untp-test-suite/__tests__/interfaces/cli/testResultProcessor.test.ts @@ -38,6 +38,12 @@ jest.mock( jest.mock('../../../src/utils/common', () => ({ getPackageVersion: () => '0.0.1', + truncateString: jest.fn((str: string, maxLength: number) => { + if (str.length <= maxLength) { + return str; + } + return `${str.slice(0, maxLength)}...`; + }), })); const errorTestSuite = { diff --git a/packages/untp-test-suite/__tests__/interfaces/utils/common.test.ts b/packages/untp-test-suite/__tests__/interfaces/utils/common.test.ts index 2877b10c..eca1850a 100644 --- a/packages/untp-test-suite/__tests__/interfaces/utils/common.test.ts +++ b/packages/untp-test-suite/__tests__/interfaces/utils/common.test.ts @@ -1,6 +1,6 @@ import fs from 'fs/promises'; -import { readJsonFile } from '../../../src/interfaces/utils/common'; +import { readJsonFile, truncateString } from '../../../src/interfaces/utils/common'; describe('readJsonFile', () => { const credentialFilePath = 'config/credential.json'; @@ -31,3 +31,35 @@ describe('readJsonFile', () => { expect(fileData).toBeNull(); }); }); + +describe('truncateString', () => { + it('should return the original string if it is shorter than the maxLength', () => { + const result = truncateString('Short text', 20); + expect(result).toBe('Short text'); + }); + + it('should return the original string if its length is equal to the maxLength', () => { + const result = truncateString('Exact length', 12); + expect(result).toBe('Exact length'); + }); + + it('should return the truncated string with "..." if it exceeds the maxLength', () => { + const result = truncateString('This is a very long string', 10); + expect(result).toBe('This is a ...'); + }); + + it('should return an empty string if an empty string is provided', () => { + const result = truncateString('', 10); + expect(result).toBe(''); + }); + + it('should handle a very short maxLength and still return a truncated string with "..."', () => { + const result = truncateString('Hello World', 3); + expect(result).toBe('Hel...'); + }); + + it('should return the original string if maxLength is greater than string length', () => { + const result = truncateString('Hello', 10); + expect(result).toBe('Hello'); + }); +}); diff --git a/packages/untp-test-suite/integration/cli/untpTest.integration.test.ts b/packages/untp-test-suite/integration/cli/untpTest.integration.test.ts index 7f4e7ac8..398e77b7 100644 --- a/packages/untp-test-suite/integration/cli/untpTest.integration.test.ts +++ b/packages/untp-test-suite/integration/cli/untpTest.integration.test.ts @@ -3,7 +3,7 @@ import fs from 'fs'; import { exec } from 'child_process'; import { IConfigContent } from '../../build/core/types'; -describe("CLI 'untp test' Commands", () => { +describe("CLI 'untp test' Commands with local schema", () => { afterEach(() => { jest.clearAllMocks(); }); @@ -172,3 +172,171 @@ describe("CLI 'untp test' Commands", () => { }); }); }); + +describe("CLI 'untp test' Commands with remote schema", () => { + describe('validation of `schema` in the configuration file', () => { + let credentialFileName: string; + let storePath: string; + let stdout: any; + let credentials: IConfigContent[]; + + const mockPath = `${process.cwd()}/integration/mock/untpTestPass`; + + beforeAll((done) => { + credentialFileName = 'credentialsRemoteSchema.json'; + storePath = `${mockPath}/${credentialFileName}`; + const fileContent = fs.readFileSync(storePath, 'utf8'); + + try { + credentials = JSON.parse(fileContent).credentials; + } catch (error) { + expect(error).toBeNull(); + } + + exec(`yarn untp test`, (error, result) => { + if (error) { + console.error(`execSync error: ${error}`); + return; + } + + stdout = result; + done(); + }); + }); + + it('should ensure that the schema file of each credential exists', () => { + expect(stdout).not.toBeNull(); + for (const credential of credentials) { + expect(fs.existsSync(`${process.cwd()}/src/schemas/${credential.type}/${credential.version}/schema.json`)).toBe( + true, + ); + } + }); + + it('should return the content of `schema` when file is valid', () => { + expect(stdout).not.toBeNull(); + for (const credential of credentials) { + const data = fs.readFileSync( + `${process.cwd()}/src/schemas/${credential.type}/${credential.version}/schema.json`, + 'utf8', + ); + + expect(data).not.toBe(''); + } + }); + }); + + describe('process test runner and final report return PASS', () => { + let credentialFileName: string; + let storePath: string; + let stdout: any; + + const mockPath = `${process.cwd()}/integration/mock/untpTestPass`; + beforeAll((done) => { + credentialFileName = 'credentialsRemoteSchema.json'; + storePath = `${mockPath}/${credentialFileName}`; + + exec(`yarn untp test -c ${storePath}`, (error, result) => { + if (error) { + console.error(`execSync error: ${error}`); + return; + } + + stdout = result; + done(); + }); + }); + + it('should show PASS in report when all data validate', () => { + expect(stdout).toMatch(/PASS/); + expect(stdout).toContain('Your credentials are UNTP compliant'); + }); + }); + + describe('process test runner and final report return FAIL', () => { + let credentialFileName: string; + let storePath: string; + let stdout: any; + + const mockPath = `${process.cwd()}/integration/mock/untpTestFail`; + beforeAll((done) => { + credentialFileName = 'credentialsRemoteSchema.json'; + storePath = `${mockPath}/${credentialFileName}`; + + exec(`yarn untp test -c ${storePath}`, (error, result) => { + if (error) { + console.error(`execSync error: ${error}`); + return; + } + + stdout = result; + done(); + }); + }); + + it('should show FAIL in the report when data invalidate', () => { + expect(stdout).toMatch(/FAIL/); + expect(stdout).toMatch(/Your credentials are not UNTP compliant/); + expect(stdout).toContain('url field Failed to fetch data '); + expect(stdout).toContain(`field must have required property 'id'.`); + expect(stdout).toContain(`url field The URL 'in-valid-url' is not a valid URL..`); + expect(stdout).toContain(`url field The URL 'abc://example.com' must use http or https protocol..`); + }); + }); + + describe('process test runner and final report return WARN', () => { + let credentialFileName: string; + let storePath: string; + let stdout: any; + + const mockPath = `${process.cwd()}/integration/mock/untpTestWarn`; + beforeAll((done) => { + credentialFileName = 'credentialsRemoteSchema.json'; + storePath = `${mockPath}/${credentialFileName}`; + + exec(`yarn untp test -c ${storePath}`, (error, result) => { + if (error) { + console.error(`execSync error: ${error}`); + return; + } + + stdout = result; + done(); + }); + }); + + it('should show WARN in the report when data invalidate', () => { + expect(stdout).toMatch(/WARN/); + expect(stdout).toMatch(/Your credentials are UNTP compliant, but have extended the data model/); + }); + }); + + describe('process test runner with result combine FAIL and WARN and final report return FAIL', () => { + let credentialFileName: string; + let storePath: string; + let stdout: any; + + const mockPath = `${process.cwd()}/integration/mock/untpTestFailuresAndWarnings`; + beforeAll((done) => { + credentialFileName = 'credentialsRemoteSchema.json'; + storePath = `${mockPath}/${credentialFileName}`; + + exec(`yarn untp test -c ${storePath}`, (error, result) => { + if (error) { + console.error(`execSync error: ${error}`); + return; + } + + stdout = result; + done(); + }); + }); + + it('should show WARN in the report when data invalidate', () => { + expect(stdout).toMatch(/FAIL/); + expect(stdout).toMatch(/Your credentials are not UNTP compliant/); + expect(stdout).toContain('Additional property found'); + expect(stdout).toContain('url field Failed to fetch data from the URL'); + }); + }); +}); diff --git a/packages/untp-test-suite/integration/mock/untpTestFail/credentialsRemoteSchema.json b/packages/untp-test-suite/integration/mock/untpTestFail/credentialsRemoteSchema.json new file mode 100644 index 00000000..eb773464 --- /dev/null +++ b/packages/untp-test-suite/integration/mock/untpTestFail/credentialsRemoteSchema.json @@ -0,0 +1,28 @@ +{ + "credentials": [ + { + "type": "objectEvent", + "version": "v0.0.1", + "dataPath": "integration/mock/untpTestPass/data/objectEvent.json", + "url": "in-valid-url" + }, + { + "type": "", + "version": "", + "dataPath": "integration/mock/untpTestFail/data/objectEvent.json", + "url": "abc://example.com" + }, + { + "type": "", + "version": "", + "dataPath": "integration/mock/untpTestFail/data/objectEvent.json", + "url": "https://jargon.sh/user/unece/traceabilityEvents/v/0.3.10/artefacts/jsonSchemas/DigitalTraceabilityEvent.js" + }, + { + "type": "", + "version": "", + "dataPath": "integration/mock/untpTestFail/data/objectEvent.json", + "url": "https://jargon.sh/user/unece/traceabilityEvents/v/0.3.10/artefacts/jsonSchemas/DigitalTraceabilityEvent.json?class=DigitalTraceabilityEvent" + } + ] +} diff --git a/packages/untp-test-suite/integration/mock/untpTestFailuresAndWarnings/credentialsRemoteSchema.json b/packages/untp-test-suite/integration/mock/untpTestFailuresAndWarnings/credentialsRemoteSchema.json new file mode 100644 index 00000000..63599fc7 --- /dev/null +++ b/packages/untp-test-suite/integration/mock/untpTestFailuresAndWarnings/credentialsRemoteSchema.json @@ -0,0 +1,16 @@ +{ + "credentials": [ + { + "type": "", + "version": "", + "dataPath": "integration/mock/untpTestWarn/data/objectEvent.json", + "url": "https://jargon.sh/user/unece/traceabilityEvents/v/working/artefacts/jsonSchemas/AssociationEvent.json?class=AssociationEvent" + }, + { + "type": "", + "version": "", + "dataPath": "integration/mock/untpTestWarn/data/associationEvent.json", + "url": "https://jargon.sh/user/unece/traceabilityEvents/v/working/artefacts/jsonSchemas/AssociationEvent.json?class=AssociationEvents" + } + ] +} diff --git a/packages/untp-test-suite/integration/mock/untpTestPass/credentialsRemoteSchema.json b/packages/untp-test-suite/integration/mock/untpTestPass/credentialsRemoteSchema.json new file mode 100644 index 00000000..12dbe191 --- /dev/null +++ b/packages/untp-test-suite/integration/mock/untpTestPass/credentialsRemoteSchema.json @@ -0,0 +1,16 @@ +{ + "credentials": [ + { + "type": "objectEvent", + "version": "v0.0.1", + "dataPath": "integration/mock/untpTestPass/data/digitalTraceabilityEvent.json", + "url": "https://jargon.sh/user/unece/traceabilityEvents/v/0.3.10/artefacts/jsonSchemas/DigitalTraceabilityEvent.json?class=DigitalTraceabilityEvent" + }, + { + "type": "transformationEvent", + "version": "v0.0.1", + "dataPath": "integration/mock/untpTestPass/data/transformationEvent.json", + "url": "" + } + ] +} diff --git a/packages/untp-test-suite/integration/mock/untpTestPass/data/digitalTraceabilityEvent.json b/packages/untp-test-suite/integration/mock/untpTestPass/data/digitalTraceabilityEvent.json new file mode 100644 index 00000000..b94bb54f --- /dev/null +++ b/packages/untp-test-suite/integration/mock/untpTestPass/data/digitalTraceabilityEvent.json @@ -0,0 +1,352 @@ +{ + "type": ["DigitalTraceabilityEvent", "VerifiableCredential"], + "id": "https://example-company.com/credentials/2a423366-a0d6-4855-ba65-2e0c926d09b0", + "@context": ["https://www.w3.org/ns/credentials/v2", "https://vocabulary.uncefact.org/untp/dte/0.3.10"], + "issuer": { + "type": ["CredentialIssuer"], + "id": "did:web:identifiers.example-company.com:12345", + "name": "Example Company Pty Ltd", + "otherIdentifiers": [ + { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + } + ] + }, + "validFrom": "2024-03-15T12:00:00", + "credentialSubject": [ + { + "type": ["TransformationEvent", "Event"], + "id": "https://events.sample.com/b681df10-c682-454a-b11b-d0b9374c01bd", + "eventTime": "2024-09-01T12:00:00", + "action": "add", + "disposition": "https://ref.gs1.org/cbv/Disp-active", + "bizStep": "https://ref.gs1.org/cbv/BizStep-commissioning", + "bizLocation": "https://id.gs1.org/414/9520123456788", + "sensorElementList": [ + { + "sensorMetadata": { + "device": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "dataProcessingMethod": "https://standards.org/sensorMethod#1234" + }, + "sensorReport": [ + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + }, + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + } + ], + "sensorIntegrityProof": "https://jargon.sh" + }, + { + "sensorMetadata": { + "device": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "dataProcessingMethod": "https://standards.org/sensorMethod#1234" + }, + "sensorReport": [ + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + }, + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + } + ], + "sensorIntegrityProof": "https://jargon.sh" + } + ], + "outputEPCList": [ + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + } + ], + "inputEPCList": [ + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + } + ], + "inputQuantityList": [ + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + }, + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + } + ], + "outputQuantityList": [ + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + }, + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + } + ], + "processType": "https://textileIndustry.org/spinning" + }, + { + "type": ["ObjectEvent", "Event"], + "id": "https://events.sample.com/b681df10-c682-454a-b11b-d0b9374c01bd", + "eventTime": "2024-09-01T12:00:00", + "action": "add", + "disposition": "https://ref.gs1.org/cbv/Disp-active", + "bizStep": "https://ref.gs1.org/cbv/BizStep-commissioning", + "bizLocation": "https://id.gs1.org/414/9520123456788", + "sensorElementList": [ + { + "sensorMetadata": { + "device": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "dataProcessingMethod": "https://standards.org/sensorMethod#1234" + }, + "sensorReport": [ + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + }, + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + } + ], + "sensorIntegrityProof": "https://jargon.sh" + }, + { + "sensorMetadata": { + "device": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "dataProcessingMethod": "https://standards.org/sensorMethod#1234" + }, + "sensorReport": [ + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + }, + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + } + ], + "sensorIntegrityProof": "https://jargon.sh" + } + ], + "epcList": [ + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + } + ], + "quantityList": [ + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + }, + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + } + ] + } + ] +} diff --git a/packages/untp-test-suite/integration/mock/untpTestWarn/credentialsRemoteSchema.json b/packages/untp-test-suite/integration/mock/untpTestWarn/credentialsRemoteSchema.json new file mode 100644 index 00000000..531b90f0 --- /dev/null +++ b/packages/untp-test-suite/integration/mock/untpTestWarn/credentialsRemoteSchema.json @@ -0,0 +1,10 @@ +{ + "credentials": [ + { + "type": "", + "version": "", + "dataPath": "integration/mock/untpTestWarn/data/objectEvent.json", + "url": "https://jargon.sh/user/unece/traceabilityEvents/v/working/artefacts/jsonSchemas/AssociationEvent.json?class=AssociationEvent" + } + ] +} diff --git a/packages/untp-test-suite/integration/mock/untpTestWarn/data/associationEvent.json b/packages/untp-test-suite/integration/mock/untpTestWarn/data/associationEvent.json new file mode 100644 index 00000000..070d8291 --- /dev/null +++ b/packages/untp-test-suite/integration/mock/untpTestWarn/data/associationEvent.json @@ -0,0 +1,140 @@ +{ + "type": ["AssociationEvent", "Event"], + "id": "https://events.sample.com/b681df10-c682-454a-b11b-d0b9374c01bd", + "eventTime": "2024-09-01T12:00:00", + "action": "Add", + "disposition": "https://ref.gs1.org/cbv/Disp-active", + "bizStep": "https://ref.gs1.org/cbv/BizStep-commissioning", + "bizLocation": "https://id.gs1.org/414/9520123456788", + "sensorElementList": [ + { + "sensorMetadata": { + "device": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "dataProcessingMethod": "https://standards.org/sensorMethod#1234" + }, + "sensorReport": [ + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + }, + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + } + ], + "sensorIntegrityProof": "https://jargon.sh" + }, + { + "sensorMetadata": { + "device": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "dataProcessingMethod": "https://standards.org/sensorMethod#1234" + }, + "sensorReport": [ + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + }, + { + "time": "2024-07-24T12:00:00", + "sensorType": "https://samplesensors.com/model1234", + "value": 25, + "uom": "KGM" + } + ], + "sensorIntegrityProof": "https://jargon.sh" + } + ], + "parentEPC": { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "childEPCs": [ + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + { + "type": ["Item", "Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + } + ], + "childQuantityList": [ + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + }, + { + "product": { + "type": ["Entity"], + "id": "https://id.gs1.org/01/09520123456788/21/12345", + "name": "EV battery 300Ah.", + "registeredId": "90664869327", + "idScheme": { + "type": ["IdentifierScheme"], + "id": "https://id.gs1.org/01/", + "name": "Global Trade Identification Number (GTIN)" + } + }, + "quantity": 20, + "uom": "KGM" + } + ] +} diff --git a/packages/untp-test-suite/src/interfaces/cli/testResultProcessor.ts b/packages/untp-test-suite/src/interfaces/cli/testResultProcessor.ts index c2b0bdbb..8bab4bf4 100644 --- a/packages/untp-test-suite/src/interfaces/cli/testResultProcessor.ts +++ b/packages/untp-test-suite/src/interfaces/cli/testResultProcessor.ts @@ -8,6 +8,7 @@ import { ITestSuiteResult, TestSuiteResultEnum, } from '../../core/types/index.js'; +import { truncateString } from '../utils/common.js'; export function getLogStatus(credentialTestResults: ICredentialTestResult[]) { let resultMessage = ''; @@ -40,12 +41,13 @@ export function getFinalReport(testSuiteResult: ITestSuiteResult) { const credentialStatuses = credentialTestResults.map((credentialTestResult) => [ credentialTestResult.credentialType, credentialTestResult.version, + truncateString(credentialTestResult.url, 50), getMessageWithColorByResult(credentialTestResult.result, credentialTestResult.result), ]); table.push([{ colSpan: 3, content: chalk.blue.bold('UNTP Core Test Suite'), hAlign: 'center' }]); table.push([{ colSpan: 3, content: chalk.blue.bold(`Runner version ${packageVersion}`), hAlign: 'center' }]); - table.push(['Credential Type', 'Version', 'Status']); + table.push(['Credential Type', 'Version', 'URL', 'Status']); table.push(...credentialStatuses); table.push([ { diff --git a/packages/untp-test-suite/src/interfaces/utils/common.ts b/packages/untp-test-suite/src/interfaces/utils/common.ts index afcf7b37..fd5f59f9 100644 --- a/packages/untp-test-suite/src/interfaces/utils/common.ts +++ b/packages/untp-test-suite/src/interfaces/utils/common.ts @@ -10,3 +10,13 @@ export async function readJsonFile(filePath: string): Promise { return null; } } + +// Utility function to truncate strings +export const truncateString = (str: string | undefined, maxLength: number) => { + if (!str) return; + + if (str.length <= maxLength) { + return str; + } + return str.slice(0, maxLength) + '...'; +}; diff --git a/packages/untp-test-suite/src/templates/templateMessages/credentialResult.hbs b/packages/untp-test-suite/src/templates/templateMessages/credentialResult.hbs index 7d9b60db..103c282a 100644 --- a/packages/untp-test-suite/src/templates/templateMessages/credentialResult.hbs +++ b/packages/untp-test-suite/src/templates/templateMessages/credentialResult.hbs @@ -2,5 +2,6 @@ "credentialType": "{{type}}", "version": "{{version}}", "path": "{{dataPath}}", + "url": "{{url}}", "result": "{{result}}" } \ No newline at end of file