From 41560682a1dc06fad540ae57780d5048153f311a Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Sat, 7 Jan 2023 19:03:35 +0100 Subject: [PATCH] fix: Handle roster items staying the same --- packages/moxxmpp/lib/src/roster/roster.dart | 28 +++++++++- packages/moxxmpp/lib/src/roster/state.dart | 9 +++- packages/moxxmpp/test/roster_state_test.dart | 55 ++++++++++++++++++++ 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/packages/moxxmpp/lib/src/roster/roster.dart b/packages/moxxmpp/lib/src/roster/roster.dart index 2bdf3bf..a2ba685 100644 --- a/packages/moxxmpp/lib/src/roster/roster.dart +++ b/packages/moxxmpp/lib/src/roster/roster.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:meta/meta.dart'; import 'package:moxxmpp/src/jid.dart'; import 'package:moxxmpp/src/managers/attributes.dart'; import 'package:moxxmpp/src/managers/base.dart'; @@ -14,13 +15,38 @@ import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/types/result.dart'; +@immutable class XmppRosterItem { - XmppRosterItem({ required this.jid, required this.subscription, this.ask, this.name, this.groups = const [] }); + const XmppRosterItem({ required this.jid, required this.subscription, this.ask, this.name, this.groups = const [] }); final String jid; final String? name; final String subscription; final String? ask; final List groups; + + @override + bool operator==(Object other) { + // TODO(PapaTutuWawa): Implement the groups + return other is XmppRosterItem && + other.jid == jid && + other.name == name && + other.subscription == subscription && + other.ask == ask; /*&& + other.groups == groups;*/ + } + + @override + int get hashCode => jid.hashCode ^ name.hashCode ^ subscription.hashCode ^ ask.hashCode ^ groups.hashCode; + + @override + String toString() { + return 'XmppRosterItem(' + 'jid: $jid, ' + 'name: $name, ' + 'subscription: $subscription, ' + 'ask: $ask, ' + 'groups: $groups)'; + } } enum RosterRemovalResult { diff --git a/packages/moxxmpp/lib/src/roster/state.dart b/packages/moxxmpp/lib/src/roster/state.dart index bc41e3d..95db7ad 100644 --- a/packages/moxxmpp/lib/src/roster/state.dart +++ b/packages/moxxmpp/lib/src/roster/state.dart @@ -114,7 +114,7 @@ abstract class BaseRosterStateManager { null, item, ); - } else { + } else if (_currentRoster![index] != item) { // The item is updated _currentRoster![index] = item; return _RosterProcessTriple( @@ -123,6 +123,13 @@ abstract class BaseRosterStateManager { null, ); } + + // Item has not been modified or added + return const _RosterProcessTriple( + null, + null, + null, + ); } /// Handles a roster push from the RosterManager. diff --git a/packages/moxxmpp/test/roster_state_test.dart b/packages/moxxmpp/test/roster_state_test.dart index 510ca02..ac96123 100644 --- a/packages/moxxmpp/test/roster_state_test.dart +++ b/packages/moxxmpp/test/roster_state_test.dart @@ -95,4 +95,59 @@ void main() { expect(rs.getRosterItems().indexWhere((item) => item.jid == 'testuser2@server2.example') != -1, true); expect(rs.getRosterItems().indexWhere((item) => item.jid == 'testuser3@server3.example') != -1, true); }); + + test('Test a roster fetch if we already have a roster', () async { + XmppEvent? event; + final rs = TestingRosterStateManager('aaaaa', [ + XmppRosterItem( + jid: 'testuser@server.example', + subscription: 'both', + ), + XmppRosterItem( + jid: 'testuser2@server2.example', + subscription: 'to', + ), + XmppRosterItem( + jid: 'testuser3@server3.example', + subscription: 'from', + ), + ]); + rs.register((_event) { + event = _event; + }); + + // Fetch the roster + await rs.handleRosterFetch( + RosterRequestResult( + [ + XmppRosterItem( + jid: 'testuser@server.example', + subscription: 'both', + ), + XmppRosterItem( + jid: 'testuser2@server2.example', + subscription: 'to', + ), + XmppRosterItem( + jid: 'testuser3@server3.example', + subscription: 'both', + ), + XmppRosterItem( + jid: 'testuser4@server4.example', + subscription: 'both', + ), + ], + 'bbbbb', + ), + ); + + expect(event is RosterUpdatedEvent, true); + final updateEvent = event as RosterUpdatedEvent; + + expect(updateEvent.added.length, 1); + expect(updateEvent.added.first.jid, 'testuser4@server4.example'); + expect(updateEvent.modified.length, 1); + expect(updateEvent.modified.first.jid, 'testuser3@server3.example'); + expect(updateEvent.removed.isEmpty, true); + }); }