Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Regression] TF-2528 Fix sort by sender name incorrect #3257

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend-docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ services:
- ./mailetcontainer.xml:/root/conf/mailetcontainer.xml
- ./imapserver.xml:/root/conf/imapserver.xml
- ./jmap.properties:/root/conf/jmap.properties
- ../provisioning/integration_test/search_email_with_sort_order/provisioning.sh:/root/conf/integration_test/search_email_with_sort_order/provisioning.sh
- ../provisioning/integration_test/search_email_with_sort_order/eml:/root/conf/integration_test/search_email_with_sort_order/eml
ports:
- "80:80"
environment:
Expand Down
1 change: 1 addition & 0 deletions core/lib/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export 'presentation/extensions/capitalize_extension.dart';
export 'presentation/extensions/list_extensions.dart';
export 'presentation/extensions/list_nullable_extensions.dart';
export 'domain/extensions/datetime_extension.dart';
export 'domain/extensions/list_datetime_extension.dart';
export 'presentation/extensions/html_extension.dart';
export 'presentation/extensions/compare_string_extension.dart';
export 'presentation/extensions/compare_list_extensions.dart';
Expand Down
21 changes: 21 additions & 0 deletions core/lib/domain/extensions/list_datetime_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

extension ListDateTimeExtension on List<DateTime> {

bool isSortedByMostRecent() {
for (int i = 0; i < length - 1; i++) {
if (this[i].isBefore(this[i + 1])) {
return false;
}
}
return true;
}

bool isSortedByOldestFirst() {
for (int i = 0; i < length - 1; i++) {
if (this[i].isAfter(this[i + 1])) {
return false;
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import 'package:pointer_interceptor/pointer_interceptor.dart';
class CupertinoActionSheetBuilder {

final BuildContext _context;
final Key? key;
final List<Widget> _actionTiles = [];

Widget? _titleWidget;
Widget? _messageWidget;
Widget? _cancelWidget;

CupertinoActionSheetBuilder(this._context);
CupertinoActionSheetBuilder(this._context, {this.key});

void title(Widget? titleWidget) {
_titleWidget = titleWidget;
Expand All @@ -35,6 +36,7 @@ class CupertinoActionSheetBuilder {
context: _context,
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
builder: (context) => PointerInterceptor(child: CupertinoActionSheet(
key: key,
title: _titleWidget,
message: _messageWidget,
actions: _actionTiles,
Expand Down
6 changes: 6 additions & 0 deletions integration_test/base/base_scenario.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

abstract class BaseScenario {
Expand All @@ -6,4 +7,9 @@ abstract class BaseScenario {
const BaseScenario(this.$);

Future<void> execute();

Future<void> expectViewVisible(PatrolFinder patrolFinder) async {
await $.waitUntilVisible(patrolFinder);
expect(patrolFinder, findsWidgets);
}
}
6 changes: 0 additions & 6 deletions integration_test/base/core_robot.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

abstract class CoreRobot {
final PatrolIntegrationTester $;

CoreRobot(this.$);

Future<void> ensureViewVisible(PatrolFinder patrolFinder) async {
await $.waitUntilVisible(patrolFinder);
expect(patrolFinder, findsWidgets);
}

dynamic ignoreException() => $.tester.takeException();
}
4 changes: 0 additions & 4 deletions integration_test/robots/composer_robot.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ class ComposerRobot extends CoreRobot {
.tap();
}

Future<void> expectSendEmailSuccessToast() async {
expect($('Message has been sent successfully'), findsOneWidget);
}

Future<void> grantContactPermission() async {
if (await $.native.isPermissionDialogVisible(timeout: const Duration(seconds: 5))) {
await $.native.grantPermissionWhenInUse();
Expand Down
10 changes: 6 additions & 4 deletions integration_test/robots/login_robot.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import 'package:core/presentation/views/text/type_ahead_form_field_builder.dart';
import 'package:flutter/material.dart';
import 'package:patrol/patrol.dart';
import 'package:tmail_ui_user/features/login/domain/model/recent_login_username.dart';
import 'package:tmail_ui_user/features/login/presentation/login_view.dart';
import 'package:tmail_ui_user/features/login/presentation/widgets/login_text_input_builder.dart';
import 'package:tmail_ui_user/features/starting_page/presentation/twake_welcome/twake_welcome_view.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';

import '../base/core_robot.dart';

class LoginRobot extends CoreRobot {
LoginRobot(super.$);

Future<void> expectWelcomeViewVisible() => ensureViewVisible($(TwakeWelcomeView));
Future<void> grantNotificationPermission(NativeAutomator nativeAutomator) async {
if (await nativeAutomator.isPermissionDialogVisible(timeout: const Duration(seconds: 5))) {
await nativeAutomator.grantPermissionWhenInUse();
}
}

Future<void> tapOnUseCompanyServer() async {
await $.pumpAndSettle();
await $(AppLocalizations().useCompanyServer).tap();
}

Future<void> expectLoginViewVisible() => ensureViewVisible($(LoginView));

Future<void> enterEmail(String email) async {
final finder = $(LoginView).$(TextField);
await finder.enterText(email);
Expand Down
30 changes: 30 additions & 0 deletions integration_test/robots/search_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import '../base/core_robot.dart';

class SearchRobot extends CoreRobot {
SearchRobot(super.$);

Future<void> enterQueryString(String queryString) async {
await $(#search_email_text_field).enterText(queryString);
}

Future<void> scrollToEndListSearchFilter() async {
await $.scrollUntilVisible(
finder: $(#mobile_sortBy_search_filter_button),
view: $(#search_filter_list_view),
scrollDirection: AxisDirection.right,
delta: 300,
hoangdat marked this conversation as resolved.
Show resolved Hide resolved
);
}

Future<void> openSortOrderBottomDialog() async {
await $(#mobile_sortBy_search_filter_button).tap();
}

Future<void> selectSortOrder(String sortOrderName) async {
await $(find.text(sortOrderName)).tap();
await $.pump(const Duration(seconds: 2));
}
}
9 changes: 4 additions & 5 deletions integration_test/robots/thread_robot.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import 'package:core/presentation/views/search/search_bar_view.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/widget/compose_floating_button.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';

import '../base/core_robot.dart';

class ThreadRobot extends CoreRobot {
ThreadRobot(super.$);

Future<void> expectThreadViewVisible() => ensureViewVisible($(ThreadView));

Future<void> openComposer() async {
await $(ComposeFloatingButton).$(InkWell).tap();
}

Future<void> expectComposerViewVisible() => ensureViewVisible($(ComposerView));
Future<void> openSearchView() async {
await $(SearchBarView).$(InkWell).tap();
}
}
24 changes: 16 additions & 8 deletions integration_test/scenarios/login_with_basic_auth_scenario.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:tmail_ui_user/features/login/presentation/login_view.dart';
import 'package:tmail_ui_user/features/starting_page/presentation/twake_welcome/twake_welcome_view.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';

import '../base/base_scenario.dart';
import '../robots/login_robot.dart';
import '../robots/thread_robot.dart';
import '../utils/scenario_utils_mixin.dart';

class LoginWithBasicAuthScenario extends BaseScenario with ScenarioUtilsMixin {
class LoginWithBasicAuthScenario extends BaseScenario {
const LoginWithBasicAuthScenario(
super.$,
{
Expand All @@ -22,21 +24,27 @@ class LoginWithBasicAuthScenario extends BaseScenario with ScenarioUtilsMixin {
@override
Future<void> execute() async {
final loginRobot = LoginRobot($);
final threadRobot = ThreadRobot($);

await loginRobot.expectWelcomeViewVisible();
await _expectWelcomeViewVisible();

await loginRobot.tapOnUseCompanyServer();
await _expectLoginViewVisible();

await loginRobot.expectLoginViewVisible();
await loginRobot.enterEmail(username);
await loginRobot.enterHostUrl(hostUrl);

await loginRobot.enterBasicAuthEmail(email);
await loginRobot.enterBasicAuthPassword(password);
await loginRobot.loginBasicAuth();

await grantNotificationPermission($.native);
await loginRobot.grantNotificationPermission($.native);

await threadRobot.expectThreadViewVisible();
await _expectThreadViewVisible();
}

Future<void> _expectWelcomeViewVisible() => expectViewVisible($(TwakeWelcomeView));

Future<void> _expectLoginViewVisible() => expectViewVisible($(LoginView));

Future<void> _expectThreadViewVisible() => expectViewVisible($(ThreadView));
}
Loading
Loading