fix(vk): persist settings via VK Bridge storage; hide competing sign-in in Mini App hosts
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m28s
CI / conformance (pull_request) Successful in 16s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m6s
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m28s
CI / conformance (pull_request) Successful in 16s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m6s
VK moderation follow-ups. 1. Settings (theme, language, board style, reduce-motion, zoom, first-run coachmark flags) were lost between reloads in VK's desktop iframe: Firefox partitions/blocks IndexedDB and localStorage in a cross-origin iframe, so the browser-local store is empty on every reload (a plain tab / PWA keeps them — first-party storage — and Telegram has its own CloudStorage sync). Mirror the prefs (plus the locale, which has no other durable client home on VK) and the coachmark flags to VK Bridge storage (VKWebAppStorageSet/Get), which travels over postMessage to vk.com and survives; reconcile them on the VK launch before the first paint. The VK identity re-derives from the signed launch params each load, so the values reload onto the same account. 2. Inside a proprietary Mini App host (VK or Telegram) the profile now surfaces only email linking — both the Telegram and VK link/unlink entries are hidden (signInProvidersVisible), so a competing sign-in is never advertised (a platform ToS requirement; VK forbids showing a Telegram login, mirrored in Telegram for VK). A provider linked earlier on the web stays attached and is managed from the web; web/native builds show both. Tests: vkprefs codec + signInProvidersVisible unit tests. Docs: ARCHITECTURE, FUNCTIONAL (+_ru). No schema/wire change.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
VK_ONBOARDING_KEY,
|
||||
VK_PREFS_KEY,
|
||||
decodeVKOnboarding,
|
||||
decodeVKPrefs,
|
||||
encodeVKOnboarding,
|
||||
encodeVKPrefs,
|
||||
} from './vkprefs';
|
||||
|
||||
describe('vkprefs', () => {
|
||||
it('round-trips the synced display prefs', () => {
|
||||
const p = {
|
||||
theme: 'dark',
|
||||
locale: 'ru',
|
||||
reduceMotion: true,
|
||||
boardLabels: 'classic',
|
||||
zoomBoard: false,
|
||||
} as const;
|
||||
expect(decodeVKPrefs(encodeVKPrefs(p))).toEqual(p);
|
||||
});
|
||||
|
||||
it('carries the locale (unlike the Telegram bundle)', () => {
|
||||
const raw = encodeVKPrefs({
|
||||
theme: 'light',
|
||||
locale: 'en',
|
||||
reduceMotion: false,
|
||||
boardLabels: 'none',
|
||||
zoomBoard: true,
|
||||
});
|
||||
expect(raw).toContain('locale');
|
||||
expect(decodeVKPrefs(raw).locale).toBe('en');
|
||||
});
|
||||
|
||||
it('returns an empty partial for missing or malformed prefs input', () => {
|
||||
expect(decodeVKPrefs(null)).toEqual({});
|
||||
expect(decodeVKPrefs(undefined)).toEqual({});
|
||||
expect(decodeVKPrefs('')).toEqual({});
|
||||
expect(decodeVKPrefs('not json')).toEqual({});
|
||||
expect(decodeVKPrefs('[1,2,3]')).toEqual({});
|
||||
});
|
||||
|
||||
it('keeps only valid prefs fields and drops unknown or mistyped ones', () => {
|
||||
const raw = JSON.stringify({
|
||||
theme: 'neon',
|
||||
locale: 'de',
|
||||
reduceMotion: 'yes',
|
||||
boardLabels: 'classic',
|
||||
zoomBoard: 1,
|
||||
extra: true,
|
||||
});
|
||||
expect(decodeVKPrefs(raw)).toEqual({ boardLabels: 'classic' });
|
||||
});
|
||||
|
||||
it('round-trips the onboarding flags', () => {
|
||||
const s = { lobbyDone: true, gameDone: false } as const;
|
||||
expect(decodeVKOnboarding(encodeVKOnboarding(s))).toEqual(s);
|
||||
});
|
||||
|
||||
it('keeps only boolean onboarding flags', () => {
|
||||
expect(decodeVKOnboarding(null)).toEqual({});
|
||||
expect(decodeVKOnboarding(JSON.stringify({ lobbyDone: 1, gameDone: true }))).toEqual({ gameDone: true });
|
||||
});
|
||||
|
||||
it('exposes the VK Bridge storage keys', () => {
|
||||
expect(VK_PREFS_KEY).toBe('prefs');
|
||||
expect(VK_ONBOARDING_KEY).toBe('onboarding');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user