-
Notifications
You must be signed in to change notification settings - Fork 133
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
Feature/megamenu fixes #875
Conversation
…eCloud/pwa-kit into feature/megamenu-fixes
packages/template-retail-react-app/app/components/drawer-menu/index.test.js
Outdated
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/list-menu/index.jsx
Outdated
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/list-menu/index.test.js
Outdated
Show resolved
Hide resolved
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.
(Incomplete review, but leaving comments since I'll be out.)
packages/template-retail-react-app/app/components/list-menu/index.test.js
Outdated
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/list-menu/index.jsx
Outdated
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/list-menu/index.jsx
Outdated
Show resolved
Hide resolved
…eCloud/pwa-kit into feature/megamenu-fixes
const theme = useTheme() | ||
const {baseStyle} = theme.components.ListMenu | ||
const [ariaBusy, setAriaBusy] = useState('true') |
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.
Nit:
const [ariaBusy, setAriaBusy] = useState('true') | |
const [isAriaBusy, setIsAriaBusy] = useState('true') |
useEffect(() => { | ||
setAriaBusy('false') | ||
}, []) |
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 might have mislead you in one of my previous comments, but it seems weird to have ariaBusy
default to true
, and then immediately set it to false after mount in this useEffect?
I'd imagine the busy state should based on if the fetch category promise is resolved.
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 don't think we need useState
at all for this. We just need
<nav
id="list-menu"
aria-label="main"
aria-live="polite"
aria-busy={root?.[itemsKey]?.filter(item => !item.loaded)?.length > 0}
aria-atomic="true"
>
ctx.delay(0), | ||
ctx.json({ | ||
customer_id: 'test', | ||
access_token: 'testtoken', |
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.
instead of mocking isTokenValid
, we could generate a valid jwt (with an expiration date 10 years from now) and paste it in here.
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.
10 years? Dream big! What's the latest date we could possibly use without breaking things? 🤔
jest.mock('./utils', () => { | ||
const originalModule = jest.requireActual('./utils') | ||
return { | ||
...originalModule | ||
} | ||
}) |
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 code block does nothing 😛 ... it mocks the module by the actual module itself. Unless there is some black magic behind this, if so, could you add a comment on why we need this?
jest.mock('./utils', () => { | |
const originalModule = jest.requireActual('./utils') | |
return { | |
...originalModule | |
} | |
}) |
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 added this because tests in this file will fail if it relies on the isTokenValid
mock in the global jest-setup
file but I will use the other approach to generate a valid JWT instead!
jest.mock('./utils', () => { | ||
const originalModule = jest.requireActual('./utils') | ||
return { | ||
...originalModule | ||
} | ||
}) |
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.
* | ||
*/ | ||
export const CategoriesContext = React.createContext() | ||
export const CategoriesProvider = ({categories: initialCategories = {}, children}) => { | ||
const [categories, setCategories] = useState(initialCategories) | ||
export const CategoriesProvider = ({treeRoot = {}, children, locale}) => { |
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.
Have we thought about what it might look like for the hook integration? This component seems to grown from a one liner to a pretty complicated one. I'm worried that we might end up re-write the logic during the hook integration, what can we do to mitigate that risk? (Sorry, I wish i could have said this at the beginning of the work, not when this is almost done..)
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 change should be all located in one spot, and if we can't call a hook inside a useEffect
then I think we've uncovered a problem with the hooks library in that we still need the SDK to make calls like this. I expect we might need to continue to use the SDK in some places. If that's true, then this might be one of those spots where we don't use the hooks library
// iterates through each deep nested object and if finds object that has prop and value specified in objToFindBy | ||
// argument, it replaces the current object with replacementObj, stops recursive walk and returns the whole tree. | ||
// If none is found, it returns false. | ||
const findAndModifyFirst = (tree, childrenKey, objToFindBy, replacementObj) => { |
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.
As a general best practices, a function should not mutate its input. Mutating the input leads to unexpected issues and makes code harder to understand. We could clone the input and always return that clone from the function.
const findAndModifyFirst = (tree, childrenKey, objToFindBy, replacementObj) => {
const clone = Object.assign({}, tree)
// do work ...
return clone
}
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.
Good suggestion. @wjhsf had mentioned this and I agree that we need to not mutate the input
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.
Actually @kevinxh my preference (not a big deal) is to use object spread which handles cloning implicitly.
const findAndModifyFirst = (tree, childrenKey, objToFindBy, replacementObj) => {
// do work
return {
...tree
}
}
) | ||
} | ||
|
||
global.server = setupMockServer() |
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 feels like a bad pattern. Tests should be isolated so that they can be run independently, and a globally shared variable makes it too easy to subtly change the server between tests and not notice. To guarantee a known state, each test should use its own mock server. If you want to DRY a bit, you could move the setup/teardown hooks into setupMockServer
.
(Also, you should pretty much never use global
; export
things instead.)
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 is a guaranteed known state. It is setupMockServer
(and to @kevinxh 's point, we should have a global catch to prevent any get|put|patch
etc. requests from touching the network).
I'm going to disagree here, our setupMockServer
implementation is unnecessary boilerplate and with the introduction of the change to <CategoriesProvider />
to make an API call, we would pretty much have to add setupMockServer
to every test file. Thus we are doing it globally.
We need to merge this and not rework it forever, so I'm going to vote against localizing / non-globalizing this
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.
As long as we can guarantee a known state per test, then that's fine. Should still switch to import
/export
, though, unless there's weird jest nonsense going on.
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 attempted to switch to import
/ export
, but things are not working for some reasons I couldn't figure out. Let's make this a iterative change and we will need to take a closer look at those tests.
ctx.delay(0), | ||
ctx.json({ | ||
customer_id: 'test', | ||
access_token: 'testtoken', |
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.
10 years? Dream big! What's the latest date we could possibly use without breaking things? 🤔
packages/template-retail-react-app/app/pages/reset-password/index.test.jsx
Show resolved
Hide resolved
packages/template-retail-react-app/app/pages/reset-password/index.test.jsx
Show resolved
Hide resolved
packages/template-retail-react-app/app/components/list-menu/index.test.js
Show resolved
Hide resolved
Promise.all( | ||
root?.[itemsKey]?.map(async (cat) => { |
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.
Sometimes I like to split things up to avoid extra nesting.
const promises = root?.[itemsKey]?.map(async (cat) => {
// ...
})
await Promise.all(promises)
}) | ||
) | ||
} catch (e) { | ||
return e |
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 this error returned?
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 still an outstanding issue. This will result in the category items being Category | Error
, which does not seem like what we want.
} | ||
|
||
const fetchCategoryNode = async (id, depth = 1) => { | ||
const STALE_TIME = 10000 // 10 seconds |
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 hasn't been marked resolved, but I just want to highlight that this is still an important issue to address.)
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.
Yikes, so much controversy on this one, most of it caused by me forgetting to remove that tree walking code that wasn't needed.
Great work pushing through 🏅
…eCloud/pwa-kit into feature/megamenu-fixes
}) | ||
) | ||
} catch (e) { | ||
return e |
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 still an outstanding issue. This will result in the category items being Category | Error
, which does not seem like what we want.
const storageString = window?.localStorage?.getItem( | ||
`${LOCAL_STORAGE_PREFIX}${id}-${locale}` | ||
) | ||
if (Date.now() < storageString?.fetchTime + STALE_TIME) { |
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 have an explicit condition here for if there's nothing in storage.
} | ||
setRoot(newTree) | ||
}) | ||
.catch((err) => console.log(err)) |
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 will log the error to the browser console without any context, and then do nothing. Is that what we want? Do we have a fallback / error state that the menus can show?
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.
#875 (comment) - Regarding this issue and the one referenced, would it be better to throw err
?
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.
They're different scenarios. For the other comment, I don't think we want error handling at that layer (don't catch/rethrow), just let it bubble up to whatever error handling we do have.
I'm not sure what the proper solution is, here. Depends on what happens when the category data requests fail. Probably not log and ignore, which is the current state. Maybe just let the error bubble up to react and then have proper error handling in a follow up ticket.
* New year, new look! (#876) * New year, new look! * Use JS to compute current year. * Small bump to max deps allowed. Needed to so that non-code changes will pass CI. Hitting the limit can be addressed later. * Update from 2.5.0 (#881) * Starting release process for 2.5.0 * allow commerce react sdk to release * bump version to 2.5.0 (#879) * bump version to 2.5.0 * bump max packages * Begin development on 2.6.0 * Set commerce-sdk-react package to private (#882) * test-commerce: comment out not-implemented customer hooks (#877) * Change padding (#899) * [Snyk] Security upgrade eslint-import-resolver-webpack from 0.10.0 to 0.13.1 (#887) * fix: packages/internal-lib-build/package.json & packages/internal-lib-build/package-lock.json to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-DEBUG-3227433 * upgrade eslint-webpack-plugin-import, regen lock file Co-authored-by: Alex Vuong <alex.vuong@salesforce.com> Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> * Cache SLAS callback using request processor (#884) * cache callback in request processor * fix import path * cache callback for a year * use native URLSearchParams * revert use native URLSearchParams * Rotate fingerprint ssh for deploy commerce sdk doc (#905) * Feature/megamenu fixes (#875) * [W-11996527] WIP - commit megamenu spike results / findings to feature branch * resolve search error * move default variables to constants file * cleanup code * add aria-live to menu categories * lint * implement aria live and busy * fix failing tests * update mock categories data, implement aria busy for listmenu * update mock data and fix list-menu test * lint * resolve unmounted component error * temporary testing server errors fix * set spinner opacity to 0 and increase max package value * lint * remove mock data from app code, clean up * allow padding of categories with loaded: true to bypass initial useEffect API call * fix last failing test * Update list-menu/index.jsx Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> * fix aria-busy implementation and cleanup * add more test cases - when there is no root categories * remove mit license comment * add depndency array to useeffect * globally mock getcategory api call * WIP * fix tests WIP * remove all instances of setupmockserver in test files * globally mock istokenvalid AND many other cleanup items * refactor tree walking code * add locale checks and time to localstorage * WIP removing tree walking logic * remove tree walking code, update setroot and extract stale time * add catch to promise all * lint * namespace constants, remove unnecessary try catch... * final cleanup * fix lint Co-authored-by: Brian Feister <bfeister@salesforce.com> Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> Co-authored-by: Kevin He <kevin.he@salesforce.com> * Mega menu fixes (#910) * Remove unnecessary catch clause. * Update copyright. * Don't return error when category is expected. * Fix bug preventing cache invalidation. * Set fetchTime when data is fetched, rather than every page load. * Update comment. * Convert promise chain to async/await for readability. * Guard against missing category items. * Move comment inside code block. * Change useEffect back to promise chain, not async/await. useEffect expects the callback to return nothing or a function; returning a promise could break things. * GitHub Actions (#854) * Add test workflow * Use actions/checkout v3 * Don't use CI image * Add step install npm dependencies * Add setup action * Set DEVELOP and RELEASE env variables * Add required shell property * Update action.yml * Update action.yml * Adding test matrix * cleanup * Split setup windows and ubuntu * Update test.yml * Update test.yml * Add Lighthouse and smoketest scripts * Not using actions/cache for now * Add generated matrix * Add missing runs-on prop to generated matrix * Add Setup Node step to generated matrix * Add Setup machine to generated matrix * Add cron schedule * Add timeout-minutes 5 * Move timeout to generate project step * Add Run tests on generated projects * Use dynamic generated-project folder * Run tests on test-project and retail-react-app-demo * Add Push Bundle step * Skip flaky test * Disable fail-fast strategy * Use env variables * Re-arrange env * Add step before push bundle * cleanup * cleanup * Use temp test-env-3 * testing slack notifs * testing * add publish to npm step * fix indent * python-dev does not exist anymore * use python2 * increase max packages * test slack notifs * add snyk cli and datadog step * update mrt user credentials * testing slack with pwa kit channel * syntax * fix conditionals * test push bundle * add push bundle step for generated * syntax * fix syntax error * update slack payload * run steps in container * testing * refactor * syntax * sudo container error * testing * update * add pip * use different docker * no container * container * testing * add user to container * fix * syntax add shell * syntax errors * remove container, use act * syntax errors * add snyk audit and other syntax stuff * extract steps to own actions * add inputs for actions * add shell for steps in actions with run * project cannot be generated in action file * updated snyk token, uncommenting code * Fix typo. * Add missing appkey property. * Use snake_case names for legibility. * Restore missing clean check * Fix skipped conversion to snake_case. * Trim trailing whitespace. * Extract conditionals to vars and clean up vars. * Change env IS_TESTABLE_TEMPLATE to more clear IS_TEMPLATE_FROM_RETAIL_REACT_APP * Fix YAML breaking conditional. * Try explicitly checking value. * Try explicitly checking true/false string values. * Try string comparisons. * Fix bad YAML. * Replace " with ' * Get ready for the prime time! * Fail fast! * Update TODOs. * Clean up npm version management. * Add TODO to merge workflows. * Update step names. * End files with newline. * Run on pull_request to support forked repos. * Only run on push for develop/release. We can assume all other branches will eventually have a PR. * Only push to MRT when actually desired. * Get that JavaScript nonsense outta here! * Check DEVELOP in step conditional, not in action execution. * Add some TODOs. * Too many newlines! Co-authored-by: yunakim714 <yunakim@salesforce.com> Co-authored-by: yunakim714 <84923642+yunakim714@users.noreply.github.com> Co-authored-by: Will Harney <wharney@salesforce.com> Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> * GitHub Actions fixes (#915) * Update is not fork check * Add single quote to cron expression * Add cron docs * Remove Circle CI config, fix IS_NOT_FORK (#921) * Fix develop branch name (#923) * Fix wrong proptypes (#924) * fix wrong proptypes * Update packages/template-retail-react-app/app/components/recommended-products/index.jsx Co-authored-by: Vincent Marta <vmarta@salesforce.com> Co-authored-by: Brian Feister <47546998+bfeister@users.noreply.github.com> Co-authored-by: Vincent Marta <vmarta@salesforce.com> * Update createOrder to send SLAS USID (#920) * Update createOrder to send SLAS USID * Modify some tests to include setting the header Co-authored-by: echessman <37908171+echessman@users.noreply.github.com> * Upgrade prettier to v2 (#926) * Upgrade to prettier v2 for modern TypeScript support. * Change trailing comma to prettier v1 default. Minimizes changes during v2 upgrade. * Apply prettier v2 formatting changes. Yaaay touching all of the files! * Set end of line to LF. * Remove unnecessary map statement (#929) * fix: packages/pwa-kit-runtime/package.json & packages/pwa-kit-runtime/package-lock.json to reduce vulnerabilities (#935) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-UAPARSERJS-3244450 Co-authored-by: snyk-bot <snyk-bot@snyk.io> * Update `develop` with v2.6.0 (#939) * Starting release process for 2.6.0 * 🚢 Release v2.6.0 (#937) * Update changelog files * Set `commerce-sdk-react-preview` as public * Version 2.6.0 * Begin development on 2.7.0 * Clean changelog files * Allow support for multiple sites concurrently w/ `commerce-sdk-react` (#911) * Namespace storage keys using the current siteId. Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> * @W-11920099 Re-write 'npm push' in Typescript, warn if Node deprecated (#763) * Rewrite ancient scripts in Typescript. * Show warnings on push when using a deprecated Node version. * Automatically select a `.mobify` credentials file based on `--cloud-origin`. * Fix broken CI – confusing path to package.json in the 'dist' directory! (#946) * Reliably look up project and pwa-kit-dev package.json in scripts * fix: handle special characters in `boldString` util (#942) + Add a new util for escaping special regex characters + Apply new util to `boldString` + Add and update util tests Co-authored-by: Brian Feister <47546998+bfeister@users.noreply.github.com> * Replace isomorphic jest mocks with msw handlers (#944) * replace most manual mocks * more replacements * more replacements in addresses test * lint * resolve flaky cart test * remove some jest mocks * replace all isomorphic mocks * cleanup * fix auth modal mocks * remove timers from auth hooks test, fix password test * remove timer from create account test * add timeout * cleanup --------- Co-authored-by: Brian Feister <bfeister@salesforce.com> * Remove the PersistentCache functionality (#949) * Initial pass at PersistentCache * Drop test coverage * Change test * Update customer baskets cache when there is a basket mutation (#945) * update customer baskets cache on basket mutations * Fix layout shift for mega menu (#952) * remove custom styling * remove theme in theme file * spinners in drawer menu should be visible * Serialize category data once only (#953) * serialize data only once * remove console log --------- Co-authored-by: Brian Feister <47546998+bfeister@users.noreply.github.com> * chore: update pwa-kit-dev eslint config (#950) + Bump `eslint-plugin-react` to latest version + Auto-detect React version Co-authored-by: Adam Raya <adamraya@users.noreply.github.com> * resolving testing/merge errors * Add Shopper Experience hooks (#958) * Initial commit * Update license * Update test project to use bjnl_dev * Fix usePage hook and Refactor test page * Add usePages hook * Add usePages pdp and plp test cases * Clean up * Update Changelog & Restore `zzrf-001` config --------- Co-authored-by: Ben Chypak <bchypak@salesforce.com> * add changelog * Apply changes from commerce react sdk in feature branch (#964) * apply change from commerce react sdk in feature branch * Remove wrong changlog * keep the same as develop * linting * fix formatMessage * bump sizes temporarily * fix product list tests * fix header tests * fix add to cart modal * skip tests and low test coverate temporarily * linting --------- Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com> Co-authored-by: Alex Vuong <52219283+alexvuong@users.noreply.github.com> Co-authored-by: vcua-mobify <47404250+vcua-mobify@users.noreply.github.com> Co-authored-by: Vincent Marta <vmarta@salesforce.com> Co-authored-by: Pavel <65617653+GoodNightBuddy@users.noreply.github.com> Co-authored-by: Snyk bot <snyk-bot@snyk.io> Co-authored-by: Alex Vuong <alex.vuong@salesforce.com> Co-authored-by: yunakim714 <84923642+yunakim714@users.noreply.github.com> Co-authored-by: Brian Feister <bfeister@salesforce.com> Co-authored-by: Adam Raya <adamraya@users.noreply.github.com> Co-authored-by: yunakim714 <yunakim@salesforce.com> Co-authored-by: Will Harney <wharney@salesforce.com> Co-authored-by: Brian Feister <47546998+bfeister@users.noreply.github.com> Co-authored-by: echessman <37908171+echessman@users.noreply.github.com> Co-authored-by: CC ProdSec <65211003+cc-prodsec@users.noreply.github.com> Co-authored-by: Ben Chypak <bchypak@mobify.com> Co-authored-by: Oliver Brook <o.brook@salesforce.com> Co-authored-by: Brad Adams <hi@breadadams.com> Co-authored-by: Kieran Haberstock <80915722+kieran-sf@users.noreply.github.com> Co-authored-by: Ben Chypak <bchypak@salesforce.com>
Description
Types of Changes
Changes
How to Test-Drive This PR
Checklists
General
Accessibility Compliance
You must check off all items in one of the follow two lists:
or...
Localization