Skip to content

Commit

Permalink
TF-3294 Fix BLUE-BAR mail to attendees duplicated recipients
Browse files Browse the repository at this point in the history
  • Loading branch information
dab246 authored and hoangdat committed Dec 2, 2024
1 parent e59fc1f commit c5b1e87
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action
import 'package:tmail_ui_user/features/email/presentation/bindings/calendar_event_interactor_bindings.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/email_supervisor_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/attachment_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_attendee_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_organizer_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/model/blob_calendar_event.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/email/presentation/model/email_loaded.dart';
Expand Down Expand Up @@ -1853,19 +1855,20 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
}

void handleMailToAttendees(CalendarOrganizer? organizer, List<CalendarAttendee>? attendees) {
final listEmailAddressAttendees = attendees
?.map((attendee) => EmailAddress(attendee.name?.name, attendee.mailto?.mailAddress.value))
.toList() ?? [];
List<EmailAddress> listEmailAddressAttendees = [];

if (organizer != null) {
listEmailAddressAttendees.add(EmailAddress(organizer.name, organizer.mailto?.value));
listEmailAddressAttendees.add(organizer.toEmailAddress());
}

final listEmailAddressMailTo = listEmailAddressAttendees
.where((emailAddress) => emailAddress.emailAddress.isNotEmpty && emailAddress.emailAddress != mailboxDashBoardController.sessionCurrent?.username.value)
.toSet()
.toList();
final listEmailAddress = attendees
?.map((attendee) => attendee.toEmailAddress())
.toList() ?? [];

listEmailAddressAttendees.addAll(listEmailAddress);

final username = mailboxDashBoardController.sessionCurrent?.username.value ?? '';
final listEmailAddressMailTo = listEmailAddressAttendees.removeInvalidEmails(username);
log('SingleEmailController::handleMailToAttendees: listEmailAddressMailTo = $listEmailAddressMailTo');
mailboxDashBoardController.goToComposer(
ComposerArguments.fromMailtoUri(listEmailAddress: listEmailAddressMailTo)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

import 'package:jmap_dart_client/jmap/mail/calendar/properties/attendee/calendar_attendee.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';

extension CalendarAttendeeExtension on CalendarAttendee {
EmailAddress toEmailAddress() {
return EmailAddress(
name?.name,
mailto?.mailAddress.value,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

import 'package:jmap_dart_client/jmap/mail/calendar/properties/calendar_organizer.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';

extension CalendarOrganizerExtension on CalendarOrganizer {
EmailAddress toEmailAddress() {
return EmailAddress(
name,
mailto?.value,
);
}
}
9 changes: 9 additions & 0 deletions model/lib/extensions/list_email_address_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ extension SetEmailAddressExtension on Set<EmailAddress>? {

extension ListEmailAddressExtension on List<EmailAddress> {
Set<String> asSetAddress() => map((emailAddress) => emailAddress.emailAddress).toSet();

List<EmailAddress> removeInvalidEmails(String username) {
final Set<String> seenEmails = {};
return where((email) {
if (email.emailAddress.isEmpty) return false;
if (email.emailAddress == username) return false;
return seenEmails.add(email.emailAddress);
}).toList();
}
}
71 changes: 71 additions & 0 deletions model/test/extensions/list_email_address_extension_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/list_email_address_extension.dart';

void main() {
group('ListEmailAddressExtension::removeInvalidEmails::test', () {
test('SHOULD remove email addresses that are empty', () {
final emails = [
EmailAddress('Alice', '[email protected]'),
EmailAddress('Bob', ''),
EmailAddress('Charlie', '[email protected]'),
];

final validEmails = emails.removeInvalidEmails('[email protected]');

expect(validEmails.length, 2);
expect(validEmails[0].emailAddress, '[email protected]');
expect(validEmails[1].emailAddress, '[email protected]');
});

test('SHOULD remove email addresses that match the provided username', () {
final emails = [
EmailAddress('Alice', '[email protected]'),
EmailAddress('Bob', '[email protected]'),
EmailAddress('Charlie', '[email protected]'),
];

final validEmails = emails.removeInvalidEmails('[email protected]');

expect(validEmails.length, 2);
expect(validEmails[0].emailAddress, '[email protected]');
expect(validEmails[1].emailAddress, '[email protected]');
});

test('SHOULD remove duplicate email addresses, keeping only the first occurrence', () {
final emails = [
EmailAddress('Alice', '[email protected]'),
EmailAddress('Bob', '[email protected]'),
EmailAddress('Charlie', '[email protected]'),
EmailAddress('David', '[email protected]'),
];

final validEmails = emails.removeInvalidEmails('[email protected]');

expect(validEmails.length, 2);
expect(validEmails[0].emailAddress, '[email protected]');
expect(validEmails[1].emailAddress, '[email protected]');
});

test('SHOULD return an empty list if all email addresses are invalid', () {
final emails = [
EmailAddress('Alice', ''),
EmailAddress('Bob', '[email protected]'),
EmailAddress('Charlie', '[email protected]'),
];

final validEmails = emails.removeInvalidEmails('[email protected]');

expect(validEmails.isEmpty, true);
});

test('SHOULD return an empty list for an empty input list', () {
final emails = <EmailAddress>[];

final validEmails = emails.removeInvalidEmails('[email protected]');

expect(validEmails.isEmpty, true);
});
});
}

0 comments on commit c5b1e87

Please sign in to comment.