Issues (14)

tests/unit/test_main.py (13 issues)

1
"""Tests for the main madule."""
2 1
import asyncio
3 1
from unittest.mock import patch, call, MagicMock
4 1
from datetime import datetime, timedelta
5
6 1
import pytz
7 1
import pytest
8
9 1
from kytos.lib.helpers import get_controller_mock, get_test_client
10 1
from napps.kytos.maintenance.main import Main
11 1
from napps.kytos.maintenance.models import MaintenanceWindow as MW
12 1
from napps.kytos.maintenance.models import MaintenanceWindows
13
14 1
TIME_FMT = "%Y-%m-%dT%H:%M:%S%z"
15
16
17 1
class TestMain:
18
    """Test the Main class of this NApp."""
19
20
    # pylint: disable=too-many-public-methods
21
22 1
    def setup_method(self):
23
        """Initialize before tests are executed."""
24 1
        self.controller = get_controller_mock()
25 1
        self.controller.switches = MagicMock()
26 1
        self.scheduler = MagicMock()
27 1
        new_sched = (
28
            "napps.kytos.maintenance.managers.MaintenanceScheduler.new_scheduler"
29
        )
30 1
        with patch(new_sched) as new_scheduler:
31 1
            new_scheduler.return_value = self.scheduler
32 1
            self.napp = Main(self.controller)
33 1
        self.api = get_test_client(self.controller, self.napp)
34 1
        self.maxDiff = None
35 1
        self.base_endpoint = "kytos/maintenance/v1"
36
37 1
    async def test_create_mw_case_1(self):
38
        """Test a successful case of the REST to create."""
39 1
        self.napp.controller.loop = asyncio.get_running_loop()
40 1
        url = f"{self.base_endpoint}"
41 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
42 1
        end = start + timedelta(hours=2)
43 1
        self.controller.switches = MagicMock()
44 1
        self.controller.get_interface_by_id = MagicMock()
45 1
        self.controller.links = MagicMock()
46 1
        switches = {"00:00:00:00:00:00:00:02": 1, "00:00:00:00:00:00:00:03": 2}
47 1
        interfaces = {"00:00:00:00:00:00:00:03:3": 1, "00:00:00:00:00:00:00:02:1": 2}
48 1
        links = {
49
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260": 1,
50
            "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30": 2,
51
        }
52 1
        self.controller.switches.get.side_effect = switches.get
53 1
        get_interface_side_effect = lambda interface_id: interfaces.get(interface_id)
54 1
        self.controller.get_interface_by_id.side_effect = get_interface_side_effect
55 1
        self.controller.links.get.side_effect = links.get
56 1
        payload = {
57
            "start": start.strftime(TIME_FMT),
58
            "end": end.strftime(TIME_FMT),
59
            "switches": ["00:00:00:00:00:00:00:02", "00:00:00:00:00:00:00:03"],
60
            "interfaces": ["00:00:00:00:00:00:00:03:3", "00:00:00:00:00:00:00:02:1"],
61
            "links": [
62
                "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
63
                "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30",
64
            ],
65
        }
66 1
        response = await self.api.post(url, json=payload)
67 1
        current_data = response.json()
68 1
        assert response.status_code == 201, current_data
69 1
        switch_calls = [
70
            call("00:00:00:00:00:00:00:02"),
71
            call("00:00:00:00:00:00:00:03"),
72
        ]
73 1
        self.controller.switches.get.assert_has_calls(switch_calls)
74 1
        interface_calls = [
75
            call("00:00:00:00:00:00:00:03:3"),
76
            call("00:00:00:00:00:00:00:02:1"),
77
        ]
78 1
        self.controller.get_interface_by_id.assert_has_calls(interface_calls)
79 1
        link_calls = [
80
            call("cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"),
81
            call("4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30"),
82
        ]
83 1
        self.controller.links.get.assert_has_calls(
84
            link_calls
85
        )
86 1
        args, kwargs = self.scheduler.add.call_args
87 1
        window: MW = args[0]
88
89 1
        assert window.start == start.replace(microsecond=0)
90 1
        assert window.end == end.replace(microsecond=0)
91 1
        assert window.switches == ["00:00:00:00:00:00:00:02", "00:00:00:00:00:00:00:03"]
92 1
        assert window.interfaces == [
93
            "00:00:00:00:00:00:00:03:3",
94
            "00:00:00:00:00:00:00:02:1",
95
        ]
