Skip to content

Commit 9348856

Browse files
committed
[chores] Various improvements to be discussed
1 parent 26bb98e commit 9348856

1 file changed

Lines changed: 86 additions & 67 deletions

File tree

openwisp_network_topology/tests/test_realtime.py

Lines changed: 86 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import json
2-
from copy import copy
32
from time import sleep
43

54
import pytest
@@ -40,6 +39,7 @@ class TestRealTime(
4039
link_model = Link
4140
topology_model = Topology
4241
application = import_string(getattr(settings, "ASGI_APPLICATION"))
42+
browser = "chrome"
4343

4444
def setUp(self):
4545
org = self._create_org()
@@ -68,11 +68,47 @@ def setUp(self):
6868
topology=self.topology,
6969
status="up",
7070
)
71+
self.org = org
72+
73+
async def _prepare(self, admin=True):
74+
communicator = await self._get_communicator(self.admin_client, self.topology.pk)
75+
connected, _ = await communicator.connect()
76+
assert connected is True
77+
if admin:
78+
path = reverse(f"{self.prefix}_topology_change", args=[self.topology.pk])
79+
else:
80+
path = reverse("topology_detail", kwargs={"pk": self.topology.pk})
81+
self.login()
82+
if admin:
83+
self.open(path)
84+
self.find_element(By.CSS_SELECTOR, "input.visualizelink").click()
85+
else:
86+
# non admin visualizer doesn't need clicking to show the graph
87+
self.open(path, html_container=".djnjg-overlay")
88+
return communicator
7189

7290
def _snooze(self):
7391
"""Allows a bit of time for the UI to update, reduces flakyness"""
7492
sleep(0.25)
7593

94+
def _create_node3(self):
95+
self.node3 = self._create_node(
96+
label="node3",
97+
addresses=["192.168.0.3"],
98+
topology=self.topology,
99+
organization=self.org,
100+
)
101+
102+
def _assert_no_js_errors(self):
103+
browser_logs = []
104+
for log in self.get_browser_logs():
105+
# ignore random 403 errors
106+
if log["level"] == "SEVERE" and "403" in log["message"]:
107+
continue
108+
else:
109+
browser_logs.append(log)
110+
self.assertEqual(browser_logs, [])
111+
76112
async def _get_communicator(self, admin_client, topology_id):
77113
session_id = admin_client.cookies["sessionid"].value
78114
communicator = WebsocketCommunicator(
@@ -91,13 +127,7 @@ async def test_real_time_link_status_update(self):
91127
# preparation
92128
self.link.status = "down"
93129
await database_sync_to_async(self.link.save)()
94-
communicator = await self._get_communicator(self.admin_client, self.topology.pk)
95-
connected, _ = await communicator.connect()
96-
assert connected is True
97-
path = reverse(f"{self.prefix}_topology_change", args=[self.topology.pk])
98-
self.login()
99-
self.open(path)
100-
self.find_element(By.CSS_SELECTOR, "input.visualizelink").click()
130+
communicator = await self._prepare()
101131
# changing the status of a link will change it in the browser graph too
102132
self.link.status = "up"
103133
await database_sync_to_async(self.link.save)()
@@ -127,33 +157,28 @@ async def test_real_time_link_status_update(self):
127157
]["status"],
128158
"down",
129159
)
160+
self._assert_no_js_errors()
130161
await communicator.disconnect()
131162

