diff --git a/src/utilities/Accounts-test.js b/src/utilities/Accounts-test.js
new file mode 100644
index 0000000000..fa0a00513c
--- /dev/null
+++ b/src/utilities/Accounts-test.js
@@ -0,0 +1,104 @@
+import { describe, expect, it } from 'vitest'
+import { getSortedAccountsWithMembers } from 'src/utilities/Accounts'
+
+describe('getSortedAccountsWithMembers', () => {
+ it('returns empty array when no accounts match members', () => {
+ const accounts = [{ guid: 'ACC-1', member_guid: 'MEM-999', user_name: 'Account 1' }]
+ const members = [{ guid: 'MEM-1', name: 'Member 1' }]
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result).toEqual([])
+ })
+
+ it('filters accounts by member guid and adds member name', () => {
+ const accounts = [
+ { guid: 'ACC-1', member_guid: 'MEM-1', user_name: 'Checking' },
+ { guid: 'ACC-2', member_guid: 'MEM-2', user_name: 'Savings' },
+ ]
+ const members = [
+ { guid: 'MEM-1', name: 'Bank of America' },
+ { guid: 'MEM-2', name: 'Chase' },
+ ]
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result).toHaveLength(2)
+
+ const checking = result.find((a) => a.guid === 'ACC-1')
+ const savings = result.find((a) => a.guid === 'ACC-2')
+
+ expect(checking).toEqual({
+ guid: 'ACC-1',
+ member_guid: 'MEM-1',
+ user_name: 'Checking',
+ memberName: 'Bank of America',
+ })
+ expect(savings).toEqual({
+ guid: 'ACC-2',
+ member_guid: 'MEM-2',
+ user_name: 'Savings',
+ memberName: 'Chase',
+ })
+ })
+
+ it('sorts accounts by user_name alphabetically', () => {
+ const accounts = [
+ { guid: 'ACC-1', member_guid: 'MEM-1', user_name: 'Savings' },
+ { guid: 'ACC-2', member_guid: 'MEM-1', user_name: 'Checking' },
+ { guid: 'ACC-3', member_guid: 'MEM-1', user_name: 'Investment' },
+ ]
+ const members = [{ guid: 'MEM-1', name: 'Bank' }]
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result[0].user_name).toBe('Checking')
+ expect(result[1].user_name).toBe('Investment')
+ expect(result[2].user_name).toBe('Savings')
+ })
+
+ it('filters out accounts without matching member', () => {
+ const accounts = [
+ { guid: 'ACC-1', member_guid: 'MEM-1', user_name: 'Account 1' },
+ { guid: 'ACC-2', member_guid: 'MEM-999', user_name: 'Account 2' },
+ { guid: 'ACC-3', member_guid: 'MEM-2', user_name: 'Account 3' },
+ ]
+ const members = [
+ { guid: 'MEM-1', name: 'Member 1' },
+ { guid: 'MEM-2', name: 'Member 2' },
+ ]
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result).toHaveLength(2)
+ expect(result.find((a) => a.guid === 'ACC-2')).toBeUndefined()
+ })
+
+ it('handles empty members array', () => {
+ const accounts = [{ guid: 'ACC-1', member_guid: 'MEM-1', user_name: 'Account 1' }]
+ const members = []
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result).toEqual([])
+ })
+
+ it('handles empty accounts array', () => {
+ const accounts = []
+ const members = [{ guid: 'MEM-1', name: 'Member 1' }]
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result).toEqual([])
+ })
+
+ it('leaves memberName undefined when the matched member has no name', () => {
+ const accounts = [{ guid: 'ACC-1', member_guid: 'MEM-1', user_name: 'Account 1' }]
+ const members = [{ guid: 'MEM-1' }]
+
+ const result = getSortedAccountsWithMembers(accounts, members)
+
+ expect(result).toHaveLength(1)
+ expect(result[0].memberName).toBeUndefined()
+ })
+})
diff --git a/src/utilities/KeyPress-test.js b/src/utilities/KeyPress-test.js
new file mode 100644
index 0000000000..0fddbd8d6f
--- /dev/null
+++ b/src/utilities/KeyPress-test.js
@@ -0,0 +1,22 @@
+import { describe, expect, it, vi } from 'vitest'
+import { preventDefaultAndStopAllPropagation } from 'src/utilities/KeyPress'
+
+describe('preventDefaultAndStopAllPropagation', () => {
+ const createMockEvent = () => ({
+ preventDefault: vi.fn(),
+ stopPropagation: vi.fn(),
+ nativeEvent: {
+ stopImmediatePropagation: vi.fn(),
+ },
+ })
+
+ it('stops the event on both the synthetic and native event so global listeners do not fire', () => {
+ const event = createMockEvent()
+
+ preventDefaultAndStopAllPropagation(event)
+
+ expect(event.preventDefault).toHaveBeenCalledTimes(1)
+ expect(event.stopPropagation).toHaveBeenCalledTimes(1)
+ expect(event.nativeEvent.stopImmediatePropagation).toHaveBeenCalledTimes(1)
+ })
+})
diff --git a/src/utilities/Polyfill-test.js b/src/utilities/Polyfill-test.js
new file mode 100644
index 0000000000..c56d8cf79d
--- /dev/null
+++ b/src/utilities/Polyfill-test.js
@@ -0,0 +1,97 @@
+import { describe, expect, it, beforeEach, afterEach } from 'vitest'
+import { fromEntriesPolyfill } from 'src/utilities/Polyfill'
+
+describe('fromEntriesPolyfill', () => {
+ let originalFromEntries
+
+ const installPolyfill = () => {
+ delete Object.fromEntries
+ fromEntriesPolyfill()
+ }
+
+ beforeEach(() => {
+ originalFromEntries = Object.fromEntries
+ })
+
+ afterEach(() => {
+ Object.fromEntries = originalFromEntries
+ })
+
+ it('does not override Object.fromEntries if it exists', () => {
+ const existingImpl = Object.fromEntries
+
+ fromEntriesPolyfill()
+
+ expect(Object.fromEntries).toBe(existingImpl)
+ })
+
+ it('adds Object.fromEntries if it does not exist', () => {
+ installPolyfill()
+
+ expect(Object.fromEntries).toBeDefined()
+ expect(typeof Object.fromEntries).toBe('function')
+ })
+
+ it('creates object from entries array when polyfilled', () => {
+ installPolyfill()
+
+ const entries = [
+ ['a', 1],
+ ['b', 2],
+ ['c', 3],
+ ]
+ const result = Object.fromEntries(entries)
+
+ expect(result).toEqual({ a: 1, b: 2, c: 3 })
+ })
+
+ it('handles Map entries when polyfilled', () => {
+ installPolyfill()
+
+ const map = new Map([
+ ['key1', 'value1'],
+ ['key2', 'value2'],
+ ])
+ const result = Object.fromEntries(map)
+
+ expect(result).toEqual({ key1: 'value1', key2: 'value2' })
+ })
+
+ it('throws for non-iterable arguments when polyfilled', () => {
+ installPolyfill()
+
+ const expectedError = 'Object.fromEntries() requires a single iterable argument'
+
+ expect(() => Object.fromEntries(null)).toThrow(expectedError)
+ expect(() => Object.fromEntries(42)).toThrow(expectedError)
+ })
+
+ it('handles empty entries array when polyfilled', () => {
+ installPolyfill()
+
+ const result = Object.fromEntries([])
+
+ expect(result).toEqual({})
+ })
+
+ it('handles various value types when polyfilled', () => {
+ installPolyfill()
+
+ const entries = [
+ ['string', 'value'],
+ ['number', 42],
+ ['boolean', true],
+ ['null', null],
+ ['object', { nested: 'object' }],
+ ]
+ const result = Object.fromEntries(entries)
+
+ expect(result).toEqual({
+ string: 'value',
+ number: 42,
+ boolean: true,
+ null: null,
+ object: { nested: 'object' },
+ })
+ })
+})
diff --git a/src/utilities/ScrollToTop-test.js b/src/utilities/ScrollToTop-test.js
new file mode 100644
index 0000000000..8260206035
--- /dev/null
+++ b/src/utilities/ScrollToTop-test.js
@@ -0,0 +1,23 @@
+import { describe, expect, it, vi } from 'vitest'
+import { scrollToTop } from 'src/utilities/ScrollToTop'
+
+describe('scrollToTop', () => {
+ it('scrolls the ref element into view and returns the result', () => {
+ const scrollIntoView = vi.fn().mockReturnValue('scrolled')
+ const ref = {
+ current: {
+ scrollIntoView,
+ },
+ }
+
+ const result = scrollToTop(ref)
+
+ expect(scrollIntoView).toHaveBeenCalledWith(true)
+ expect(result).toBe('scrolled')
+ })
+
+ it('does nothing and returns undefined when ref.current is not set', () => {
+ expect(scrollToTop({ current: null })).toBeUndefined()
+ expect(scrollToTop({ current: undefined })).toBeUndefined()
+ })
+})
diff --git a/src/views/consent/ConsentModal-test.tsx b/src/views/consent/ConsentModal-test.tsx
new file mode 100644
index 0000000000..3f6459f9d5
--- /dev/null
+++ b/src/views/consent/ConsentModal-test.tsx
@@ -0,0 +1,88 @@
+import React from 'react'
+import { render, screen } from 'src/utilities/testingLibrary'
+import { ConsentModal } from 'src/views/consent/ConsentModal'
+import * as globalUtils from 'src/utilities/global'
+
+vi.mock('src/utilities/global', () => ({
+ goToUrlLink: vi.fn(),
+}))
+
+describe('ConsentModal', () => {
+ const mockSetDialogIsOpen = vi.fn()
+ const defaultProps = {
+ dialogIsOpen: true,
+ setDialogIsOpen: mockSetDialogIsOpen,
+ }
+
+ beforeEach(() => {
+ vi.clearAllMocks()
+ })
+
+ describe('Rendering', () => {
+ it('should render the modal with its content when dialogIsOpen is true', () => {
+ render()
+
+ expect(screen.getByText('Who is MX Technologies?')).toBeInTheDocument()
+ expect(
+ screen.getByText(
+ /MX is a trusted financial data platform that securely connects your accounts/i,
+ ),
+ ).toBeInTheDocument()
+ expect(screen.getByText('MX promise:')).toBeInTheDocument()
+ })
+
+ it('should render the secure, control, and private promise sections', () => {
+ render()
+
+ expect(screen.getByText('Secure:')).toBeInTheDocument()
+ expect(
+ screen.getByText('Industry-standard encryption protects your data.'),
+ ).toBeInTheDocument()
+ expect(screen.getByText('Control:')).toBeInTheDocument()
+ expect(screen.getByText('You can manage and revoke access anytime.')).toBeInTheDocument()
+ expect(screen.getByText('Private:')).toBeInTheDocument()
+ expect(
+ screen.getByText('Your data is never sold or shared without consent.'),
+ ).toBeInTheDocument()
+ })
+
+ it('should not render the modal when dialogIsOpen is false', () => {
+ render()
+
+ expect(screen.queryByText('Who is MX Technologies?')).not.toBeInTheDocument()
+ })
+ })
+
+ describe('Interactions', () => {
+ it('should toggle dialogIsOpen when the Close button is clicked', async () => {
+ const { user } = render()
+
+ await user.click(screen.getByText('Close'))
+
+ expect(mockSetDialogIsOpen).toHaveBeenCalledWith(expect.any(Function))
+
+ // The updater flips the previous open state.
+ const toggle = mockSetDialogIsOpen.mock.calls[0][0]
+ expect(toggle(true)).toBe(false)
+ expect(toggle(false)).toBe(true)
+ })
+
+ it('should toggle dialogIsOpen when the dialog is dismissed with Escape', async () => {
+ const { user } = render()
+
+ expect(screen.getByRole('dialog')).toBeInTheDocument()
+
+ await user.keyboard('{Escape}')
+
+ expect(mockSetDialogIsOpen).toHaveBeenCalledWith(expect.any(Function))
+ })
+
+ it('should open the MX company page when Learn more is clicked', async () => {
+ const { user } = render()
+
+ await user.click(screen.getByText('Learn more'))
+
+ expect(globalUtils.goToUrlLink).toHaveBeenCalledWith('https://www.mx.com/company/')
+ })
+ })
+})
diff --git a/src/views/consent/DynamicDisclosure-test.tsx b/src/views/consent/DynamicDisclosure-test.tsx
new file mode 100644
index 0000000000..82fa6641f1
--- /dev/null
+++ b/src/views/consent/DynamicDisclosure-test.tsx
@@ -0,0 +1,473 @@
+import React from 'react'
+import { screen, render, waitFor } from 'src/utilities/testingLibrary'
+import { DynamicDisclosure } from 'src/views/consent/DynamicDisclosure'
+import { initialState } from 'src/services/mockedData'
+import { AGG_MODE, VERIFY_MODE } from 'src/const/Connect'
+import { ActionTypes } from 'src/redux/actions/Connect'
+import * as Animation from 'src/utilities/Animation'
+import * as Intl from 'src/utilities/Intl'
+
+declare global {
+ interface Window {
+ app: {
+ options: { language: string }
+ }
+ }
+}
+
+vi.mock('src/utilities/Animation', () => ({
+ fadeOut: vi.fn(() => Promise.resolve()),
+}))
+
+const dispatch = vi.fn()
+vi.mock('react-redux', async (importActual) => {
+ const actual = await importActual()
+ return {
+ ...actual,
+ useDispatch: () => dispatch,
+ }
+})
+
+const onConsentClick = vi.fn()
+const onGoBackClick = vi.fn()
+
+const dynamicDisclosureProps = {
+ onConsentClick,
+ onGoBackClick,
+}
+
+const mockInstitution = {
+ guid: 'INS-123',
+ name: 'Test Bank',
+ logo_url: 'https://example.com/logo.png',
+}
+
+describe('DynamicDisclosure', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ window.app = { options: { language: 'en-us' } }
+ Object.defineProperty(document.documentElement, 'scrollHeight', {
+ writable: true,
+ configurable: true,
+ value: 1000,
+ })
+ Object.defineProperty(document.documentElement, 'scrollTop', {
+ writable: true,
+ configurable: true,
+ value: 0,
+ })
+ Object.defineProperty(document.documentElement, 'clientHeight', {
+ writable: true,
+ configurable: true,
+ value: 800,
+ })
+ })
+
+ describe('Rendering', () => {
+ it('loads the consent screen', async () => {
+ const ref = React.createRef()
+ render()
+
+ expect(await screen.findByTestId('dynamic-disclosure-title')).toBeInTheDocument()
+ expect(await screen.findByTestId('dynamic-disclosure-p1')).toBeInTheDocument()
+ expect(await screen.findByText('I consent')).toBeInTheDocument()
+ expect(await screen.findByText('Account Information')).toBeInTheDocument()
+ })
+
+ it('should render with app name when provided', () => {
+ const state = {
+ ...initialState,
+ profiles: {
+ ...initialState.profiles,
+ client: {
+ ...initialState.profiles.client,
+ oauth_app_name: 'MyApp',
+ },
+ },
+ connect: {
+ ...initialState.connect,
+ selectedInstitution: mockInstitution,
+ },
+ }
+
+ const { container } = render(, {
+ preloadedState: state,
+ })
+
+ expect(container.textContent).toContain('MyApp uses MX Technologies')
+ })
+
+ it('should render without app name when not provided', () => {
+ const state = {
+ ...initialState,
+ profiles: {
+ ...initialState.profiles,
+ client: {
+ ...initialState.profiles.client,
+ oauth_app_name: null,
+ },
+ },
+ connect: {
+ ...initialState.connect,
+ selectedInstitution: mockInstitution,
+ },
+ }
+
+ const { container } = render(, {
+ preloadedState: state,
+ })
+
+ expect(container.textContent).toContain('This app uses MX Technologies')
+ })
+
+ it('should render Share your data title', () => {
+ render()
+
+ expect(screen.getByTestId('dynamic-disclosure-title')).toHaveTextContent('Share your data')
+ })
+
+ it('should render PrivateAndSecure component', () => {
+ render()
+
+ expect(screen.getByText(/Private and secure/i)).toBeInTheDocument()
+ })
+ })
+
+ describe('Mode-specific rendering', () => {
+ it('should render AGG mode content when mode is AGG_MODE', () => {
+ const state = {
+ ...initialState,
+ config: {
+ ...initialState.config,
+ mode: AGG_MODE,
+ },
+ connect: {
+ ...initialState.connect,
+ selectedInstitution: mockInstitution,
+ },
+ }
+
+ const { container } = render(, {
+ preloadedState: state,
+ })
+
+ expect(container.textContent).toContain('manage your finances')
+ })
+
+ it('should render VERIFY mode content when mode is VERIFY_MODE', () => {
+ const state = {
+ ...initialState,
+ config: {
+ ...initialState.config,
+ mode: VERIFY_MODE,
+ },
+ connect: {
+ ...initialState.connect,
+ selectedInstitution: mockInstitution,
+ },
+ }
+
+ const { container } = render(, {
+ preloadedState: state,
+ })
+
+ expect(container.textContent).toContain('move money')
+ })
+
+ it('should render combined mode content when both AGG and VERIFY', () => {
+ const state = {
+ ...initialState,
+ config: {
+ ...initialState.config,
+ mode: AGG_MODE,
+ data_request: {
+ products: ['transactions', 'identity_verification'],
+ },
+ },
+ connect: {
+ ...initialState.connect,
+ selectedInstitution: mockInstitution,
+ },
+ }
+
+ const { container } = render(, {
+ preloadedState: state,
+ })
+
+ expect(container.textContent).toContain('move money and manage your finances')
+ })
+
+ it('should render AGG mode when include_transactions is true', () => {
+ const state = {
+ ...initialState,
+ config: {
+ ...initialState.config,
+ include_transactions: true,
+ },
+ connect: {
+ ...initialState.connect,
+ selectedInstitution: mockInstitution,
+ },
+ }
+
+ const { container } = render(, {
+ preloadedState: state,
+ })
+
+ expect(container.textContent).toContain('manage your finances')
+ })
+ })
+
+ describe('Modal interaction', () => {
+ it('loads the consent screen and clicks the info button to open modal', async () => {
+ const ref = React.createRef()
+ const { user } = render()
+
+ await user.click(await screen.findByTestId('info-button'))
+
+ expect(await screen.findByText('Who is MX Technologies?')).toBeInTheDocument()
+ })
+
+ it('should toggle modal when info button is clicked multiple times', async () => {
+ const { user } = render()
+
+ const infoButton = screen.getByTestId('info-button')
+ await user.click(infoButton)
+ expect(screen.getByText('Who is MX Technologies?')).toBeInTheDocument()
+
+ const closeButton = screen.getByText('Close')
+ await user.click(closeButton)
+ expect(screen.queryByText('Who is MX Technologies?')).not.toBeInTheDocument()
+ })
+ })
+
+ describe('Consent button', () => {
+ it('should have consent button disabled initially when not scrolled to bottom', () => {
+ Object.defineProperty(document.documentElement, 'scrollHeight', {
+ writable: true,
+ configurable: true,
+ value: 2000,
+ })
+ Object.defineProperty(document.documentElement, 'scrollTop', {
+ writable: true,
+ configurable: true,
+ value: 0,
+ })
+ Object.defineProperty(document.documentElement, 'clientHeight', {
+ writable: true,
+ configurable: true,
+ value: 800,
+ })
+
+ render()
+
+ const consentButton = screen.getByTestId('consent-button')
+ expect(consentButton).toBeDisabled()
+ })
+
+ it('should enable consent button when scrolled to bottom', async () => {
+ Object.defineProperty(document.documentElement, 'scrollHeight', {
+ writable: true,
+ configurable: true,
+ value: 1000,
+ })
+ Object.defineProperty(document.documentElement, 'scrollTop', {
+ writable: true,
+ configurable: true,
+ value: 200,
+ })
+ Object.defineProperty(document.documentElement, 'clientHeight', {
+ writable: true,
+ configurable: true,
+ value: 800,
+ })
+
+ render()
+
+ window.dispatchEvent(new Event('scroll'))
+ const consentButton = await screen.findByTestId('consent-button')
+ expect(consentButton).not.toBeDisabled()
+ })
+
+ it('should dispatch USER_CONSENTED action when consent button is clicked', async () => {
+ Object.defineProperty(document.documentElement, 'scrollHeight', {
+ writable: true,
+ configurable: true,
+ value: 1000,
+ })
+ Object.defineProperty(document.documentElement, 'scrollTop', {
+ writable: true,
+ configurable: true,
+ value: 200,
+ })
+ Object.defineProperty(document.documentElement, 'clientHeight', {
+ writable: true,
+ configurable: true,
+ value: 800,
+ })
+
+ const { user } = render()
+
+ window.dispatchEvent(new Event('scroll'))
+
+ await waitFor(() => {
+ const consentButton = screen.getByTestId('consent-button')
+ expect(consentButton).not.toBeDisabled()
+ })
+
+ const consentButton = screen.getByTestId('consent-button')
+ await user.click(consentButton)
+
+ expect(dispatch).toHaveBeenCalledWith({ type: ActionTypes.USER_CONSENTED })
+ })
+ })
+
+ describe('Translation toggle', () => {
+ it('should show translation link for Spanish locale', () => {
+ window.app = { options: { language: 'es' } }
+ vi.spyOn(Intl, 'getLocale').mockReturnValue('es')
+
+ render()
+
+ expect(screen.getByTestId('translation-button')).toBeInTheDocument()
+ })
+
+ it('should show translation link for French-Canadian locale', () => {
+ window.app = { options: { language: 'fr-ca' } }
+ vi.spyOn(Intl, 'getLocale').mockReturnValue('fr-ca')
+
+ render()
+
+ expect(screen.getByTestId('translation-button')).toBeInTheDocument()
+ })
+
+ it('should not show translation link for English locale', () => {
+ window.app = { options: { language: 'en-us' } }
+ vi.spyOn(Intl, 'getLocale').mockReturnValue('en')
+
+ render()
+
+ expect(screen.queryByTestId('translation-button')).not.toBeInTheDocument()
+ })
+
+ it('should toggle locale when translation link is clicked', async () => {
+ window.app = { options: { language: 'es' } }
+ const setLocaleSpy = vi.spyOn(Intl, 'setLocale')
+ vi.spyOn(Intl, 'getLocale').mockReturnValue('es')
+
+ const { user } = render()
+
+ const translationButton = screen.getByTestId('translation-button')
+ await user.click(translationButton)
+
+ expect(setLocaleSpy).toHaveBeenCalledWith('en')
+ })
+ })
+
+ describe('Imperative handle', () => {
+ it('should call fadeOut and onGoBackClick when handleBackButton is called', async () => {
+ const ref = React.createRef<{ handleBackButton: () => void }>()
+ render()
+
+ ref.current?.handleBackButton()
+
+ await waitFor(() => {
+ expect(Animation.fadeOut).toHaveBeenCalled()
+ expect(onGoBackClick).toHaveBeenCalled()
+ })
+ })
+
+ it('should return true for showBackButton when institution search is not disabled', () => {
+ const state = {
+ ...initialState,
+ config: {
+ ...initialState.config,
+ disable_institution_search: false,
+ },
+ }
+
+ const ref = React.createRef<{ showBackButton: () => boolean }>()
+ render(, { preloadedState: state })
+
+ expect(ref.current?.showBackButton()).toBe(true)
+ })
+
+ it('should return false for showBackButton when institution search is disabled', () => {
+ const state = {
+ ...initialState,
+ config: {
+ ...initialState.config,
+ disable_institution_search: true,
+ },
+ }
+
+ const ref = React.createRef<{ showBackButton: () => boolean }>()
+ render(, { preloadedState: state })
+
+ expect(ref.current?.showBackButton()).toBe(false)
+ })
+
+ it('should restore locale when handleBackButton is called with non-English initial locale', async () => {
+ window.app = { options: { language: 'es' } }
+ const setLocaleSpy = vi.spyOn(Intl, 'setLocale')
+ vi.spyOn(Intl, 'getLocale').mockReturnValue('en')
+
+ const ref = React.createRef<{ handleBackButton: () => void }>()
+ render()
+
+ ref.current?.handleBackButton()
+
+ await waitFor(() => {
+ expect(setLocaleSpy).toHaveBeenCalledWith('es')
+ })
+ })
+
+ it('should restore locale when consent button is clicked with non-English initial locale', async () => {
+ window.app = { options: { language: 'es' } }
+ const setLocaleSpy = vi.spyOn(Intl, 'setLocale')
+ vi.spyOn(Intl, 'getLocale').mockReturnValue('en')
+
+ Object.defineProperty(document.documentElement, 'scrollHeight', {
+ writable: true,
+ configurable: true,
+ value: 1000,
+ })
+ Object.defineProperty(document.documentElement, 'scrollTop', {
+ writable: true,
+ configurable: true,
+ value: 200,
+ })
+ Object.defineProperty(document.documentElement, 'clientHeight', {
+ writable: true,
+ configurable: true,
+ value: 800,
+ })
+
+ const { user } = render()
+
+ window.dispatchEvent(new Event('scroll'))
+
+ await waitFor(() => {
+ const consentButton = screen.getByTestId('consent-button')
+ expect(consentButton).not.toBeDisabled()
+ })
+
+ const consentButton = screen.getByTestId('consent-button')
+ await user.click(consentButton)
+
+ expect(setLocaleSpy).toHaveBeenCalledWith('es')
+ })
+ })
+
+ describe('Cleanup', () => {
+ it('should remove scroll event listener on unmount', () => {
+ const removeEventListenerSpy = vi.spyOn(window, 'removeEventListener')
+
+ const { unmount } = render()
+
+ unmount()
+
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function))
+ })
+ })
+})
diff --git a/src/views/consent/__tests__/DynamicDisclosure-test.tsx b/src/views/consent/__tests__/DynamicDisclosure-test.tsx
deleted file mode 100644
index 5ecba50faa..0000000000
--- a/src/views/consent/__tests__/DynamicDisclosure-test.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react'
-
-import { screen, render } from 'src/utilities/testingLibrary'
-
-import { DynamicDisclosure } from 'src/views/consent/DynamicDisclosure'
-
-const onConsentClick = vi.fn()
-const onGoBackClick = vi.fn()
-
-const dynamicDisclosureProps = {
- onConsentClick,
- onGoBackClick,
-}
-
-describe('dynamic disclosure', () => {
- it('loads the consent screen', async () => {
- const ref = React.createRef()
- render()
-
- expect(await screen.findByTestId('dynamic-disclosure-title')).toBeInTheDocument()
- expect(await screen.findByTestId('dynamic-disclosure-p1')).toBeInTheDocument()
- expect(await screen.findByText('I consent')).toBeInTheDocument()
- expect(await screen.findByText('Account Information')).toBeInTheDocument()
- const buttons = screen.getAllByRole('button')
- expect(buttons).toHaveLength(5)
- })
-
- it('loads the consent screen and clicks the info button to open modal', async () => {
- const ref = React.createRef()
- const { user } = render()
-
- await user.click(await screen.findByTestId('info-button'))
-
- expect(await screen.findByText('Who is MX Technologies?')).toBeInTheDocument()
- })
-})