96 1
        assert window.links == [
97
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
98
            "4d42dc0852278accac7d9df15418f6d921db160b13d674029a87cef1b5f67f30",
99
        ]
100
101 1
        assert current_data == {"mw_id": window.id}
102
103 1 View Code Duplication
    async def test_create_mw_case_2(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
104
        """Test a successful case of the REST to create."""
105 1
        self.napp.controller.loop = asyncio.get_running_loop()
106 1
        url = f"{self.base_endpoint}"
107 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
108 1
        end = start + timedelta(hours=2)
109 1
        self.controller.switches = MagicMock()
110 1
        switches = {"00:00:00:00:00:00:00:01": 1}
111 1
        self.controller.switches.get.side_effect = switches.get
112 1
        payload = {
113
            "start": start.strftime(TIME_FMT),
114
            "end": end.strftime(TIME_FMT),
115
            "switches": [
116
                "00:00:00:00:00:00:00:01",
117
            ],
118
        }
119 1
        response = await self.api.post(url, json=payload)
120 1
        current_data = response.json()
121 1
        assert response.status_code == 201, current_data
122 1
        self.controller.switches.get.assert_called_with("00:00:00:00:00:00:00:01")
123 1
        args, kwargs = self.scheduler.add.call_args
124 1
        window: MW = args[0]
125
126 1
        assert window.start == start.replace(microsecond=0)
127 1
        assert window.end == end.replace(microsecond=0)
128 1
        assert window.switches == ["00:00:00:00:00:00:00:01"]
129 1
        assert window.interfaces == []
130 1
        assert window.links == []
131
132 1
        assert current_data == {"mw_id": window.id}
133
134 1
    async def test_create_mw_case_3(self):
135
        """Test a successful case of the REST to create."""
136 1
        self.napp.controller.loop = asyncio.get_running_loop()
137 1
        url = f"{self.base_endpoint}"
138 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
139 1
        end = start + timedelta(hours=2)
140 1
        self.controller.get_interface_by_id = MagicMock()
141 1
        interfaces = {"00:00:00:00:00:00:00:01:1": 1}
142 1
        get_interface_side_effect = lambda interface_id: interfaces.get(interface_id)
143 1
        self.controller.get_interface_by_id.side_effect = get_interface_side_effect
144 1
        payload = {
145
            "id": "some_mw",
146
            "description": "some_mw",
147
            "start": start.strftime(TIME_FMT),
148
            "end": end.strftime(TIME_FMT),
149
            "interfaces": [
150
                "00:00:00:00:00:00:00:01:1",
151
            ],
152
        }
153 1
        response = await self.api.post(url, json=payload)
154 1
        current_data = response.json()
155 1
        assert response.status_code == 201, current_data
156 1
        self.controller.get_interface_by_id.assert_called_with(
157
            "00:00:00:00:00:00:00:01:1"
158
        )
159 1
        assert response.status_code == 201, current_data
160 1
        args, kwargs = self.scheduler.add.call_args
161 1
        response = await self.api.get(f"{url}/some_mw")
162 1
        window: MW = args[0]
163
164 1
        assert window.start == start.replace(microsecond=0)
165 1
        assert window.end == end.replace(microsecond=0)
166 1
        assert window.switches == []
167 1
        assert window.interfaces == ["00:00:00:00:00:00:00:01:1"]
168 1
        assert window.links == []
169
170 1
        assert current_data == {"mw_id": "some_mw"}
171
172 1 View Code Duplication
    async def test_create_mw_case_4(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
173
        """Test a successful case of the REST to create."""
174 1
        self.napp.controller.loop = asyncio.get_running_loop()
175 1
        url = f"{self.base_endpoint}"
176 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
177 1
        end = start + timedelta(hours=2)
178 1
        self.controller.links = MagicMock()
179 1
        links = {"cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260": 1}
180 1
        self.controller.links.get.side_effect = links.get
181 1
        payload = {
182
            "start": start.strftime(TIME_FMT),
183
            "end": end.strftime(TIME_FMT),
184
            "links": [
185
                "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260",
186
            ],
187
        }
188 1
        response = await self.api.post(url, json=payload)
189 1
        current_data = response.json()
190 1
        assert response.status_code == 201, current_data
191 1
        self.controller.links.get.assert_called_with(
192
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"
193
        )
194 1
        assert response.status_code == 201, current_data
195 1
        args, kwargs = self.scheduler.add.call_args
196 1
        window: MW = args[0]
197
198 1
        assert window.start == start.replace(microsecond=0)
199 1
        assert window.end == end.replace(microsecond=0)
200 1
        assert window.switches == []
201 1
        assert window.interfaces == []
202 1
        assert window.links == [
203
            "cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260"
204
        ]
205
206 1
        assert current_data == {"mw_id": window.id}
207
208 1
    async def test_create_mw_case_5(self):
209
        """Test a fail case of the REST to create a maintenance window."""
210 1
        self.napp.controller.loop = asyncio.get_running_loop()
211 1
        url = f"{self.base_endpoint}"
212 1
        payload = {
213
            "switches": [
214
                "00:00:00:00:00:00:02",
215
            ],
216
            "interfaces": [
217
                "00:00:00:00:00:00:00:03:3",
218
            ],
219
        }
220 1
        response = await self.api.post(url, json=payload)
221
        assert response.status_code == 400
222
        self.scheduler.add.assert_not_called()
223
224 1 View Code Duplication
    async def test_create_mw_case_6(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
225
        """Test a fail case of the REST to create a maintenance window."""
226 1
        self.napp.controller.loop = asyncio.get_running_loop()
227 1
        url = f"{self.base_endpoint}"
228 1
        start = datetime.now(pytz.utc) - timedelta(days=1)
229 1
        end = start + timedelta(hours=2)
230 1
        payload = {
231
            "start": start.strftime(TIME_FMT),
232
            "end": end.strftime(TIME_FMT),
233
            "switches": [
234
                "00:00:00:00:00:00:02",
235
            ],
236
            "interfaces": [
237
                "00:00:00:00:00:00:00:03:3",
238
            ],
239
        }
240 1
        response = await self.api.post(url, json=payload)
241
        current_data = response.json()
242
        assert response.status_code == 400
243
        assert current_data["description"] == "start: Value error, Start in the past not allowed"
244
        self.scheduler.add.assert_not_called()
245
246 1 View Code Duplication
    async def test_create_mw_case_7(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
247
        """Test a fail case of the REST to create a maintenance window."""
248 1
        self.napp.controller.loop = asyncio.get_running_loop()
249 1
        url = f"{self.base_endpoint}"
250 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
251 1
        end = start - timedelta(hours=2)
252 1
        payload = {
253
            "start": start.strftime(TIME_FMT),
254
            "end": end.strftime(TIME_FMT),
255
            "switches": [
256
                "00:00:00:00:00:00:02",
257
            ],
258
            "interfaces": [
259
                "00:00:00:00:00:00:00:03:3",
260
            ],
261
        }
262 1
        response = await self.api.post(url, json=payload)
263
        current_data = response.json()
264
265
        assert response.status_code == 400
266
        assert current_data["description"] == "end: Value error, End before start not allowed"
267
        self.scheduler.add.assert_not_called()
268
269 1 View Code Duplication
    @pytest.mark.skip(reason="Future feature")
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
270 1
    async def test_create_mw_case_8(self):
271
        """Test a fail case of the REST to create a maintenance window."""
272
        self.napp.controller.loop = asyncio.get_running_loop()
273
        url = f"{self.base_endpoint}"
274
        start = datetime.now(pytz.utc) + timedelta(days=1)
275
        end = start + timedelta(hours=2)
276
        payload = {
277
            "id": "1234",
278
            "start": start.strftime(TIME_FMT),
279
            "end": end.strftime(TIME_FMT),
280
            "switches": [
281
                "00:00:00:00:00:00:02",
282
            ],
283
            "interfaces": [
284
                "00:00:00:00:00:00:00:03:3",
285
            ],
286
        }
287
        response = await self.api.post(url, json=payload)
288
        current_data = response.json()
289
290
        assert response.status_code == 400
291
        assert current_data["description"] == "Setting a maintenance id is not allowed"
292
        self.scheduler.add.assert_not_called()
293
294 1 View Code Duplication
    async def test_create_mw_case_9(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
295
        """Test a fail case of the REST to create a maintenance window."""
296 1
        self.napp.controller.loop = asyncio.get_running_loop()
297 1
        url = f"{self.base_endpoint}"
298 1
        start = datetime.now(pytz.utc) + timedelta(days=1)
299 1
        end = start + timedelta(hours=2)
300 1
        payload = {
301
            "status": "fun",
302
            "start": start.strftime(TIME_FMT),
303
            "end": end.strftime(TIME_FMT),
304
            "switches": [
305
                "00:00:00:00:00:00:02",
306
            ],
307
            "interfaces": [
308
                "00:00:00:00:00:00:00:03:3",
309
            ],
310
        }
311 1
        response = await self.api.post(url, json=payload)
312
        current_data = response.json()
313
314
        assert response.status_code == 400
315
        assert (
316
            current_data["description"] == "Setting a maintenance status is not allowed"
317
        )
318
        self.scheduler.add.assert_not_called()
319
320 1
    async def test_get_mw_case_1(self):
321
        """Test get all maintenance windows, empty list."""
322 1
        self.scheduler.list_maintenances.return_value = MaintenanceWindows.model_construct(
323
            root=[]
324
        )
325 1
        url = f"{self.base_endpoint}"
326 1
        response = await self.api.get(url)
327 1
        current_data = response.json()
328 1
        assert response.status_code == 200
329 1
        assert current_data == []
330 1
        self.scheduler.list_maintenances.assert_called_once()
331
332 1
    async def test_get_mw_case_2(self):
333
        """Test get all maintenance windows."""
334 1
        now = datetime.now(pytz.utc)
335 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
336 1
        end1 = start1 + timedelta(hours=6)
337 1
        start2 = datetime.now(pytz.utc) + timedelta(hours=5)
338 1
        end2 = start2 + timedelta(hours=1, minutes=30)
339 1
        self.scheduler.list_maintenances.return_value = MaintenanceWindows.model_construct(
340
            root=[
341
                MW.model_construct(
342
                    id="1234",
343
                    start=start1.replace(microsecond=0),
344
                    end=end1.replace(microsecond=0),
345
                    switches=["00:00:00:00:00:00:12:23"],
346
                    description="",
347
                    links=[],
348
                    interfaces=[],
349
                    status="pending",
350
                    updated_at=now.replace(microsecond=0),
351
                    inserted_at=now.replace(microsecond=0),
352
                ),
353
                MW.model_construct(
354
                    id="4567",
355
                    start=start2.replace(microsecond=0),
356
                    end=end2.replace(microsecond=0),
357
                    switches=["12:34:56:78:90:ab:cd:ef"],
358
                    description="",
359
                    links=[],
360
                    interfaces=[],
361
                    status="pending",
362
                    updated_at=now.replace(microsecond=0),
363
                    inserted_at=now.replace(microsecond=0),
364
                ),
365
            ]
366
        )
367 1
        mw_dict = [
368
            {
369
                "id": "1234",
370
                "start": start1.strftime(TIME_FMT),
371
                "end": end1.strftime(TIME_FMT),
372
                "switches": ["00:00:00:00:00:00:12:23"],
373
                "description": "",
374
                "links": [],
375
                "interfaces": [],
376
                "status": "pending",
377
                "updated_at": now.strftime(TIME_FMT),
378
                "inserted_at": now.strftime(TIME_FMT),
379
            },
380
            {
381
                "id": "4567",
382
                "start": start2.strftime(TIME_FMT),
383
                "end": end2.strftime(TIME_FMT),
384
                "switches": ["12:34:56:78:90:ab:cd:ef"],
385
                "description": "",
386
                "links": [],
387
                "interfaces": [],
388
                "status": "pending",
389
                "updated_at": now.strftime(TIME_FMT),
390
                "inserted_at": now.strftime(TIME_FMT),
391
            },
392
        ]
393
394 1
        url = f"{self.base_endpoint}"
395 1
        response = await self.api.get(url)
396 1
        current_data = response.json()
397 1
        assert response.status_code == 200
398 1
        assert current_data == mw_dict
399 1
        self.scheduler.list_maintenances.assert_called_once()
400
401 1
    async def test_get_mw_case_3(self):
402
        """Test get non-existent id."""
403 1
        self.scheduler.get_maintenance.return_value = None
404 1
        url = f"{self.base_endpoint}/2345"
405 1
        response = await self.api.get(url)
406
        current_data = response.json()
407
        assert response.status_code == 404
408
        assert current_data["description"] == "Maintenance with id 2345 not found"
409
        self.scheduler.get_maintenance.assert_called_once_with("2345")
410
411 1
    async def test_get_mw_case_4(self):
412
        """Test get existent id."""
413 1
        now = datetime.now(pytz.utc)
414 1
        start2 = datetime.now(pytz.utc) + timedelta(hours=5)
415 1
        end2 = start2 + timedelta(hours=1, minutes=30)
416 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
417
            id="4567",
418
            start=start2.replace(microsecond=0),
419
            end=end2.replace(microsecond=0),
420
            switches=["12:34:56:78:90:ab:cd:ef"],
421
            updated_at=now.replace(microsecond=0),
422
            inserted_at=now.replace(microsecond=0),
423
        )
424 1
        mw_dict = {
425
            "id": "4567",
426
            "start": start2.strftime(TIME_FMT),
427
            "end": end2.strftime(TIME_FMT),
428
            "switches": ["12:34:56:78:90:ab:cd:ef"],
429
            "description": "",
430
            "links": [],
431
            "interfaces": [],
432
            "status": "pending",
433
            "updated_at": now.strftime(TIME_FMT),
434
            "inserted_at": now.strftime(TIME_FMT),
435
        }
436 1
        url = f"{self.base_endpoint}/4567"
437 1
        response = await self.api.get(url)
438 1
        current_data = response.json()
439 1
        assert response.status_code == 200
440 1
        assert current_data == mw_dict
441 1
        self.scheduler.get_maintenance.assert_called_once_with("4567")
442
443 1
    async def test_remove_mw_case_1(self):
444
        """Test remove non-existent id."""
445 1
        self.scheduler.get_maintenance.return_value = None
446 1
        url = f"{self.base_endpoint}/2345"
447 1
        response = await self.api.delete(url)
448
        current_data = response.json()
449
        assert response.status_code == 404
450
        assert current_data["description"] == "Maintenance with id 2345 not found"
451
        self.scheduler.get_maintenance.assert_called_once_with("2345")
452
        self.scheduler.remove.assert_not_called()
453
454 1 View Code Duplication
    async def test_remove_mw_case_2(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
455
        """Test remove existent id."""
456 1
        start1 = datetime.now(pytz.utc) + timedelta(hours=1)
457 1
        end1 = start1 + timedelta(hours=6)
458 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
459
            id="1234",
460
            start=start1.replace(microsecond=0),
461
            end=end1.replace(microsecond=0),
462
            switches=["00:00:00:00:00:00:12:23"],
463
        )
464 1
        url = f"{self.base_endpoint}/1234"
465 1
        response = await self.api.delete(url)
466 1
        current_data = response.json()
467 1
        assert response.status_code == 200
468 1
        assert current_data == {
469
            "response": "Maintenance with id 1234 " "successfully removed"
470
        }
471 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
472 1
        self.scheduler.remove.assert_called_once_with("1234")
473
474 1 View Code Duplication
    async def test_remove_mw_case_3(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
475
        """Test remove existent id."""
476 1
        start1 = datetime.now(pytz.utc) - timedelta(days=1)
477 1
        end1 = start1 + timedelta(hours=6)
478 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
479
            id="1234",
480
            start=start1.replace(microsecond=0),
481
            end=end1.replace(microsecond=0),
482
            switches=["00:00:00:00:00:00:12:23"],
483
            status="running",
484
        )
485 1
        url = f"{self.base_endpoint}/1234"
486 1
        response = await self.api.delete(url)
487
        current_data = response.json()
488
        assert response.status_code == 400
489
        assert (
490
            current_data["description"]
491
            == "Deleting a running maintenance is not allowed"
492
        )
493
        self.scheduler.get_maintenance.assert_called_once_with("1234")
494
        self.scheduler.remove.assert_not_called()
495
496 1
    async def test_update_mw_case_1(self):
497
        """Test update non-existent id."""
498 1
        self.napp.controller.loop = asyncio.get_running_loop()
499 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
500 1
        self.scheduler.get_maintenance.return_value = None
501 1
        payload = {
502
            "start": start1.strftime(TIME_FMT),
503
        }
504 1
        url = f"{self.base_endpoint}/2345"
505 1
        response = await self.api.patch(url, json=payload)
506
        current_data = response.json()
507
        assert response.status_code == 404
508
        assert current_data["description"] == "Maintenance with id 2345 not found"
509
        self.scheduler.update.assert_not_called()
510
511 1
    async def test_update_mw_case_2(self):
512
        """Test update no data."""
513 1
        self.napp.controller.loop = asyncio.get_running_loop()
514 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
515 1
        payload = {
516
            "start": start1.strftime(TIME_FMT),
517
        }
518 1
        url = f"{self.base_endpoint}/1234"
519 1
        response = await self.api.patch(url, json=payload)
520
        current_data = response.json()
521
        assert response.status_code == 400
522
        assert "Field required" in current_data["description"]
523
524 1
    async def test_update_mw_case_3(self):
525
        """Test successful update."""
526 1
        self.napp.controller.loop = asyncio.get_running_loop()
527 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
528 1
        end1 = start1 + timedelta(hours=6)
529 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
530
            id="1234",
531
            start=start1.replace(microsecond=0),
532
            end=end1.replace(microsecond=0),
533
            switches=["00:00:00:00:00:00:12:23"],
534
        )
535 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
536 1
        payload = {
537
            "start": start_new.strftime(TIME_FMT),
538
        }
539 1
        url = f"{self.base_endpoint}/1234"
540 1
        response = await self.api.patch(url, json=payload)
541 1
        current_data = response.json()
542 1
        assert current_data == {"response": "Maintenance 1234 updated"}
543 1
        assert response.status_code == 200
544 1
        self.scheduler.get_maintenance.assert_called_once_with("1234")
545 1
        self.scheduler.update.assert_called_once_with(
546
            MW.model_construct(
547
                id="1234",
548
                start=start_new.replace(microsecond=0),
549
                end=end1.replace(microsecond=0),
550
                switches=["00:00:00:00:00:00:12:23"],
551
            )
552
        )
553
554 1 View Code Duplication
    async def test_update_mw_case_4(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
555
        """Test successful update."""
556 1
        self.napp.controller.loop = asyncio.get_running_loop()
557 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
558 1
        end1 = start1 + timedelta(hours=6)
559 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
560
            id="1234",
561
            start=start1.replace(microsecond=0),
562
            end=end1.replace(microsecond=0),
563
            switches=["00:00:00:00:00:00:12:23"],
564
        )
565 1
        start_new = datetime.now(pytz.utc) - timedelta(days=1, hours=3)
566 1
        payload = {
567
            "start": start_new.strftime(TIME_FMT),
568
        }
569 1
        url = f"{self.base_endpoint}/1234"
570 1
        response = await self.api.patch(url, json=payload)
571
        current_data = response.json()
572
        assert response.status_code == 400
573
        assert current_data["description"] == "start: Value error, Start in the past not allowed"
574
        self.scheduler.get_maintenance.assert_called_once_with("1234")
575
        self.scheduler.update.assert_not_called()
576
577 1 View Code Duplication
    async def test_update_mw_case_5(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
578
        """Test successful update."""
579 1
        self.napp.controller.loop = asyncio.get_running_loop()
580 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
581 1
        end1 = start1 + timedelta(hours=6)
582 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
583
            id="1234",
584
            start=start1.replace(microsecond=0),
585
            end=end1.replace(microsecond=0),
586
            switches=["00:00:00:00:00:00:12:23"],
587
        )
588 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
589 1
        end_new = start_new - timedelta(hours=5)
590 1
        payload = {
591
            "start": start_new.strftime(TIME_FMT),
592
            "end": end_new.strftime(TIME_FMT),
593
        }
594 1
        url = f"{self.base_endpoint}/1234"
595 1
        response = await self.api.patch(url, json=payload)
596
        current_data = response.json()
597
        assert response.status_code == 400
598
        assert current_data["description"] == "end: Value error, End before start not allowed"
599
        self.scheduler.get_maintenance.assert_called_once_with("1234")
600
        self.scheduler.update.assert_not_called()
601
602 1
    async def test_update_mw_case_6(self):
603
        """Test successful update."""
604 1
        self.napp.controller.loop = asyncio.get_running_loop()
605 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
606 1
        end1 = start1 + timedelta(hours=6)
607 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
608
            id="1234",
609
            start=start1.replace(microsecond=0),
610
            end=end1.replace(microsecond=0),
611
            switches=["00:00:00:00:00:00:12:23"],
612
        )
613 1
        start_new = datetime.now(pytz.utc) + timedelta(days=1, hours=3)
614 1
        payload = {
615
            "start": start_new.strftime(TIME_FMT),
616
            "switches": [],
617
            "interfaces": [],
618
            "links": [],
619
        }
620
621 1
        url = f"{self.base_endpoint}/1234"
622 1
        response = await self.api.patch(url, json=payload)
623
        current_data = response.json()
624
        assert response.status_code == 400
625
        assert (
626
            current_data["description"]
627
            == ": Value error, At least one item must be provided"
628
        )
629
        self.scheduler.get_maintenance.assert_called_once_with("1234")
630
        self.scheduler.update.assert_not_called()
631
632 1
    async def test_update_mw_case_7(self):
633
        """Test successful update."""
634 1
        self.napp.controller.loop = asyncio.get_running_loop()
635 1
        start1 = datetime.now(pytz.utc) + timedelta(days=1)
636 1
        end1 = start1 + timedelta(hours=6)
637 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
638
            id="1234",
639
            start=start1.replace(microsecond=0),
640
            end=end1.replace(microsecond=0),
641
            switches=["00:00:00:00:00:00:12:23"],
642
        )
643 1
        payload = {
644
            "status": "running",
645
        }
646 1
        url = f"{self.base_endpoint}/1234"
647 1
        response = await self.api.patch(url, json=payload)
648
        current_data = response.json()
649
        assert response.status_code == 400
650
        assert (
651
            current_data["description"]
652
            == "Updating a maintenance status is not allowed"
653
        )
654
        self.scheduler.update.assert_not_called()
655
656 1
    async def test_end_mw_case_1(self):
657
        """Test method that finishes the maintenance now."""
658 1
        self.scheduler.get_maintenance.return_value = None
659 1
        url = f"{self.base_endpoint}/2345/end"
660 1
        response = await self.api.patch(url)
661
        current_data = response.json()
662
        assert response.status_code == 404
663
        assert current_data["description"] == "Maintenance with id 2345 not found"
664
665 1 View Code Duplication
    async def test_end_mw_case_2(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
666
        """Test method that finishes the maintenance now."""
667 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=1)
668 1
        end1 = start1 + timedelta(hours=6)
669 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
670
            id="1234",
671
            start=start1.replace(microsecond=0),
672
            end=end1.replace(microsecond=0),
673
            switches=["00:00:00:00:00:00:12:23"],
674
            status="running",
675
        )
