Skip to content

Commit

Permalink
Merge pull request #1036 from saithsab877/unit-tests
Browse files Browse the repository at this point in the history
[Unit Test]: `createSocketInstance` and `prepareForTesting` and  `MockParentComponent`
  • Loading branch information
elraphty authored Feb 6, 2025
2 parents 548f30b + 734e4f0 commit 943e1a7
Show file tree
Hide file tree
Showing 3 changed files with 297 additions and 1 deletion.
99 changes: 99 additions & 0 deletions src/hooks/__tests__/socket.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { waitFor } from '@testing-library/react';
import { createSocketInstance } from 'config/socket';
import { v4 as uuidv4 } from 'uuid';

jest.mock('uuid', () => ({
v4: jest.fn(() => 'mock-uuid')
}));

describe('createSocketInstance', () => {
let mockWebSocket: jest.Mock;
let mockLocalStorage: { [key: string]: string | null };

beforeEach(() => {
mockWebSocket = jest.fn(() => ({
onclose: null,
onerror: null,
OPEN: true
}));
global.WebSocket = mockWebSocket as any;

mockLocalStorage = {};
Storage.prototype.getItem = jest.fn((key: string) => mockLocalStorage[key] || null);
Storage.prototype.setItem = jest.fn((key: string, value: string) => {
mockLocalStorage[key] = value;
});

jest.resetModules();
});

test('Standard Socket Creation', () => {
mockLocalStorage['websocket_token'] = 'existing-token';
const socket = createSocketInstance();

expect(mockWebSocket).toHaveBeenCalledWith(expect.stringContaining('?uniqueId=existing-token'));
expect(socket).toBeDefined();
expect(socket.onclose).toBeDefined();
expect(socket.onerror).toBeDefined();
});

test('Reusing Existing Socket', () => {
const socket1 = createSocketInstance();
const firstCallCount = mockWebSocket.mock.calls.length;

const socket2 = createSocketInstance();

expect(socket1).toBe(socket2);
expect(mockWebSocket.mock.calls.length).toBe(firstCallCount);
});

test('Empty LocalStorage Token', () => {
mockLocalStorage['websocket_token'] = '';
createSocketInstance();

waitFor(() => {
expect(uuidv4).toHaveBeenCalled();
expect(mockWebSocket).toHaveBeenCalledWith(expect.stringContaining('?uniqueId=mock-uuid'));
expect(mockLocalStorage['websocket_token']).toBe('mock-uuid');
});
});

test('Null LocalStorage Token', () => {
mockLocalStorage['websocket_token'] = null;
createSocketInstance();

waitFor(() => {
expect(uuidv4).toHaveBeenCalled();
expect(mockWebSocket).toHaveBeenCalledWith(expect.stringContaining('?uniqueId=mock-uuid'));

expect(mockLocalStorage['websocket_token']).toBe('mock-uuid');
});
});

test('URL Construction Based on Environment', () => {
const originalEnv = process.env.NODE_ENV;

Object.defineProperty(process.env, 'NODE_ENV', {
value: 'production',
configurable: true
});
createSocketInstance();
waitFor(() => {
expect(mockWebSocket).toHaveBeenCalledWith(expect.stringContaining('wss://'));
});

Object.defineProperty(process.env, 'NODE_ENV', {
value: 'development',
configurable: true
});
createSocketInstance();
waitFor(() => {
expect(mockWebSocket).toHaveBeenCalledWith(expect.stringContaining('ws://'));
});

Object.defineProperty(process.env, 'NODE_ENV', {
value: originalEnv,
configurable: true
});
});
});
75 changes: 75 additions & 0 deletions src/hooks/__tests__/useInViewport.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { waitFor } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { useInViewPort } from 'hooks/useInViewport';
import { IntersectionOptions } from 'react-intersection-observer';
Expand Down Expand Up @@ -54,4 +55,78 @@ describe('useInViewport hook', () => {

expect(isVisible).toBe(true);
});

