mattermost-mobile-upstream/app/components/formatted_date/index.test.tsx
Elias Nahum b6fc85385e
Migrate from RNN to Expo router (#9402)
* Expo-Router partial migration

* Full migration to ExpoRouter

* i18n

* add tests

* Merge branch 'main' into expo-router

* align package-lock.json

* i18n

* feedback review

* feedback review

* android 16kb patch

* Refactored emoji picker keyboard using a state machine

* set android launch_screen in drawables instead of layout

* no conditional hooks

* remove duplicate call in test

* address feedback

* fix tests and address more feedback

* small corrections

* small corrections

* small corrections

* fix draft test

* fix draft test 2

* remove navigateToScreen in draff test

* fix nit in draft test

* remove doc file

* Feedback review

* fix snapshots

* improve test coverage

* fix i18n

* Upgrade t o RN 0.83, other dependencies and new architecture (#9737)

* library hardware-keyboard android new arch support fix

* library rnshare android new arch support fix

* library rnutils android new arch support fix

* library secure-pdf-viewer add new arch support

* Enable new arch on iOS and Android

* update emm and network client with new-arch

* update intune to use new-arch

* performance improvements

* fix tests

* fixes post input on new-arch

* fix android emoji picker

* remove doc

* run tests in parallel

* upgrade to React Native 0.83.9, Expo 55, React 19, and New Architecture

Bumps core dependencies to their latest versions:
- React Native 0.77.3 → 0.83.9 (New Architecture enabled)
- React 18.3.1 → 19.2.5
- Expo SDK 52 → 55
- TypeScript 5.8.3 → 6.0.3
- Node.js 22.16.0 → 24.15.0
- react-native-reanimated 3.17.3 → 4.3.0
- Various other dependency upgrades

Migrates iOS AppDelegate from Objective-C to Swift, updates Android
build tooling and Gradle wrapper, refreshes all patches and font
assets, and adapts app code, tests, and CI workflows throughout for
API changes introduced by these upgrades.

* remove unecessary dismissKeyboard in notifications

* feedback review

* update intune to use new-arch

* update @mattermost deps

* missing i18n string

* additional fixes

* update fastlane
2026-05-13 17:44:55 +08:00

144 lines
4.4 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import locales from '@i18n/languages';
import React from 'react';
import timezones from 'timezones.json';
import {renderWithIntl} from '@test/intl-test-helper';
import {logDebug} from '@utils/log';
import FormattedDate, {type FormattedDateFormat} from './index';
jest.mock('@utils/log', () => ({
logDebug: jest.fn(),
logError: jest.fn(),
logInfo: jest.fn(),
logWarning: jest.fn(),
}));
const DATE = new Date('2024-10-26T10:01:04.653Z');
const FORMATS = [
undefined,
{weekday: 'long'},
{dateStyle: 'medium'},
{month: 'short', day: 'numeric'},
{
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
{
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
},
] satisfies Array<FormattedDateFormat | undefined>;
const TEST_MATRIX = Object.keys(locales).
map((locale) => FORMATS.map<[string, FormattedDateFormat | undefined]>((format) => [locale, format])).
flat(1);
function getTimezoneTestsCases() {
// Mimics the logic for the timezones offered by the web app
// in webapp/channels/src/components/user_settings/display/manage_timezones/manage_timezones.tsx
let index = 0;
const testCases = [];
let previousTimezone = '';
for (const timezone of timezones) {
if (timezone.utc[index] === previousTimezone) {
index++;
} else {
index = 0;
}
testCases.push([timezone.utc[index]]);
previousTimezone = timezone.utc[index];
}
return testCases;
}
describe('<FormattedDate/>', () => {
it.each(TEST_MATRIX)("should match snapshot for '%s' locale and '%p' format", (locale, format) => {
const wrapper = renderWithIntl(
<FormattedDate
format={format}
value={DATE}
timezone='UTC'
/>,
{locale},
);
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('should render with a manual user time', () => {
const wrapper = renderWithIntl(
<FormattedDate
value={DATE}
timezone={{
automaticTimezone: '',
manualTimezone: 'Indian/Mauritius',
useAutomaticTimezone: '',
}}
/>,
);
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('should render with an automatic user time', () => {
const wrapper = renderWithIntl(
<FormattedDate
value={DATE}
timezone={{
automaticTimezone: 'Indian/Mauritius',
manualTimezone: '',
useAutomaticTimezone: 'true',
}}
/>,
);
// Just check that the component render as automatic timezone is environment dependant
expect(wrapper.toJSON()).toBeTruthy();
});
it.each(getTimezoneTestsCases())('should render with timezone %s', (timezone) => {
const wrapper = renderWithIntl(
<FormattedDate
value={DATE}
timezone={timezone}
format={{hour: 'numeric', minute: 'numeric'}}
/>,
);
expect(wrapper.queryByText('Unknown')).not.toBeTruthy();
expect(logDebug).not.toHaveBeenCalled();
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('should default when timezone is not found', () => {
const wrapper = renderWithIntl(
<FormattedDate
value={DATE}
timezone={'not valid timezone'}
format={{hour: 'numeric', minute: 'numeric'}}
/>,
);
expect(wrapper.queryByText('Unknown')).not.toBeTruthy();
expect(logDebug).toHaveBeenCalledTimes(1);
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('should show unknown on other errors', () => {
const wrapper = renderWithIntl(
<FormattedDate
value={DATE}
timezone={undefined}
format={{hour: 'numeric', minute: 'invalid' as any}}
/>,
);
expect(wrapper.queryByText('Unknown')).toBeTruthy();
expect(logDebug).toHaveBeenCalledTimes(2);
});
});