fix(nightscape): do not fail on empty array

This commit is contained in:
Jan De Dobbeleer 2021-11-24 15:07:25 +01:00 committed by Jan De Dobbeleer
parent 8269148aab
commit 1075b82e10
2 changed files with 84 additions and 21 deletions

View file

@ -2,6 +2,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
) )
// segment struct, makes templating easier // segment struct, makes templating easier
@ -82,46 +83,59 @@ func (ns *nightscout) string() string {
} }
func (ns *nightscout) getResult() (*NightscoutData, error) { func (ns *nightscout) getResult() (*NightscoutData, error) {
url := ns.props.getString(URL, "") parseSingleElement := func(data []byte) (*NightscoutData, error) {
// natural and understood NS timeout is 5, anything else is unusual var result []*NightscoutData
cacheTimeout := ns.props.getInt(NSCacheTimeout, 5) err := json.Unmarshal(data, &result)
response := &NightscoutData{} if err != nil {
if cacheTimeout > 0 { return nil, err
// check if data stored in cache }
val, found := ns.env.cache().get(url) if len(result) == 0 {
return nil, errors.New("no elements in the array")
}
return result[0], nil
}
getCacheValue := func(key string) (*NightscoutData, error) {
val, found := ns.env.cache().get(key)
// we got something from the cache // we got something from the cache
if found { if found {
err := json.Unmarshal([]byte(val), response) if data, err := parseSingleElement([]byte(val)); err == nil {
if err != nil { return data, nil
return nil, err
} }
return response, nil }
return nil, errors.New("no data in cache")
}
url := ns.props.getString(URL, "")
httpTimeout := ns.props.getInt(HTTPTimeout, DefaultHTTPTimeout)
// natural and understood NS timeout is 5, anything else is unusual
cacheTimeout := ns.props.getInt(NSCacheTimeout, 5)
if cacheTimeout > 0 {
if data, err := getCacheValue(url); err == nil {
return data, nil
} }
} }
httpTimeout := ns.props.getInt(HTTPTimeout, DefaultHTTPTimeout)
body, err := ns.env.doGet(url, httpTimeout) body, err := ns.env.doGet(url, httpTimeout)
if err != nil { if err != nil {
return &NightscoutData{}, err return nil, err
} }
var arr []*NightscoutData var arr []*NightscoutData
err = json.Unmarshal(body, &arr) err = json.Unmarshal(body, &arr)
if err != nil { if err != nil {
return &NightscoutData{}, err return nil, err
} }
firstelement := arr[0] data, err := parseSingleElement(body)
firstData, err := json.Marshal(firstelement)
if err != nil { if err != nil {
return &NightscoutData{}, err return nil, err
} }
if cacheTimeout > 0 { if cacheTimeout > 0 {
// persist new sugars in cache // persist new sugars in cache
ns.env.cache().set(url, string(firstData), cacheTimeout) ns.env.cache().set(url, string(body), cacheTimeout)
} }
return firstelement, nil return data, nil
} }
func (ns *nightscout) init(props *properties, env environmentInfo) { func (ns *nightscout) init(props *properties, env environmentInfo) {

View file

@ -17,6 +17,8 @@ func TestNSSegment(t *testing.T) {
JSONResponse string JSONResponse string
ExpectedString string ExpectedString string
ExpectedEnabled bool ExpectedEnabled bool
CacheTimeout int
CacheFoundFail bool
Template string Template string
Error error Error error
}{ }{
@ -82,18 +84,65 @@ func TestNSSegment(t *testing.T) {
Error: errors.New("Something went wrong"), Error: errors.New("Something went wrong"),
ExpectedEnabled: false, ExpectedEnabled: false,
}, },
{
Case: "Empty array",
JSONResponse: "[]",
ExpectedEnabled: false,
},
{
Case: "DoubleDown 50 from cache",
JSONResponse: `
[{"_id":"619d6fa819696e8ded5b2206","sgv":50,"date":1637707537000,"dateString":"2021-11-23T22:45:37.000Z","trend":4,"direction":"DoubleDown","device":"share2","type":"sgv","utcOffset":0,"sysTime":"2021-11-23T22:45:37.000Z","mills":1637707537000}]`, // nolint:lll
Template: " {{.Sgv}}{{.TrendIcon}}",
ExpectedString: " 50↓↓",
ExpectedEnabled: true,
CacheTimeout: 10,
},
{
Case: "DoubleDown 50 from cache not found",
JSONResponse: `
[{"_id":"619d6fa819696e8ded5b2206","sgv":50,"date":1637707537000,"dateString":"2021-11-23T22:45:37.000Z","trend":4,"direction":"DoubleDown","device":"share2","type":"sgv","utcOffset":0,"sysTime":"2021-11-23T22:45:37.000Z","mills":1637707537000}]`, // nolint:lll
Template: " {{.Sgv}}{{.TrendIcon}}",
ExpectedString: " 50↓↓",
ExpectedEnabled: true,
CacheTimeout: 10,
CacheFoundFail: true,
},
{
Case: "Error parsing response",
JSONResponse: `
4tffgt4e4567`,
Template: " {{.Sgv}}{{.TrendIcon}}",
ExpectedString: " 50↓↓",
ExpectedEnabled: false,
CacheTimeout: 10,
},
{
Case: "Faulty template",
JSONResponse: `
[{"sgv":50,"direction":"DoubleDown"}]`,
Template: " {{.Sgv}}{{.Burp}}",
ExpectedString: incorrectTemplate,
ExpectedEnabled: true,
CacheTimeout: 10,
},
} }
for _, tc := range cases { for _, tc := range cases {
env := &MockedEnvironment{} env := &MockedEnvironment{}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
CacheTimeout: 0, CacheTimeout: tc.CacheTimeout,
URL: "FAKE", URL: "FAKE",
}, },
} }
cache := &MockedCache{}
cache.On("get", NSAPIURL).Return(tc.JSONResponse, !tc.CacheFoundFail)
cache.On("set", NSAPIURL, tc.JSONResponse, tc.CacheTimeout).Return()
env.On("doGet", NSAPIURL).Return([]byte(tc.JSONResponse), tc.Error) env.On("doGet", NSAPIURL).Return([]byte(tc.JSONResponse), tc.Error)
env.On("cache", nil).Return(cache)
if tc.Template != "" { if tc.Template != "" {
props.values[SegmentTemplate] = tc.Template props.values[SegmentTemplate] = tc.Template