-
Notifications
You must be signed in to change notification settings - Fork 684
/
Copy pathmockup.py
77 lines (63 loc) · 2.77 KB
/
mockup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# coding: utf8
import json
import os
from unittest.mock import Mock
from requests import Session, Response
SERVER = "https://my.test.server.com"
RESPONSE_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "responses")
def mockup_server():
return SERVER
def request_mockup(*args, **kwargs):
method = kwargs["method"]
url = kwargs["url"]
if not url.startswith(SERVER + "/"):
raise ValueError(f"URL [{url}] does not start with [{SERVER}/].")
parts = url[len(SERVER) + 1 :].split("?")
url = parts[0]
response_key = parts[1] if len(parts) > 1 else None
if kwargs["data"] is not None:
response_key = str(kwargs["data"])
response = Response()
response.url = kwargs["url"]
response_file = os.path.join(RESPONSE_ROOT, url, method)
try:
with open(response_file, encoding="utf-8") as f:
data = {"responses": {}, "__builtins__": {}, "true": True, "false": False, "null": None}
exec(f.read(), data)
data = data["responses"][response_key]
if type(data) is dict:
if "status_code" in data:
response.status_code = data.pop("status_code")
else:
response.status_code = 200
if "headers" in data:
response.headers = data.pop("headers")
# Extend the links with the server
for item in [None, "owner", "project", "workspace"]:
# Use values of paged response
for elem in data["values"] if "values" in data else [data]:
cur_dict = elem if item is None else elem.get(item, {})
if "links" in cur_dict:
for link in list(cur_dict["links"].values()):
for ld in link if type(link) is list else [link]:
ld["href"] = f"{SERVER}/{ld['href']}"
if "next" in data:
data["next"] = f"{SERVER}/{data['next']}"
response.encoding = "utf-8"
response._content = bytes(json.dumps(data), response.encoding)
else:
response.status_code = 200
response._content = data
except FileNotFoundError:
response.encoding = "utf-8"
response._content = b"{}"
response.status_code = 404 # Not found
response.reason = f"No stub defined [{response_file}]"
except KeyError:
response.encoding = "utf-8"
response._content = b"{}"
response.status_code = 404 # Not found
response.reason = f"No stub defined for key [{response_key}] in [{response_file}]"
return response
Session.request = Mock()
Session.request.side_effect = request_mockup