mirror of
https://github.com/immich-app/immich.git
synced 2026-02-04 08:49:01 +03:00
fix(mobile): newest/oldest album sort (#20743)
* fix(mobile): newest/oldest album sort * chore: use sqlite to determine album asset timestamps * Fix missing future Co-authored-by: Alex <alex.tran1502@gmail.com> * fix: async handling of sort * chore: tests * chore: code review changes * fix: use created at for newest asset * fix: use localDateTime for sorting * chore: cleanup * chore: use final * feat: loading indicator --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
116
mobile/test/domain/services/album.service_test.dart
Normal file
116
mobile/test/domain/services/album.service_test.dart
Normal file
@@ -0,0 +1,116 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||
import 'package:immich_mobile/domain/services/remote_album.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../infrastructure/repository.mock.dart';
|
||||
|
||||
void main() {
|
||||
late RemoteAlbumService sut;
|
||||
late DriftRemoteAlbumRepository mockRemoteAlbumRepo;
|
||||
late DriftAlbumApiRepository mockAlbumApiRepo;
|
||||
|
||||
setUp(() {
|
||||
mockRemoteAlbumRepo = MockRemoteAlbumRepository();
|
||||
mockAlbumApiRepo = MockDriftAlbumApiRepository();
|
||||
sut = RemoteAlbumService(mockRemoteAlbumRepo, mockAlbumApiRepo);
|
||||
|
||||
when(() => mockRemoteAlbumRepo.getNewestAssetTimestamp(any())).thenAnswer((invocation) {
|
||||
// Simulate a timestamp for the newest asset in the album
|
||||
final albumID = invocation.positionalArguments[0] as String;
|
||||
|
||||
if (albumID == '1') {
|
||||
return Future.value(DateTime(2023, 1, 1));
|
||||
} else if (albumID == '2') {
|
||||
return Future.value(DateTime(2023, 2, 1));
|
||||
}
|
||||
|
||||
return Future.value(DateTime.fromMillisecondsSinceEpoch(0));
|
||||
});
|
||||
|
||||
when(() => mockRemoteAlbumRepo.getOldestAssetTimestamp(any())).thenAnswer((invocation) {
|
||||
// Simulate a timestamp for the oldest asset in the album
|
||||
final albumID = invocation.positionalArguments[0] as String;
|
||||
|
||||
if (albumID == '1') {
|
||||
return Future.value(DateTime(2019, 1, 1));
|
||||
} else if (albumID == '2') {
|
||||
return Future.value(DateTime(2019, 2, 1));
|
||||
}
|
||||
|
||||
return Future.value(DateTime.fromMillisecondsSinceEpoch(0));
|
||||
});
|
||||
});
|
||||
|
||||
final albumA = RemoteAlbum(
|
||||
id: '1',
|
||||
name: 'Album A',
|
||||
description: "",
|
||||
isActivityEnabled: false,
|
||||
order: AlbumAssetOrder.asc,
|
||||
assetCount: 1,
|
||||
createdAt: DateTime(2023, 1, 1),
|
||||
updatedAt: DateTime(2023, 1, 2),
|
||||
ownerId: 'owner1',
|
||||
ownerName: "Test User",
|
||||
);
|
||||
|
||||
final albumB = RemoteAlbum(
|
||||
id: '2',
|
||||
name: 'Album B',
|
||||
description: "",
|
||||
isActivityEnabled: false,
|
||||
order: AlbumAssetOrder.desc,
|
||||
assetCount: 2,
|
||||
createdAt: DateTime(2023, 2, 1),
|
||||
updatedAt: DateTime(2023, 2, 2),
|
||||
ownerId: 'owner2',
|
||||
ownerName: "Test User",
|
||||
);
|
||||
|
||||
group('sortAlbums', () {
|
||||
test('should sort correctly based on name', () async {
|
||||
final albums = [albumB, albumA];
|
||||
|
||||
final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.title);
|
||||
expect(result, [albumA, albumB]);
|
||||
});
|
||||
|
||||
test('should sort correctly based on createdAt', () async {
|
||||
final albums = [albumB, albumA];
|
||||
|
||||
final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.created);
|
||||
expect(result, [albumA, albumB]);
|
||||
});
|
||||
|
||||
test('should sort correctly based on updatedAt', () async {
|
||||
final albums = [albumB, albumA];
|
||||
|
||||
final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.lastModified);
|
||||
expect(result, [albumA, albumB]);
|
||||
});
|
||||
|
||||
test('should sort correctly based on assetCount', () async {
|
||||
final albums = [albumB, albumA];
|
||||
|
||||
final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.assetCount);
|
||||
expect(result, [albumA, albumB]);
|
||||
});
|
||||
|
||||
test('should sort correctly based on newestAssetTimestamp', () async {
|
||||
final albums = [albumB, albumA];
|
||||
|
||||
final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.mostRecent);
|
||||
expect(result, [albumA, albumB]);
|
||||
});
|
||||
|
||||
test('should sort correctly based on oldestAssetTimestamp', () async {
|
||||
final albums = [albumB, albumA];
|
||||
|
||||
final result = await sut.sortAlbums(albums, RemoteAlbumSortMode.mostOldest);
|
||||
expect(result, [albumB, albumA]);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -2,12 +2,14 @@ import 'package:immich_mobile/infrastructure/repositories/device_asset.repositor
|
||||
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';
|
||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/user_api.repository.dart';
|
||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockStoreRepository extends Mock implements IsarStoreRepository {}
|
||||
@@ -22,6 +24,8 @@ class MockSyncStreamRepository extends Mock implements SyncStreamRepository {}
|
||||
|
||||
class MockLocalAlbumRepository extends Mock implements DriftLocalAlbumRepository {}
|
||||
|
||||
class MockRemoteAlbumRepository extends Mock implements DriftRemoteAlbumRepository {}
|
||||
|
||||
class MockLocalAssetRepository extends Mock implements DriftLocalAssetRepository {}
|
||||
|
||||
class MockStorageRepository extends Mock implements StorageRepository {}
|
||||
@@ -30,3 +34,5 @@ class MockStorageRepository extends Mock implements StorageRepository {}
|
||||
class MockUserApiRepository extends Mock implements UserApiRepository {}
|
||||
|
||||
class MockSyncApiRepository extends Mock implements SyncApiRepository {}
|
||||
|
||||
class MockDriftAlbumApiRepository extends Mock implements DriftAlbumApiRepository {}
|
||||
|
||||
Reference in New Issue
Block a user