refactor: yeet old timeline (#27666)

* refactor: yank old timeline

# Conflicts:
#	mobile/lib/presentation/pages/editing/drift_edit.page.dart
#	mobile/lib/providers/websocket.provider.dart
#	mobile/lib/routing/router.dart

* more cleanup

* remove native code

* chore: bump sqlite-data version

* remove old background tasks from BGTaskSchedulerPermittedIdentifiers

* rebase

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong
2026-04-15 23:00:27 +05:30
committed by GitHub
parent 6dd6053222
commit 79fccdbee0
367 changed files with 332 additions and 50870 deletions
@@ -1,131 +0,0 @@
import 'package:drift/drift.dart' hide isNull;
import 'package:drift/native.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/store.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
import 'package:immich_mobile/utils/migration.dart';
import 'package:mocktail/mocktail.dart';
import '../../infrastructure/repository.mock.dart';
void main() {
late Drift db;
late SyncStreamRepository mockSyncStreamRepository;
setUpAll(() async {
db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
await StoreService.init(storeRepository: DriftStoreRepository(db));
mockSyncStreamRepository = MockSyncStreamRepository();
when(() => mockSyncStreamRepository.reset()).thenAnswer((_) async => {});
});
tearDown(() async {
await Store.clear();
});
group('handleBetaMigration Tests', () {
group("version < 15", () {
test('already on new timeline', () async {
await Store.put(StoreKey.betaTimeline, true);
await handleBetaMigration(14, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), true);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
test('already on old timeline', () async {
await Store.put(StoreKey.betaTimeline, false);
await handleBetaMigration(14, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.needBetaMigration), true);
});
test('fresh install', () async {
await Store.delete(StoreKey.betaTimeline);
await handleBetaMigration(14, true, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), true);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
});
group("version == 15", () {
test('already on new timeline', () async {
await Store.put(StoreKey.betaTimeline, true);
await handleBetaMigration(15, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), true);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
test('already on old timeline', () async {
await Store.put(StoreKey.betaTimeline, false);
await handleBetaMigration(15, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.needBetaMigration), true);
});
test('fresh install', () async {
await Store.delete(StoreKey.betaTimeline);
await handleBetaMigration(15, true, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), true);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
});
group("version > 15", () {
test('already on new timeline', () async {
await Store.put(StoreKey.betaTimeline, true);
await handleBetaMigration(16, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), true);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
test('already on old timeline', () async {
await Store.put(StoreKey.betaTimeline, false);
await handleBetaMigration(16, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), false);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
test('fresh install', () async {
await Store.delete(StoreKey.betaTimeline);
await handleBetaMigration(16, true, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.betaTimeline), true);
expect(Store.tryGet(StoreKey.needBetaMigration), false);
});
});
});
group('sync reset tests', () {
test('version < 16', () async {
await Store.put(StoreKey.shouldResetSync, false);
await handleBetaMigration(15, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.shouldResetSync), true);
});
test('version >= 16', () async {
await Store.put(StoreKey.shouldResetSync, false);
await handleBetaMigration(16, false, mockSyncStreamRepository);
expect(Store.tryGet(StoreKey.shouldResetSync), false);
});
});
}
@@ -1,46 +0,0 @@
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;
_Counter();
int get count => _count;
void increment() {
dPrint(() => "Counter inside increment: $count");
_count = _count + 1;
}
}
void main() {
test('Executes the method immediately if no calls received previously', () async {
var counter = _Counter();
final throttler = Throttler(interval: const Duration(milliseconds: 300));
throttler.run(() => counter.increment());
expect(counter.count, 1);
});
test('Does not execute calls before throttle interval', () async {
var counter = _Counter();
final throttler = Throttler(interval: const Duration(milliseconds: 100));
throttler.run(() => counter.increment());
throttler.run(() => counter.increment());
throttler.run(() => counter.increment());
throttler.run(() => counter.increment());
throttler.run(() => counter.increment());
await Future.delayed(const Duration(seconds: 1));
expect(counter.count, 1);
});
test('Executes the method if received in intervals', () async {
var counter = _Counter();
final throttler = Throttler(interval: const Duration(milliseconds: 100));
for (final _ in Iterable<int>.generate(10)) {
throttler.run(() => counter.increment());
await Future.delayed(const Duration(milliseconds: 50));
}
await Future.delayed(const Duration(seconds: 1));
expect(counter.count, 5);
});
}
@@ -1,63 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:immich_mobile/domain/models/exif.model.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/utils/thumbnail_utils.dart';
void main() {
final dateTime = DateTime(2025, 04, 25, 12, 13, 14);
final dateTimeString = DateFormat.yMMMMd().format(dateTime);
test('returns description if it has one', () {
final result = getAltText(const ExifInfo(description: 'description'), dateTime, AssetType.image, []);
expect(result, 'description');
});
test('returns image alt text with date if no location', () {
final (template, args) = getAltTextTemplate(const ExifInfo(), dateTime, AssetType.image, []);
expect(template, "image_alt_text_date");
expect(args["isVideo"], "false");
expect(args["date"], dateTimeString);
});
test('returns image alt text with date and place', () {
final (template, args) = getAltTextTemplate(
const ExifInfo(city: 'city', country: 'country'),
dateTime,
AssetType.video,
[],
);
expect(template, "image_alt_text_date_place");
expect(args["isVideo"], "true");
expect(args["date"], dateTimeString);
expect(args["city"], "city");
expect(args["country"], "country");
});
test('returns image alt text with date and some people', () {
final (template, args) = getAltTextTemplate(const ExifInfo(), dateTime, AssetType.image, ["Alice", "Bob"]);
expect(template, "image_alt_text_date_2_people");
expect(args["isVideo"], "false");
expect(args["date"], dateTimeString);
expect(args["person1"], "Alice");
expect(args["person2"], "Bob");
});
test('returns image alt text with date and location and many people', () {
final (template, args) = getAltTextTemplate(
const ExifInfo(city: "city", country: 'country'),
dateTime,
AssetType.video,
["Alice", "Bob", "Carol", "David", "Eve"],
);
expect(template, "image_alt_text_date_place_4_or_more_people");
expect(args["isVideo"], "true");
expect(args["date"], dateTimeString);
expect(args["city"], "city");
expect(args["country"], "country");
expect(args["person1"], "Alice");
expect(args["person2"], "Bob");
expect(args["person3"], "Carol");
expect(args["additionalCount"], "2");
});
}