Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added missing unit tests #7369

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { renderHook, act } from '@testing-library/react';
import { useRef } from 'react';

import useNavigationState from '@/hooks/react-client/useNavigationState';
import { NavigationStateContext } from '@/providers/navigationStateProvider';

describe('useNavigationState', () => {
it('should save and restore scroll position', () => {
const mockElement = {
scrollLeft: 0,
scrollTop: 0,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
scroll: jest.fn(),
};

const mockRef = { current: mockElement };
const mockContextValue = {};

const wrapper = ({ children }) => (
<NavigationStateContext.Provider value={mockContextValue}>
{children}
</NavigationStateContext.Provider>
);

renderHook(() => useNavigationState('test-id', mockRef), { wrapper });

expect(mockElement.addEventListener).toHaveBeenCalledWith(
'scroll',
expect.any(Function),
{ passive: true }
);

act(() => {
mockElement.scrollTop = 100;
mockElement.scrollLeft = 50;
mockElement.addEventListener.mock.calls[0][1]();
});

expect(mockContextValue['test-id']).toEqual({ x: 50, y: 100 });

act(() => {
mockElement.scrollTop = 0;
mockElement.scrollLeft = 0;
mockElement.scroll.mock.calls[0][0]();
});

expect(mockElement.scroll).toHaveBeenCalledWith({
top: 100,
behavior: 'instant',
});
});

it('should add and remove scroll event listener', () => {
const mockElement = {
scrollLeft: 0,
scrollTop: 0,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
};

const mockRef = { current: mockElement };
const mockContextValue = {};

const wrapper = ({ children }) => (
<NavigationStateContext.Provider value={mockContextValue}>
{children}
</NavigationStateContext.Provider>
);

const { unmount } = renderHook(() => useNavigationState('test-id', mockRef), {
wrapper,
});

expect(mockElement.addEventListener).toHaveBeenCalledWith(
'scroll',
expect.any(Function),
{ passive: true }
);

unmount();

expect(mockElement.removeEventListener).toHaveBeenCalledWith(
'scroll',
expect.any(Function)
);
});
});
74 changes: 74 additions & 0 deletions apps/site/reducers/__tests__/releaseReducer.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import releaseReducer, { releaseState, getActions } from '@/reducers/releaseReducer';

describe('releaseReducer', () => {
it('should return the initial state', () => {
expect(releaseReducer(undefined, {})).toEqual(releaseState);
});

it('should handle SET_VERSION', () => {
const action = { type: 'SET_VERSION', payload: 'v14.17.0' };
const expectedState = { ...releaseState, version: 'v14.17.0' };
expect(releaseReducer(releaseState, action)).toEqual(expectedState);
});

it('should handle SET_OS', () => {
const action = { type: 'SET_OS', payload: 'WIN' };
const expectedState = { ...releaseState, os: 'WIN' };
expect(releaseReducer(releaseState, action)).toEqual(expectedState);
});

it('should handle SET_PLATFORM', () => {
const action = { type: 'SET_PLATFORM', payload: 'x64' };
const expectedState = { ...releaseState, platform: 'x64' };
expect(releaseReducer(releaseState, action)).toEqual(expectedState);
});

it('should handle SET_INSTALL_METHOD', () => {
const action = { type: 'SET_INSTALL_METHOD', payload: 'brew' };
const expectedState = { ...releaseState, installMethod: 'brew' };
expect(releaseReducer(releaseState, action)).toEqual(expectedState);
});

it('should handle SET_MANAGER', () => {
const action = { type: 'SET_MANAGER', payload: 'yarn' };
const expectedState = { ...releaseState, packageManager: 'yarn' };
expect(releaseReducer(releaseState, action)).toEqual(expectedState);
});
});

describe('getActions', () => {
it('should create setVersion action', () => {
const dispatch = jest.fn();
const actions = getActions(dispatch);
actions.setVersion('v14.17.0');
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_VERSION', payload: 'v14.17.0' });
});

it('should create setOS action', () => {
const dispatch = jest.fn();
const actions = getActions(dispatch);
actions.setOS('WIN');
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_OS', payload: 'WIN' });
});

it('should create setPlatform action', () => {
const dispatch = jest.fn();
const actions = getActions(dispatch);
actions.setPlatform('x64');
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_PLATFORM', payload: 'x64' });
});

it('should create setInstallMethod action', () => {
const dispatch = jest.fn();
const actions = getActions(dispatch);
actions.setInstallMethod('brew');
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_INSTALL_METHOD', payload: 'brew' });
});

it('should create setPackageManager action', () => {
const dispatch = jest.fn();
const actions = getActions(dispatch);
actions.setPackageManager('yarn');
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_MANAGER', payload: 'yarn' });
});
});
24 changes: 24 additions & 0 deletions apps/site/util/__tests__/assignClientContext.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ describe('assignClientContext', () => {
expect(result.headings).toEqual(mockContext.headings);
expect(result.readingTime).toEqual(mockContext.readingTime);
expect(result.filename).toEqual(mockContext.filename);
expect(result.os).toEqual(mockContext.os);
expect(result.architecture).toEqual(mockContext.architecture);
expect(result.bitness).toEqual(mockContext.bitness);

expect(result).toEqual(mockContext);
});
Expand All @@ -42,5 +45,26 @@ describe('assignClientContext', () => {
words: 0,
});
expect(result.filename).toEqual('');
expect(result.os).toEqual('OTHER');
expect(result.architecture).toEqual('x64');
expect(result.bitness).toEqual(64);
});

