import 'package:flutter_test/flutter_test.dart'; import 'package:userfront/core/i18n/locale_storage_backend.dart'; import 'package:userfront/core/i18n/locale_storage_engine.dart'; import 'package:userfront/core/i18n/locale_storage_policy.dart'; class _FakeTarget implements LocaleStorageTarget { _FakeTarget(); final Map store = {}; bool throwOnRead = false; bool throwOnWrite = false; bool throwOnRemove = false; bool throwOnClear = false; @override String? read(String key) { if (throwOnRead) { throw StateError('read blocked'); } return store[key]; } @override bool write(String key, String value) { if (throwOnWrite) { throw StateError('write blocked'); } store[key] = value; return true; } @override bool remove(String key) { if (throwOnRemove) { throw StateError('remove blocked'); } store.remove(key); return true; } @override void clear() { if (throwOnClear) { throw StateError('clear blocked'); } store.clear(); } } void main() { late _FakeTarget localTarget; late _FakeTarget sessionTarget; late LocaleStorageEngine engine; setUp(() { localTarget = _FakeTarget(); sessionTarget = _FakeTarget(); engine = LocaleStorageEngine( localTarget: localTarget, sessionTarget: sessionTarget, ); engine.clearForTests(); }); test('기본 모드에서는 local 우선으로 저장/조회한다', () { engine.write('ko'); expect(engine.read(), 'ko'); final state = engine.debugStateForTests(); expect(state.localCurrent, 'ko'); expect(state.sessionCurrent, isNull); expect(state.memoryCurrent, isNull); }); test('legacy key를 읽으면 current key로 마이그레이션한다', () { localTarget.store[LocaleStoragePolicy.legacyKey] = 'en'; expect(engine.read(), 'en'); final state = engine.debugStateForTests(); expect(state.localCurrent, 'en'); expect(state.localLegacy, isNull); }); test('localStorage가 차단되면 sessionStorage로 fallback 한다', () { localTarget ..throwOnRead = true ..throwOnWrite = true ..throwOnRemove = true; engine.write('ko'); expect(engine.read(), 'ko'); final state = engine.debugStateForTests(); expect(state.localCurrent, isNull); expect(state.sessionCurrent, 'ko'); expect(state.memoryCurrent, isNull); }); test('local/session 모두 차단되면 memory fallback 한다', () { localTarget ..throwOnRead = true ..throwOnWrite = true ..throwOnRemove = true; sessionTarget ..throwOnRead = true ..throwOnWrite = true ..throwOnRemove = true; engine.write('en'); expect(engine.read(), 'en'); final state = engine.debugStateForTests(); expect(state.localCurrent, isNull); expect(state.sessionCurrent, isNull); expect(state.memoryCurrent, 'en'); }); test('sessionOnly 모드에서는 session + memory만 사용한다', () { engine.setTestMode(LocaleStorageTestMode.sessionOnly); engine.write('ko'); final state = engine.debugStateForTests(); expect(state.localCurrent, isNull); expect(state.sessionCurrent, 'ko'); expect(state.memoryCurrent, isNull); }); test('memoryOnly 모드에서는 memory만 사용한다', () { engine.setTestMode(LocaleStorageTestMode.memoryOnly); engine.write('en'); final state = engine.debugStateForTests(); expect(state.localCurrent, isNull); expect(state.sessionCurrent, isNull); expect(state.memoryCurrent, 'en'); }); }