Skip to content

Commit 14f7603

Browse files
committed
Refactor: SnapshotSaveAs
1 parent d51d64a commit 14f7603

File tree

4 files changed

+134
-17
lines changed

4 files changed

+134
-17
lines changed

.github/workflows/unittest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
fail_below_min: true
4747
format: markdown
4848
hide_branch_rate: false
49-
hide_complexity: false
49+
hide_complexity: true
5050
indicators: true
5151
output: both
5252
thresholds: '15 30'

mod/controller/rest/snapshot.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python3
22
# SPDX-FileCopyrightText: 2012-2023 MOD Audio UG
33
# SPDX-License-Identifier: AGPL-3.0-or-later
4+
from tornado import gen, web
5+
46
from mod.controller.handler.json_request_handler import JsonRequestHandler
57
from mod.session import SESSION
68
from mod.settings import DEFAULT_SNAPSHOT_NAME
@@ -66,3 +68,34 @@ def post(self):
6668
"""
6769
ok = SESSION.host.snapshot_save()
6870
self.write(ok)
71+
72+
class SnapshotSaveAs(JsonRequestHandler):
73+
74+
# TODO: Replace GET /snapshot/saveas
75+
# to POST /pedalboards/current/snapshots/saveas
76+
@web.asynchronous
77+
@gen.engine
78+
def get(self):
79+
"""
80+
Create a new snapshot with the suggested ``title`` based on the current pedalboard status;
81+
.. code-block:: json
82+
83+
{
84+
"ok": true,
85+
"id": 1,
86+
"title": "Snapshot name"
87+
}
88+
89+
:return: `true` if it was successfully deleted
90+
"""
91+
title = self.get_argument('title')
92+
idx = SESSION.host.snapshot_saveas(title)
93+
title = SESSION.host.snapshot_name(idx)
94+
95+
yield gen.Task(SESSION.host.hmi_report_ss_name_if_current, idx)
96+
97+
self.write({
98+
'ok': idx is not None, # FIXME: Always true
99+
'id': idx,
100+
'title': title,
101+
})

mod/webserver.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
from mod.controller.handler.json_request_handler import JsonRequestHandler
2424
from mod.controller.handler.timeless_request_handler import TimelessRequestHandler
25-
from mod.controller.rest.snapshot import SnapshotName, SnapshotList, SnapshotSave
25+
from mod.controller.rest.snapshot import SnapshotName, SnapshotList, SnapshotSave, SnapshotSaveAs
2626

2727
try:
2828
from signal import signal, SIGUSR1, SIGUSR2
@@ -1555,21 +1555,6 @@ def post(self, mode):
15551555
ok = yield gen.Task(SESSION.web_set_sync_mode, transport_sync)
15561556
self.write(ok)
15571557

1558-
class SnapshotSaveAs(JsonRequestHandler):
1559-
@web.asynchronous
1560-
@gen.engine
1561-
def get(self):
1562-
title = self.get_argument('title')
1563-
idx = SESSION.host.snapshot_saveas(title)
1564-
title = SESSION.host.snapshot_name(idx)
1565-
1566-
yield gen.Task(SESSION.host.hmi_report_ss_name_if_current, idx)
1567-
1568-
self.write({
1569-
'ok': idx is not None,
1570-
'id': idx,
1571-
'title': title,
1572-
})
15731558

15741559
class SnapshotRename(JsonRequestHandler):
15751560
@web.asynchronous
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python3
2+
# SPDX-FileCopyrightText: 2012-2023 MOD Audio UG
3+
# SPDX-License-Identifier: AGPL-3.0-or-later
4+
# This test uses coroutine style.
5+
import json
6+
from uuid import uuid4
7+
8+
from tornado.httpclient import HTTPRequest
9+
from tornado.testing import AsyncHTTPTestCase
10+
11+
from mod.webserver import application
12+
13+
14+
class SnapshotSaveAsTestCase(AsyncHTTPTestCase):
15+
def get_app(self):
16+
return application
17+
18+
def test_save_as(self):
19+
# Create a snapshot
20+
name = str(uuid4())
21+
snapshot = self._save_as(name)
22+
23+
# Assert is saved
24+
self.assertDictEqual(
25+
{
26+
"ok": True,
27+
"id": snapshot['id'],
28+
"title": name
29+
},
30+
snapshot
31+
)
32+
33+
# Clear
34+
self.fetch("/snapshot/remove?id=" + str(snapshot['id']))
35+
36+
def test_save_as_deleted_snapshot(self):
37+
"""
38+
It's possible, because the snapshot is created based on pedalboard's
39+
current state instead of a last snapshot loaded
40+
"""
41+
# Create two snapshots
42+
# because it is necessary to exists at least one
43+
snapshot_1_name = str(uuid4())
44+
snapshot_2_name = str(uuid4())
45+
46+
snapshot_1 = self._save_as(snapshot_1_name)
47+
snapshot_2 = self._save_as(snapshot_2_name)
48+
49+
# Save snapshot created
50+
self.fetch("/snapshot/load?id=" + str(snapshot_2['id']))
51+
response = self.post("/snapshot/save")
52+
53+
# Assert is saved
54+
self.assertTrue(json.loads(response.body))
55+
56+
# Delete created snapshot
57+
self.fetch("/snapshot/remove?id=" + str(snapshot_2['id']))
58+
59+
# Save as deleted snapshot
60+
snapshot_3_name = str(uuid4())
61+
snapshot_3 = self._save_as(snapshot_3_name)
62+
self.assertEqual(response.code, 200)
63+
self.assertDictEqual(
64+
{
65+
"ok": True,
66+
"id": snapshot_3['id'],
67+
"title": snapshot_3_name
68+
},
69+
snapshot_3
70+
)
71+
72+
# Clear
73+
self.fetch("/snapshot/remove?id=" + str(snapshot_3['id']))
74+
self.fetch("/snapshot/remove?id=" + str(snapshot_1['id']))
75+
76+
def test_save_duplicated_name(self):
77+
snapshot_1_name = snapshot_2_name = str(uuid4())
78+
79+
self.assertEqual(snapshot_1_name, snapshot_2_name)
80+
81+
snapshot_1 = self._save_as(snapshot_1_name)
82+
snapshot_2 = self._save_as(snapshot_2_name)
83+
84+
self.assertNotEqual(snapshot_1['title'], snapshot_2['title'])
85+
self.assertTrue(snapshot_1['title'] < snapshot_2['title'])
86+
87+
# Clear
88+
self.fetch("/snapshot/remove?id=" + str(snapshot_2['id']))
89+
self.fetch("/snapshot/remove?id=" + str(snapshot_1['id']))
90+
91+
def post(self, url):
92+
self.http_client.fetch(HTTPRequest(self.get_url(url), "POST", allow_nonstandard_methods=True), self.stop)
93+
return self.wait()
94+
95+
def _save_as(self, name):
96+
response = self.fetch("/snapshot/saveas?title=" + name)
97+
self.assertEqual(response.code, 200)
98+
99+
return json.loads(response.body)

0 commit comments

Comments
 (0)