Skip to content

Commit

Permalink
Merge pull request #187 from kabisa/test/migrate-to-rtl
Browse files Browse the repository at this point in the history
Test/migrate to rtl
  • Loading branch information
matthijsgroen authored May 27, 2024
2 parents 2c31480 + d6be692 commit a6ca9f4
Show file tree
Hide file tree
Showing 67 changed files with 1,625 additions and 2,541 deletions.
15 changes: 13 additions & 2 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
version: "2" # required to adjust maintainability checks
version: "2" # required to adjust maintainability checks
checks:
method-lines:
config:
threshold: 80
plugins:
eslint:
enabled: true
channel: "eslint-7"
config:
extensions:
- .js
- .jsx
- .ts
- .tsx
exclude_patterns:
- "spec/"
- "!spec/support/helpers"
Expand All @@ -15,4 +25,5 @@ exclude_patterns:
- "**/*.d.ts"
- "**/*.spec.tsx"
- "**/spec_helper.tsx"
- "**/PullToRefresh.js"
- "**/*.stories.tsx"
- "**/PullToRefresh.js"
14 changes: 8 additions & 6 deletions .eslintrc.json → .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@
"prettier"
],
"rules": {
"react/jsx-props-no-spreading": 0,
"import/no-cycle": 0,
"react/destructuring-assignment": 0,
"import/prefer-default-export": 0,
"react/jsx-props-no-spreading": "off",
"import/no-cycle": "off",
"require-await": "error",
"react/destructuring-assignment": "off",
"import/prefer-default-export": "off",
"max-len": ["error", { "code": 120 }],
"react/button-has-type": 0,
"react/button-has-type": "off",
"react/react-in-jsx-scope": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": 1
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unused-vars": "warn"
},
"ignorePatterns": ["jest.config.js", ".storybook/*", "src/**/*.stories.tsx"],
"settings": {
Expand Down
Binary file modified .yarn/install-state.gz
Binary file not shown.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.3.0]

### Changed

- Replaced Enzyme with React testing library
- Added confirm steps on remove actions
- Show open lock icon for achieved goals

## [1.2.1]

### Fixed
Expand Down
12 changes: 4 additions & 8 deletions TECH_DEBT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@ Setting up graphql codegen will make it easier to work with graphql queries and

## Extract graphql queries from components

Move graphql queries from components to separate files. This will make it easier to work with graphql codegen and queries can be re-used.
Move graphql queries from components to separate files. This will make it easier to work with graphql codegen and queries can be re-used.

## Replace class components with functional components

In a lot of places class components are still being used. Replace these with functional components and use hooks for extracting logic. Also, in some of these class components, the state of child components is managed by the children themselves. This should be moved to the parent component, or to a context.

## Replace Enzyme tests with React Testing Library
## Upgrade to React 18

Enzyme is no longer maintained. Replace Enzyme tests with React Testing Library.

## Upgrade to React 18 after removing Enzyme

Upgrade the project to React 18 once enzyme is removed.
Upgrade the project to React 18.

## Implement UI components from ui folder

Currently UI components from @kabisa/ui-components are used. Replace these with the wrapper UI components from de ui folder. There might be functionality missing from these wrapper components. Implement this functionality.
Currently UI components from @kabisa/ui-components are used. Replace these with the wrapper UI components from de ui folder. There might be functionality missing from these wrapper components. Implement this functionality.
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^14.4.3",
"@types/enzyme": "^3.10.5",
"@types/jest": "^29.5.3",
"@types/node": "^13.9.0",
"@types/react": "^17.0.2",
Expand All @@ -82,9 +81,7 @@
"@types/uuid": "^9.0.5",
"@typescript-eslint/eslint-plugin": "^6.3.0",
"@typescript-eslint/parser": "^6.3.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"babel-plugin-named-exports-order": "^0.0.2",
"enzyme": "^3.11.0",
"eslint": "^7.1.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.18.2",
Expand Down
17 changes: 8 additions & 9 deletions src/components/AuthenticatedRoute.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { mount, ReactWrapper } from "enzyme";
import { findByTestId, withMockedProviders } from "../spec_helper";
import { withMockedProviders } from "../spec_helper";
import AuthenticatedRoute from "./AuthenticatedRoute";
import { Auth } from "../support";
import { render, screen } from "@testing-library/react";

jest.mock("../support/auth");

const fakeComponent = () => <h1>Fake component</h1>;

let wrapper: ReactWrapper;
const setup = (allowNoTeam: boolean) => {
wrapper = mount(
render(
withMockedProviders(
<AuthenticatedRoute
allowNoTeam={allowNoTeam}
Expand All @@ -18,6 +17,7 @@ const setup = (allowNoTeam: boolean) => {
),
);
};

describe("<AuthenticatedRoute />", () => {
afterEach(() => {
jest.clearAllMocks();
Expand All @@ -28,30 +28,29 @@ describe("<AuthenticatedRoute />", () => {
Auth.isLoggedIn = jest.fn(() => false);
setup(false);

expect(findByTestId(wrapper, "redirect").length).toBe(1);
expect(screen.getByText("Login Page")).toBeInTheDocument();
});

it("does not render the page if the user has no team and allowNoTeam is false", () => {
Auth.isLoggedIn = jest.fn(() => true);
Auth.hasTeam = jest.fn(() => false);
setup(false);

expect(findByTestId(wrapper, "redirect").length).toBe(1);
expect(screen.getByText("Choose team Page")).toBeInTheDocument();
});

it("does render the page if the user has no team and allowNoTeam is true", () => {
Auth.isLoggedIn = jest.fn(() => true);
Auth.hasTeam = jest.fn(() => false);
setup(true);

expect(findByTestId(wrapper, "component").length).toBe(1);
expect(screen.getByText("Fake component")).toBeInTheDocument();
});

it("does render the page if the user is logged in and has a team", () => {
Auth.isLoggedIn = jest.fn(() => true);
Auth.hasTeam = jest.fn(() => true);
setup(false);

expect(findByTestId(wrapper, "component").length).toBe(1);
expect(screen.getByText("Fake component")).toBeInTheDocument();
});
});
6 changes: 3 additions & 3 deletions src/components/AuthenticatedRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ export default function AuthenticatedRoute({
{...rest}
render={(props) => {
if (!Auth.isLoggedIn()) {
return <Redirect data-testid="redirect" to={PATH_LOGIN} />;
return <Redirect to={PATH_LOGIN} />;
}

if (Auth.hasTeam() || allowNoTeam) {
return <Component data-testid="component" {...props} />;
return <Component {...props} />;
}

return <Redirect data-testid="redirect" to={PATH_CHOOSE_TEAM} />;
return <Redirect to={PATH_CHOOSE_TEAM} />;
}}
/>
);
Expand Down
18 changes: 8 additions & 10 deletions src/components/Circle/Circle.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { mount, ReactWrapper } from "enzyme";
import { findByTestId, withMockedProviders } from "../../spec_helper";
import { withMockedProviders } from "../../spec_helper";
import CustomCircle from "./Circle";
import { render, screen } from "@testing-library/react";

describe("<CustomCircle />", () => {
let wrapper: ReactWrapper;

beforeEach(() => {
wrapper = mount(
render(
withMockedProviders(
<CustomCircle
percent={50}
Expand All @@ -19,14 +17,14 @@ describe("<CustomCircle />", () => {
});

it("renders the correct current kudo amount", () => {
const summary = findByTestId(wrapper, "current-kudos");
const summary = screen.getByRole("heading", { level: 2, name: "200 ₭" });

expect(summary.text()).toBe("200₭");
expect(summary).toBeInTheDocument();
});

it("renders the correct goal", () => {
const goal = findByTestId(wrapper, "goal-kudos");

expect(goal.text()).toBe("of 500₭ for Some goal");
const summary = screen.getByTestId("goal-kudos");
expect(summary.textContent).toEqual("of 500₭ for Some goal");
expect(summary).toBeInTheDocument();
});
});
18 changes: 18 additions & 0 deletions src/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ComponentProps } from "react";
import { Link as RouterLink } from "react-router-dom";
import styles from "@kabisa/ui-components/src/atoms/Link/index.module.css";

export type Props = ComponentProps<typeof RouterLink> & {
theme: "light" | "dark";
};

export const Link: React.FC<Props> = ({ theme, children, ...props }: Props) => {
return (
<RouterLink
{...props}
className={`${props.className} ${styles.link} ${styles[theme]}`}
>
{children}
</RouterLink>
);
};
2 changes: 1 addition & 1 deletion src/components/back-button/BackButton.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const MediaWrapper = ({
</ResponsiveContext.Provider>
);

test("backButton", async () => {
test("backButton", () => {
render(
<MediaWrapper screen="desktop">
<BackButton />
Expand Down
4 changes: 2 additions & 2 deletions src/components/navigation/Desktop.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe("<Desktop />", () => {
renderResult.rerender(withMockedProviders(<Desktop />, mocks()));
});

it("has a manage team button", async () => {
it("has a manage team button", () => {
const profileLink = screen.queryByTestId("manage-team-button");
expect(profileLink).not.toBeNull();
});
Expand All @@ -75,7 +75,7 @@ describe("<Desktop />", () => {
renderResult.rerender(withMockedProviders(<Desktop />, mocks()));
});

it("does not have a manage team button", async () => {
it("does not have a manage team button", () => {
const profileLink = screen.queryByTestId("manage-team-button");
expect(profileLink).toBeNull();
});
Expand Down
49 changes: 26 additions & 23 deletions src/components/navigation/Mobile.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { mount, ReactWrapper } from "enzyme";
import {
findByTestId,
mockLocalstorage,
withMockedProviders,
} from "../../spec_helper";
import { mockLocalstorage, withMockedProviders } from "../../spec_helper";
import Mobile from "./Mobile";
import { Auth } from "../../support";
import { RenderResult, render, screen } from "@testing-library/react";

let wrapper: ReactWrapper;
let result: RenderResult | null = null;
const setup = () => {
wrapper = mount(withMockedProviders(<Mobile />));
if (result) {
result.unmount();
}
result = render(withMockedProviders(<Mobile />));
};

describe("<Mobile />", () => {
Expand All @@ -19,32 +18,36 @@ describe("<Mobile />", () => {
setup();
});

it("should have a button to the settings page", () => {
expect(findByTestId(wrapper, "settings-button").length).toBe(1);
it("has a button to the settings page", () => {
expect(screen.getByRole("link", { name: "settings" })).toBeInTheDocument();
});

it("should have a button to the profile page", () => {
expect(findByTestId(wrapper, "profile-button").length).toBe(1);
it("has a button to the profile page", () => {
expect(screen.getByRole("link", { name: "person" })).toBeInTheDocument();
});

it("should have a button to the feed page if the user is logged in", () => {
expect(findByTestId(wrapper, "home-button").length).toBe(1);
it("has a button to the feed page if the user is logged in", () => {
expect(screen.getByRole("link", { name: "home" })).toBeInTheDocument();
});

it("should have a button to the statistics page if the user is logged in", () => {
expect(findByTestId(wrapper, "statistics-button").length).toBe(1);
it("has a button to the statistics page if the user is logged in", () => {
expect(
screen.getByRole("link", { name: "monitoring" }),
).toBeInTheDocument();
});

it("should have a button to the notifications page if the user is logged in", () => {
expect(findByTestId(wrapper, "notifications-button").length).toBe(1);
it("has a button to the notifications page if the user is logged in", () => {
expect(
screen.getByRole("link", { name: "notifications" }),
).toBeInTheDocument();
});

// eslint-disable-next-line max-len
it("should not have a button to the feed, statistics and notifications page if the user doesnt not have a team", () => {
it("has no buttons to the feed, statistics and notifications page if the user has no team", () => {
Auth.hasTeam = jest.fn(() => false);
setup();
expect(findByTestId(wrapper, "home-button").length).toBe(0);
expect(findByTestId(wrapper, "notifications-button").length).toBe(0);
expect(findByTestId(wrapper, "statistics-button").length).toBe(0);

expect(screen.queryByRole("link", { name: "monitoring" })).toBeNull();
expect(screen.queryByRole("link", { name: "notifications" })).toBeNull();
expect(screen.queryByRole("link", { name: "home" })).toBeNull();
});
});
Loading

0 comments on commit a6ca9f4

Please sign in to comment.