describe('prepareForTesting function', () => {
beforeEach(() => {
delete (window as Window).IntersectionObserver;
});

test('Test with isIntersecting as true', () => {
prepareForTesting(true);

const mockedObserver = (window as Window).IntersectionObserver as jest.Mock;
const mockCallback = jest.fn();

mockedObserver(mockCallback);
expect(mockCallback).toHaveBeenCalledWith([{ isIntersecting: true }]);
});

test('Test with isIntersecting as false', () => {
prepareForTesting(false);

const mockedObserver = (window as Window).IntersectionObserver as jest.Mock;
const mockCallback = jest.fn();

mockedObserver(mockCallback);
expect(mockCallback).toHaveBeenCalledWith([{ isIntersecting: false }]);
});

test('Test with multiple calls to prepareForTesting', () => {
prepareForTesting(true);
const firstObserver = (window as Window).IntersectionObserver;

prepareForTesting(false);
const secondObserver = (window as Window).IntersectionObserver;

expect(firstObserver).not.toBe(secondObserver);

const mockCallback = jest.fn();
(secondObserver as jest.Mock)(mockCallback);
expect(mockCallback).toHaveBeenCalledWith([{ isIntersecting: false }]);
});

test('Test with invalid input type', () => {
// @ts-expect-error - Testing with invalid input
prepareForTesting('not-a-boolean');

const mockedObserver = (window as Window).IntersectionObserver as jest.Mock;
const mockCallback = jest.fn();

mockedObserver(mockCallback);

waitFor(() => {
expect(mockCallback).toHaveBeenCalledWith([{ isIntersecting: true }]);
});
});

test('Test with null input', () => {
// @ts-expect-error - Testing with null input
prepareForTesting(null);

const mockedObserver = (window as Window).IntersectionObserver as jest.Mock;
const mockCallback = jest.fn();

mockedObserver(mockCallback);

waitFor(() => {
expect(mockCallback).toHaveBeenCalledWith([{ isIntersecting: false }]);
});

const instance = mockedObserver(mockCallback);
waitFor(() => {
expect(instance.observe).toBeDefined();
expect(instance.unobserve).toBeDefined();
});
});
});
});
124 changes: 123 additions & 1 deletion src/pages/tickets/__tests__/PostBountyModalTest.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render } from '@testing-library/react';
import { render, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import Input from '../../../components/form/inputs';
import { Props } from '../../../components/form/inputs/propsType.ts';
Expand Down Expand Up @@ -61,3 +61,125 @@ test("Clicking on 'Deliverables' placeholder should not focus on NumberInputNew"

expect(document.activeElement).toBeInTheDocument();
});

describe('MockParentComponent', () => {
test('renders without crashing', () => {
const { container } = render(<MockParentComponent />);
expect(container).toBeInTheDocument();
});

test('renders TextArea Input with correct props', () => {
const { getByTestId } = render(<MockParentComponent />);
waitFor(() => {
const textArea = getByTestId('deliverables-textarea');

expect(textArea).toBeInTheDocument();
expect(textArea).toHaveAttribute('type', 'textarea');
expect(textArea.parentElement).toHaveTextContent('Deliverables');
});
});

test('renders Number Input with correct props', () => {
const { getByTestId } = render(<MockParentComponent />);

waitFor(() => {
const numberInput = getByTestId('price-sats-input');

expect(numberInput).toBeInTheDocument();
expect(numberInput).toHaveAttribute('type', 'number');
});
});

test('renders with empty props', () => {
const emptyProps = {
...mockProps,
value: '',
label: '',
placeholder: '',
options: []
};

const EmptyPropsComponent = () => (
<>
<Input {...emptyProps} type="textarea" />
<Input {...emptyProps} type="numbersats" />
</>
);

const { container } = render(<EmptyPropsComponent />);
expect(container).toBeInTheDocument();
});

test('handles invalid prop types gracefully', () => {
const invalidProps = {
...mockProps,
value: null,
label: undefined,
style: 'invalid-style',
maxLength: 'invalid-max'
};

const InvalidPropsComponent = () => (
<>
<Input {...invalidProps} type="textarea" />
<Input {...invalidProps} type="numbersats" />
</>
);

const { container } = render(<InvalidPropsComponent />);
expect(container).toBeInTheDocument();
});

test('handles large prop values', () => {
const largeProps = {
...mockProps,
value: 'a'.repeat(1000),
label: 'b'.repeat(1000),
maxLength: 9999999
};

const LargePropsComponent = () => (
<>
<Input {...largeProps} type="textarea" />
<Input {...largeProps} type="numbersats" />
</>
);

const { container } = render(<LargePropsComponent />);
expect(container).toBeInTheDocument();
});

test('handles minimum and maximum values', () => {
const { getByTestId } = render(<MockParentComponent />);
waitFor(() => {
const numberInput = getByTestId('price-sats-input');

fireEvent.change(numberInput, { target: { value: '-1' } });
expect(numberInput).toHaveValue(0);

const maxValue = Number.MAX_SAFE_INTEGER;
fireEvent.change(numberInput, { target: { value: maxValue + 1 } });
expect(numberInput).toHaveValue(maxValue);
});
});

test('renders correctly with duplicate prop values', () => {
const duplicateProps = {
...mockProps,
options: [
{ label: 'Duplicate', value: '1' },
{ label: 'Duplicate', value: '1' }
]
};

const DuplicatePropsComponent = () => (
<>
<Input {...duplicateProps} type="textarea" />
<Input {...duplicateProps} type="numbersats" />
</>
);

const { container } = render(<DuplicatePropsComponent />);
expect(container).toBeInTheDocument();
});
});

0 comments on commit 943e1a7

Please sign in to comment.