diff --git a/packages/renderer/__tests__/providers/render-template-2024.test.ts b/packages/renderer/__tests__/providers/render-template-2024.test.ts index 1158a539..5ab66d03 100644 --- a/packages/renderer/__tests__/providers/render-template-2024.test.ts +++ b/packages/renderer/__tests__/providers/render-template-2024.test.ts @@ -1,26 +1,33 @@ import { RenderTemplate2024 } from '../../src/providers/render-template-2024'; -import universityDegreeCredentialTemplate2024 from '../../fixtures/univerisity-degree-credential-template-2024.json'; import { jest } from '@jest/globals'; describe('RenderTemplate2024', () => { let renderer: RenderTemplate2024; + let context: any; + + let data: any; beforeEach(() => { renderer = new RenderTemplate2024(); - }); + context = { + agent: { + computeHash: () => { + return 'zQmWkr8ZchZN5DgimHcW3pFYnjEk5CdyRm4w5kccemQJotn'; + }, + }, + }; - it('should return an error message if the template is not provided', async () => { - const data = { + data = { 'https://w3id.org/security#digestMultibase': [ { '@type': 'https://w3id.org/security#multibase', - '@value': '', + '@value': 'zQmWkr8ZchZN5DgimHcW3pFYnjEk5CdyRm4w5kccemQJotn', }, ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ + 'https://www.w3.org/ns/credentials/examples#mediaQuery': [ { '@value': - '', + '@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}', }, ], 'https://schema.org/encodingFormat': [ @@ -30,365 +37,130 @@ describe('RenderTemplate2024', () => { ], 'https://www.w3.org/2018/credentials#renderMethod#template': [ { - '@value': - '', + '@value': '
{{name}}
', }, ], 'https://www.w3.org/2018/credentials#renderMethod#url': [ { - '@value': '', + '@value': 'https://example.com', }, ], - }; - const result = await renderer.renderCredential({ data, document: {} }); - - expect(result).toStrictEqual( - {"renderedTemplate": "Error: No template or url provided"} - ); - }); - - it('should render the template with the credential data', async () => { - const document = { name: 'John Doe' }; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ + 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ { '@value': - '

{{name}}

', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', + '@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}', }, ], }; + }); - const renderedContent = await renderer.renderCredential({ - data, - document, + it('should render successfully with valid data and document', async () => { + // Mock fetch function + global.fetch = jest.fn() as typeof fetch; + const mockTemplate = '
{{name}}
'; + (global.fetch as jest.Mock).mockReturnValue({ + ok: true, + text: async () => mockTemplate, }); - expect(renderedContent).toEqual({"renderedTemplate": "

John Doe

"}); - }); - - it('should return an error message if the template and the digestMultibase are not the same', async () => { const document = { name: 'John Doe' }; - const data = { - 'https://w3id.org/security#digestMultibase': [ - { - '@type': 'https://w3id.org/security#multibase', - '@value': 'abc123', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ - { - '@value': - '@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}', - }, - ], - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '

{{name}}

', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - }; - const result = await renderer.renderCredential({ - data, - document, - }); - expect(result).toStrictEqual( - {"renderedTemplate": "Error: No hash function provided to verify the template"} - ); + const result = await renderer.renderCredential({ data, document, context }); + + expect(result.renderedTemplate).toEqual('
John Doe
'); }); - it('should throw an error if the template is not a valid handlebars template', async () => { + it('should render successfully by inline template, when fetching url error', async () => { + // Mock fetch function + global.fetch = jest.fn() as typeof fetch; + (global.fetch as jest.Mock).mockReturnValue({ + ok: false, + }); + const document = { name: 'John Doe' }; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '

{{name}

', // Invalid handlebars template missing closing curly brace - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - }; - await expect(async () => { - await renderer.renderCredential({ - data, - document, - }); - }).rejects.toThrow(); + + const result = await renderer.renderCredential({ data, document, context }); + + expect(result.renderedTemplate).toEqual('
John Doe
'); }); - it('should return an error message if the template is not a string', async () => { + it('should render successfully by inline template, when no url', async () => { + // Mock data without url + delete data['https://www.w3.org/2018/credentials#renderMethod#url']; + const document = { name: 'John Doe' }; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': 123, // Invalid template value, should be a string - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - }; - await expect(async () => { - await renderer.renderCredential({ - data, - document, - }); - }).rejects.toThrow(); - }); - - it('should return an error message if the template is not provided and there is no default template', async () => { - const data = { - 'https://w3id.org/security#digestMultibase': [ - { - '@type': 'https://w3id.org/security#multibase', - '@value': '', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ - { - '@value': - '', - }, - ], - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - }; - const rendererWithoutDefaultTemplate = new RenderTemplate2024(); - const result = await rendererWithoutDefaultTemplate.renderCredential({ data, document: {} }); - expect(result).toStrictEqual( - {"renderedTemplate": "Error: No template or url provided"} - ); + + const result = await renderer.renderCredential({ data, document, context }); + + expect(result.renderedTemplate).toEqual('
John Doe
'); }); - it('should render the template with the credential data and media query', async () => { + it('should return "Error: Unsupported media type", when using invalit mediaType', async () => { + // Mock data without url + delete data['https://www.w3.org/2018/credentials#renderMethod#url']; + // Mock invalid mediaType + data['https://schema.org/encodingFormat'] = [ + { '@value': 'application/json' }, + ]; + const document = { name: 'John Doe' }; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '

{{name}}

', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ - { - '@value': - '@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}', - }, - ], - }; - const renderedContent = await renderer.renderCredential({ - data, - document, - }); + const result = await renderer.renderCredential({ data, document, context }); - expect(renderedContent).toEqual({"renderedTemplate": "

John Doe

"}); + expect(result.renderedTemplate).toEqual('Error: Unsupported media type'); }); - it('should return an error message if the mediaType is unsupported', async () => { + it('should return "Error: No template or url provided", when no url and template', async () => { + // Mock data without url and template + delete data['https://www.w3.org/2018/credentials#renderMethod#url']; + delete data['https://www.w3.org/2018/credentials#renderMethod#template']; + const document = { name: 'John Doe' }; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'application/json', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '

{{name}}

', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaType': [ - { - '@value': 'application/json', // Unsupported mediaType - }, - ], - }; - const result = await renderer.renderCredential({ - data, - document, - }); - expect(result).toStrictEqual( - {"renderedTemplate": "Error: Unsupported media type"} + + const result = await renderer.renderCredential({ data, document, context }); + + expect(result.renderedTemplate).toEqual( + 'Error: No template or url provided', ); }); - it('should return the template if it failed to fetch template from url', async () => { + it('should return "Error: No hash function provided to verify the template", when context empty object', async () => { + // Mock data without url + data['https://www.w3.org/2018/credentials#renderMethod#url'] = [ + { '@value': '' }, + ]; + // Mock context empty object + context = {}; + const document = { name: 'John Doe' }; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '

{{name}}

', - }, - ] - }; - const renderedContent = await renderer.renderCredential({ - data, - document, - }); - expect(renderedContent).toEqual({"renderedTemplate": "

John Doe

"}); - }); - it('should return error if the digestMultibase is provided but there is no context', async () => { - const document = universityDegreeCredentialTemplate2024; - const data = { - 'https://w3id.org/security#digestMultibase': [ - { - '@type': 'https://w3id.org/security#multibase', - '@value': 'abc123', // Replace with the actual hashed template value - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ - { - '@value': - '@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}', - }, - ], - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '

{{name}}

', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': '', - }, - ], - }; - const result = await renderer.renderCredential({ - data, - document, - }); - expect(result).toEqual({"renderedTemplate": 'Error: No hash function provided to verify the template'}); - }); + const result = await renderer.renderCredential({ data, document, context }); - it('should return template with style added', async () => { - const document = { name: 'John Doe', url: 'example.com'}; - const data = { - 'https://schema.org/encodingFormat': [ - { - '@value': 'text/html', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#template': [ - { - '@value': - '', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#mediaQuery': [ - { - '@value': - '@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}', - }, - ], - 'https://www.w3.org/2018/credentials#renderMethod#url': [ - { - '@value': 'example.com', // Replace with the actual URL - }, - ], - }; - const result = await renderer.renderCredential({ - data, - document, - }); - expect(JSON.stringify(result.renderedTemplate)).toBe("\"\""); + expect(result.renderedTemplate).toEqual( + 'Error: No hash function provided to verify the template', + ); }); - it('should fetch template from URL and render correctly', async () => { - global.fetch = jest.fn() as typeof fetch; - const mockTemplate = '
{{name}}
'; - (global.fetch as jest.Mock).mockReturnValue({ - ok: true, - text: async () => mockTemplate, - }); + it('should return "Error: Template hash does not match the provided digest", when invalid hash', async () => { + // Mock data without url + data['https://www.w3.org/2018/credentials#renderMethod#url'] = [ + { '@value': '' }, + ]; - const data = { - 'https://www.w3.org/2018/credentials#renderMethod#url': [{ '@value': 'https://example.com/template' }], - 'https://schema.org/encodingFormat': [{ '@value': 'text/html' }], - 'https://schema.org/name': [{ '@value': 'Test Name' }], - }; + // Mock context empty object + data['https://w3id.org/security#digestMultibase'] = [ + { + '@type': 'https://w3id.org/security#multibase', + '@value': 'abc123', + }, + ]; - const result = await renderer.renderCredential({ - data, - document: { name: 'Test Name' }, - }); + const document = { name: 'John Doe' }; - expect(result.renderedTemplate).toBe('
Test Name
'); - expect(global.fetch).toHaveBeenCalledWith('https://example.com/template'); - }); + const result = await renderer.renderCredential({ data, document, context }); + expect(result.renderedTemplate).toEqual( + 'Error: Template hash does not match the provided digest', + ); + }); }); diff --git a/packages/renderer/__tests__/providers/web-rendering-template-2022.test.ts b/packages/renderer/__tests__/providers/web-rendering-template-2022.test.ts index d5599550..f0167d16 100644 --- a/packages/renderer/__tests__/providers/web-rendering-template-2022.test.ts +++ b/packages/renderer/__tests__/providers/web-rendering-template-2022.test.ts @@ -14,10 +14,9 @@ describe('WebRenderingTemplate2022', () => { const data = { 'https://www.w3.org/2018/credentials#renderMethod#template': [ { - '@value': - '

{{name}}

', + '@value': '

{{name}}

', }, - ] + ], }; const renderedContent = await renderer.renderCredential({ @@ -25,7 +24,7 @@ describe('WebRenderingTemplate2022', () => { document, }); - expect(renderedContent).toStrictEqual({"renderedTemplate": "

John Doe

"}); + expect(renderedContent).toEqual({ renderedTemplate: '

John Doe

' }); }); it('should return an empty string if the template is empty', async () => { @@ -34,10 +33,9 @@ describe('WebRenderingTemplate2022', () => { const data = { 'https://www.w3.org/2018/credentials#renderMethod#template': [ { - '@value': - '', + '@value': '', }, - ] + ], }; const renderedContent = await renderer.renderCredential({ @@ -45,19 +43,17 @@ describe('WebRenderingTemplate2022', () => { document, }); - expect(renderedContent).toStrictEqual({"renderedTemplate": ""}); + expect(renderedContent).toEqual({ renderedTemplate: '' }); }); it('should return the template content if the template is random text', async () => { - const template = 'Some random text'; const document = { name: 'John Doe' }; const data = { 'https://www.w3.org/2018/credentials#renderMethod#template': [ { - '@value': - 'Some random text', + '@value': 'Some random text', }, - ] + ], }; const renderedContent = await renderer.renderCredential({ @@ -65,7 +61,9 @@ describe('WebRenderingTemplate2022', () => { document, }); - expect(renderedContent).toStrictEqual({"renderedTemplate": "Some random text"}); + expect(renderedContent).toEqual({ + renderedTemplate: 'Some random text', + }); }); it('should return an empty string if the template contains only whitespace', async () => { @@ -74,10 +72,9 @@ describe('WebRenderingTemplate2022', () => { const data = { 'https://www.w3.org/2018/credentials#renderMethod#template': [ { - '@value': - ' \t\n ', + '@value': ' \t\n ', }, - ] + ], }; const renderedContent = await renderer.renderCredential({ @@ -85,7 +82,7 @@ describe('WebRenderingTemplate2022', () => { document, }); - expect(renderedContent).toStrictEqual({"renderedTemplate": ""}); + expect(renderedContent).toEqual({ renderedTemplate: '' }); }); it('should throw an error if the template is not a valid handlebars template', async () => { @@ -94,10 +91,9 @@ describe('WebRenderingTemplate2022', () => { const data = { 'https://www.w3.org/2018/credentials#renderMethod#template': [ { - '@value': - '

{{name}

', + '@value': '

{{name}

', }, - ] + ], }; await expect(async () => { @@ -107,6 +103,5 @@ describe('WebRenderingTemplate2022', () => { }); }).rejects.toThrow(); }); - }); }); diff --git a/packages/renderer/__tests__/renderer.test.ts b/packages/renderer/__tests__/renderer.test.ts index f78724b7..416d84e6 100644 --- a/packages/renderer/__tests__/renderer.test.ts +++ b/packages/renderer/__tests__/renderer.test.ts @@ -1,12 +1,13 @@ import { Renderer } from '../src/renderer'; import { WebRenderingTemplate2022 } from '../src/providers/web-rendering-template-2022'; +import { RenderTemplate2024 } from '../src/providers/render-template-2024'; import { IRendererProvider, IRenderCredentialArgs, IRendererContext, IRenderResult, RenderDocument, - IRenderedResult + IRenderedResult, } from '@vckit/core-types'; import universityDegreeCredential from '../fixtures/university-degree-credential.json'; import universityDegreeCredentialTemplate2024 from '../fixtures/univerisity-degree-credential-template-2024.json'; @@ -14,27 +15,42 @@ import universityDegreeCredentialTemplate2024 from '../fixtures/univerisity-degr describe('Renderer', () => { // Mock renderer provider const MockWebRenderingTemplate2022: IRendererProvider = { - async renderCredential({data: any, document: RenderDocument}): Promise { + async renderCredential({ + data: any, + document: RenderDocument, + }): Promise { // Mock implementation return { - renderedTemplate: 'Rendered credential successfully' + renderedTemplate: 'Rendered credential successfully', }; }, + + extractData(data: any): { [k: string]: any } { + return { template: 'Rendered credential successfully' }; + }, }; const MockRenderTemplate2024: IRendererProvider = { - async renderCredential({data: any, document: RenderDocument}): Promise { + async renderCredential({ + data: any, + document: RenderDocument, + }): Promise { // Mock implementation return { - renderedTemplate: 'Rendered credential successfully' + renderedTemplate: 'Rendered credential successfully', }; }, + + extractData(data: any): { [k: string]: any } { + return { template: 'Rendered credential successfully' }; + }, }; // Create an instance of Renderer const renderer = new Renderer({ providers: { WebRenderingTemplate2022: new WebRenderingTemplate2022(), + RenderTemplate2024: new RenderTemplate2024(), }, defaultProvider: 'WebRenderingTemplate2022', }); @@ -43,14 +59,14 @@ describe('Renderer', () => { const rendererMockProvider = new Renderer({ providers: { WebRenderingTemplate2022: MockWebRenderingTemplate2022, - RenderTemplate2024: MockRenderTemplate2024 + RenderTemplate2024: MockRenderTemplate2024, }, defaultProvider: 'WebRenderingTemplate2022', }); const renderer2024Provider = new Renderer({ providers: { - RenderTemplate2024: MockRenderTemplate2024 + RenderTemplate2024: MockRenderTemplate2024, }, defaultProvider: 'RenderTemplate2024', }); @@ -62,23 +78,52 @@ describe('Renderer', () => { }); it('should render a verifiable credential using the specified render methods', async () => { - // Mock data - const args: IRenderCredentialArgs = { + const context: any = { + agent: { + computeHash: () => { + return 'zQmXPqSNrf6ZR2R5VVdYRpPxQREDCW1i3h98NAHLdAwLBxx'; + }, + }, + }; + // Mock data using WebRenderingTemplate2022 + const webRenderingTemplate2022Args: IRenderCredentialArgs = { credential: universityDegreeCredential, }; - const context = {}; + + // Mock data using RenderTemplate2024 + const renderTemplate2024Args: IRenderCredentialArgs = { + credential: universityDegreeCredentialTemplate2024, + }; // Call the renderCredential method - const result: IRenderResult = await renderer.renderCredential( - args, - context as IRendererContext - ); + const webRenderingTemplate2022Result: IRenderResult = + await renderer.renderCredential( + webRenderingTemplate2022Args, + context as IRendererContext, + ); + + const renderTemplate2024Result: IRenderResult = + await renderer.renderCredential( + renderTemplate2024Args, + context as IRendererContext, + ); // Verify the result - expect(result.documents).toEqual([{ - "renderedTemplate": "RXJyb3I6IGludmFsaWQgdGVtcGxhdGUgcHJvdmlkZWQ=", - "type": "WebRenderingTemplate2022", - }]); + expect(webRenderingTemplate2022Result.documents).toEqual([ + { + renderedTemplate: + 'PGRpdiBzdHlsZT0id2lkdGg6MzAwcHg7IGhlaWdodDoxMDBweDsgYm9yZGVyOiAycHggc29saWQgYmxhY2s7IHRleHQtYWxpZ246Y2VudGVyIj4KICA8ZGl2PgogICAgVGhpcyBCYWNoZWxvciBvZiBTY2llbmNlIGFuZCBBcnRzIGlzIGNvbmZlcnJlZCB0bwogIDwvZGl2PgogIDxzdHJvbmcgc3R5bGU9ImZvbnQtc2l6ZTogMTZweCI+CiAgICBKYW5lIFNtaXRoCiAgPC9zdHJvbmc+CiAgPGRpdj4KICAgIGJ5IEV4YW1wbGUgVW5pdmVyc2l0eS4KICA8L2Rpdj4KPC9kaXY+', + type: 'WebRenderingTemplate2022', + }, + ]); + + expect(renderTemplate2024Result.documents).toEqual([ + { + renderedTemplate: + 'PGRpdiBzdHlsZT0id2lkdGg6MzAwcHg7IGhlaWdodDozMDBweDsgYm9yZGVyOiAycHggc29saWQgYmxhY2s7IHRleHQtYWxpZ246Y2VudGVyIj4gIAoJPGgyPkNlcnRpZmljYXRlPC9oMj4KICAgIDxwPk9mIENvbXBsZXRpb248L3A+CiAgPGRpdj4gICAgVGhpcyBpcyB0byBjZXJ0aWZ5IHRoYXQgIDwvZGl2PiAgCiAgPHN0cm9uZyBzdHlsZT0iZm9udC1zaXplOiAxNnB4Ij4gICBKb2huIERvZSAgPC9zdHJvbmc+CiAgPGRpdj5oYXMgY29tcGxldGVkIHRoZSBCYWNoZWxvciBvZiBDb21wdXRlciBTY2llbmNlPC9kaXY+CiAgPGRpdj4gICAgYnkgRXhhbXBsZSBVbml2ZXJzaXR5LiAgPC9kaXY+CjwvZGl2Pg==', + type: 'RenderTemplate2024', + }, + ]); }); it('should render a verifiable credential using the default render method', async () => { @@ -100,15 +145,15 @@ describe('Renderer', () => { // Call the renderCredential method const result: IRenderResult = await rendererMockProvider.renderCredential( args, - context as IRendererContext + context as IRendererContext, ); // Verify the result expect(result.documents).toEqual([ { - "renderedTemplate": "UmVuZGVyZWQgY3JlZGVudGlhbCBzdWNjZXNzZnVsbHk=", - "type": "SvgRenderingHint2022" - } + renderedTemplate: 'UmVuZGVyZWQgY3JlZGVudGlhbCBzdWNjZXNzZnVsbHk=', + type: 'SvgRenderingHint2022', + }, ]); }); @@ -136,7 +181,7 @@ describe('Renderer', () => { // Call the renderCredential method await expect( - rendererMockProvider.renderCredential(args, context as IRendererContext) + rendererMockProvider.renderCredential(args, context as IRendererContext), ).rejects.toThrow('Render method not found in the verifiable credential'); }); @@ -168,32 +213,93 @@ describe('Renderer', () => { // Call the renderCredential method await expect( - rendererNoDefault.renderCredential(args, context as IRendererContext) + rendererNoDefault.renderCredential(args, context as IRendererContext), ).rejects.toThrow('Renderer provider invalid-render-type not found'); }); - it('should render a verifiable credential using the RenderTemplate2024 render method', async () => { + it('should render a verifiable credential with no render methods', async () => { // Mock data const args: IRenderCredentialArgs = { credential: { - ...universityDegreeCredentialTemplate2024, + '@context': [ + 'https://www.w3.org/2018/credentials/v1', + 'https://www.w3.org/2018/credentials/examples/v1', + ], + id: 'http://example.edu/credentials/3732', + type: ['VerifiableCredential', 'UniversityDegreeCredential'], + issuer: 'https://example.edu/issuers/565049', + issuanceDate: '2010-01-01T00:00:00Z', + credentialSubject: {}, + render: [ + { + template: 'random-template', + '@type': 'WebRenderingTemplate2022', + }, + ], }, }; const context = {}; // Call the renderCredential method - const result: IRenderResult = await renderer2024Provider.renderCredential( - args, - context as IRendererContext - ); + await expect( + renderer.renderCredential(args, context as IRendererContext), + ).rejects.toThrow('Render method not found in the verifiable credential'); + }); + + it('should render a verifiable credential with an empty credential object', async () => { + // Mock data + const args: IRenderCredentialArgs = { + credential: {} as any, + }; + const context = {}; + + await expect( + renderer.renderCredential(args, context as IRendererContext), + ).rejects.toThrow('Error expanding the verifiable credential'); + }); + + it('should render a verifiable credential with an empty context object', async () => { + const context: any = {}; + // Mock data using WebRenderingTemplate2022 + const webRenderingTemplate2022Args: IRenderCredentialArgs = { + credential: universityDegreeCredential, + }; + + // Mock data using RenderTemplate2024 + const renderTemplate2024Args: IRenderCredentialArgs = { + credential: universityDegreeCredentialTemplate2024, + }; + + // Call the renderCredential method + const webRenderingTemplate2022Result: IRenderResult = + await renderer.renderCredential( + webRenderingTemplate2022Args, + context as IRendererContext, + ); + + const renderTemplate2024Result: IRenderResult = + await renderer.renderCredential( + renderTemplate2024Args, + context as IRendererContext, + ); + // Verify the result - expect(result.documents).toEqual([ + expect(webRenderingTemplate2022Result.documents).toEqual([ { - "renderedTemplate": "UmVuZGVyZWQgY3JlZGVudGlhbCBzdWNjZXNzZnVsbHk=", - "type": "RenderTemplate2024" - } + renderedTemplate: + 'PGRpdiBzdHlsZT0id2lkdGg6MzAwcHg7IGhlaWdodDoxMDBweDsgYm9yZGVyOiAycHggc29saWQgYmxhY2s7IHRleHQtYWxpZ246Y2VudGVyIj4KICA8ZGl2PgogICAgVGhpcyBCYWNoZWxvciBvZiBTY2llbmNlIGFuZCBBcnRzIGlzIGNvbmZlcnJlZCB0bwogIDwvZGl2PgogIDxzdHJvbmcgc3R5bGU9ImZvbnQtc2l6ZTogMTZweCI+CiAgICBKYW5lIFNtaXRoCiAgPC9zdHJvbmc+CiAgPGRpdj4KICAgIGJ5IEV4YW1wbGUgVW5pdmVyc2l0eS4KICA8L2Rpdj4KPC9kaXY+', + type: 'WebRenderingTemplate2022', + }, + ]); + + expect(renderTemplate2024Result.documents).toEqual([ + { + renderedTemplate: + 'RXJyb3I6IE5vIGhhc2ggZnVuY3Rpb24gcHJvdmlkZWQgdG8gdmVyaWZ5IHRoZSB0ZW1wbGF0ZQ==', + type: 'RenderTemplate2024', + }, ]); }); - + it('should render a verifiable credential with multiple render methods', async () => { // Mock data const args: IRenderCredentialArgs = { @@ -215,43 +321,18 @@ describe('Renderer', () => { // Call the renderCredential method const result: IRenderResult = await renderer.renderCredential( args, - context as IRendererContext + context as IRendererContext, ); // Verify the result expect(result.documents).toEqual([ { - renderedTemplate: 'RXJyb3I6IGludmFsaWQgdGVtcGxhdGUgcHJvdmlkZWQ=', + renderedTemplate: 'dGVtcGxhdGUx', type: 'WebRenderingTemplate2022', }, { - renderedTemplate: 'RXJyb3I6IGludmFsaWQgdGVtcGxhdGUgcHJvdmlkZWQ=', + renderedTemplate: 'dGVtcGxhdGUy', type: 'WebRenderingTemplate2022', }, ]); }); - - it('should throw an error if there is no context file for renderer', async () => { - // Mock data - const args: IRenderCredentialArgs = { - credential: { - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://www.w3.org/2018/credentials/examples/v1', - ], - id: 'http://example.edu/credentials/3732', - type: ['VerifiableCredential', 'UniversityDegreeCredential'], - issuer: 'https://example.edu/issuers/565049', - issuanceDate: '2010-01-01T00:00:00Z', - credentialSubject: { - id: 'did:example:ebfeb1f712ebc6f1c276e12ec21', - }, - }, - }; - const context = {}; - // Call the renderCredential method - await expect( - renderer.renderCredential(args, context as IRendererContext) - ).rejects.toThrow(); - }); - }); diff --git a/packages/renderer/fixtures/univerisity-degree-credential-template-2024.json b/packages/renderer/fixtures/univerisity-degree-credential-template-2024.json index 8901c0fa..c153f588 100644 --- a/packages/renderer/fixtures/univerisity-degree-credential-template-2024.json +++ b/packages/renderer/fixtures/univerisity-degree-credential-template-2024.json @@ -28,7 +28,7 @@ "@type": "RenderTemplate2024", "mediaQuery": "@media (min-width: 1024px) {\n .title {\n font-weight: bold;\n color: #223675;\n }\n}", "mediaType": "text/html", - "url": "", + "url": "", "digestMultibase": "zQmXPqSNrf6ZR2R5VVdYRpPxQREDCW1i3h98NAHLdAwLBxx" } ] diff --git a/packages/renderer/fixtures/university-degree-credential.json b/packages/renderer/fixtures/university-degree-credential.json index 10d44b4b..ad6b8132 100644 --- a/packages/renderer/fixtures/university-degree-credential.json +++ b/packages/renderer/fixtures/university-degree-credential.json @@ -3,7 +3,9 @@ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1", { - "render": "https://www.w3.org/2018/credentials#renderMethod" + "ex": "https://www.w3.org/2018/credentials#renderMethod#", + "render": "https://www.w3.org/2018/credentials#renderMethod", + "template": "ex:template" } ], "id": "http://example.edu/credentials/3732", diff --git a/packages/renderer/src/renderer.ts b/packages/renderer/src/renderer.ts index e73984b5..b960fa8a 100644 --- a/packages/renderer/src/renderer.ts +++ b/packages/renderer/src/renderer.ts @@ -102,7 +102,7 @@ export class Renderer implements IAgentPlugin { ? convertToBase64(document.renderedTemplate) : '', name: document.name, - id: document.id + id: document.id, }; return responseDocument; }),