Explorar el Código

Add tests for MQTT device alias functionality

Christopher Mullins hace 6 años
padre
commit
3191095e5a
Se han modificado 2 ficheros con 126 adiciones y 46 borrados
  1. 8 5
      test/remote/helpers/mqtt_helpers.rb
  2. 118 41
      test/remote/spec/mqtt_spec.rb

+ 8 - 5
test/remote/helpers/mqtt_helpers.rb

@@ -5,7 +5,7 @@ module MqttHelpers
     ENV.fetch('ESPMH_MQTT_TOPIC_PREFIX')
   end
 
-  def mqtt_parameters
+  def mqtt_parameters(overrides = {})
     topic_prefix = mqtt_topic_prefix()
 
     {
@@ -15,17 +15,20 @@ module MqttHelpers
       mqtt_topic_pattern: "#{topic_prefix}commands/:device_id/:device_type/:group_id",
       mqtt_state_topic_pattern: "#{topic_prefix}state/:device_id/:device_type/:group_id",
       mqtt_update_topic_pattern: "#{topic_prefix}updates/:device_id/:device_type/:group_id"
-    }
+    }.merge(overrides)
   end
 
-  def create_mqtt_client
-    params = mqtt_parameters
+  def create_mqtt_client(overrides = {})
+    params =
+      mqtt_parameters
+      .merge({topic_prefix: mqtt_topic_prefix()})
+      .merge(overrides)
 
     MqttClient.new(
       params[:mqtt_server],
       params[:mqtt_username],
       params[:mqtt_password],
-      mqtt_topic_prefix()
+      params[:topic_prefix]
     )
   end
 end

+ 118 - 41
test/remote/spec/mqtt_spec.rb

@@ -4,7 +4,9 @@ RSpec.describe 'MQTT' do
   before(:all) do
     @client = ApiClient.new(ENV.fetch('ESPMH_HOSTNAME'), ENV.fetch('ESPMH_TEST_DEVICE_ID_BASE'))
     @client.upload_json('/settings', 'settings.json')
+  end
 
+  before(:each) do
     mqtt_params = mqtt_parameters()
     @updates_topic = mqtt_params[:updates_topic]
     @topic_prefix = mqtt_topic_prefix()
@@ -13,9 +15,7 @@ RSpec.describe 'MQTT' do
       '/settings',
       mqtt_params
     )
-  end
 
