summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test_events.py3
-rw-r--r--tests/test_jid.py10
-rw-r--r--tests/test_stanza_base.py3
-rw-r--r--tests/test_stanza_element.py5
-rw-r--r--tests/test_stanza_error.py3
-rw-r--r--tests/test_stanza_gmail.py5
-rw-r--r--tests/test_stanza_iq.py3
-rw-r--r--tests/test_stanza_message.py8
-rw-r--r--tests/test_stanza_presence.py6
-rw-r--r--tests/test_stanza_roster.py5
-rw-r--r--tests/test_stanza_xep_0004.py5
-rw-r--r--tests/test_stanza_xep_0030.py5
-rw-r--r--tests/test_stanza_xep_0033.py5
-rw-r--r--tests/test_stanza_xep_0047.py6
-rw-r--r--tests/test_stanza_xep_0050.py4
-rw-r--r--tests/test_stanza_xep_0059.py4
-rw-r--r--tests/test_stanza_xep_0060.py18
-rw-r--r--tests/test_stanza_xep_0085.py6
-rw-r--r--tests/test_stanza_xep_0184.py5
-rw-r--r--tests/test_stanza_xep_0323.py393
-rw-r--r--tests/test_stanza_xep_0325.py248
-rw-r--r--tests/test_stream.py3
-rw-r--r--tests/test_stream_exceptions.py5
-rw-r--r--tests/test_stream_filters.py7
-rw-r--r--tests/test_stream_handlers.py16
-rw-r--r--tests/test_stream_presence.py3
-rw-r--r--tests/test_stream_roster.py28
-rw-r--r--tests/test_stream_xep_0030.py4
-rw-r--r--tests/test_stream_xep_0047.py3
-rw-r--r--tests/test_stream_xep_0050.py7
-rw-r--r--tests/test_stream_xep_0059.py3
-rw-r--r--tests/test_stream_xep_0060.py7
-rw-r--r--tests/test_stream_xep_0066.py4
-rw-r--r--tests/test_stream_xep_0085.py4
-rw-r--r--tests/test_stream_xep_0092.py9
-rw-r--r--tests/test_stream_xep_0128.py8
-rw-r--r--tests/test_stream_xep_0249.py6
-rw-r--r--tests/test_stream_xep_0323.py1250
-rw-r--r--tests/test_stream_xep_0325.py365
-rw-r--r--tests/test_tostring.py6
40 files changed, 2383 insertions, 105 deletions
diff --git a/tests/test_events.py b/tests/test_events.py
index fb34be30..a41ed017 100644
--- a/tests/test_events.py
+++ b/tests/test_events.py
@@ -1,5 +1,6 @@
import time
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestEvents(SleekTest):
diff --git a/tests/test_jid.py b/tests/test_jid.py
index aeb635a1..ed2aeea9 100644
--- a/tests/test_jid.py
+++ b/tests/test_jid.py
@@ -1,5 +1,9 @@
-from sleekxmpp.test import *
+# -*- encoding: utf8 -*-
+from __future__ import unicode_literals
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp import JID, InvalidJID
+from sleekxmpp.jid import nodeprep
class TestJIDClass(SleekTest):
@@ -278,5 +282,9 @@ class TestJIDClass(SleekTest):
#self.assertRaises(InvalidJID, JID, '%s@example.com' % '\\20foo2')
#self.assertRaises(InvalidJID, JID, '%s@example.com' % 'bar2\\20')
+ def testNodePrepIdemptotent(self):
+ node = 'ᴹᴵᴷᴬᴱᴸ'
+ self.assertEqual(nodeprep(node), nodeprep(nodeprep(node)))
+
suite = unittest.TestLoader().loadTestsFromTestCase(TestJIDClass)
diff --git a/tests/test_stanza_base.py b/tests/test_stanza_base.py
index 9bd326b6..deb7ab96 100644
--- a/tests/test_stanza_base.py
+++ b/tests/test_stanza_base.py
@@ -1,4 +1,5 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.xmlstream.stanzabase import ET, StanzaBase
diff --git a/tests/test_stanza_element.py b/tests/test_stanza_element.py
index b7ccdb87..2b9676cf 100644
--- a/tests/test_stanza_element.py
+++ b/tests/test_stanza_element.py
@@ -1,5 +1,6 @@
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream.stanzabase import ElementBase
+import unittest
+from sleekxmpp.test import SleekTest
+from sleekxmpp.xmlstream.stanzabase import ElementBase, register_stanza_plugin, ET
from sleekxmpp.thirdparty import OrderedDict
diff --git a/tests/test_stanza_error.py b/tests/test_stanza_error.py
index a41bf4bf..d95a33ce 100644
--- a/tests/test_stanza_error.py
+++ b/tests/test_stanza_error.py
@@ -1,4 +1,5 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestErrorStanzas(SleekTest):
diff --git a/tests/test_stanza_gmail.py b/tests/test_stanza_gmail.py
index 6190c608..a15fea20 100644
--- a/tests/test_stanza_gmail.py
+++ b/tests/test_stanza_gmail.py
@@ -1,5 +1,8 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp import Iq
+from sleekxmpp.test import SleekTest
import sleekxmpp.plugins.gmail_notify as gmail
+from sleekxmpp.xmlstream import register_stanza_plugin, ET
class TestGmail(SleekTest):
diff --git a/tests/test_stanza_iq.py b/tests/test_stanza_iq.py
index 42e4dcde..0f5e30b0 100644
--- a/tests/test_stanza_iq.py
+++ b/tests/test_stanza_iq.py
@@ -1,4 +1,5 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.xmlstream.stanzabase import ET
diff --git a/tests/test_stanza_message.py b/tests/test_stanza_message.py
index e55971df..9968a630 100644
--- a/tests/test_stanza_message.py
+++ b/tests/test_stanza_message.py
@@ -1,6 +1,8 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.stanza.message import Message
from sleekxmpp.stanza.htmlim import HTMLIM
+from sleekxmpp.xmlstream import register_stanza_plugin
class TestMessageStanzas(SleekTest):
@@ -30,9 +32,7 @@ class TestMessageStanzas(SleekTest):
msg['to'] = "fritzy@netflint.net/sleekxmpp"
msg['body'] = "this is the plaintext message"
msg['type'] = 'chat'
- p = ET.Element('{http://www.w3.org/1999/xhtml}p')
- p.text = "This is the htmlim message"
- msg['html']['body'] = p
+ msg['html']['body'] = '<p>This is the htmlim message</p>'
self.check(msg, """
<message to="fritzy@netflint.net/sleekxmpp" type="chat">
<body>this is the plaintext message</body>
diff --git a/tests/test_stanza_presence.py b/tests/test_stanza_presence.py
index 2ec43b65..184dce96 100644
--- a/tests/test_stanza_presence.py
+++ b/tests/test_stanza_presence.py
@@ -1,6 +1,6 @@
-from sleekxmpp.test import *
-from sleekxmpp.stanza.presence import Presence
-
+import unittest
+import sleekxmpp
+from sleekxmpp.test import SleekTest
class TestPresenceStanzas(SleekTest):
diff --git a/tests/test_stanza_roster.py b/tests/test_stanza_roster.py
index 8ec2d32b..d121568b 100644
--- a/tests/test_stanza_roster.py
+++ b/tests/test_stanza_roster.py
@@ -1,5 +1,6 @@
-from sleekxmpp.test import *
-from sleekxmpp.stanza.roster import Roster
+import unittest
+from sleekxmpp.test import SleekTest
+from sleekxmpp.xmlstream import ET
class TestRosterStanzas(SleekTest):
diff --git a/tests/test_stanza_xep_0004.py b/tests/test_stanza_xep_0004.py
index e183e5e9..9056c663 100644
--- a/tests/test_stanza_xep_0004.py
+++ b/tests/test_stanza_xep_0004.py
@@ -1,7 +1,10 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp import Message
+from sleekxmpp.test import SleekTest
from sleekxmpp.thirdparty import OrderedDict
import sleekxmpp.plugins.xep_0004 as xep_0004
+from sleekxmpp.xmlstream import register_stanza_plugin
class TestDataForms(SleekTest):
diff --git a/tests/test_stanza_xep_0030.py b/tests/test_stanza_xep_0030.py
index 2d64988d..986c1880 100644
--- a/tests/test_stanza_xep_0030.py
+++ b/tests/test_stanza_xep_0030.py
@@ -1,5 +1,8 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp import Iq
+from sleekxmpp.test import SleekTest
import sleekxmpp.plugins.xep_0030 as xep_0030
+from sleekxmpp.xmlstream import register_stanza_plugin
class TestDisco(SleekTest):
diff --git a/tests/test_stanza_xep_0033.py b/tests/test_stanza_xep_0033.py
index ec9a5309..bf10cf6c 100644
--- a/tests/test_stanza_xep_0033.py
+++ b/tests/test_stanza_xep_0033.py
@@ -1,5 +1,8 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp import Message
+from sleekxmpp.test import SleekTest
import sleekxmpp.plugins.xep_0033 as xep_0033
+from sleekxmpp.xmlstream import register_stanza_plugin
class TestAddresses(SleekTest):
diff --git a/tests/test_stanza_xep_0047.py b/tests/test_stanza_xep_0047.py
index 6aa2314b..9fd3c4d6 100644
--- a/tests/test_stanza_xep_0047.py
+++ b/tests/test_stanza_xep_0047.py
@@ -1,5 +1,9 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.exceptions import XMPPError
+from sleekxmpp import Iq
+from sleekxmpp.test import SleekTest
from sleekxmpp.plugins.xep_0047 import Data
+from sleekxmpp.xmlstream import register_stanza_plugin, ET
class TestIBB(SleekTest):
diff --git a/tests/test_stanza_xep_0050.py b/tests/test_stanza_xep_0050.py
index e02e86c3..9d49b3ee 100644
--- a/tests/test_stanza_xep_0050.py
+++ b/tests/test_stanza_xep_0050.py
@@ -1,6 +1,8 @@
from sleekxmpp import Iq
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.plugins.xep_0050 import Command
+from sleekxmpp.xmlstream import register_stanza_plugin
class TestAdHocCommandStanzas(SleekTest):
diff --git a/tests/test_stanza_xep_0059.py b/tests/test_stanza_xep_0059.py
index 913436a6..860ec869 100644
--- a/tests/test_stanza_xep_0059.py
+++ b/tests/test_stanza_xep_0059.py
@@ -1,5 +1,7 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.plugins.xep_0059 import Set
+from sleekxmpp.xmlstream import ET
class TestSetStanzas(SleekTest):
diff --git a/tests/test_stanza_xep_0060.py b/tests/test_stanza_xep_0060.py
index 16a7cb37..332b53ea 100644
--- a/tests/test_stanza_xep_0060.py
+++ b/tests/test_stanza_xep_0060.py
@@ -1,6 +1,8 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
import sleekxmpp.plugins.xep_0004 as xep_0004
import sleekxmpp.plugins.xep_0060.stanza as pubsub
+from sleekxmpp.xmlstream.stanzabase import ET
class TestPubsubStanzas(SleekTest):
@@ -129,20 +131,6 @@ class TestPubsubStanzas(SleekTest):
</pubsub>
</iq>""")
- def testState(self):
- "Testing iq/psstate stanzas"
- iq = self.Iq()
- iq['psstate']['node']= 'mynode'
- iq['psstate']['item']= 'myitem'
- pl = ET.Element('{http://andyet.net/protocol/pubsubqueue}claimed')
- iq['psstate']['payload'] = pl
- self.check(iq, """
- <iq id="0">
- <state xmlns="http://jabber.org/protocol/psstate" node="mynode" item="myitem">
- <claimed xmlns="http://andyet.net/protocol/pubsubqueue" />
- </state>
- </iq>""")
-
def testDefault(self):
"Testing iq/pubsub_owner/default stanzas"
iq = self.Iq()
diff --git a/tests/test_stanza_xep_0085.py b/tests/test_stanza_xep_0085.py
index 61784e47..303e6c5b 100644
--- a/tests/test_stanza_xep_0085.py
+++ b/tests/test_stanza_xep_0085.py
@@ -1,5 +1,9 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp import Message
+from sleekxmpp.test import SleekTest
import sleekxmpp.plugins.xep_0085 as xep_0085
+from sleekxmpp.xmlstream import register_stanza_plugin
+
class TestChatStates(SleekTest):
diff --git a/tests/test_stanza_xep_0184.py b/tests/test_stanza_xep_0184.py
index 13472373..0c340487 100644
--- a/tests/test_stanza_xep_0184.py
+++ b/tests/test_stanza_xep_0184.py
@@ -1,5 +1,8 @@
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp import Message
+from sleekxmpp.test import SleekTest
import sleekxmpp.plugins.xep_0184 as xep_0184
+from sleekxmpp.xmlstream import register_stanza_plugin
class TestReciept(SleekTest):
diff --git a/tests/test_stanza_xep_0323.py b/tests/test_stanza_xep_0323.py
new file mode 100644
index 00000000..67e0daf0
--- /dev/null
+++ b/tests/test_stanza_xep_0323.py
@@ -0,0 +1,393 @@
+# -*- coding: utf-8 -*-
+
+from sleekxmpp.test import *
+import sleekxmpp.plugins.xep_0323 as xep_0323
+
+namespace='sn'
+
+class TestSensorDataStanzas(SleekTest):
+
+
+ def setUp(self):
+ pass
+ #register_stanza_plugin(Iq, xep_0323.stanza.Request)
+ #register_stanza_plugin(Iq, xep_0323.stanza.Accepted)
+ #register_stanza_plugin(Message, xep_0323.stanza.Failure)
+ #register_stanza_plugin(xep_0323.stanza.Failure, xep_0323.stanza.Error)
+ #register_stanza_plugin(Iq, xep_0323.stanza.Rejected)
+ #register_stanza_plugin(Message, xep_0323.stanza.Fields)
+ #register_stanza_plugin(Message, xep_0323.stanza.Request)
+ #register_stanza_plugin(Message, xep_0323.stanza.Accepted)
+ #register_stanza_plugin(Message, xep_0323.stanza.Failure)
+ # register_stanza_plugin(Message, xep_0323.stanza.Result)
+ # register_stanza_plugin(Message, xep_0323.stanza.Gone)
+ # register_stanza_plugin(Message, xep_0323.stanza.Inactive)
+ # register_stanza_plugin(Message, xep_0323.stanza.Paused)
+
+ def testRequest(self):
+ """
+ test of request stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'get'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '1'
+ iq['req']['seqnr'] = '1'
+ iq['req']['momentary'] = 'true'
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'/>
+ </iq>
+ """
+ )
+
+ def testRequestNodes(self):
+ """
+ test of request nodes stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'get'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '1'
+ iq['req']['seqnr'] = '1'
+ iq['req']['momentary'] = 'true'
+
+
+ iq['req'].add_node("Device02", "Source02", "CacheType");
+ iq['req'].add_node("Device44");
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'>
+ <node nodeId='Device02' sourceId='Source02' cacheType='CacheType'/>
+ <node nodeId='Device44'/>
+ </req>
+ </iq>
+ """
+ )
+
+ iq['req'].del_node("Device02");
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'>
+ <node nodeId='Device44'/>
+ </req>
+ </iq>
+ """
+ )
+
+ iq['req'].del_nodes();
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'>
+ </req>
+ </iq>
+ """
+ )
+
+ def testRequestField(self):
+ """
+ test of request field stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'get'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '1'
+ iq['req']['seqnr'] = '1'
+ iq['req']['momentary'] = 'true'
+
+
+ iq['req'].add_field("Top temperature");
+ iq['req'].add_field("Bottom temperature");
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'>
+ <field name='Top temperature'/>
+ <field name='Bottom temperature'/>
+ </req>
+ </iq>
+ """
+ )
+
+ iq['req'].del_field("Top temperature")
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'>
+ <field name='Bottom temperature'/>
+ </req>
+ </iq>
+ """
+ )
+
+ iq['req'].del_fields()
+
+ self.check(iq,"""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'>
+ </req>
+ </iq>
+ """
+ )
+
+
+ def testAccepted(self):
+ """
+ test of request stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'result'
+ iq['from'] = 'device@clayster.com'
+ iq['to'] = 'master@clayster.com/amr'
+ iq['id'] = '2'
+ iq['accepted']['seqnr'] = '2'
+
+ self.check(iq,"""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='2'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='2'/>
+ </iq>
+ """
+ )
+
+ def testRejected(self):
+ """
+ test of request stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'error'
+ iq['from'] = 'device@clayster.com'
+ iq['to'] = 'master@clayster.com/amr'
+ iq['id'] = '4'
+ iq['rejected']['seqnr'] = '4'
+ iq['rejected']['error'] = 'Access denied.'
+
+ self.check(iq,"""
+ <iq type='error'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='4'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='4'>
+ <error>Access denied.</error>
+ </rejected>
+ </iq>
+ """
+ )
+
+ def testFailure(self):
+ """
+ test of failure stanza
+ """
+ msg = self.Message()
+ msg['from'] = 'device@clayster.com'
+ msg['to'] = 'master@clayster.com/amr'
+ msg['failure']['seqnr'] = '3'
+ msg['failure']['done'] = 'true'
+ msg['failure']['error']['nodeId'] = 'Device01'
+ msg['failure']['error']['timestamp'] = '2013-03-07T17:13:30'
+ msg['failure']['error']['text'] = 'Timeout.'
+
+ self.check(msg,"""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <failure xmlns='urn:xmpp:iot:sensordata' seqnr='3' done='true'>
+ <error nodeId='Device01' timestamp='2013-03-07T17:13:30'>
+ Timeout.</error>
+ </failure>
+ </message>
+ """
+ )
+
+ def testFields(self):
+ """
+ test of fields stanza
+ """
+ msg = self.Message()
+ msg['from'] = 'device@clayster.com'
+ msg['to'] = 'master@clayster.com/amr'
+ msg['fields']['seqnr'] = '1'
+
+ node = msg['fields'].add_node("Device02");
+ ts = node.add_timestamp("2013-03-07T16:24:30");
+
+ data = ts.add_data(typename="numeric", name="Temperature", value="-12.42", unit='K');
+ data['momentary'] = 'true';
+ data['automaticReadout'] = 'true';
+
+ self.check(msg,"""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId='Device02'>
+ <timestamp value='2013-03-07T16:24:30'>
+ <numeric name='Temperature' momentary='true' automaticReadout='true' value='-12.42' unit='K'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """
+ )
+
+ node = msg['fields'].add_node("EmptyDevice");
+ node = msg['fields'].add_node("Device04");
+ ts = node.add_timestamp("EmptyTimestamp");
+
+
+ self.check(msg,"""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId='Device02'>
+ <timestamp value='2013-03-07T16:24:30'>
+ <numeric name='Temperature' momentary='true' automaticReadout='true' value='-12.42' unit='K'/>
+ </timestamp>
+ </node>
+ <node nodeId='EmptyDevice'/>
+ <node nodeId='Device04'>
+ <timestamp value='EmptyTimestamp'/>
+ </node>
+ </fields>
+ </message>
+ """
+ )
+
+ node = msg['fields'].add_node("Device77");
+ ts = node.add_timestamp("2013-05-03T12:00:01");
+ data = ts.add_data(typename="numeric", name="Temperature", value="-12.42", unit='K');
+ data['historicalDay'] = 'true';
+ data = ts.add_data(typename="numeric", name="Speed", value="312.42", unit='km/h');
+ data['historicalWeek'] = 'false';
+ data = ts.add_data(typename="string", name="Temperature name", value="Bottom oil");
+ data['historicalMonth'] = 'true';
+ data = ts.add_data(typename="string", name="Speed name", value="Top speed");
+ data['historicalQuarter'] = 'false';
+ data = ts.add_data(typename="dateTime", name="T1", value="1979-01-01T00:00:00");
+ data['historicalYear'] = 'true';
+ data = ts.add_data(typename="dateTime", name="T2", value="2000-01-01T01:02:03");
+ data['historicalOther'] = 'false';
+ data = ts.add_data(typename="timeSpan", name="TS1", value="P5Y");
+ data['missing'] = 'true';
+ data = ts.add_data(typename="timeSpan", name="TS2", value="PT2M1S");
+ data['manualEstimate'] = 'false';
+ data = ts.add_data(typename="enum", name="top color", value="red", dataType="string");
+ data['invoiced'] = 'true';
+ data = ts.add_data(typename="enum", name="bottom color", value="black", dataType="string");
+ data['powerFailure'] = 'false';
+ data = ts.add_data(typename="boolean", name="Temperature real", value="false");
+ data['historicalDay'] = 'true';
+ data = ts.add_data(typename="boolean", name="Speed real", value="true");
+ data['historicalWeek'] = 'false';
+
+ self.check(msg,"""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId='Device02'>
+ <timestamp value='2013-03-07T16:24:30'>
+ <numeric name='Temperature' momentary='true' automaticReadout='true' value='-12.42' unit='K'/>
+ </timestamp>
+ </node>
+ <node nodeId='EmptyDevice'/>
+ <node nodeId='Device04'>
+ <timestamp value='EmptyTimestamp'/>
+ </node>
+ <node nodeId='Device77'>
+ <timestamp value='2013-05-03T12:00:01'>
+ <numeric name='Temperature' historicalDay='true' value='-12.42' unit='K'/>
+ <numeric name='Speed' historicalWeek='false' value='312.42' unit='km/h'/>
+ <string name='Temperature name' historicalMonth='true' value='Bottom oil'/>
+ <string name='Speed name' historicalQuarter='false' value='Top speed'/>
+ <dateTime name='T1' historicalYear='true' value='1979-01-01T00:00:00'/>
+ <dateTime name='T2' historicalOther='false' value='2000-01-01T01:02:03'/>
+ <timeSpan name='TS1' missing='true' value='P5Y'/>
+ <timeSpan name='TS2' manualEstimate='false' value='PT2M1S'/>
+ <enum name='top color' invoiced='true' value='red' dataType='string'/>
+ <enum name='bottom color' powerFailure='false' value='black' dataType='string'/>
+ <boolean name='Temperature real' historicalDay='true' value='false'/>
+ <boolean name='Speed real' historicalWeek='false' value='true'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """
+ )
+
+
+ def testTimestamp(self):
+ msg = self.Message();
+
+ msg['from'] = 'device@clayster.com'
+ msg['to'] = 'master@clayster.com/amr'
+ msg['fields']['seqnr'] = '1'
+
+ node = msg['fields'].add_node("Device02");
+ node = msg['fields'].add_node("Device03");
+
+ ts = node.add_timestamp("2013-03-07T16:24:30");
+ ts = node.add_timestamp("2013-03-07T16:24:31");
+
+
+
+ self.check(msg,"""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId='Device02'/>
+ <node nodeId='Device03'>
+ <timestamp value='2013-03-07T16:24:30'/>
+ <timestamp value='2013-03-07T16:24:31'/>
+ </node>
+ </fields>
+ </message>
+ """
+ )
+
+
+ def testStringIdsMatcher(self):
+ """
+ test of StringIds follow spec
+ """
+ emptyStringIdXML='<message xmlns="jabber:client"><fields xmlns="urn:xmpp:iot:sensordata" /></message>'
+
+ msg = self.Message()
+ msg['fields']['stringIds'] = "Nisse"
+ self.check(msg,emptyStringIdXML)
+ msg['fields']['stringIds'] = "Nisse___nje#"
+ self.check(msg,emptyStringIdXML)
+ msg['fields']['stringIds'] = "1"
+ self.check(msg,emptyStringIdXML)
+
+
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestSensorDataStanzas)
diff --git a/tests/test_stanza_xep_0325.py b/tests/test_stanza_xep_0325.py
new file mode 100644
index 00000000..b15b764c
--- /dev/null
+++ b/tests/test_stanza_xep_0325.py
@@ -0,0 +1,248 @@
+# -*- coding: utf-8 -*-
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Implementation of xeps for Internet of Things
+ http://wiki.xmpp.org/web/Tech_pages/IoT_systems
+ Copyright (C) 2013 Sustainable Innovation, Joachim.lindborg@sust.se, bjorn.westrom@consoden.se
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.test import *
+import sleekxmpp.plugins.xep_0325 as xep_0325
+
+namespace='sn'
+
+class TestControlStanzas(SleekTest):
+
+
+ def setUp(self):
+ pass
+
+ def testSetRequest(self):
+ """
+ test of set request stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'set'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '1'
+ iq['set'].add_node("Device02", "Source02", "MyCacheType");
+ iq['set'].add_node("Device15");
+ iq['set'].add_data("Tjohej", "boolean", "true")
+
+ self.check(iq,"""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device02' sourceId='Source02' cacheType='MyCacheType'/>
+ <node nodeId='Device15'/>
+ <boolean name='Tjohej' value='true'/>
+ </set>
+ </iq>
+ """
+ )
+
+ iq['set'].del_node("Device02");
+
+ self.check(iq,"""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device15'/>
+ <boolean name='Tjohej' value='true'/>
+ </set>
+ </iq>
+ """
+ )
+
+ iq['set'].del_nodes();
+
+ self.check(iq,"""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <boolean name='Tjohej' value='true'/>
+ </set>
+ </iq>
+ """
+ )
+
+
+ def testDirectSet(self):
+ """
+ test of direct set stanza
+ """
+ msg = self.Message()
+ msg['from'] = 'master@clayster.com/amr'
+ msg['to'] = 'device@clayster.com'
+ msg['set'].add_node("Device02");
+ msg['set'].add_node("Device15");
+ msg['set'].add_data("Tjohej", "boolean", "true")
+
+ self.check(msg,"""
+ <message
+ from='master@clayster.com/amr'
+ to='device@clayster.com'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device02'/>
+ <node nodeId='Device15'/>
+ <boolean name='Tjohej' value='true'/>
+ </set>
+ </message>
+ """
+ )
+
+
+ def testSetResponse(self):
+ """
+ test of set response stanza
+ """
+ iq = self.Iq()
+ iq['type'] = 'result'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '8'
+ iq['setResponse']['responseCode'] = "OK";
+
+ self.check(iq,"""
+ <iq type='result'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='8'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode='OK' />
+ </iq>
+ """
+ )
+
+ iq = self.Iq()
+ iq['type'] = 'error'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '9'
+ iq['setResponse']['responseCode'] = "OtherError";
+ iq['setResponse']['error']['var'] = "Output";
+ iq['setResponse']['error']['text'] = "Test of other error.!";
+
+
+ self.check(iq,"""
+ <iq type='error'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='9'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode='OtherError'>
+ <error var='Output'>Test of other error.!</error>
+ </setResponse>
+ </iq>
+ """
+ )
+
+ iq = self.Iq()
+ iq['type'] = 'error'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '9'
+ iq['setResponse']['responseCode'] = "NotFound";
+ iq['setResponse'].add_node("Device17", "Source09");
+ iq['setResponse'].add_node("Device18", "Source09");
+ iq['setResponse'].add_data("Tjohopp");
+
+
+ self.check(iq,"""
+ <iq type='error'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='9'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode='NotFound'>
+ <node nodeId='Device17' sourceId='Source09'/>
+ <node nodeId='Device18' sourceId='Source09'/>
+ <parameter name='Tjohopp' />
+ </setResponse>
+ </iq>
+ """
+ )
+
+ def testSetRequestDatas(self):
+ """
+ test of set request data stanzas
+ """
+ iq = self.Iq()
+ iq['type'] = 'set'
+ iq['from'] = 'master@clayster.com/amr'
+ iq['to'] = 'device@clayster.com'
+ iq['id'] = '1'
+ iq['set'].add_node("Device02", "Source02", "MyCacheType");
+ iq['set'].add_node("Device15");
+
+ iq['set'].add_data("Tjohej", "boolean", "true");
+ iq['set'].add_data("Tjohej2", "boolean", "false");
+
+ iq['set'].add_data("TjohejC", "color", "FF00FF");
+ iq['set'].add_data("TjohejC2", "color", "00FF00");
+
+ iq['set'].add_data("TjohejS", "string", "String1");
+ iq['set'].add_data("TjohejS2", "string", "String2");
+
+ iq['set'].add_data("TjohejDate", "date", "2012-01-01");
+ iq['set'].add_data("TjohejDate2", "date", "1900-12-03");
+
+ iq['set'].add_data("TjohejDateT4", "dateTime", "1900-12-03 12:30");
+ iq['set'].add_data("TjohejDateT2", "dateTime", "1900-12-03 11:22");
+
+ iq['set'].add_data("TjohejDouble2", "double", "200.22");
+ iq['set'].add_data("TjohejDouble3", "double", "-12232131.3333");
+
+ iq['set'].add_data("TjohejDur", "duration", "P5Y");
+ iq['set'].add_data("TjohejDur2", "duration", "PT2M1S");
+
+ iq['set'].add_data("TjohejInt", "int", "1");
+ iq['set'].add_data("TjohejInt2", "int", "-42");
+
+ iq['set'].add_data("TjohejLong", "long", "123456789098");
+ iq['set'].add_data("TjohejLong2", "long", "-90983243827489374");
+
+ iq['set'].add_data("TjohejTime", "time", "23:59");
+ iq['set'].add_data("TjohejTime2", "time", "12:00");
+
+ self.check(iq,"""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device02' sourceId='Source02' cacheType='MyCacheType'/>
+ <node nodeId='Device15'/>
+ <boolean name='Tjohej' value='true'/>
+ <boolean name='Tjohej2' value='false'/>
+ <color name='TjohejC' value='FF00FF'/>
+ <color name='TjohejC2' value='00FF00'/>
+ <string name='TjohejS' value='String1'/>
+ <string name='TjohejS2' value='String2'/>
+ <date name='TjohejDate' value='2012-01-01'/>
+ <date name='TjohejDate2' value='1900-12-03'/>
+ <dateTime name='TjohejDateT4' value='1900-12-03 12:30'/>
+ <dateTime name='TjohejDateT2' value='1900-12-03 11:22'/>
+ <double name='TjohejDouble2' value='200.22'/>
+ <double name='TjohejDouble3' value='-12232131.3333'/>
+ <duration name='TjohejDur' value='P5Y'/>
+ <duration name='TjohejDur2' value='PT2M1S'/>
+ <int name='TjohejInt' value='1'/>
+ <int name='TjohejInt2' value='-42'/>
+ <long name='TjohejLong' value='123456789098'/>
+ <long name='TjohejLong2' value='-90983243827489374'/>
+ <time name='TjohejTime' value='23:59'/>
+ <time name='TjohejTime2' value='12:00'/>
+ </set>
+ </iq>
+ """
+ )
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestControlStanzas)
diff --git a/tests/test_stream.py b/tests/test_stream.py
index deac24a5..f68f8426 100644
--- a/tests/test_stream.py
+++ b/tests/test_stream.py
@@ -1,5 +1,6 @@
import time
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamTester(SleekTest):
diff --git a/tests/test_stream_exceptions.py b/tests/test_stream_exceptions.py
index c41edbb2..d18d059a 100644
--- a/tests/test_stream_exceptions.py
+++ b/tests/test_stream_exceptions.py
@@ -1,9 +1,8 @@
-import sys
-import sleekxmpp
from sleekxmpp.xmlstream.matcher import MatchXPath
from sleekxmpp.xmlstream.handler import Callback
from sleekxmpp.exceptions import XMPPError
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamExceptions(SleekTest):
diff --git a/tests/test_stream_filters.py b/tests/test_stream_filters.py
index ef4d5dc8..ee17ffdc 100644
--- a/tests/test_stream_filters.py
+++ b/tests/test_stream_filters.py
@@ -1,9 +1,8 @@
import time
from sleekxmpp import Message
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream.handler import *
-from sleekxmpp.xmlstream.matcher import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestFilters(SleekTest):
@@ -84,5 +83,5 @@ class TestFilters(SleekTest):
""")
-
+
suite = unittest.TestLoader().loadTestsFromTestCase(TestFilters)
diff --git a/tests/test_stream_handlers.py b/tests/test_stream_handlers.py
index d3850a94..ef46da6a 100644
--- a/tests/test_stream_handlers.py
+++ b/tests/test_stream_handlers.py
@@ -1,9 +1,9 @@
import time
-from sleekxmpp import Message
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream.handler import *
-from sleekxmpp.xmlstream.matcher import *
+import unittest
+from sleekxmpp.test import SleekTest
+from sleekxmpp.exceptions import IqTimeout
+from sleekxmpp import Callback, MatchXPath
class TestHandlers(SleekTest):
@@ -21,7 +21,7 @@ class TestHandlers(SleekTest):
"""Test using stream callback handlers."""
def callback_handler(stanza):
- self.xmpp.sendRaw("""
+ self.xmpp.send_raw("""
<message>
<body>Success!</body>
</message>
@@ -31,7 +31,7 @@ class TestHandlers(SleekTest):
MatchXPath('{test}tester'),
callback_handler)
- self.xmpp.registerHandler(callback)
+ self.xmpp.register_handler(callback)
self.recv("""<tester xmlns="test" />""")
@@ -49,7 +49,7 @@ class TestHandlers(SleekTest):
iq['query'] = 'test'
reply = iq.send(block=True)
if reply:
- self.xmpp.sendRaw("""
+ self.xmpp.send_raw("""
<message>
<body>Successful: %s</body>
</message>
@@ -112,7 +112,7 @@ class TestHandlers(SleekTest):
time.sleep(0.1)
# Check that the waiter is no longer registered
- waiter_exists = self.xmpp.removeHandler('IqWait_test2')
+ waiter_exists = self.xmpp.remove_handler('IqWait_test2')
self.failUnless(waiter_exists == False,
"Waiter handler was not removed.")
diff --git a/tests/test_stream_presence.py b/tests/test_stream_presence.py
index 4f2ede16..365a09ed 100644
--- a/tests/test_stream_presence.py
+++ b/tests/test_stream_presence.py
@@ -1,5 +1,6 @@
import time
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamPresence(SleekTest):
diff --git a/tests/test_stream_roster.py b/tests/test_stream_roster.py
index 652ea1ce..221954ab 100644
--- a/tests/test_stream_roster.py
+++ b/tests/test_stream_roster.py
@@ -1,8 +1,9 @@
# -*- encoding:utf-8 -*-
-
from __future__ import unicode_literals
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.exceptions import IqTimeout
+from sleekxmpp.test import SleekTest
import time
import threading
@@ -19,16 +20,9 @@ class TestStreamRoster(SleekTest):
"""Test handling roster requests."""
self.stream_start(mode='client', jid='tester@localhost')
- events = []
-
- def roster_received(iq):
- events.append('roster_received')
+ roster_updates = []
- def roster_update(iq):
- events.append('roster_update')
-
- self.xmpp.add_event_handler('roster_received', roster_received)
- self.xmpp.add_event_handler('roster_update', roster_update)
+ self.xmpp.add_event_handler('roster_update', roster_updates.append)
# Since get_roster blocks, we need to run it in a thread.
t = threading.Thread(name='get_roster', target=self.xmpp.get_roster)
@@ -56,6 +50,9 @@ class TestStreamRoster(SleekTest):
# Wait for get_roster to return.
t.join()
+ # Give the event queue time to process.
+ time.sleep(.1)
+
self.check_roster('tester@localhost', 'user@localhost',
name='User',
subscription='from',
@@ -63,11 +60,8 @@ class TestStreamRoster(SleekTest):
pending_out=True,
groups=['Friends', 'Examples'])
- # Give the event queue time to process.
- time.sleep(.1)
-
- self.failUnless(events == ['roster_received', 'roster_update'],
- "Wrong roster events fired: %s" % events)
+ self.failUnless(len(roster_updates) == 1,
+ "Wrong number of roster_update events fired: %s (should be 1)" % len(roster_updates))
def testRosterSet(self):
"""Test handling pushed roster updates."""
@@ -156,7 +150,7 @@ class TestStreamRoster(SleekTest):
"""Test rejecting a roster push from an unauthorized source."""
self.stream_start()
self.recv("""
- <iq to='tester@localhost' from="malicious_user@localhost"
+ <iq to='tester@localhost' from="malicious_user@localhost"
type="set" id="1">
<query xmlns="jabber:iq:roster">
<item jid="user@localhost"
diff --git a/tests/test_stream_xep_0030.py b/tests/test_stream_xep_0030.py
index dd43778a..37d29d33 100644
--- a/tests/test_stream_xep_0030.py
+++ b/tests/test_stream_xep_0030.py
@@ -1,8 +1,8 @@
-import sys
import time
import threading
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamDisco(SleekTest):
diff --git a/tests/test_stream_xep_0047.py b/tests/test_stream_xep_0047.py
index 8c46606e..0515bca5 100644
--- a/tests/test_stream_xep_0047.py
+++ b/tests/test_stream_xep_0047.py
@@ -1,7 +1,8 @@
import threading
import time
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestInBandByteStreams(SleekTest):
diff --git a/tests/test_stream_xep_0050.py b/tests/test_stream_xep_0050.py
index 5ad9d6ae..261a0057 100644
--- a/tests/test_stream_xep_0050.py
+++ b/tests/test_stream_xep_0050.py
@@ -1,8 +1,9 @@
import time
import logging
-import threading
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
+from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin
class TestAdHocCommands(SleekTest):
@@ -35,7 +36,7 @@ class TestAdHocCommands(SleekTest):
logging.debug(initial)
new_payload = TestPayload()
if initial:
- new_payload['bar'] = 'Received: %s' % initial['bar']
+ new_payload['bar'] = 'Received: %s' % initial['bar']
else:
new_payload['bar'] = 'Failed'
diff --git a/tests/test_stream_xep_0059.py b/tests/test_stream_xep_0059.py
index 249ecf66..5f3ea079 100644
--- a/tests/test_stream_xep_0059.py
+++ b/tests/test_stream_xep_0059.py
@@ -1,6 +1,7 @@
import threading
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.xmlstream import register_stanza_plugin
from sleekxmpp.plugins.xep_0030 import DiscoItems
from sleekxmpp.plugins.xep_0059 import ResultIterator, Set
diff --git a/tests/test_stream_xep_0060.py b/tests/test_stream_xep_0060.py
index e0936660..581d5d00 100644
--- a/tests/test_stream_xep_0060.py
+++ b/tests/test_stream_xep_0060.py
@@ -1,8 +1,7 @@
-import sys
-import time
import threading
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
from sleekxmpp.stanza.atom import AtomEntry
from sleekxmpp.xmlstream import register_stanza_plugin
@@ -431,7 +430,7 @@ class TestStreamPubsub(SleekTest):
</publish>
</pubsub>
</iq>
- """)
+ """, use_values=False)
def testPublishSingleOptions(self):
"""Test publishing a single item, with options."""
diff --git a/tests/test_stream_xep_0066.py b/tests/test_stream_xep_0066.py
index e3f2ddfa..175026d2 100644
--- a/tests/test_stream_xep_0066.py
+++ b/tests/test_stream_xep_0066.py
@@ -1,7 +1,7 @@
-import time
import threading
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestOOB(SleekTest):
diff --git a/tests/test_stream_xep_0085.py b/tests/test_stream_xep_0085.py
index 2a814805..54e7e15f 100644
--- a/tests/test_stream_xep_0085.py
+++ b/tests/test_stream_xep_0085.py
@@ -1,7 +1,7 @@
-import threading
import time
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamChatStates(SleekTest):
diff --git a/tests/test_stream_xep_0092.py b/tests/test_stream_xep_0092.py
index 4a038558..c0748697 100644
--- a/tests/test_stream_xep_0092.py
+++ b/tests/test_stream_xep_0092.py
@@ -1,6 +1,7 @@
import threading
-from sleekxmpp.test import *
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamSet(SleekTest):
@@ -36,7 +37,9 @@ class TestStreamSet(SleekTest):
def query():
r = self.xmpp['xep_0092'].get_version('foo@bar')
- results.append(r)
+ results.append((r['software_version']['name'],
+ r['software_version']['version'],
+ r['software_version']['os']))
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092'])
@@ -61,7 +64,7 @@ class TestStreamSet(SleekTest):
t.join()
- expected = [{'name': 'Foo', 'version': '1.0', 'os':'Linux'}]
+ expected = [('Foo', '1.0', 'Linux')]
self.assertEqual(results, expected,
"Did not receive expected results: %s" % results)
diff --git a/tests/test_stream_xep_0128.py b/tests/test_stream_xep_0128.py
index 42fc9143..10222d9b 100644
--- a/tests/test_stream_xep_0128.py
+++ b/tests/test_stream_xep_0128.py
@@ -1,9 +1,5 @@
-import sys
-import time
-import threading
-
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream import ElementBase
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamExtendedDisco(SleekTest):
diff --git a/tests/test_stream_xep_0249.py b/tests/test_stream_xep_0249.py
index 9a25253f..8edea270 100644
--- a/tests/test_stream_xep_0249.py
+++ b/tests/test_stream_xep_0249.py
@@ -1,9 +1,7 @@
-import sys
import time
-import threading
-from sleekxmpp.test import *
-from sleekxmpp.xmlstream import ElementBase
+import unittest
+from sleekxmpp.test import SleekTest
class TestStreamDirectInvite(SleekTest):
diff --git a/tests/test_stream_xep_0323.py b/tests/test_stream_xep_0323.py
new file mode 100644
index 00000000..b10f0b0d
--- /dev/null
+++ b/tests/test_stream_xep_0323.py
@@ -0,0 +1,1250 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import datetime
+import time
+import threading
+
+from sleekxmpp.test import *
+from sleekxmpp.xmlstream import ElementBase
+from sleekxmpp.plugins.xep_0323.device import Device
+
+
+class TestStreamSensorData(SleekTest):
+
+ """
+ Test using the XEP-0323 plugin.
+ """
+ def setUp(self):
+ pass
+
+ def _time_now(self):
+ return datetime.datetime.now().replace(microsecond=0).isoformat();
+
+ def tearDown(self):
+ self.stream_close()
+
+ def testRequestAccept(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device22");
+ myDevice._add_field(name="Temperature", typename="numeric", unit="°C");
+ myDevice._set_momentary_timestamp("2013-03-07T16:24:30")
+ myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"});
+
+ self.xmpp['xep_0323'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1' done='true'>
+ <node nodeId='Device22'>
+ <timestamp value='2013-03-07T16:24:30'>
+ <numeric name='Temperature' momentary='true' automaticReadout='true' value='23.4' unit='°C'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ def testRequestRejectAuth(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ self.xmpp['xep_0323']._set_authenticated("darth@deathstar.com");
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='4'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='5' momentary='true'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='error'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='4'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='5'>
+ <error>Access denied</error>
+ </rejected>
+ </iq>
+ """)
+
+ def testRequestNode(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='77'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='66' momentary='true'>
+ <node nodeId='Device33'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='error'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='77'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='66'>
+ <error>Invalid nodeId Device33</error>
+ </rejected>
+ </iq>
+ """)
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='8'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='7' momentary='true'>
+ <node nodeId='Device44'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='8'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='7'/>
+ </iq>
+ """)
+
+
+ def testRequestField(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ myDevice._add_field(name='Voltage', typename="numeric", unit="V");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.4", timestamp="2000-01-01T00:01:02", flags={"invoiced": "true"});
+
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='7'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <field name='Current'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='error'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='7'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <error>Invalid field Current</error>
+ </rejected>
+ </iq>
+ """)
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='8'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <field name='Voltage'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='8'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='7'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-01-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.4' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7' done='true'>
+ </fields>
+ </message>
+ """)
+
+ def testRequestMultiTimestampSingleField(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ myDevice._add_field(name='Voltage', typename="numeric", unit="V");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.4", timestamp="2000-01-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field(name='Current', typename="numeric", unit="A");
+ myDevice._add_field(name='Height', typename="string");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.6", timestamp="2000-01-01T01:01:02");
+ myDevice._add_field_timestamp_data(name="Height", value="115 m", timestamp="2000-01-01T01:01:02", flags={"invoiced": "true"});
+
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='8'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <field name='Voltage'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='8'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='7'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-01-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.4' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-01-01T01:01:02'>
+ <numeric name='Voltage' value='230.6' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7' done='true'>
+ </fields>
+ </message>
+ """)
+
+ def testRequestMultiTimestampAllFields(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ myDevice._add_field(name='Voltage', typename="numeric", unit="V");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.4", timestamp="2000-01-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field(name='Current', typename="numeric", unit="A");
+ myDevice._add_field(name='Height', typename="string");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.6", timestamp="2000-01-01T01:01:02");
+ myDevice._add_field_timestamp_data(name="Height", value="115 m", timestamp="2000-01-01T01:01:02", flags={"invoiced": "true"});
+
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='8'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='7'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='8'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='7'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-01-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.4' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-01-01T01:01:02'>
+ <numeric name='Voltage' value='230.6' unit='V'/>
+ <string name='Height' invoiced='true' value='115 m'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='7' done='true'>
+ </fields>
+ </message>
+ """)
+
+ def testRequestAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", callback=None);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
+ </iq>
+ """)
+
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33', 'Device22'], callback=None);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='2'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='2'>
+ <node nodeId="Device33"/>
+ <node nodeId="Device22"/>
+ </req>
+ </iq>
+ """)
+
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", fields=['Temperature', 'Voltage'], callback=None);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='3'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='3'>
+ <field name="Temperature"/>
+ <field name="Voltage"/>
+ </req>
+ </iq>
+ """)
+
+ def testRequestRejectAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ results = [];
+
+ def my_callback(from_jid, result, nodeId=None, timestamp=None, fields=None, error_msg=None):
+ if (result == "rejected") and (error_msg == "Invalid device Device22"):
+ results.append("rejected");
+
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33', 'Device22'], callback=my_callback);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId="Device33"/>
+ <node nodeId="Device22"/>
+ </req>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='error'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <error>Invalid device Device22</error>
+ </rejected>
+ </iq>
+ """)
+
+ time.sleep(.1)
+
+ self.failUnless(results == ["rejected"],
+ "Rejected callback was not properly executed");
+
+ def testRequestAcceptedAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ results = [];
+
+ def my_callback(from_jid, result, nodeId=None, timestamp=None, fields=None, error_msg=None):
+ results.append(result);
+
+ self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33', 'Device22'], callback=my_callback);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId="Device33"/>
+ <node nodeId="Device22"/>
+ </req>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
+ </iq>
+ """)
+
+ time.sleep(.1)
+
+ self.failUnless(results == ["accepted"],
+ "Accepted callback was not properly executed");
+
+ def testRequestFieldsAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ results = [];
+ callback_data = {};
+
+ def my_callback(from_jid, result, nodeId=None, timestamp=None, fields=None, error_msg=None):
+ results.append(result);
+ if result == "fields":
+ callback_data["nodeId"] = nodeId;
+ callback_data["timestamp"] = timestamp;
+ callback_data["error_msg"] = error_msg;
+ for f in fields:
+ callback_data["field_" + f['name']] = f;
+
+ t1= threading.Thread(name="request_data",
+ target=self.xmpp['xep_0323'].request_data,
+ kwargs={"from_jid": "tester@localhost",
+ "to_jid": "you@google.com",
+ "nodeIds": ['Device33'],
+ "callback": my_callback});
+ t1.start();
+ #self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33'], callback=my_callback);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId="Device33"/>
+ </req>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
+ </iq>
+ """)
+
+ self.recv("""
+ <message from='you@google.com'
+ to='tester@localhost'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId='Device33'>
+ <timestamp value='2000-01-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.4' unit='V'/>
+ <boolean name='TestBool' value='true'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.recv("""
+ <message from='you@google.com'
+ to='tester@localhost'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1' done='true'/>
+ </message>
+ """)
+
+ t1.join();
+ time.sleep(.5)
+
+ self.failUnlessEqual(results, ["accepted","fields","done"]);
+ # self.assertIn("nodeId", callback_data);
+ self.assertTrue(callback_data.has_key("nodeId"));
+ self.failUnlessEqual(callback_data["nodeId"], "Device33");
+ # self.assertIn("timestamp", callback_data);
+ self.assertTrue(callback_data.has_key("timestamp"));
+ self.failUnlessEqual(callback_data["timestamp"], "2000-01-01T00:01:02");
+ #self.assertIn("field_Voltage", callback_data);
+ self.assertTrue(callback_data.has_key("field_Voltage"));
+ self.failUnlessEqual(callback_data["field_Voltage"], {"name": "Voltage", "value": "230.4", "typename": "numeric", "unit": "V", "flags": {"invoiced": "true"}});
+ #self.assertIn("field_TestBool", callback_data);
+ self.assertTrue(callback_data.has_key("field_TestBool"));
+ self.failUnlessEqual(callback_data["field_TestBool"], {"name": "TestBool", "value": "true", "typename": "boolean" });
+
+ def testServiceDiscoveryClient(self):
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323']);
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='tester@localhost'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ to='master@clayster.com/amr'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'>
+ <identity category='client' type='bot'/>
+ <feature var='urn:xmpp:iot:sensordata'/>
+ </query>
+ </iq>
+ """)
+
+ def testServiceDiscoveryComponent(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323']);
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='tester@localhost'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='tester@localhost'
+ to='master@clayster.com/amr'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'>
+ <identity category='component' type='generic'/>
+ <feature var='urn:xmpp:iot:sensordata'/>
+ </query>
+ </iq>
+ """)
+
+ def testRequestTimeout(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ results = [];
+ callback_data = {};
+
+ def my_callback(from_jid, result, nodeId=None, timestamp=None, error_msg=None):
+ results.append(result);
+ if result == "failure":
+ callback_data["nodeId"] = nodeId;
+ callback_data["timestamp"] = timestamp;
+ callback_data["error_msg"] = error_msg;
+
+ t1= threading.Thread(name="request_data",
+ target=self.xmpp['xep_0323'].request_data,
+ kwargs={"from_jid": "tester@localhost",
+ "to_jid": "you@google.com",
+ "nodeIds": ['Device33'],
+ "callback": my_callback});
+ t1.start();
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId="Device33"/>
+ </req>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
+ </iq>
+ """)
+
+ self.recv("""
+ <message from='you@google.com'
+ to='tester@localhost'>
+ <failure xmlns='urn:xmpp:iot:sensordata' seqnr='1' done='true'>
+ <error nodeId='Device33' timestamp='2013-03-07T17:13:30'>Timeout.</error>
+ </failure>
+ </message>
+ """)
+
+ t1.join();
+ time.sleep(.5)
+
+ self.failUnlessEqual(results, ["accepted","failure"]);
+ # self.assertIn("nodeId", callback_data);
+ self.assertTrue(callback_data.has_key("nodeId"));
+ self.failUnlessEqual(callback_data["nodeId"], "Device33");
+ # self.assertIn("timestamp", callback_data);
+ self.assertTrue(callback_data.has_key("timestamp"));
+ self.failUnlessEqual(callback_data["timestamp"], "2013-03-07T17:13:30");
+ # self.assertIn("error_msg", callback_data);
+ self.assertTrue(callback_data.has_key("error_msg"));
+ self.failUnlessEqual(callback_data["error_msg"], "Timeout.");
+
+ def testDelayedRequest(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device22");
+ myDevice._add_field(name="Temperature", typename="numeric", unit="°C");
+ myDevice._set_momentary_timestamp("2013-03-07T16:24:30")
+ myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"});
+
+ self.xmpp['xep_0323'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ dtnow = datetime.datetime.now()
+ ts_2sec = datetime.timedelta(0,2)
+ dtnow_plus_2sec = dtnow + ts_2sec
+ when_flag = dtnow_plus_2sec.replace(microsecond=0).isoformat()
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true' when='""" + when_flag + """'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1' queued='true' />
+ </iq>
+ """)
+
+ time.sleep(2)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <started xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1' done='true'>
+ <node nodeId='Device22'>
+ <timestamp value='2013-03-07T16:24:30'>
+ <numeric name='Temperature' momentary='true' automaticReadout='true' value='23.4' unit='°C'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ def testDelayedRequestFail(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device22");
+ myDevice._add_field(name="Temperature", typename="numeric", unit="°C");
+ myDevice._set_momentary_timestamp("2013-03-07T16:24:30")
+ myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"});
+
+ self.xmpp['xep_0323'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ dtnow = datetime.datetime.now()
+ ts_2sec = datetime.timedelta(0,2)
+ dtnow_minus_2sec = dtnow - ts_2sec
+ when_flag = dtnow_minus_2sec.replace(microsecond=0).isoformat()
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true' when='""" + when_flag + """'/>
+ </iq>
+ """)
+
+ # Remove the returned datetime to allow predictable test
+ xml_stanza = self._filtered_stanza_prepare()
+ error_text = xml_stanza['rejected']['error'] #['text']
+ error_text = error_text[:error_text.find(':')]
+ xml_stanza['rejected']['error'] = error_text
+
+ self._filtered_stanza_check("""
+ <iq type='error'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <error>Invalid datetime in 'when' flag, cannot set a time in the past. Current time</error>
+ </rejected>
+ </iq>
+ """, xml_stanza)
+
+
+ def _filtered_stanza_prepare(self, timeout=.5):
+ sent = self.xmpp.socket.next_sent(timeout)
+ if sent is None:
+ self.fail("No stanza was sent.")
+
+ xml = self.parse_xml(sent)
+ self.fix_namespaces(xml, 'jabber:client')
+ sent = self.xmpp._build_stanza(xml, 'jabber:client')
+ return sent
+
+ def _filtered_stanza_check(self, data, filtered, defaults=None, use_values=True, method='exact'):
+ self.check(filtered, data,
+ method=method,
+ defaults=defaults,
+ use_values=use_values)
+
+ def testRequestFieldFrom(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ myDevice._add_field(name='Voltage', typename="numeric", unit="V");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.1", timestamp="2000-01-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.2", timestamp="2000-02-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.3", timestamp="2000-03-01T00:01:02", flags={"invoiced": "true"});
+
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='6'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='6' from='2000-01-02T00:00:01'>
+ <field name='Voltage'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='6'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='6'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-02-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.2' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-03-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.3' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6' done='true'>
+ </fields>
+ </message>
+ """)
+
+ def testRequestFieldTo(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ myDevice._add_field(name='Voltage', typename="numeric", unit="V");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.1", timestamp="2000-01-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.2", timestamp="2000-02-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.3", timestamp="2000-03-01T00:01:02", flags={"invoiced": "true"});
+
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='6'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='6' to='2000-02-02T00:00:01'>
+ <field name='Voltage'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='6'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='6'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-01-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.1' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-02-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.2' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6' done='true'>
+ </fields>
+ </message>
+ """)
+
+ def testRequestFieldFromTo(self):
+
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device44");
+ myDevice._add_field(name='Voltage', typename="numeric", unit="V");
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.1", timestamp="2000-01-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.2", timestamp="2000-02-01T00:01:02", flags={"invoiced": "true"});
+ myDevice._add_field_timestamp_data(name="Voltage", value="230.3", timestamp="2000-03-01T00:01:02", flags={"invoiced": "true"});
+
+ self.xmpp['xep_0323'].register_node('Device44', myDevice, commTimeout=0.5);
+
+ print("."),
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='6'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='6' from='2000-01-01T00:01:03' to='2000-02-02T00:00:01'>
+ <field name='Voltage'/>
+ </req>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='6'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='6'/>
+ </iq>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6'>
+ <node nodeId='Device44'>
+ <timestamp value='2000-02-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.2' unit='V'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.send("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='6' done='true'>
+ </fields>
+ </message>
+ """)
+
+ def testDelayedRequestClient(self):
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ results = [];
+ callback_data = {};
+
+ def my_callback(from_jid, result, nodeId=None, timestamp=None, fields=None, error_msg=None):
+ results.append(result);
+ if result == "fields":
+ callback_data["nodeId"] = nodeId;
+ callback_data["timestamp"] = timestamp;
+ callback_data["error_msg"] = error_msg;
+ for f in fields:
+ callback_data["field_" + f['name']] = f;
+
+ t1= threading.Thread(name="request_data",
+ target=self.xmpp['xep_0323'].request_data,
+ kwargs={"from_jid": "tester@localhost",
+ "to_jid": "you@google.com",
+ "nodeIds": ['Device33'],
+ "callback": my_callback});
+ t1.start();
+ #self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33'], callback=my_callback);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId="Device33"/>
+ </req>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1' queued='true'/>
+ </iq>
+ """)
+
+ self.recv("""
+ <message from='device@clayster.com'
+ to='master@clayster.com/amr'>
+ <started xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </message>
+ """)
+
+ self.recv("""
+ <message from='you@google.com'
+ to='tester@localhost'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId='Device33'>
+ <timestamp value='2000-01-01T00:01:02'>
+ <numeric name='Voltage' invoiced='true' value='230.4' unit='V'/>
+ <boolean name='TestBool' value='true'/>
+ </timestamp>
+ </node>
+ </fields>
+ </message>
+ """)
+
+ self.recv("""
+ <message from='you@google.com'
+ to='tester@localhost'>
+ <fields xmlns='urn:xmpp:iot:sensordata' seqnr='1' done='true'/>
+ </message>
+ """)
+
+ t1.join();
+ time.sleep(.5)
+
+ self.failUnlessEqual(results, ["queued","started","fields","done"]);
+ # self.assertIn("nodeId", callback_data);
+ self.assertTrue(callback_data.has_key("nodeId"));
+ self.failUnlessEqual(callback_data["nodeId"], "Device33");
+ # self.assertIn("timestamp", callback_data);
+ self.assertTrue(callback_data.has_key("timestamp"));
+ self.failUnlessEqual(callback_data["timestamp"], "2000-01-01T00:01:02");
+ # self.assertIn("field_Voltage", callback_data);
+ self.assertTrue(callback_data.has_key("field_Voltage"));
+ self.failUnlessEqual(callback_data["field_Voltage"], {"name": "Voltage", "value": "230.4", "typename": "numeric", "unit": "V", "flags": {"invoiced": "true"}});
+ # self.assertIn("field_TestBool", callback_data);
+ self.assertTrue(callback_data.has_key("field_TestBool"));
+ self.failUnlessEqual(callback_data["field_TestBool"], {"name": "TestBool", "value": "true", "typename": "boolean" });
+
+
+ def testRequestFieldsCancelAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ results = [];
+
+ def my_callback(from_jid, result, nodeId=None, timestamp=None, fields=None, error_msg=None):
+ results.append(result);
+
+ session = self.xmpp['xep_0323'].request_data(from_jid="tester@localhost", to_jid="you@google.com", nodeIds=['Device33'], callback=my_callback);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <node nodeId="Device33"/>
+ </req>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
+ </iq>
+ """)
+
+ self.xmpp['xep_0323'].cancel_request(session=session);
+
+ self.send("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <cancel xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <cancelled xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </iq>
+ """)
+
+ time.sleep(.5)
+
+ self.failUnlessEqual(results, ["accepted","cancelled"]);
+
+ def testDelayedRequestCancel(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0323'])
+
+ myDevice = Device("Device22");
+ myDevice._add_field(name="Temperature", typename="numeric", unit="°C");
+ myDevice._set_momentary_timestamp("2013-03-07T16:24:30")
+ myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"});
+
+ self.xmpp['xep_0323'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ dtnow = datetime.datetime.now()
+ ts_2sec = datetime.timedelta(0,2)
+ dtnow_plus_2sec = dtnow + ts_2sec
+ when_flag = dtnow_plus_2sec.replace(microsecond=0).isoformat()
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <req xmlns='urn:xmpp:iot:sensordata' seqnr='1' momentary='true' when='""" + when_flag + """'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1' queued='true' />
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <cancel xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <cancelled xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </iq>
+ """)
+
+ # Test cancel of non-existing request
+ self.recv("""
+ <iq type='get'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <cancel xmlns='urn:xmpp:iot:sensordata' seqnr='1' />
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='error'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <rejected xmlns='urn:xmpp:iot:sensordata' seqnr='1'>
+ <error>Cancel request received, no matching request is active.</error>
+ </rejected>
+ </iq>
+ """)
+
+ time.sleep(2)
+
+ # Ensure we don't get anything after cancellation
+ self.send(None)
+
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamSensorData)
+
diff --git a/tests/test_stream_xep_0325.py b/tests/test_stream_xep_0325.py
new file mode 100644
index 00000000..4b3250fc
--- /dev/null
+++ b/tests/test_stream_xep_0325.py
@@ -0,0 +1,365 @@
+# -*- coding: utf-8 -*-
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Implementation of xeps for Internet of Things
+ http://wiki.xmpp.org/web/Tech_pages/IoT_systems
+ Copyright (C) 2013 Sustainable Innovation, Joachim.lindborg@sust.se, bjorn.westrom@consoden.se
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+import sys
+import datetime
+import time
+import threading
+
+from sleekxmpp.test import *
+from sleekxmpp.xmlstream import ElementBase
+from sleekxmpp.plugins.xep_0325.device import Device
+
+
+class TestStreamControl(SleekTest):
+
+ """
+ Test using the XEP-0325 plugin.
+ """
+ def setUp(self):
+ pass
+
+ def _time_now(self):
+ return datetime.datetime.now().replace(microsecond=0).isoformat();
+
+ def tearDown(self):
+ self.stream_close()
+
+ def testRequestSetOk(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ myDevice = Device("Device22");
+ myDevice._add_control_field(name="Temperature", typename="int", value="15");
+
+ self.xmpp['xep_0325'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ self.recv("""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <int name="Temperature" value="17"/>
+ </set>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode="OK" />
+ </iq>
+ """)
+
+ self.assertEqual(myDevice._get_field_value("Temperature"), "17");
+
+ def testRequestSetMulti(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ myDevice = Device("Device22");
+ myDevice._add_control_field(name="Temperature", typename="int", value="15");
+ myDevice._add_control_field(name="Startup", typename="date", value="2013-01-03");
+
+ myDevice2 = Device("Device23");
+ myDevice2._add_control_field(name="Temperature", typename="int", value="19");
+ myDevice2._add_control_field(name="Startup", typename="date", value="2013-01-09");
+
+ self.xmpp['xep_0325'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+ self.xmpp['xep_0325'].register_node(nodeId="Device23", device=myDevice2, commTimeout=0.5);
+
+ self.recv("""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device22' />
+ <int name="Temperature" value="17"/>
+ </set>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='1'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode="OK" />
+ </iq>
+ """)
+
+ self.assertEqual(myDevice._get_field_value("Temperature"), "17");
+ self.assertEqual(myDevice2._get_field_value("Temperature"), "19");
+
+ self.recv("""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='2'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device23' />
+ <node nodeId='Device22' />
+ <date name="Startup" value="2013-02-01"/>
+ <int name="Temperature" value="20"/>
+ </set>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='2'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode="OK" />
+ </iq>
+ """)
+
+ self.assertEqual(myDevice._get_field_value("Temperature"), "20");
+ self.assertEqual(myDevice2._get_field_value("Temperature"), "20");
+ self.assertEqual(myDevice._get_field_value("Startup"), "2013-02-01");
+ self.assertEqual(myDevice2._get_field_value("Startup"), "2013-02-01");
+
+ def testRequestSetFail(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ myDevice = Device("Device23");
+ myDevice._add_control_field(name="Temperature", typename="int", value="15");
+
+ self.xmpp['xep_0325'].register_node(nodeId="Device23", device=myDevice, commTimeout=0.5);
+
+ self.recv("""
+ <iq type='set'
+ from='master@clayster.com/amr'
+ to='device@clayster.com'
+ id='9'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <int name="Voltage" value="17"/>
+ </set>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='error'
+ from='device@clayster.com'
+ to='master@clayster.com/amr'
+ id='9'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode='NotFound'>
+ <parameter name='Voltage' />
+ <error var='Output'>Invalid field Voltage</error>
+ </setResponse>
+ </iq>
+ """)
+
+ self.assertEqual(myDevice._get_field_value("Temperature"), "15");
+ self.assertFalse(myDevice.has_control_field("Voltage", "int"));
+
+ def testDirectSetOk(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ myDevice = Device("Device22");
+ myDevice._add_control_field(name="Temperature", typename="int", value="15");
+
+ self.xmpp['xep_0325'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ self.recv("""
+ <message
+ from='master@clayster.com/amr'
+ to='device@clayster.com'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <int name="Temperature" value="17"/>
+ </set>
+ </message>
+ """)
+
+ time.sleep(.5)
+
+ self.assertEqual(myDevice._get_field_value("Temperature"), "17");
+
+ def testDirectSetFail(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ myDevice = Device("Device22");
+ myDevice._add_control_field(name="Temperature", typename="int", value="15");
+
+ self.xmpp['xep_0325'].register_node(nodeId="Device22", device=myDevice, commTimeout=0.5);
+
+ self.recv("""
+ <message
+ from='master@clayster.com/amr'
+ to='device@clayster.com'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <int name="Voltage" value="17"/>
+ </set>
+ </message>
+ """)
+
+ time.sleep(.5)
+
+ self.assertEqual(myDevice._get_field_value("Temperature"), "15");
+ self.assertFalse(myDevice.has_control_field("Voltage", "int"));
+
+
+ def testRequestSetOkAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ results = [];
+
+ def my_callback(from_jid, result, nodeIds=None, fields=None, error_msg=None):
+ results.append(result);
+
+ fields = []
+ fields.append(("Temperature", "double", "20.5"))
+ fields.append(("TemperatureAlarmSetting", "string", "High"))
+
+ self.xmpp['xep_0325'].set_request(from_jid="tester@localhost", to_jid="you@google.com", fields=fields, nodeIds=['Device33', 'Device22'], callback=my_callback);
+
+ self.send("""
+ <iq type='set'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device33' />
+ <node nodeId='Device22' />
+ <double name="Temperature" value="20.5" />
+ <string name="TemperatureAlarmSetting" value="High" />
+ </set>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='result'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode="OK" />
+ </iq>
+ """)
+
+ time.sleep(.5)
+
+ self.assertEqual(results, ["OK"]);
+
+ def testRequestSetErrorAPI(self):
+
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0325'])
+
+ results = [];
+
+ def my_callback(from_jid, result, nodeIds=None, fields=None, error_msg=None):
+ results.append(result);
+
+ fields = []
+ fields.append(("Temperature", "double", "20.5"))
+ fields.append(("TemperatureAlarmSetting", "string", "High"))
+
+ self.xmpp['xep_0325'].set_request(from_jid="tester@localhost", to_jid="you@google.com", fields=fields, nodeIds=['Device33', 'Device22'], callback=my_callback);
+
+ self.send("""
+ <iq type='set'
+ from='tester@localhost'
+ to='you@google.com'
+ id='1'>
+ <set xmlns='urn:xmpp:iot:control'>
+ <node nodeId='Device33' />
+ <node nodeId='Device22' />
+ <double name="Temperature" value="20.5" />
+ <string name="TemperatureAlarmSetting" value="High" />
+ </set>
+ </iq>
+ """)
+
+ self.recv("""
+ <iq type='error'
+ from='you@google.com'
+ to='tester@localhost'
+ id='1'>
+ <setResponse xmlns='urn:xmpp:iot:control' responseCode="OtherError" >
+ <error var='Temperature'>Sensor error</error>
+ </setResponse>
+ </iq>
+ """)
+
+ time.sleep(.5)
+
+ self.assertEqual(results, ["OtherError"]);
+
+ def testServiceDiscoveryClient(self):
+ self.stream_start(mode='client',
+ plugins=['xep_0030',
+ 'xep_0325']);
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='tester@localhost'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ to='master@clayster.com/amr'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'>
+ <identity category='client' type='bot'/>
+ <feature var='urn:xmpp:iot:control'/>
+ </query>
+ </iq>
+ """)
+
+ def testServiceDiscoveryComponent(self):
+ self.stream_start(mode='component',
+ plugins=['xep_0030',
+ 'xep_0325']);
+
+ self.recv("""
+ <iq type='get'
+ from='master@clayster.com/amr'
+ to='tester@localhost'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'/>
+ </iq>
+ """)
+
+ self.send("""
+ <iq type='result'
+ from='tester@localhost'
+ to='master@clayster.com/amr'
+ id='disco1'>
+ <query xmlns='http://jabber.org/protocol/disco#info'>
+ <identity category='component' type='generic'/>
+ <feature var='urn:xmpp:iot:control'/>
+ </query>
+ </iq>
+ """)
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamControl)
+
diff --git a/tests/test_tostring.py b/tests/test_tostring.py
index 8c04f00c..e6148533 100644
--- a/tests/test_tostring.py
+++ b/tests/test_tostring.py
@@ -1,6 +1,6 @@
-from sleekxmpp.test import *
-from sleekxmpp.stanza import Message
-from sleekxmpp.xmlstream.stanzabase import ET, ElementBase
+import unittest
+from sleekxmpp.test import SleekTest
+from sleekxmpp.xmlstream.stanzabase import ET
from sleekxmpp.xmlstream.tostring import tostring, escape