mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-21 20:19:32 +08:00
STAR-322: Documenting the network manager mock
This commit is contained in:
parent
45f51c3588
commit
c495ade2d3
@ -9,10 +9,15 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply
|
|||||||
from UM.Signal import Signal
|
from UM.Signal import Signal
|
||||||
|
|
||||||
|
|
||||||
|
## This class can be used to mock the QNetworkManager class and test the code using it.
|
||||||
|
# After patching the QNetworkManager class, requests are prepared before they can be executed.
|
||||||
|
# Any requests not prepared beforehand will cause KeyErrors.
|
||||||
class NetworkManagerMock:
|
class NetworkManagerMock:
|
||||||
|
# signals used in the network manager.
|
||||||
finished = Signal()
|
finished = Signal()
|
||||||
authenticationRequired = Signal()
|
authenticationRequired = Signal()
|
||||||
|
|
||||||
|
# an enumeration of the supported operations and their code for the network access manager.
|
||||||
_OPERATIONS = {
|
_OPERATIONS = {
|
||||||
"GET": QNetworkAccessManager.GetOperation,
|
"GET": QNetworkAccessManager.GetOperation,
|
||||||
"POST": QNetworkAccessManager.PostOperation,
|
"POST": QNetworkAccessManager.PostOperation,
|
||||||
@ -22,15 +27,29 @@ class NetworkManagerMock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
# a dict with the prepared replies, using the format {(http_method, url): reply}
|
||||||
self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply]
|
self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply]
|
||||||
|
|
||||||
def __getattr__(self, method):
|
## Mock implementation of the get, post, put, delete and head methods from the network manager.
|
||||||
|
# Since the methods are very simple and the same it didn't make sense to repeat the code.
|
||||||
|
# \param method: The method being called.
|
||||||
|
# \return The mocked function, if the method name is known. Defaults to the standard getattr function.
|
||||||
|
def __getattr__(self, method: str):
|
||||||
operation = self._OPERATIONS.get(method.upper())
|
operation = self._OPERATIONS.get(method.upper())
|
||||||
if operation:
|
if operation:
|
||||||
|
# this mock implementation will simply return the reply from the prepared ones.
|
||||||
|
# it raises a KeyError if requests are done without being prepared.
|
||||||
return lambda request, *_: self.replies[method.upper(), request.url().toString()]
|
return lambda request, *_: self.replies[method.upper(), request.url().toString()]
|
||||||
return super().__getattribute__(method)
|
|
||||||
|
|
||||||
def prepareResponse(self, method: str, url: str, status_code: int, response: dict) -> None:
|
# the attribute is not one of the implemented methods, default to the standard implementation.
|
||||||
|
return getattr(super(), method)
|
||||||
|
|
||||||
|
## Prepares a server reply for the given parameters.
|
||||||
|
# \param method: The HTTP method.
|
||||||
|
# \param url: The URL being requested.
|
||||||
|
# \param status_code: The HTTP status code for the response.
|
||||||
|
# \param response: A dictionary with the response from the server (this is converted to JSON).
|
||||||
|
def prepareReply(self, method: str, url: str, status_code: int, response: dict) -> None:
|
||||||
reply_mock = MagicMock()
|
reply_mock = MagicMock()
|
||||||
reply_mock.url().toString.return_value = url
|
reply_mock.url().toString.return_value = url
|
||||||
reply_mock.operation.return_value = self._OPERATIONS[method]
|
reply_mock.operation.return_value = self._OPERATIONS[method]
|
||||||
@ -38,9 +57,30 @@ class NetworkManagerMock:
|
|||||||
reply_mock.readAll.return_value = json.dumps(response).encode()
|
reply_mock.readAll.return_value = json.dumps(response).encode()
|
||||||
self.replies[method, url] = reply_mock
|
self.replies[method, url] = reply_mock
|
||||||
|
|
||||||
|
## Prepares a reply for the API call to get clusters.
|
||||||
|
def prepareGetClusters(self) -> None:
|
||||||
|
self.prepareReply(
|
||||||
|
"GET", "https://api-staging.ultimaker.com/connect/v1/clusters",
|
||||||
|
200, {
|
||||||
|
"data": [{
|
||||||
|
"cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq",
|
||||||
|
"host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050",
|
||||||
|
"host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807",
|
||||||
|
"is_online": False, "status": "inactive"
|
||||||
|
}, {
|
||||||
|
"cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC",
|
||||||
|
"host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050",
|
||||||
|
"host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807",
|
||||||
|
"is_online": True, "status": "active"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
## Emits the signal that the reply is ready to all prepared replies.
|
||||||
def flushReplies(self):
|
def flushReplies(self):
|
||||||
for reply in self.replies.values():
|
for reply in self.replies.values():
|
||||||
self.finished.emit(reply)
|
self.finished.emit(reply)
|
||||||
|
|
||||||
|
## Deletes all prepared replies
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.replies.clear()
|
self.replies.clear()
|
||||||
|
@ -18,22 +18,7 @@ class TestCloudOutputDeviceManager(TestCase):
|
|||||||
self.app.initialize()
|
self.app.initialize()
|
||||||
|
|
||||||
self.network = NetworkManagerMock()
|
self.network = NetworkManagerMock()
|
||||||
self.network.prepareResponse(
|
self.network.prepareGetClusters()
|
||||||
"GET", "https://api-staging.ultimaker.com/connect/v1/clusters",
|
|
||||||
200, {
|
|
||||||
"data": [{
|
|
||||||
"cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq",
|
|
||||||
"host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050",
|
|
||||||
"host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807",
|
|
||||||
"is_online": False, "status": "inactive"
|
|
||||||
}, {
|
|
||||||
"cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC",
|
|
||||||
"host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050",
|
|
||||||
"host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807",
|
|
||||||
"is_online": True, "status": "active"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
@ -48,4 +33,6 @@ class TestCloudOutputDeviceManager(TestCase):
|
|||||||
self.network.flushReplies()
|
self.network.flushReplies()
|
||||||
|
|
||||||
devices = self.app.getOutputDeviceManager().getOutputDevices()
|
devices = self.app.getOutputDeviceManager().getOutputDevices()
|
||||||
self.assertEqual([CloudOutputDevice], list(map(type, devices)))
|
self.assertEqual([CloudOutputDevice], [type(d) for d in devices])
|
||||||
|
self.assertEqual(["R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC"], [d.key for d in devices])
|
||||||
|
self.assertEqual(["ultimakersystem-ccbdd30044ec"], [d.host_name for d in devices])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user