Skip to content

Commit 51a53ed

Browse files
committed
refactor(v1-components): Locale detection & checking it is actually works
1 parent 5a50a4f commit 51a53ed

File tree

4 files changed

+90
-89
lines changed

4 files changed

+90
-89
lines changed

packages/v1-components/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
"dependencies": {
5757
"@omnicajs/vue-remote": "^0.2.5",
5858
"@remote-ui/rpc": "^1.4.5",
59-
"@retailcrm/image-preview": "^1.0.2"
59+
"@retailcrm/image-preview": "^1.0.2",
60+
"date-fns": "^4.1.0"
6061
},
6162
"devDependencies": {
6263
"@storybook/addon-a11y": "^8.4.7",
@@ -75,8 +76,8 @@
7576
"@storybook/vue3-vite": "^8.4.7",
7677
"@vitejs/plugin-vue": "^5.1.4",
7778
"@vue/compiler-sfc": "^3.5.12",
79+
"@vue/test-utils": "^2.4.6",
7880
"@yandex/ymaps3-types": "^0.0.21",
79-
"date-fns": "^4.1.0",
8081
"less": "^4.2.0",
8182
"react": "^18.3.1",
8283
"react-dom": "^18.3.1",

packages/v1-components/src/common/formatters/date.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ export const formatDateRu = (date: Date | string) => format(date, 'dd.MM.yyyy',
1010

1111
export const formatTime = (date: Date | string) => format(date, 'HH:mm', { locale: enGB })
1212

13-
export const formatDate = (date: Date | string, locale?: Locale) => {
14-
return (detectLocale() ?? locale) === 'ru-RU'
13+
export const formatDate = (date: Date | string, locale: Locale | undefined = undefined) => {
14+
return (locale ?? detectLocale()) === 'ru-RU'
1515
? formatDateRu(date)
1616
: formatDateLat(date)
1717
}
1818

19-
export const formatDateTime = (date: Date | string, locale?: Locale) => format(date, 'Pp', {
19+
export const formatDateTime = (date: Date | string, locale: Locale | undefined = undefined) => format(date, 'Pp', {
2020
locale: {
2121
'en-GB': enGB,
2222
'es-ES': es,
@@ -25,28 +25,25 @@ export const formatDateTime = (date: Date | string, locale?: Locale) => format(d
2525
})
2626

2727
function detectLocale(): Locale {
28-
let detectedLocale: Locale = 'en-GB'
2928
const instance = getCurrentInstance()
30-
3129
// Safely access i18n instance with proper type checking
3230
const i18n = instance?.appContext?.app?.config?.globalProperties?.$i18n
3331

3432
if (i18n) {
3533
try {
36-
const localeValue = typeof i18n.locale === 'object' ? i18n.locale.value : i18n.locale
37-
const rawLocale = localeValue?.toString() || 'en-GB'
38-
39-
if (rawLocale.startsWith('en')) {
40-
detectedLocale = 'en-GB'
41-
} else if (rawLocale.startsWith('ru')) {
42-
detectedLocale = 'ru-RU'
43-
} else if (rawLocale.startsWith('es')) {
44-
detectedLocale = 'es-ES'
45-
}
34+
const locale = (
35+
typeof i18n.locale === 'object'
36+
? i18n.locale.value
37+
: i18n.locale
38+
) ?? 'en-GB'
39+
40+
if (locale.startsWith('en')) return 'en-GB'
41+
if (locale.startsWith('es')) return 'es-ES'
42+
if (locale.startsWith('ru')) return 'ru-RU'
4643
} catch (error) {
4744
console.warn('Error detecting locale:', error)
4845
}
4946
}
5047

51-
return detectedLocale
48+
return 'en-GB'
5249
}
Lines changed: 73 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,99 @@
1-
import { beforeEach, describe, expect, test, vi } from 'vitest'
1+
import { describe, expect, test } from 'vitest'
2+
3+
import { mount } from '@vue/test-utils'
24

35
import {
46
formatDate,
57
formatDateTime,
68
formatTime,
79
} from '../../../src/common/formatters/date'
810

9-
import { App, ComponentInternalInstance, getCurrentInstance } from 'vue'
1011
import { createI18n } from 'vue-i18n'
12+
import { h, nextTick } from 'vue'
1113

14+
describe('common/formatters/date', () => {
15+
describe('formatDate', () => {
16+
test('falls back to en-GB', () => {
17+
expect(formatDate(new Date('2024-01-01T12:30:00'))).toMatch(/01\/01\/2024/)
18+
})
1219

13-
vi.mock('vue', async () => {
14-
const actual = await vi.importActual<typeof import('vue')>('vue')
15-
return {
16-
...actual,
17-
getCurrentInstance: vi.fn(),
18-
}
19-
})
20+
test('handles string dates', () => {
21+
expect(formatDate('2024-01-01')).toMatch(/01\/01\/2024/)
22+
})
2023

21-
const mockVue3Instance = (locale: string | { value: string }) => ({
22-
proxy: {
23-
$i18n: { locale },
24-
},
25-
})
24+
test('should detect i18n locale from Vue instance', async () => {
25+
const i18n = createI18n({
26+
legacy: false,
27+
locale: 'en-GB',
28+
fallbackLocale: 'en-GB',
29+
})
2630

27-
describe('common/formatters/date', () => {
28-
const mockDate = new Date('2024-01-01T12:30:00')
31+
const wrapper = mount({
32+
setup: () => () => h('div', [formatDate(new Date('2024-01-01T12:30:00'))]),
33+
}, {
34+
global: { plugins: [i18n] },
35+
})
2936

30-
beforeEach(() => {
31-
vi.clearAllMocks()
32-
})
37+
expect(wrapper.text()).toMatch('01/01/2024')
3338

39+
i18n.global.locale.value = 'ru-RU'
3440

35-
test('should detect i18n locale from Vue instance', () => {
36-
// Create proper i18n instance
37-
const i18n = createI18n({
38-
legacy: false,
39-
locale: 'en-GB',
40-
fallbackLocale: 'ru-RU',
41-
})
41+
await nextTick()
4242

43-
// Create proper component instance mock
44-
const mockInstance = {
45-
appContext: {
46-
app: {
47-
config: {
48-
globalProperties: {
49-
$i18n: i18n.global,
50-
},
51-
},
52-
} as unknown as App,
53-
},
54-
proxy: {
55-
$i18n: i18n.global,
56-
},
57-
} as unknown as ComponentInternalInstance
58-
59-
vi.mocked(getCurrentInstance).mockReturnValue(mockInstance as ComponentInternalInstance)
60-
61-
i18n.global.locale.value = 'en-GB'
62-
expect(formatDateTime(mockDate)).toMatch('01/01/2024, 12:30')
63-
64-
i18n.global.locale.value = 'ru-RU'
65-
expect(formatDateTime(mockDate)).toMatch('01.01.2024, 12:30')
66-
67-
i18n.global.locale.value = 'es-ES'
68-
expect(formatDateTime(mockDate)).toMatch('01/01/2024, 12:30')
69-
})
43+
expect(wrapper.text()).toMatch('01.01.2024')
7044

71-
test('should fallback to en-GB when no i18n instance exists', () => {
72-
vi.mocked(getCurrentInstance).mockReturnValue(null)
73-
74-
const result = formatDateTime(mockDate)
75-
expect(result).toMatch('01/01/2024, 12:30')
76-
})
45+
i18n.global.locale.value = 'es-ES'
7746

78-
test('formatTime uses explicit locale', () => {
79-
expect(formatTime(new Date('2024-01-01T12:30:00'))).toBe('12:30')
47+
await nextTick()
48+
49+
expect(wrapper.text()).toMatch('01/01/2024')
50+
})
8051
})
8152

82-
test('formatDate falls back to en-GB', () => {
83-
expect(formatDate(new Date('2024-01-01T12:30:00'))).toMatch(/01\/01\/2024/)
53+
describe('formatTime', () => {
54+
test('uses explicit locale', () => {
55+
expect(formatTime(new Date('2024-01-01T12:30:00'))).toBe('12:30')
56+
})
8457
})
8558

59+
describe('formatDateTime', () => {
60+
test('falls back to en-GB when no i18n instance exists', () => {
61+
expect(formatDateTime(new Date('2024-01-01T12:30:00'))).toMatch('01/01/2024, 12:30')
62+
})
8663

87-
test('formatDateTime combines date and time', () => {
88-
mockVue3Instance('es-ES')
89-
const result = formatDateTime(new Date('2024-01-01T12:30:00'))
90-
expect(result).toMatch(/01\/01\/2024/)
91-
expect(result).toMatch(/12:30/)
92-
})
64+
test('combines date and time', () => {
65+
const result = formatDateTime(new Date('2024-01-01T12:30:00'))
66+
67+
expect(result).toMatch(/01\/01\/2024/)
68+
expect(result).toMatch(/12:30/)
69+
})
70+
71+
test('should detect i18n locale from Vue instance', async () => {
72+
const i18n = createI18n({
73+
legacy: false,
74+
locale: 'en-GB',
75+
fallbackLocale: 'en-GB',
76+
})
77+
78+
const wrapper = mount({
79+
setup: () => () => h('div', [formatDateTime(new Date('2024-01-01T12:30:00'))]),
80+
}, {
81+
global: { plugins: [i18n] },
82+
})
83+
84+
expect(wrapper.text()).toMatch('01/01/2024, 12:30')
9385

94-
test('handles string dates', () => {
95-
expect(formatDate('2024-01-01')).toMatch(/01\/01\/2024/)
86+
i18n.global.locale.value = 'ru-RU'
87+
88+
await nextTick()
89+
90+
expect(wrapper.text()).toMatch('01.01.2024, 12:30')
91+
92+
i18n.global.locale.value = 'es-ES'
93+
94+
await nextTick()
95+
96+
expect(wrapper.text()).toMatch('01/01/2024, 12:30')
97+
})
9698
})
9799
})

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,7 @@ __metadata:
11671167
"@storybook/vue3-vite": "npm:^8.4.7"
11681168
"@vitejs/plugin-vue": "npm:^5.1.4"
11691169
"@vue/compiler-sfc": "npm:^3.5.12"
1170+
"@vue/test-utils": "npm:^2.4.6"
11701171
"@yandex/ymaps3-types": "npm:^0.0.21"
11711172
date-fns: "npm:^4.1.0"
11721173
less: "npm:^4.2.0"

0 commit comments

Comments
 (0)