676 1
        url = f"{self.base_endpoint}/1234/end"
677 1
        response = await self.api.patch(url)
678 1
        current_data = response.json()
679 1
        self.scheduler.get.asssert_called_once_with("1234")
680 1
        self.scheduler.end_maintenance_early.assert_called_once_with("1234")
681 1
        assert response.status_code == 200
682 1
        assert current_data == {"response": "Maintenance window 1234 finished"}
683
684 1
    async def test_end_mw_case_3(self):
685
        """Test method that finishes the maintenance now."""
686 1
        start1 = datetime.now(pytz.utc) + timedelta(hours=1)
687 1
        end1 = start1 + timedelta(hours=6)
688 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
689
            id="1234",
690
            start=start1.replace(microsecond=0),
691
            end=end1.replace(microsecond=0),
692
            switches=["00:00:00:00:00:00:12:23"],
693
            status="pending",
694
        )
695 1
        url = f"{self.base_endpoint}/1234/end"
696 1
        response = await self.api.patch(url)
697
        current_data = response.json()
698
        self.scheduler.get.asssert_called_once_with("1234")
699
        self.scheduler.end_maintenance_early.assert_not_called()
700
        assert response.status_code == 400
701
        assert (
702
            current_data["description"] == "Maintenance window 1234 has not yet started"
703
        )
