Skip to content

Commit 2130ed8

Browse files
committed
Add more unit tests
1 parent 8f595d7 commit 2130ed8

5 files changed

Lines changed: 85 additions & 9 deletions

File tree

src/components/MessagesRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import useLocalize from '@hooks/useLocalize';
55
import useTheme from '@hooks/useTheme';
66
import useThemeStyles from '@hooks/useThemeStyles';
77
import CONST from '@src/CONST';
8+
import type {TranslationKeyError} from '@src/languages/types';
89
import type {ReceiptError} from '@src/types/onyx/Transaction';
910
import {isEmptyObject} from '@src/types/utils/EmptyObject';
10-
import type { TranslationKeyError } from '@src/languages/types';
1111
import DotIndicatorMessage from './DotIndicatorMessage';
1212
import Icon from './Icon';
1313
import * as Expensicons from './Icon/Expensicons';

src/components/OfflineWithFeedback.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import mapChildrenFlat from '@libs/mapChildrenFlat';
88
import shouldRenderOffscreen from '@libs/shouldRenderOffscreen';
99
import type {AllStyles} from '@styles/utils/types';
1010
import CONST from '@src/CONST';
11+
import type {TranslationKeyErrors} from '@src/languages/types';
1112
import type * as OnyxCommon from '@src/types/onyx/OnyxCommon';
1213
import type {ReceiptErrors} from '@src/types/onyx/Transaction';
1314
import type ChildrenProps from '@src/types/utils/ChildrenProps';
1415
import {isEmptyObject} from '@src/types/utils/EmptyObject';
15-
import type { TranslationKeyErrors } from '@src/languages/types';
1616
import CustomStylesForChildrenProvider from './CustomStylesForChildrenProvider';
1717
import ErrorMessageRow from './ErrorMessageRow';
1818
import ImageSVG from './ImageSVG';

src/languages/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ type DefaultTranslation = typeof en;
7777
type TranslationPaths = FlattenObject<DefaultTranslation>;
7878

7979
type TranslationKeyError = {
80-
translationKey: TranslationPaths
81-
}
80+
translationKey: TranslationPaths;
81+
};
8282

8383
type TranslationKeyErrors = Record<string, TranslationKeyError>;
8484
/**

src/libs/ErrorUtils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ function isReceiptError(message: unknown): message is ReceiptError {
209209
* Check if the error includes a translation key.
210210
*/
211211
function isTranslationKeyError(message: unknown): message is TranslationKeyError {
212+
if (!message) {
213+
return false;
214+
}
212215
if (typeof message === 'string') {
213216
return false;
214217
}

tests/unit/ErrorUtilsTest.ts

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as ErrorUtils from '@src/libs/ErrorUtils';
21
import DateUtils from '@src/libs/DateUtils';
2+
import * as ErrorUtils from '@src/libs/ErrorUtils';
33
import type {Errors} from '@src/types/onyx/OnyxCommon';
44

55
// Mock DateUtils
@@ -122,10 +122,12 @@ describe('ErrorUtils', () => {
122122
});
123123

124124
test('should return false for objects with multiple keys', () => {
125-
expect(ErrorUtils.isTranslationKeyError({
126-
translationKey: 'passwordForm.error.fallback',
127-
extraKey: 'extra',
128-
})).toBe(false);
125+
expect(
126+
ErrorUtils.isTranslationKeyError({
127+
translationKey: 'passwordForm.error.fallback',
128+
extraKey: 'extra',
129+
}),
130+
).toBe(false);
129131
});
130132

131133
test('should return false for objects without translationKey property', () => {
@@ -150,4 +152,75 @@ describe('ErrorUtils', () => {
150152
expect(ErrorUtils.isTranslationKeyError(false)).toBe(false);
151153
});
152154
});
155+
156+
describe('Integration: getMicroSecondTranslationErrorWithTranslationKey and isTranslationKeyError', () => {
157+
beforeEach(() => {
158+
jest.clearAllMocks();
159+
});
160+
161+
test('should create translation error objects that are correctly identified by isTranslationKeyError', () => {
162+
const mockMicroseconds = 1234567890123;
163+
(DateUtils.getMicroseconds as jest.Mock).mockReturnValue(mockMicroseconds);
164+
165+
const errorObject = ErrorUtils.getMicroSecondTranslationErrorWithTranslationKey('passwordForm.error.incorrectLoginOrPassword');
166+
167+
// The error object should have one key (the timestamp)
168+
const keys = Object.keys(errorObject);
169+
expect(keys).toHaveLength(1);
170+
171+
// The value at that key should be a valid translation key error
172+
const errorValue = errorObject[keys[0]];
173+
expect(ErrorUtils.isTranslationKeyError(errorValue)).toBe(true);
174+
});
175+
176+
test('should work with custom error keys', () => {
177+
const customErrorKey = 9876543210;
178+
const errorObject = ErrorUtils.getMicroSecondTranslationErrorWithTranslationKey('passwordForm.error.fallback', customErrorKey);
179+
180+
// The error object should have the custom key
181+
expect(errorObject).toHaveProperty(customErrorKey.toString());
182+
183+
// The value should be a valid translation key error
184+
const errorValue = errorObject[customErrorKey];
185+
expect(ErrorUtils.isTranslationKeyError(errorValue)).toBe(true);
186+
});
187+
188+
test('should create objects with multiple errors that are all valid translation key errors', () => {
189+
const mockMicroseconds1 = 1111111111111;
190+
const mockMicroseconds2 = 2222222222222;
191+
192+
(DateUtils.getMicroseconds as jest.Mock).mockReturnValueOnce(mockMicroseconds1).mockReturnValueOnce(mockMicroseconds2);
193+
194+
const error1 = ErrorUtils.getMicroSecondTranslationErrorWithTranslationKey('passwordForm.error.incorrectLoginOrPassword');
195+
const error2 = ErrorUtils.getMicroSecondTranslationErrorWithTranslationKey('session.offlineMessageRetry');
196+
197+
// Combine the error objects
198+
const combinedErrors = {...error1, ...error2};
199+
200+
// All values should be valid translation key errors
201+
Object.values(combinedErrors).forEach((errorValue) => {
202+
expect(ErrorUtils.isTranslationKeyError(errorValue)).toBe(true);
203+
});
204+
});
205+
206+
test('should verify the structure of created translation key errors', () => {
207+
const mockMicroseconds = 5555555555555;
208+
(DateUtils.getMicroseconds as jest.Mock).mockReturnValue(mockMicroseconds);
209+
210+
const errorObject = ErrorUtils.getMicroSecondTranslationErrorWithTranslationKey('passwordForm.error.twoFactorAuthenticationEnabled');
211+
const errorValue = errorObject[mockMicroseconds];
212+
213+
// Verify the structure matches what isTranslationKeyError expects
214+
expect(errorValue).toEqual({
215+
translationKey: 'passwordForm.error.twoFactorAuthenticationEnabled',
216+
});
217+
218+
// Verify it passes all the checks in isTranslationKeyError
219+
expect(typeof errorValue).not.toBe('string');
220+
expect(Array.isArray(errorValue)).toBe(false);
221+
expect(Object.keys(errorValue)).toHaveLength(1);
222+
expect(errorValue.translationKey).toBeDefined();
223+
expect(ErrorUtils.isTranslationKeyError(errorValue)).toBe(true);
224+
});
225+
});
153226
});

0 commit comments

Comments
 (0)