Compare commits

...

2 Commits

57 changed files with 340 additions and 88 deletions

View File

@ -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 the development shell provided by the NixOS Flake, ensure that `ANDROID_HOME` and
`ANDROID_AVD_HOME` are pointing to the correct directories. `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 ## License
See `./LICENSE`. See `./LICENSE`.

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 544 B

View File

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View File

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 721 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -16,10 +16,10 @@ dependencies:
version: 0.1.4+1 version: 0.1.4+1
moxxmpp: moxxmpp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: 0.3.0 version: 0.3.1
moxxmpp_socket_tcp: moxxmpp_socket_tcp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: 0.3.0 version: 0.3.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

6
examples_dart/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
# Files and directories created by pub.
.dart_tool/
.packages
# Conventional directory for build output.
build/

7
examples_dart/README.md Normal file
View File

@ -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.

View File

@ -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

View File

@ -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));
}

View File

@ -0,0 +1,26 @@
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.1
moxxmpp_socket_tcp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: 0.3.1
dependency_overrides:
moxxmpp:
path: ../packages/moxxmpp
moxxmpp_socket_tcp:
path: ../packages/moxxmpp_socket_tcp
dev_dependencies:
lints: ^2.0.0
test: ^1.16.0

View File

@ -7,7 +7,7 @@
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "moxxmpp-docs"; pname = "moxxmpp-docs";
version = "0.3.0"; version = "0.3.1";
PUB_CACHE = "${pubCache}"; PUB_CACHE = "${pubCache}";

View File

@ -1,3 +1,7 @@
## 0.3.1
- Fix some issues with running moxxmpp as a component
## 0.3.0 ## 0.3.0
- **BREAKING**: Removed `connectAwaitable` and merged it with `connect`. - **BREAKING**: Removed `connectAwaitable` and merged it with `connect`.

View File

@ -9,7 +9,7 @@ Include the following as a dependency in your pubspec file:
``` ```
moxxmpp: moxxmpp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: 0.3.0 version: 0.3.1
``` ```
You can find the documentation [here](https://moxxy.org/developers/docs/moxxmpp/). You can find the documentation [here](https://moxxy.org/developers/docs/moxxmpp/).

View File

@ -446,6 +446,9 @@ class XmppConnection {
break; break;
} }
} }
stanza_ = stanza_.copyWith(
xmlns: _negotiationsHandler.getStanzaNamespace(),
);
_log.fine('Running pre stanza handlers..'); _log.fine('Running pre stanza handlers..');
final data = await _runOutgoingPreStanzaHandlers( final data = await _runOutgoingPreStanzaHandlers(
@ -731,6 +734,7 @@ class XmppConnection {
), ),
); );
if (!incomingHandlers.done) { if (!incomingHandlers.done) {
_log.warning('Returning error for unhandled stanza');
await handleUnhandledStanza(this, incomingPreHandlers); await handleUnhandledStanza(this, incomingPreHandlers);
} }
} }

View File

@ -81,6 +81,9 @@ abstract class NegotiationsHandler {
log = Logger(toString()); log = Logger(toString());
} }
/// Returns the xmlns attribute that stanzas should have.
String getStanzaNamespace();
/// Registers the negotiator [negotiator] against this negotiations handler. /// Registers the negotiator [negotiator] against this negotiations handler.
void registerNegotiator(XmppFeatureNegotiatorBase negotiator); void registerNegotiator(XmppFeatureNegotiatorBase negotiator);

View File

@ -35,6 +35,9 @@ class ClientToServerNegotiator extends NegotiationsHandler {
/// The currently active negotiator. /// The currently active negotiator.
XmppFeatureNegotiatorBase? _currentNegotiator; XmppFeatureNegotiatorBase? _currentNegotiator;
@override
String getStanzaNamespace() => stanzaXmlns;
@override @override
void registerNegotiator(XmppFeatureNegotiatorBase negotiator) { void registerNegotiator(XmppFeatureNegotiatorBase negotiator) {
negotiators[negotiator.id] = negotiator; negotiators[negotiator.id] = negotiator;

View File

@ -41,6 +41,9 @@ class ComponentToServerNegotiator extends NegotiationsHandler {
/// The state the negotiation handler is currently in /// The state the negotiation handler is currently in
ComponentToServerState _state = ComponentToServerState.idle; ComponentToServerState _state = ComponentToServerState.idle;
@override
String getStanzaNamespace() => componentAcceptXmlns;
@override @override
void registerNegotiator(XmppFeatureNegotiatorBase negotiator) {} void registerNegotiator(XmppFeatureNegotiatorBase negotiator) {}

View File

@ -4,88 +4,108 @@ import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.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 { 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]. /// 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) { bool matches(XMLNode node) {
var matches = false; var matches = true;
if (nonzaTag == null && nonzaXmlns == null) { if (nonzaTag == null && nonzaXmlns == null) {
matches = true; return true;
} } else {
if (nonzaXmlns != null) {
if (nonzaXmlns != null && nonzaTag != null) { matches &= node.attributes['xmlns'] == nonzaXmlns;
matches = (node.attributes['xmlns'] ?? '') == nonzaXmlns! && }
node.tag == nonzaTag!; if (nonzaTag != null) {
} matches &= node.tag == nonzaTag;
}
if (matchStanzas && nonzaTag == null) {
matches = ['iq', 'presence', 'message'].contains(node.tag);
} }
return matches; return matches;
} }
} }
class NonzaHandler extends Handler { /// A Handler that only matches stanzas.
NonzaHandler({
required this.callback,
String? nonzaTag,
String? nonzaXmlns,
}) : super(
false,
nonzaTag: nonzaTag,
nonzaXmlns: nonzaXmlns,
);
final Future<bool> Function(XMLNode) callback;
}
class StanzaHandler extends Handler { class StanzaHandler extends Handler {
StanzaHandler({ StanzaHandler({
required this.callback, required this.callback,
this.tagXmlns, this.tagXmlns,
this.tagName, this.tagName,
this.priority = 0, this.priority = 0,
String? stanzaTag, this.stanzaTag,
}) : super( this.xmlns = stanzaXmlns,
true, });
nonzaTag: stanzaTag,
nonzaXmlns: stanzaXmlns, /// If specified, then the stanza must contain a direct child with a tag equal to
); /// [tagName].
final String? 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; 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; final int priority;
/// The function to call when a stanza matches the description.
final Future<StanzaHandlerData> Function(Stanza, StanzaHandlerData) callback; final Future<StanzaHandlerData> Function(Stanza, StanzaHandlerData) callback;
@override @override
bool matches(XMLNode node) { bool matches(XMLNode node) {
var matches = super.matches(node); var matches = ['iq', 'message', 'presence'].contains(node.tag);
if (stanzaTag != null) {
if (matches == false) { matches &= node.tag == stanzaTag;
return false; }
if (xmlns != null) {
matches &= node.xmlns == xmlns;
} }
if (tagName != null) { if (tagName != null) {
final firstTag = node.firstTag(tagName!, xmlns: tagXmlns); final firstTag = node.firstTag(tagName!, xmlns: tagXmlns);
matches &= firstTag != null;
matches = firstTag != null; if (tagXmlns != null) {
matches &= firstTag?.xmlns == tagXmlns;
}
} else if (tagXmlns != null) { } else if (tagXmlns != null) {
return listContains( matches &= listContains(
node.children, node.children,
(XMLNode node_) => (XMLNode node_) => node_.attributes['xmlns'] == tagXmlns,
node_.attributes.containsKey('xmlns') &&
node_.attributes['xmlns'] == tagXmlns,
); );
} }
if (tagName == null && tagXmlns == null) {
matches = true;
}
return matches; return matches;
} }
} }

View File

@ -107,11 +107,13 @@ class PresenceManager extends XmppManagerBase {
} }
final attrs = getAttributes(); final attrs = getAttributes();
attrs.sendNonza( await attrs.sendStanza(
Stanza.presence( Stanza.presence(
from: attrs.getFullJID().toString(), from: attrs.getFullJID().toString(),
children: children, children: children,
), ),
awaitable: false,
addId: false,
); );
} }

View File

@ -33,6 +33,7 @@ class Stanza extends XMLNode {
List<XMLNode> children = const [], List<XMLNode> children = const [],
required String tag, required String tag,
Map<String, String> attributes = const {}, Map<String, String> attributes = const {},
String? xmlns,
}) : super( }) : super(
tag: tag, tag: tag,
attributes: <String, dynamic>{ attributes: <String, dynamic>{
@ -45,7 +46,7 @@ class Stanza extends XMLNode {
...from != null ...from != null
? <String, dynamic>{'from': from} ? <String, dynamic>{'from': from}
: <String, dynamic>{}, : <String, dynamic>{},
'xmlns': stanzaXmlns if (xmlns != null) 'xmlns': xmlns,
}, },
children: children, children: children,
); );
@ -57,6 +58,7 @@ class Stanza extends XMLNode {
String? id, String? id,
List<XMLNode> children = const [], List<XMLNode> children = const [],
Map<String, String>? attributes = const {}, Map<String, String>? attributes = const {},
String? xmlns,
}) { }) {
return Stanza( return Stanza(
tag: 'iq', tag: 'iq',
@ -64,8 +66,9 @@ class Stanza extends XMLNode {
to: to, to: to,
id: id, id: id,
type: type, type: type,
attributes: <String, String>{...attributes!, 'xmlns': stanzaXmlns}, attributes: <String, String>{...attributes!},
children: children, children: children,
xmlns: xmlns,
); );
} }
@ -76,6 +79,7 @@ class Stanza extends XMLNode {
String? id, String? id,
List<XMLNode> children = const [], List<XMLNode> children = const [],
Map<String, String>? attributes = const {}, Map<String, String>? attributes = const {},
String? xmlns,
}) { }) {
return Stanza( return Stanza(
tag: 'presence', tag: 'presence',
@ -83,8 +87,9 @@ class Stanza extends XMLNode {
to: to, to: to,
id: id, id: id,
type: type, type: type,
attributes: <String, String>{...attributes!, 'xmlns': stanzaXmlns}, attributes: <String, String>{...attributes!},
children: children, children: children,
xmlns: xmlns,
); );
} }
factory Stanza.message({ factory Stanza.message({
@ -94,6 +99,7 @@ class Stanza extends XMLNode {
String? id, String? id,
List<XMLNode> children = const [], List<XMLNode> children = const [],
Map<String, String>? attributes = const {}, Map<String, String>? attributes = const {},
String? xmlns,
}) { }) {
return Stanza( return Stanza(
tag: 'message', tag: 'message',
@ -101,8 +107,9 @@ class Stanza extends XMLNode {
to: to, to: to,
id: id, id: id,
type: type, type: type,
attributes: <String, String>{...attributes!, 'xmlns': stanzaXmlns}, attributes: <String, String>{...attributes!},
children: children, children: children,
xmlns: xmlns,
); );
} }
@ -134,6 +141,7 @@ class Stanza extends XMLNode {
String? to, String? to,
String? type, String? type,
List<XMLNode>? children, List<XMLNode>? children,
String? xmlns,
}) { }) {
return Stanza( return Stanza(
tag: tag, tag: tag,
@ -142,6 +150,10 @@ class Stanza extends XMLNode {
id: id ?? this.id, id: id ?? this.id,
type: type ?? this.type, type: type ?? this.type,
children: children ?? this.children, children: children ?? this.children,
attributes: {
...attributes.cast<String, String>(),
},
xmlns: xmlns ?? this.xmlns,
); );
} }
} }

View File

@ -1,6 +1,6 @@
name: moxxmpp name: moxxmpp
description: A pure-Dart XMPP library description: A pure-Dart XMPP library
version: 0.3.0 version: 0.3.1
homepage: https://codeberg.org/moxxy/moxxmpp homepage: https://codeberg.org/moxxy/moxxmpp
publish_to: https://git.polynom.me/api/packages/Moxxy/pub publish_to: https://git.polynom.me/api/packages/Moxxy/pub

View File

@ -3,9 +3,11 @@ import 'package:test/test.dart';
final stanza1 = Stanza.iq( final stanza1 = Stanza.iq(
children: [XMLNode.xmlns(tag: 'tag', xmlns: 'owo')], children: [XMLNode.xmlns(tag: 'tag', xmlns: 'owo')],
xmlns: stanzaXmlns,
); );
final stanza2 = Stanza.message( final stanza2 = Stanza.message(
children: [XMLNode.xmlns(tag: 'some-other-tag', xmlns: 'owo')], children: [XMLNode.xmlns(tag: 'some-other-tag', xmlns: 'owo')],
xmlns: stanzaXmlns,
); );
void main() { void main() {
@ -19,11 +21,17 @@ void main() {
), ),
); );
expect(handler.matches(Stanza.iq()), true); expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), true);
expect(handler.matches(Stanza.message()), true); expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), true);
expect(handler.matches(Stanza.presence()), true); expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), true);
expect(handler.matches(stanza1), true); expect(handler.matches(stanza1), true);
expect(handler.matches(stanza2), true); expect(handler.matches(stanza2), true);
expect(
handler.matches(
XMLNode.xmlns(tag: 'active', xmlns: csiXmlns),
),
false,
);
}); });
test('xmlns matching', () { test('xmlns matching', () {
final handler = StanzaHandler( final handler = StanzaHandler(
@ -36,12 +44,13 @@ void main() {
tagXmlns: 'owo', tagXmlns: 'owo',
); );
expect(handler.matches(Stanza.iq()), false); expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.message()), false); expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.presence()), false); expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
expect(handler.matches(stanza1), true); expect(handler.matches(stanza1), true);
expect(handler.matches(stanza2), true); expect(handler.matches(stanza2), true);
}); });
test('stanzaTag matching', () { test('stanzaTag matching', () {
var run = false; var run = false;
final handler = StanzaHandler( final handler = StanzaHandler(
@ -57,9 +66,9 @@ void main() {
stanzaTag: 'iq', stanzaTag: 'iq',
); );
expect(handler.matches(Stanza.iq()), true); expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), true);
expect(handler.matches(Stanza.message()), false); expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.presence()), false); expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
expect(handler.matches(stanza1), true); expect(handler.matches(stanza1), true);
expect(handler.matches(stanza2), false); expect(handler.matches(stanza2), false);
@ -74,6 +83,7 @@ void main() {
); );
expect(run, true); expect(run, true);
}); });
test('tagName matching', () { test('tagName matching', () {
final handler = StanzaHandler( final handler = StanzaHandler(
callback: (stanza, _) async => StanzaHandlerData( callback: (stanza, _) async => StanzaHandlerData(
@ -85,12 +95,13 @@ void main() {
tagName: 'tag', tagName: 'tag',
); );
expect(handler.matches(Stanza.iq()), false); expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.message()), false); expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.presence()), false); expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
expect(handler.matches(stanza1), true); expect(handler.matches(stanza1), true);
expect(handler.matches(stanza2), false); expect(handler.matches(stanza2), false);
}); });
test('combined matching', () { test('combined matching', () {
final handler = StanzaHandler( final handler = StanzaHandler(
callback: (stanza, _) async => StanzaHandlerData( callback: (stanza, _) async => StanzaHandlerData(
@ -104,13 +115,32 @@ void main() {
tagXmlns: 'owo', tagXmlns: 'owo',
); );
expect(handler.matches(Stanza.iq()), false); expect(handler.matches(Stanza.iq(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.message()), false); expect(handler.matches(Stanza.message(xmlns: stanzaXmlns)), false);
expect(handler.matches(Stanza.presence()), false); expect(handler.matches(Stanza.presence(xmlns: stanzaXmlns)), false);
expect(handler.matches(stanza1), true); expect(handler.matches(stanza1), true);
expect(handler.matches(stanza2), false); 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', () { test('sorting', () {
final handlerList = [ final handlerList = [
StanzaHandler( StanzaHandler(

View File

@ -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>', '<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, 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>", "<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>",
'', '',
), ),

View File

@ -1,3 +1,4 @@
import 'dart:async';
import 'package:moxxmpp/moxxmpp.dart'; import 'package:moxxmpp/moxxmpp.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../helpers/logging.dart'; import '../helpers/logging.dart';
@ -88,6 +89,7 @@ void main() {
final stanza = Stanza( final stanza = Stanza(
to: 'some.user@server.example', to: 'some.user@server.example',
tag: 'message', tag: 'message',
xmlns: stanzaXmlns,
); );
test('Test stream with SM enablement', () async { test('Test stream with SM enablement', () async {
@ -388,10 +390,14 @@ void main() {
"<enable xmlns='urn:xmpp:sm:3' resume='true' />", "<enable xmlns='urn:xmpp:sm:3' resume='true' />",
'<enabled xmlns="urn:xmpp:sm:3" id="some-long-sm-id" 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>", "<presence xmlns='jabber:client' from='polynomdivision@test.server/MU29eEZn'><show>chat</show></presence>",
'<iq type="result" />', '<iq type="result" />',
), ),
StringExpectation(
"<r xmlns='urn:xmpp:sm:3' />",
"<a xmlns='urn:xmpp:sm:3' h='1' />",
),
StanzaExpectation( StanzaExpectation(
"<iq to='user@example.com' type='get' id='a' xmlns='jabber:client' />", "<iq to='user@example.com' type='get' id='a' xmlns='jabber:client' />",
"<iq from='user@example.com' type='result' id='a' />", "<iq from='user@example.com' type='result' id='a' />",
@ -425,7 +431,8 @@ void main() {
waitUntilLogin: true, 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(await conn.getConnectionState(), XmppConnectionState.connected);
expect( expect(
conn conn
@ -502,9 +509,6 @@ void main() {
password: 'aaaa', password: 'aaaa',
); );
await conn.registerManagers([ await conn.registerManagers([
PresenceManager(),
RosterManager(TestingRosterStateManager('', [])),
DiscoManager([]),
StreamManagementManager(), StreamManagementManager(),
]); ]);
await conn.registerFeatureNegotiators([ await conn.registerFeatureNegotiators([
@ -523,7 +527,8 @@ void main() {
await conn.connect( await conn.connect(
waitUntilLogin: true, waitUntilLogin: true,
); );
expect(fakeSocket.getState(), 7);
expect(fakeSocket.getState(), 6);
expect(await conn.getConnectionState(), XmppConnectionState.connected); expect(await conn.getConnectionState(), XmppConnectionState.connected);
expect( expect(
conn conn

View File

@ -1,3 +1,7 @@
## 0.3.1
- Keep version in sync with moxxmpp
## 0.1.2+9 ## 0.1.2+9
- Update a dependency to the latest release. - Update a dependency to the latest release.

View File

@ -1,6 +1,6 @@
name: moxxmpp_socket_tcp name: moxxmpp_socket_tcp
description: A socket for moxxmpp using TCP that implements the RFC6120 connection algorithm and XEP-0368 description: A socket for moxxmpp using TCP that implements the RFC6120 connection algorithm and XEP-0368
version: 0.3.0 version: 0.3.1
homepage: https://codeberg.org/moxxy/moxxmpp homepage: https://codeberg.org/moxxy/moxxmpp
publish_to: https://git.polynom.me/api/packages/Moxxy/pub publish_to: https://git.polynom.me/api/packages/Moxxy/pub