704
705 1
    async def test_end_mw_case_4(self):
706
        """Test method that finishes the maintenance now."""
707 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=5)
708 1
        end1 = start1 + timedelta(hours=4)
709 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
710
            id="1234",
711
            start=start1.replace(microsecond=0),
712
            end=end1.replace(microsecond=0),
713
            switches=["00:00:00:00:00:00:12:23"],
714
            status="finished",
715
        )
716 1
        url = f"{self.base_endpoint}/1234/end"
717 1
        response = await self.api.patch(url)
718
        current_data = response.json()
719
        self.scheduler.get.asssert_called_once_with("1234")
720
        self.scheduler.end_maintenance_early.assert_not_called()
721
        assert response.status_code == 400
722
        assert (
723
            current_data["description"]
724
            == "Maintenance window 1234 has already finished"
725
        )
726
727 1
    async def test_extend_case_1(self):
728
        """Test successful extension."""
729 1
        self.napp.controller.loop = asyncio.get_running_loop()
730 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=3)
731 1
        end1 = start1 + timedelta(hours=4)
732 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
733
            id="1234",
734
            start=start1.replace(microsecond=0),
735
            end=end1.replace(microsecond=0),
736
            switches=["00:00:00:00:00:00:12:23"],
737
            status="running",
738
        )
