1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-22 01:47:08 +02:00
immich/mobile/test/modules/activity/activity_provider_test.dart
shenlong af32183728
refactor(mobile): Activities (#5990)
* refactor: autoroutex pushroute

* refactor: autoroutex popRoute

* refactor: autoroutex navigate and replace

* chore: add doc comments for extension methods

* refactor: Add LoggerMixin and refactor Album activities to use mixin

* refactor: Activity page

* chore: activity user from user constructor

* fix: update current asset after build method

* refactor: tests with similar structure as lib

* chore: remove avoid-declaring-call-method rule from dcm analysis

* test: fix proper expect order

* test: activity_statistics_provider_test

* test: activity_provider_test

* test: use proper matchers

* test: activity_text_field_test & dismissible_activity_test added

* test: add http mock to return transparent image

* test: download isar core libs during test

* test: add widget tags to widget test cases

* test: activity_tile_test

* build: currentAlbumProvider to generator

* movie add / remove like to activity input tile

* test: activities_page_test.dart

* chore: better error logs

* chore: dismissibleactivity as statelesswidget

---------

Co-authored-by: shalong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2024-01-04 23:20:55 -06:00

354 lines
10 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/activities/models/activity.model.dart';
import 'package:immich_mobile/modules/activities/providers/activity.provider.dart';
import 'package:immich_mobile/modules/activities/providers/activity_service.provider.dart';
import 'package:immich_mobile/modules/activities/providers/activity_statistics.provider.dart';
import 'package:mocktail/mocktail.dart';
import '../../fixtures/user.stub.dart';
import '../../test_utils.dart';
import 'activity_mocks.dart';
final _activities = [
Activity(
id: '1',
createdAt: DateTime(100),
type: ActivityType.comment,
comment: 'First Activity',
assetId: 'asset-2',
user: UserStub.admin,
),
Activity(
id: '2',
createdAt: DateTime(200),
type: ActivityType.comment,
comment: 'Second Activity',
user: UserStub.user1,
),
Activity(
id: '3',
createdAt: DateTime(300),
type: ActivityType.like,
assetId: 'asset-1',
user: UserStub.admin,
),
Activity(
id: '4',
createdAt: DateTime(400),
type: ActivityType.like,
user: UserStub.user1,
),
];
void main() {
late ActivityServiceMock activityMock;
late ActivityStatisticsMock activityStatisticsMock;
late ProviderContainer container;
late AlbumActivityProvider provider;
late ListenerMock<AsyncValue<List<Activity>>> listener;
setUpAll(() {
registerFallbackValue(AsyncData<List<Activity>>([..._activities]));
});
setUp(() async {
activityMock = ActivityServiceMock();
activityStatisticsMock = ActivityStatisticsMock();
container = TestUtils.createContainer(
overrides: [
activityServiceProvider.overrideWith((ref) => activityMock),
activityStatisticsProvider('test-album', 'test-asset')
.overrideWith(() => activityStatisticsMock),
],
);
// Mock values
when(
() => activityMock.getAllActivities('test-album', assetId: 'test-asset'),
).thenAnswer((_) async => [..._activities]);
// Init and wait for providers future to complete
provider = albumActivityProvider('test-album', 'test-asset');
listener = ListenerMock();
container.listen(
provider,
listener,
fireImmediately: true,
);
await container.read(provider.future);
});
test('Returns a list of activity', () async {
verifyInOrder([
() => listener.call(null, const AsyncLoading()),
() => listener.call(
const AsyncLoading(),
any(
that: allOf(
[
isA<AsyncData<List<Activity>>>(),
predicate(
(AsyncData<List<Activity>> ad) =>
ad.requireValue.every((e) => _activities.contains(e)),
),
],
),
),
),
]);
verifyNoMoreInteractions(listener);
});
group('addLike()', () {
test('Like successfully added', () async {
final like = Activity(
id: '5',
createdAt: DateTime(2023),
type: ActivityType.like,
user: UserStub.admin,
);
when(
() => activityMock.addActivity(
'test-album',
ActivityType.like,
assetId: 'test-asset',
),
).thenAnswer((_) async => AsyncData(like));
await container.read(provider.notifier).addLike();
verify(
() => activityMock.addActivity(
'test-album',
ActivityType.like,
assetId: 'test-asset',
),
);
final activities = await container.read(provider.future);
expect(activities, hasLength(5));
expect(activities, contains(like));
// Never bump activity count for new likes
verifyNever(() => activityStatisticsMock.addActivity());
});
test('Like failed', () async {
final like = Activity(
id: '5',
createdAt: DateTime(2023),
type: ActivityType.like,
user: UserStub.admin,
);
when(
() => activityMock.addActivity(
'test-album',
ActivityType.like,
assetId: 'test-asset',
),
).thenAnswer(
(_) async => AsyncError(Exception('Mock'), StackTrace.current),
);
await container.read(provider.notifier).addLike();
verify(
() => activityMock.addActivity(
'test-album',
ActivityType.like,
assetId: 'test-asset',
),
);
final activities = await container.read(provider.future);
expect(activities, hasLength(4));
expect(activities, isNot(contains(like)));
});
});
group('removeActivity()', () {
test('Like successfully removed', () async {
when(() => activityMock.removeActivity('3'))
.thenAnswer((_) async => true);
await container.read(provider.notifier).removeActivity('3');
verify(
() => activityMock.removeActivity('3'),
);
final activities = await container.read(provider.future);
expect(activities, hasLength(3));
expect(
activities,
isNot(anyElement(predicate((Activity a) => a.id == '3'))),
);
verifyNever(() => activityStatisticsMock.removeActivity());
});
test('Remove Like failed', () async {
when(() => activityMock.removeActivity('3'))
.thenAnswer((_) async => false);
await container.read(provider.notifier).removeActivity('3');
final activities = await container.read(provider.future);
expect(activities, hasLength(4));
expect(
activities,
anyElement(predicate((Activity a) => a.id == '3')),
);
});
test('Comment successfully removed', () async {
when(() => activityMock.removeActivity('1'))
.thenAnswer((_) async => true);
await container.read(provider.notifier).removeActivity('1');
final activities = await container.read(provider.future);
expect(
activities,
isNot(anyElement(predicate((Activity a) => a.id == '1'))),
);
verify(() => activityStatisticsMock.removeActivity());
});
});
group('addComment()', () {
late ActivityStatisticsMock albumActivityStatisticsMock;
setUp(() {
albumActivityStatisticsMock = ActivityStatisticsMock();
container = TestUtils.createContainer(
overrides: [
activityServiceProvider.overrideWith((ref) => activityMock),
activityStatisticsProvider('test-album', 'test-asset')
.overrideWith(() => activityStatisticsMock),
activityStatisticsProvider('test-album')
.overrideWith(() => albumActivityStatisticsMock),
],
);
});
test('Comment successfully added', () async {
final comment = Activity(
id: '5',
createdAt: DateTime(2023),
type: ActivityType.comment,
user: UserStub.admin,
comment: 'Test-Comment',
assetId: 'test-asset',
);
when(
() => activityMock.addActivity(
'test-album',
ActivityType.comment,
assetId: 'test-asset',
comment: 'Test-Comment',
),
).thenAnswer((_) async => AsyncData(comment));
when(() => activityStatisticsMock.build('test-album', 'test-asset'))
.thenReturn(4);
when(() => albumActivityStatisticsMock.build('test-album')).thenReturn(2);
await container.read(provider.notifier).addComment('Test-Comment');
verify(
() => activityMock.addActivity(
'test-album',
ActivityType.comment,
assetId: 'test-asset',
comment: 'Test-Comment',
),
);
final activities = await container.read(provider.future);
expect(activities, hasLength(5));
expect(activities, contains(comment));
verify(() => activityStatisticsMock.addActivity());
verify(() => albumActivityStatisticsMock.addActivity());
});
test('Comment successfully added without assetId', () async {
final comment = Activity(
id: '5',
createdAt: DateTime(2023),
type: ActivityType.comment,
user: UserStub.admin,
assetId: 'test-asset',
comment: 'Test-Comment',
);
when(
() => activityMock.addActivity(
'test-album',
ActivityType.comment,
comment: 'Test-Comment',
),
).thenAnswer((_) async => AsyncData(comment));
when(() => albumActivityStatisticsMock.build('test-album')).thenReturn(2);
when(() => activityMock.getAllActivities('test-album'))
.thenAnswer((_) async => [..._activities]);
final albumProvider = albumActivityProvider('test-album');
await container.read(albumProvider.notifier).addComment('Test-Comment');
verify(
() => activityMock.addActivity(
'test-album',
ActivityType.comment,
assetId: null,
comment: 'Test-Comment',
),
);
final activities = await container.read(albumProvider.future);
expect(activities, hasLength(5));
expect(activities, contains(comment));
verifyNever(() => activityStatisticsMock.addActivity());
verify(() => albumActivityStatisticsMock.addActivity());
});
test('Comment failed', () async {
final comment = Activity(
id: '5',
createdAt: DateTime(2023),
type: ActivityType.comment,
user: UserStub.admin,
comment: 'Test-Comment',
assetId: 'test-asset',
);
when(
() => activityMock.addActivity(
'test-album',
ActivityType.comment,
assetId: 'test-asset',
comment: 'Test-Comment',
),
).thenAnswer(
(_) async => AsyncError(Exception('Error'), StackTrace.current),
);
await container.read(provider.notifier).addComment('Test-Comment');
final activities = await container.read(provider.future);
expect(activities, hasLength(4));
expect(activities, isNot(contains(comment)));
verifyNever(() => activityStatisticsMock.addActivity());
verifyNever(() => albumActivityStatisticsMock.addActivity());
});
});
}