jabber4r-revive 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG +45 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +12 -0
- data/README.md +29 -0
- data/Rakefile +71 -0
- data/jabber4r-revive.gemspec +25 -0
- data/lib/jabber4r/bosh_session.rb +224 -0
- data/lib/jabber4r/connection.rb +258 -0
- data/lib/jabber4r/debugger.rb +61 -0
- data/lib/jabber4r/jid.rb +125 -0
- data/lib/jabber4r/protocol/iq.rb +260 -0
- data/lib/jabber4r/protocol/message.rb +246 -0
- data/lib/jabber4r/protocol/parsed_xml_element.rb +208 -0
- data/lib/jabber4r/protocol/presence.rb +160 -0
- data/lib/jabber4r/protocol/xml_element.rb +144 -0
- data/lib/jabber4r/protocol.rb +257 -0
- data/lib/jabber4r/rexml_1.8_patch.rb +16 -0
- data/lib/jabber4r/roster.rb +322 -0
- data/lib/jabber4r/session.rb +615 -0
- data/lib/jabber4r/vcard.rb +42 -0
- data/lib/jabber4r/version.rb +3 -0
- data/lib/jabber4r.rb +33 -0
- data/spec/lib/jabber4r/bosh_session_spec.rb +150 -0
- data/spec/lib/jabber4r/connection_spec.rb +174 -0
- data/spec/lib/jabber4r/debugger_spec.rb +36 -0
- data/spec/lib/jabber4r/jid_spec.rb +198 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/mocks/tcp_socket_mock.rb +8 -0
- metadata +151 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
# License: see LICENSE.txt
|
2
|
+
# Jabber4R - Jabber Instant Messaging Library for Ruby
|
3
|
+
# Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
|
4
|
+
#
|
5
|
+
|
6
|
+
|
7
|
+
module Jabber
|
8
|
+
|
9
|
+
##
|
10
|
+
# The VCard class holds the parsed VCard data from the Jabber service.
|
11
|
+
#
|
12
|
+
class VCard
|
13
|
+
attr_accessor :given, :family, :middle, :nickname, :email
|
14
|
+
|
15
|
+
##
|
16
|
+
# Factory to create the VCard from the ParsedXMLElement
|
17
|
+
#
|
18
|
+
# je:: [ParsedXMLElement] The VCard as an xml element.
|
19
|
+
# return:: [Jabber::VCard] The newly created VCard.
|
20
|
+
#
|
21
|
+
def VCard.from_element(je)
|
22
|
+
card = VCard.new
|
23
|
+
return card unless je
|
24
|
+
card.given = je.N.GIVEN.element_data
|
25
|
+
card.family = je.N.FAMILY.element_data
|
26
|
+
card.middle = je.N.MIDDLE.element_data
|
27
|
+
card.email = je.EMAIL.element_data
|
28
|
+
card.nickname = je.NICKNAME.element_data
|
29
|
+
return card
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Dumps the attributes of the VCard
|
34
|
+
#
|
35
|
+
# return:: [String] The VCard as a string.
|
36
|
#
|
37
|
+
def to_s
|
38
|
+
"VCARD: [first=#{@given} last=#{@family} nick=#{@nickname} email=#{@email}]"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
data/lib/jabber4r.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# License: see LICENSE.txt
|
2
|
+
# Jabber4R - Jabber Instant Messaging Library for Ruby
|
3
|
+
# Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
|
4
|
+
|
5
|
+
|
6
|
+
# The Jabber module is the main namespace for all Jabber modules
|
7
|
+
# and classes.
|
8
|
+
module Jabber
|
9
|
+
DEBUG = false
|
10
|
+
|
11
|
+
# Public: Should raise if connection was force closed
|
12
|
+
class ConnectionForceCloseError < StandardError; end
|
13
|
+
|
14
|
+
# Public: Should raise if received XML data is malformed
|
15
|
+
class XMLMalformedError < StandardError; end
|
16
|
+
|
17
|
+
# Public: Should raise if authentication failed
|
18
|
+
class AuthenticationError < StandardError; end
|
19
|
+
end
|
20
|
+
|
21
|
+
require "jabber4r/debugger"
|
22
|
+
require "jabber4r/session"
|
23
|
+
require "jabber4r/bosh_session"
|
24
|
+
require "jabber4r/protocol"
|
25
|
+
require "jabber4r/connection"
|
26
|
+
require "jabber4r/protocol/iq"
|
27
|
+
require "jabber4r/protocol/presence"
|
28
|
+
require "jabber4r/protocol/message"
|
29
|
+
require "jabber4r/protocol/xml_element"
|
30
|
+
require "jabber4r/protocol/parsed_xml_element"
|
31
|
+
require "jabber4r/roster"
|
32
|
+
require "jabber4r/jid"
|
33
|
+
require "jabber4r/vcard"
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Jabber::BoshSession do
|
5
|
+
let(:successful_login) { '<body xmlns="http://jabber.org/protocol/httpbind"><iq type="result" xmlns="jabber:client" id="2034"/></body>' }
|
6
|
+
let(:successful_open_stream) do
|
7
|
+
[
|
8
|
+
'<body xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" xmlns:stream="http://etherx.jabber.org/streams"',
|
9
|
+
'authid="3780309894" sid="ce21410" from="localhost"',
|
10
|
+
'wait="60" requests="2" inactivity="30" maxpause="120" polling="2" ver="1.8" secure="true" />'
|
11
|
+
].join " "
|
12
|
+
end
|
13
|
+
let(:is_open_stream?) { ->(data) { x = Ox.parse(data); ["1", "localhost"] == [x[:rid], x[:to]] } }
|
14
|
+
let(:is_login?) { ->(data) { x = Ox.parse(data); ["1", "ce21410"] == [x[:rid], x[:sid]] } }
|
15
|
+
let(:bosh_session) { described_class.bind("strech@localhost/resource", "password") }
|
16
|
+
|
17
|
+
before { Jabber::BoshSession.any_instance.stub(:generate_next_rid).and_return "1" }
|
18
|
+
|
19
|
+
describe "#bind" do
|
20
|
+
context "when session successfuly binded" do
|
21
|
+
before do
|
22
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
23
|
+
.with(body: is_open_stream?)
|
24
|
+
.to_return(body: successful_open_stream)
|
25
|
+
|
26
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
27
|
+
.with(body: is_login?)
|
28
|
+
.to_return(body: successful_login)
|
29
|
+
end
|
30
|
+
|
31
|
+
it { expect(bosh_session).to be_alive }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when couldn't open stream" do
|
35
|
+
context "when response body missed authid attribute" do
|
36
|
+
let(:malformed_body) { '<body xmlns="http://jabber.org/protocol/httpbind" sid="ce21410" />' }
|
37
|
+
|
38
|
+
before do
|
39
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
40
|
+
.with(body: is_open_stream?)
|
41
|
+
.to_return(body: malformed_body)
|
42
|
+
|
43
|
+
WebMock.should_not have_requested(:post, "http://localhost:5280/http-bind")
|
44
|
+
.with(body: is_login?)
|
45
|
+
end
|
46
|
+
|
47
|
+
it { expect { bosh_session }.to raise_error Jabber::XMLMalformedError, "Couldn't find <body /> attribute [authid]" }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when response body missed sid attribute" do
|
51
|
+
let(:malformed_body) { '<body xmlns="http://jabber.org/protocol/httpbind" authid="3780309894" />' }
|
52
|
+
|
53
|
+
before do
|
54
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
55
|
+
.with(body: is_open_stream?)
|
56
|
+
.to_return(body: malformed_body)
|
57
|
+
|
58
|
+
WebMock.should_not have_requested(:post, "http://localhost:5280/http-bind")
|
59
|
+
.with(body: is_login?)
|
60
|
+
end
|
61
|
+
|
62
|
+
it { expect { bosh_session }.to raise_error Jabber::XMLMalformedError, "Couldn't find <body /> attribute [sid]" }
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when response was not 200 OK" do
|
66
|
+
before do
|
67
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
68
|
+
.with(body: is_open_stream?)
|
69
|
+
.to_return(body: "Foo", status: 401)
|
70
|
+
|
71
|
+
WebMock.should_not have_requested(:post, "http://localhost:5280/http-bind")
|
72
|
+
.with(body: is_login?)
|
73
|
+
end
|
74
|
+
|
75
|
+
it { expect { bosh_session }.to raise_error Net::HTTPBadResponse }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when couldn't login in opened stream" do
|
80
|
+
context "when response is a malformed xml without IQ tag" do
|
81
|
+
let(:malformed_body) { '<body xmlns="http://jabber.org/protocol/httpbind"></body>' }
|
82
|
+
|
83
|
+
before do
|
84
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
85
|
+
.with(body: is_open_stream?)
|
86
|
+
.to_return(body: successful_open_stream)
|
87
|
+
|
88
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
89
|
+
.with(body: is_login?)
|
90
|
+
.to_return(body: malformed_body)
|
91
|
+
end
|
92
|
+
|
93
|
+
it { expect { bosh_session }.to raise_error Jabber::XMLMalformedError, "Couldn't find xml tag <iq/>" }
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when response has type not equal 'result'" do
|
97
|
+
let(:malformed_body) { '<body xmlns="http://jabber.org/protocol/httpbind"><iq type="error" xmlns="jabber:client" id="2034"/></body>' }
|
98
|
+
|
99
|
+
before do
|
100
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
101
|
+
.with(body: is_open_stream?)
|
102
|
+
.to_return(body: successful_open_stream)
|
103
|
+
|
104
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
105
|
+
.with(body: is_login?)
|
106
|
+
.to_return(body: malformed_body)
|
107
|
+
end
|
108
|
+
|
109
|
+
it { expect { bosh_session }.to raise_error Jabber::AuthenticationError, "Failed to login" }
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when response was not 200 OK" do
|
113
|
+
before do
|
114
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
115
|
+
.with(body: is_open_stream?)
|
116
|
+
.to_return(body: successful_open_stream)
|
117
|
+
|
118
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
119
|
+
.with(body: is_login?)
|
120
|
+
.to_return(body: "Foo", status: 401)
|
121
|
+
end
|
122
|
+
|
123
|
+
it { expect { bosh_session }.to raise_error Net::HTTPBadResponse }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#to_json" do
|
129
|
+
let(:json) { JSON.parse(bosh_session.to_json) }
|
130
|
+
|
131
|
+
before do
|
132
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
133
|
+
.with(body: is_open_stream?)
|
134
|
+
.to_return(body: successful_open_stream)
|
135
|
+
|
136
|
+
|
137
|
+
stub_request(:post, "http://localhost:5280/http-bind")
|
138
|
+
.with(body: is_login?)
|
139
|
+
.to_return(body: successful_login)
|
140
|
+
end
|
141
|
+
|
142
|
+
it { expect(json).to have_key "jid" }
|
143
|
+
it { expect(json).to have_key "rid" }
|
144
|
+
it { expect(json).to have_key "sid" }
|
145
|
+
|
146
|
+
it { expect(json["jid"]).to eq "strech@localhost/resource"}
|
147
|
+
it { expect(json["rid"]).to eq "1"}
|
148
|
+
it { expect(json["sid"]).to eq "ce21410"}
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Jabber::Connection do
|
5
|
+
let(:socket) { TCPSocketMock.new }
|
6
|
+
let(:connection) { described_class.new "localhost" }
|
7
|
+
|
8
|
+
before { TCPSocket.stub(:new).and_return socket }
|
9
|
+
|
10
|
+
describe "#connect" do
|
11
|
+
before { connection.connect }
|
12
|
+
|
13
|
+
it { expect(connection).to be_connected }
|
14
|
+
it { expect(connection.poll_thread).to be_alive }
|
15
|
+
it { expect(connection.parser_thread).to be_alive }
|
16
|
+
it { expect(connection.socket).not_to be_closed }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#close" do
|
20
|
+
before { connection.connect }
|
21
|
+
before { connection.close; sleep 0.01 }
|
22
|
+
|
23
|
+
it { expect(connection).to be_disconnected }
|
24
|
+
it { expect(connection.poll_thread).not_to be_alive }
|
25
|
+
it { expect(connection.parser_thread).not_to be_alive }
|
26
|
+
it { expect(connection.socket).to be_closed }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#add_filter" do
|
30
|
+
context "when filter name and block is given" do
|
31
|
+
before { connection.add_filter("hello") { 1 } }
|
32
|
+
|
33
|
+
it { expect(connection.filters).to have_key "hello" }
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when only filter name give" do
|
37
|
+
it { expect { connection.add_filter("hello") }.to raise_error ArgumentError }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#remove_filter" do
|
42
|
+
before { connection.add_filter("hello") { 1 } }
|
43
|
+
it { expect(connection.filters).to have_key "hello" }
|
44
|
+
|
45
|
+
it "should remove filter" do
|
46
|
+
connection.remove_filter("hello")
|
47
|
+
expect(connection.filters).not_to have_key "hello"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#send" do
|
52
|
+
let(:handler) { proc { 1 } }
|
53
|
+
|
54
|
+
before { connection.connect }
|
55
|
+
before { Thread.stub(:current).and_return "current" }
|
56
|
+
|
57
|
+
context "when own handler is given" do
|
58
|
+
before { connection.send("hello", handler) }
|
59
|
+
|
60
|
+
it { expect(connection.handlers).to have_key "current" }
|
61
|
+
it { expect(connection.handlers["current"]).to eq handler }
|
62
|
+
|
63
|
+
describe "socket" do
|
64
|
+
it { expect(socket.to_s).to eq "hello" }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when only block is given" do
|
69
|
+
before { connection.send("hello") { 1 } }
|
70
|
+
|
71
|
+
it { expect(connection.handlers).to have_key "current" }
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when handler and block are given" do
|
75
|
+
before { connection.send("hello", handler) { 1 } }
|
76
|
+
|
77
|
+
it { expect(connection.handlers).to have_key "current" }
|
78
|
+
it { expect(connection.handlers["current"]).to eq handler }
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when no handlers and block are given" do
|
82
|
+
before { connection.send("hello") }
|
83
|
+
|
84
|
+
it { expect(connection.handlers).to be_empty }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#receive" do
|
89
|
+
let(:thread) { double("Pseudo thread", alive?: true) }
|
90
|
+
let(:element) { double("XML Element", element_consumed?: false) }
|
91
|
+
|
92
|
+
let(:consume) { ->(element) { element.stub(:element_consumed?).and_return true } }
|
93
|
+
let(:skip) { ->(element) { element.stub(:element_consumed?).and_return false } }
|
94
|
+
|
95
|
+
before { connection.stub :register_parsing_thread }
|
96
|
+
before { connection.stub :register_polling_thread }
|
97
|
+
|
98
|
+
context "when handlers are not empty" do
|
99
|
+
context "when filters are empty" do
|
100
|
+
before do
|
101
|
+
thread.should_receive(:wakeup)
|
102
|
+
connection.stub(:handlers).and_return({thread => consume})
|
103
|
+
|
104
|
+
connection.receive(element)
|
105
|
+
end
|
106
|
+
|
107
|
+
it { expect(connection.handlers).to be_empty }
|
108
|
+
it { expect(connection.filters).to be_empty }
|
109
|
+
end
|
110
|
+
|
111
|
+
context "when filters are not empty" do
|
112
|
+
context "when handler consume element" do
|
113
|
+
before do
|
114
|
+
thread.should_receive(:wakeup)
|
115
|
+
skip.should_not_receive(:call)
|
116
|
+
|
117
|
+
connection.stub(:handlers).and_return({thread => consume})
|
118
|
+
connection.stub(:filters).and_return({f1: skip})
|
119
|
+
|
120
|
+
connection.receive(element)
|
121
|
+
end
|
122
|
+
|
123
|
+
it { expect(connection.handlers).to be_empty }
|
124
|
+
it { expect(connection.filters).not_to be_empty }
|
125
|
+
end
|
126
|
+
|
127
|
+
context "when handler doesn't consume element" do
|
128
|
+
before do
|
129
|
+
thread.should_not_receive(:wakeup)
|
130
|
+
consume.should_receive(:call).and_call_original
|
131
|
+
|
132
|
+
connection.stub(:handlers).and_return({thread => skip})
|
133
|
+
connection.stub(:filters).and_return({f1: consume})
|
134
|
+
|
135
|
+
connection.receive(element)
|
136
|
+
end
|
137
|
+
|
138
|
+
it { expect(connection.handlers).not_to be_empty }
|
139
|
+
it { expect(connection.filters).not_to be_empty }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "when handlers are empty" do
|
145
|
+
context "when filters are empty" do
|
146
|
+
before do
|
147
|
+
thread.should_not_receive(:wakeup)
|
148
|
+
connection.should_receive(:wait_for_consume?).and_return false
|
149
|
+
|
150
|
+
connection.receive(element)
|
151
|
+
end
|
152
|
+
|
153
|
+
it { expect(connection.handlers).to be_empty }
|
154
|
+
it { expect(connection.filters).to be_empty }
|
155
|
+
end
|
156
|
+
|
157
|
+
context "when filters are not empty" do
|
158
|
+
before do
|
159
|
+
thread.should_not_receive(:wakeup)
|
160
|
+
consume.should_receive(:call).and_call_original
|
161
|
+
|
162
|
+
connection.stub(:filters).and_return({f1: consume})
|
163
|
+
|
164
|
+
connection.receive(element)
|
165
|
+
end
|
166
|
+
|
167
|
+
it { expect(connection.handlers).to be_empty }
|
168
|
+
it { expect(connection.filters).not_to be_empty }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# TODO : When socket is empty?
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Jabber::Debugger do
|
5
|
+
let(:debugger) { described_class.clone.instance }
|
6
|
+
before { described_class.stub(:instance).and_return debugger }
|
7
|
+
|
8
|
+
describe "#initialize" do
|
9
|
+
it { expect(described_class).not_to be_enabled }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#enable" do
|
13
|
+
before { described_class.enable! }
|
14
|
+
|
15
|
+
it { expect(described_class).to be_enabled }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#disable" do
|
19
|
+
before { described_class.disable! }
|
20
|
+
|
21
|
+
it { expect(described_class).not_to be_enabled }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#logger=" do
|
25
|
+
let(:logger) { double("Logger") }
|
26
|
+
|
27
|
+
before { described_class.logger = logger }
|
28
|
+
it { expect(debugger.logger).to eq logger }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "generated methods" do
|
32
|
+
it { expect(described_class).to respond_to :warn }
|
33
|
+
it { expect(described_class).to respond_to :info }
|
34
|
+
it { expect(described_class).to respond_to :debug }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Jabber::JID do
|
5
|
+
describe "#initialize" do
|
6
|
+
context "when need parse jid from string" do
|
7
|
+
context "when only node given" do
|
8
|
+
it { expect { described_class.new "user" }.to raise_error ArgumentError }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when node and host given" do
|
12
|
+
subject { described_class.new "user@localhost" }
|
13
|
+
|
14
|
+
its(:node) { should eq "user" }
|
15
|
+
its(:host) { should eq "localhost" }
|
16
|
+
its(:resource) { should be_nil }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when node, host and resource given" do
|
20
|
+
subject { described_class.new "user@localhost/attach" }
|
21
|
+
|
22
|
+
its(:node) { should eq "user" }
|
23
|
+
its(:host) { should eq "localhost" }
|
24
|
+
its(:resource) { should eq "attach" }
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when empty string given" do
|
28
|
+
it { expect { described_class.new "" }.to raise_error ArgumentError }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when extra arguments given" do
|
33
|
+
context "when only host given" do
|
34
|
+
subject { described_class.new "user", "localhost" }
|
35
|
+
|
36
|
+
its(:node) { should eq "user" }
|
37
|
+
its(:host) { should eq "localhost" }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when host and resource given" do
|
41
|
+
subject { described_class.new "user", "localhost", "attach" }
|
42
|
+
|
43
|
+
its(:node) { should eq "user" }
|
44
|
+
its(:host) { should eq "localhost" }
|
45
|
+
its(:resource) { should eq "attach" }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when node is fully loaded and host, resource given" do
|
49
|
+
subject { described_class.new "user@example.com/bind", "localhost", "attach" }
|
50
|
+
|
51
|
+
its(:node) { should eq "user" }
|
52
|
+
its(:host) { should eq "localhost" }
|
53
|
+
its(:resource) { should eq "attach" }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#strip" do
|
59
|
+
subject { described_class.new(args).strip }
|
60
|
+
|
61
|
+
context "when JID has no resource" do
|
62
|
+
let(:args) { "strech@localhost" }
|
63
|
+
|
64
|
+
its(:to_s) { should eq "strech@localhost" }
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when JID has no resource" do
|
68
|
+
let(:args) { "strech@localhost/pewpew" }
|
69
|
+
|
70
|
+
its(:to_s) { should eq "strech@localhost" }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#strip!" do
|
75
|
+
subject { described_class.new(args).strip! }
|
76
|
+
|
77
|
+
context "when JID has no resource" do
|
78
|
+
let(:args) { "strech@localhost" }
|
79
|
+
|
80
|
+
its(:to_s) { should eq "strech@localhost" }
|
81
|
+
its(:resource) { should be_nil }
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when JID has no resource" do
|
85
|
+
let(:args) { "strech@localhost/pewpew" }
|
86
|
+
|
87
|
+
its(:to_s) { should eq "strech@localhost" }
|
88
|
+
its(:resource) { should be_nil }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#hash" do
|
93
|
+
let(:hash) { "strech@pewpew/one".hash }
|
94
|
+
subject { described_class.new "strech@pewpew/one" }
|
95
|
+
|
96
|
+
its(:hash) { should eq hash }
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#to_s" do
|
100
|
+
context "when only host and domain exists" do
|
101
|
+
subject { described_class.new("strech", "localhost").to_s }
|
102
|
+
|
103
|
+
it { should eq "strech@localhost" }
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when only host and domain exists" do
|
107
|
+
subject { described_class.new("strech", "localhost", "attach-resource").to_s }
|
108
|
+
|
109
|
+
it { should eq "strech@localhost/attach-resource" }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#==" do
|
114
|
+
subject { jid1 == jid2 }
|
115
|
+
|
116
|
+
context "when jids are equal" do
|
117
|
+
let(:jid1) { described_class.new "strech@localhost" }
|
118
|
+
let(:jid2) { described_class.new "strech@localhost" }
|
119
|
+
|
120
|
+
it { should be_true }
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when jids are not equal" do
|
124
|
+
let(:jid1) { described_class.new "strech@localhost" }
|
125
|
+
let(:jid2) { described_class.new "strech@localhost/resource1" }
|
126
|
+
|
127
|
+
it { should be_false }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#same?" do
|
132
|
+
subject { jid1.same? jid2 }
|
133
|
+
|
134
|
+
context "when jids are equal" do
|
135
|
+
context "when jid1 and jid2 has no resource" do
|
136
|
+
let(:jid1) { described_class.new "strech@localhost" }
|
137
|
+
let(:jid2) { described_class.new "strech@localhost" }
|
138
|
+
|
139
|
+
it { should be_true }
|
140
|
+
end
|
141
|
+
|
142
|
+
context "when jid1 has resource, but jid2 not" do
|
143
|
+
let(:jid1) { described_class.new "strech@localhost/pewpew" }
|
144
|
+
let(:jid2) { described_class.new "strech@localhost" }
|
145
|
+
|
146
|
+
it { should be_true }
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when jid1 and jid2 has resources" do
|
150
|
+
let(:jid1) { described_class.new "strech@localhost/pewpew" }
|
151
|
+
let(:jid2) { described_class.new "strech@localhost/hola" }
|
152
|
+
|
153
|
+
it { should be_true }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "when jids are not equal" do
|
158
|
+
context "when jid1 and jid2 has no resource" do
|
159
|
+
let(:jid1) { described_class.new "strech@localhost" }
|
160
|
+
let(:jid2) { described_class.new "strech@gmail.com" }
|
161
|
+
|
162
|
+
it { should be_false }
|
163
|
+
end
|
164
|
+
|
165
|
+
context "when jid1 has resource, but jid2 not" do
|
166
|
+
let(:jid1) { described_class.new "strech@localhost/pewpew" }
|
167
|
+
let(:jid2) { described_class.new "strech@gmail.com" }
|
168
|
+
|
169
|
+
it { should be_false }
|
170
|
+
end
|
171
|
+
|
172
|
+
context "when jid1 and jid2 has resources" do
|
173
|
+
let(:jid1) { described_class.new "strech@localhost/pewpew" }
|
174
|
+
let(:jid2) { described_class.new "strech@gmail.com/hola" }
|
175
|
+
|
176
|
+
it { should be_false }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "::to_jid" do
|
182
|
+
subject { Jabber::JID.to_jid jid }
|
183
|
+
|
184
|
+
context "when jid is a Jabber::JID" do
|
185
|
+
let(:jid) { described_class.new "strech@localhost" }
|
186
|
+
|
187
|
+
its(:object_id) { should eq jid.object_id }
|
188
|
+
its(:to_s) { should eq "strech@localhost" }
|
189
|
+
end
|
190
|
+
|
191
|
+
context "when jid is a String" do
|
192
|
+
let(:jid) { "strech@localhost/resource" }
|
193
|
+
|
194
|
+
its(:object_id) { should_not eq jid.object_id }
|
195
|
+
its(:to_s) { should eq "strech@localhost/resource" }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|