merge main

This commit is contained in:
shenlong-tanwen
2025-09-17 16:08:34 +05:30
528 changed files with 17365 additions and 6390 deletions
@@ -30,8 +30,9 @@ void main() {
late SyncStreamService sut;
late SyncStreamRepository mockSyncStreamRepo;
late SyncApiRepository mockSyncApiRepo;
late Function(List<SyncEvent>, Function()) handleEventsCallback;
late Future<void> Function(List<SyncEvent>, Function(), Function()) handleEventsCallback;
late _MockAbortCallbackWrapper mockAbortCallbackWrapper;
late _MockAbortCallbackWrapper mockResetCallbackWrapper;
successHandler(Invocation _) async => true;
@@ -39,6 +40,7 @@ void main() {
mockSyncStreamRepo = MockSyncStreamRepository();
mockSyncApiRepo = MockSyncApiRepository();
mockAbortCallbackWrapper = _MockAbortCallbackWrapper();
mockResetCallbackWrapper = _MockAbortCallbackWrapper();
when(() => mockAbortCallbackWrapper()).thenReturn(false);
@@ -46,6 +48,10 @@ void main() {
handleEventsCallback = invocation.positionalArguments.first;
});
when(() => mockSyncApiRepo.streamChanges(any(), onReset: any(named: 'onReset'))).thenAnswer((invocation) async {
handleEventsCallback = invocation.positionalArguments.first;
});
when(() => mockSyncApiRepo.ack(any())).thenAnswer((_) async => {});
when(() => mockSyncStreamRepo.updateUsersV1(any())).thenAnswer(successHandler);
@@ -86,7 +92,7 @@ void main() {
Future<void> simulateEvents(List<SyncEvent> events) async {
await sut.sync();
await handleEventsCallback(events, mockAbortCallbackWrapper.call);
await handleEventsCallback(events, mockAbortCallbackWrapper.call, mockResetCallbackWrapper.call);
}
group("SyncStreamService - _handleEvents", () {
@@ -156,7 +162,7 @@ void main() {
when(() => cancellationChecker()).thenReturn(true);
});
await handleEventsCallback(events, mockAbortCallbackWrapper.call);
await handleEventsCallback(events, mockAbortCallbackWrapper.call, mockResetCallbackWrapper.call);
verify(() => mockSyncStreamRepo.deleteUsersV1(any())).called(1);
verifyNever(() => mockSyncStreamRepo.updateUsersV1(any()));
@@ -188,7 +194,11 @@ void main() {
final events = [SyncStreamStub.userDeleteV1, SyncStreamStub.userV1Admin, SyncStreamStub.partnerDeleteV1];
final processingFuture = handleEventsCallback(events, mockAbortCallbackWrapper.call);
final processingFuture = handleEventsCallback(
events,
mockAbortCallbackWrapper.call,
mockResetCallbackWrapper.call,
);
await pumpEventQueue();
expect(handler1Started, isTrue);
+4 -1
View File
@@ -12,6 +12,7 @@ import 'schema_v6.dart' as v6;
import 'schema_v7.dart' as v7;
import 'schema_v8.dart' as v8;
import 'schema_v9.dart' as v9;
import 'schema_v10.dart' as v10;
class GeneratedHelper implements SchemaInstantiationHelper {
@override
@@ -35,10 +36,12 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v8.DatabaseAtV8(db);
case 9:
return v9.DatabaseAtV9(db);
case 10:
return v10.DatabaseAtV10(db);
default:
throw MissingSchemaException(version, versions);
}
}
static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9];
static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1,5 +1,4 @@
import 'package:immich_mobile/domain/models/user.model.dart';
import 'package:immich_mobile/domain/models/user_metadata.model.dart';
abstract final class UserStub {
const UserStub._();
@@ -4,12 +4,15 @@ import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:immich_mobile/domain/models/sync_event.model.dart';
import 'package:immich_mobile/domain/services/store.service.dart';
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart';
import 'package:mocktail/mocktail.dart';
import 'package:openapi/api.dart';
import '../../api.mocks.dart';
import '../../service.mocks.dart';
import '../../test_utils.dart';
class MockHttpClient extends Mock implements http.Client {}
@@ -33,6 +36,10 @@ void main() {
late StreamController<List<int>> responseStreamController;
late int testBatchSize = 3;
setUpAll(() async {
await StoreService.init(storeRepository: IsarStoreRepository(await TestUtils.initIsar()));
});
setUp(() {
mockApiService = MockApiService();
mockApiClient = MockApiClient();
@@ -63,7 +70,9 @@ void main() {
}
});
Future<void> streamChanges(Function(List<SyncEvent>, Function() abort) onDataCallback) {
Future<void> streamChanges(
Future<void> Function(List<SyncEvent>, Function() abort, Function() reset) onDataCallback,
) {
return sut.streamChanges(onDataCallback, batchSize: testBatchSize, httpClient: mockHttpClient);
}
@@ -72,7 +81,7 @@ void main() {
bool abortWasCalledInCallback = false;
List<SyncEvent> receivedEventsBatch1 = [];
onDataCallback(List<SyncEvent> events, Function() abort) {
Future<void> onDataCallback(List<SyncEvent> events, Function() abort, Function() _) async {
onDataCallCount++;
if (onDataCallCount == 1) {
receivedEventsBatch1 = events;
@@ -116,7 +125,7 @@ void main() {
int onDataCallCount = 0;
bool abortWasCalledInCallback = false;
onDataCallback(List<SyncEvent> events, Function() abort) {
Future<void> onDataCallback(List<SyncEvent> events, Function() abort, Function() _) async {
onDataCallCount++;
if (onDataCallCount == 1) {
abort();
@@ -158,7 +167,7 @@ void main() {
List<SyncEvent> receivedEventsBatch1 = [];
List<SyncEvent> receivedEventsBatch2 = [];
onDataCallback(List<SyncEvent> events, Function() _) {
Future<void> onDataCallback(List<SyncEvent> events, Function() _, Function() __) async {
onDataCallCount++;
if (onDataCallCount == 1) {
receivedEventsBatch1 = events;
@@ -202,7 +211,7 @@ void main() {
final streamError = Exception("Network Error");
int onDataCallCount = 0;
onDataCallback(List<SyncEvent> events, Function() _) {
Future<void> onDataCallback(List<SyncEvent> events, Function() _, Function() __) async {
onDataCallCount++;
}
@@ -229,8 +238,7 @@ void main() {
when(() => mockStreamedResponse.stream).thenAnswer((_) => http.ByteStream(errorBodyController.stream));
int onDataCallCount = 0;
onDataCallback(List<SyncEvent> events, Function() _) {
Future<void> onDataCallback(List<SyncEvent> events, Function() _, Function() __) async {
onDataCallCount++;
}
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:immich_mobile/utils/throttle.dart';
import 'package:immich_mobile/utils/debug_print.dart';
class _Counter {
int _count = 0;
@@ -8,7 +8,7 @@ class _Counter {
int get count => _count;
void increment() {
debugPrint("Counter inside increment: $count");
dPrint(() => "Counter inside increment: $count");
_count = _count + 1;
}
}
@@ -81,6 +81,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -110,6 +111,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -124,6 +126,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: true,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -141,6 +144,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -156,6 +160,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: true,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -171,6 +176,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -188,6 +194,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -203,6 +210,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -218,6 +226,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: true,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -233,6 +242,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -248,6 +258,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -265,6 +276,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -280,6 +292,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -295,6 +308,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -312,6 +326,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -327,6 +342,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -342,6 +358,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: true,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -359,6 +376,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -374,6 +392,7 @@ void main() {
isTrashEnabled: false,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -391,6 +410,7 @@ void main() {
isTrashEnabled: false,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -406,6 +426,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -423,6 +444,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -440,6 +462,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -457,6 +480,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -472,6 +496,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -489,6 +514,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -506,6 +532,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: album,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -520,6 +547,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -537,6 +565,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: album,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -552,6 +581,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: album,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -567,6 +597,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: album,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -581,12 +612,45 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
expect(ActionButtonType.likeActivity.shouldShow(context), isFalse);
});
});
group('advancedTroubleshooting button', () {
test('should show when in advanced troubleshooting mode', () {
final context = ActionButtonContext(
asset: mergedAsset,
isOwner: true,
isArchived: false,
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: true,
source: ActionSource.timeline,
);
expect(ActionButtonType.advancedInfo.shouldShow(context), isTrue);
});
test('should not show when not in advanced troubleshooting mode', () {
final context = ActionButtonContext(
asset: mergedAsset,
isOwner: true,
isArchived: false,
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
expect(ActionButtonType.advancedInfo.shouldShow(context), isFalse);
});
});
});
group('ActionButtonType.buildButton', () {
@@ -602,6 +666,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
});
@@ -617,6 +682,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: album,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
final widget = buttonType.buildButton(contextWithAlbum);
@@ -639,6 +705,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -658,6 +725,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: album,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -675,6 +743,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -693,6 +762,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);
@@ -705,6 +775,7 @@ void main() {
isTrashEnabled: true,
isInLockedView: false,
currentAlbum: null,
advancedTroubleshooting: false,
source: ActionSource.timeline,
);