-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement renderer 2024 provider #177
Conversation
# Conflicts: # packages/cli/default/default-dev.yml # packages/cli/default/default.yml # packages/core-types/package.json # packages/core-types/src/index.ts # packages/core-types/src/plugin.schema.json
if ( | ||
digestMultibase && | ||
context && | ||
typeof context.agent.createVerifiableCredentialOA === 'function' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to check createVerifiableCredentialOA
?
/** | ||
* @public | ||
*/ | ||
export class WebRenderingTemplate2024 implements IRendererProvider { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on w3c-ccg/vc-render-method#9, the name should be RenderTemplate2024
context?: IRendererContext; | ||
}): Promise<string> { | ||
try { | ||
let svgTemplate: string | any = ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the name of the variable is svgTemplate
? And the type should be only string
return('<p style="color: red">Error: Template hash does not match the provided digest</p>'); | ||
} | ||
} | ||
const compiledTemplate = handlebars.compile(svgTemplate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check the mediaType to choose the template engine? Like the XML
can not use with the handlebars
packages/renderer/src/renderer.ts
Outdated
} from '@vckit/core-types'; | ||
import schema from '@vckit/core-types/build/plugin.schema.json' assert { type: 'json' }; | ||
import { url } from 'inspector'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is it used?
packages/renderer/src/renderer.ts
Outdated
@@ -82,30 +83,55 @@ export class Renderer implements IAgentPlugin { | |||
|
|||
// TODO: There's an issue with W3 availability causing the fetching of some W3 context files to fail. Since we know the exact location of the template we can bypass the JSONLD expansion. This is a temporary workaround. | |||
|
|||
const render = args.credential.render; | |||
const render = args.credential.render || args.credential.renderMethod; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous, we had hotfix for the performance issue. So please follow the TODO to handle it right
packages/renderer/src/renderer.ts
Outdated
return convertToBase64(document); | ||
const responseDocument = { | ||
type: renderMethod['@type'], | ||
renderedTemplate: convertToBase64(document), | ||
id: renderMethod.id, | ||
name: renderMethod.name, | ||
mediaType: renderMethod.mediaType, | ||
|
||
}; | ||
return responseDocument; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the new output backward compatible with the old WebRenderingTemplate2022?
# Conflicts: # pnpm-lock.yaml
* next: chore: fix version of react feat: implement vc api v2 in open api (#178) # Conflicts: # pnpm-lock.yaml
* next: chore: fix version of react and react-dom
* next: fix: add interface for compute hash (#179)
* next: docs: add yarn to prerequisites
* next: fix: using revocation list on explorer and handle no hash (#192)
Coverage report
Test suite run success21 tests passing in 3 suites. Report generated by π§ͺjest coverage report action from 25ff963 |
packages/renderer/__tests__/providers/render-template-2024.test.ts
Outdated
Show resolved
Hide resolved
expect(result.renderedTemplate).toBe('Error: Unsupported media type'); | ||
}); | ||
|
||
it('should return empty string if it failed to fetch template from url', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no it's not. this is to cover the statement in the code(like if-else, try-catch etc...)
expect(result.renderedTemplate).toBe(''); | ||
}); | ||
|
||
it('should return template with style added', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is to reduce the uncovered count for statements as well, so yes, we need this case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disagree, 2 test cases are mostly the same, please review it again
if (url) { | ||
try { | ||
const response = await fetch(url); | ||
renderTemplate = await response.text(); | ||
} catch (error) { | ||
console.error(`Failed to fetch from ${url}:`, error); | ||
} | ||
}else if (template) { | ||
renderTemplate = template; | ||
}else{ | ||
return { | ||
renderedTemplate: 'Error: No template or url provided', | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does the condition expression cover the case of the fetching URL is timeout, then using inline template to render?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @namhoang1604 I've handled this
β¦ the case that fetch template from url
expect(result).toStrictEqual( | ||
{"renderedTemplate": "Error: No hash function provided to verify the template"} | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should assert with the error message Error: Template hash does not match the provided digest
for this test case. Because the title suggests comparing the template hashed string with the digestMultibase
value.
await expect(async () => { | ||
await renderer.renderCredential({ | ||
data, | ||
document, | ||
}); | ||
}).rejects.toThrow(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test case is should return an error message if the template is not a string
, but the expect is throw error
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"} | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the default template? Please correct the test case
expect(result.renderedTemplate).toBe(''); | ||
}); | ||
|
||
it('should return template with style added', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disagree, 2 test cases are mostly the same, please review it again
const template = this.extractTemplate(data); | ||
if (!template?.trim()) { | ||
return { | ||
renderedTemplate: 'Error: invalid template provided', | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the empty template invalid? Where is the document saying that?
} | ||
|
||
private extractTemplate(data: any) { | ||
// const RENDER_METHOD = 'https://www.w3.org/2018/credentials#renderMethod'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the comment
}); | ||
|
||
it('should throw an error if the template is not a valid handlebars template', async () => { | ||
// const template = '<p>{{name}}</p>'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove comment
'PGRpdiBzdHlsZT0id2lkdGg6MzAwcHg7IGhlaWdodDoxMDBweDsgYm9yZGVyOiAycHggc29saWQgYmxhY2s7IHRleHQtYWxpZ246Y2VudGVyIj4KICA8ZGl2PgogICAgVGhpcyBCYWNoZWxvciBvZiBTY2llbmNlIGFuZCBBcnRzIGlzIGNvbmZlcnJlZCB0bwogIDwvZGl2PgogIDxzdHJvbmcgc3R5bGU9ImZvbnQtc2l6ZTogMTZweCI+CiAgICBKYW5lIFNtaXRoCiAgPC9zdHJvbmc+CiAgPGRpdj4KICAgIGJ5IEV4YW1wbGUgVW5pdmVyc2l0eS4KICA8L2Rpdj4KPC9kaXY+', | ||
]); | ||
expect(result.documents).toEqual([{ | ||
"renderedTemplate": "RXJyb3I6IGludmFsaWQgdGVtcGxhdGUgcHJvdmlkZWQ=", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the result of renderedTemplate
is Error: invalid template provided
? That should render the template successfully
@@ -115,29 +140,26 @@ describe('Renderer', () => { | |||
).rejects.toThrow('Render method not found in the verifiable credential'); | |||
}); | |||
|
|||
it('should throw an error if the verifiable credential contains an invalid render method', async () => { | |||
it('should throw an error with invalid @type and non-default provider', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you edit the important test case?
}); | ||
|
||
it('should skip render methods without @type or template', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not remove the required test cases
it('should throw an error with invalid @type and non-default provider', async () => { | ||
it('should throw an error if there is no context file for renderer', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not remove the required test cases, you can add new ones
Signed-off-by: Nam Hoang <hoangxuannam160493@gmail.com>
Signed-off-by: Nam Hoang <hoangxuannam160493@gmail.com>
f9901ad
to
25ff963
Compare
β¦erge-next-to-main * 'next' of github.com:uncefact/project-vckit: (90 commits) feat: enveloping proof (#207) feat: Add `eddsa-rdfc-2022-cryptosuite` Plugin (#200) chore: update bitstring status package (#211) docs: update identifier creation (#208) feat(cd): ghcr.io setup and docker image build workflow (#206) changed Dockerfile to use default agent.template.yml (#201) (#205) parameterised API Key for Docker builds (#203) (#204) feat: setup package workflow feat: create git workflow for release tagging and generate the release note (#199) fix: Provide meaningful error message when signature verification fails (#197) docs: add documentation site (#198) feat: implement renderer 2024 provider (#177) chore: update arguments and envs for the Dockerfile (#194) fix: using revocation list on explorer and handle no hash (#192) docs: add yarn to prerequisites chore: change node version to 20.12.2 (#187) chore: update default agent for Status plugin (#186) chore: fix the dockerfile to set entrypoint chore: update vckit Dockerfile (#184) chore: update DockerFile and agent template (#183) ... Signed-off-by: Nam Hoang <hoangxuannam160493@gmail.com> # Conflicts: # .github/workflows/build-test-publish.yml # .github/workflows/deploy-to-s3.yml # jest.config.mjs # package.json # packages/core-types/package.json # packages/credential-oa/__tests__/action-handler.test.ts # packages/credential-oa/src/action-handler.ts # pnpm-lock.yaml
What type of PR is this? (check all applicable)
Description
This PR is about implementing a new renderer provider and enhancing the UI of demo explorer to display the new templates.
Related Tickets & Documents
https://github.com/gs-gs/fa-ag-trace/issues/430
https://github.com/gs-gs/fa-ag-trace/issues/431
Mobile & Desktop Screenshots/Recordings
new-renderer.mov
Added tests?
Added to documentation?
[optional] Are there any post-deployment tasks we need to perform?