Skip to content

Commit

Permalink
Merge pull request #235 from ProximaEPFL/test-time-dists
Browse files Browse the repository at this point in the history
Test human readable time and distances values in UI
  • Loading branch information
gruvw authored May 9, 2024
2 parents 570a4e4 + 688736d commit e1dfd3f
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ dependencies:
fake_cloud_firestore: ^2.4.8
geoflutterfire_plus: ^0.0.20
geolocator: ^11.0.0
mockito: ^5.4.4
google_fonts: ^6.2.1
google_maps_flutter: ^2.6.1
flutter_svg: ^2.0.10+1
Expand All @@ -40,6 +39,7 @@ dev_dependencies:
flutter_lints: ^3.0.0
riverpod_lint: ^2.3.9
test: ^1.24.9
mockito: ^5.4.4

flutter:
uses-material-design: true
Expand Down
12 changes: 12 additions & 0 deletions test/mocks/data/post_overview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,15 @@ final List<PostOverview> testPosts = [
distance: 20,
),
];

// Custom post for testing specific date and distances
final timeDistancePost = PostOverview(
postId: const PostIdFirestore(value: "post_1"),
title: "title",
description: "description",
voteScore: 1,
commentNumber: 5,
ownerDisplayName: "owner",
publicationDate: DateTime.utc(1999),
distance: 100,
);
9 changes: 9 additions & 0 deletions test/mocks/overrides/override_human_time.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import "package:proxima/services/human_time_service.dart";

import "../providers/provider_human_time_service.dart";

final humanTimeServiceOverride = [
humanTimeServiceProvider.overrideWith(
(ref) => ref.watch(constantHumanTimeServiceProvider),
),
];
21 changes: 21 additions & 0 deletions test/mocks/providers/provider_human_time_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/services/human_time_service.dart";

final constantTestingTime = DateTime.utc(2000);

CurrentDateTimeCallback constantTimeCallback() {
return () => constantTestingTime;
}

final constantDateTimeCallbackProvider =
Provider<CurrentDateTimeCallback>((ref) {
return constantTimeCallback();
});

final constantHumanTimeServiceProvider = Provider<HumanTimeService>((ref) {
final currentDateTimeCallback = ref.watch(constantDateTimeCallbackProvider);

return HumanTimeService(
currentDateTimeCallback: currentDateTimeCallback,
);
});
20 changes: 20 additions & 0 deletions test/mocks/providers/provider_post_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:proxima/models/database/user/user_id_firestore.dart";
import "package:proxima/models/ui/post_overview.dart";
import "package:proxima/services/database/comment_repository_service.dart";
import "package:proxima/viewmodels/login_view_model.dart";
import "package:proxima/views/navigation/routes.dart";
Expand All @@ -10,6 +11,7 @@ import "../data/post_overview.dart";
import "../overrides/override_comment_view_model.dart";
import "../overrides/override_dynamic_user_avatar_view_model.dart";
import "../overrides/override_firestore.dart";
import "../overrides/override_human_time.dart";
import "../services/mock_comment_repository_service.dart";

// Create a post page with the first post from the testPosts list
Expand Down Expand Up @@ -51,3 +53,21 @@ ProviderScope postPageProvider(
child: postPage,
);
}

ProviderScope customPostOverviewPage(PostOverview post) {
final customPostApp = MaterialApp(
onGenerateRoute: generateRoute,
home: PostPage(
postOverview: post,
),
);

return ProviderScope(
overrides: [
...mockDynamicUserAvatarViewModelTestLoginUserOverride,
...mockEmptyCommentViewModelOverride,
...humanTimeServiceOverride,
],
child: customPostApp,
);
}
118 changes: 118 additions & 0 deletions test/services/human_time_service_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import "package:flutter_test/flutter_test.dart";
import "package:proxima/services/human_time_service.dart";

import "../mocks/providers/provider_human_time_service.dart";

