From 35e275d62255e8cdec4bbcdd50e58911fdb76b56 Mon Sep 17 00:00:00 2001 From: Lukas Grossberger Date: Mon, 13 May 2024 19:13:51 +0200 Subject: [PATCH] test contact repo filter profile --- lib/data/repositories/contacts.dart | 79 ++++++--------- test/data/repositories/contacts_test.dart | 117 ++++++++++++++++++++++ 2 files changed, 147 insertions(+), 49 deletions(-) create mode 100644 test/data/repositories/contacts_test.dart diff --git a/lib/data/repositories/contacts.dart b/lib/data/repositories/contacts.dart index 3169d22..241a5bf 100644 --- a/lib/data/repositories/contacts.dart +++ b/lib/data/repositories/contacts.dart @@ -70,61 +70,42 @@ String contactDetailKey(int i, T detail) { return ''; } +List filterContactDetailsList( + List values, + Map> settings, + List activeCircles, +) { + if (activeCircles.isEmpty) { + return []; + } + final updatedValues = Map.from(values.asMap()) + ..removeWhere((i, e) => !(settings[contactDetailKey(i, e)] + ?.asSet() + .intersectsWith(activeCircles.asSet()) ?? + false)); + return updatedValues.values.asList(); +} + ContactDetails filterDetails(ContactDetails details, ProfileSharingSettings settings, List activeCircles) => ContactDetails( // TODO: filter the names as well displayName: details.displayName, name: details.name, - phones: (details.phones.asMap() - ..removeWhere((i, e) => - (settings.phones[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), - emails: (details.emails.asMap() - ..removeWhere((i, e) => - (settings.emails[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), - addresses: (details.addresses.asMap() - ..removeWhere((i, e) => - (settings.addresses[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), - organizations: (details.organizations.asMap() - ..removeWhere((i, e) => - (settings.organizations[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), - websites: (details.websites.asMap() - ..removeWhere((i, e) => - (settings.websites[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), - socialMedias: (details.socialMedias.asMap() - ..removeWhere((i, e) => - (settings.socialMedias[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), - events: (details.events.asMap() - ..removeWhere((i, e) => - (settings.events[contactDetailKey(i, e)] ?? []) - .asSet() - .intersectsWith(activeCircles.asSet()))) - .values - .asList(), + phones: filterContactDetailsList( + details.phones, settings.phones, activeCircles), + emails: filterContactDetailsList( + details.emails, settings.emails, activeCircles), + addresses: filterContactDetailsList( + details.addresses, settings.addresses, activeCircles), + organizations: filterContactDetailsList( + details.organizations, settings.organizations, activeCircles), + websites: filterContactDetailsList( + details.websites, settings.websites, activeCircles), + socialMedias: filterContactDetailsList( + details.socialMedias, settings.socialMedias, activeCircles), + events: filterContactDetailsList( + details.events, settings.events, activeCircles), ); // TODO: Implement me; but maybe switch for address locations to a similar indexing scheme like with the other details for circles? diff --git a/test/data/repositories/contacts_test.dart b/test/data/repositories/contacts_test.dart new file mode 100644 index 0000000..54b6ce4 --- /dev/null +++ b/test/data/repositories/contacts_test.dart @@ -0,0 +1,117 @@ +// Copyright 2024 The Coagulate Authors. All rights reserved. +// SPDX-License-Identifier: MPL-2.0 + +import 'package:coagulate/data/models/coag_contact.dart'; +import 'package:coagulate/data/models/contact_location.dart'; +import 'package:coagulate/data/models/profile_sharing_settings.dart'; +import 'package:coagulate/data/repositories/contacts.dart'; +import 'package:flutter_contacts/flutter_contacts.dart'; +import 'package:flutter_test/flutter_test.dart'; + +// TODO: Group tests +void main() { + test('contact detail key construction', () { + expect(contactDetailKey(1, Phone('123', label: PhoneLabel.home)), + '1|home'); + expect( + contactDetailKey( + 2, Phone('123', label: PhoneLabel.custom, customLabel: 'CUZTOM')), + '2|CUZTOM'); + expect( + contactDetailKey( + 3, Organization(company: 'corp', title: 'CEO')), + '3|corp'); + }); + + test('filter details list, no active circles', () { + final filtered = filterContactDetailsList([Phone('123')], {}, []); + expect(filtered, []); + }); + + test('filter details list, no allowed circles', () { + final filtered = + filterContactDetailsList([Phone('123')], {}, ['C1', 'C2']); + expect(filtered, []); + }); + + test('filter details list, one allowed circles', () { + final filtered = filterContactDetailsList([ + Phone('123', label: PhoneLabel.home), + Phone('321', label: PhoneLabel.work) + ], { + '1|work': ['C2'] + }, [ + 'C1', + 'C2' + ]); + expect(filtered, [Phone('321', label: PhoneLabel.work)]); + }); + + test('filter details without active circles', () { + final filteredDetails = filterDetails( + ContactDetails( + displayName: 'Display', + name: Name(first: 'first'), + phones: [Phone('1234')], + emails: [Email('hi@mail.com')], + addresses: [Address('Home 123')], + organizations: [Organization(company: 'Corp', title: 'CEO')], + socialMedias: [SocialMedia('@beste')], + websites: [Website('awesome.org')], + events: [Event(month: 1, day: 30)], + ), + const ProfileSharingSettings(), + []); + // TODO: Check that names are also filtered out + expect(filteredDetails.emails, []); + expect(filteredDetails.phones, []); + expect(filteredDetails.addresses, []); + expect(filteredDetails.organizations, []); + expect(filteredDetails.socialMedias, []); + expect(filteredDetails.websites, []); + expect(filteredDetails.events, []); + }); + + test('filter to future events', () { + final contact = CoagContact( + coagContactId: '1', + systemContact: Contact(displayName: 'Contact Name'), + temporaryLocations: [ + ContactTemporaryLocation( + coagContactId: '1', + name: 'past', + details: '', + start: DateTime.now().subtract(Duration(days: 2)), + end: DateTime.now().subtract(Duration(days: 1)), + longitude: 12, + latitude: 13), + ContactTemporaryLocation( + coagContactId: '1', + name: 'less than a day ago', + details: '', + start: DateTime.now().subtract(const Duration(hours: 2)), + end: DateTime.now().subtract(const Duration(hours: 1)), + circles: const ['Circle'], + longitude: 12, + latitude: 13), + ContactTemporaryLocation( + coagContactId: '1', + name: 'future', + details: '', + start: DateTime.now().add(const Duration(days: 1)), + end: DateTime.now().add(const Duration(days: 2)), + circles: const ['Circle'], + longitude: 15, + latitude: 16), + ]); + final filtered = filterAccordingToSharingProfile( + profile: contact, + settings: const ProfileSharingSettings(), + activeCircles: ['Circle'], + shareBackSettings: null); + expect(filtered.temporaryLocations.length, 2); + expect(filtered.temporaryLocations[0].name, 'less than a day ago'); + expect(filtered.temporaryLocations[1].name, 'future'); + expect(filtered.temporaryLocations[1], contact.temporaryLocations[2]); + }); +}