it('should handle invalid inputs gracefully', () => {
const result = assignClientContext(null);

expect(result.frontmatter).toEqual({});
expect(result.pathname).toEqual('');
expect(result.headings).toEqual([]);
expect(result.readingTime).toEqual({
text: '',
minutes: 0,
time: 0,
words: 0,
});
expect(result.filename).toEqual('');
expect(result.os).toEqual('OTHER');
expect(result.architecture).toEqual('x64');
expect(result.bitness).toEqual(64);
});
});
45 changes: 45 additions & 0 deletions apps/site/util/__tests__/authorUtils.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import {
mapAuthorToCardAuthors,
getAuthorWithId,
getAuthorWithName,
getAuthorName,
getAuthorBio,
getAuthorImage,
} from '../authorUtils';

describe('mapAuthorToCardAuthors', () => {
Expand Down Expand Up @@ -96,3 +99,45 @@ describe('getAuthorWithName', () => {
]);
});
});

describe('getAuthorName', () => {
it('should return the correct author name', () => {
const authorId = 'tjfontaine';
const result = getAuthorName(authorId);
expect(result).toBe('Timothy J Fontaine');
});

it('should return undefined for an unknown author', () => {
const authorId = 'unknown';
const result = getAuthorName(authorId);
expect(result).toBeUndefined();
});
});

describe('getAuthorBio', () => {
it('should return the correct author bio', () => {
const authorId = 'tjfontaine';
const result = getAuthorBio(authorId);
expect(result).toBeUndefined(); // Assuming no bio is provided in the authors.json
});

it('should return undefined for an unknown author', () => {
const authorId = 'unknown';
const result = getAuthorBio(authorId);
expect(result).toBeUndefined();
});
});

describe('getAuthorImage', () => {
it('should return the correct author image URL', () => {
const authorId = 'tjfontaine';
const result = getAuthorImage(authorId);
expect(result).toBe('https://avatars.githubusercontent.com/tjfontaine');
});

it('should return undefined for an unknown author', () => {
const authorId = 'unknown';
const result = getAuthorImage(authorId);
expect(result).toBeUndefined();
});
});
27 changes: 27 additions & 0 deletions apps/site/util/__tests__/blogUtils.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { getBlogPosts, getBlogCategories, getBlogTags } from '@/util/blogUtils';

describe('blogUtils', () => {
describe('getBlogPosts', () => {
it('should retrieve blog posts', () => {
const blogPosts = getBlogPosts();
expect(blogPosts).toBeDefined();
expect(Array.isArray(blogPosts)).toBe(true);
});
});

describe('getBlogCategories', () => {
it('should retrieve blog categories', () => {
const blogCategories = getBlogCategories();
expect(blogCategories).toBeDefined();
expect(Array.isArray(blogCategories)).toBe(true);
});
});

describe('getBlogTags', () => {
it('should retrieve blog tags', () => {
const blogTags = getBlogTags();
expect(blogTags).toBeDefined();
expect(Array.isArray(blogTags)).toBe(true);
});
});
});
40 changes: 39 additions & 1 deletion apps/site/util/__tests__/dateUtils.test.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dateIsBetween } from '@/util/dateUtils';
import { dateIsBetween, formatDate, parseDate, isValidDate } from '@/util/dateUtils';

describe('dateIsBetween', () => {
it('returns true when the current date is between start and end dates', () => {
Expand Down Expand Up @@ -28,3 +28,41 @@ describe('dateIsBetween', () => {
);
});
});

describe('formatDate', () => {
it('formats a valid date correctly', () => {
const date = new Date('2024-02-17T00:00:00.000Z');
const formattedDate = formatDate(date, 'yyyy-MM-dd');
expect(formattedDate).toBe('2024-02-17');
});

it('throws an error for an invalid date', () => {
const invalidDate = new Date('Invalid Date');
expect(() => formatDate(invalidDate, 'yyyy-MM-dd')).toThrow('Invalid date');
});
});

describe('parseDate', () => {
it('parses a valid date string correctly', () => {
const dateString = '2024-02-17';
const parsedDate = parseDate(dateString, 'yyyy-MM-dd');
expect(parsedDate).toEqual(new Date('2024-02-17T00:00:00.000Z'));
});

it('throws an error for an invalid date string', () => {
const invalidDateString = 'Invalid Date';
expect(() => parseDate(invalidDateString, 'yyyy-MM-dd')).toThrow('Invalid date string');
});
});

describe('isValidDate', () => {
it('returns true for a valid date', () => {
const validDate = new Date('2024-02-17T00:00:00.000Z');
expect(isValidDate(validDate)).toBe(true);
});

it('returns false for an invalid date', () => {
const invalidDate = new Date('Invalid Date');
expect(isValidDate(invalidDate)).toBe(false);
});
});
29 changes: 29 additions & 0 deletions apps/site/util/__tests__/debounce.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,33 @@ describe('debounce', () => {

expect(fn).toHaveBeenCalledWith(3);
});

it('should delay the execution of the function', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);

debouncedFn();

expect(fn).not.toHaveBeenCalled();

jest.advanceTimersByTime(500);
expect(fn).not.toHaveBeenCalled();

jest.advanceTimersByTime(500);
expect(fn).toHaveBeenCalled();
});

it('should execute only once within the delay', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);

debouncedFn();
jest.advanceTimersByTime(500);
debouncedFn();
jest.advanceTimersByTime(500);
debouncedFn();
jest.advanceTimersByTime(1000);

expect(fn).toHaveBeenCalledTimes(1);
});
});
Loading
Loading