mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 00:07:01 +00:00
fix: show how many emails were moved instead of {count}
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// The toasts the email store raises fill every placeholder their catalog text
|
||||
// has. Moving several emails to a folder without a name read
|
||||
// "{count} emails moved": the call passed no count, and the catalog text
|
||||
// (the webmail's notifications.emails_moved) wins over the fallback.
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
vi.mock('expo-localization', () => ({ getLocales: () => [] }));
|
||||
|
||||
import { getDictionary, translate } from '../../i18n';
|
||||
|
||||
const SOURCE = path.resolve(__dirname, '../email-store.ts');
|
||||
|
||||
function flatten(obj: Record<string, unknown>, prefix = '', out = new Map<string, string>()): Map<string, string> {
|
||||
for (const [k, v] of Object.entries(obj)) {
|
||||
const key = prefix ? `${prefix}.${k}` : k;
|
||||
if (v && typeof v === 'object') flatten(v as Record<string, unknown>, key, out);
|
||||
else if (typeof v === 'string') out.set(key, v);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// t('key', 'fallback') closed right after the fallback: no values passed.
|
||||
const CALL_WITHOUT_VALUES = /\bt\(\s*'([^']+)'\s*,\s*('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`[^`]*`)\s*,?\s*\)/g;
|
||||
const PLACEHOLDER = /(?<!\{)\{\s*\w+\s*[,}]/;
|
||||
|
||||
describe('email store toasts', () => {
|
||||
it('pass values for every catalog text with a placeholder', () => {
|
||||
const en = flatten(getDictionary('en') as Record<string, unknown>);
|
||||
const source = fs.readFileSync(SOURCE, 'utf8');
|
||||
const offenders = [...source.matchAll(CALL_WITHOUT_VALUES)]
|
||||
.map((m) => ({ key: m[1], text: en.get(m[1]) }))
|
||||
.filter(({ text }) => !!text && PLACEHOLDER.test(text))
|
||||
.map(({ key, text }) => `${key} = ${text}`);
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
|
||||
it('reads the moved count in the catalog text', () => {
|
||||
expect(translate('en', 'notifications.emails_moved', 'Emails moved', { count: 3 })).toBe('3 emails moved');
|
||||
expect(PLACEHOLDER.test('{count} emails moved')).toBe(true);
|
||||
expect([..."t('notifications.emails_moved', 'Emails moved')".matchAll(CALL_WITHOUT_VALUES)]).toHaveLength(1);
|
||||
expect([..."t('notifications.emails_moved', `${count} emails moved`, { count })".matchAll(CALL_WITHOUT_VALUES)]).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
@@ -2072,7 +2072,9 @@ export const useEmailStore = create<EmailState>()(
|
||||
? (targets.length === 1
|
||||
? t('notifications.moved_to_mailbox', `Email moved to ${targetName}`, { mailbox: targetName })
|
||||
: t('email_list.emails_moved_to', `${targets.length} emails moved to ${targetName}`, { count: targets.length, mailbox: targetName }))
|
||||
: t('notifications.emails_moved', 'Emails moved'),
|
||||
: (targets.length === 1
|
||||
? t('notifications.email_moved', 'Email moved')
|
||||
: t('notifications.emails_moved', `${targets.length} emails moved`, { count: targets.length })),
|
||||
createdAt: Date.now(),
|
||||
accountId: source.accountId,
|
||||
items,
|
||||
@@ -2838,7 +2840,9 @@ async function fileAcrossAccounts(action: SpanningAction, targets: Email[], toMa
|
||||
? (count === 1
|
||||
? t('notifications.moved_to_mailbox', `Email moved to ${targetName}`, { mailbox: targetName })
|
||||
: t('email_list.emails_moved_to', `${count} emails moved to ${targetName}`, { count, mailbox: targetName }))
|
||||
: t('notifications.emails_moved', 'Emails moved');
|
||||
: (count === 1
|
||||
? t('notifications.email_moved', 'Email moved')
|
||||
: t('notifications.emails_moved', `${count} emails moved`, { count }));
|
||||
set({
|
||||
emails: get().emails.filter((e) => !goneKeys.has(rowKeyOf(e))),
|
||||
...(count > 0
|
||||
|
||||
Reference in New Issue
Block a user