diff --git a/README.md b/README.md index d088440..203736a 100644 --- a/README.md +++ b/README.md @@ -29,4 +29,3 @@ This project follows [these instructions](https://cronos-hq.notion.site/Front-En ## TODO - Error handling -- Testing diff --git a/src/components/__tests__/PricingCard.tsx b/src/components/__tests__/PricingCard.tsx new file mode 100644 index 0000000..d527ce5 --- /dev/null +++ b/src/components/__tests__/PricingCard.tsx @@ -0,0 +1,54 @@ +import { screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import PricingCard from 'components/PricingCard/PricingCard' +import renderWithProviders from 'testUtils' +import { beforeAll } from 'vitest' + +describe('', () => { + beforeAll(() => { + window.HTMLElement.prototype.setPointerCapture = vi.fn() + window.HTMLElement.prototype.hasPointerCapture = vi.fn() + }) + + it('should render', async () => { + renderWithProviders() + + expect(screen.getByText('100K PAGEVIEWS')).toBeInTheDocument() + expect(screen.getByText('$16.00')).toBeInTheDocument() + expect(await screen.findByText('or ~160 CRO')).toBeInTheDocument() + }) + + it('should apply a 25% discount on prices when the switch is on', async () => { + renderWithProviders() + + const billingSwitch = screen.getByRole('switch') + await userEvent.click(billingSwitch) + + expect(screen.getByText('$12.00')).toBeInTheDocument() + expect(await screen.findByText('or ~120 CRO')).toBeInTheDocument() + }) + + it('should increase pageviews and prices when the right arrow key is pressed', async () => { + renderWithProviders() + + const [slider] = screen.getAllByRole('slider') + await userEvent.type(slider, '{arrowright}') + + expect(screen.getByText('500K PAGEVIEWS')).toBeInTheDocument() + expect(screen.getByText('$24.00')).toBeInTheDocument() + expect(await screen.findByText('or ~240 CRO')).toBeInTheDocument() + }) + + it('should decrease pageviews and apply a 25% discount on prices when the switch is on and the left arrow key is pressed', async () => { + renderWithProviders() + + const billingSwitch = screen.getByRole('switch') + await userEvent.click(billingSwitch) + const [slider] = screen.getAllByRole('slider') + await userEvent.type(slider, '{arrowleft}') + + expect(screen.getByText('50K PAGEVIEWS')).toBeInTheDocument() + expect(screen.getByText('$9.00')).toBeInTheDocument() + expect(await screen.findByText('or ~90 CRO')).toBeInTheDocument() + }) +}) diff --git a/src/components/__tests__/PricingCardSlider.tsx b/src/components/__tests__/PricingCardSlider.tsx new file mode 100644 index 0000000..e0b9d81 --- /dev/null +++ b/src/components/__tests__/PricingCardSlider.tsx @@ -0,0 +1,42 @@ +import { screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import PricingCardSlider from 'components/PricingCard/PricingCardSlider' +import renderWithProviders from 'testUtils' +import { beforeAll } from 'vitest' + +describe('', () => { + beforeAll(() => { + window.HTMLElement.prototype.setPointerCapture = vi.fn() + window.HTMLElement.prototype.hasPointerCapture = vi.fn() + }) + + it('should render', async () => { + renderWithProviders() + + expect(screen.getByRole('slider')).toBeInTheDocument() + }) + + it('should increase the value when the right arrow key is pressed', async () => { + renderWithProviders() + + const slider = screen.getByRole('slider') + + expect(slider.getAttribute('aria-valuenow')).toBe('2') + + await userEvent.type(slider, '{arrowright}') + + expect(slider.getAttribute('aria-valuenow')).toBe('3') + }) + + it('should decrease the value when the left arrow key is pressed', async () => { + renderWithProviders() + + const slider = screen.getByRole('slider') + + expect(slider.getAttribute('aria-valuenow')).toBe('2') + + await userEvent.type(slider, '{arrowleft}') + + expect(slider.getAttribute('aria-valuenow')).toBe('1') + }) +}) diff --git a/src/components/__tests__/PricingCardSwitch.tsx b/src/components/__tests__/PricingCardSwitch.tsx new file mode 100644 index 0000000..f426cbb --- /dev/null +++ b/src/components/__tests__/PricingCardSwitch.tsx @@ -0,0 +1,31 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import PricingCardSwitch from 'components/PricingCard/PricingCardSwitch' +import { expect } from 'vitest' + +describe('', () => { + it('should render', async () => { + render() + + expect(screen.getByText('Monthly Billing')).toBeInTheDocument() + expect(screen.getByText('Yearly Billing')).toBeInTheDocument() + expect(screen.getByText('25% discount')).toBeInTheDocument() + expect(screen.getByRole('switch')).toBeInTheDocument() + }) + + it('should toggle the value when clicking on switch', async () => { + render() + + const billingSwitch = screen.getByRole('switch') + + expect(billingSwitch.dataset.state).toBe('unchecked') + + await userEvent.click(billingSwitch) + + expect(billingSwitch.dataset.state).toBe('checked') + + await userEvent.click(billingSwitch) + + expect(billingSwitch.dataset.state).toBe('unchecked') + }) +}) diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index 5f50571..1a02e31 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -1,5 +1,9 @@ -import type { HttpHandler } from 'msw' +import { http, HttpResponse, type HttpHandler } from 'msw' -const handlers: HttpHandler[] = [] +const handlers: HttpHandler[] = [ + http.get('https://api.coingecko.com/api/v3/simple/price', () => + HttpResponse.json({ 'crypto-com-chain': { usd: 0.1 } }) + ) +] export default handlers diff --git a/src/setupTests.ts b/src/setupTests.ts index 616a22f..1d3f6d4 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -4,6 +4,12 @@ import server from 'mocks/server' import { DESKTOP_RESOLUTION_HEIGHT, DESKTOP_RESOLUTION_WIDTH } from 'testUtils' import 'whatwg-fetch' +global.ResizeObserver = vi.fn().mockImplementation(() => ({ + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn() +})) + beforeAll(() => { server.listen({ onUnhandledRequest: 'error' }) diff --git a/src/testUtils.tsx b/src/testUtils.tsx index d3b867c..c9eac3a 100644 --- a/src/testUtils.tsx +++ b/src/testUtils.tsx @@ -1,5 +1,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render } from '@testing-library/react' +import { Provider as JotaiProvider } from 'jotai' import type { PropsWithChildren, ReactElement } from 'react' import { BrowserRouter } from 'react-router-dom' @@ -18,15 +19,14 @@ export const DESKTOP_RESOLUTION_HEIGHT = 800 export const MOBILE_RESOLUTION_WIDTH = 414 export const MOBILE_RESOLUTION_HEIGHT = 896 -export default function renderWithProviders( - ui: ReactElement, - includeRouter = true -): void { +export default function renderWithProviders(ui: ReactElement): void { render(ui, { wrapper: ({ children }: PropsWithChildren): ReactElement => ( - - {includeRouter ? {children} : children} - + + + {children} + + ) }) }