fix(style): Fix style issues

This commit is contained in:
PapaTutuWawa 2023-09-29 20:46:14 +02:00
parent edf1d0b257
commit 0a68f09fb4
4 changed files with 58 additions and 20 deletions

View File

@ -3,8 +3,12 @@ import 'package:moxxmpp/src/stringxml.dart';
import 'package:synchronized/synchronized.dart';
/// (JID we sent a stanza to, the id of the sent stanza, the tag of the sent stanza).
// ignore: avoid_private_typedef_functions
typedef _StanzaCompositeKey = (String?, String, String);
/// Callback function that returns the bare JID of the connection as a String.
typedef GetBareJidCallback = String Function();
/// This class handles the await semantics for stanzas. Stanzas are given a "unique"
/// key equal to the tuple (to, id, tag) with which their response is identified.
///
@ -14,6 +18,10 @@ typedef _StanzaCompositeKey = (String?, String, String);
///
/// This class also handles some "edge cases" of RFC 6120, like an empty "from" attribute.
class StanzaAwaiter {
StanzaAwaiter(this._bareJidCallback);
final GetBareJidCallback _bareJidCallback;
/// The pending stanzas, identified by their surrogate key.
final Map<_StanzaCompositeKey, Completer<XMLNode>> _pending = {};
@ -27,9 +35,12 @@ class StanzaAwaiter {
///
/// Returns a future that might resolve to the response to the stanza.
Future<Future<XMLNode>> addPending(String? to, String id, String tag) async {
// Check if we want to send a stanza to our bare JID and replace it with null.
final processedTo = to != null && to == _bareJidCallback() ? null : to;
final completer = await _lock.synchronized(() {
final completer = Completer<XMLNode>();
_pending[(to, id, tag)] = completer;
_pending[(processedTo, id, tag)] = completer;
return completer;
});
@ -43,8 +54,13 @@ class StanzaAwaiter {
final id = stanza.attributes['id'] as String?;
if (id == null) return false;
// Check if we want to send a stanza to our bare JID and replace it with null.
final from = stanza.attributes['from'] as String?;
final processedFrom =
from != null && from == _bareJidCallback() ? null : from;
final key = (
stanza.attributes['from'] as String?,
processedFrom,
id,
stanza.tag,
);

View File

@ -90,6 +90,9 @@ class XmppConnection {
},
);
_stanzaAwaiter = StanzaAwaiter(
() => connectionSettings.jid.toBare().toString(),
);
_incomingStanzaQueue = IncomingStanzaQueue(handleXmlStream, _stanzaAwaiter);
_socketStream = _socket.getDataStream();
// TODO(Unknown): Handle on done
@ -125,7 +128,7 @@ class XmppConnection {
final ConnectivityManager _connectivityManager;
/// A helper for handling await semantics with stanzas
final StanzaAwaiter _stanzaAwaiter = StanzaAwaiter();
late final StanzaAwaiter _stanzaAwaiter;
/// Sorted list of handlers that we call or incoming and outgoing stanzas
final List<_StanzaHandlerWrapper> _incomingStanzaHandlers =
@ -531,15 +534,12 @@ class XmppConnection {
_log.finest('==> $prefix${newStanza.toXml()}');
if (details.awaitable) {
final isOwnJid =
data.stanza.to == connectionSettings.jid.toBare().toString();
await _stanzaAwaiter
.addPending(
// A stanza with no to attribute is for direct processing by the server. As such,
// we can correlate it by just *assuming* we have that attribute
// (RFC 6120 Section 8.1.1.1)
isOwnJid ? null : data.stanza.to,
data.stanza.to,
data.stanza.id!,
data.stanza.tag,
)
@ -774,15 +774,8 @@ class XmppConnection {
return;
}
// In case the stanza came from our own bare Jid, remove it so that the stanza
// awaiter works correctly.
final isOwnJid = incomingPreHandlers.stanza.from ==
connectionSettings.jid.toBare().toString();
final ownJidStanza = isOwnJid
? incomingPreHandlers.stanza.copyWith(from: null)
: incomingPreHandlers.stanza;
final awaited = await _stanzaAwaiter.onData(
ownJidStanza,
incomingPreHandlers.stanza,
);
if (awaited) {
return;

View File

@ -92,7 +92,6 @@ class IncomingStanzaQueue {
}
object as XMPPStreamElement;
// TODO: Check the from attribute to ensure that it is matched correctly.
return _stanzaAwaiter.isAwaited(object.node);
}
}

View File

@ -2,9 +2,12 @@ import 'package:moxxmpp/moxxmpp.dart';
import 'package:moxxmpp/src/awaiter.dart';
import 'package:test/test.dart';
const bareJid = 'user4@example.org';
String getBareJidCallback() => bareJid;
void main() {
test('Test awaiting an awaited stanza with a from attribute', () async {
final awaiter = StanzaAwaiter();
final awaiter = StanzaAwaiter(getBareJidCallback);
// "Send" a stanza
final future = await awaiter.addPending(
@ -39,7 +42,7 @@ void main() {
});
test('Test awaiting an awaited stanza without a from attribute', () async {
final awaiter = StanzaAwaiter();
final awaiter = StanzaAwaiter(getBareJidCallback);
// "Send" a stanza
final future = await awaiter.addPending(null, 'abc123', 'iq');
@ -60,7 +63,7 @@ void main() {
});
test('Test awaiting a stanza that was already awaited', () async {
final awaiter = StanzaAwaiter();
final awaiter = StanzaAwaiter(getBareJidCallback);
// "Send" a stanza
final future = await awaiter.addPending(null, 'abc123', 'iq');
@ -81,7 +84,7 @@ void main() {
});
test('Test ignoring a stanza that has the wrong tag', () async {
final awaiter = StanzaAwaiter();
final awaiter = StanzaAwaiter(getBareJidCallback);
// "Send" a stanza
final future = await awaiter.addPending(null, 'abc123', 'iq');
@ -100,4 +103,31 @@ void main() {
expect(result2, true);
expect(await future, stanza);
});
test('Sending a stanza to our bare JID', () async {
final awaiter = StanzaAwaiter(getBareJidCallback);
// "Send" a stanza
final future = await awaiter.addPending(bareJid, 'abc123', 'iq');
// Receive the response.
final stanza = XMLNode.fromString('<iq id="abc123" type="result" />');
await awaiter.onData(stanza);
expect(await future, stanza);
});
test(
'Sending a stanza to our bare JID and receiving stanza with a from attribute',
() async {
final awaiter = StanzaAwaiter(getBareJidCallback);
// "Send" a stanza
final future = await awaiter.addPending(bareJid, 'abc123', 'iq');
// Receive the response.
final stanza =
XMLNode.fromString('<iq from="$bareJid" id="abc123" type="result" />');
await awaiter.onData(stanza);
expect(await future, stanza);
});
}