diff --git a/api/src/utils/apply-function-to-column-name.test.ts b/api/src/utils/apply-function-to-column-name.test.ts new file mode 100644 index 0000000000..a2cc9f4fe5 --- /dev/null +++ b/api/src/utils/apply-function-to-column-name.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest'; + +import { applyFunctionToColumnName } from './apply-function-to-column-name'; + +test.each([ + { input: 'test', expected: 'test' }, + { input: 'year(date_created)', expected: 'date_created_year' }, + { input: `hour(timestamp)`, expected: 'timestamp_hour' }, + { input: `count(value)`, expected: 'value_count' }, +])('should return "$expected" for "$input"', ({ input, expected }) => { + expect(applyFunctionToColumnName(input)).toBe(expected); +}); diff --git a/api/src/utils/get-date-formatted.test.ts b/api/src/utils/get-date-formatted.test.ts new file mode 100644 index 0000000000..9394bf4266 --- /dev/null +++ b/api/src/utils/get-date-formatted.test.ts @@ -0,0 +1,37 @@ +import { afterEach, beforeEach, expect, test, vi } from 'vitest'; + +import { getDateFormatted } from './get-date-formatted'; + +beforeEach(() => { + vi.useFakeTimers(); +}); + +afterEach(() => { + vi.useRealTimers(); +}); + +function getUtcDateForString(date: string) { + const now = new Date(date); + + // account for timezone difference depending on the machine where this test is ran + const timezoneOffsetInMinutes = now.getTimezoneOffset(); + const timezoneOffsetInMilliseconds = timezoneOffsetInMinutes * 60 * 1000; + const nowUTC = new Date(now.valueOf() + timezoneOffsetInMilliseconds); + + return nowUTC; +} + +test.each([ + { utc: '2023-01-01T01:23:45.678Z', expected: '20230101-12345' }, + { utc: '2023-01-11T01:23:45.678Z', expected: '20230111-12345' }, + { utc: '2023-11-01T01:23:45.678Z', expected: '20231101-12345' }, + { utc: '2023-11-11T12:34:56.789Z', expected: '20231111-123456' }, + { utc: '2023-06-01T01:23:45.678Z', expected: '20230601-12345' }, + { utc: '2023-06-11T12:34:56.789Z', expected: '20230611-123456' }, +])('should format $utc into "$expected"', ({ utc, expected }) => { + const nowUTC = getUtcDateForString(utc); + + vi.setSystemTime(nowUTC); + + expect(getDateFormatted()).toBe(expected); +}); diff --git a/api/src/utils/md.test.ts b/api/src/utils/md.test.ts new file mode 100644 index 0000000000..5777bb6a5d --- /dev/null +++ b/api/src/utils/md.test.ts @@ -0,0 +1,11 @@ +import { expect, test } from 'vitest'; + +import { md } from './md'; + +test.each([ + { str: 'test', expected: '
test
\n' }, + { str: ``, expected: '' }, + { str: `test`, expected: 'test
\n' }, +])('should sanitize "$str" into "$expected"', ({ str, expected }) => { + expect(md(str)).toBe(expected); +}); diff --git a/api/src/utils/stall.test.ts b/api/src/utils/stall.test.ts new file mode 100644 index 0000000000..e427be5341 --- /dev/null +++ b/api/src/utils/stall.test.ts @@ -0,0 +1,41 @@ +import { afterAll, beforeAll, expect, SpyInstance, test, vi } from 'vitest'; + +import { stall } from './stall'; + +let performanceNowSpy: SpyInstance; + +beforeAll(() => { + vi.useFakeTimers(); + + // fake timers doesn't fake performance.now(), so this is used to mock it + performanceNowSpy = vi.spyOn(performance, 'now').mockReturnValue(0); +}); + +afterAll(() => { + vi.useRealTimers(); +}); + +const STALL_TIME = 100; + +test('does not stall if elapsed time has already past the stall time', () => { + const startTime = performance.now(); + + // intentionally advance past the stall time first + performanceNowSpy.mockReturnValueOnce(1000); + + stall(STALL_TIME, startTime); + + expect(vi.getTimerCount()).toBe(0); +}); + +test('should stall for a set amount of time', () => { + const startTime = performance.now(); + + stall(STALL_TIME, startTime); + + expect(vi.getTimerCount()).toBe(1); + + vi.advanceTimersByTime(STALL_TIME); + + expect(vi.getTimerCount()).toBe(0); +}); diff --git a/api/src/utils/strip-function.test.ts b/api/src/utils/strip-function.test.ts new file mode 100644 index 0000000000..e994021a5b --- /dev/null +++ b/api/src/utils/strip-function.test.ts @@ -0,0 +1,10 @@ +import { expect, test } from 'vitest'; + +import { stripFunction } from './strip-function'; + +test.each([ + { field: 'year(date_created)', expected: 'date_created' }, + { field: 'test', expected: 'test' }, +])('should return "$expected" for "$field"', ({ field, expected }) => { + expect(stripFunction(field)).toBe(expected); +}); diff --git a/api/src/utils/user-name.test.ts b/api/src/utils/user-name.test.ts new file mode 100644 index 0000000000..17b9181069 --- /dev/null +++ b/api/src/utils/user-name.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from 'vitest'; + +import { userName } from './user-name'; + +const unknownUser = 'Unknown User'; + +test('should return "Unknown User" when user is undefined', () => { + expect(userName(undefined as any)).toBe(unknownUser); +}); + +test('should return "Test User" when user first name is "Test" and last name is "User"', () => { + expect(userName({ first_name: 'Test', last_name: 'User' })).toBe('Test User'); +}); + +test('should return "Test" when user first name is "Test" but does not have last name', () => { + expect(userName({ first_name: 'Test' })).toBe('Test'); +}); + +test('should return user email when user only has email without first name and last name', () => { + expect(userName({ email: 'test@example.com' })).toBe('test@example.com'); +}); + +test('should return "Unknown User" when user is empty', () => { + expect(userName({})).toBe(unknownUser); +}); diff --git a/api/src/utils/validate-env.test.ts b/api/src/utils/validate-env.test.ts new file mode 100644 index 0000000000..6b7efce56d --- /dev/null +++ b/api/src/utils/validate-env.test.ts @@ -0,0 +1,41 @@ +import { afterEach, beforeAll, expect, test, vi } from 'vitest'; + +import { validateEnv } from './validate-env'; +import logger from '../logger'; + +vi.mock('../env', () => ({ + getEnv: vi.fn().mockReturnValue({ + PRESENT_TEST_VARIABLE: true, + }), +})); +vi.mock('../logger', () => ({ + default: { + error: vi.fn(), + }, +})); + +vi.mock('process', () => ({ + exit: vi.fn(), +})); + +beforeAll(() => { + vi.spyOn(process, 'exit').mockImplementation(() => undefined as never); +}); + +afterEach(() => { + vi.clearAllMocks(); +}); + +test('should not have any error when key is present', () => { + validateEnv(['PRESENT_TEST_VARIABLE']); + + expect(logger.error).not.toHaveBeenCalled(); + expect(process.exit).not.toHaveBeenCalled(); +}); + +test('should have error when key is missing', () => { + validateEnv(['ABSENT_TEST_VARIABLE']); + + expect(logger.error).toHaveBeenCalled(); + expect(process.exit).toHaveBeenCalled(); +});