Coverage for tests/test_microservice_websocket/test_routes/test_route_payload.py: 99%

131 statements  

« prev     ^ index     » next       coverage.py v7.0.0, created at 2022-12-20 14:31 +0000

1import pytest 

2from fastapi.testclient import TestClient 

3from mock import mock_open, patch 

4 

5from microservice_websocket.app.services import database as db 

6from microservice_websocket.app.utils.enums import NodeState, PayloadType 

7 

8 

9class TestPublishPayload: 

10 endpoint = "/api/payload/" 

11 

12 # Trying to post data to non-existing application 

13 @pytest.mark.asyncio 

14 async def test_publish_not_existing_app(self, app_client: TestClient): 

15 org = db.Organization(organizationName="foo") 

16 await org.save() 

17 # Done setup 

18 

19 with patch("builtins.open", mock_open(read_data="1234")): 

20 response = app_client.post( 

21 self.endpoint, 

22 json={ 

23 "nodeID": 123, 

24 "nodeName": "nodeName", 

25 "applicationID": "63186eab0ca2d54a5c258384", 

26 "organizationID": str(org.id), 

27 "payloadType": PayloadType.TOTAL_READING, 

28 "data": None, 

29 }, 

30 headers={"Authorization": "Bearer 1234"}, 

31 ) 

32 

33 assert ( 

34 response.status_code == 404 

35 ), "Invalid response code when posting data to non-existing application" 

36 

37 # Post data to non-existing node 

38 @pytest.mark.asyncio 

39 async def test_publish_not_existing_node(self, app_client: TestClient): 

40 org = db.Organization(organizationName="foo") 

41 await org.save() 

42 app = db.Application(applicationName="bar", organization=org.id) 

43 await app.save() 

44 # Done setup 

45 

46 total_reading_data = { 

47 "canID": 1, 

48 "sensorNumber": 2, 

49 "value": 3, 

50 "count": 111, 

51 "sessionID": 3, 

52 "readingID": 1, 

53 } 

54 

55 with ( 

56 patch("builtins.open", mock_open(read_data="1234")), 

57 patch("socketio.Client.emit", return_value=None), 

58 ): 

59 response = app_client.post( 

60 self.endpoint, 

61 json={ 

62 "nodeID": 123, 

63 "nodeName": "nodeName", 

64 "applicationID": str(app.id), 

65 "organizationID": str(org.id), 

66 "payloadType": PayloadType.TOTAL_READING, 

67 "data": total_reading_data, 

68 }, 

69 headers={"Authorization": "Bearer 1234"}, 

70 ) 

71 

72 assert ( 

73 response.status_code == 200 

74 ), "Invalid response code when publishing valid payload" 

75 assert ( 

76 len(await db.Node.find_all().to_list()) == 1 

77 ), "Couldn't create node upon posting data" 

78 assert ( 

79 len(await db.Reading.find_all().to_list()) == 1 

80 ), "Couldn't create reading upon posting data" 

81 assert ( 

82 node := await db.Node.find_one() 

83 ) and node.state == NodeState.READY, "Invalid Node state" 

84 

85 # Post all window readings 

86 @pytest.mark.asyncio 

87 async def test_publish_window_readings(self, app_client: TestClient): 

88 org = db.Organization(organizationName="foo") 

89 await org.save() 

90 app = db.Application(applicationName="bar", organization=org.id) 

91 await app.save() 

92 total_reading_data = { 

93 "canID": 1, 

94 "sensorNumber": 2, 

95 "value": 3, 

96 "count": 111, 

97 "sessionID": 3, 

98 "readingID": 1, 

99 } 

100 

101 with ( 

102 patch("builtins.open", mock_open(read_data="1234")), 

103 patch("socketio.Client.emit", return_value=None), 

104 ): 

105 response = app_client.post( 

106 self.endpoint, 

107 json={ 

108 "nodeID": 123, 

109 "nodeName": "nodeName", 

110 "applicationID": str(app.id), 

111 "organizationID": str(org.id), 

112 "payloadType": PayloadType.TOTAL_READING, 

113 "data": total_reading_data, 

114 }, 

115 headers={"Authorization": "Bearer 1234"}, 

116 ) 

117 # Done setup 

