-
Notifications
You must be signed in to change notification settings - Fork 4
86b82fa34 - feat: add url fragment linking to tabs on edit sponsor page #751
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
base: master
Are you sure you want to change the base?
Changes from all commits
90c4895
5540ef4
339a9b0
d7cdf0c
c3e31c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,226 @@ | ||||||||||||||||||||||||||||||||||
| import React from "react"; | ||||||||||||||||||||||||||||||||||
| import userEvent from "@testing-library/user-event"; | ||||||||||||||||||||||||||||||||||
| import { act, screen } from "@testing-library/react"; | ||||||||||||||||||||||||||||||||||
| import EditSponsorPage, { | ||||||||||||||||||||||||||||||||||
| getFragmentFromValue, | ||||||||||||||||||||||||||||||||||
| getTabFromUrlFragment | ||||||||||||||||||||||||||||||||||
| } from "../edit-sponsor-page"; | ||||||||||||||||||||||||||||||||||
| import { renderWithRedux } from "../../../utils/test-utils"; | ||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||
| DEFAULT_STATE as currentSponsorDefaultState | ||||||||||||||||||||||||||||||||||
| } from "../../../reducers/sponsors/sponsor-reducer"; | ||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||
| DEFAULT_ENTITY as defaultSummitEntity, | ||||||||||||||||||||||||||||||||||
| DEFAULT_STATE as currentSummitDefaultState | ||||||||||||||||||||||||||||||||||
| } from "../../../reducers/summits/current-summit-reducer"; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| global.window = { location: { pathname: "/sponsor-forms/items" } }; | ||||||||||||||||||||||||||||||||||
| jest.mock( | ||||||||||||||||||||||||||||||||||
| "../sponsor-forms-tab/components/manage-items/sponsor-forms-manage-items.js" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| jest.mock("../sponsor-users-list-per-sponsor/index.js"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| describe("EditSponsorPage", () => { | ||||||||||||||||||||||||||||||||||
| describe("getFragmentFromValue", () => { | ||||||||||||||||||||||||||||||||||
| it("returns correct values", () => { | ||||||||||||||||||||||||||||||||||
| const result1 = getFragmentFromValue(0); | ||||||||||||||||||||||||||||||||||
| expect(result1).toBe("general"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result2 = getFragmentFromValue(2); | ||||||||||||||||||||||||||||||||||
| expect(result2).toBe("pages"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result3 = getFragmentFromValue(3); | ||||||||||||||||||||||||||||||||||
| expect(result3).toBe("media_uploads"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result4 = getFragmentFromValue(7); | ||||||||||||||||||||||||||||||||||
| expect(result4).toBe("badge_scans"); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| describe("getTabFromUrlFragment", () => { | ||||||||||||||||||||||||||||||||||
| it("returns correct values for defined fragments", () => { | ||||||||||||||||||||||||||||||||||
| const newUrl1 = "#general"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl1; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result1 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result1).toBe(0); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const newUrl2 = "#pages"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl2; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result2 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result2).toBe(2); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const newUrl3 = "#media_uploads"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl3; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result3 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result3).toBe(3); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const newUrl4 = "#badge_scans"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl4; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result4 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result4).toBe(7); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| it("returns correct values for undefined fragments", () => { | ||||||||||||||||||||||||||||||||||
| const newUrl1 = "#generalx"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl1; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result1 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result1).toBe(0); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const newUrl2 = "#frewawqfwedwdwqq"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl2; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result2 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result2).toBe(0); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const newUrl3 = "#"; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl3; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result3 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result3).toBe(0); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const newUrl4 = ""; | ||||||||||||||||||||||||||||||||||
| window.location.hash = newUrl4; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const result4 = getTabFromUrlFragment(); | ||||||||||||||||||||||||||||||||||
| expect(result4).toBe(0); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| describe("Component", () => { | ||||||||||||||||||||||||||||||||||
| const originalWindowLocation = window.location; | ||||||||||||||||||||||||||||||||||
| it("should change the url fragment on tab click", async () => { | ||||||||||||||||||||||||||||||||||
| delete window.location; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Object.defineProperty(window, "location", { | ||||||||||||||||||||||||||||||||||
| configurable: true, | ||||||||||||||||||||||||||||||||||
| writable: true, | ||||||||||||||||||||||||||||||||||
| value: { | ||||||||||||||||||||||||||||||||||
| ...originalWindowLocation, | ||||||||||||||||||||||||||||||||||
| hash: "#general" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| renderWithRedux( | ||||||||||||||||||||||||||||||||||
| <EditSponsorPage | ||||||||||||||||||||||||||||||||||
| history={{}} | ||||||||||||||||||||||||||||||||||
| location={{ | ||||||||||||||||||||||||||||||||||
| pathname: "/sponsor-forms/items" | ||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||
| match={{}} | ||||||||||||||||||||||||||||||||||
| />, | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| initialState: { | ||||||||||||||||||||||||||||||||||
| currentSummitState: { | ||||||||||||||||||||||||||||||||||
| currentSummit: defaultSummitEntity, | ||||||||||||||||||||||||||||||||||
| ...currentSummitDefaultState | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| loggedUserState: { | ||||||||||||||||||||||||||||||||||
| member: { | ||||||||||||||||||||||||||||||||||
| groups: {} | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| currentSummitSponsorshipListState: { | ||||||||||||||||||||||||||||||||||
| sponsorships: [], | ||||||||||||||||||||||||||||||||||
| currentPage: 1, | ||||||||||||||||||||||||||||||||||
| lastPage: 1, | ||||||||||||||||||||||||||||||||||
| perPage: 100, | ||||||||||||||||||||||||||||||||||
| order: "order", | ||||||||||||||||||||||||||||||||||
| orderDir: 1, | ||||||||||||||||||||||||||||||||||
| totalSponsorships: 0 | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| currentSponsorState: { | ||||||||||||||||||||||||||||||||||
| sponsorships: [], | ||||||||||||||||||||||||||||||||||
| ...currentSponsorDefaultState | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const usersTabReference = screen.getByText("edit_sponsor.tab.forms"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| await act(async () => { | ||||||||||||||||||||||||||||||||||
| await userEvent.click(usersTabReference); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| expect(window.location.hash).toBe("forms"); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+144
to
+151
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, find and read the test file
cat -n src/pages/sponsors/__tests__/edit-sponsor-page.test.js | head -200Repository: fntechgit/summit-admin Length of output: 6883 🏁 Script executed: # Find and read the EditSponsorPage component
cat -n src/pages/sponsors/edit-sponsor-page.js | head -300Repository: fntechgit/summit-admin Length of output: 11190 Fix hash format to match JSDOM behavior. 🔧 Suggested fix- expect(window.location.hash).toBe("forms");
+ expect(window.location.hash).toBe("#forms");📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| it("should change the tab rendered on fragment change", async () => { | ||||||||||||||||||||||||||||||||||
| delete window.location; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Object.defineProperty(window, "location", { | ||||||||||||||||||||||||||||||||||
| configurable: true, | ||||||||||||||||||||||||||||||||||
| writable: true, | ||||||||||||||||||||||||||||||||||
| value: { | ||||||||||||||||||||||||||||||||||
| ...originalWindowLocation, | ||||||||||||||||||||||||||||||||||
| hash: "#general" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| renderWithRedux( | ||||||||||||||||||||||||||||||||||
| <EditSponsorPage | ||||||||||||||||||||||||||||||||||
| history={{}} | ||||||||||||||||||||||||||||||||||
| location={{ | ||||||||||||||||||||||||||||||||||
| pathname: "/sponsor-forms/items" | ||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||
| match={{}} | ||||||||||||||||||||||||||||||||||
| />, | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| initialState: { | ||||||||||||||||||||||||||||||||||
| currentSummitState: { | ||||||||||||||||||||||||||||||||||
| currentSummit: defaultSummitEntity, | ||||||||||||||||||||||||||||||||||
| ...currentSummitDefaultState | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| loggedUserState: { | ||||||||||||||||||||||||||||||||||
| member: { | ||||||||||||||||||||||||||||||||||
| groups: {} | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| currentSummitSponsorshipListState: { | ||||||||||||||||||||||||||||||||||
| sponsorships: [], | ||||||||||||||||||||||||||||||||||
| currentPage: 1, | ||||||||||||||||||||||||||||||||||
| lastPage: 1, | ||||||||||||||||||||||||||||||||||
| perPage: 100, | ||||||||||||||||||||||||||||||||||
| order: "order", | ||||||||||||||||||||||||||||||||||
| orderDir: 1, | ||||||||||||||||||||||||||||||||||
| totalSponsorships: 0 | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| currentSponsorState: { | ||||||||||||||||||||||||||||||||||
| sponsorships: [], | ||||||||||||||||||||||||||||||||||
| ...currentSponsorDefaultState | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const generalTabPanel = screen.getByTestId("simple-tabpanel-0"); | ||||||||||||||||||||||||||||||||||
| expect(generalTabPanel).toBeDefined(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| delete window.location; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Object.defineProperty(window, "location", { | ||||||||||||||||||||||||||||||||||
| configurable: true, | ||||||||||||||||||||||||||||||||||
| writable: true, | ||||||||||||||||||||||||||||||||||
| value: { | ||||||||||||||||||||||||||||||||||
| ...originalWindowLocation, | ||||||||||||||||||||||||||||||||||
| hash: "#users" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const usersTabPanel = screen.getByTestId("simple-tabpanel-1"); | ||||||||||||||||||||||||||||||||||
| expect(usersTabPanel).toBeDefined(); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+153
to
+217
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, confirm the test file exists and check the code around lines 153-217
fd "edit-sponsor-page.test.js" --type fRepository: fntechgit/summit-admin Length of output: 120 🏁 Script executed: # Find and explore the test file
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '140,220p'Repository: fntechgit/summit-admin Length of output: 2648 🏁 Script executed: # Check the EditSponsorPage component to see how it handles hash changes
fd "edit-sponsor-page" --type f | grep -v test | grep -v ".test"Repository: fntechgit/summit-admin Length of output: 105 🏁 Script executed: # Examine the EditSponsorPage component to understand how it handles hash changes
cat -n "src/pages/sponsors/edit-sponsor-page.js" | head -150Repository: fntechgit/summit-admin Length of output: 5445 🏁 Script executed: # Search for hashchange or hash-related event listeners in the component
rg "hashchange|window.location.hash|hash" "src/pages/sponsors/edit-sponsor-page.js" -A 3 -B 2Repository: fntechgit/summit-admin Length of output: 502 🏁 Script executed: # Check if the component uses useEffect to listen to hash changes
ast-grep --pattern 'useEffect($$$)' "src/pages/sponsors/edit-sponsor-page.js"Repository: fntechgit/summit-admin Length of output: 1168 🏁 Script executed: # Check the test setup and imports to see what testing utilities are available
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | head -50Repository: fntechgit/summit-admin Length of output: 2017 🏁 Script executed: # Search for how hashchange is handled elsewhere in tests
rg "hashchange|HashChangeEvent" --type js -iRepository: fntechgit/summit-admin Length of output: 164 🏁 Script executed: # Check if there's a custom hook or utility for managing hash-based routing
rg "getTabFromUrlFragment|getFragmentFromValue" --type js -A 2 -B 2Repository: fntechgit/summit-admin Length of output: 6929 🏁 Script executed: # Check if there are other tests that use hashchange or similar patterns
rg "hashchange|HashChangeEvent|window.dispatchEvent" --type js -B 2 -A 2Repository: fntechgit/summit-admin Length of output: 488 🏁 Script executed: # Look at the complete test to see if there's proper act() wrapping or waitFor
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '100,220p'Repository: fntechgit/summit-admin Length of output: 3955 🏁 Script executed: # Check package.json to see what testing libraries are available
rg "testing-library|jest" package.jsonRepository: fntechgit/summit-admin Length of output: 525 🏁 Script executed: # Check if the component has any hashchange event listeners
cat -n "src/pages/sponsors/edit-sponsor-page.js" | grep -A 20 "useEffect"Repository: fntechgit/summit-admin Length of output: 1893 🏁 Script executed: # Verify the CustomTabPanel implementation to understand the hidden/visibility logic
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '69,84p'Repository: fntechgit/summit-admin Length of output: 570 🏁 Script executed: # Check if other components in the codebase listen to hashchange and how they do it
rg "addEventListener.*hash|window.onhashchange" --type js -B 3 -A 5Repository: fntechgit/summit-admin Length of output: 788 🏁 Script executed: # Check how other tests in this file handle async state changes and waits
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '70,105p'Repository: fntechgit/summit-admin Length of output: 1237 🏁 Script executed: # Search for patterns of waiting for effects in similar tests
rg "waitFor|act.*hash|fireEvent" "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" -A 3 -B 1Repository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Check if there are other tests that verify visibility of rendered elements
rg "toBeVisible|hidden|role.*tabpanel" --type js -B 2 -A 2 | head -40Repository: fntechgit/summit-admin Length of output: 3005 🏁 Script executed: # Let's look at the complete test and see if there's any waiting mechanism
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '150,225p'Repository: fntechgit/summit-admin Length of output: 2503 🏁 Script executed: # Check if renderWithRedux or test setup does anything special with effects
rg "renderWithRedux|beforeEach|afterEach" "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" -A 10 -B 1Repository: fntechgit/summit-admin Length of output: 1185 🏁 Script executed: # Verify how React's useEffect dependency works - check if the component actually responds to hash changes at runtime
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '119,135p'Repository: fntechgit/summit-admin Length of output: 640 🏁 Script executed: # Check if there are any imports of fireEvent or other event simulation tools in the test
head -30 "src/pages/sponsors/__tests__/edit-sponsor-page.test.js"Repository: fntechgit/summit-admin Length of output: 1138 🏁 Script executed: # Verify if jest-dom provides toBeVisible matcher
rg "jest-dom|toBeVisible|toHaveAttribute" "src/pages/sponsors/__tests__/edit-sponsor-page.test.js"Repository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Check if the component implementation actually listens to hashchange events
rg "addEventListener.*hashchange|on.*hashchange|onhashchange" "src/pages/sponsors/edit-sponsor-page.js"Repository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Check if jest-dom is set up in a setup file
fd "setup" --type f | grep -i jestRepository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Look for jest configuration to see if jest-dom is imported
rg "setupFilesAfterEnv|testEnvironment" package.json -A 3Repository: fntechgit/summit-admin Length of output: 170 🏁 Script executed: # Test a hypothesis: check if the component would even work correctly with the dependency on window.location.hash
# Search for similar useEffect patterns with window.location
rg "useEffect.*window.location|dependency.*window" --type js -B 2 -A 3Repository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Let's check the test setup file to understand the environment better
cat "testSetupFile.js" | head -50Repository: fntechgit/summit-admin Length of output: 182 🏁 Script executed: # Verify if the CustomTabPanel's hidden attribute actually hides elements testable with toBeVisible
rg "hidden.*attribute|aria-hidden|display.*none" "src/pages/sponsors/edit-sponsor-page.js" -B 2 -A 2Repository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Let's trace through what happens - check if there's any event listener setup elsewhere
rg "addEventListener" "src/pages/sponsors/edit-sponsor-page.js"Repository: fntechgit/summit-admin Length of output: 48 🏁 Script executed: # Check the complete rendering of the component to see all tabs
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '170,250p'Repository: fntechgit/summit-admin Length of output: 3688 🏁 Script executed: # Verify the exact behavior: does the component update when window.location.hash changes at runtime?
# Let's check if maybe there's a different mechanism (like router props) that drives updates
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '90,130p'Repository: fntechgit/summit-admin Length of output: 1384 Assert tab visibility, not just existence. The test changes 🔧 Suggested fix Object.defineProperty(window, "location", {
configurable: true,
writable: true,
value: {
...originalWindowLocation,
hash: "#users"
}
});
+ window.dispatchEvent(new HashChangeEvent("hashchange"));
const usersTabPanel = screen.getByTestId("simple-tabpanel-1");
- expect(usersTabPanel).toBeDefined();
+ expect(usersTabPanel).toBeVisible();
+ expect(generalTabPanel).not.toBeVisible();🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| afterEach(() => { | ||||||||||||||||||||||||||||||||||
| Object.defineProperty(window, "location", { | ||||||||||||||||||||||||||||||||||
| configurable: true, | ||||||||||||||||||||||||||||||||||
| value: originalWindowLocation | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,14 +46,35 @@ import SponsorCartTab from "./sponsor-cart-tab"; | |
| import SponsorFormsManageItems from "./sponsor-forms-tab/components/manage-items/sponsor-forms-manage-items"; | ||
| import { SPONSOR_TABS } from "../../utils/constants"; | ||
|
|
||
| const CustomTabPanel = (props) => { | ||
| export const tabsToFragmentMap = [ | ||
| "general", | ||
| "users", | ||
| "pages", | ||
| "media_uploads", | ||
| "forms", | ||
| "cart", | ||
| "purchases", | ||
| "badge_scans" | ||
| ]; | ||
|
|
||
| export const getFragmentFromValue = (index) => tabsToFragmentMap[index]; | ||
|
|
||
| export const getTabFromUrlFragment = () => { | ||
| const result = tabsToFragmentMap.indexOf( | ||
| window.location.hash.replace("#", "") | ||
| ); | ||
| return result > -1 ? result : 0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on the initial load
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup! If the |
||
| }; | ||
|
|
||
| export const CustomTabPanel = (props) => { | ||
| const { children, value, index, ...other } = props; | ||
|
|
||
| return ( | ||
| <div | ||
| role="tabpanel" | ||
| hidden={value !== index} | ||
| id={`simple-tabpanel-${index}`} | ||
| data-testid={`simple-tabpanel-${index}`} | ||
| aria-labelledby={`simple-tab-${index}`} | ||
| {...other} | ||
| > | ||
|
|
@@ -97,16 +118,15 @@ const EditSponsorPage = (props) => { | |
| getExtraQuestionMeta | ||
| } = props; | ||
|
|
||
| const [selectedTab, setSelectedTab] = useState( | ||
| location.pathname.includes("/sponsor-forms/") && | ||
| location.pathname.includes("/items") | ||
| ? SPONSOR_TABS.FORMS | ||
| : 0 | ||
| ); | ||
| const [selectedTab, setSelectedTab] = useState(getTabFromUrlFragment()); | ||
|
|
||
| useEffect(() => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @niko-exo To support SPA-style hash navigation (manual hash edits, back/forward), please replace that effect with a hashchange listener |
||
| setSelectedTab(getTabFromUrlFragment()); | ||
| }, [window.location.hash]); | ||
|
|
||
| const handleTabChange = (event, newValue) => { | ||
| setSelectedTab(newValue); | ||
| history.push(`/app/summits/${currentSummit.id}/sponsors/${entity.id}`); | ||
| window.location.hash = getFragmentFromValue(newValue); | ||
| }; | ||
|
|
||
| useEffect(() => { | ||
|
|
||
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.
🧩 Analysis chain
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 207
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 2017
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 1833
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 5445
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 873
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 5213
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 732
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 652
🏁 Script executed:
# Check what the full test file looks like to understand the testing strategy wc -l src/pages/sponsors/__tests__/edit-sponsor-page.test.jsRepository: fntechgit/summit-admin
Length of output: 124
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 1197
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 1348
🏁 Script executed:
Repository: fntechgit/summit-admin
Length of output: 245
Remove the global.window override — it prevents JSDOM's Location API from functioning properly.
Line 17 replaces the entire JSDOM window with a minimal stub. This becomes the "reference" used by tests, preventing proper Location semantics when later tests try to mock
window.location.hash. Remove the override and keep the real JSDOM window; tests already resetwindow.locationas needed viaObject.definePropertyin their setup.Fix
- global.window = { location: { pathname: "/sponsor-forms/items" } };📝 Committable suggestion
🤖 Prompt for AI Agents