mirror of
https://github.com/immich-app/immich.git
synced 2026-07-28 14:47:30 -07:00
* fix: still part of live photo hidden on bg upload * add foreground tests --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
129 lines
5.4 KiB
Dart
129 lines
5.4 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:drift/drift.dart' hide isNull, isNotNull;
|
|
import 'package:drift/native.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
|
import 'package:immich_mobile/domain/services/store.service.dart';
|
|
import 'package:immich_mobile/entities/store.entity.dart';
|
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
|
import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart';
|
|
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
|
import 'package:immich_mobile/repositories/upload.repository.dart';
|
|
import 'package:immich_mobile/services/foreground_upload.service.dart';
|
|
import 'package:mocktail/mocktail.dart';
|
|
|
|
import '../api.mocks.dart';
|
|
import '../fixtures/asset.stub.dart';
|
|
import '../infrastructure/repository.mock.dart';
|
|
import '../mocks/asset_entity.mock.dart';
|
|
import '../repository.mocks.dart';
|
|
|
|
void main() {
|
|
late ForegroundUploadService sut;
|
|
late MockUploadRepository mockUploadRepository;
|
|
late MockStorageRepository mockStorageRepository;
|
|
late MockDriftBackupRepository mockBackupRepository;
|
|
late MockConnectivityApi mockConnectivityApi;
|
|
late MockAssetMediaRepository mockAssetMediaRepository;
|
|
late Drift db;
|
|
|
|
setUpAll(() async {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
|
|
const MethodChannel('plugins.flutter.io/path_provider'),
|
|
(MethodCall methodCall) async => 'test',
|
|
);
|
|
db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
|
await StoreService.init(storeRepository: DriftStoreRepository(db));
|
|
await SettingsRepository.ensureInitialized(db);
|
|
|
|
await Store.put(StoreKey.serverEndpoint, 'http://demo.immich.app');
|
|
await Store.put(StoreKey.deviceId, 'device-id');
|
|
|
|
registerFallbackValue(File('file'));
|
|
registerFallbackValue(<String, String>{});
|
|
});
|
|
|
|
setUp(() {
|
|
mockUploadRepository = MockUploadRepository();
|
|
mockStorageRepository = MockStorageRepository();
|
|
mockBackupRepository = MockDriftBackupRepository();
|
|
mockConnectivityApi = MockConnectivityApi();
|
|
mockAssetMediaRepository = MockAssetMediaRepository();
|
|
|
|
sut = ForegroundUploadService(
|
|
mockUploadRepository,
|
|
mockStorageRepository,
|
|
mockBackupRepository,
|
|
mockConnectivityApi,
|
|
mockAssetMediaRepository,
|
|
);
|
|
});
|
|
|
|
List<Map<String, String>> captureFields() {
|
|
final captured = <Map<String, String>>[];
|
|
when(
|
|
() => mockUploadRepository.uploadFile(
|
|
file: any(named: 'file'),
|
|
originalFileName: any(named: 'originalFileName'),
|
|
fields: any(named: 'fields'),
|
|
cancelToken: any(named: 'cancelToken'),
|
|
onProgress: any(named: 'onProgress'),
|
|
logContext: any(named: 'logContext'),
|
|
),
|
|
).thenAnswer((invocation) async {
|
|
final fields = invocation.namedArguments[#fields] as Map<String, String>;
|
|
captured.add(Map.of(fields));
|
|
return UploadResult.success(remoteAssetId: 'remote-${captured.length}');
|
|
});
|
|
return captured;
|
|
}
|
|
|
|
group('uploadSingleAsset', () {
|
|
test('should upload the motion part hidden and keep the still image visible', () async {
|
|
final asset = LocalAssetStub.image1;
|
|
final mockEntity = MockAssetEntity();
|
|
final stillFile = File('/path/to/still.heic');
|
|
final videoFile = File('/path/to/motion.mov');
|
|
|
|
when(() => mockEntity.isLivePhoto).thenReturn(true);
|
|
when(() => mockStorageRepository.getAssetEntityForAsset(asset)).thenAnswer((_) async => mockEntity);
|
|
when(() => mockStorageRepository.isAssetAvailableLocally(asset.id)).thenAnswer((_) async => true);
|
|
when(() => mockStorageRepository.getFileForAsset(asset.id)).thenAnswer((_) async => stillFile);
|
|
when(() => mockStorageRepository.getMotionFileForAsset(asset)).thenAnswer((_) async => videoFile);
|
|
when(() => mockAssetMediaRepository.getOriginalFilename(asset.id)).thenAnswer((_) async => 'live.heic');
|
|
|
|
final captured = captureFields();
|
|
|
|
await sut.uploadSingleAsset(asset, null, callbacks: const UploadCallbacks());
|
|
|
|
expect(captured, hasLength(2));
|
|
expect(captured[0]['visibility'], equals('hidden'));
|
|
expect(captured[0].containsKey('livePhotoVideoId'), isFalse);
|
|
expect(captured[1].containsKey('visibility'), isFalse);
|
|
expect(captured[1]['livePhotoVideoId'], equals('remote-1'));
|
|
});
|
|
|
|
test('should not set visibility for a regular photo', () async {
|
|
final asset = LocalAssetStub.image1;
|
|
final mockEntity = MockAssetEntity();
|
|
final stillFile = File('/path/to/photo.jpg');
|
|
|
|
when(() => mockEntity.isLivePhoto).thenReturn(false);
|
|
when(() => mockStorageRepository.getAssetEntityForAsset(asset)).thenAnswer((_) async => mockEntity);
|
|
when(() => mockStorageRepository.isAssetAvailableLocally(asset.id)).thenAnswer((_) async => true);
|
|
when(() => mockStorageRepository.getFileForAsset(asset.id)).thenAnswer((_) async => stillFile);
|
|
when(() => mockAssetMediaRepository.getOriginalFilename(asset.id)).thenAnswer((_) async => 'photo.jpg');
|
|
|
|
final captured = captureFields();
|
|
|
|
await sut.uploadSingleAsset(asset, null, callbacks: const UploadCallbacks());
|
|
|
|
expect(captured, hasLength(1));
|
|
expect(captured[0].containsKey('visibility'), isFalse);
|
|
});
|
|
});
|
|
}
|