118 

119 data_w1 = { 

120 "canID": 1, 

121 "sensorNumber": 2, 

122 "value": 0, 

123 "count": 111, 

124 "sessionID": 3, 

125 "readingID": 1, 

126 } 

127 

128 data_w2 = { 

129 "canID": 1, 

130 "sensorNumber": 2, 

131 "value": 1, 

132 "count": 222, 

133 "sessionID": 3, 

134 "readingID": 1, 

135 } 

136 

137 data_w3 = { 

138 "canID": 1, 

139 "sensorNumber": 2, 

140 "value": 2, 

141 "count": 333, 

142 "sessionID": 3, 

143 "readingID": 1, 

144 } 

145 

146 with ( 

147 patch("builtins.open", mock_open(read_data="1234")), 

148 patch("socketio.Client.emit", return_value=None), 

149 ): 

150 for data in [data_w1, data_w2, data_w3]: 

151 response = app_client.post( 

152 self.endpoint, 

153 json={ 

154 "nodeID": 123, 

155 "nodeName": "nodeName", 

156 "applicationID": str(app.id), 

157 "organizationID": str(org.id), 

158 "payloadType": PayloadType.WINDOW_READING, 

159 "data": data, 

160 }, 

161 headers={"Authorization": "Bearer 1234"}, 

162 ) 

163 

164 assert ( 

165 response.status_code == 200 

166 ), "Invalid response code when publishing valid payload" 

167 

168 assert len(await db.Node.find_all().to_list()) == 1, "Invalid node count" 

169 assert ( 

170 node := await db.Node.find_one() 

171 ) and node.state == NodeState.RUNNING, "Invalid Node state" 

172 assert ( 

173 len(await db.Reading.find_all().to_list()) == 1 

174 ), "Couldn't merge readings with same readingID, canID and sensorNumber" 

175 

176 reading = await db.Reading.find_one() 

177 assert reading 

178 

179 assert ( 

180 reading.dangerLevel == 3 

181 and reading.window1 == 111 

182 and reading.window2 == 222 

183 and reading.window3 == 333 

184 ), "Invalid reading merge" 

185 

186 # Create reading by sending windows first 

187 @pytest.mark.asyncio 

188 async def test_publish_windows_first(self, app_client: TestClient): 

189 org = db.Organization(organizationName="foo") 

190 await org.save() 

191 app = db.Application(applicationName="bar", organization=org.id) 

192 await app.save() 

193 # Done setup 

194 

195 data_w1 = { 

196 "canID": 1, 

197 "sensorNumber": 2, 

198 "value": 0, 

199 "count": 111, 

200 "sessionID": 5, 

201 "readingID": 7, 

202 } 

203 

204 data_w2 = { 

205 "canID": 1, 

206 "sensorNumber": 2, 

207 "value": 1, 

208 "count": 222, 

209 "sessionID": 5, 

210 "readingID": 7, 

211 } 

212 

213 data_w3 = { 

214 "canID": 1, 

215 "sensorNumber": 2, 

216 "value": 2, 

217 "count": 333, 

218 "sessionID": 5, 

219 "readingID": 7, 

220 } 

221 

222 data_total = { 

223 "canID": 1, 

224 "sensorNumber": 2, 

225 "value": 4, 

226 "count": 777, 

227 "sessionID": 5, 

228 "readingID": 7, 

229 } 

230 

231 with ( 

232 patch("builtins.open", mock_open(read_data="1234")), 

233 patch("socketio.Client.emit", return_value=None), 

234 ): 

235 for data in [data_w1, data_w2, data_w3]: 

236 response = app_client.post( 

237 self.endpoint, 

238 json={ 

239 "nodeID": 123, 

240 "nodeName": "nodeName", 

241 "applicationID": str(app.id), 

242 "organizationID": str(org.id), 

243 "payloadType": PayloadType.WINDOW_READING, 

244 "data": data, 

245 }, 

246 headers={"Authorization": "Bearer 1234"}, 

247 ) 

248 assert ( 

249 response.status_code == 200 

250 ), "Invalid response code when publishing valid payload" 

251 

252 # End the registration 

253 node = await db.Node.find_one() 

254 assert node 

255 node.state = NodeState.READY 

