refactor: app metadata

This commit is contained in:
shenlong-tanwen
2026-04-24 19:23:21 +05:30
parent 8cff5883b5
commit cc56f86333
33 changed files with 14221 additions and 85 deletions
@@ -1,11 +1,12 @@
import 'package:collection/collection.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:immich_mobile/constants/constants.dart';
import 'package:immich_mobile/domain/models/config/log_config.dart';
import 'package:immich_mobile/domain/models/config/system_config.dart';
import 'package:immich_mobile/domain/models/log.model.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/domain/models/metadata_kind.dart';
import 'package:immich_mobile/domain/services/log.service.dart';
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
import 'package:logging/logging.dart';
import 'package:mocktail/mocktail.dart';
@@ -29,21 +30,26 @@ final _kWarnLog = LogMessage(
void main() {
late LogService sut;
late LogRepository mockLogRepo;
late DriftStoreRepository mockStoreRepo;
late MockCachedMetadataRepository mockMetadataRepository;
setUp(() async {
mockLogRepo = MockLogRepository();
mockStoreRepo = MockDriftStoreRepository();
mockMetadataRepository = MockCachedMetadataRepository();
registerFallbackValue(_kInfoLog);
SystemConfig identityMutator(SystemConfig c) => c;
registerFallbackValue(identityMutator);
when(() => mockLogRepo.truncate(limit: any(named: 'limit'))).thenAnswer((_) async => {});
when(() => mockStoreRepo.tryGet<int>(StoreKey.logLevel)).thenAnswer((_) async => LogLevel.fine.index);
when(
() => mockMetadataRepository.read(MetadataKind.systemConfig),
).thenReturn(const SystemConfig(log: LogConfig(level: LogLevel.fine)));
when(() => mockMetadataRepository.update<SystemConfig>(MetadataKind.systemConfig, any())).thenAnswer((_) async {});
when(() => mockLogRepo.getAll()).thenAnswer((_) async => []);
when(() => mockLogRepo.insert(any())).thenAnswer((_) async => true);
when(() => mockLogRepo.insertAll(any())).thenAnswer((_) async => true);
sut = await LogService.create(logRepository: mockLogRepo, storeRepository: mockStoreRepo);
sut = await LogService.create(logRepository: mockLogRepo, metadataRepository: mockMetadataRepository);
});
tearDown(() async {
@@ -56,21 +62,25 @@ void main() {
expect(limit, kLogTruncateLimit);
});
test('Sets log level based on the store setting', () {
verify(() => mockStoreRepo.tryGet<int>(StoreKey.logLevel)).called(1);
test('Sets log level based on the metadata repository', () {
verify(() => mockMetadataRepository.read(MetadataKind.systemConfig)).called(1);
expect(Logger.root.level, Level.FINE);
});
});
group("Log Service Set Level:", () {
setUp(() async {
when(() => mockStoreRepo.upsert<int>(StoreKey.logLevel, any())).thenAnswer((_) async => true);
await sut.setLogLevel(LogLevel.shout);
});
test('Updates the log level in store', () {
final index = verify(() => mockStoreRepo.upsert<int>(StoreKey.logLevel, captureAny())).captured.firstOrNull;
expect(index, LogLevel.shout.index);
test('Updates the log level via metadata repository', () {
final mutator =
verify(
() => mockMetadataRepository.update<SystemConfig>(MetadataKind.systemConfig, captureAny()),
).captured.firstOrNull
as SystemConfig Function(SystemConfig)?;
final result = mutator?.call(const SystemConfig());
expect(result?.log.level, LogLevel.shout);
});
test('Sets log level on logger', () {
@@ -81,7 +91,11 @@ void main() {
group("Log Service Buffer:", () {
test('Buffers logs until timer elapses', () {
TestUtils.fakeAsync((time) async {
sut = await LogService.create(logRepository: mockLogRepo, storeRepository: mockStoreRepo, shouldBuffer: true);
sut = await LogService.create(
logRepository: mockLogRepo,
metadataRepository: mockMetadataRepository,
shouldBuffer: true,
);
final logger = Logger(_kInfoLog.logger!);
logger.info(_kInfoLog.message);
@@ -95,7 +109,11 @@ void main() {
test('Batch inserts all logs on timer', () {
TestUtils.fakeAsync((time) async {
sut = await LogService.create(logRepository: mockLogRepo, storeRepository: mockStoreRepo, shouldBuffer: true);
sut = await LogService.create(
logRepository: mockLogRepo,
metadataRepository: mockMetadataRepository,
shouldBuffer: true,
);
final logger = Logger(_kInfoLog.logger!);
logger.info(_kInfoLog.message);
@@ -112,7 +130,11 @@ void main() {
test('Does not buffer when off', () {
TestUtils.fakeAsync((time) async {
sut = await LogService.create(logRepository: mockLogRepo, storeRepository: mockStoreRepo, shouldBuffer: false);
sut = await LogService.create(
logRepository: mockLogRepo,
metadataRepository: mockMetadataRepository,
shouldBuffer: false,
);
final logger = Logger(_kInfoLog.logger!);
logger.info(_kInfoLog.message);
@@ -142,7 +164,11 @@ void main() {
test('Combines result from both DB + Buffer', () {
TestUtils.fakeAsync((time) async {
sut = await LogService.create(logRepository: mockLogRepo, storeRepository: mockStoreRepo, shouldBuffer: true);
sut = await LogService.create(
logRepository: mockLogRepo,
metadataRepository: mockMetadataRepository,
shouldBuffer: true,
);
final logger = Logger(_kWarnLog.logger!);
logger.warning(_kWarnLog.message);
+4
View File
@@ -28,6 +28,7 @@ import 'schema_v21.dart' as v21;
import 'schema_v22.dart' as v22;
import 'schema_v23.dart' as v23;
import 'schema_v24.dart' as v24;
import 'schema_v25.dart' as v25;
class GeneratedHelper implements SchemaInstantiationHelper {
@override
@@ -81,6 +82,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v23.DatabaseAtV23(db);
case 24:
return v24.DatabaseAtV24(db);
case 25:
return v25.DatabaseAtV25(db);
default:
throw MissingSchemaException(version, versions);
}
@@ -111,5 +114,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
22,
23,
24,
25,
];
}
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,5 @@
import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/cached_metadata.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
@@ -17,6 +18,8 @@ import 'package:mocktail/mocktail.dart';
class MockDriftStoreRepository extends Mock implements DriftStoreRepository {}
class MockCachedMetadataRepository extends Mock implements CachedMetadataRepository {}
class MockLogRepository extends Mock implements LogRepository {}
class MockSyncStreamRepository extends Mock implements SyncStreamRepository {}
@@ -12,6 +12,7 @@ import 'package:mocktail/mocktail.dart';
import 'package:openapi/api.dart';
import '../domain/service.mock.dart';
import '../infrastructure/repository.mock.dart';
import '../repository.mocks.dart';
import '../service.mocks.dart';
@@ -23,6 +24,7 @@ void main() {
late MockNetworkService networkService;
late MockBackgroundSyncManager backgroundSyncManager;
late MockAppSettingService appSettingsService;
late MockCachedMetadataRepository metadataRepository;
late Drift db;
setUp(() async {
@@ -32,6 +34,7 @@ void main() {
networkService = MockNetworkService();
backgroundSyncManager = MockBackgroundSyncManager();
appSettingsService = MockAppSettingService();
metadataRepository = MockCachedMetadataRepository();
sut = AuthService(
authApiRepository,
@@ -40,6 +43,7 @@ void main() {
networkService,
backgroundSyncManager,
appSettingsService,
metadataRepository,
);
registerFallbackValue(Uri());