more unit tests for fronius plugin
BrainDoctor committed
Jul 18, 2017 at 16:16 UTC
1b54db67ba71dd2c65dd31d49cb8798ac4cc4d89
5 files changed
+349
-65
node.d/fronius.node.js
+22
-7
@@ -205,9 +205,8 @@ var fronius = {
205
},
206
207
processResponse: function (service, content) {
208
- if (content === null) return;
209
- var json = JSON.parse(content);
210
- if (!fronius.isResponseValid(json)) return;
208
+ var json = fronius.parseResponse(content);
209
+ if (json === null) return;
210
211
// add the service
212
service.commit();
@@ -255,12 +254,19 @@ var fronius = {
254
}
255
},
256
257
+ parseResponse: function (httpBody) {
258
+ if (httpBody === null) return null;
259
+ var json = httpBody;
260
+ if (typeof httpBody !== "object") json = JSON.parse(httpBody);
261
+ return this.isResponseValid(json) ? json : null;
262
+ },
263
+
264
// some basic validation
265
isResponseValid: function (json) {
260
- if (fronius.isUndefined(json.Body)) return false;
261
- if (fronius.isUndefined(json.Body.Data)) return false;
262
- if (fronius.isUndefined(json.Body.Data.Site)) return false;
263
- return fronius.isDefined(json.Body.Data.Inverters);
266
+ if (this.isUndefined(json.Body)) return false;
267
+ if (this.isUndefined(json.Body.Data)) return false;
268
+ if (this.isUndefined(json.Body.Data.Site)) return false;
269
+ return this.isDefined(json.Body.Data.Inverters);
270
},
271
272
// module.serviceExecute()
@@ -287,6 +293,7 @@ var fronius = {
293
while (len--) {
294
var server = config.servers[len];
295
if (fronius.isUndefined(server.update_every)) server.update_every = this.update_every;
296
+ if (fronius.areUndefined([server.name, server.hostname, server.api_path])) continue;
297
298
var url = server.hostname + server.api_path;
299
this.serviceExecute(server.name, url, server.update_every);
@@ -309,6 +316,14 @@ var fronius = {
316
return typeof value === 'undefined';
317
},
318
319
+ areUndefined: function (valueArray) {
320
+ var i = 0;
321
+ for (i; i < valueArray.length; i++) {
322
+ if (this.isUndefined(valueArray[i])) return true;
323
+ }
324
+ return false;
325
+ },
326
+
327
isDefined: function (value) {
328
return typeof value !== 'undefined';
329
}
tests/node.d/fronius.chart.spec.js
new
+102
@@ -0,0 +1,102 @@
1
+"use strict";
2
+
3
+var netdata = require("../../node.d/node_modules/netdata");
4
+// remember: subject will be a singleton!
5
+var subject = require("../../node.d/fronius.node");
6
+
7
+var service = netdata.service({
8
+ name: "fronius",
9
+ module: this
10
+});
11
+
12
+describe("fronius chart creation", function () {
13
+
14
+ beforeAll(function () {
15
+ // change this to enable debug log
16
+ netdata.options.DEBUG = false;
17
+ });
18
+
19
+ it("should return a basic chart dimension", function () {
20
+ var result = subject.createBasicDimension("id", "name", 2);
21
+
22
+ expect(result.divisor).toBe(2);
23
+ expect(result.id).toBe("id");
24
+ expect(result.algorithm).toEqual(netdata.chartAlgorithms.absolute);
25
+ expect(result.multiplier).toBe(1);
26
+ });
27
+
28
+ it("should return the power chart definition", function () {
29
+ var id = "power";
30
+ var result = subject.getSitePowerChart(service, id);
31
+
32
+ expect(result.id).toBe(id);
33
+ expect(result.units).toBe("W");
34
+ expect(result.type).toBe(netdata.chartTypes.area);
35
+ expect(result.family).toBe("power");
36
+ expect(result.context).toBe("fronius.power");
37
+ expect(result.dimensions[subject.powerGridId].name).toBe("Grid");
38
+ expect(result.dimensions[subject.powerPvId].name).toBe("Photovoltaics");
39
+ expect(result.dimensions[subject.powerAccuId].name).toBe("Accumulator");
40
+ expect(Object.keys(result.dimensions).length).toBe(3);
41
+ });
42
+
43
+ it("should return the consumption chart definition", function () {
44
+ var id = "Load";
45
+ var result = subject.getSiteConsumptionChart(service, id);
46
+
47
+ expect(result.id).toBe(id);
48
+ expect(result.units).toBe("W");
49
+ expect(result.type).toBe(netdata.chartTypes.area);
50
+ expect(result.family).toBe("consumption");
51
+ expect(result.context).toBe("fronius.consumption");
52
+ expect(Object.keys(result.dimensions).length).toBe(1);
53
+ expect(result.dimensions[subject.consumptionLoadId].name).toBe("Load");
54
+ });
55
+
56
+ it("should return the autonomy chart definition", function () {
57
+ var id = "Autonomy";
58
+ var result = subject.getSiteAutonomyChart(service, id);
59
+
60
+ expect(result.id).toBe(id);
61
+ expect(result.units).toBe("%");
62
+ expect(result.type).toBe(netdata.chartTypes.area);
63
+ expect(result.family).toBe("autonomy");
64
+ expect(result.context).toBe("fronius.autonomy");
65
+ expect(Object.keys(result.dimensions).length).toBe(2);
66
+ expect(result.dimensions[subject.autonomyId].name).toBe("Autonomy");
67
+ expect(result.dimensions[subject.consumptionSelfId].name).toBe("Self Consumption");
68
+ });
69
+
70
+ it("should return the energy today chart definition", function () {
71
+ var id = "Energy today";
72
+ var result = subject.getSiteEnergyTodayChart(service, id);
73
+
74
+ expect(result.id).toBe(id);
75
+ expect(result.units).toBe("kWh");
76
+ expect(result.type).toBe(netdata.chartTypes.area);
77
+ expect(result.family).toBe("energy");
78
+ expect(result.context).toBe("fronius.energy.today");
79
+ expect(Object.keys(result.dimensions).length).toBe(1);
80
+ expect(result.dimensions[subject.energyTodayId].name).toBe("Today");
81
+ });
82
+
83
+ it("should return the energy year chart definition", function () {
84
+ var id = "Energy year";
85
+ var result = subject.getSiteEnergyYearChart(service, id);
86
+
87
+ expect(result.id).toBe(id);
88
+ expect(result.units).toBe("kWh");
89
+ expect(result.type).toBe(netdata.chartTypes.area);
90
+ expect(result.family).toBe("energy");
91
+ expect(result.context).toBe("fronius.energy.year");
92
+ expect(Object.keys(result.dimensions).length).toBe(1);
93
+ expect(result.dimensions[subject.energyYearId].name).toBe("Year");
94
+ });
95
+
96
+ it("should return the same chart definition on second call for lazy loading", function () {
97
+ var first = subject.getSitePowerChart(service, "id");
98
+ var second = subject.getSitePowerChart(service, "id");
99
+
100
+ expect(first).toBe(second);
101
+ });
102
+});
\ No newline at end of file
tests/node.d/fronius.parse.spec.js
new
+67
@@ -0,0 +1,67 @@
1
+"use strict";
2
+
3
+var netdata = require("../../node.d/node_modules/netdata");
4
+// remember: subject will be a singleton!
5
+var subject = require("../../node.d/fronius.node");
6
+
7
+var service = netdata.service({
8
+ name: "fronius",
9
+ module: this
10
+});
11
+
12
+describe("fronius data parsing", function () {
13
+
14
+ var fakeResponse = {
15
+ "Head" : {
16
+ "RequestArguments" : {},
17
+ "Status" : {
18
+ "Code" : 0,
19
+ "Reason" : "",
20
+ "UserMessage" : ""
21
+ },
22
+ "Timestamp" : "2017-07-17T16:01:04+02:00"
23
+ },
24
+ "Body" : {
25
+ "Data" : {
26
+ "Site" : {
27
+ "Mode" : "meter",
28
+ "P_Grid" : -3430.729923,
29
+ "P_Load" : -910.270077,
30
+ "P_Akku" : null,
31
+ "P_PV" : 4341,
32
+ "rel_SelfConsumption" : 20.969133,
33
+ "rel_Autonomy" : 100,
34
+ "E_Day" : 57230,
35
+ "E_Year" : 6425915.5,
36
+ "E_Total" : 15388710,
37
+ "Meter_Location" : "grid"
38
+ },
39
+ "Inverters" : {
40
+ "1" : {
41
+ "DT" : 123,
42
+ "P" : 4341,
43
+ "E_Day" : 57230,
44
+ "E_Year" : 6425915.5,
45
+ "E_Total" : 15388710
46
+ }
47
+ }
48
+ }
49
+ }
50
+ };
51
+
52
+ beforeAll(function () {
53
+ // change this to enable debug log
54
+ netdata.options.DEBUG = false;
55
+ });
56
+
57
+ it("should return a parsed value", function () {
58
+ // arrange
59
+ netdata.send = jasmine.createSpy("send");
60
+ // act
61
+ subject.processResponse(service, fakeResponse);
62
+ var result = netdata.send.calls.argsFor(0)[0];
63
+ // assert
64
+ expect(result).toContain("SET p_grid = -3431");
65
+ });
66
+
67
+});
tests/node.d/fronius.spec.js
deleted
-58
@@ -1,58 +0,0 @@
1
-"use strict";
2
-// delete these comments if not needed anymore.
3
-
4
-var netdata = require("../../node.d/node_modules/netdata");
5
-var fronius = require("../../node.d/fronius.node");
6
-
7
-describe("fronius chart creation", function () {
8
-
9
- beforeAll(function () {
10
- // change this to enable debug log
11
- netdata.options.DEBUG = false;
12
- });
13
-
14
- it("should return a basic chart definition", function () {
15
- // act
16
- var result = fronius.createBasicDimension("id", "name", 2);
17
- // assert
18
- expect(result.divisor).toBe(2);
19
- expect(result.id).toBe("id");
20
- expect(result.algorithm).toEqual("absolute");
21
- expect(result.multiplier).toBe(1);
22
- });
23
-
24
- it("will fail", function () {
25
- netdata.debug("test");
26
-
27
- throw new Error("demonstrate failure of unit test runner");
28
- });
29
-
30
-});
31
-
32
-describe("fronius data parsing", function () {
33
-
34
- var service = netdata.service({
35
- name: "fronius",
36
- module: this
37
- });
38
-
39
- // this is a faked JSON response from the server.
40
- // Used with freeformatter.com/json-escape.html to escape the json and turn it into a string.
41
- var fakeResponse = "{\r\n\t\"Head\" : {\r\n\t\t\"RequestArguments\" : {},\r\n\t\t\"Status\" : {\r\n\t\t\t\"Code\" : 0,\r\n\t\t\t\"Reason\" : \"\",\r\n\t\t\t\"UserMessage\" : \"\"\r\n\t\t},\r\n\t\t\"Timestamp\" : \"2017-07-17T16:01:04+02:00\"\r\n\t},\r\n\t\"Body\" : {\r\n\t\t\"Data\" : {\r\n\t\t\t\"Site\" : {\r\n\t\t\t\t\"Mode\" : \"meter\",\r\n\t\t\t\t\"P_Grid\" : -3430.729923,\r\n\t\t\t\t\"P_Load\" : -910.270077,\r\n\t\t\t\t\"P_Akku\" : null,\r\n\t\t\t\t\"P_PV\" : 4341,\r\n\t\t\t\t\"rel_SelfConsumption\" : 20.969133,\r\n\t\t\t\t\"rel_Autonomy\" : 100,\r\n\t\t\t\t\"E_Day\" : 57230,\r\n\t\t\t\t\"E_Year\" : 6425915.5,\r\n\t\t\t\t\"E_Total\" : 15388710,\r\n\t\t\t\t\"Meter_Location\" : \"grid\"\r\n\t\t\t},\r\n\t\t\t\"Inverters\" : {\r\n\t\t\t\t\"1\" : {\r\n\t\t\t\t\t\"DT\" : 123,\r\n\t\t\t\t\t\"P\" : 4341,\r\n\t\t\t\t\t\"E_Day\" : 57230,\r\n\t\t\t\t\t\"E_Year\" : 6425915.5,\r\n\t\t\t\t\t\"E_Total\" : 15388710\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}"
42
-
43
- beforeAll(function () {
44
- // change this to enable debug log
45
- netdata.options.DEBUG = false;
46
- });
47
-
48
- it("should return a parsed value", function () {
49
- // arrange
50
- netdata.send = jasmine.createSpy("send");
51
- // act
52
- fronius.processResponse(service, fakeResponse);
53
- var result = netdata.send.calls.argsFor(0)[0];
54
- // assert
55
- expect(result).toContain("SET p_grid = -3431");
56
- });
57
-
58
-});
tests/node.d/fronius.validation.spec.js
new
+158
@@ -0,0 +1,158 @@
1
+"use strict";
2
+
3
+var netdata = require("../../node.d/node_modules/netdata");
4
+// remember: subject will be a singleton!
5
+var subject = require("../../node.d/fronius.node");
6
+
7
+var service = netdata.service({
8
+ name: "fronius",
9
+ module: this
10
+});
11
+
12
+describe("fronius response validation", function () {
13
+
14
+ // this is a faked JSON response from the server.
15
+ // Used with freeformatter.com/json-escape.html to escape the json and turn it into a string.
16
+ var fakeResponse = "{\r\n\t\"Head\" : {\r\n\t\t\"RequestArguments\" : {},\r\n\t\t\"Status\" " +
17
+ ": {\r\n\t\t\t\"Code\" : 0,\r\n\t\t\t\"Reason\" : \"\",\r\n\t\t\t\"UserMessage\" : " +
18
+ "\"\"\r\n\t\t},\r\n\t\t\"Timestamp\" : \"2017-07-17T16:01:04+02:00\"\r\n\t},\r\n\t\"Body\" : " +
19
+ "{\r\n\t\t\"Data\" : {\r\n\t\t\t\"Site\" : {\r\n\t\t\t\t\"Mode\" : \"meter\",\r\n\t\t\t\t\"P_Grid\" " +
20
+ ": -3430.729923,\r\n\t\t\t\t\"P_Load\" : -910.270077,\r\n\t\t\t\t\"P_Akku\" : " +
21
+ "null,\r\n\t\t\t\t\"P_PV\" : 4341,\r\n\t\t\t\t\"rel_SelfConsumption\" : " +
22
+ "20.969133,\r\n\t\t\t\t\"rel_Autonomy\" : 100,\r\n\t\t\t\t\"E_Day\" : 57230,\r\n\t\t\t\t\"E_Year\" " +
23
+ ": 6425915.5,\r\n\t\t\t\t\"E_Total\" : 15388710,\r\n\t\t\t\t\"Meter_Location\" : " +
24
+ "\"grid\"\r\n\t\t\t},\r\n\t\t\t\"Inverters\" : {\r\n\t\t\t\t\"1\" : {\r\n\t\t\t\t\t\"DT\" : " +
25
+ "123,\r\n\t\t\t\t\t\"P\" : 4341,\r\n\t\t\t\t\t\"E_Day\" : 57230,\r\n\t\t\t\t\t\"E_Year\" : " +
26
+ "6425915.5,\r\n\t\t\t\t\t\"E_Total\" : 15388710\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}";
27
+
28
+ it("should do nothing if response is null", function () {
29
+ netdata.send = jasmine.createSpy("send");
30
+
31
+ subject.processResponse(service, null);
32
+ var result = netdata.send.calls.count();
33
+
34
+ expect(result).toBe(0);
35
+ });
36
+
37
+ it("should return null if response is null", function () {
38
+ var result = subject.parseResponse(null);
39
+
40
+ expect(result).toBeNull();
41
+ });
42
+
43
+ it("should return true if response is valid", function () {
44
+ var result = subject.isResponseValid({
45
+ "Body": {
46
+ "Data": {
47
+ "Site": {
48
+ "Mode": "meter"
49
+ },
50
+ "Inverters": {
51
+ "1": {}
52
+ }
53
+ }
54
+ }
55
+ });
56
+
57
+ expect(result).toBeTruthy();
58
+ });
59
+
60
+ it("should return false if response is missing data", function () {
61
+ var result = subject.isResponseValid({
62
+ "Body": {}
63
+ });
64
+
65
+ expect(result).toBeFalsy();
66
+ });
67
+
68
+ it("should return false if response is missing inverter", function () {
69
+ var result = subject.isResponseValid({
70
+ "Body": {
71
+ "Data": {
72
+ "Site": {}
73
+ }
74
+ }
75
+ });
76
+
77
+ expect(result).toBeFalsy();
78
+ });
79
+
80
+ it("should return false if response is missing inverter", function () {
81
+ var result = subject.isResponseValid({
82
+ "Body": {
83
+ "Data": {
84
+ "Inverters": {}
85
+ }
86
+ }
87
+ });
88
+
89
+ expect(result).toBeFalsy();
90
+ });
91
+
92
+});
93
+
94
+describe("fronius configuration validation", function () {
95
+
96
+ it("should return 0 if there are no servers configured", function () {
97
+ var result = subject.configure({});
98
+
99
+ expect(result).toBe(0);
100
+ });
101
+
102
+ it("should return 0 if the servers array is empty", function () {
103
+ var result = subject.configure({
104
+ "servers": []
105
+ });
106
+
107
+ expect(result).toBe(0);
108
+ });
109
+
110
+ it("should return 0 if there is one server configured incorrectly", function () {
111
+ var result = subject.configure({
112
+ "servers": [{}]
113
+ });
114
+
115
+ expect(result).toBe(0);
116
+ });
117
+
118
+ it("should return 1 if there is one server configured", function () {
119
+ subject.serviceExecute = jasmine.createSpy("serviceExecute");
120
+ var name = "solar1";
121
+ var result = subject.configure({
122
+ "servers": [{
123
+ "name": name,
124
+ "api_path": "/api/",
125
+ "hostname": "solar1.local"
126
+ }]
127
+ });
128
+
129
+ expect(result).toBe(1);
130
+ expect(subject.serviceExecute).toHaveBeenCalledWith(name, "solar1.local/api/", 5);
131
+ });
132
+
133
+ it("should return 2 if there are two servers configured", function () {
134
+ subject.serviceExecute = jasmine.createSpy("serviceExecute");
135
+ var name1 = "solar 1";
136
+ var name2 = "solar 2";
137
+ var result = subject.configure({
138
+ "servers": [
139
+ {
140
+ "name": name1,
141
+ "api_path": "/",
142
+ "hostname": "solar1.local"
143
+ },
144
+ {
145
+ "name": name2,
146
+ "api_path": "/",
147
+ "hostname": "solar2.local",
148
+ "update_every": 3
149
+ }
150
+ ]
151
+ });
152
+
153
+ expect(result).toBe(2);
154
+ expect(subject.serviceExecute).toHaveBeenCalledWith(name1, "solar1.local/", 5);
155
+ expect(subject.serviceExecute).toHaveBeenCalledWith(name2, "solar2.local/", 3);
156
+ });
157
+
158
+});
\ No newline at end of file