-
Notifications
You must be signed in to change notification settings - Fork 9
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
VATEAM-88634: Create a normalization layer for Digital Forms #2215
VATEAM-88634: Create a normalization layer for Digital Forms #2215
Conversation
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.
ESLint is disabled
vets-website
uses ESLint to help enforce code quality. In most situations we would like ESLint to remain enabled.
What you can do
See if the code can be refactored to avoid disabling ESLint, or wait for a VSP review.
@@ -0,0 +1,15 @@ | |||
/* eslint-disable @department-of-veterans-affairs/axe-check-required */ |
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.
ESLint disabled here
@@ -0,0 +1,21 @@ | |||
/* eslint-disable @department-of-veterans-affairs/axe-check-required */ |
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.
ESLint disabled here
@@ -0,0 +1,14 @@ | |||
/* eslint-disable @department-of-veterans-affairs/axe-check-required */ |
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.
ESLint disabled here
@@ -0,0 +1,22 @@ | |||
/* eslint-disable @department-of-veterans-affairs/axe-check-required */ |
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.
ESLint disabled here
@@ -0,0 +1,105 @@ | |||
/* eslint-disable @department-of-veterans-affairs/axe-check-required */ |
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.
ESLint disabled here
778c927
to
777eda3
Compare
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.
Let's quickly chat about this, but it looks great!
id: parseInt(entity.entityId, 10), | ||
chapterTitle: entity.fieldTitle, | ||
type: entity.type.entity.entityId, | ||
pageTitle: entity.type.entity.entityLabel, |
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.
Just acknowledging here that this structure assumes the one-page-per-chapter model, which I'm not sure is going to stand the test of time. For now, though, this is fine.
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.
Acknowledged. That's a bridge we'll cross when we get there.
|
||
const normalizeForm = form => { | ||
return { | ||
id: form.nid, |
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.
LET'S DISCUSS
I think we need to align on what a form id is. I do think we want to capture the node/entity id somewhere, so this looks good, but my model up to this point (when working on parsing the form id from the url) has been that the form number would have to be available somewhere. I think we might want to add something like:
{
...
formId: form.fieldVaFormNumber,
...
}
We might even need to format it in some way (strip spaces, convert to lowercase, etc.):
{
...
formId: formatFormNumber(form.fieldVaFormNumber),
...
}
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.
Per our discussion, formId
has been added, id
has been renamed to cmsId
, and subTitle
has been removed.
}; | ||
}; | ||
|
||
const normalizeForms = forms => forms.map(form => normalizeForm(form)); |
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.
Same as above - this can just be forms.map(normalizeForm)
. Again, this might be a personal preference.
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.
Done
}; | ||
|
||
const normalizeChapters = chapters => | ||
chapters.map(chapter => normalizeChapter(chapter)); |
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 can just be chapters.map(normalizeChapter), though that's a matter of preference I suppose.
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.
Done
|
||
return additionalFields; | ||
}; | ||
const extractForms = resultObject => resultObject.data.nodeQuery.entities; |
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 happens if resultObject
isn't shaped properly? I think we might want to be defensive here with some optional chaining and appropriate checks.
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.
Fixed and tests added for this scenario.
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 looks very, very nice. Some very robust application code.
I added some commentary around one of the tests, but it's not something I consider blocking approval. I'll give you some time if you feel compelled to change anything or tell me I'm crazy, otherwise I'll get this merged.
} | ||
}; | ||
|
||
const postProcessDigitalForm = (queryResult, logger = logDrupal) => { |
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 love the dependency injection 😍
let processedResult; | ||
|
||
beforeEach(() => { | ||
sinon.stub(drupalUtils, 'logDrupal'); |
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.
CONSIDER
It feels like this should be a spy rather than a stub.
Perhaps more pertinently, though, it feels like we shouldn't need to spy on the specific implementation (drupalUtils.logDrupal
), but rather take advantage of the dependency injection you've beautifully included in your application code to pass a dummy logger (see line 177).
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.
Fixed
}; | ||
processedResult = postProcessDigitalForm( | ||
queryResult, | ||
drupalUtils.logDrupal, |
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.
CONSIDER
Connected to comment above (line 111). Do we need to import an actual implementation and pass it in here? It feels like we would want one of two things here:
- Do not pass a logger in here and test that the default logger is called. So, spy on
drupalUtils.logDrupal
but don't pass it in explicitly. - (Probably more valuable) Utilize the dependency injection, which allows us to better isolate the function in question, and pass a dummy logger.
It's arguable we'd want to do both of these, but, in that case, we would need two separate calls to postProcessDigitalForm
. I personally find more value in the second case, but there's always an "it depends".
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.
Spying on drupalUtils.logDrupal
didn't work for me. Not sure why. But I agree, now that we have the dependency injection, we don't actually need to spy on logDrupal
and can just pass in a sinon spy/stub to see that it is being called. I'll update the tests.
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.
Fixed.
* Add normalizeForms step to postProcessDigitalForm * Add subtitle to normalized form * Add OMB Number to normalized form * Normalize chapters for each form * Add additional fields for Name and Date of Birth step * Fix import spec * Remove redundant JSON parsing * Remove JSON conversion from returned value * Add formID and rename id to cmsId * Remove subTitle * Refactor normalizeForms method * Refactor normalizeChapters * Defend against malformed query responses * Remove unused import
* Add normalizeForms step to postProcessDigitalForm * Add subtitle to normalized form * Add OMB Number to normalized form * Normalize chapters for each form * Add additional fields for Name and Date of Birth step * Fix import spec * Remove redundant JSON parsing * Remove JSON conversion from returned value * Add formID and rename id to cmsId * Remove subTitle * Refactor normalizeForms method * Refactor normalizeChapters * Defend against malformed query responses * Remove unused import
* Add normalizeForms step to postProcessDigitalForm * Add subtitle to normalized form * Add OMB Number to normalized form * Normalize chapters for each form * Add additional fields for Name and Date of Birth step * Fix import spec * Remove redundant JSON parsing * Remove JSON conversion from returned value * Add formID and rename id to cmsId * Remove subTitle * Refactor normalizeForms method * Refactor normalizeChapters * Defend against malformed query responses * Remove unused import
* Add normalizeForms step to postProcessDigitalForm * Add subtitle to normalized form * Add OMB Number to normalized form * Normalize chapters for each form * Add additional fields for Name and Date of Birth step * Fix import spec * Remove redundant JSON parsing * Remove JSON conversion from returned value * Add formID and rename id to cmsId * Remove subTitle * Refactor normalizeForms method * Refactor normalizeChapters * Defend against malformed query responses * Remove unused import
* VATEAM-87714: Add KISS configuration for Digital Forms (#2213) * Create postProcessDigitalForm function * Add nameAndDateOfBirth fragment * Create digitalForm GraphQL fragment * Import nameAndDateOfBirth into digitalForm fragment * Create digitalForm query object * Import digitalForm fragment into query object * Export postProcessDigitalForm as postProcess * Add Digital Forms to DATA_FILES array * Fix module imports * Fix typo * Adds blank line for consistent spacing. --------- Co-authored-by: Ryan Koch <ryan.koch.0213@gmail.com> * VATEAM-88634: Create a normalization layer for Digital Forms (#2215) * Add normalizeForms step to postProcessDigitalForm * Add subtitle to normalized form * Add OMB Number to normalized form * Normalize chapters for each form * Add additional fields for Name and Date of Birth step * Fix import spec * Remove redundant JSON parsing * Remove JSON conversion from returned value * Add formID and rename id to cmsId * Remove subTitle * Refactor normalizeForms method * Refactor normalizeChapters * Defend against malformed query responses * Remove unused import --------- Co-authored-by: Derek Houck <derek@derekhouck.com>
Summary
Normalizes how a Digital Form object looks for post-processing.
Before
After
Related issue(s)
Testing done
What areas of the site does it impact?
Only affects the output of
digital-forms.json
, which is not currently generated in production.Acceptance criteria
Quality Assurance & Testing
Error Handling
Authentication
Requested Feedback
Is this the format desired for the normalization layer? Can you foresee any situations where this format will cause issues?