fix(core): Fix components' stanza matching
This commit is contained in:
1 parent
5c47c35a46
commit
916be1c927
51 files changed
+324
-82
No files matched your search
@@ -24,6 +24,15 @@ To run the example, make sure that Flutter is correctly set up and working. If y
|
||||
the development shell provided by the NixOS Flake, ensure that `ANDROID_HOME` and
|
||||
`ANDROID_AVD_HOME` are pointing to the correct directories.
|
||||
|
||||
## Examples
|
||||
|
||||
This repository contains 2 types of examples:
|
||||
|
||||
- `example_flutter`: An example of using moxxmpp using Flutter
|
||||
- `examples_dart`: A collection of pure Dart examples for showing different aspects of moxxmpp
|
||||
|
||||
For more information, see the respective README files.
|
||||
|
||||
## License
|
||||
|
||||
See `./LICENSE`.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# melos_managed_dependency_overrides: moxxmpp,moxxmpp_socket_tcp
|
||||
dependency_overrides:
|
||||
moxxmpp:
|
||||
path: ../packages/moxxmpp
|
||||
moxxmpp_socket_tcp:
|
||||
path: ../packages/moxxmpp_socket_tcp
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,6 @@
|
||||
# Files and directories created by pub.
|
||||
.dart_tool/
|
||||
.packages
|
||||
|
||||
# Conventional directory for build output.
|
||||
build/
|
||||
@@ -0,0 +1,7 @@
|
||||
# Dart Examples
|
||||
|
||||
Run using `dart run bin/<example>.dart`.
|
||||
|
||||
## Examples
|
||||
|
||||
- `component.dart`: Use moxxmpp to implement a component using XEP-0114.
|
||||
@@ -0,0 +1,30 @@
|
||||
# This file configures the static analysis results for your project (errors,
|
||||
# warnings, and lints).
|
||||
#
|
||||
# This enables the 'recommended' set of lints from `package:lints`.
|
||||
# This set helps identify many issues that may lead to problems when running
|
||||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
|
||||
# style and format.
|
||||
#
|
||||
# If you want a smaller set of lints you can change this to specify
|
||||
# 'package:lints/core.yaml'. These are just the most critical lints
|
||||
# (the recommended set includes the core lints).
|
||||
# The core lints are also what is used by pub.dev for scoring packages.
|
||||
|
||||
include: package:lints/recommended.yaml
|
||||
|
||||
# Uncomment the following section to specify additional rules.
|
||||
|
||||
# linter:
|
||||
# rules:
|
||||
# - camel_case_types
|
||||
|
||||
# analyzer:
|
||||
# exclude:
|
||||
# - path/to/excluded/files/**
|
||||
|
||||
# For more information about the core and recommended set of lints, see
|
||||
# https://dart.dev/go/core-lints
|
||||
|
||||
# For additional information about configuring this file, see
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
@@ -0,0 +1,90 @@
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:moxxmpp/moxxmpp.dart';
|
||||
import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart';
|
||||
|
||||
class TestingTCPSocketWrapper extends TCPSocketWrapper {
|
||||
@override
|
||||
bool onBadCertificate(dynamic certificate, String domain) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class EchoMessageManager extends XmppManagerBase {
|
||||
EchoMessageManager() : super('org.moxxy.example.message');
|
||||
|
||||
@override
|
||||
Future<bool> isSupported() async => true;
|
||||
|
||||
@override
|
||||
List<StanzaHandler> getIncomingStanzaHandlers() => [
|
||||
StanzaHandler(
|
||||
stanzaTag: 'message',
|
||||
callback: _onMessage,
|
||||
priority: -100,
|
||||
xmlns: null,
|
||||
)
|
||||
];
|
||||
|
||||
Future<StanzaHandlerData> _onMessage(
|
||||
Stanza stanza,
|
||||
StanzaHandlerData state,
|
||||
) async {
|
||||
final body = stanza.firstTag('body');
|
||||
if (body == null) return state.copyWith(done: true);
|
||||
|
||||
final bodyText = body.innerText();
|
||||
|
||||
await getAttributes().sendStanza(
|
||||
Stanza.message(
|
||||
to: stanza.from,
|
||||
children: [
|
||||
XMLNode(
|
||||
tag: 'body',
|
||||
text: 'Hello, ${stanza.from}! You said "$bodyText"',
|
||||
),
|
||||
],
|
||||
),
|
||||
awaitable: false,
|
||||
);
|
||||
|
||||
return state.copyWith(done: true);
|
||||
}
|
||||
}
|
||||
|
||||
void main(List<String> arguments) async {
|
||||
Logger.root.level = Level.ALL;
|
||||
Logger.root.onRecord.listen((record) {
|
||||
// ignore: avoid_print
|
||||
print(
|
||||
'[${record.level.name}] (${record.loggerName}) ${record.time}: ${record.message}',
|
||||
);
|
||||
});
|
||||
|
||||
final conn = XmppConnection(
|
||||
TestingReconnectionPolicy(),
|
||||
AlwaysConnectedConnectivityManager(),
|
||||
ComponentToServerNegotiator(),
|
||||
TestingTCPSocketWrapper(),
|
||||
)..connectionSettings = ConnectionSettings(
|
||||
jid: JID.fromString('component.localhost'),
|
||||
password: 'abc123',
|
||||
host: '127.0.0.1',
|
||||
port: 8888,
|
||||
);
|
||||
await conn.registerManagers([
|
||||
EchoMessageManager(),
|
||||
]);
|
||||
|
||||
final result = await conn.connect(
|
||||
waitUntilLogin: true,
|
||||
shouldReconnect: false,
|
||||
enableReconnectOnSuccess: false,
|
||||
);
|
||||
if (result.isType<XmppError>()) {
|
||||
print('Failed to connect as component');
|
||||
return;
|
||||
}
|
||||
|
||||
// Just block for some time to test the connection
|
||||
await Future<void>.delayed(const Duration(seconds: 9999));
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
name: example_dart
|
||||
description: A sample command-line application.
|
||||
version: 1.0.0
|
||||
# homepage: https://www.example.com
|
||||
|
||||
environment:
|
||||
sdk: '>=2.18.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
logging: ^1.0.2
|
||||
moxxmpp:
|
||||
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
||||
version: 0.3.0
|
||||
moxxmpp_socket_tcp:
|
||||
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
||||
version: 0.3.0
|
||||
|
||||
dependency_overrides:
|
||||
moxxmpp:
|
||||
path: ../packages/moxxmpp
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^2.0.0
|
||||
test: ^1.16.0
|
||||
@@ -446,6 +446,9 @@ class XmppConnection {
|
||||
break;
|
||||
}
|
||||
}
|
||||
stanza_ = stanza_.copyWith(
|
||||
xmlns: _negotiationsHandler.getStanzaNamespace(),
|
||||
);
|
||||
|
||||
_log.fine('Running pre stanza handlers..');
|
||||
final data = await _runOutgoingPreStanzaHandlers(
|
||||
@@ -731,6 +734,7 @@ class XmppConnection {
|
||||
),
|
||||
);
|
||||
if (!incomingHandlers.done) {
|
||||
_log.warning('Returning error for unhandled stanza');
|
||||
await handleUnhandledStanza(this, incomingPreHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,9 @@ abstract class NegotiationsHandler {
|
||||
log = Logger(toString());
|
||||
}
|
||||
|
||||
/// Returns the xmlns attribute that stanzas should have.
|
||||
String getStanzaNamespace();
|
||||
|
||||
/// Registers the negotiator [negotiator] against this negotiations handler.
|
||||
void registerNegotiator(XmppFeatureNegotiatorBase negotiator);
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ class ClientToServerNegotiator extends NegotiationsHandler {
|
||||
/// The currently active negotiator.
|
||||
XmppFeatureNegotiatorBase? _currentNegotiator;
|
||||
|
||||
@override
|
||||
String getStanzaNamespace() => stanzaXmlns;
|
||||
|
||||
@override
|
||||
void registerNegotiator(XmppFeatureNegotiatorBase negotiator) {
|
||||
negotiators[negotiator.id] = negotiator;
|
||||
|
||||
@@ -41,6 +41,9 @@ class ComponentToServerNegotiator extends NegotiationsHandler {
|
||||
/// The state the negotiation handler is currently in
|
||||
ComponentToServerState _state = ComponentToServerState.idle;
|
||||
|
||||
@override
|
||||
String getStanzaNamespace() => componentAcceptXmlns;
|
||||
|
||||
@override
|
||||
void registerNegotiator(XmppFeatureNegotiatorBase negotiator) {}
|
||||
|
||||
|
||||
@@ -4,88 +4,108 @@ import 'package:moxxmpp/src/namespaces.dart';
|
||||
import 'package:moxxmpp/src/stanza.dart';
|
||||
import 'package:moxxmpp/src/stringxml.dart';
|
||||
|
||||
/// A Handler is responsible for matching any kind of toplevel item in the XML stream
|
||||
/// (stanzas and Nonzas). For that, its [matches] method is called. What happens
|
||||
/// next depends on the subclass.
|
||||
// ignore: one_member_abstracts
|
||||
abstract class Handler {
|
||||
const Handler(this.matchStanzas, {this.nonzaTag, this.nonzaXmlns});
|
||||
final String? nonzaTag;
|
||||
final String? nonzaXmlns;
|
||||
final bool matchStanzas;
|
||||
|
||||
/// Returns true if the node matches the description provided by this [Handler].
|
||||
bool matches(XMLNode node);
|
||||
}
|
||||
|
||||
/// A Handler that specialises in matching Nonzas (and stanzas).
|
||||
class NonzaHandler extends Handler {
|
||||
NonzaHandler({
|
||||
required this.callback,
|
||||
this.nonzaTag,
|
||||
this.nonzaXmlns,
|
||||
});
|
||||
|
||||
/// The function to call when a nonza matches the description.
|
||||
final Future<bool> Function(XMLNode) callback;
|
||||
|
||||
/// The expected tag of a matching nonza.
|
||||
final String? nonzaTag;
|
||||
|
||||
// The expected xmlns attribute of a matching nonza.
|
||||
final String? nonzaXmlns;
|
||||
|
||||
@override
|
||||
bool matches(XMLNode node) {
|
||||
var matches = false;
|
||||
|
||||
var matches = true;
|
||||
if (nonzaTag == null && nonzaXmlns == null) {
|
||||
matches = true;
|
||||
}
|
||||
|
||||
if (nonzaXmlns != null && nonzaTag != null) {
|
||||
matches = (node.attributes['xmlns'] ?? '') == nonzaXmlns! &&
|
||||
node.tag == nonzaTag!;
|
||||
}
|
||||
|
||||
if (matchStanzas && nonzaTag == null) {
|
||||
matches = ['iq', 'presence', 'message'].contains(node.tag);
|
||||
return true;
|
||||
} else {
|
||||
if (nonzaXmlns != null) {
|
||||
matches &= node.attributes['xmlns'] == nonzaXmlns;
|
||||
}
|
||||
if (nonzaTag != null) {
|
||||
matches &= node.tag == nonzaTag;
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
|
||||
class NonzaHandler extends Handler {
|
||||
NonzaHandler({
|
||||
required this.callback,
|
||||
String? nonzaTag,
|
||||
String? nonzaXmlns,
|
||||
}) : super(
|
||||
false,
|
||||
nonzaTag: nonzaTag,
|
||||
nonzaXmlns: nonzaXmlns,
|
||||
);
|
||||
final Future<bool> Function(XMLNode) callback;
|
||||
}
|
||||
|
||||
/// A Handler that only matches stanzas.
|
||||
class StanzaHandler extends Handler {
|
||||
StanzaHandler({
|
||||
required this.callback,
|
||||
this.tagXmlns,
|
||||
this.tagName,
|
||||
this.priority = 0,
|
||||
String? stanzaTag,
|
||||
}) : super(
|
||||
true,
|
||||
nonzaTag: stanzaTag,
|
||||
nonzaXmlns: stanzaXmlns,
|
||||
);
|
||||
this.stanzaTag,
|
||||
this.xmlns = stanzaXmlns,
|
||||
});
|
||||
|
||||
/// If specified, then the stanza must contain a direct child with a tag equal to
|
||||
/// [tagName].
|
||||
final String? tagName;
|
||||
|
||||
/// If specified, then the stanza must contain a direct child with a xmlns attribute
|
||||
/// equal to [tagXmlns]. If [tagName] is also non-null, then the element must also
|
||||
/// have a tag equal to [tagName].
|
||||
final String? tagXmlns;
|
||||
|
||||
/// If specified, the matching stanza must have a tag equal to [stanzaTag].
|
||||
final String? stanzaTag;
|
||||
|
||||
/// If specified, then the stanza must have a xmlns attribute equal to [xmlns].
|
||||
/// This defaults to [stanzaXmlns], but can be set to any other value or null. This
|
||||
/// is useful, for example, for components.
|
||||
final String? xmlns;
|
||||
|
||||
/// The priority after which [StanzaHandler]s are sorted.
|
||||
final int priority;
|
||||
|
||||
/// The function to call when a stanza matches the description.
|
||||
final Future<StanzaHandlerData> Function(Stanza, StanzaHandlerData) callback;
|
||||
|
||||
@override
|
||||
bool matches(XMLNode node) {
|
||||
var matches = super.matches(node);
|
||||
|
||||
if (matches == false) {
|
||||
return false;
|
||||
var matches = ['iq', 'message', 'presence'].contains(node.tag);
|
||||
if (stanzaTag != null) {
|
||||
matches &= node.tag == stanzaTag;
|
||||
}
|
||||
if (xmlns != null) {
|
||||
matches &= node.xmlns == xmlns;
|
||||
}
|
||||
|
||||
if (tagName != null) {
|
||||
final firstTag = node.firstTag(tagName!, xmlns: tagXmlns);
|
||||
matches &= firstTag != null;
|
||||
|
||||
matches = firstTag != null;
|
||||
if (tagXmlns != null) {
|
||||
matches &= firstTag?.xmlns == tagXmlns;
|
||||
}
|
||||
} else if (tagXmlns != null) {
|
||||
return listContains(
|
||||
matches &= listContains(
|
||||
node.children,
|
||||
(XMLNode node_) =>
|
||||
node_.attributes.containsKey('xmlns') &&
|
||||
node_.attributes['xmlns'] == tagXmlns,
|
||||
(XMLNode node_) => node_.attributes['xmlns'] == tagXmlns,
|
||||
);
|
||||
}
|
||||
|
||||
if (tagName == null && tagXmlns == null) {
|
||||
matches = true;
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,11 +107,13 @@ class PresenceManager extends XmppManagerBase {
|
||||
}
|
||||
|
||||
final attrs = getAttributes();
|
||||
attrs.sendNonza(
|
||||
await attrs.sendStanza(
|
||||
Stanza.presence(
|
||||
from: attrs.getFullJID().toString(),
|
||||
children: children,
|
||||
),
|
||||
awaitable: false,
|
||||
addId: false,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ class Stanza extends XMLNode {
|
||||
List<XMLNode> children = const [],
|
||||
required String tag,
|
||||
Map<String, String> attributes = const {},
|
||||
String? xmlns,
|
||||
}) : super(
|
||||
tag: tag,
|
||||
attributes: <String, dynamic>{
|
||||
@@ -45,7 +46,7 @@ class Stanza extends XMLNode {
|
||||
...from != null
|
||||
? <String, dynamic>{'from': from}
|
||||
: <String, dynamic>{},
|
||||
'xmlns': stanzaXmlns
|
||||
if (xmlns != null) 'xmlns': xmlns,
|
||||
},
|
||||
children: children,
|
||||
);
|
||||
@@ -57,6 +58,7 @@ class Stanza extends XMLNode {
|
||||
String? id,
|
||||
List<XMLNode> children = const [],
|
||||
Map<String, String>? attributes = const {},
|
||||
String? xmlns,
|
||||
}) {
|
||||
return Stanza(
|
||||
tag: 'iq',
|
||||
@@ -64,8 +66,9 @@ class Stanza extends XMLNode {
|
||||
to: to,
|
||||
id: id,
|
||||
type: type,
|
||||
attributes: <String, String>{...attributes!, 'xmlns': stanzaXmlns},
|
||||
attributes: <String, String>{...attributes!},
|
||||
children: children,
|
||||
xmlns: xmlns,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,6 +79,7 @@ class Stanza extends XMLNode {
|
||||
String? id,
|
||||
List<XMLNode> children = const [],
|
||||
Map<String, String>? attributes = const {},
|
||||
String? xmlns,
|
||||
}) {
|
||||
return Stanza(
|
||||
tag: 'presence',
|
||||
@@ -83,8 +87,9 @@ class Stanza extends XMLNode {
|
||||
to: to,
|
||||
id: id,
|
||||
type: type,
|
||||
attributes: <String, String>{...attributes!, 'xmlns': stanzaXmlns},
|
||||
attributes: <String, String>{...attributes!},
|
||||
children: children,
|
||||
xmlns: xmlns,
|
||||
);
|
||||
}
|
||||
factory Stanza.message({
|
||||
@@ -94,6 +99,7 @@ class Stanza extends XMLNode {
|
||||
String? id,
|
||||
List<XMLNode> children = const [],
|
||||
Map<String, String>? attributes = const {},
|
||||
String? xmlns,
|
||||
}) {
|
||||
return Stanza(
|
||||
tag: 'message',
|
||||
@@ -101,8 +107,9 @@ class Stanza extends XMLNode {
|
||||
to: to,
|
||||
id: id,
|
||||
type: type,
|
||||
attributes: <String, String>{...attributes!, 'xmlns': stanzaXmlns},
|
||||
attributes: <String, String>{...attributes!},
|
||||
children: children,
|
||||
xmlns: xmlns,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,6 +141,7 @@ class Stanza extends XMLNode {
|
||||
String? to,
|
||||
String? type,
|
||||
List<XMLNode>? children,
|
||||
String? xmlns,
|
||||
}) {
|
||||
return Stanza(
|
||||
tag: tag,
|
||||
@@ -142,6 +150,10 @@ class Stanza extends XMLNode {
|
||||
id: id ?? this.id,
|
||||
type: type ?? this.type,
|
||||
children: children ?? this.children,
|
||||
attributes: {
|
||||
...attributes.cast<String, String>(),
|
||||
},
|
||||
xmlns: xmlns ?? this.xmlns,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ import 'package:test/test.dart';
|
||||
|
||||
final stanza1 = Stanza.iq(
|
||||
children: [XMLNode.xmlns(tag: 'tag', xmlns: 'owo')],
|
||||
xmlns: stanzaXmlns,
|
||||
);
|
||||
final stanza2 = Stanza.message(
|
||||
children: [XMLNode.xmlns(tag: 'some-other-tag', xmlns: 'owo')],
|
||||
xmlns: stanzaXmlns,
|
||||
);
|
||||
|
||||
void main() {
|
||||
@@ -19,11 +21,17 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), true);
|
||||
expect(handler.matches(Stanza.message()), true);
|
||||
expect(handler.matches(Stanza.presence()), true);
|
||||
expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), true);
|
||||
expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), true);
|
||||
expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), true);
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), true);
|
||||
expect(
|
||||
handler.matches(
|
||||
XMLNode.xmlns(tag: 'active', xmlns: csiXmlns),
|
||||
),
|
||||
false,
|
||||
);
|
||||
});
|
||||
test('xmlns matching', () {
|
||||
final handler = StanzaHandler(
|
||||
@@ -36,12 +44,13 @@ void main() {
|
||||
tagXmlns: 'owo',
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), false);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
expect(handler.matches(Stanza.presence()), false);
|
||||
expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), true);
|
||||
});
|
||||
|
||||
test('stanzaTag matching', () {
|
||||
var run = false;
|
||||
final handler = StanzaHandler(
|
||||
@@ -57,9 +66,9 @@ void main() {
|
||||
stanzaTag: 'iq',
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), true);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
expect(handler.matches(Stanza.presence()), false);
|
||||
expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), true);
|
||||
expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), false);
|
||||
|
||||
@@ -74,6 +83,7 @@ void main() {
|
||||
);
|
||||
expect(run, true);
|
||||
});
|
||||
|
||||
test('tagName matching', () {
|
||||
final handler = StanzaHandler(
|
||||
callback: (stanza, _) async => StanzaHandlerData(
|
||||
@@ -85,12 +95,13 @@ void main() {
|
||||
tagName: 'tag',
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), false);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
expect(handler.matches(Stanza.presence()), false);
|
||||
expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), false);
|
||||
});
|
||||
|
||||
test('combined matching', () {
|
||||
final handler = StanzaHandler(
|
||||
callback: (stanza, _) async => StanzaHandlerData(
|
||||
@@ -104,13 +115,32 @@ void main() {
|
||||
tagXmlns: 'owo',
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), false);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
expect(handler.matches(Stanza.presence()), false);
|
||||
expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), false);
|
||||
});
|
||||
|
||||
test('Test matching stanzas with a different xmlns', () {
|
||||
final handler = StanzaHandler(
|
||||
callback: (stanza, _) async => StanzaHandlerData(
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
stanza,
|
||||
),
|
||||
xmlns: componentAcceptXmlns,
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
|
||||
expect(handler.matches(Stanza.iq(xmlns: componentAcceptXmlns)), true);
|
||||
expect(handler.matches(stanza1), false);
|
||||
expect(handler.matches(stanza2), false);
|
||||
});
|
||||
|
||||
test('sorting', () {
|
||||
final handlerList = [
|
||||
StanzaHandler(
|
||||
|
||||
@@ -56,7 +56,7 @@ void main() {
|
||||
'<iq xmlns="jabber:client" type="result" id="a"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>polynomdivision@test.server/MU29eEZn</jid></bind></iq>',
|
||||
ignoreId: true,
|
||||
),
|
||||
StringExpectation(
|
||||
StanzaExpectation(
|
||||
"<presence xmlns='jabber:client' from='polynomdivision@test.server/MU29eEZn'><show>chat</show><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://moxxmpp.example' ver='3QvQ2RAy45XBDhArjxy/vEWMl+E=' /></presence>",
|
||||
'',
|
||||
),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'package:moxxmpp/moxxmpp.dart';
|
||||
import 'package:test/test.dart';
|
||||
import '../helpers/logging.dart';
|
||||
@@ -88,6 +89,7 @@ void main() {
|
||||
final stanza = Stanza(
|
||||
to: 'some.user@server.example',
|
||||
tag: 'message',
|
||||
xmlns: stanzaXmlns,
|
||||
);
|
||||
|
||||
test('Test stream with SM enablement', () async {
|
||||
@@ -388,10 +390,14 @@ void main() {
|
||||
"<enable xmlns='urn:xmpp:sm:3' resume='true' />",
|
||||
'<enabled xmlns="urn:xmpp:sm:3" id="some-long-sm-id" resume="true" />',
|
||||
),
|
||||
StringExpectation(
|
||||
StanzaExpectation(
|
||||
"<presence xmlns='jabber:client' from='polynomdivision@test.server/MU29eEZn'><show>chat</show></presence>",
|
||||
'<iq type="result" />',
|
||||
),
|
||||
StringExpectation(
|
||||
"<r xmlns='urn:xmpp:sm:3' />",
|
||||
"<a xmlns='urn:xmpp:sm:3' h='1' />",
|
||||
),
|
||||
StanzaExpectation(
|
||||
"<iq to='user@example.com' type='get' id='a' xmlns='jabber:client' />",
|
||||
"<iq from='user@example.com' type='result' id='a' />",
|
||||
@@ -425,7 +431,8 @@ void main() {
|
||||
waitUntilLogin: true,
|
||||
);
|
||||
|
||||
expect(fakeSocket.getState(), 6);
|
||||
await Future<void>.delayed(const Duration(seconds: 3));
|
||||
expect(fakeSocket.getState(), 7);
|
||||
expect(await conn.getConnectionState(), XmppConnectionState.connected);
|
||||
expect(
|
||||
conn
|
||||
@@ -502,9 +509,6 @@ void main() {
|
||||
password: 'aaaa',
|
||||
);
|
||||
await conn.registerManagers([
|
||||
PresenceManager(),
|
||||
RosterManager(TestingRosterStateManager('', [])),
|
||||
DiscoManager([]),
|
||||
StreamManagementManager(),
|
||||
]);
|
||||
await conn.registerFeatureNegotiators([
|
||||
@@ -523,7 +527,8 @@ void main() {
|
||||
await conn.connect(
|
||||
waitUntilLogin: true,
|
||||
);
|
||||
expect(fakeSocket.getState(), 7);
|
||||
|
||||
expect(fakeSocket.getState(), 6);
|
||||
expect(await conn.getConnectionState(), XmppConnectionState.connected);
|
||||
expect(
|
||||
conn
|
||||
|
||||
Reference in new issue
Block a user