Skip to content

Commit 003c0e2

Browse files
Add api tests (#186)
* Add api test (#173) * Add unit tests for api only added two tests, many cases are covert by frontend * Modify tests/api_tests/test_api.py add assert * Add an other test add test_wrong_body * Remove print statements * Remove __pycache__/test_api.cpython-311-pytest-8.3.2.pyc * Add variables for expected values * Update api test to new requirements * Add test_getenphse_authorization_url.py * Add test_getenphse_token_and_system_id - bad redirect url - bad redirect url with correct param - fixtures * Update requirements.txt * skip some tests --------- Co-authored-by: BraunRudolf <48672663+BraunRudolf@users.noreply.github.com>
1 parent 0208f57 commit 003c0e2

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ async_timeout
1616
uvicorn
1717
fastapi
1818
pydantic_settings
19+
httpx

tests/api_tests/test_api.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import pytest
2+
from fastapi.testclient import TestClient
3+
4+
from api.app.api import app
5+
6+
7+
expected_prediction_key = "power_kw"
8+
expected_dict_keys = ["timestamp", "predictions"]
9+
prediction_key = expected_dict_keys[1]
10+
expected_number_of_values = 192
11+
expected_response_on_wrong_types = {
12+
"detail": [
13+
{
14+
"loc": ["body","site", "latitude"],
15+
"msg": "Input should be less than or equal to 90",
16+
"type": "less_than_equal",
17+
"input": 91,
18+
"ctx": {"le": 90.0},
19+
},
20+
{
21+
"loc": ["body", "site", "longitude"],
22+
"msg": "Input should be greater than or equal to -180",
23+
"type": "greater_than_equal",
24+
"input": -181,
25+
"ctx": {"ge": -180.0},
26+
},
27+
{
28+
"loc": ["body","site", "capacity_kwp"],
29+
"msg": "Input should be greater than or equal to 0",
30+
"type": "greater_than_equal",
31+
"input": -1,
32+
"ctx": {"ge": 0.0},
33+
},
34+
{
35+
"loc": ["body","site", "tilt"],
36+
"msg": "Input should be less than or equal to 90",
37+
"type": "less_than_equal",
38+
"input": 91,
39+
"ctx": {"le": 90.0},
40+
},
41+
{
42+
"loc": ["body","site", "orientation"],
43+
"msg": "Input should be less than or equal to 360",
44+
"type": "less_than_equal",
45+
"input": 361,
46+
"ctx": {"le": 360.0},
47+
},
48+
]
49+
}
50+
51+
52+
@pytest.fixture
53+
def client():
54+
return TestClient(app)
55+
56+
57+
@pytest.fixture
58+
def body():
59+
return {
60+
"site":{
61+
"latitude": -90,
62+
"longitude": -180,
63+
"capacity_kwp": 0,
64+
"tilt": 35,
65+
"orientation": 180,
66+
"inverter_type": "string",
67+
},
68+
"timestamp": "2021-01-26 01:15:00",
69+
}
70+
71+
72+
@pytest.fixture
73+
def body_short():
74+
return {
75+
"site":{
76+
"latitude": -90,
77+
"longitude": -180,
78+
"capacity_kwp": 0,
79+
},
80+
"timestamp": "2021-01-26 01:15:00",
81+
}
82+
83+
84+
@pytest.fixture
85+
def body_wrong():
86+
return {
87+
"site":{
88+
"latitude": 91,
89+
"longitude": -181,
90+
"capacity_kwp": -1,
91+
"tilt": 91,
92+
"orientation": 361,
93+
"inverter_type": "string",
94+
},
95+
"timestamp": "2021-01-26 01:15:00",
96+
}
97+
98+
@pytest.fixture
99+
def bad_redirect_url(client):
100+
return "url"
101+
102+
@pytest.fixture
103+
def bad_redirect_url_correct_param(client):
104+
return "url?code=code"
105+
106+
def test_api_ok(client, body):
107+
response = client.post("/forecast/", json=body)
108+
response_body = response.json()
109+
assert response.status_code == 200
110+
assert isinstance(response_body[prediction_key][expected_prediction_key], dict)
111+
assert all([key in response_body.keys() for key in expected_dict_keys]), "Expected dictonary key is missing"
112+
assert len(response_body[prediction_key][expected_prediction_key]) == expected_number_of_values, "Expected number of values is wrong"
113+
114+
115+
def test_api_ok_short(client, body_short):
116+
response = client.post("/forecast/", json=body_short)
117+
response_body = response.json()
118+
119+
assert response.status_code == 200
120+
assert isinstance(response_body[prediction_key][expected_prediction_key], dict)
121+
assert all([key in response_body.keys() for key in expected_dict_keys]), "Expected dictonary key is missing"
122+
assert len(response_body[prediction_key][expected_prediction_key]) == expected_number_of_values
123+
124+
125+
def test_api_wrong_body(client, body_wrong):
126+
# Tests all wrong data types responses
127+
response = client.post("/forecast/", json=body_wrong)
128+
response_body = response.json()
129+
130+
assert response.status_code == 422
131+
assert response_body == expected_response_on_wrong_types
132+
133+
@pytest.mark.skip('There needs to be some extra mocking here')
134+
def test_getenphse_authorization_url(client):
135+
response = client.get("/solar_inverters/enphase/auth_url")
136+
assert response.status_code == 200
137+
assert isinstance(response.json()["auth_url"], str)
138+
139+
@pytest.mark.skip('There needs to be some extra mocking here')
140+
def test_getenphse_token_and_system_id_bad_redirect_url(client, bad_redirect_url):
141+
142+
response = client.post("/solar_inverters/enphase/token_and_id", json={"redirect_url": bad_redirect_url})
143+
response_body = response.json()
144+
assert response.status_code == 400
145+
assert response_body['detail'] == 'Invalid redirect URL'
146+
147+
@pytest.mark.skip('There needs to be some extra mocking here')
148+
def test_getenphse_token_and_system_id_bad_redirect_url(client, bad_redirect_url_correct_param):
149+
response = client.post("/solar_inverters/enphase/token_and_id", json={"redirect_url": bad_redirect_url_correct_param})
150+
response_body = response.json()
151+
assert response.status_code == 400
152+
assert 'Error getting access token and system ID: ' in response_body['detail']

0 commit comments

Comments
 (0)