739 1
        url = f"{self.base_endpoint}/1234/extend"
740 1
        payload = {"minutes": 45}
741 1
        response = await self.api.patch(url, json=payload)
742 1
        assert response.status_code == 200
743 1
        self.scheduler.get_maintenance.called_with("1234")
744 1
        self.scheduler.update.assert_called_with(
745
            MW.model_construct(
746
                id="1234",
747
                start=start1.replace(microsecond=0),
748
                end=end1.replace(microsecond=0) + timedelta(minutes=45),
749
                switches=["00:00:00:00:00:00:12:23"],
750
                status="running",
751
            )
752
        )
753
754 1
    async def test_extend_case_2(self):
755
        """Test no payload error."""
756 1
        self.napp.controller.loop = asyncio.get_running_loop()
757 1
        url = f"{self.base_endpoint}/1234/extend"
758 1
        response = await self.api.patch(url)
759
        assert response.status_code == 400
760
        current_data = response.json()
761
        assert "Invalid json" in current_data["description"]
762
        self.scheduler.update.assert_not_called()
763
764 1
    async def test_extend_case_3(self):
765
        """Test payload without minutes."""
766 1
        self.napp.controller.loop = asyncio.get_running_loop()
767 1
        url = f"{self.base_endpoint}/1234/extend"
