浏览代码

Fix bug where settings were not applied after POSTing

Christopher Mullins 6 年之前
父节点
当前提交
d88656dd44
共有 4 个文件被更改,包括 83 次插入2 次删除
  1. 3 0
      lib/Settings/Settings.cpp
  2. 7 1
      lib/WebServer/MiLightHttpServer.cpp
  3. 15 1
      test/remote/lib/api_client.rb
  4. 58 0
      test/remote/spec/settings_spec.rb

+ 3 - 0
lib/Settings/Settings.cpp

@@ -162,6 +162,9 @@ void Settings::patch(JsonObject& parsedSettings) {
 
 void Settings::load(Settings& settings) {
   if (SPIFFS.exists(SETTINGS_FILE)) {
+    // Clear in-memory settings
+    settings = Settings();
+
     File f = SPIFFS.open(SETTINGS_FILE, "r");
     String settingsContents = f.readStringUntil(SETTINGS_TERMINATOR);
     f.close();

+ 7 - 1
lib/WebServer/MiLightHttpServer.cpp

@@ -31,7 +31,7 @@ void MiLightHttpServer::begin() {
 
   server.onPatternAuthenticated("/raw_commands/:type", HTTP_ANY, [this](const UrlTokenBindings* b) { handleSendRaw(b); });
   server.onAuthenticated("/web", HTTP_POST, [this]() { server.send_P(200, TEXT_PLAIN, PSTR("success")); }, handleUpdateFile(WEB_INDEX_FILENAME));
-  server.on("/about", HTTP_GET, [this]() { handleAbout(); });
+  server.onAuthenticated("/about", HTTP_GET, [this]() { handleAbout(); });
   server.onAuthenticated("/system", HTTP_POST, [this]() { handleSystemPost(); });
   server.onAuthenticated("/firmware", HTTP_POST, [this]() { handleFirmwarePost(); }, [this]() { handleFirmwareUpload(); });
 
@@ -213,6 +213,12 @@ void MiLightHttpServer::handleUpdateSettings() {
 
 void MiLightHttpServer::handleUpdateSettingsPost() {
   Settings::load(settings);
+
+  this->applySettings(settings);
+  if (this->settingsSavedHandler) {
+    this->settingsSavedHandler();
+  }
+
   server.send_P(200, TEXT_PLAIN, PSTR("success."));
 }
 

+ 15 - 1
test/remote/lib/api_client.rb

@@ -15,6 +15,16 @@ class ApiClient
     id
   end
 
+  def set_auth!(username, password)
+    @username = username
+    @password = password
+  end
+
+  def clear_auth!
+    @username = nil
+    @password = nil
+  end
+
   def request(type, path, req_body = nil)
     uri = URI("http://#{@host}#{path}")
     Net::HTTP.start(uri.host, uri.port) do |http|
@@ -27,6 +37,10 @@ class ApiClient
         req.body = req_body
       end
 
+      if @username && @password
+        req.basic_auth(@username, @password)
+      end
+
       res = http.request(req)
       res.value
 
@@ -41,7 +55,7 @@ class ApiClient
   end
 
   def upload_json(path, file)
-    `curl -s "http://#{@host}#{path}" -X POST -F 'f=@settings.json'`
+    `curl -s "http://#{@host}#{path}" -X POST -F 'f=@#{file}'`
   end
 
   def get(path)

+ 58 - 0
test/remote/spec/settings_spec.rb

@@ -1,9 +1,67 @@
 require 'api_client'
+require 'tempfile'
 
 RSpec.describe 'Settings' do
   before(:all) do
     @client = ApiClient.new(ENV.fetch('ESPMH_HOSTNAME'), ENV.fetch('ESPMH_TEST_DEVICE_ID_BASE'))
     @client.upload_json('/settings', 'settings.json')
+
+    @username = 'a'
+    @password = 'a'
+  end
+
+  after(:all) do
+    @client.set_auth!(@username, @password)
+    @client.put('/settings', admin_username: '', admin_password: '')
+    @client.clear_auth!
+  end
+
+  before(:each) do
+    @client.set_auth!(@username, @password)
+    @client.put('/settings', admin_username: '', admin_password: '')
+    @client.clear_auth!
+  end
+
+  context 'POST settings file' do
+    it 'should clobber patched settings' do
+      file = Tempfile.new('espmh-settings.json')
+      file.write({
+        mqtt_server: 'test123'
+      }.to_json)
+      file.close
+
+      @client.upload_json('/settings', file.path)
+
+      settings = @client.get('/settings')
+      expect(settings['mqtt_server']).to eq('test123')
+
+      @client.put('/settings', {mqtt_server: 'abc123', mqtt_username: 'foo'})
+      
+      settings = @client.get('/settings')
+      expect(settings['mqtt_server']).to eq('abc123')
+      expect(settings['mqtt_username']).to eq('foo')
+
+      @client.upload_json('/settings', file.path)
+      settings = @client.get('/settings')
+
+      expect(settings['mqtt_server']).to eq('test123')
+      expect(settings['mqtt_username']).to eq('')
+
+      File.delete(file.path)
+    end
+
+    it 'should apply POSTed settings' do
+      file = Tempfile.new('espmh-settings.json')
+      file.write({
+        admin_username: @username,
+        admin_password: @password
+      }.to_json)
+      file.close
+
+      @client.upload_json('/settings', file.path)
+
+      expect { @client.get('/settings') }.to raise_error(Net::HTTPServerException)
+    end
   end
 
   context 'radio' do