Skip to content

Commit

Permalink
added tests for EditableRichTextComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
shubham43MP committed Aug 9, 2024
1 parent 2a540a2 commit cd183be
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 33 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default {
moduleNameMapper: {
"\\.(css|less|sass|scss)$": "identity-obj-proxy",
"^.+\\.svg$": "jest-transformer-svg",
"^@/(.*)$": "<rootDir>/src/$1",
},

setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"ts-jest": "^29.2.4",
"ts-node": "^10.9.2",
"typescript": "^5.2.2",
"vite": "^5.4.0"
"vite": "^5.4.0",
"vite-tsconfig-paths": "^5.0.0"
},
"engines": {
"npm": ">=8.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/assets/Icons/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const EditIcon = ({ customClass = 'h-6 w-6' }: SVGTSXIconProps) => {
width="12"
height="12"
viewBox="0 0 12 12"
className={`fill-black-700 ${customClass}`}
className={`edit-icon-class fill-black-700 ${customClass}`}
>
<path d="M1.333 10.667h.95L8.8 4.15l-.95-.95-6.517 6.517v.95zM.667 12a.645.645 0 01-.475-.192.645.645 0 01-.192-.475V9.717a1.316 1.316 0 01.383-.934L8.8.383c.133-.122.28-.216.442-.283a1.38 1.38 0 011.025 0c.166.067.31.167.433.3l.917.933c.133.123.23.267.291.434a1.444 1.444 0 010 1.008 1.25 1.25 0 01-.291.442l-8.4 8.4a1.316 1.316 0 01-.933.383H.666zm7.65-8.317L7.85 3.2l.95.95-.483-.467z"></path>
</svg>
Expand Down
2 changes: 1 addition & 1 deletion src/assets/Icons/portfolio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const PortfolioIcon = ({ customClass = 'h-6 w-6' }: SVGTSXIconProps) => {
width="18"
height="18"
viewBox="0 0 18 18"
className={`fill-black-700 ${customClass}`}
className={`portfolio-icon-class fill-black-700 ${customClass}`}
>
<path d="M2 8C1.45 8 .98 7.804.587 7.412A1.926 1.926 0 010 6V2C0 1.45.196.98.588.587A1.926 1.926 0 012 0h4c.55 0 1.02.196 1.412.588C7.804.979 8 1.45 8 2v4c0 .55-.196 1.02-.588 1.412A1.926 1.926 0 016 8H2zm0 10c-.55 0-1.02-.196-1.413-.587A1.926 1.926 0 010 16v-4c0-.55.196-1.02.588-1.412A1.926 1.926 0 012 10h4c.55 0 1.02.196 1.412.588.392.391.588.862.588 1.412v4c0 .55-.196 1.02-.588 1.413A1.926 1.926 0 016 18H2zM12 8c-.55 0-1.02-.196-1.412-.588A1.926 1.926 0 0110 6V2c0-.55.196-1.02.588-1.413A1.926 1.926 0 0112 0h4c.55 0 1.02.196 1.413.588C17.803.979 18 1.45 18 2v4c0 .55-.196 1.02-.587 1.412A1.926 1.926 0 0116 8h-4zm0 10c-.55 0-1.02-.196-1.412-.587A1.926 1.926 0 0110 16v-4c0-.55.196-1.02.588-1.412A1.926 1.926 0 0112 10h4c.55 0 1.02.196 1.413.588.391.391.587.862.587 1.412v4c0 .55-.196 1.02-.587 1.413A1.926 1.926 0 0116 18h-4zM2 6h4V2H2v4zm10 0h4V2h-4v4zm0 10h4v-4h-4v4zM2 16h4v-4H2v4z"></path>
</svg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const EditableRichTextComp = memo(
<ReactQuill
theme="snow"
value={richText}
onChange={value => debounced(value)}
onChange={(value: string) => debounced(value)}
className="h-full w-full"
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { render, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { EditableRichTextComp } from './EditableRichTextComp';

jest.mock('usehooks-ts', () => ({
...jest.requireActual('usehooks-ts'),
useToggle: (preview: boolean) => [preview, jest.fn()],
useDebounceCallback: jest.fn()
}));

jest.mock('react-quill', () => (props: any) => (
<textarea
data-testid="react-quill"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
));

describe('EditableRichTextComp', () => {
const mockRichTextChangeHandler = jest.fn();
const identifier = 'test-identifier';
const flag = 'test-flag' as any; // replace with the actual type of flag if necessary

beforeEach(() => {
jest.clearAllMocks();
});

it('renders in preview mode by default', () => {
const { getByText, queryByTestId } = render(
<>
<EditableRichTextComp
preview
richText="<p>Test Rich Text</p>"
richTextChangeHandler={mockRichTextChangeHandler}
identifier={identifier}
flag={flag}
/>
</>
);

expect(getByText('Test Rich Text')).toBeInTheDocument();
expect(queryByTestId('react-quill')).toBeNull();
});

it('toggles to edit mode and back to preview mode', async () => {
const { getByText, getByRole, getByTestId } = render(
<EditableRichTextComp
preview={false}
richText="<p>Test Rich Text</p>"
richTextChangeHandler={mockRichTextChangeHandler}
identifier={identifier}
flag={flag}
/>
);

fireEvent.click(getByRole('button'));

await waitFor(() => {
expect(getByTestId('react-quill')).toBeInTheDocument();
});

fireEvent.click(getByRole('button'));

await waitFor(() => {
expect(getByText('<p>Test Rich Text</p>')).toBeInTheDocument();
});
});

it('calls richTextChangeHandler with debouncing', async () => {
const debounceMock = jest.requireMock('usehooks-ts').useDebounceCallback;
let debouncedFn: (value: string) => void;
debounceMock.mockImplementation(
(fn: (value: string) => void, delay: any) => {
console.log({ delay });
debouncedFn = fn;
return fn;
}
);

const { getByTestId } = render(
<EditableRichTextComp
preview={false}
richText="<p>Test Rich Text</p>"
richTextChangeHandler={mockRichTextChangeHandler}
identifier={identifier}
flag={flag}
/>
);

const quillElement = getByTestId('react-quill');

fireEvent.change(quillElement, {
target: { value: '<p>Updated Text</p>' }
});

await waitFor(() => {
debouncedFn('<p>Updated Text</p>');
expect(mockRichTextChangeHandler).toHaveBeenCalledWith(
'<p>Updated Text</p>',
identifier,
flag
);
});
});

it('renders with EditIcon when in preview mode', () => {
const { getByRole } = render(
<EditableRichTextComp
preview
richText="<p>Test Rich Text</p>"
richTextChangeHandler={mockRichTextChangeHandler}
identifier={identifier}
flag={flag}
/>
);

const button = getByRole('button');
expect(button.firstChild).toHaveClass('edit-icon-class'); // replace with the actual class of EditIcon
});

it('renders with PortfolioIcon when in edit mode', () => {
const { getByRole } = render(
<EditableRichTextComp
preview={false}
richText="<p>Test Rich Text</p>"
richTextChangeHandler={mockRichTextChangeHandler}
identifier={identifier}
flag={flag}
/>
);

const button = getByRole('button');
expect(button.firstChild).toHaveClass('portfolio-icon-class'); // replace with the actual class of PortfolioIcon
});
});
2 changes: 2 additions & 0 deletions tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"paths": {
"@/*": ["./src/*"],
},
Expand Down
3 changes: 2 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tsconfigPaths from "vite-tsconfig-paths";
import * as path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [react(), tsconfigPaths()],
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, 'src') },
Expand Down
50 changes: 22 additions & 28 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2439,6 +2439,11 @@ globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"

globrex@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==

gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
Expand Down Expand Up @@ -4060,16 +4065,7 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"

"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -4087,14 +4083,7 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -4308,6 +4297,11 @@ ts-node@^10.9.2:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"

tsconfck@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.1.tgz#c7284913262c293b43b905b8b034f524de4a3162"
integrity sha512-00eoI6WY57SvZEVjm13stEVE90VkEdJAFGgpFLTsZbJyW/LwFQ7uQxJHWpZ2hzSWgCPKc9AnBnNP+0X7o3hAmQ==

type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
Expand Down Expand Up @@ -4404,6 +4398,15 @@ v8-to-istanbul@^9.0.1:
"@types/istanbul-lib-coverage" "^2.0.1"
convert-source-map "^2.0.0"

vite-tsconfig-paths@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-5.0.0.tgz#67c0a013279a8e7136e3c11184c37b0eac4a7dc5"
integrity sha512-sCdKc6uC7ir102lW8deBiMnS0NGEs0100OJX8WZQmf3Uf7tJ/T3uQnzznq/tZWph7tkG+44JYOsKE7YTZjDn+Q==
dependencies:
debug "^4.1.1"
globrex "^0.1.2"
tsconfck "^3.0.3"

vite@^5.4.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.0.tgz#11dca8a961369ba8b5cae42d068c7ad684d5370f"
Expand Down Expand Up @@ -4466,16 +4469,7 @@ word-wrap@^1.2.5:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand Down

0 comments on commit cd183be

Please sign in to comment.