mirror of
https://github.com/immich-app/immich
synced 2026-08-22 13:13:05 +00:00
simplify the created date pick and rework the migration test
This commit is contained in:
parent
bce12f43e7
commit
849a4886f7
3 changed files with 44 additions and 90 deletions
|
|
@ -176,15 +176,11 @@ open class NativeSyncApiImplBase(context: Context) : ImmichPlugin(), ActivityAwa
|
|||
else -> 0L
|
||||
}
|
||||
// Date taken is in ms; added/modified are in seconds, and modified can be 0 when unset.
|
||||
// No-EXIF assets use the earliest positive added/modified date, or raw added if neither is positive.
|
||||
// If EXIF date taken exists use it, else if modified is empty use added, else the earliest of the two.
|
||||
val modifiedAt = c.getLong(dateModifiedColumn)
|
||||
val addedAt = c.getLong(dateAddedColumn)
|
||||
val createdAt = (c.getLong(dateTakenColumn).takeIf { it > 0 }?.div(1000))
|
||||
?: when {
|
||||
modifiedAt <= 0 -> addedAt
|
||||
addedAt <= 0 -> modifiedAt
|
||||
else -> minOf(modifiedAt, addedAt)
|
||||
}
|
||||
?: if (modifiedAt <= 0) addedAt else minOf(modifiedAt, addedAt)
|
||||
val width = c.getInt(widthColumn).toLong()
|
||||
val height = c.getInt(heightColumn).toLong()
|
||||
// Duration is milliseconds
|
||||
|
|
|
|||
|
|
@ -313,6 +313,7 @@ class MediumRepositoryContext {
|
|||
TrashOrigin? source,
|
||||
AssetType? type,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
bool? isFavorite,
|
||||
}) async {
|
||||
id ??= TestUtils.uuid();
|
||||
|
|
@ -328,6 +329,7 @@ class MediumRepositoryContext {
|
|||
source: .new(source ?? TrashOrigin.remoteSync),
|
||||
isFavorite: .new(isFavorite ?? false),
|
||||
createdAt: .new(TestUtils.date(createdAt)),
|
||||
updatedAt: .new(TestUtils.date(updatedAt)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +1,49 @@
|
|||
import 'package:drift/drift.dart' as drift;
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.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/entities/local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||
import 'package:immich_mobile/utils/migration.dart';
|
||||
|
||||
import '../../medium/repository_context.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
late Drift db;
|
||||
late DriftStoreRepository storeRepository;
|
||||
late MediumRepositoryContext ctx;
|
||||
|
||||
setUpAll(() async {
|
||||
debugDefaultTargetPlatformOverride = TargetPlatform.android;
|
||||
db = Drift(drift.DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||
storeRepository = DriftStoreRepository(db);
|
||||
await StoreService.init(storeRepository: storeRepository, listenUpdates: false);
|
||||
ctx = MediumRepositoryContext();
|
||||
await StoreService.init(storeRepository: DriftStoreRepository(ctx.db), listenUpdates: false);
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await Store.clear();
|
||||
await db.delete(db.localAssetEntity).go();
|
||||
await db.delete(db.trashedLocalAssetEntity).go();
|
||||
await db.customStatement('DROP TRIGGER IF EXISTS fail_migration');
|
||||
await ctx.db.delete(ctx.db.localAssetEntity).go();
|
||||
await ctx.db.delete(ctx.db.trashedLocalAssetEntity).go();
|
||||
await ctx.db.customStatement('DROP TRIGGER IF EXISTS fail_migration');
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
debugDefaultTargetPlatformOverride = null;
|
||||
await Store.clear();
|
||||
await db.close();
|
||||
await ctx.dispose();
|
||||
});
|
||||
|
||||
test('stores version 26 when migration 27 fails', () async {
|
||||
await Store.put(StoreKey.version, 25);
|
||||
await db
|
||||
.into(db.localAssetEntity)
|
||||
.insert(
|
||||
LocalAssetEntityCompanion.insert(
|
||||
id: 'asset',
|
||||
name: 'asset.jpg',
|
||||
type: AssetType.image,
|
||||
createdAt: drift.Value(DateTime(2026)),
|
||||
updatedAt: drift.Value(DateTime(2025)),
|
||||
),
|
||||
);
|
||||
await db.customStatement(
|
||||
await ctx.newLocalAsset(id: 'asset', createdAt: DateTime(2026), updatedAt: DateTime(2025));
|
||||
await ctx.db.customStatement(
|
||||
"CREATE TRIGGER fail_migration BEFORE UPDATE OF created_at ON local_asset_entity "
|
||||
"BEGIN SELECT RAISE(FAIL, 'migration failed'); END",
|
||||
);
|
||||
|
||||
await migrateDatabaseIfNeeded(db);
|
||||
await migrateDatabaseIfNeeded(ctx.db);
|
||||
|
||||
expect(await storeRepository.tryGet(StoreKey.version), 26);
|
||||
expect(Store.tryGet(StoreKey.version), 26);
|
||||
});
|
||||
|
||||
test('fixes dates in active and trashed assets', () async {
|
||||
|
|
@ -67,67 +51,39 @@ void main() {
|
|||
final updatedAt = DateTime(2025);
|
||||
final epoch = DateTime.fromMillisecondsSinceEpoch(0);
|
||||
await Store.put(StoreKey.version, 26);
|
||||
await db
|
||||
.into(db.localAssetEntity)
|
||||
.insert(
|
||||
LocalAssetEntityCompanion.insert(
|
||||
id: 'local',
|
||||
name: 'local.jpg',
|
||||
type: AssetType.image,
|
||||
createdAt: drift.Value(createdAt),
|
||||
updatedAt: drift.Value(updatedAt),
|
||||
),
|
||||
);
|
||||
await db
|
||||
.into(db.localAssetEntity)
|
||||
.insert(
|
||||
LocalAssetEntityCompanion.insert(
|
||||
id: 'epoch',
|
||||
name: 'epoch.jpg',
|
||||
type: AssetType.image,
|
||||
createdAt: drift.Value(createdAt),
|
||||
updatedAt: drift.Value(epoch),
|
||||
),
|
||||
);
|
||||
await db
|
||||
.into(db.trashedLocalAssetEntity)
|
||||
.insert(
|
||||
TrashedLocalAssetEntityCompanion.insert(
|
||||
id: 'trashed',
|
||||
albumId: 'album',
|
||||
name: 'trashed.jpg',
|
||||
type: AssetType.image,
|
||||
createdAt: drift.Value(createdAt),
|
||||
updatedAt: drift.Value(updatedAt),
|
||||
source: TrashOrigin.localSync,
|
||||
),
|
||||
);
|
||||
await db
|
||||
.into(db.trashedLocalAssetEntity)
|
||||
.insert(
|
||||
TrashedLocalAssetEntityCompanion.insert(
|
||||
id: 'trashed-epoch',
|
||||
albumId: 'album',
|
||||
name: 'trashed-epoch.jpg',
|
||||
type: AssetType.image,
|
||||
createdAt: drift.Value(createdAt),
|
||||
updatedAt: drift.Value(epoch),
|
||||
source: TrashOrigin.localSync,
|
||||
),
|
||||
);
|
||||
await ctx.newLocalAsset(id: 'local', createdAt: createdAt, updatedAt: updatedAt);
|
||||
await ctx.newLocalAsset(id: 'epoch', createdAt: createdAt, updatedAt: epoch);
|
||||
await ctx.newTrashedLocalAsset(
|
||||
id: 'trashed',
|
||||
albumId: 'album',
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
source: TrashOrigin.localSync,
|
||||
);
|
||||
await ctx.newTrashedLocalAsset(
|
||||
id: 'trashed-epoch',
|
||||
albumId: 'album',
|
||||
createdAt: createdAt,
|
||||
updatedAt: epoch,
|
||||
source: TrashOrigin.localSync,
|
||||
);
|
||||
|
||||
await migrateDatabaseIfNeeded(db);
|
||||
await migrateDatabaseIfNeeded(ctx.db);
|
||||
|
||||
final local = await (db.select(db.localAssetEntity)..where((row) => row.id.equals('local'))).getSingle();
|
||||
final unchanged = await (db.select(db.localAssetEntity)..where((row) => row.id.equals('epoch'))).getSingle();
|
||||
final trashed = await (db.select(db.trashedLocalAssetEntity)..where((row) => row.id.equals('trashed'))).getSingle();
|
||||
final trashedUnchanged = await (db.select(
|
||||
db.trashedLocalAssetEntity,
|
||||
final local = await (ctx.db.select(ctx.db.localAssetEntity)..where((row) => row.id.equals('local'))).getSingle();
|
||||
final unchanged = await (ctx.db.select(
|
||||
ctx.db.localAssetEntity,
|
||||
)..where((row) => row.id.equals('epoch'))).getSingle();
|
||||
final trashed = await (ctx.db.select(
|
||||
ctx.db.trashedLocalAssetEntity,
|
||||
)..where((row) => row.id.equals('trashed'))).getSingle();
|
||||
final trashedUnchanged = await (ctx.db.select(
|
||||
ctx.db.trashedLocalAssetEntity,
|
||||
)..where((row) => row.id.equals('trashed-epoch'))).getSingle();
|
||||
expect(local.createdAt, updatedAt);
|
||||
expect(unchanged.createdAt, createdAt);
|
||||
expect(trashed.createdAt, updatedAt);
|
||||
expect(trashedUnchanged.createdAt, createdAt);
|
||||
expect(await storeRepository.tryGet(StoreKey.version), 27);
|
||||
expect(Store.tryGet(StoreKey.version), 27);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue