fix(xep): Fix usage of 'max' in publish options (#33)
This commit fixes two issues: 1. Fix an issue where [PubSubManager.publish] would always, if given publish options with maxItems set to 'max', use 'max' in the max_items publish options, even if the server indicates it does not support that. 2. Fix an issue with the StanzaExpectation, where it would let every stanza pass.
This commit is contained in:
parent
324ef9ca29
commit
f49eb66bb7
@ -1,3 +1,5 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:moxxmpp/src/events.dart';
|
||||
import 'package:moxxmpp/src/jid.dart';
|
||||
import 'package:moxxmpp/src/managers/base.dart';
|
||||
@ -130,7 +132,10 @@ class PubSubManager extends XmppManagerBase {
|
||||
return count;
|
||||
}
|
||||
|
||||
Future<PubSubPublishOptions> _preprocessPublishOptions(
|
||||
// TODO(PapaTutuWawa): This should return a Result<T> in case we cannot proceed
|
||||
// with the requested configuration.
|
||||
@visibleForTesting
|
||||
Future<PubSubPublishOptions> preprocessPublishOptions(
|
||||
String jid,
|
||||
String node,
|
||||
PubSubPublishOptions options,
|
||||
@ -285,7 +290,7 @@ class PubSubManager extends XmppManagerBase {
|
||||
}) async {
|
||||
PubSubPublishOptions? pubOptions;
|
||||
if (options != null) {
|
||||
pubOptions = await _preprocessPublishOptions(jid, node, options);
|
||||
pubOptions = await preprocessPublishOptions(jid, node, options);
|
||||
}
|
||||
|
||||
final result = await getAttributes().sendStanza(
|
||||
@ -310,14 +315,11 @@ class PubSubManager extends XmppManagerBase {
|
||||
)
|
||||
],
|
||||
),
|
||||
...options != null
|
||||
? [
|
||||
if (pubOptions != null)
|
||||
XMLNode(
|
||||
tag: 'publish-options',
|
||||
children: [options.toXml()],
|
||||
children: [pubOptions.toXml()],
|
||||
),
|
||||
]
|
||||
: [],
|
||||
],
|
||||
)
|
||||
],
|
||||
|
63
packages/moxxmpp/test/helpers/manager.dart
Normal file
63
packages/moxxmpp/test/helpers/manager.dart
Normal file
@ -0,0 +1,63 @@
|
||||
import 'dart:async';
|
||||
import 'package:moxxmpp/src/connection.dart';
|
||||
import 'package:moxxmpp/src/connectivity.dart';
|
||||
import 'package:moxxmpp/src/jid.dart';
|
||||
import 'package:moxxmpp/src/managers/attributes.dart';
|
||||
import 'package:moxxmpp/src/managers/base.dart';
|
||||
import 'package:moxxmpp/src/reconnect.dart';
|
||||
import 'package:moxxmpp/src/settings.dart';
|
||||
import 'package:moxxmpp/src/socket.dart';
|
||||
import 'package:moxxmpp/src/stringxml.dart';
|
||||
|
||||
import '../helpers/xmpp.dart';
|
||||
|
||||
/// This class allows registering managers for easier testing.
|
||||
class TestingManagerHolder {
|
||||
TestingManagerHolder({
|
||||
BaseSocketWrapper? socket,
|
||||
}) : _socket = socket ?? StubTCPSocket([]);
|
||||
|
||||
final BaseSocketWrapper _socket;
|
||||
|
||||
final Map<String, XmppManagerBase> _managers = {};
|
||||
|
||||
static final JID jid = JID.fromString('testuser@example.org/abc123');
|
||||
static final ConnectionSettings settings = ConnectionSettings(
|
||||
jid: jid,
|
||||
password: 'abc123',
|
||||
useDirectTLS: true,
|
||||
allowPlainAuth: true,
|
||||
);
|
||||
|
||||
Future<XMLNode> _sendStanza(stanza, { StanzaFromType addFrom = StanzaFromType.full, bool addId = true, bool awaitable = true, bool encrypted = false, bool forceEncryption = false, }) async {
|
||||
return XMLNode.fromString('<iq />');
|
||||
}
|
||||
|
||||
T? _getManagerById<T extends XmppManagerBase>(String id) {
|
||||
return _managers[id] as T?;
|
||||
}
|
||||
|
||||
Future<void> register(XmppManagerBase manager) async {
|
||||
manager.register(
|
||||
XmppManagerAttributes(
|
||||
sendStanza: _sendStanza,
|
||||
getConnection: () => XmppConnection(
|
||||
TestingReconnectionPolicy(),
|
||||
AlwaysConnectedConnectivityManager(),
|
||||
_socket,
|
||||
),
|
||||
getConnectionSettings: () => settings,
|
||||
sendNonza: (_) {},
|
||||
sendEvent: (_) {},
|
||||
getSocket: () => _socket,
|
||||
isFeatureSupported: (_) => false,
|
||||
getNegotiatorById: getNegotiatorNullStub,
|
||||
getFullJID: () => jid,
|
||||
getManagerById: _getManagerById,
|
||||
),
|
||||
);
|
||||
|
||||
await manager.postRegisterCallback();
|
||||
_managers[manager.id] = manager;
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:moxxmpp/moxxmpp.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
@ -13,8 +14,8 @@ T? getManagerNullStub<T extends XmppManagerBase>(String id) {
|
||||
}
|
||||
|
||||
abstract class ExpectationBase {
|
||||
|
||||
ExpectationBase(this.expectation, this.response);
|
||||
|
||||
final String expectation;
|
||||
final String response;
|
||||
|
||||
@ -33,27 +34,84 @@ class StringExpectation extends ExpectationBase {
|
||||
///
|
||||
class StanzaExpectation extends ExpectationBase {
|
||||
StanzaExpectation(String expectation, String response, {this.ignoreId = false, this.adjustId = false }) : super(expectation, response);
|
||||
|
||||
final bool ignoreId;
|
||||
final bool adjustId;
|
||||
|
||||
@override
|
||||
bool matches(String input) {
|
||||
final ex = XMLNode.fromString(expectation);
|
||||
final recv = XMLNode.fromString(expectation);
|
||||
final recv = XMLNode.fromString(input);
|
||||
|
||||
return compareXMLNodes(recv, ex, ignoreId: ignoreId);
|
||||
}
|
||||
}
|
||||
|
||||
class StubTCPSocket extends BaseSocketWrapper { // Request -> Response(s)
|
||||
/// Use [settings] to build the beginning of a play that can be used with StubTCPSocket. [settings]'s allowPlainAuth must
|
||||
/// be set to true.
|
||||
List<ExpectationBase> buildAuthenticatedPlay(ConnectionSettings settings) {
|
||||
assert(settings.allowPlainAuth, 'SASL PLAIN must be allowed');
|
||||
|
||||
final plain = base64.encode(utf8.encode('\u0000${settings.jid.local}\u0000${settings.password}'));
|
||||
return [
|
||||
StringExpectation(
|
||||
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='${settings.jid.domain}' xml:lang='en'>",
|
||||
'''
|
||||
<stream:stream
|
||||
xmlns="jabber:client"
|
||||
version="1.0"
|
||||
xmlns:stream="http://etherx.jabber.org/streams"
|
||||
from="${settings.jid.domain}"
|
||||
xml:lang="en">
|
||||
<stream:features xmlns="http://etherx.jabber.org/streams">
|
||||
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
||||
<mechanism>PLAIN</mechanism>
|
||||
</mechanisms>
|
||||
</stream:features>''',
|
||||
),
|
||||
StringExpectation(
|
||||
"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>$plain</auth>",
|
||||
'<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl" />'
|
||||
),
|
||||
StringExpectation(
|
||||
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='${settings.jid.domain}' xml:lang='en'>",
|
||||
'''
|
||||
<stream:stream
|
||||
xmlns="jabber:client"
|
||||
version="1.0"
|
||||
xmlns:stream="http://etherx.jabber.org/streams"
|
||||
from="test.server"
|
||||
xml:lang="en">
|
||||
<stream:features xmlns="http://etherx.jabber.org/streams">
|
||||
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
||||
<required/>
|
||||
</bind>
|
||||
</stream:features>
|
||||
''',
|
||||
),
|
||||
StanzaExpectation(
|
||||
'<iq xmlns="jabber:client" type="set" id="a"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>',
|
||||
'<iq xmlns="jabber:client" type="result" id="a"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>${settings.jid.toBare()}/MU29eEZn</jid></bind></iq>',
|
||||
ignoreId: true,
|
||||
),
|
||||
StanzaExpectation(
|
||||
"<presence xmlns='jabber:client' from='${settings.jid.toBare()}/MU29eEZn'><show>chat</show></presence>",
|
||||
'',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class StubTCPSocket extends BaseSocketWrapper { // Request -> Response(s)
|
||||
StubTCPSocket(this._play);
|
||||
|
||||
StubTCPSocket.authenticated(ConnectionSettings settings, List<ExpectationBase> play) : _play = [
|
||||
...buildAuthenticatedPlay(settings),
|
||||
...play,
|
||||
];
|
||||
|
||||
StubTCPSocket({ required List<ExpectationBase> play })
|
||||
: _play = play,
|
||||
_dataStream = StreamController<String>.broadcast(),
|
||||
_eventStream = StreamController<XmppSocketEvent>.broadcast();
|
||||
int _state = 0;
|
||||
final StreamController<String> _dataStream;
|
||||
final StreamController<XmppSocketEvent> _eventStream;
|
||||
final StreamController<String> _dataStream = StreamController<String>.broadcast();
|
||||
final StreamController<XmppSocketEvent> _eventStream = StreamController<XmppSocketEvent>.broadcast();
|
||||
final List<ExpectationBase> _play;
|
||||
String? lastId;
|
||||
|
||||
@ -99,9 +157,11 @@ class StubTCPSocket extends BaseSocketWrapper { // Request -> Response(s)
|
||||
str = str.substring(0, str.length - 16);
|
||||
}
|
||||
|
||||
if (!expectation.matches(str)) {
|
||||
expect(true, false, reason: 'Expected ${expectation.expectation}, got $str');
|
||||
}
|
||||
expect(
|
||||
expectation.matches(str),
|
||||
true,
|
||||
reason: 'Expected ${expectation.expectation}, got $str',
|
||||
);
|
||||
|
||||
// Make sure to only progress if everything passed so far
|
||||
_state++;
|
||||
@ -109,7 +169,7 @@ class StubTCPSocket extends BaseSocketWrapper { // Request -> Response(s)
|
||||
var response = expectation.response;
|
||||
if (expectation is StanzaExpectation) {
|
||||
final inputNode = XMLNode.fromString(str);
|
||||
lastId = inputNode.attributes['id'];
|
||||
lastId = inputNode.attributes['id'] as String?;
|
||||
|
||||
if (expectation.adjustId) {
|
||||
final outputNode = XMLNode.fromString(response);
|
||||
|
@ -29,4 +29,52 @@ void main() {
|
||||
expect(compareXMLNodes(node1.firstTag('body')!, XMLNode.fromString('<body>Hallo</body>')), true);
|
||||
expect(compareXMLNodes(node1.firstTagByXmlns('a')!, XMLNode.fromString('<a xmlns="a" />')), true);
|
||||
});
|
||||
|
||||
test('Test compareXMLNodes', () {
|
||||
final node1 = XMLNode.fromString('''
|
||||
<iq type='set' id='0327c373-2e34-46bd-ab7f-1274a6f7095f' to='pubsub.server.example.org' from='testuser@example.org/MU29eEZn' xmlns='jabber:client'>
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
||||
<publish node='princely_musings'>
|
||||
<item id='current'>
|
||||
<test-item />
|
||||
</item>
|
||||
</publish>
|
||||
<publish-options >
|
||||
<x xmlns='jabber:x:data' type='submit'>
|
||||
<field var='FORM_TYPE' type='hidden'>
|
||||
<value>http://jabber.org/protocol/pubsub#publish-options</value>
|
||||
</field>
|
||||
<field var='pubsub#max_items'>
|
||||
<value>max</value>
|
||||
</field>
|
||||
</x>
|
||||
</publish-options>
|
||||
</pubsub>
|
||||
</iq>
|
||||
''',
|
||||
);
|
||||
final node2 = XMLNode.fromString('''
|
||||
<iq type="set" to="pubsub.server.example.org" id="a">
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
||||
<publish node='princely_musings'>
|
||||
<item id="current">
|
||||
<test-item />
|
||||
</item>
|
||||
</publish>
|
||||
<publish-options>
|
||||
<x xmlns='jabber:x:data' type='submit'>
|
||||
<field var='FORM_TYPE' type='hidden'>
|
||||
<value>http://jabber.org/protocol/pubsub#publish-options</value>
|
||||
</field>
|
||||
<field var='pubsub#max_items'>
|
||||
<value>1</value>
|
||||
</field>
|
||||
</x>
|
||||
</publish-options>
|
||||
</pubsub>
|
||||
</iq>
|
||||
''');
|
||||
|
||||
expect(compareXMLNodes(node1, node2, ignoreId: true), false);
|
||||
});
|
||||
}
|
||||
|
@ -2,121 +2,23 @@ import 'package:moxxmpp/moxxmpp.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../helpers/logging.dart';
|
||||
import '../helpers/manager.dart';
|
||||
import '../helpers/xmpp.dart';
|
||||
|
||||
class StubbedDiscoManager extends DiscoManager {
|
||||
StubbedDiscoManager() : super([]);
|
||||
StubbedDiscoManager(this._itemError) : super([]);
|
||||
|
||||
final bool _itemError;
|
||||
|
||||
@override
|
||||
Future<Result<DiscoError, DiscoInfo>> discoInfoQuery(String entity, { String? node, bool shouldEncrypt = true }) async {
|
||||
final result = DiscoInfo.fromQuery(
|
||||
XMLNode.fromString(
|
||||
'''<query xmlns='http://jabber.org/protocol/disco#info'>
|
||||
<identity category='account' type='registered'/>
|
||||
<identity type='service' category='pubsub' name='PubSub acs-clustered'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#retrieve-default'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#purge-nodes'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#subscribe'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#member-affiliation'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#subscription-notifications'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#create-nodes'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#outcast-affiliation'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#get-pending'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#presence-notifications'/>
|
||||
<feature var='urn:xmpp:ping'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#delete-nodes'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#config-node'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#retrieve-items'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#access-whitelist'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#access-presence'/>
|
||||
<feature var='http://jabber.org/protocol/disco#items'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#meta-data'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#multi-items'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#item-ids'/>
|
||||
<feature var='urn:xmpp:mam:1'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#instant-nodes'/>
|
||||
<feature var='urn:xmpp:mam:2'/>
|
||||
<feature var='urn:xmpp:mam:2#extended'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#modify-affiliations'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#multi-collection'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#persistent-items'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#create-and-configure'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#publisher-affiliation'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#access-open'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#retrieve-affiliations'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#access-authorize'/>
|
||||
<feature var='jabber:iq:version'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#retract-items'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#manage-subscriptions'/>
|
||||
<feature var='http://jabber.org/protocol/commands'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#auto-subscribe'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#publish-options'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#access-roster'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#publish'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#collections'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#retrieve-subscriptions'/>
|
||||
<feature var='http://jabber.org/protocol/disco#info'/>
|
||||
<x type='result' xmlns='jabber:x:data'>
|
||||
<field type='hidden' var='FORM_TYPE'>
|
||||
<value>http://jabber.org/network/serverinfo</value>
|
||||
</field>
|
||||
<field type='list-multi' var='abuse-addresses'>
|
||||
<value>mailto:support@tigase.net</value>
|
||||
<value>xmpp:tigase@mix.tigase.im</value>
|
||||
<value>xmpp:tigase@muc.tigase.org</value>
|
||||
<value>https://tigase.net/technical-support</value>
|
||||
</field>
|
||||
</x>
|
||||
<feature var='http://jabber.org/protocol/pubsub#auto-create'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#auto-subscribe'/>
|
||||
<feature var='urn:xmpp:mix:pam:2'/>
|
||||
<feature var='urn:xmpp:carbons:2'/>
|
||||
<feature var='urn:xmpp:carbons:rules:0'/>
|
||||
<feature var='jabber:iq:auth'/>
|
||||
<feature var='vcard-temp'/>
|
||||
<feature var='http://jabber.org/protocol/amp'/>
|
||||
<feature var='msgoffline'/>
|
||||
<feature var='http://jabber.org/protocol/disco#info'/>
|
||||
<feature var='http://jabber.org/protocol/disco#items'/>
|
||||
<feature var='urn:xmpp:blocking'/>
|
||||
<feature var='urn:xmpp:reporting:0'/>
|
||||
<feature var='urn:xmpp:reporting:abuse:0'/>
|
||||
<feature var='urn:xmpp:reporting:spam:0'/>
|
||||
<feature var='urn:xmpp:reporting:1'/>
|
||||
<feature var='urn:xmpp:ping'/>
|
||||
<feature var='urn:ietf:params:xml:ns:xmpp-sasl'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#owner'/>
|
||||
<feature var='http://jabber.org/protocol/pubsub#publish'/>
|
||||
<identity type='pep' category='pubsub'/>
|
||||
<feature var='urn:xmpp:pep-vcard-conversion:0'/>
|
||||
<feature var='urn:xmpp:bookmarks-conversion:0'/>
|
||||
<feature var='urn:xmpp:archive:auto'/>
|
||||
<feature var='urn:xmpp:archive:manage'/>
|
||||
<feature var='urn:xmpp:push:0'/>
|
||||
<feature var='tigase:push:away:0'/>
|
||||
<feature var='tigase:push:encrypt:0'/>
|
||||
<feature var='tigase:push:encrypt:aes-128-gcm'/>
|
||||
<feature var='tigase:push:filter:ignore-unknown:0'/>
|
||||
<feature var='tigase:push:filter:groupchat:0'/>
|
||||
<feature var='tigase:push:filter:muted:0'/>
|
||||
<feature var='tigase:push:priority:0'/>
|
||||
<feature var='tigase:push:jingle:0'/>
|
||||
<feature var='jabber:iq:roster'/>
|
||||
<feature var='jabber:iq:roster-dynamic'/>
|
||||
<feature var='urn:xmpp:mam:1'/>
|
||||
<feature var='urn:xmpp:mam:2'/>
|
||||
<feature var='urn:xmpp:mam:2#extended'/>
|
||||
<feature var='urn:xmpp:mix:pam:2#archive'/>
|
||||
<feature var='jabber:iq:version'/>
|
||||
<feature var='urn:xmpp:time'/>
|
||||
<feature var='jabber:iq:privacy'/>
|
||||
<feature var='urn:ietf:params:xml:ns:xmpp-bind'/>
|
||||
<feature var='urn:xmpp:extdisco:2'/>
|
||||
<feature var='http://jabber.org/protocol/commands'/>
|
||||
<feature var='urn:ietf:params:xml:ns:vcard-4.0'/>
|
||||
<feature var='jabber:iq:private'/>
|
||||
<feature var='urn:ietf:params:xml:ns:xmpp-session'/>
|
||||
'''
|
||||
<query xmlns='http://jabber.org/protocol/disco#info'>
|
||||
<identity category='pubsub' type='service' />
|
||||
<feature var="http://jabber.org/protocol/pubsub" />
|
||||
<feature var="http://jabber.org/protocol/pubsub#multi-items" />
|
||||
</query>'''
|
||||
),
|
||||
JID.fromString('pubsub.server.example.org'),
|
||||
@ -124,49 +26,156 @@ class StubbedDiscoManager extends DiscoManager {
|
||||
|
||||
return Result(result);
|
||||
}
|
||||
}
|
||||
|
||||
T? getDiscoManagerStub<T extends XmppManagerBase>(String id) {
|
||||
return StubbedDiscoManager() as T;
|
||||
@override
|
||||
Future<Result<DiscoError, List<DiscoItem>>> discoItemsQuery(String entity, {String? node, bool shouldEncrypt = true}) async {
|
||||
if (_itemError) {
|
||||
return Result(
|
||||
UnknownDiscoError(),
|
||||
);
|
||||
}
|
||||
return const Result<DiscoError, List<DiscoItem>>(
|
||||
<DiscoItem>[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
initLogger();
|
||||
|
||||
test('Test publishing with pubsub#max_items when the server does not support it', () async {
|
||||
XMLNode? sent;
|
||||
test('Test pre-processing with pubsub#max_items when the server does not support it (1/2)', () async {
|
||||
final manager = PubSubManager();
|
||||
manager.register(
|
||||
XmppManagerAttributes(
|
||||
sendStanza: (stanza, { StanzaFromType addFrom = StanzaFromType.full, bool addId = true, bool awaitable = true, bool encrypted = false, bool forceEncryption = false, }) async {
|
||||
sent = stanza;
|
||||
final TestingManagerHolder tm = TestingManagerHolder();
|
||||
await tm.register(StubbedDiscoManager(false));
|
||||
await tm.register(manager);
|
||||
|
||||
return XMLNode.fromString('<iq />');
|
||||
},
|
||||
sendNonza: (_) {},
|
||||
sendEvent: (_) {},
|
||||
getManagerById: getDiscoManagerStub,
|
||||
getConnectionSettings: () => ConnectionSettings(
|
||||
jid: JID.fromString('hallo@example.server'),
|
||||
password: 'password',
|
||||
useDirectTLS: true,
|
||||
allowPlainAuth: false,
|
||||
),
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('hallo@example.server/uwu'),
|
||||
getSocket: () => StubTCPSocket(play: []),
|
||||
getConnection: () => XmppConnection(TestingReconnectionPolicy(), AlwaysConnectedConnectivityManager(), StubTCPSocket(play: [])),
|
||||
getNegotiatorById: getNegotiatorNullStub,
|
||||
),
|
||||
final result = await manager.preprocessPublishOptions(
|
||||
'pubsub.server.example.org',
|
||||
'urn:xmpp:omemo:2:bundles',
|
||||
const PubSubPublishOptions(maxItems: 'max'),
|
||||
);
|
||||
|
||||
// final result = await manager.preprocessPublishOptions(
|
||||
// 'pubsub.server.example.org',
|
||||
// 'example:node',
|
||||
// PubSubPublishOptions(
|
||||
// maxItems: 'max',
|
||||
// ),
|
||||
// );
|
||||
expect(result.maxItems, '1');
|
||||
});
|
||||
|
||||
test('Test pre-processing with pubsub#max_items when the server does not support it (2/2)', () async {
|
||||
final manager = PubSubManager();
|
||||
final TestingManagerHolder tm = TestingManagerHolder();
|
||||
await tm.register(StubbedDiscoManager(true));
|
||||
await tm.register(manager);
|
||||
|
||||
final result = await manager.preprocessPublishOptions(
|
||||
'pubsub.server.example.org',
|
||||
'urn:xmpp:omemo:2:bundles',
|
||||
const PubSubPublishOptions(maxItems: 'max'),
|
||||
);
|
||||
|
||||
expect(result.maxItems, '1');
|
||||
});
|
||||
|
||||
test('Test publishing with pubsub#max_items when the server does not support it', () async {
|
||||
final socket = StubTCPSocket.authenticated(
|
||||
TestingManagerHolder.settings,
|
||||
[
|
||||
StanzaExpectation(
|
||||
'''
|
||||
<iq type="get" to="pubsub.server.example.org" id="a" from="testuser@example.org/MU29eEZn" xmlns="jabber:client">
|
||||
<query xmlns="http://jabber.org/protocol/disco#info" />
|
||||
</iq>
|
||||
''',
|
||||
'''
|
||||
<iq type="result" from="pubsub.server.example.org" id="a" xmlns="jabber:client">
|
||||
<query xmlns="http://jabber.org/protocol/disco#info">
|
||||
<identity category='pubsub' type='service' />
|
||||
<feature var="http://jabber.org/protocol/pubsub" />
|
||||
<feature var="http://jabber.org/protocol/pubsub#multi-items" />
|
||||
</query>
|
||||
</iq>
|
||||
''',
|
||||
ignoreId: true,
|
||||
adjustId: true,
|
||||
),
|
||||
StanzaExpectation(
|
||||
'''
|
||||
<iq type="get" to="pubsub.server.example.org" id="a" from="testuser@example.org/MU29eEZn" xmlns="jabber:client">
|
||||
<query xmlns="http://jabber.org/protocol/disco#items" node="princely_musings" />
|
||||
</iq>
|
||||
''',
|
||||
'''
|
||||
<iq type="result" from="pubsub.server.example.org" id="a" xmlns="jabber:client">
|
||||
<query xmlns="http://jabber.org/protocol/disco#items" node="princely_musings" />
|
||||
</iq>
|
||||
''',
|
||||
ignoreId: true,
|
||||
adjustId: true,
|
||||
),
|
||||
StanzaExpectation(
|
||||
'''
|
||||
<iq type="set" to="pubsub.server.example.org" id="a" from="testuser@example.org/MU29eEZn" xmlns="jabber:client">
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
||||
<publish node='princely_musings'>
|
||||
<item id="current">
|
||||
<test-item />
|
||||
</item>
|
||||
</publish>
|
||||
<publish-options>
|
||||
<x xmlns='jabber:x:data' type='submit'>
|
||||
<field var='FORM_TYPE' type='hidden'>
|
||||
<value>http://jabber.org/protocol/pubsub#publish-options</value>
|
||||
</field>
|
||||
<field var='pubsub#max_items'>
|
||||
<value>1</value>
|
||||
</field>
|
||||
</x>
|
||||
</publish-options>
|
||||
</pubsub>
|
||||
</iq>''',
|
||||
'''
|
||||
<iq type="result" from="pubsub.server.example.org" id="a" xmlns="jabber:client">
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
||||
<publish node='princely_musings'>
|
||||
<item id='current'/>
|
||||
</publish>
|
||||
</pubsub>
|
||||
</iq>''',
|
||||
ignoreId: true,
|
||||
adjustId: true,
|
||||
)
|
||||
],
|
||||
);
|
||||
|
||||
final connection = XmppConnection(
|
||||
TestingReconnectionPolicy(),
|
||||
AlwaysConnectedConnectivityManager(),
|
||||
socket,
|
||||
);
|
||||
|
||||
await connection.registerManagers([
|
||||
PubSubManager(),
|
||||
DiscoManager([]),
|
||||
PresenceManager(),
|
||||
MessageManager(),
|
||||
RosterManager(TestingRosterStateManager(null, [])),
|
||||
PingManager(),
|
||||
]);
|
||||
connection..registerFeatureNegotiators([
|
||||
SaslPlainNegotiator(),
|
||||
ResourceBindingNegotiator(),
|
||||
])
|
||||
..setConnectionSettings(TestingManagerHolder.settings);
|
||||
await connection.connect(
|
||||
waitUntilLogin: true,
|
||||
);
|
||||
|
||||
final item = XMLNode(tag: "test-item");
|
||||
final result = await connection.getManagerById<PubSubManager>(pubsubManager)!.publish(
|
||||
'pubsub.server.example.org',
|
||||
'princely_musings',
|
||||
item,
|
||||
id: 'current',
|
||||
options: const PubSubPublishOptions(maxItems: 'max'),
|
||||
);
|
||||
|
||||
expect(result.isType<bool>(), true);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user