Skip to content
Merged
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
8 changes: 4 additions & 4 deletions apps/mobile/src/components/feature-flags-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { type FeatureFlagStatus, useFeatureFlagStatuses } from '@/lib/analytics/
* predates the flag's minimum app version. Read-only: flags are controlled in
* PostHog. Renders nothing when `__DEV__` is false.
*
* Each row reads `<value> · <source> · <version relation>`, e.g.
* Each row reads `<value> · <source> · <relation>`, e.g.
* `Enabled · remote · ≥ 1.0.4`: the value the UI acts on, whether it came
* from PostHog or the flag's default, and the gate that decided. The source
* and relation copy is technical notation (see the i18n allowlist); the
* translated part is the value word and the section header.
* from PostHog or the flag's default, and the gate that decided. Every word
* comes from the catalog — the value, the source and the state; only the
* `{{min}}`/`v{{version}}` versions and the `≥`/`<` operators are notation.
*/
function FlagRow({ status }: { status: FeatureFlagStatus }) {
const { t } = useTranslation();
Expand Down
56 changes: 56 additions & 0 deletions apps/mobile/src/i18n/feature-flag-copy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { describe, expect, it } from 'vitest';

import { CATALOG_LOADERS } from './catalogs';
import { SUPPORTED_LANGUAGES, type SupportedLanguage } from './languages';

/**
* The Preferences feature-flag rows name the source and state of the value the
* build acted on: `remote` or `default`, and the version gate. The row prefix
* (`common.enabled`) is translated, but the source and state words shipped as
* English notation in every catalog, so the otherwise Arabic screen read
* `default · not loaded` beside the localized value word.
*
* Key parity only fails when a key is English in EVERY locale, so a single
* catalog left in English passes `catalog-parity.test.ts` and still shows the
* English copy on the device. That is the half this test owns, and it is the
* rule `label-reference.test.ts` already applies to the PR-comment copy. The
* assertions below fire on every catalog that still ships English: a catalog
* that is missing a key resolves to English at runtime, so it fails here too.
*/
const FEATURE_FLAG_COPY_KEYS = [
'preferences.featureFlagApplied',
'preferences.featureFlagSkipped',
'preferences.featureFlagNotLoaded',
] as const;

/** The string a catalog itself ships for a dotted key, or undefined. */
function catalogValue(tag: SupportedLanguage, key: string): string | undefined {
let node: unknown = CATALOG_LOADERS[tag]();
for (const part of key.split('.')) {
if (typeof node !== 'object' || node === null) {
return undefined;
}
node = (node as Record<string, unknown>)[part];
}
return typeof node === 'string' ? node : undefined;
}

describe('feature-flag row copy', () => {
it('defines every key in English', () => {
for (const key of FEATURE_FLAG_COPY_KEYS) {
expect(catalogValue('en', key), `en.json is missing ${key}`).toBeTruthy();
}
});

it.each(SUPPORTED_LANGUAGES.filter(tag => tag !== 'en'))(
'%s ships its own feature-flag copy',
tag => {
for (const key of FEATURE_FLAG_COPY_KEYS) {
const value = catalogValue(tag, key);
expect(value, `${tag} ${key} is missing`).toBeTruthy();
expect(value?.trim(), `${tag} ${key} is empty`).toBeTruthy();
expect(value, `${tag} ${key} is the English copy`).not.toBe(catalogValue('en', key));
}
}
);
});
6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/af.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/am.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/ar.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/az.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/be.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/bg.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/bn.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/bs.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/ca.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/ckb.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/cs.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/cy.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/da.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/de.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/el.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/es.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/et.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apps/mobile/src/i18n/locales/eu.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading