From 34ab89f2291a9d719b4804868bdfc42f50c4b19b Mon Sep 17 00:00:00 2001 From: Alec <30310787+alec-pinson@users.noreply.github.com> Date: Sat, 25 Mar 2023 10:16:35 +0000 Subject: [PATCH] Allow insecure https urls (#3) * Allow insecure https urls * some urls won't return json so don't error on this * added some response code checks * add response to trigger endpoint * fix disable bug, added more tests --- cmd/terrarium-bot-v2/alert.go | 6 +- cmd/terrarium-bot-v2/apiserver.go | 1 + cmd/terrarium-bot-v2/config.go | 2 + cmd/terrarium-bot-v2/config_test.go | 282 +++++++++++------------- cmd/terrarium-bot-v2/configuration.yaml | 4 + cmd/terrarium-bot-v2/http.go | 22 +- cmd/terrarium-bot-v2/http_test.go | 10 +- cmd/terrarium-bot-v2/sensor.go | 8 +- cmd/terrarium-bot-v2/switch.go | 14 +- cmd/terrarium-bot-v2/trigger.go | 9 +- cmd/terrarium-bot-v2/trigger_test.go | 50 ++++- 11 files changed, 227 insertions(+), 181 deletions(-) diff --git a/cmd/terrarium-bot-v2/alert.go b/cmd/terrarium-bot-v2/alert.go index 63c8ecf..47a55fa 100644 --- a/cmd/terrarium-bot-v2/alert.go +++ b/cmd/terrarium-bot-v2/alert.go @@ -125,8 +125,8 @@ func (a *Alert) isDisabled() bool { if a.Disabled == 0 { return false } - if a.DisabledAt.Add(a.Disabled).After(time.Now()) { - return true + if a.DisabledAt.Add(a.Disabled).Before(time.Now()) { + return false } - return false + return true } diff --git a/cmd/terrarium-bot-v2/apiserver.go b/cmd/terrarium-bot-v2/apiserver.go index eeaf3d0..2ec5761 100644 --- a/cmd/terrarium-bot-v2/apiserver.go +++ b/cmd/terrarium-bot-v2/apiserver.go @@ -29,6 +29,7 @@ func (apiServer APIServer) Endpoint(w http.ResponseWriter, r *http.Request) { // check if this is a trigger endpoint, if so do action yes, t := isTriggerEndpoint(path) if yes { + fmt.Fprintf(w, "ok") t.doAction("Triggered by endpoint '" + path + "'") } } diff --git a/cmd/terrarium-bot-v2/config.go b/cmd/terrarium-bot-v2/config.go index 3663e60..a96f2f1 100644 --- a/cmd/terrarium-bot-v2/config.go +++ b/cmd/terrarium-bot-v2/config.go @@ -48,6 +48,7 @@ type Switch struct { Id string `yaml:"id"` On string `yaml:"on"` Off string `yaml:"off"` + Insecure bool `yaml:"insecure"` Status string // on/off Disabled time.Duration DisabledAt time.Time @@ -57,6 +58,7 @@ type Switch struct { type Sensor struct { Id string `yaml:"id"` Url string `yaml:"url"` + Insecure bool `yaml:"insecure"` JsonPath string `yaml:"jsonPath"` Unit string `yaml:"unit"` Value int diff --git a/cmd/terrarium-bot-v2/config_test.go b/cmd/terrarium-bot-v2/config_test.go index 4d9cfc0..fa7d91a 100644 --- a/cmd/terrarium-bot-v2/config_test.go +++ b/cmd/terrarium-bot-v2/config_test.go @@ -4,192 +4,166 @@ import ( "os" "testing" "time" + + "github.com/stretchr/testify/assert" ) -func TestLoad(t *testing.T) { +func TestLoadConfig(t *testing.T) { // set up environment variables os.Setenv("DEBUG", "true") os.Setenv("DRY_RUN", "true") os.Setenv("CONFIG_FILE", "test.yaml") os.Setenv("NOTIFICATION_USER_TOKEN", "user123") os.Setenv("NOTIFICATION_API_TOKEN", "api123") - os.Setenv("USE_IN_MEMORY_STATUS", "false") - - // create test configuration - expectedConfig := Config{ - Debug: true, - DryRun: true, - File: "test.yaml", - Day: StartAction{Start: "08:00", Action: []string{"do this", "then that"}}, - Night: StartAction{Start: "22:00", Action: []string{"do that", "then this"}}, - Sunrise: StartAction{Start: "06:00", Action: []string{"do something"}}, - Sunset: StartAction{Start: "18:00", Action: []string{"do something else"}}, - Trigger: []*Trigger{{Id: "tigger1", Sensor: "sensor1", Endpoint: "endpoint1", When: When{}, Action: []string{"do this"}}}, - Switch: []*Switch{{Id: "switch1", On: "on", Off: "off"}}, - Sensor: []*Sensor{{Id: "sensor1", Url: "http://sensor1.com", JsonPath: "path1", Unit: "unit1"}}, - Notification: []*Notification{{ - Id: "notif1", - AntiSpam: 10 * time.Minute, - Device: "device1", - UserToken: "NOTIFICATION_USER_TOKEN", - APIToken: "NOTIFICATION_API_TOKEN", - UserTokenValue: "", - APITokenValue: "", - LastNotification: time.Time{}, - }}, - Alert: []*Alert{{Sensor: "sensor1", When: When{}, After: 30 * time.Minute, Notification: []string{"notif1"}}}, - UseInMemoryStatus: false, - } - - // convert times - expectedConfig.Day.StartTime, _ = time.Parse("15:04", expectedConfig.Day.Start) - expectedConfig.Night.StartTime, _ = time.Parse("15:04", expectedConfig.Night.Start) - expectedConfig.Sunrise.StartTime, _ = time.Parse("15:04", expectedConfig.Sunrise.Start) - expectedConfig.Sunset.StartTime, _ = time.Parse("15:04", expectedConfig.Sunset.Start) + os.Setenv("USE_IN_MEMORY_STATUS", "true") // create the test yaml file - data := ` + configFileYaml := ` day: - start: 08:00 - action: - - do this - - then that + start: "06:00" + action: ["doSomething"] night: - start: 22:00 - action: - - do that - - then this + start: "22:00" + action: ["doSomething"] sunrise: - start: 06:00 - action: - - do something + start: "06:22" + action: ["doSomething"] sunset: - start: 18:00 - action: - - do something else + start: "21:30" + action: ["doSomething"] trigger: - - id: trigger1 - sensor: sensor1 - endpoint: endpoint1 + - id: "trigger1" + sensor: "sensor1" + endpoint: "http://localhost:8080" when: day: - below: 50 - above: 100 + below: 5 night: - below: 20 - above: 80 - action: - - do this - else: - - do that + below: 5 + action: ["doSomething"] + else: ["doSomethingElse"] + - id: "trigger2" + sensor: "sensor2" + endpoint: "http://anotherhost:8080" + when: + day: + above: 100 + every: 10s + action: ["doSomething", "doSomethingElse"] + else: ["doSomethingElse", "doSomethingElseElse"] switch: - - id: switch1 - on: on - off: off + - id: "switch1" + on: "http://localhost:8081/on" + off: "http://localhost:8081/off" + insecure: true + - id: "switch2" + on: "http://localhost:8081/on" + off: "http://localhost:8081/off" + insecure: false sensor: - - id: sensor1 - url: http://sensor1.com - jsonPath: path1 - unit: unit1 + - id: "sensor1" + url: "http://localhost:8888" + jsonPath: "json.path" + unit: "unit" + - id: "sensor2" + url: "http://localhost:9999" + jsonPath: "json.path" + unit: "unit" notification: - - id: notif1 - antiSpam: 10m - device: device1 - userToken: NOTIFICATION_USER_TOKEN - apiToken: NOTIFICATION_API_TOKEN - lastNotification: "" + - id: "notification1" + antiSpam: "30s" + device: "my_device" + userToken: "NOTIFICATION_USER_TOKEN" + apiToken: "NOTIFICATION_API_TOKEN" alert: - - sensor: sensor1 + - id: "alert1" + sensor: "sensor1" when: day: - below: 50 - above: 100 + below: 10 night: - below: 20 - above: 80 - after: 30m - notification: - - notif1 -useInMemoryStatus: false` - err := os.WriteFile("test.yaml", []byte(data), 0644) + below: 5 + after: "20m" + notification: ["notification1"] +useInMemoryStatus: true` + err := os.WriteFile("test.yaml", []byte(configFileYaml), 0644) if err != nil { t.Errorf("Error creating test.yaml: %v", err) } // load the configuration - loadedConfig := expectedConfig.Load() + loadedConfig := config.Load() // ensure loaded configuration matches expected values - if loadedConfig.Debug != expectedConfig.Debug { - t.Errorf("Expected Debug %v, got %v", expectedConfig.Debug, loadedConfig.Debug) - } - if loadedConfig.DryRun != expectedConfig.DryRun { - t.Errorf("Expected DryRun %v, got %v", expectedConfig.DryRun, loadedConfig.DryRun) - } - if loadedConfig.File != expectedConfig.File { - t.Errorf("Expected File %v, got %v", expectedConfig.File, loadedConfig.File) - } - if loadedConfig.Day.Start != expectedConfig.Day.Start { - t.Errorf("Expected Day.Start %v, got %v", expectedConfig.Day.Start, loadedConfig.Day.Start) - } - if !loadedConfig.Day.StartTime.Equal(expectedConfig.Day.StartTime) { - t.Errorf("Expected Day.StartTime %v, got %v", expectedConfig.Day.StartTime, loadedConfig.Day.StartTime) - } - if len(loadedConfig.Day.Action) != len(expectedConfig.Day.Action) { - t.Errorf("Expected %v actions, got %v", len(expectedConfig.Day.Action), len(loadedConfig.Day.Action)) - } - if loadedConfig.Night.Start != expectedConfig.Night.Start { - t.Errorf("Expected Night.Start %v, got %v", expectedConfig.Night.Start, loadedConfig.Night.Start) - } - if !loadedConfig.Night.StartTime.Equal(expectedConfig.Night.StartTime) { - t.Errorf("Expected Night.StartTime %v, got %v", expectedConfig.Night.StartTime, loadedConfig.Night.StartTime) - } - if len(loadedConfig.Night.Action) != len(expectedConfig.Night.Action) { - t.Errorf("Expected %v actions, got %v", len(expectedConfig.Night.Action), len(loadedConfig.Night.Action)) - } - if loadedConfig.Sunrise.Start != expectedConfig.Sunrise.Start { - t.Errorf("Expected Sunrise.Start %v, got %v", expectedConfig.Sunrise.Start, loadedConfig.Sunrise.Start) - } - if !loadedConfig.Sunrise.StartTime.Equal(expectedConfig.Sunrise.StartTime) { - t.Errorf("Expected Sunrise.StartTime %v, got %v", expectedConfig.Sunrise.StartTime, loadedConfig.Sunrise.StartTime) - } - if len(loadedConfig.Sunrise.Action) != len(expectedConfig.Sunrise.Action) { - t.Errorf("Expected %v actions, got %v", len(expectedConfig.Sunrise.Action), len(loadedConfig.Sunrise.Action)) - } - if loadedConfig.Sunset.Start != expectedConfig.Sunset.Start { - t.Errorf("Expected Sunset.Start %v, got %v", expectedConfig.Sunset.Start, loadedConfig.Sunset.Start) - } - if !loadedConfig.Sunset.StartTime.Equal(expectedConfig.Sunset.StartTime) { - t.Errorf("Expected Sunset.StartTime %v, got %v", expectedConfig.Sunset.StartTime, loadedConfig.Sunset.StartTime) - } - if len(loadedConfig.Sunset.Action) != len(expectedConfig.Sunset.Action) { - t.Errorf("Expected %v actions, got %v", len(expectedConfig.Sunset.Action), len(loadedConfig.Sunset.Action)) - } - if len(loadedConfig.Trigger) != len(expectedConfig.Trigger) { - t.Errorf("Expected %v triggers, got %v", len(expectedConfig.Trigger), len(loadedConfig.Trigger)) - } - if len(loadedConfig.Switch) != len(expectedConfig.Switch) { - t.Errorf("Expected %v switches, got %v", len(expectedConfig.Switch), len(loadedConfig.Switch)) - } - if len(loadedConfig.Sensor) != len(expectedConfig.Sensor) { - t.Errorf("Expected %v sensors, got %v", len(expectedConfig.Sensor), len(loadedConfig.Sensor)) - } - if len(loadedConfig.Notification) != len(expectedConfig.Notification) { - t.Errorf("Expected %v notifications, got %v", len(expectedConfig.Notification), len(loadedConfig.Notification)) - } - if len(loadedConfig.Alert) != len(expectedConfig.Alert) { - t.Errorf("Expected %v alerts, got %v", len(expectedConfig.Alert), len(loadedConfig.Alert)) - } - if loadedConfig.UseInMemoryStatus != expectedConfig.UseInMemoryStatus { - t.Errorf("Expected UseInMemoryStatus %v, got %v", expectedConfig.UseInMemoryStatus, loadedConfig.UseInMemoryStatus) - } - if loadedConfig.Notification[0].UserTokenValue != "user123" { - t.Errorf("Expected UserTokenValue %v, got %v", "user123", loadedConfig.Notification[0].UserTokenValue) - } - if loadedConfig.Notification[0].APITokenValue != "api123" { - t.Errorf("Expected APITokenValue %v, got %v", "api123", loadedConfig.Notification[0].APITokenValue) - } + assert.True(t, loadedConfig.Debug) + assert.True(t, loadedConfig.DryRun) + assert.Equal(t, "test.yaml", loadedConfig.File) + + assert.Equal(t, "06:00", loadedConfig.Day.Start) + assert.Equal(t, []string{"doSomething"}, loadedConfig.Day.Action) + dayStartTime, err := time.Parse("15:04", "06:00") + assert.NoError(t, err) + assert.Equal(t, dayStartTime, loadedConfig.Day.StartTime) + + assert.Equal(t, "22:00", loadedConfig.Night.Start) + assert.Equal(t, []string{"doSomething"}, loadedConfig.Night.Action) + nightStartTime, err := time.Parse("15:04", "22:00") + assert.NoError(t, err) + assert.Equal(t, nightStartTime, loadedConfig.Night.StartTime) + + assert.Equal(t, "06:22", loadedConfig.Sunrise.Start) + assert.Equal(t, []string{"doSomething"}, loadedConfig.Sunrise.Action) + sunriseStartTime, err := time.Parse("15:04", "06:22") + assert.NoError(t, err) + assert.Equal(t, sunriseStartTime, loadedConfig.Sunrise.StartTime) + + assert.Equal(t, "21:30", loadedConfig.Sunset.Start) + assert.Equal(t, []string{"doSomething"}, loadedConfig.Sunset.Action) + sunsetStartTime, err := time.Parse("15:04", "21:30") + assert.NoError(t, err) + assert.Equal(t, sunsetStartTime, loadedConfig.Sunset.StartTime) + + assert.Len(t, loadedConfig.Trigger, 2) + assert.Equal(t, "trigger1", loadedConfig.Trigger[0].Id) + assert.Equal(t, "sensor1", loadedConfig.Trigger[0].Sensor) + assert.Equal(t, "http://localhost:8080", loadedConfig.Trigger[0].Endpoint) + assert.Equal(t, 5, loadedConfig.Trigger[0].When.Day.Below) + assert.Equal(t, 5, loadedConfig.Trigger[0].When.Night.Below) + assert.Equal(t, []string{"doSomething"}, loadedConfig.Trigger[0].Action) + assert.Equal(t, []string{"doSomethingElse"}, loadedConfig.Trigger[0].Else) + + assert.Len(t, loadedConfig.Switch, 2) + assert.Equal(t, "switch1", loadedConfig.Switch[0].Id) + assert.Equal(t, "http://localhost:8081/on", loadedConfig.Switch[0].On) + assert.Equal(t, "http://localhost:8081/off", loadedConfig.Switch[0].Off) + assert.True(t, loadedConfig.Switch[0].Insecure) + + assert.Len(t, loadedConfig.Sensor, 2) + assert.Equal(t, "sensor1", loadedConfig.Sensor[0].Id) + assert.Equal(t, "http://localhost:8888", loadedConfig.Sensor[0].Url) + assert.False(t, loadedConfig.Sensor[0].Insecure) + assert.Equal(t, "json.path", loadedConfig.Sensor[0].JsonPath) + assert.Equal(t, "unit", loadedConfig.Sensor[0].Unit) + + assert.Len(t, loadedConfig.Notification, 1) + assert.Equal(t, "notification1", loadedConfig.Notification[0].Id) + assert.Equal(t, 30*time.Second, loadedConfig.Notification[0].AntiSpam) + assert.Equal(t, "my_device", loadedConfig.Notification[0].Device) + assert.Equal(t, "NOTIFICATION_USER_TOKEN", loadedConfig.Notification[0].UserToken) + assert.Equal(t, "NOTIFICATION_API_TOKEN", loadedConfig.Notification[0].APIToken) + assert.Equal(t, "user123", loadedConfig.Notification[0].UserTokenValue) + assert.Equal(t, "api123", loadedConfig.Notification[0].APITokenValue) + + assert.Len(t, loadedConfig.Alert, 1) + assert.Equal(t, "alert1", loadedConfig.Alert[0].Id) + assert.Equal(t, "sensor1", loadedConfig.Alert[0].Sensor) + assert.Equal(t, 10, loadedConfig.Alert[0].When.Day.Below) + assert.Equal(t, 5, loadedConfig.Alert[0].When.Night.Below) + assert.Equal(t, 20*time.Minute, loadedConfig.Alert[0].After) + assert.Equal(t, []string{"notification1"}, loadedConfig.Alert[0].Notification) + + assert.True(t, loadedConfig.UseInMemoryStatus) - // clean up test files + // clean up os.Remove("test.yaml") } diff --git a/cmd/terrarium-bot-v2/configuration.yaml b/cmd/terrarium-bot-v2/configuration.yaml index efbb90c..f422418 100644 --- a/cmd/terrarium-bot-v2/configuration.yaml +++ b/cmd/terrarium-bot-v2/configuration.yaml @@ -30,6 +30,7 @@ sunset: start: "20:55" action: - switch.big_led.off + - alert.temperature.disable.1h # disable temperature alert for 1 hour (allow to settle from day to night temps) trigger: - id: heating @@ -115,12 +116,15 @@ switch: - id: camera-night-vision-1 on: https://root:${CAMERA_PASSWORD}@dafang/cgi-bin/action.cgi?cmd=toggle-rtsp-nightvision-on off: https://root:${CAMERA_PASSWORD}@dafang/cgi-bin/action.cgi?cmd=toggle-rtsp-nightvision-off + insecure: true # ignore ssl certificate - id: camera-night-vision-2 on: https://root:${CAMERA_PASSWORD}@dafang/cgi-bin/action.cgi?cmd=ir_led_on off: https://root:${CAMERA_PASSWORD}@dafang/cgi-bin/action.cgi?cmd=ir_led_off + insecure: true # ignore ssl certificate - id: camera-night-vision-3 on: https://root:${CAMERA_PASSWORD}@dafang/cgi-bin/action.cgi?cmd=ir_cut_off off: https://root:${CAMERA_PASSWORD}@dafang/cgi-bin/action.cgi?cmd=ir_cut_on + insecure: true # ignore ssl certificate sensor: # - id: temperature diff --git a/cmd/terrarium-bot-v2/http.go b/cmd/terrarium-bot-v2/http.go index 2c934a3..36cad9b 100644 --- a/cmd/terrarium-bot-v2/http.go +++ b/cmd/terrarium-bot-v2/http.go @@ -1,6 +1,7 @@ package main import ( + "crypto/tls" "encoding/json" "fmt" "log" @@ -8,13 +9,18 @@ import ( "net/http/httputil" ) -func SendRequest(url string) (map[string]interface{}, error) { +func SendRequest(url string, insecure bool) (map[string]interface{}, int, error) { result := map[string]interface{}{} - resp, err := http.Get(url) + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure}, + } + client := &http.Client{Transport: tr} + + resp, err := client.Get(url) if err != nil { log.Println(err) - return nil, err + return nil, 0, err } defer resp.Body.Close() @@ -29,12 +35,8 @@ func SendRequest(url string) (map[string]interface{}, error) { fmt.Printf("Response\n: %v\n\n", string(responseDump)) } - // decode and return response + // attempt decode and return response decoder := json.NewDecoder(resp.Body) - err = decoder.Decode(&result) - if err != nil { - log.Println(err) - return nil, err - } - return result, nil + decoder.Decode(&result) + return result, resp.StatusCode, nil } diff --git a/cmd/terrarium-bot-v2/http_test.go b/cmd/terrarium-bot-v2/http_test.go index ddab173..1a44dae 100644 --- a/cmd/terrarium-bot-v2/http_test.go +++ b/cmd/terrarium-bot-v2/http_test.go @@ -28,10 +28,13 @@ func TestSendRequest(t *testing.T) { defer server.Close() // Send request to mocked server URL - res, err := SendRequest(server.URL) + res, respCode, err := SendRequest(server.URL, false) if err != nil { t.Fatalf("Unexpected error: %v", err) } + if respCode != 200 { + t.Fatalf("Expected response code 200, got %v", respCode) + } // Assert response is as expected if !reflect.DeepEqual(res, expected) { @@ -40,9 +43,12 @@ func TestSendRequest(t *testing.T) { }) t.Run("Invalid URL", func(t *testing.T) { - _, err := SendRequest("invalid_url") + _, respCode, err := SendRequest("invalid_url", false) if err == nil { t.Error("Expected error, but got nil") } + if respCode != 0 { + t.Fatalf("Expected response code 0, got %v", respCode) + } }) } diff --git a/cmd/terrarium-bot-v2/sensor.go b/cmd/terrarium-bot-v2/sensor.go index 7c8149d..fea9e1e 100644 --- a/cmd/terrarium-bot-v2/sensor.go +++ b/cmd/terrarium-bot-v2/sensor.go @@ -35,13 +35,19 @@ func (s *Sensor) GetValue() int { } func (s *Sensor) getSensorValue() int { - r, err := SendRequest(s.Url) + r, respCode, err := SendRequest(s.Url, s.Insecure) if err != nil { log.Println(err) + return 0 + } + if respCode != 200 { + log.Printf("Unable to get sensor value, response code: %v", respCode) + return 0 } b, err := json.MarshalIndent(r, "", " ") if err != nil { log.Println(err) + return 0 } value := getJsonValue(string(b), s.JsonPath) intValue, err := strconv.Atoi(fmt.Sprintf("%.0f", value)) diff --git a/cmd/terrarium-bot-v2/switch.go b/cmd/terrarium-bot-v2/switch.go index 75e470a..ac8d850 100644 --- a/cmd/terrarium-bot-v2/switch.go +++ b/cmd/terrarium-bot-v2/switch.go @@ -65,10 +65,10 @@ func (s *Switch) isDisabled() bool { if s.Disabled == 0 { return false } - if s.DisabledAt.Add(s.Disabled).After(time.Now()) { - return true + if s.DisabledAt.Add(s.Disabled).Before(time.Now()) { + return false } - return false + return true } func (s *Switch) fixURLs() { if strings.Contains(s.On, "$") { @@ -91,8 +91,8 @@ func (s *Switch) TurnOn(For string, Reason string) { s.SetLastAction() if !config.DryRun { - _, err := SendRequest(s.On) - if err != nil { + _, respCode, err := SendRequest(s.On, s.Insecure) + if err != nil || respCode != 200 { log.Printf("Switch Offline: %s", s.Id) for _, n := range config.Notification { n.SendNotification("Currently unable to turn on switch '%s'. Please check the logs.", s.Id) @@ -116,8 +116,8 @@ func (s *Switch) TurnOff(reason string) { } s.SetLastAction() if !config.DryRun { - _, err := SendRequest(s.Off) - if err != nil { + _, respCode, err := SendRequest(s.Off, s.Insecure) + if err != nil || respCode != 200 { log.Printf("Switch Offline: %s", s.Id) for _, n := range config.Notification { n.SendNotification("Currently unable to turn off switch '%s'. Please check the logs.", s.Id) diff --git a/cmd/terrarium-bot-v2/trigger.go b/cmd/terrarium-bot-v2/trigger.go index 5d14672..71c2117 100644 --- a/cmd/terrarium-bot-v2/trigger.go +++ b/cmd/terrarium-bot-v2/trigger.go @@ -50,6 +50,9 @@ func (t *Trigger) monitor() { if t.isDisabled() { Debug("Trigger %s is currently disabled", t.Id) + if isTesting { + return + } time.Sleep(1 * time.Minute) continue } @@ -173,8 +176,8 @@ func (t *Trigger) isDisabled() bool { if t.Disabled == 0 { return false } - if t.DisabledAt.Add(t.Disabled).After(time.Now()) { - return true + if t.DisabledAt.Add(t.Disabled).Before(time.Now()) { + return false } - return false + return true } diff --git a/cmd/terrarium-bot-v2/trigger_test.go b/cmd/terrarium-bot-v2/trigger_test.go index cdefc07..06d3ee7 100644 --- a/cmd/terrarium-bot-v2/trigger_test.go +++ b/cmd/terrarium-bot-v2/trigger_test.go @@ -5,7 +5,7 @@ import ( "time" ) -func TestMonitorSensor(t *testing.T) { +func TestMonitorTrigger(t *testing.T) { // disable http calls when turning on/off switches config.DryRun = true // set testing mode so we exit the for loop @@ -48,6 +48,22 @@ func TestMonitorSensor(t *testing.T) { t.Errorf("Trigger should have turned off the mock-switch but didn't") } + config.Debug = true + + // test dsiabled triggers + trigger.Disable("2s", "") + s.Value = 60 + time.Sleep(1 * time.Second) + trigger.monitor() + if ss.getStatus() != "off" { + t.Errorf("Trigger should still be turned off but isn't") + } + time.Sleep(3 * time.Second) + trigger.monitor() + if ss.getStatus() != "on" { + t.Errorf("Trigger should have turned on the mock-switch but didn't") + } + // reset config.DryRun = false isTesting = false @@ -70,3 +86,35 @@ func TestIsTriggerEndpoint(t *testing.T) { t.Errorf("Expected endpoint to not exist") } } + +func TestTriggerDisable(t *testing.T) { + trigger := &Trigger{Id: "disable"} + + // Set disable and ensure that it's set correctly + trigger.Disable("1m", "") + if trigger.Disabled != 1*time.Minute { + t.Errorf("Trigger Disable was not set correctly") + } +} + +func TestTriggerIsDisabled(t *testing.T) { + // Test case 1: trigger should not be disabled + trigger := Trigger{Disabled: 0} + trigger.Disable("", "") + trigger.Enable("") + if trigger.isDisabled() { + t.Errorf("Test case 1 failed: expected false but got true") + } + + // Test case 2: trigger should be disabled for 2 seconds + trigger.Disable("2s", "") + time.Sleep(1 * time.Second) // sleep for 1 second + if !trigger.isDisabled() { + t.Errorf("Test case 2 failed: expected true but got false") + } + time.Sleep(3 * time.Second) // sleep for 3 seconds + // should not be disabled anymore + if trigger.isDisabled() { + t.Errorf("Test case 2 failed: expected false but got true") + } +}