TF-4233 Fix the response success check to use key presence instead of value nullness.

This commit is contained in:
dab246
2026-01-23 12:06:55 +07:00
committed by Dat H. Pham
parent 6551750bd2
commit 69c3d32e3c
10 changed files with 49 additions and 29 deletions
@@ -5,6 +5,8 @@ import 'package:flutter/material.dart';
class ModalListActionButtonWidget extends StatelessWidget { class ModalListActionButtonWidget extends StatelessWidget {
final String positiveLabel; final String positiveLabel;
final String negativeLabel; final String negativeLabel;
final Key? positiveKey;
final Key? negativeKey;
final VoidCallback onNegativeAction; final VoidCallback onNegativeAction;
final VoidCallback onPositiveAction; final VoidCallback onPositiveAction;
final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? padding;
@@ -18,6 +20,8 @@ class ModalListActionButtonWidget extends StatelessWidget {
required this.onNegativeAction, required this.onNegativeAction,
this.isPositiveActionEnabled = true, this.isPositiveActionEnabled = true,
this.padding, this.padding,
this.positiveKey,
this.negativeKey,
}); });
@override @override
@@ -26,6 +30,7 @@ class ModalListActionButtonWidget extends StatelessWidget {
constraints: const BoxConstraints(minWidth: 67), constraints: const BoxConstraints(minWidth: 67),
height: 48, height: 48,
child: ConfirmDialogButton( child: ConfirmDialogButton(
key: negativeKey,
label: negativeLabel, label: negativeLabel,
onTapAction: onNegativeAction, onTapAction: onNegativeAction,
), ),
@@ -35,6 +40,7 @@ class ModalListActionButtonWidget extends StatelessWidget {
constraints: const BoxConstraints(minWidth: 153), constraints: const BoxConstraints(minWidth: 153),
height: 48, height: 48,
child: ConfirmDialogButton( child: ConfirmDialogButton(
key: positiveKey,
label: positiveLabel, label: positiveLabel,
backgroundColor: isPositiveActionEnabled backgroundColor: isPositiveActionEnabled
? AppColor.primaryMain ? AppColor.primaryMain
@@ -1,8 +1,8 @@
import 'package:core/presentation/views/text/text_field_builder.dart'; import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:tmail_ui_user/features/base/widget/label_input_field_builder.dart'; import 'package:tmail_ui_user/features/base/widget/label_input_field_builder.dart';
import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart';
import 'package:tmail_ui_user/features/labels/presentation/widgets/create_new_label_modal.dart'; import 'package:tmail_ui_user/features/labels/presentation/widgets/create_new_label_modal.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import '../../base/core_robot.dart'; import '../../base/core_robot.dart';
@@ -16,7 +16,11 @@ class CreateLabelModalRobot extends CoreRobot {
.enterText(name); .enterText(name);
} }
Future<void> tapSaveButton() async { Future<void> tapPositiveActionButton(LabelActionType actionType) async {
await $(CreateNewLabelModal).$(AppLocalizations().save).tap(); if (actionType == LabelActionType.create) {
await $(CreateNewLabelModal).$(#create_label_button_action).tap();
} else {
await $(CreateNewLabelModal).$(#save_label_button_action).tap();
}
} }
} }
@@ -1,5 +1,6 @@
import 'package:core/utils/platform_info.dart'; import 'package:core/utils/platform_info.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import '../../base/base_test_scenario.dart'; import '../../base/base_test_scenario.dart';
@@ -40,7 +41,7 @@ class EditATagScenario extends BaseTestScenario
const newLabelName = 'New edit tag 1'; const newLabelName = 'New edit tag 1';
await createLabelModalRobot.enterNewLabelName(newLabelName); await createLabelModalRobot.enterNewLabelName(newLabelName);
await createLabelModalRobot.tapSaveButton(); await createLabelModalRobot.tapPositiveActionButton(LabelActionType.edit);
await _expectLabelWithNewNameUpdated(newLabelName); await _expectLabelWithNewNameUpdated(newLabelName);
} }
@@ -47,10 +47,11 @@ class LabelApi with HandleSetErrorMixin {
SetLabelResponse.deserialize, SetLabelResponse.deserialize,
); );
final labelCreated = response?.created?[generateCreateId]; final labelIdsCreated = response?.created?.keys ?? <Id>[];
if (labelCreated != null) { if (labelIdsCreated.contains(generateCreateId)) {
final newLabelCreated = labelCreated.copyWith( final labelCreated = response?.created?[generateCreateId];
final newLabelCreated = labelCreated!.copyWith(
displayName: labelData.displayName, displayName: labelData.displayName,
color: labelData.color, color: labelData.color,
); );
@@ -83,9 +84,9 @@ class LabelApi with HandleSetErrorMixin {
SetLabelResponse.deserialize, SetLabelResponse.deserialize,
); );
final labelUpdated = response?.updated?[labelId]; final labelIdsUpdated = response?.updated?.keys ?? <Id>[];
if (labelUpdated != null) { if (labelIdsUpdated.contains(labelId)) {
final newLabelUpdated = newLabel.copyWith( final newLabelUpdated = newLabel.copyWith(
id: labelId, id: labelId,
keyword: labelRequest.labelKeyword, keyword: labelRequest.labelKeyword,
@@ -48,7 +48,7 @@ extension HandleLabelActionTypeExtension on LabelController {
labels: labels, labels: labels,
selectedLabel: label, selectedLabel: label,
actionType: LabelActionType.edit, actionType: LabelActionType.edit,
onCreateNewLabelCallback: (newLabel) => onLabelActionCallback: (newLabel) =>
editLabel( editLabel(
accountId: accountId, accountId: accountId,
selectedLabel: label, selectedLabel: label,
@@ -89,7 +89,7 @@ class LabelController extends BaseController with LabelContextMenuMixin {
await DialogRouter().openDialogModal( await DialogRouter().openDialogModal(
child: CreateNewLabelModal( child: CreateNewLabelModal(
labels: labels, labels: labels,
onCreateNewLabelCallback: (label) => _createNewLabel(accountId, label), onLabelActionCallback: (label) => _createNewLabel(accountId, label),
), ),
dialogLabel: 'create-new-label-modal', dialogLabel: 'create-new-label-modal',
); );
@@ -12,6 +12,8 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
mixin LabelContextMenuMixin on PopupContextMenuActionMixin { mixin LabelContextMenuMixin on PopupContextMenuActionMixin {
static const _labelActions = [LabelActionType.edit];
Future<void> _openLabelPopupMenuAction( Future<void> _openLabelPopupMenuAction(
BuildContext context, BuildContext context,
ImagePaths imagePaths, ImagePaths imagePaths,
@@ -19,9 +21,7 @@ mixin LabelContextMenuMixin on PopupContextMenuActionMixin {
RelativeRect position, RelativeRect position,
OnLabelActionTypeCallback onLabelActionTypeCallback, OnLabelActionTypeCallback onLabelActionTypeCallback,
) async { ) async {
final listLabelAction = [LabelActionType.edit]; final popupMenuItems = _labelActions
final popupMenuItems = listLabelAction
.map((actionType) => _buildLabelPopupMenuItem( .map((actionType) => _buildLabelPopupMenuItem(
label, label,
actionType, actionType,
@@ -89,9 +89,7 @@ mixin LabelContextMenuMixin on PopupContextMenuActionMixin {
Label label, Label label,
OnLabelActionTypeCallback onLabelActionTypeCallback, OnLabelActionTypeCallback onLabelActionTypeCallback,
) async { ) async {
final listLabelAction = [LabelActionType.edit]; final contextMenuActions = _labelActions
final contextMenuActions = listLabelAction
.map((actionType) => _buildLabelContextMenuItem( .map((actionType) => _buildLabelContextMenuItem(
actionType, actionType,
AppLocalizations.of(context), AppLocalizations.of(context),
@@ -43,6 +43,15 @@ enum LabelActionType {
} }
} }
Key getModalPositiveActionKey() {
switch (this) {
case LabelActionType.create:
return const Key('create_label_button_action');
case LabelActionType.edit:
return const Key('save_label_button_action');
}
}
String getContextMenuIcon(ImagePaths imagePaths) { String getContextMenuIcon(ImagePaths imagePaths) {
switch (this) { switch (this) {
case LabelActionType.create: case LabelActionType.create:
@@ -25,18 +25,18 @@ import 'package:tmail_ui_user/features/mailbox_creator/presentation/extensions/v
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
typedef OnCreateNewLabelCallback = Function(Label label); typedef OnLabelActionCallback = Function(Label label);
class CreateNewLabelModal extends StatefulWidget { class CreateNewLabelModal extends StatefulWidget {
final List<Label> labels; final List<Label> labels;
final LabelActionType actionType; final LabelActionType actionType;
final OnCreateNewLabelCallback onCreateNewLabelCallback; final OnLabelActionCallback onLabelActionCallback;
final Label? selectedLabel; final Label? selectedLabel;
const CreateNewLabelModal({ const CreateNewLabelModal({
super.key, super.key,
required this.labels, required this.labels,
required this.onCreateNewLabelCallback, required this.onLabelActionCallback,
this.actionType = LabelActionType.create, this.actionType = LabelActionType.create,
this.selectedLabel, this.selectedLabel,
}); });
@@ -182,6 +182,7 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
isPositiveActionEnabled: value, isPositiveActionEnabled: value,
onPositiveAction: _onCreateNewLabel, onPositiveAction: _onCreateNewLabel,
onNegativeAction: _onCloseModal, onNegativeAction: _onCloseModal,
positiveKey: widget.actionType.getModalPositiveActionKey(),
); );
}, },
), ),
@@ -338,7 +339,7 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
? HexColor(_selectedColor!.toHexTriplet()) ? HexColor(_selectedColor!.toHexTriplet())
: null, : null,
); );
widget.onCreateNewLabelCallback(newLabel); widget.onLabelActionCallback(newLabel);
popBack(); popBack();
} }
@@ -16,19 +16,19 @@ extension HandleLabelActionTypeExtension on MailboxDashBoardController {
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
isPopupMenuOpened.value = true; isPopupMenuOpened.value = true;
} }
return labelController try {
.openLabelMenuAction( await labelController.openLabelMenuAction(
context, context,
imagePaths, imagePaths,
label, label,
position: position, position: position,
_onPerformLabelActionType, _onPerformLabelActionType,
) );
.whenComplete(() { } finally {
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
isPopupMenuOpened.value = false; isPopupMenuOpened.value = false;
} }
}); }
} }
void _onPerformLabelActionType(Label label, LabelActionType actionType) { void _onPerformLabelActionType(Label label, LabelActionType actionType) {