768 1
        payload = {"seconds": 240}
769 1
        response = await self.api.patch(url, json=payload)
770
        assert response.status_code == 400
771
        current_data = response.json()
772
        assert current_data["description"] == "Minutes of extension must be sent"
773
        self.scheduler.update.assert_not_called()
774
775 1
    async def test_extend_case_4(self):
776
        """Test no integer extension minutes."""
777 1
        self.napp.controller.loop = asyncio.get_running_loop()
778 1
        url = f"{self.base_endpoint}/1234/extend"
779 1
        payload = {"minutes": "240"}
780 1
        response = await self.api.patch(url, json=payload)
781
        assert response.status_code == 400
782
        current_data = response.json()
783
        assert current_data["description"] == "Minutes of extension must be integer"
784
        self.scheduler.update.assert_not_called()
785
786 1 View Code Duplication
    async def test_extend_case_5(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
787
        """Test maintenance did not start."""
788 1
        self.napp.controller.loop = asyncio.get_running_loop()
789 1
        start1 = datetime.now(pytz.utc) + timedelta(hours=3)
790 1
        end1 = start1 + timedelta(hours=4)
791 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
792
            id="1234",
793
            start=start1.replace(microsecond=0),
794
            end=end1.replace(microsecond=0),
795
            switches=["00:00:00:00:00:00:12:23"],
796
            status="pending",
797
        )
