Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/components/NcCounterBubble/NcCounterBubble.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,20 @@ const props = withDefaults(defineProps<{
type: '',
})

// Special case: browsers do not shorten numbers in German
// Fallback to English to have 2K instead of 2048
// TODO: what about Italian with the same issue?
let locale = getCanonicalLocale()
if (locale === 'de' || locale === 'de-DE') {
locale = 'en'
}

const humanizedCount = computed(() => {
if (props.raw) {
return props.count.toString()
}

const formatter = new Intl.NumberFormat(getCanonicalLocale(), {
const formatter = new Intl.NumberFormat(locale, {
notation: 'compact',
compactDisplay: 'short',
})
Expand Down
48 changes: 43 additions & 5 deletions tests/unit/components/NcCounterBubble/NcCounterBubble.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,23 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import type { MockedFunction } from 'vitest'

import { getCanonicalLocale } from '@nextcloud/l10n'
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { afterEach, describe, expect, it, vi } from 'vitest'
import NcCounterBubble from '../../../../src/components/NcCounterBubble/NcCounterBubble.vue'

vi.mock('@nextcloud/l10n', async () => {
const actual = await vi.importActual('@nextcloud/l10n')
return {
...actual,
getCanonicalLocale: vi.fn(() => 'en'),
}
})

const getCanonicalLocaleMock = getCanonicalLocale as unknown as MockedFunction<typeof getCanonicalLocale>

describe('NcCounterBubble', () => {
describe('displaying count', () => {
it('should render count from prop', () => {
Expand All @@ -16,10 +29,8 @@ describe('NcCounterBubble', () => {
})

describe('with humanization', () => {
it('should render count 1020 with humanization as "1K"', () => {
const wrapper = mount(NcCounterBubble, { props: { count: 1042 } })
expect(wrapper.text()).toBe('1K')
expect(wrapper.attributes('title')).toBe('1042')
afterEach(() => {
vi.restoreAllMocks()
})

it('should render count 12 without humanization and without title', () => {
Expand All @@ -28,6 +39,33 @@ describe('NcCounterBubble', () => {
expect(wrapper.attributes('title')).toBeUndefined()
})

it('should render count 1042 with humanization as "1K" in English', () => {
const wrapper = mount(NcCounterBubble, { props: { count: 1042 } })
expect(wrapper.text()).toBe('1K')
expect(wrapper.attributes('title')).toBe('1042')
})

it('should render count 12000 with humanization as "1.2万" in Chinese', () => {
getCanonicalLocaleMock.mockReturnValue('zh')
const wrapper = mount(NcCounterBubble, { props: { count: 12_000 } })
expect(wrapper.text()).toBe('1.2万')
expect(wrapper.attributes('title')).toBe('12000')
})

it('should render count 1042 with humanization as "1K" in German', () => {
getCanonicalLocaleMock.mockReturnValue('de')
const wrapper = mount(NcCounterBubble, { props: { count: 1042 } })
expect(wrapper.text()).toBe('1K')
expect(wrapper.attributes('title')).toBe('1042')
})

it('should render count 1042 with humanization as "1042" in Italian', () => {
getCanonicalLocaleMock.mockReturnValue('it')
const wrapper = mount(NcCounterBubble, { props: { count: 1042 } })
expect(wrapper.text()).toBe('1042')
expect(wrapper.attributes('title')).toBeUndefined()
})

it('should not humanize with raw', () => {
const wrapper = mount(NcCounterBubble, { props: { count: 1042, raw: true } })
expect(wrapper.text()).toBe('1042')
Expand Down
Loading