spec/mqtt_client_spec.rb in mqtt-0.4.0 vs spec/mqtt_client_spec.rb in mqtt-0.5.0
- old
+ new
@@ -26,11 +26,11 @@
describe "initializing a client" do
it "with no arguments, it should use the defaults" do
client = MQTT::Client.new
expect(client.host).to eq(nil)
expect(client.port).to eq(1883)
- expect(client.version).to eq('3.1.0')
+ expect(client.version).to eq('3.1.1')
expect(client.keep_alive).to eq(15)
end
it "with a single string argument, it should use it has the host" do
client = MQTT::Client.new('otherhost.mqtt.org')
@@ -115,10 +115,26 @@
expect(client.port).to eq(1883)
expect(client.username).to eq('auser')
expect(client.password).to eq('bpass')
end
+ it "with a URI containing an escaped username and password" do
+ client = MQTT::Client.new(URI.parse('mqtt://foo%20bar:%40123%2B%25@mqtt.example.com'))
+ expect(client.host).to eq('mqtt.example.com')
+ expect(client.port).to eq(1883)
+ expect(client.username).to eq('foo bar')
+ expect(client.password).to eq('@123+%')
+ end
+
+ it "with a URI containing a double escaped username and password" do
+ client = MQTT::Client.new(URI.parse('mqtt://foo%2520bar:123%2525@mqtt.example.com'))
+ expect(client.host).to eq('mqtt.example.com')
+ expect(client.port).to eq(1883)
+ expect(client.username).to eq('foo%20bar')
+ expect(client.password).to eq('123%25')
+ end
+
it "with a URI as a string" do
client = MQTT::Client.new('mqtt://mqtt.example.com')
expect(client.host).to eq('mqtt.example.com')
expect(client.port).to eq(1883)
end
@@ -173,11 +189,11 @@
expect(client.ssl_context.cert).to be_nil
client.cert = File.read(fixture_path('client.pem'))
expect(client.ssl_context.cert).to be_a(OpenSSL::X509::Certificate)
end
end
-
+
describe "setting a client private key file path" do
it "should add a certificate to the SSL context" do
expect(client.ssl_context.key).to be_nil
client.key_file = fixture_path('client.key')
expect(client.ssl_context.key).to be_a(OpenSSL::PKey::RSA)
@@ -321,13 +337,13 @@
it "should include the username and password for an authenticated connection" do
client.username = 'username'
client.password = 'password'
client.connect('myclient')
expect(socket.string).to eq(
- "\x10\x2A"+
- "\x00\x06MQIsdp"+
- "\x03\xC2\x00\x0f"+
+ "\x10\x28"+
+ "\x00\x04MQTT"+
+ "\x04\xC2\x00\x0f"+
"\x00\x08myclient"+
"\x00\x08username"+
"\x00\x08password"
)
end
@@ -401,10 +417,19 @@
client = MQTT::Client.new('mqtt.example.com', :ssl => :TLSv1)
expect(client.ssl_context).to receive('ssl_version=').with(:TLSv1)
allow(client).to receive(:receive_connack)
client.connect
end
+
+ it "should use set hostname on the SSL socket for SNI" do
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).and_return(ssl_socket)
+ expect(ssl_socket).to receive(:hostname=).with('mqtt.example.com')
+
+ client = MQTT::Client.new('mqtts://mqtt.example.com')
+ allow(client).to receive(:receive_connack)
+ client.connect
+ end
end
context "with a last will and testament set" do
before(:each) do
client.set_will('topic', 'hello', retain=false, qos=1)
@@ -427,13 +452,13 @@
end
it "should include the will in the CONNECT message" do
client.connect('myclient')
expect(socket.string).to eq(
- "\x10\x24"+
- "\x00\x06MQIsdp"+
- "\x03\x0e\x00\x0f"+
+ "\x10\x22"+
+ "\x00\x04MQTT"+
+ "\x04\x0e\x00\x0f"+
"\x00\x08myclient"+
"\x00\x05topic\x00\x05hello"
)
end
end
@@ -471,10 +496,11 @@
it "should not raise an exception for a successful CONNACK packet" do
socket.write("\x20\x02\x00\x00")
socket.rewind
expect { client.send(:receive_connack) }.not_to raise_error
+ expect(socket).not_to be_closed
end
it "should raise an exception if the packet type isn't CONNACK" do
socket.write("\xD0\x00")
socket.rewind
@@ -502,10 +528,17 @@
it "should raise an exception if the CONNACK packet return code is an unknown" do
socket.write("\x20\x02\x00\xAA")
socket.rewind
expect { client.send(:receive_connack) }.to raise_error(MQTT::ProtocolException, /connection refused/i)
end
+
+ it "should close the socket for an unsuccessful CONNACK packet" do
+ socket.write("\x20\x02\x00\x05")
+ socket.rewind
+ expect { client.send(:receive_connack) }.to raise_error(MQTT::ProtocolException, /not authorised/i)
+ expect(socket).to be_closed
+ end
end
describe "when calling the 'disconnect' method" do
before(:each) do
thread = double('Read Thread', :alive? => true, :kill => true)
@@ -593,11 +626,11 @@
end
it "correctly assigns consecutive ids to packets with QoS 1" do
inject_puback(1)
inject_puback(2)
-
+
expect(client).to receive(:send_packet) { |packet| expect(packet.id).to eq(1) }
client.publish "topic", "message", false, 1
expect(client).to receive(:send_packet) { |packet| expect(packet.id).to eq(2) }
client.publish "topic", "message", false, 1
end
@@ -675,10 +708,19 @@
expect(topic).to eq('topic1')
expect(payload).to eq('payload1')
expect(client.queue_empty?).to be_truthy
end
+ it "should successfully receive a valid PUBLISH packet, but not return it, if omit_retained is set" do
+ inject_packet(:topic => 'topic1', :payload => 'payload1', :qos => 1, :retain => 1)
+ inject_packet(:topic => 'topic1', :payload => 'payload2', :qos => 1)
+ topic,payload = client.get(nil, :omit_retained => true)
+ expect(topic).to eq('topic1')
+ expect(payload).to eq('payload2')
+ expect(client.queue_empty?).to be_truthy
+ end
+
it "acks calling #get_packet and qos=1" do
inject_packet(:topic => 'topic1', :payload => 'payload1', :qos => 1)
expect(client).to receive(:send_packet).with(an_instance_of(MQTT::Packet::Puback))
client.get_packet
end
@@ -710,10 +752,22 @@
client.get do |topic,payload|
payloads << payload
break if payloads.size > 1
end
end
+
+ it "should ignore a PUBLISH message when it is marked as retained and omit_retained is set" do
+ inject_packet(:topic => 'topic0', :payload => 'payload0', :retain => 1)
+ inject_packet(:topic => 'topic1', :payload => 'payload1')
+ payloads = []
+ client.get(nil, :omit_retained => true) do |topic,payload|
+ payloads << payload
+ break if payloads.size > 0
+ end
+ expect(payloads.size).to eq(1)
+ expect(payloads).to eq(['payload1'])
+ end
end
end
describe "when calling the 'get_packet' method" do
before(:each) do
@@ -842,9 +896,16 @@
client.send('keep_alive!')
}.to raise_error(
MQTT::ProtocolException,
/No Ping Response received for \d+ seconds/
)
+ end
+
+ it "should not raise an exception if no ping response received and client is disconnected" do
+ client.instance_variable_set('@last_ping_request', Time.now)
+ client.instance_variable_set('@last_ping_response', Time.at(0))
+ client.disconnect(false)
+ client.send('keep_alive!')
end
end
describe "generating a client identifier" do
context "with default parameters" do