256 await node.save() 

257 

258 response = app_client.post( 

259 self.endpoint, 

260 json={ 

261 "nodeID": 123, 

262 "nodeName": "nodeName", 

263 "applicationID": str(app.id), 

264 "organizationID": str(org.id), 

265 "payloadType": PayloadType.TOTAL_READING, 

266 "data": data_total, 

267 }, 

268 headers={"Authorization": "Bearer 1234"}, 

269 ) 

270 

271 assert ( 

272 response.status_code == 200 

273 ), "Invalid response code when publishing valid payload" 

274 

275 assert ( 

276 len(await db.Node.find_all().to_list()) == 1 

277 ), "Invalid number of Node" 

278 assert ( 

279 len(await db.Reading.find_all().to_list()) == 1 

280 ), "Invalid number of Reading" 

281 

282 assert ( 

283 node := db.Node.find_one() and node.state == NodeState.READY 

284 ), "Invalid Node state" 

285 

286 reading = await db.Reading.find_one(db.Reading.sessionID == 5) 

287 assert reading 

288 

289 assert ( 

290 reading.dangerLevel == 4 

291 and reading.window1 == 111 

292 and reading.window2 == 222 

293 and reading.window3 == 333 

294 ), "Invalid Reading structure" 

295 

296 # Publish reading with dangerLevel > ALERT_TRESHOLD 

297 @pytest.mark.asyncio 

298 async def test_publish_alert_from_state_ok(self, app_client: TestClient): 

299 org = db.Organization(organizationName="foo") 

300 await org.save() 

301 app = db.Application(applicationName="bar", organization=org.id) 

302 await app.save() 

303 # Done setup 

304 

305 with ( 

306 patch("builtins.open", mock_open(read_data="1234")), 

307 patch("socketio.Client.emit", return_value=None), 

308 ): 

309 response = app_client.post( 

310 self.endpoint, 

311 json={ 

312 "nodeID": 123, 

313 "nodeName": "nodeName", 

314 "applicationID": str(app.id), 

315 "organizationID": str(org.id), 

316 "payloadType": PayloadType.TOTAL_READING, 

317 "data": { 

318 "canID": 1, 

319 "sensorNumber": 2, 

320 "value": 9, 

321 "count": 777, 

322 "sessionID": 6, 

323 "readingID": 9, 

324 }, 

325 }, 

326 headers={"Authorization": "Bearer 1234"}, 

327 ) 

328 

329 assert ( 

330 response.status_code == 200 

331 ), "Invalid response code when publishing valid payload" 

332 

333 assert ( 

334 len(await db.Reading.find_all().to_list()) == 1 

335 ), "Invalid number of Reading" 

336 assert len(await db.Alert.find_all().to_list()) == 1, "Invalid number of Alert" 

337 assert ( 

338 node := await db.Node.find_one() 

339 ) and node.state == NodeState.ALERT_READY, "Invalid Node state" 

340 

341 # Publish reading with dangerLevel > ALERT_TRESHOLD while already in alert 

342 @pytest.mark.asyncio 

343 async def test_publish_alert_from_state_alert_ready(self, app_client: TestClient): 

344 org = db.Organization(organizationName="foo") 

345 await org.save() 

346 app = db.Application(applicationName="bar", organization=org.id) 

347 await app.save() 

348 # Done setup 

349 

350 with ( 

351 patch("builtins.open", mock_open(read_data="1234")), 

352 patch("socketio.Client.emit", return_value=None), 

353 ): 

354 

355 response = app_client.post( 

356 self.endpoint, 

357 json={ 

358 "nodeID": 123, 

359 "nodeName": "nodeName", 

360 "applicationID": str(app.id), 

361 "organizationID": str(org.id), 

362 "payloadType": PayloadType.TOTAL_READING, 

363 "data": { 

364 "canID": 1, 

365 "sensorNumber": 2, 

366 "value": 9, 

367 "count": 777, 

368 "sessionID": 6, 

369 "readingID": 11, 

370 }, 

371 }, 

372 headers={"Authorization": "Bearer 1234"}, 

373 ) 

374 

375 assert ( 

376 response.status_code == 200 

377 ), "Invalid response code when publishing valid payload" 

378 

