Skip to content

Commit

Permalink
chore: add more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ovflowd committed Dec 29, 2024
1 parent c9b01b5 commit 7a2e0a6
Show file tree
Hide file tree
Showing 20 changed files with 627 additions and 45 deletions.
4 changes: 1 addition & 3 deletions apps/site/jest.config.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import nextJest from 'next/jest.js';

const createJestConfig = nextJest({
dir: './',
});
const createJestConfig = nextJest({ dir: './' });

/** @type {import('jest').Config} */
const customJestConfig = {
Expand Down
25 changes: 25 additions & 0 deletions apps/site/providers/__tests__/navigationStateProvider.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { render } from '@testing-library/react';

import { NavigationStateProvider } from '@/providers/navigationStateProvider';

describe('NavigationStateProvider', () => {
it('should render without crashing', () => {
const { container } = render(
<NavigationStateProvider>
<div />
</NavigationStateProvider>
);

expect(container).toBeDefined();
});

it('should provide navigation state context', () => {
const { getByText } = render(
<NavigationStateProvider>
<div>Navigation State</div>
</NavigationStateProvider>
);

expect(getByText('Navigation State')).toBeDefined();
});
});
39 changes: 39 additions & 0 deletions apps/site/providers/__tests__/releaseProvider.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { render } from '@testing-library/react';

import { ReleaseProvider, ReleasesProvider } from '@/providers/releaseProvider';

describe('ReleaseProvider', () => {
it('should render without crashing', () => {
const initialRelease = { versionWithPrefix: 'v14.17.0' };
const releases = [initialRelease];
const snippets = [];

const { container } = render(
<ReleasesProvider releases={releases} snippets={snippets}>
<ReleaseProvider initialRelease={initialRelease}>
<div />
</ReleaseProvider>
</ReleasesProvider>
);

expect(container).toBeDefined();
});

it('should set version from parent provider', () => {
const initialRelease = { versionWithPrefix: 'v14.17.0' };
const releases = [initialRelease];
const snippets = [];

const { getByText } = render(
<ReleasesProvider releases={releases} snippets={snippets}>
<ReleaseProvider initialRelease={initialRelease}>
<ReleaseProvider>
<div>Child Provider</div>
</ReleaseProvider>
</ReleaseProvider>
</ReleasesProvider>
);

expect(getByText('Child Provider')).toBeDefined();
});
});
78 changes: 78 additions & 0 deletions apps/site/reducers/__tests__/releaseReducer.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import reducer, { releaseState, getActions } from '@/reducers/releaseReducer';

describe('releaseReducer', () => {
it('should return the initial state', () => {
const initialState = releaseState;
const action = { type: 'UNKNOWN_ACTION' };
expect(reducer(initialState, action)).toEqual(initialState);
});

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

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

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

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

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

describe('getActions', () => {
it('should create actions correctly', () => {
const dispatch = jest.fn();
const actions = getActions(dispatch);

actions.setVersion('v14.17.0');
expect(dispatch).toHaveBeenCalledWith({
type: 'SET_VERSION',
payload: 'v14.17.0',
});

actions.setOS('Linux');
expect(dispatch).toHaveBeenCalledWith({ type: 'SET_OS', payload: 'Linux' });

actions.setPlatform('arm64');
expect(dispatch).toHaveBeenCalledWith({
type: 'SET_PLATFORM',
payload: 'arm64',
});

actions.setInstallMethod('binary');
expect(dispatch).toHaveBeenCalledWith({
type: 'SET_INSTALL_METHOD',
payload: 'binary',
});

actions.setPackageManager('Yarn');
expect(dispatch).toHaveBeenCalledWith({
type: 'SET_MANAGER',
payload: 'Yarn',
});
});
});
25 changes: 24 additions & 1 deletion apps/site/util/__tests__/authorUtils.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
mapAuthorToCardAuthors,
getAuthorWithId,
getAuthorWithName,
} from '../authorUtils';
getAuthors,
} from '@/util/authorUtils';

describe('mapAuthorToCardAuthors', () => {
it('maps authors to card authors with default avatar source', () => {
Expand Down Expand Up @@ -96,3 +97,25 @@ describe('getAuthorWithName', () => {
]);
});
});

describe('authorUtils', () => {
test('mapAuthorToCardAuthors splits authors by common separators', () => {
const result = mapAuthorToCardAuthors('Node, React & prepared by Vue');
expect(result).toEqual(['Node', 'React', 'Vue']);
});

test('getAuthorWithId returns objects with GitHub avatars', () => {
const result = getAuthorWithId(['someUser'], false);
expect(result[0].image).toContain('github');
});

test('getAuthorWithName returns known author details or fallback to acronym', () => {
const result = getAuthorWithName(['unknownAuthor'], true);
expect(result[0].fallback).toBe('U');
});

test('getAuthors uses getAuthorWithId if usernames array is provided', () => {
const result = getAuthors({ usernames: ['testUser'] });
expect(result[0].nickname).toBe('testUser');
});
});
12 changes: 12 additions & 0 deletions apps/site/util/__tests__/blogUtils.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { mapBlogCategoryToPreviewType } from '@/util/blogUtils';

describe('mapBlogCategoryToPreviewType', () => {
test('returns the correct preview type for recognized categories', () => {
expect(mapBlogCategoryToPreviewType('release')).toBe('release');
expect(mapBlogCategoryToPreviewType('events')).toBe('announcements');
});

test('defaults to announcements for unknown categories', () => {
expect(mapBlogCategoryToPreviewType('random')).toBe('announcements');
});
});
16 changes: 13 additions & 3 deletions apps/site/util/__tests__/dateUtils.test.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { dateIsBetween } from '@/util/dateUtils';

describe('dateIsBetween', () => {
it('returns true when the current date is between start and end dates', () => {
it('should return true when the current date is between start and end dates', () => {
const startDate = '2022-01-01T00:00:00.000Z';
const endDate = '2069-01-01T00:00:00.000Z';

Expand All @@ -10,7 +10,7 @@ describe('dateIsBetween', () => {
expect(result).toBe(true);
});

it('returns false when the current date is not between start and end dates', () => {
it('should return false when the current date is not between start and end dates', () => {
const startDate = '2010-01-01T00:00:00.000Z';
const endDate = '2020-01-01T00:00:00.000Z';

Expand All @@ -19,12 +19,22 @@ describe('dateIsBetween', () => {
expect(result).toBe(false);
});

it('throws when either start or end date is invalid', () => {
it('should throw an error when either start or end date is invalid', () => {
const invalidStartDate = 'Invalid Start Date';
const validEndDate = '2024-01-01T00:00:00.000Z';

expect(() => dateIsBetween(invalidStartDate, validEndDate)).toThrow(
'dateIsBetween got called with invalid dates'
);
});

it('should return true if now is between startDate and endDate', () => {
const start = new Date(Date.now() - 1000).toISOString();
const end = new Date(Date.now() + 1000).toISOString();
expect(dateIsBetween(start, end)).toBe(true);
});

it('should throw an error if dates are invalid', () => {
expect(() => dateIsBetween('invalid', 'invalid')).toThrow();
});
});
15 changes: 13 additions & 2 deletions apps/site/util/__tests__/debounce.test.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { debounce } from '@/util/debounce';

describe('debounce', () => {
jest.useFakeTimers();
jest.useFakeTimers();

describe('debounce', () => {
it('should call the function only once', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);
Expand All @@ -28,4 +28,15 @@ describe('debounce', () => {

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

it('should call the function after the delay', () => {
const mockFn = jest.fn();
const debouncedFn = debounce(mockFn, 500);

debouncedFn();
expect(mockFn).not.toBeCalled();

jest.advanceTimersByTime(500);
expect(mockFn).toBeCalled();
});
});
17 changes: 17 additions & 0 deletions apps/site/util/__tests__/deepMerge.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import deepMerge from '@/util/deepMerge';

describe('deepMerge', () => {
it('should merge nested objects', () => {
const obj1 = { a: { b: 1 }, c: 2 };
const obj2 = { a: { d: 3 }, e: 4 };
const result = deepMerge(obj1, obj2);
expect(result).toEqual({ a: { b: 1, d: 3 }, c: 2, e: 4 });
});

it('should overwrite primitive properties', () => {
const obj1 = { a: 1 };
const obj2 = { a: 2 };
const result = deepMerge(obj1, obj2);
expect(result).toEqual({ a: 2 });
});
});
92 changes: 65 additions & 27 deletions apps/site/util/__tests__/detectOS.test.mjs
Original file line number Diff line number Diff line change
@@ -1,31 +1,69 @@
import { detectOsInUserAgent } from '@/util/detectOS';
import { detectOsInUserAgent, detectOS } from '@/util/detectOS';

const userAgentTestCases = [
[
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246',
'WIN',
],
[
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'MAC',
],
[
'Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36',
'OTHER',
],
[
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1',
'LINUX',
],
[
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.3 Mobile/15E148 Safari/604.1',
'MAC',
],
['', 'OTHER'],
['OTHERAgent/1.0', 'OTHER'],
[undefined, 'OTHER'],
];

describe('detectOsInUserAgent', () => {
it.each([
[
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246',
'WIN',
],
[
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'MAC',
],
[
'Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36',
'OTHER',
],
[
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1',
'LINUX',
],
[
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.3 Mobile/15E148 Safari/604.1',
'MAC',
],
['', 'OTHER'],
['OTHERAgent/1.0', 'OTHER'],
[undefined, 'OTHER'],
])('detectOsInUserAgent(%s) returns %s', (os, expected) => {
expect(detectOsInUserAgent(os)).toBe(expected);
it.each(userAgentTestCases)(
'should return %s for userAgent %s',
(userAgent, expected) => {
expect(detectOsInUserAgent(userAgent)).toBe(expected);
}
);

it('should return OTHER if no match is found', () => {
const result = detectOsInUserAgent('no-match');
expect(result).toBe('OTHER');
});

it('should detect Windows', () => {
const result = detectOsInUserAgent('Mozilla Win something');
expect(result).toBe('WIN');
});

it('should detect Linux', () => {
const result = detectOsInUserAgent('Mozilla/5.0 (X11; Linux x86_64)');
expect(result).toBe('LINUX');
});
});

describe('detectOS', () => {
it('should call detectOsInUserAgent', () => {
Object.defineProperty(global, 'navigator', {
value: { userAgent: 'Mac' },
configurable: true,
});
expect(detectOS()).toBe('MAC');
});

it('should return OTHER if navigator is undefined', () => {
Object.defineProperty(global, 'navigator', {
value: undefined,
configurable: true,
});
expect(detectOS()).toBe('OTHER');
});
});
Loading

0 comments on commit 7a2e0a6

Please sign in to comment.