132163
async def test_node_status_update(self):
133164
# preparation
134-
communicator = await self._get_communicator(self.admin_client, self.topology.pk)
135-
connected, _ = await communicator.connect()
136-
assert connected is True
137-
path = reverse(f"{self.prefix}_topology_change", args=[self.topology.pk])
138-
self.login()
139-
self.open(path)
140-
self.find_element(By.CSS_SELECTOR, "input.visualizelink").click()
165+
communicator = await self._prepare()
141166
# saving a new node will add it to the UI
142-
new_node = copy(self.node1)
143-
new_node.pk = None
144-
await database_sync_to_async(new_node.save)()
167+
await database_sync_to_async(self._create_node3)()
145168
message = await communicator.receive_json_from()
146169
self.assertEqual(len(json.loads(message["topology"])["nodes"]), 3)
147170
self._snooze()
171+
self._assert_no_js_errors()
148172
self.assertEqual(
149173
len(self.web_driver.execute_script("return graph.data;")["nodes"]),
150174
3,
151175
)
152176
# deleting the node from the DB will remove it from the UI
153-
await database_sync_to_async(new_node.delete)()
177+
await database_sync_to_async(self.node3.delete)()
154178
message = await communicator.receive_json_from()
155179
self.assertEqual(len(json.loads(message["topology"])["nodes"]), 2)
156180
self._snooze()
181+
self._assert_no_js_errors()
157182
self.assertEqual(
158183
len(self.web_driver.execute_script("return graph.data;")["nodes"]),
159184
2,
@@ -162,29 +187,23 @@ async def test_node_status_update(self):
162187

163188
async def test_node_link_update(self):
164189
# preparation
165-
communicator = await self._get_communicator(self.admin_client, self.topology.pk)
166-
connected, _ = await communicator.connect()
167-
assert connected is True
168-
path = reverse(f"{self.prefix}_topology_change", args=[self.topology.pk])
169-
self.login()
170-
self.open(path)
171-
self.find_element(By.CSS_SELECTOR, "input.visualizelink").click()
190+
communicator = await self._prepare()
172191
# deleting the link from the DB will remove it from the UI
173192
await database_sync_to_async(self.link.delete)()
174193
message = await communicator.receive_json_from()
175194
self.assertEqual(len(json.loads(message["topology"])["links"]), 0)
176195
self._snooze()
196+
self._assert_no_js_errors()
177197
self.assertEqual(
178198
len(self.web_driver.execute_script("return graph.data;")["links"]),
179199
0,
180200
)
181201
# adding a link will add it to the UI
182-
new_link = copy(self.link)
183-
new_link.pk = None
184-
await database_sync_to_async(new_link.save)()
202+
await database_sync_to_async(self.link.save)()
185203
message = await communicator.receive_json_from()
186204
self.assertEqual(len(json.loads(message["topology"])["links"]), 1)
187205
self._snooze()
206+
self._assert_no_js_errors()
188207
self.assertEqual(
189208
len(self.web_driver.execute_script("return graph.data;")["links"]),
190209
1,
@@ -193,44 +212,44 @@ async def test_node_link_update(self):
193212

194213
async def test_non_admin_visualizer(self):
195214
# preparation
196-
communicator = await self._get_communicator(self.admin_client, self.topology.pk)
197-
connected, _ = await communicator.connect()
198-
assert connected is True
199-
path = reverse("topology_detail", kwargs={"pk": self.topology.pk})
200-
self.login()
201-
self.open(path, html_container=".djnjg-overlay")
215+
communicator = await self._prepare(admin=False)
202216
# changing the status of a link will change it in the browser graph too
203-
self.link.status = "down"
204-
await database_sync_to_async(self.link.save)()
205-
message = await communicator.receive_json_from()
206-
assert (
207-
json.loads(message["topology"])["links"][0]["properties"]["status"]
208-
== "down"
209-
)
210-
self._snooze()
211-
self.assertEqual(
212-
self.web_driver.execute_script("return graph.data;")["links"][0][
213-
"properties"
214-
]["status"],
215-
"down",
216-
)
217+
with self.subTest("change link status"):
218+
self.link.status = "down"
219+
await database_sync_to_async(self.link.save)()
220+
message = await communicator.receive_json_from()
221+
assert (
222+
json.loads(message["topology"])["links"][0]["properties"]["status"]
223+
== "down"
224+
)
225+
self._snooze()
226+
self._assert_no_js_errors()
227+
self.assertEqual(
228+
self.web_driver.execute_script("return graph.data;")["links"][0][
229+
"properties"
230+
]["status"],
231+
"down",
232+
)
217233
# removing a link from the DB will remove it from the UI
218-
await database_sync_to_async(self.link.delete)()
219-
message = await communicator.receive_json_from()
220-
self.assertEqual(len(json.loads(message["topology"])["links"]), 0)
221-
self._snooze()
222-
self.assertEqual(
223-
len(self.web_driver.execute_script("return graph.data;")["links"]),
224-
0,
225-
)
234+
with self.subTest("remove link"):
235+
await database_sync_to_async(self.link.delete)()
236+
message = await communicator.receive_json_from()
237+
self.assertEqual(len(json.loads(message["topology"])["links"]), 0)
238+
self._snooze()
239+
self._assert_no_js_errors()
240+
self.assertEqual(
241+
len(self.web_driver.execute_script("return graph.data;")["links"]),
242+
0,
243+
)
226244
# creating a new node will add it to the UI
227-
new_node = copy(self.node1)
228-
new_node.pk = None
229-
await database_sync_to_async(new_node.save)()
230-
message = await communicator.receive_json_from()
231-
self.assertEqual(len(json.loads(message["topology"])["nodes"]), 3)
232-
self._snooze()
233-
self.assertEqual(
234-
len(self.web_driver.execute_script("return graph.data;")["nodes"]),
235-
3,
236-
)
245+
with self.subTest("add node"):
246+
await database_sync_to_async(self._create_node3)()
247+
message = await communicator.receive_json_from()
248+
self.assertEqual(len(json.loads(message["topology"])["nodes"]), 3)
249+
self._assert_no_js_errors()
250+
self._snooze()
251+
self.assertEqual(
252+
len(self.web_driver.execute_script("return graph.data;")["nodes"]),
253+
3,
254+
)
255+
await communicator.disconnect()

0 commit comments

Comments
 (0)