Repository: nodejs/nodejs.dev
Pull request #2850 (2022-10-03 00:41:32)

Test: Add unit tests for DarkModeToggle component
<!--
Please read the [Code of Conduct](https://github.com/nodejs/nodejs.dev/blob/main/CODE_OF_CONDUCT.md) and the [Contributing Guidelines](https://github.com/nodejs/nodejs.dev/blob/main/CONTRIBUTING.md) before opening a pull request.
-->

## Description

I have added unit tests for DarkModeToggle component.

<!-- Write a brief description of the changes introduced by this PR -->

## Related Issues

Related to the issue https://github.com/nodejs/nodejs.dev/issues/2744

<!--
  Link to the issue that is fixed by this PR (if there is one)
  e.g. Fixes #1234, Addresses #1234, Related to #1234, etc.
-->

### Check List

<!--
ATTENTION
Please follow this check list to ensure that you've followed all items before opening this PR
-->

- [x] I have read the [Contributing Guidelines](https://github.com/nodejs/nodejs.dev/blob/main/CONTRIBUTING.md) and made commit messages that follow the guideline.
- [x] I have run `npm run lint:js -- --fix` and/or `npm run lint:md -- --fix` for my JavaScript and/or Markdown changes.
  - This is important as most of the cases your code changes might not be correctly linted
- [x] I have run `npm run test` to check if all tests are passing, and/or `npm run test -- -u` to update snapshots if I created and/or updated React Components.
- [x] I have checked that the build works locally and that `npm run build` work fine.
- [x] I've covered new added functionality with unit tests if necessary.


codecov-commenter: # [Codecov](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
Base: **66.02**% // Head: **63.68**% // Decreases project coverage by **`-2.33%`** :warning:
> Coverage data is based on head [(`b26b6e0`)](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) compared to base [(`fd57b87`)](https://codecov.io/gh/nodejs/nodejs.dev/commit/fd57b871c2b1ad2f6fb812ed066dec074d76db22?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> Patch has no changes to coverable lines.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #2850      +/-   ##
==========================================
- Coverage   66.02%   63.68%   -2.34%     
==========================================
  Files         118      124       +6     
  Lines        1351     1465     +114     
  Branches      342      366      +24     
==========================================
+ Hits          892      933      +41     
- Misses        422      492      +70     
- Partials       37       40       +3     
```


| [Impacted Files](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [src/\_\_fixtures\_\_/hooks.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL19fZml4dHVyZXNfXy9ob29rcy50c3g=) | `100.00% <ø> (ø)` | |
| [src/\_\_fixtures\_\_/page.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL19fZml4dHVyZXNfXy9wYWdlLnRzeA==) | `94.11% <ø> (-5.89%)` | :arrow_down: |
| [...components/ApiComponents/Components/ApiHeading.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL0FwaUhlYWRpbmcudHN4) | `0.00% <ø> (ø)` | |
| [...rc/components/ApiComponents/Components/ApiLink.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL0FwaUxpbmsudHN4) | `0.00% <ø> (ø)` | |
| [...ents/ApiComponents/Components/SourceLink/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL1NvdXJjZUxpbmsvaW5kZXgudHN4) | `0.00% <ø> (ø)` | |
| [...ApiComponents/Components/VersionSelector/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL1ZlcnNpb25TZWxlY3Rvci9pbmRleC50c3g=) | `0.00% <ø> (ø)` | |
| [src/components/ApiComponents/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9pbmRleC50c3g=) | `0.00% <ø> (ø)` | |
| [src/components/Article/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXJ0aWNsZS9pbmRleC50c3g=) | `100.00% <ø> (ø)` | |
| [src/components/Banner/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQmFubmVyL2luZGV4LnRzeA==) | `100.00% <ø> (ø)` | |
| [src/components/Codebox/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQ29kZWJveC9pbmRleC50c3g=) | `100.00% <ø> (ø)` | |
| ... and [78 more](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/nodejs/nodejs.dev/pull/2850?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

ovflowd: Agreed with @benhalverson here 👀 just testing that the component renders isn't enough.
vickymhs: Thanks @ovflowd and @benhalverson for the feedback. I tried figuring out the changing of the sun and moon icon and I observed that on-click of the toggle button, the html color-schema itself changes from dark to light (and vice versa).  This is also responsible for changing the background color.

Because of this, body changes the context of the class between `<body class = 'light'>` and `<body class = 'dark'>`. This inturn triggers the base.scss to read the corresponding class elements (dark-mode-only, light-mode-only) to set the display of each of them as none.

This is my first time with React and Typescript and I am trying to find out how to read the css property of the body element that causes this. It would be really helpful if you could point me on approach this.

Apologies for the inconvenience as I am just trying to learn.

<img width="1434" alt="image" src="https://user-images.githubusercontent.com/43530800/193738965-46a1a757-ae76-4695-9a24-816acd18ca09.png">



ovflowd: Hey there, no need to apologize! Really good findings and you're correct.

What I would do here is probably try to use jest mocks to mock the package that actually does the changes. You'll notice the button triggers a call from a package for dark theming. I'm not sure if we already mocked that package, but if not, you should probably place the package mock on src/__mocks__ or whatever the mock folder is.

My advice is to mock the functionality of the package with jest functions and see if somehow you can validate the value change and that the trigger actually happens.

We don't really need to test that the CSS changed as this is done by the package, not us.

Patch:
diff --git a/firebase.json b/firebase.json
index 6352e9b7..45821c79 100644
--- a/firebase.json
+++ b/firebase.json
@@ -472,4 +472,4 @@
       "type": "301"
     }
   ]
-}
\ No newline at end of file
+}


Test patch:
diff --git a/src/components/DarkModeToggle/__tests__/__snapshots__/index.test.tsx.snap b/src/components/DarkModeToggle/__tests__/__snapshots__/index.test.tsx.snap
new file mode 100644
index 00000000..f84e815a
--- /dev/null
+++ b/src/components/DarkModeToggle/__tests__/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,38 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DarkModeToggle Component render dark mode toggle 1`] = `
+<div>
+  <button
+    class="darkModeToggle"
+    type="button"
+  >
+    <span
+      class="sr-only"
+    >
+      Toggle Dark Mode
+    </span>
+    <svg
+      aria-hidden="true"
+      class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium light-mode-only css-i4bv87-MuiSvgIcon-root"
+      data-testid="ModeNightIcon"
+      focusable="false"
+      viewBox="0 0 24 24"
+    >
+      <path
+        d="M9.5 2c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65c1.47.85 3.18 1.35 5 1.35 5.52 0 10-4.48 10-10S15.02 2 9.5 2z"
+      />
+    </svg>
+    <svg
+      aria-hidden="true"
+      class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium dark-mode-only css-i4bv87-MuiSvgIcon-root"
+      data-testid="BrightnessMediumIcon"
+      focusable="false"
+      viewBox="0 0 24 24"
+    >
+      <path
+        d="M20 15.31 23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18V6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"
+      />
+    </svg>
+  </button>
+</div>
+`;
diff --git a/src/components/DarkModeToggle/__tests__/index.test.tsx b/src/components/DarkModeToggle/__tests__/index.test.tsx
new file mode 100644
index 00000000..d2517fb3
--- /dev/null
+++ b/src/components/DarkModeToggle/__tests__/index.test.tsx
@@ -0,0 +1,38 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import DarkModeToggle from '../index';
+
+let mockCurrentTheme = '';
+const mockToggleTheme = jest.fn().mockImplementation((newTheme: string) => {
+  mockCurrentTheme = newTheme;
+});
+
+// mock dark mode module for controlling dark mode HOC behavior
+jest.mock('@skagami/gatsby-plugin-dark-mode', () => ({
+  __esModule: true,
+  useTheme: () => [mockCurrentTheme, mockToggleTheme],
+}));
+
+describe('DarkModeToggle Component', () => {
+  it('render dark mode toggle', () => {
+    const { container } = render(<DarkModeToggle />);
+    expect(container).toMatchSnapshot();
+  });
+
+  it('switches dark theme to light theme', async () => {
+    mockCurrentTheme = 'dark';
+    render(<DarkModeToggle />);
+    const toggle = await screen.findByText('Toggle Dark Mode');
+    await userEvent.click(toggle);
+    expect(mockCurrentTheme).toBe('light');
+  });
+
+  it('switches light theme to dark theme', async () => {
+    mockCurrentTheme = 'light';
+    render(<DarkModeToggle />);
+    const toggle = await screen.findByText('Toggle Dark Mode');
+    await userEvent.click(toggle);
+    expect(mockCurrentTheme).toBe('dark');
+  });
+});