-  before(:each) do
     @id_params = {
       id: @client.generate_id,
       type: 'rgb_cct',
@@ -287,7 +287,7 @@ RSpec.describe 'MQTT' do
     end
   end
 
-  context ':hex_device_id for update/state topics' do
+  describe ':hex_device_id for update/state topics' do
     before(:all) do
       @client.put(
         '/settings',
@@ -304,36 +304,38 @@ RSpec.describe 'MQTT' do
       )
     end
 
-    it 'should publish updates with hexadecimal device ID' do
-      seen_update = false
+    context 'state and updates' do
+      it 'should publish updates with hexadecimal device ID' do
+        seen_update = false
 
-      @mqtt_client.on_update(@id_params) do |id, message|
-        seen_update = (message['state'] == 'ON')
-      end
+        @mqtt_client.on_update(@id_params) do |id, message|
+          seen_update = (message['state'] == 'ON')
+        end
 
-      # Will use hex by default
-      @mqtt_client.patch_state(@id_params, status: 'ON')
-      @mqtt_client.wait_for_listeners
+        # Will use hex by default
+        @mqtt_client.patch_state(@id_params, status: 'ON')
+        @mqtt_client.wait_for_listeners
 
-      expect(seen_update).to eq(true)
-    end
+        expect(seen_update).to eq(true)
+      end
 
-    it 'should publish state with hexadecimal device ID' do
-      seen_state = false
+      it 'should publish state with hexadecimal device ID' do
+        seen_state = false
 
-      @mqtt_client.on_state(@id_params) do |id, message|
-        seen_state = (message['status'] == 'ON')
-      end
+        @mqtt_client.on_state(@id_params) do |id, message|
+          seen_state = (message['status'] == 'ON')
+        end
 
-      # Will use hex by default
-      @mqtt_client.patch_state(@id_params, status: 'ON')
-      @mqtt_client.wait_for_listeners
+        # Will use hex by default
+        @mqtt_client.patch_state(@id_params, status: 'ON')
+        @mqtt_client.wait_for_listeners
 
-      expect(seen_state).to eq(true)
+        expect(seen_state).to eq(true)
+      end
     end
   end
 
-  context ':dec_device_id for update/state topics' do
+  describe ':dec_device_id for update/state topics' do
     before(:all) do
       @client.put(
         '/settings',
@@ -350,34 +352,109 @@ RSpec.describe 'MQTT' do
       )
     end
 
-    it 'should publish updates with hexadecimal device ID' do
-      seen_update = false
-      @id_params = @id_params.merge(id_format: 'decimal')
+    context 'state and updates' do
+      it 'should publish updates with hexadecimal device ID' do
+        seen_update = false
+        @id_params = @id_params.merge(id_format: 'decimal')
 
-      @mqtt_client.on_update(@id_params) do |id, message|
-        seen_update = (message['state'] == 'ON')
+        @mqtt_client.on_update(@id_params) do |id, message|
+          seen_update = (message['state'] == 'ON')
+        end
+
+        sleep 1
+
+        # Will use hex by default
+        @mqtt_client.patch_state(@id_params, status: 'ON')
+        @mqtt_client.wait_for_listeners
+
+        expect(seen_update).to eq(true)
       end
 
-      # Will use hex by default
-      @mqtt_client.patch_state(@id_params, status: 'ON')
-      @mqtt_client.wait_for_listeners
+      it 'should publish state with hexadecimal device ID' do
+        seen_state = false
+        @id_params = @id_params.merge(id_format: 'decimal')
+
+        @mqtt_client.on_state(@id_params) do |id, message|
+          seen_state = (message['status'] == 'ON')
+        end
 
-      expect(seen_update).to eq(true)
+        sleep 1
+
+        # Will use hex by default
+        @mqtt_client.patch_state(@id_params, status: 'ON')
+        @mqtt_client.wait_for_listeners
+
+        expect(seen_state).to eq(true)
+      end
     end
+  end
 
-    it 'should publish state with hexadecimal device ID' do
-      seen_state = false
-      @id_params = @id_params.merge(id_format: 'decimal')
+  describe 'device aliases' do
+    before(:each) do
+      @aliases_topic = "#{mqtt_topic_prefix()}commands/:device_alias"
+      @client.patch_settings(
+        mqtt_topic_pattern: @aliases_topic,
+        group_id_aliases: {
+          'test_group' => [@id_params[:type], @id_params[:id], @id_params[:group_id]]
+        }
+      )
+      @client.delete_state(@id_params)
+    end
 
-      @mqtt_client.on_state(@id_params) do |id, message|
-        seen_state = (message['status'] == 'ON')
+    context ':device_alias token' do
+      it 'should accept it for command topic' do
+        @client.patch_settings(mqtt_topic_pattern: @aliases_topic)
+
+        @mqtt_client.publish("#{mqtt_topic_prefix()}commands/test_group", status: 'ON')
+
+        sleep(1)
+
+        state = @client.get_state(@id_params)
+        expect(state['status']).to eq('ON')
       end
 
-      # Will use hex by default
-      @mqtt_client.patch_state(@id_params, status: 'ON')
-      @mqtt_client.wait_for_listeners
+      it 'should support publishing state to device alias topic' do
+        @client.patch_settings(
+          mqtt_topic_pattern: @aliases_topic,
+          mqtt_state_topic_pattern: "#{mqtt_topic_prefix()}state/:device_alias"
+        )
 
-      expect(seen_state).to eq(true)
+        seen_alias = nil
+        seen_state = nil
+
+        @mqtt_client.on_message("#{mqtt_topic_prefix()}state/+") do |topic, message|
+          parts = topic.split('/')
+
+          seen_alias = parts.last
+          seen_state = JSON.parse(message)
+
+          seen_alias == 'test_group'
+        end
+        @mqtt_client.publish("#{mqtt_topic_prefix()}commands/test_group", status: 'ON')
+
+        @mqtt_client.wait_for_listeners
+
+        expect(seen_alias).to eq('test_group')
+        expect(seen_state['status']).to eq('ON')
+      end
+
+      it 'should delete retained alias messages' do
+        seen_empty_message = false
+
+        @client.patch_settings(mqtt_state_topic_pattern: "#{mqtt_topic_prefix()}state/:device_alias")
+        @client.patch_state(@id_params, status: 'ON')
+
+        @mqtt_client.on_message("#{mqtt_topic_prefix()}state/test_group") do |topic, message|
+          seen_empty_message = message.empty?
+        end
+
+        @client.patch_state(@id_params, hue: 100)
+        @client.delete_state(@id_params)
+
+        @mqtt_client.wait_for_listeners
+
+        expect(seen_empty_message).to eq(true)
+      end
     end
   end
 end