798 1
        url = f"{self.base_endpoint}/1234/extend"
799 1
        payload = {"minutes": 240}
800 1
        response = await self.api.patch(url, json=payload)
801
        assert response.status_code == 400
802
        current_data = response.json()
803
        assert (
804
            current_data["description"] == "Maintenance window 1234 has not yet started"
805
        )
806
        self.scheduler.get_maintenance.assert_called_once_with("1234")
807
        self.scheduler.update.assert_not_called()
808
809 1 View Code Duplication
    async def test_extend_case_6(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
810
        """Test maintenance already finished."""
811 1
        self.napp.controller.loop = asyncio.get_running_loop()
812 1
        start1 = datetime.now(pytz.utc) - timedelta(hours=3)
813 1
        end1 = start1 + timedelta(hours=2)
814 1
        self.scheduler.get_maintenance.return_value = MW.model_construct(
815
            id="1234",
816
            start=start1.replace(microsecond=0),
817
            end=end1.replace(microsecond=0),
818
            switches=["00:00:00:00:00:00:12:23"],
819
            status="finished",
820
        )
821 1
        url = f"{self.base_endpoint}/1234/extend"
822 1
        payload = {"minutes": 240}
823 1
        response = await self.api.patch(url, json=payload)
824
        assert response.status_code == 400
825
        current_data = response.json()
826
        assert (
827
            current_data["description"]
828
            == "Maintenance window 1234 has already finished"
829
        )
830
        self.scheduler.get_maintenance.assert_called_once_with("1234")
831
        self.scheduler.update.assert_not_called()
832
833 1
    async def test_extend_case_7(self):
834
        """Test no maintenace found."""
835 1
        self.napp.controller.loop = asyncio.get_running_loop()
836 1
        self.scheduler.get_maintenance.return_value = None
837 1
        url = f"{self.base_endpoint}/1235/extend"
838 1
        payload = {"minutes": 240}
839 1
        response = await self.api.patch(url, json=payload)
840
        assert response.status_code == 404
841
        current_data = response.json()
842
        assert current_data["description"] == "Maintenance with id 1235 not found"
843
        self.scheduler.get_maintenance.assert_called_once_with("1235")
844
        self.scheduler.update.assert_not_called()
845