379 assert ( 

380 len(await db.Reading.find_all().to_list()) == 1 

381 ), "Invalid number of Reading" 

382 assert len(await db.Alert.find_all().to_list()) == 1, "Invalid number of Alert" 

383 assert ( 

384 node := await db.Node.find_one() 

385 ) and node.state == NodeState.ALERT_READY, "Invalid Node state" 

386 

387 # Publish reading with dangerLevel > ALERT_TRESHOLD with an already handled alert 

388 @pytest.mark.asyncio 

389 async def test_publish_alert_with_already_handled_alert( 

390 self, app_client: TestClient 

391 ): 

392 org = db.Organization(organizationName="foo") 

393 await org.save() 

394 app = db.Application(applicationName="bar", organization=org.id) 

395 await app.save() 

396 

397 with ( 

398 patch("builtins.open", mock_open(read_data="1234")), 

399 patch("socketio.Client.emit", return_value=None), 

400 ): 

401 response = app_client.post( 

402 self.endpoint, 

403 json={ 

404 "nodeID": 123, 

405 "nodeName": "nodeName", 

406 "applicationID": str(app.id), 

407 "organizationID": str(org.id), 

408 "payloadType": PayloadType.TOTAL_READING, 

409 "data": { 

410 "canID": 1, 

411 "sensorNumber": 2, 

412 "value": 9, 

413 "count": 777, 

414 "sessionID": 6, 

415 "readingID": 11, 

416 }, 

417 }, 

418 headers={"Authorization": "Bearer 1234"}, 

419 ) 

420 # Done setup 

421 

422 alert = await db.Alert.find_one() 

423 assert alert 

424 alert.isHandled = True 

425 await alert.save() 

426 

427 node = await db.Node.find_one() 

428 assert node 

429 node.state = NodeState.READY 

430 await node.save() 

431 

432 with ( 

433 patch("builtins.open", mock_open(read_data="1234")), 

434 patch("socketio.Client.emit", return_value=None), 

435 ): 

436 response = app_client.post( 

437 self.endpoint, 

438 json={ 

439 "nodeID": 123, 

440 "nodeName": "nodeName", 

441 "applicationID": str(app.id), 

442 "organizationID": str(org.id), 

443 "payloadType": PayloadType.TOTAL_READING, 

444 "data": { 

445 "canID": 1, 

446 "sensorNumber": 2, 

447 "value": 9, 

448 "count": 777, 

449 "sessionID": 6, 

450 "readingID": 12, 

451 }, 

452 }, 

453 headers={"Authorization": "Bearer 1234"}, 

454 ) 

455 

456 assert ( 

457 response.status_code == 200 

458 ), "Invalid response code when publishing valid payload" 

459 

460 assert ( 

461 len(await db.Reading.find_all().to_list()) == 2 

462 ), "Invalid number of Reading" 

463 assert len(await db.Alert.find_all().to_list()) == 2, "Invalid number of Alert" 

464 assert ( 

465 node := await db.Node.find_one() 

466 ) and node.state == NodeState.ALERT_READY, "Invalid Node state" 

467 

468 @pytest.mark.asyncio 

469 async def test_publish_window_reading_wrong_value(self, app_client: TestClient): 

470 org = db.Organization(organizationName="foo") 

471 await org.save() 

472 app = db.Application(applicationName="bar", organization=org.id) 

473 await app.save() 

474 # Done setup 

475 

476 with patch("builtins.open", mock_open(read_data="1234")): 

477 with pytest.raises(ValueError): 

478 response = app_client.post( 

479 self.endpoint, 

480 json={ 

481 "nodeID": 123, 

482 "nodeName": "nodeName", 

483 "applicationID": str(app.id), 

484 "organizationID": str(org.id), 

485 "payloadType": PayloadType.WINDOW_READING, 

486 "data": { 

487 "canID": 1, 

488 "sensorNumber": 2, 

489 "value": 5, 

490 "count": 333, 

491 "sessionID": 5, 

492 "readingID": 1, 

493 }, 

494 }, 

495 headers={"Authorization": "Bearer 1234"}, 

496 ) 

497 assert ( 

498 response.status_code == 500 

499 ), "Invalid response code when publishing window with wrong value"