1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-09-20 11:21:03 +00:00
supysonic/tests/api/test_response_helper.py

209 lines
6.8 KiB
Python
Raw Normal View History

2017-10-28 19:18:34 +00:00
# This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API.
#
# Copyright (C) 2017-2018 Alban 'spl0k' Féron
2017-10-28 19:18:34 +00:00
#
# Distributed under terms of the GNU AGPLv3 license.
2017-11-27 21:30:13 +00:00
import unittest
2018-01-21 21:02:32 +00:00
import flask.json
2017-10-28 19:18:34 +00:00
from xml.etree import ElementTree
2018-02-11 11:40:10 +00:00
from supysonic.api.formatters import JSONFormatter, JSONPFormatter, XMLFormatter
2018-01-08 22:13:50 +00:00
2017-11-27 21:30:13 +00:00
from ..testbase import TestBase
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
2020-11-22 15:12:14 +00:00
class UnwrapperMixin:
2018-02-11 11:40:10 +00:00
def make_response(self, elem, data):
with self.request_context():
2020-11-22 15:12:14 +00:00
rv = super().make_response(elem, data)
2019-06-29 15:25:44 +00:00
return rv.get_data(as_text=True)
2017-11-27 21:30:13 +00:00
2018-02-11 11:40:10 +00:00
@staticmethod
def create_from(cls):
class Unwrapper(UnwrapperMixin, cls):
pass
2019-06-29 15:25:44 +00:00
2018-02-11 11:40:10 +00:00
return Unwrapper
2019-06-29 15:25:44 +00:00
2018-02-11 11:40:10 +00:00
class ResponseHelperJsonTestCase(TestBase, UnwrapperMixin.create_from(JSONFormatter)):
def make_response(self, elem, data):
2020-11-22 15:12:14 +00:00
rv = super().make_response(elem, data)
2018-02-11 11:40:10 +00:00
return flask.json.loads(rv)
2018-02-11 11:40:10 +00:00
def process_and_extract(self, d):
2019-06-29 15:25:44 +00:00
return self.make_response("tag", d)["subsonic-response"]["tag"]
2017-10-28 19:18:34 +00:00
def test_basic(self):
2018-02-11 11:40:10 +00:00
empty = self.empty
2017-10-28 19:18:34 +00:00
self.assertEqual(len(empty), 1)
2019-06-29 15:25:44 +00:00
self.assertIn("subsonic-response", empty)
self.assertIsInstance(empty["subsonic-response"], dict)
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
resp = empty["subsonic-response"]
2017-10-28 19:18:34 +00:00
self.assertEqual(len(resp), 2)
2019-06-29 15:25:44 +00:00
self.assertIn("status", resp)
self.assertIn("version", resp)
self.assertEqual(resp["status"], "ok")
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
resp = self.error(0, "message")["subsonic-response"]
self.assertEqual(resp["status"], "failed")
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
some_dict = {"intValue": 2, "someString": "Hello world!"}
2017-10-28 19:18:34 +00:00
resp = self.process_and_extract(some_dict)
2019-06-29 15:25:44 +00:00
self.assertIn("intValue", resp)
self.assertIn("someString", resp)
2017-10-28 19:18:34 +00:00
def test_lists(self):
2019-06-29 15:25:44 +00:00
resp = self.process_and_extract({"someList": [2, 4, 8, 16], "emptyList": []})
self.assertIn("someList", resp)
self.assertNotIn("emptyList", resp)
self.assertListEqual(resp["someList"], [2, 4, 8, 16])
2017-10-28 19:18:34 +00:00
def test_dicts(self):
2019-06-29 15:25:44 +00:00
resp = self.process_and_extract({"dict": {"s": "Blah", "i": 20}, "empty": {}})
self.assertIn("dict", resp)
self.assertIn("empty", resp)
self.assertDictEqual(resp["dict"], {"s": "Blah", "i": 20})
self.assertDictEqual(resp["empty"], {})
2017-10-28 19:18:34 +00:00
def test_nesting(self):
2019-06-29 15:25:44 +00:00
resp = self.process_and_extract(
{
"dict": {
"value": "hey look! a string",
"list": [1, 2, 3],
"emptyList": [],
"subdict": {"a": "A"},
},
"list": [{"b": "B"}, {"c": "C"}, [4, 5, 6], "final string"],
}
)
2017-10-28 19:18:34 +00:00
2018-02-11 11:40:10 +00:00
self.assertEqual(len(resp), 2)
2019-06-29 15:25:44 +00:00
self.assertIn("dict", resp)
self.assertIn("list", resp)
dct = resp["dict"]
lst = resp["list"]
self.assertIn("value", dct)
self.assertIn("list", dct)
self.assertNotIn("emptyList", dct)
self.assertIn("subdict", dct)
self.assertIsInstance(dct["value"], str)
self.assertIsInstance(dct["list"], list)
self.assertIsInstance(dct["subdict"], dict)
self.assertEqual(lst, [{"b": "B"}, {"c": "C"}, [4, 5, 6], "final string"])
2019-06-29 15:25:44 +00:00
2017-10-28 19:18:34 +00:00
2018-02-11 11:40:10 +00:00
class ResponseHelperJsonpTestCase(TestBase, UnwrapperMixin.create_from(JSONPFormatter)):
2017-10-28 19:18:34 +00:00
def test_basic(self):
2019-06-29 15:25:44 +00:00
self._JSONPFormatter__callback = "callback" # hacky
2018-02-11 11:40:10 +00:00
result = self.empty
2019-06-29 15:25:44 +00:00
self.assertTrue(result.startswith("callback({"))
self.assertTrue(result.endswith("})"))
2017-10-28 19:18:34 +00:00
2018-01-21 21:02:32 +00:00
json = flask.json.loads(result[9:-1])
2019-06-29 15:25:44 +00:00
self.assertIn("subsonic-response", json)
2017-10-28 19:18:34 +00:00
2018-02-11 11:40:10 +00:00
class ResponseHelperXMLTestCase(TestBase, UnwrapperMixin.create_from(XMLFormatter)):
def make_response(self, elem, data):
2020-11-22 15:12:14 +00:00
xml = super().make_response(elem, data)
2019-06-29 15:25:44 +00:00
xml = xml.replace('xmlns="http://subsonic.org/restapi"', "")
2017-10-28 19:18:34 +00:00
root = ElementTree.fromstring(xml)
return root
2018-02-11 11:40:10 +00:00
def process_and_extract(self, d):
2019-06-29 15:25:44 +00:00
rv = self.make_response("tag", d)
return rv.find("tag")
2018-02-11 11:40:10 +00:00
2017-10-28 19:18:34 +00:00
def assertAttributesMatchDict(self, elem, d):
2019-06-29 15:25:44 +00:00
d = {k: str(v) for k, v in d.items()}
2017-10-28 19:18:34 +00:00
self.assertDictEqual(elem.attrib, d)
def test_root(self):
2020-11-22 15:12:14 +00:00
xml = super().make_response("tag", {})
2019-06-29 15:25:44 +00:00
self.assertIn("<subsonic-response ", xml)
2018-01-08 22:13:50 +00:00
self.assertIn('xmlns="http://subsonic.org/restapi"', xml)
2019-06-29 15:25:44 +00:00
self.assertTrue(xml.strip().endswith("</subsonic-response>"))
2017-10-28 19:18:34 +00:00
def test_basic(self):
2018-02-11 11:40:10 +00:00
empty = self.empty
2019-06-29 15:25:44 +00:00
self.assertIsNotNone(empty.find(".[@version]"))
2018-01-08 22:13:50 +00:00
self.assertIsNotNone(empty.find(".[@status='ok']"))
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
resp = self.error(0, "message")
2018-01-08 22:13:50 +00:00
self.assertIsNotNone(resp.find(".[@status='failed']"))
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
some_dict = {"intValue": 2, "someString": "Hello world!"}
2018-02-11 11:40:10 +00:00
resp = self.process_and_extract(some_dict)
2019-06-29 15:25:44 +00:00
self.assertIsNotNone(resp.find(".[@intValue]"))
self.assertIsNotNone(resp.find(".[@someString]"))
2017-10-28 19:18:34 +00:00
def test_lists(self):
2019-06-29 15:25:44 +00:00
resp = self.process_and_extract({"someList": [2, 4, 8, 16], "emptyList": []})
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
elems = resp.findall("./someList")
2017-10-28 19:18:34 +00:00
self.assertEqual(len(elems), 4)
2019-06-29 15:25:44 +00:00
self.assertIsNone(resp.find("./emptyList"))
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
for e, i in zip(elems, [2, 4, 8, 16]):
2017-10-28 19:18:34 +00:00
self.assertEqual(int(e.text), i)
def test_dicts(self):
2019-06-29 15:25:44 +00:00
resp = self.process_and_extract({"dict": {"s": "Blah", "i": 20}, "empty": {}})
2017-10-28 19:18:34 +00:00
2019-06-29 15:25:44 +00:00
d = resp.find("./dict")
2017-10-28 19:18:34 +00:00
self.assertIsNotNone(d)
2019-06-29 15:25:44 +00:00
self.assertIsNotNone(resp.find("./empty"))
self.assertAttributesMatchDict(d, {"s": "Blah", "i": 20})
2017-10-28 19:18:34 +00:00
def test_nesting(self):
2019-06-29 15:25:44 +00:00
resp = self.process_and_extract(
{
"dict": {
"somevalue": "hey look! a string",
"list": [1, 2, 3],
"emptyList": [],
"subdict": {"a": "A"},
},
"list": [{"b": "B"}, {"c": "C"}, "final string"],
}
)
self.assertEqual(len(resp), 4) # 'dict' and 3 'list's
d = resp.find("./dict")
lists = resp.findall("./list")
2017-10-28 19:18:34 +00:00
self.assertIsNotNone(d)
2019-06-29 15:25:44 +00:00
self.assertAttributesMatchDict(d, {"somevalue": "hey look! a string"})
self.assertEqual(len(d.findall("./list")), 3)
self.assertEqual(len(d.findall("./emptyList")), 0)
self.assertIsNotNone(d.find("./subdict"))
2017-10-28 19:18:34 +00:00
self.assertEqual(len(lists), 3)
2019-06-29 15:25:44 +00:00
self.assertAttributesMatchDict(lists[0], {"b": "B"})
self.assertAttributesMatchDict(lists[1], {"c": "C"})
self.assertEqual(lists[2].text, "final string")
2017-10-28 19:18:34 +00:00
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(ResponseHelperJsonTestCase))
suite.addTest(unittest.makeSuite(ResponseHelperJsonpTestCase))
suite.addTest(unittest.makeSuite(ResponseHelperXMLTestCase))
return suite
2019-06-29 15:25:44 +00:00
if __name__ == "__main__":
unittest.main()