Efforts to make code more defensive against crashes:
Updated Link _onPress logic to no longer be async
Likely legacy carryover from flagship component that uses async for adding to calendar (as it needs to query device calendar permissions), design system Link omitted calendar as it necessitates native code so should not be relevant
Updated Icon component to allow a null passthrough and made the Link use it
Was noted as a potential error spot for the more/fewer hooks between renders as the no icon Link would return null while an icon-having Link would return the Icon component which contains hooks
With the null passthrough, it will always be "rendered" so the hooks should remain consistent
This adjustment also necessitated pulling the aligning the icon with the first row of text logic into the Icon component--I believe there's already a ticket outstanding to centralize that logic anyway and now it is so Alert/Snackbar/Checkbox can be updated accordingly if no issues are noted
The useExternalLink hook was updated to handle the unhandled promise errors from RN's Linking.openURL function when the URL is faulty
Entailed making the innards use async/await and try/catches
Should technically be impossible to fail for all Link types except url, but validated no longer getting unhandled promise warnings for various edge cases (see testing section below)
Other Link types apply a prefix (e.g. tel:) such that the url is not an empty string even if the consumer passed an empty string which results in weird behavior, but no warning of a failure
Updated 2 unit tests that broke from the changes in a manner expected based on the changes. Ticket #574 was created to more fully update unit tests separately due to time sensitivity of the changes.
Testing
Defensive code 1 above:
Validated the various link types in storybook still work as expected
Defensive code 2 above:
Validated at differing font scaling that the icon remains aligned with the first row of text
Validated with no icon that both icon was not present nor was the spacing to the link text
Spot checked Alert component icon alignment still appeared as expected with different font scaling to verify the normal flow is still working as before
Defensive code 3 above:
Validated new analytics working as expected
Validated the various link types in storybook still work as expected
Validated erroneous input:
Directions type:
"" opens maps app with no destination as expected
iOS points to some place in Ontario
Android points to a not far away business with "undefined" in the name
Did not explore manual overrides in code as it should behave the same as URL type below as a URL
Phone/TTY type:
"" phone/TTY still opens call logic with no number as before
Manually overriding removal of the tel: prefix yields expected hit of new analytic event
Text type:
"" text number opens messages logic with no number as expected
Manually overriding removal of the sms: prefix yields expected hit of new analytic event
URL type:
iOS:
https://www. yielded a server cannot be found error
https://www yielded the same
https:// yielded a cannot open page error
https: yielded the same
https yielded a "dead" click but hit new analytic event w/ error object and error message: Error: Unable to open URL: file:///private/var/containers/Bundle/Application/0CAB9745-B322-4A0B-90C7-63F66F13ACA9/Expo%20Go.app/https
http yielded the same
htt yielded the same (no confirm dialog anymore, conditional on http start)
"" yielded the same "dead" click, but different error: Invariant Violation: Invalid URL: cannot be empty
Android:
https://www. yielded a can't find site error
https://www yielded the same
https:// yielded the browser opening with URL about:blank
https: yielded the same
https yielded a "dead" click but hit new analytic event w/ robust error object and error message: Error: Could not open URL 'https': No Activity found to handle Intent { act=android.intent.action.VIEW dat=https flg=0x10000000 }
http yielded the same
htt yielded the same (no confirm dialog anymore, conditional on http start)
"" yielded the same "dead" click, but different error: Invariant Violation: Invalid URL: cannot be empty
An alpha build was considered for testing, but ultimately deemed not needed as these changes are ultimately self-contained to logic that is capable of being hit within Storybook. Additionally, it is aiming for quick turn-around with the app and app-level QA should cover any testing that would've been performed with an alpha build.
[x] Tested on iOS
[x] Tested on Android
[x] Tested on Web
PR Checklist
Code reviewer validation:
General
[x] PR is linked to ticket(s)
[x] PR has changelog label applied if it's to be included in the changelog
[ ] Acceptance criteria:
All satisfied or
Documented reason for not being performed or
Split to separate ticket and ticket is linked by relevant AC(s)
[ ] Above PR sections adequately filled out
[ ] If any breaking changes, in accordance with the pre-1.0.0 versioning guidelines: a CU ticket has been created for the VA Mobile App detailing necessary adjustments with the package version that will be published by this ticket
Code
[ ] Tests are included if appropriate (or split to separate ticket)
Description of Change
Efforts to make code more defensive against crashes:
url
, but validated no longer getting unhandled promise warnings for various edge cases (see testing section below)tel:
) such that theurl
is not an empty string even if the consumer passed an empty string which results in weird behavior, but no warning of a failureUpdated 2 unit tests that broke from the changes in a manner expected based on the changes. Ticket #574 was created to more fully update unit tests separately due to time sensitivity of the changes.
Testing
Defensive code 1 above:
Defensive code 2 above:
Defensive code 3 above:
tel:
prefix yields expected hit of new analytic eventsms:
prefix yields expected hit of new analytic eventhttps://www.
yielded a server cannot be found errorhttps://www
yielded the samehttps://
yielded a cannot open page errorhttps:
yielded the samehttps
yielded a "dead" click but hit new analytic event w/ error object and error message:Error: Unable to open URL: file:///private/var/containers/Bundle/Application/0CAB9745-B322-4A0B-90C7-63F66F13ACA9/Expo%20Go.app/https
http
yielded the samehtt
yielded the same (no confirm dialog anymore, conditional onhttp
start)Invariant Violation: Invalid URL: cannot be empty
https://www.
yielded a can't find site errorhttps://www
yielded the samehttps://
yielded the browser opening with URLabout:blank
https:
yielded the samehttps
yielded a "dead" click but hit new analytic event w/ robust error object and error message:Error: Could not open URL 'https': No Activity found to handle Intent { act=android.intent.action.VIEW dat=https flg=0x10000000 }
http
yielded the samehtt
yielded the same (no confirm dialog anymore, conditional onhttp
start)Invariant Violation: Invalid URL: cannot be empty
An alpha build was considered for testing, but ultimately deemed not needed as these changes are ultimately self-contained to logic that is capable of being hit within Storybook. Additionally, it is aiming for quick turn-around with the app and app-level QA should cover any testing that would've been performed with an alpha build.
PR Checklist
Code reviewer validation:
changelog
label applied if it's to be included in the changelogPublish
If changes warrant a new version per the versioning guidelines and the PR is approved and ready to merge:
main
into branchmain