void main() {
group("Human Time Service Unit tests", () {
late HumanTimeService humanTimeService;

setUp(() {
// Setup the `HumanTimeService` for constant time
humanTimeService = HumanTimeService(
currentDateTimeCallback: constantTimeCallback(),
);
});

test("Check correct simple absolute time", () {
// Setup actual values for simple date
final time1 = DateTime.utc(2002);

const expectedSimpleHumanText = "Tuesday, January 1, 2002 00:00";

// Use the service to get human time
final actualSimpleHumanText = humanTimeService.textTimeAbsolute(
time1,
);

// Check that the absolute time value is correct
expect(
actualSimpleHumanText,
expectedSimpleHumanText,
);
});

test("Check correct complex absolute time", () {
// Setup actual values for complex specific date
final time2 = DateTime.utc(
2023,
11,
21,
1,
);

const expectedComplexHumanText = "Tuesday, November 21, 2023 01:00";

// Use the service to get human time
final actualComplexHumanText = humanTimeService.textTimeAbsolute(
time2,
);

// Check that the specific absolute time value is correct
expect(
actualComplexHumanText,
expectedComplexHumanText,
);
});

test("Check special case 'now' relative time", () {
// Setup actual relative values for 'now' case
final closeToNowTime = constantTestingTime.subtract(
const Duration(seconds: 1),
);

const expectedNowRelativeTime = "now";

// Use the service to get relative human time
final actualNowTimeHumanText = humanTimeService.textTimeSince(
closeToNowTime,
);

// Check that the time value is correctly 'now'
expect(
actualNowTimeHumanText,
expectedNowRelativeTime,
);
});

test("Check 10 minutes relative time", () {
// Setup specific time values for 10 min before constant time
final relative10Minutes = constantTestingTime.subtract(
const Duration(minutes: 10),
);

const expectedRelative10Minutes = "10m ago";

// Use the service to get relative human time
final actualMinuteTimeHumanText = humanTimeService.textTimeSince(
relative10Minutes,
);

// Check that the time value is correct for 10 minutes
expect(
actualMinuteTimeHumanText,
expectedRelative10Minutes,
);
});

test("Check 4 days relative time", () {
// Setup specific time values for 4 days before constant time
final relative4Days = constantTestingTime.subtract(
const Duration(days: 4),
);

const expectedRelative4Days = "4d ago";

// Use the service to get relative human time
final actualDaysTimeHumanText = humanTimeService.textTimeSince(
relative4Days,
);

// Check that the time value is correct for 4 days
expect(
actualDaysTimeHumanText,
expectedRelative4Days,
);
});
});
}
93 changes: 93 additions & 0 deletions test/views/pages/post/post_page_values_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import "package:firebase_core/firebase_core.dart";
import "package:flutter/material.dart";
import "package:flutter_test/flutter_test.dart";
import "package:proxima/views/pages/post/post_page_widget/complete_post_widget.dart";

import "../../../mocks/data/post_overview.dart";
import "../../../mocks/providers/provider_post_page.dart";
import "../../../mocks/services/setup_firebase_mocks.dart";

void main() {
setUp(() async {
setupFirebaseAuthMocks();
await Firebase.initializeApp();
});

group("Post Distances and Timing values", () {
testWidgets("Check correct distance on basic post", (tester) async {
await tester.pumpWidget(emptyPostPageProvider);
await tester.pumpAndSettle();

final post = testPosts.first;
final expectedDistanceText = "${post.distance}m away";

// Find post distance value with expected human readable distance
final distanceDisplay = find.text(expectedDistanceText);

// Check that the distance is displayed with correct value
expect(distanceDisplay, findsOneWidget);
});

testWidgets("Check correct distance on custom post", (tester) async {
await tester.pumpWidget(customPostOverviewPage(timeDistancePost));
await tester.pumpAndSettle();

final expectedDistanceText = "${timeDistancePost.distance}m away";

// Find the container for the distance
final appBar = find.byType(AppBar);
// Check that the container is correctly displayed
expect(appBar, findsOneWidget);

// Find the child widget of the appBar (containing the distance)
final actualDistanceDisplayed = find.descendant(
of: appBar,
matching: find.text(expectedDistanceText),
);

// Check that the distance is correctly displayed and with the right value
expect(actualDistanceDisplayed, findsOneWidget);
});

testWidgets("Check correct timing on basic post, special 'now' case",
(tester) async {
await tester.pumpWidget(customPostOverviewPage(testPosts.first));
await tester.pumpAndSettle();

const expectedTimeValue = "now";

// Find the parent of the timing text
final postUserBar = find.byKey(CompletePostWidget.postUserBarKey);
expect(postUserBar, findsOneWidget);

// Find if the parent contains a child with the expected timing text
final actualTimeDisplayed = find.descendant(
of: postUserBar,
matching: find.text(expectedTimeValue),
);

// Check the special case 'now' is correctly handled in UI
expect(actualTimeDisplayed, findsOneWidget);
});

testWidgets("Check correct timing on custom post", (tester) async {
await tester.pumpWidget(customPostOverviewPage(timeDistancePost));
await tester.pumpAndSettle();

const expectedTimeValue = "~1y ago";

// Find the parent of the timing text
final postUserBar = find.byKey(CompletePostWidget.postUserBarKey);
expect(postUserBar, findsOneWidget);

// Find if the parent contains a child with the expected timing text
final actualTimeDisplayed = find.descendant(
of: postUserBar,
matching: find.text(expectedTimeValue),
);

// Check the timing value is correct
expect(actualTimeDisplayed, findsOneWidget);
});
});
}

0 comments on commit e1dfd3f

Please sign in to comment.