Skip to content

Commit 64e996b

Browse files
committed
Add tests for example app
1 parent a8ce2ca commit 64e996b

File tree

9 files changed

+249
-5
lines changed

9 files changed

+249
-5
lines changed

examples/__init__.py

Whitespace-only changes.

examples/app/__init__.py

Whitespace-only changes.

examples/app/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
MODEL_FACTORY = init_model_factory(base=db.Model, spec=SPEC)
1616

1717

18-
class Employee(MODEL_FACTORY(name="Employee")):
18+
class Employee(MODEL_FACTORY(name="Employee")): # type: ignore
1919
"""Employee model with serialization function."""
2020

2121
def to_dict(self):

setup.cfg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool:pytest]
2-
addopts = -v --cov=openapi_sqlalchemy --cov-config=tests/.coveragerc --flakes --strict
2+
addopts = -v --cov=openapi_sqlalchemy --cov=examples/app --cov-config=tests/.coveragerc --flakes --strict
33
flakes-ignore =
44
*__init__.py ALL
55
markers =
@@ -8,4 +8,6 @@ markers =
88
integration
99
prod_env
1010
helper
11+
app
1112
python_functions = test_*
13+
mocked-sessions = examples.app.models.db.session

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
"pylint",
3737
"pytest-cov",
3838
"pytest-flakes",
39+
"pytest-flask",
40+
"pytest-flask-sqlalchemy",
3941
"mypy",
4042
"pydocstyle",
4143
"black",

tests/.coveragerc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[run]
2-
omit =
2+
omit = examples/app/app.py
33
branch = True
44

55
[report]

tests/examples/app/conftest.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
"""Fixtures for example app."""
22

3+
import sys
4+
35
import connexion
46
import pytest
57

8+
from examples.app import models
9+
610

711
@pytest.fixture(scope="session")
812
def app():
913
"""Flask app for testing."""
14+
# Adding app directory to path
15+
sys.path.append("examples/app/")
1016
# Adding swagger file
1117
flask_app = connexion.FlaskApp(__name__, specification_dir="../../../examples/app/")
1218
flask_app.add_api("api.yaml", validate_responses=True)
@@ -15,3 +21,24 @@ def app():
1521
flask_app.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
1622

1723
return flask_app.app
24+
25+
26+
@pytest.fixture(scope="session")
27+
def _db(app): # pylint: disable=redefined-outer-name
28+
"""Database session for testing"""
29+
models.db.init_app(app)
30+
models.db.app = app
31+
models.db.create_all()
32+
return models.db
33+
34+
35+
@pytest.fixture(autouse=True)
36+
def cleanup(db_session):
37+
"""Clean out Employees."""
38+
db_session.query(models.Employee).delete()
39+
db_session.commit()
40+
41+
yield
42+
43+
db_session.query(models.Employee).delete()
44+
db_session.commit()

tests/examples/app/test_app.py

Lines changed: 212 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,215 @@
11
"""Tests for example app."""
22

3+
import json
34

4-
def test_():
5-
assert False
5+
import pytest
6+
7+
from examples.app import models
8+
9+
10+
@pytest.mark.app
11+
def test_post(client, db_session):
12+
"""
13+
GIVEN employee
14+
WHEN /employee POST is called with the employee
15+
THEN the employee is in the database.
16+
"""
17+
employee = {"id": 1, "name": "name 1", "division": "division 1", "salary": 1.0}
18+
19+
response = client.post(
20+
"/employee",
21+
data=json.dumps(employee),
22+
headers={"Content-Type": "application/json"},
23+
)
24+
25+
assert response.status_code == 200
26+
db_employees = db_session.query(models.Employee).all()
27+
assert len(db_employees) == 1
28+
db_employee = db_employees[0]
29+
assert db_employee.id == employee["id"]
30+
assert db_employee.name == employee["name"]
31+
assert db_employee.division == employee["division"]
32+
assert db_employee.salary == employee["salary"]
33+
34+
35+
@pytest.mark.app
36+
def test_post_duplicate(client):
37+
"""
38+
GIVEN employee
39+
WHEN /employee POST is called twice with the employee
40+
THEN 400 is returned.
41+
"""
42+
employee = {"id": 1, "name": "name 1", "division": "division 1", "salary": 1.0}
43+
44+
client.post(
45+
"/employee",
46+
data=json.dumps(employee),
47+
headers={"Content-Type": "application/json"},
48+
)
49+
response = client.post(
50+
"/employee",
51+
data=json.dumps(employee),
52+
headers={"Content-Type": "application/json"},
53+
)
54+
55+
assert response.status_code == 400
56+
57+
58+
@pytest.mark.app
59+
def test_get(client, db_session):
60+
"""
61+
GIVEN database with employee
62+
WHEN /employee GET is called
63+
THEN the employee is returned.
64+
"""
65+
db_employee = models.Employee(
66+
id=1, name="name 1", division="division 1", salary=1.0
67+
)
68+
db_session.add(db_employee)
69+
db_session.flush()
70+
71+
response = client.get("/employee")
72+
73+
assert response.status_code == 200
74+
employees = response.json
75+
assert len(employees) == 1
76+
employee = employees[0]
77+
assert employee["id"] == db_employee.id
78+
assert employee["name"] == db_employee.name
79+
assert employee["division"] == db_employee.division
80+
assert employee["salary"] == db_employee.salary
81+
82+
83+
@pytest.mark.app
84+
def test_get_id_miss(client, db_session):
85+
"""
86+
GIVEN database with employee
87+
WHEN /employee/{id} GET is called with a different id
88+
THEN 404 is returned.
89+
"""
90+
db_employee = models.Employee(
91+
id=1, name="name 1", division="division 1", salary=1.0
92+
)
93+
db_session.add(db_employee)
94+
db_session.flush()
95+
96+
response = client.get("/employee/2")
97+
98+
assert response.status_code == 404
99+
100+
101+
@pytest.mark.app
102+
def test_get_id_hit(client, db_session):
103+
"""
104+
GIVEN database with employee
105+
WHEN /employee/{id} GET is called with the id of the employee
106+
THEN the employee is returned.
107+
"""
108+
db_employee = models.Employee(
109+
id=1, name="name 1", division="division 1", salary=1.0
110+
)
111+
db_session.add(db_employee)
112+
db_session.flush()
113+
114+
response = client.get(f"/employee/{db_employee.id}")
115+
116+
assert response.status_code == 200
117+
employee = response.json
118+
assert employee["id"] == db_employee.id
119+
assert employee["name"] == db_employee.name
120+
assert employee["division"] == db_employee.division
121+
assert employee["salary"] == db_employee.salary
122+
123+
124+
@pytest.mark.app
125+
def test_patch_id_miss(client, db_session):
126+
"""
127+
GIVEN database with employee
128+
WHEN /employee/{id} PATCH is called with a different id
129+
THEN 404 is returned.
130+
"""
131+
db_employee = models.Employee(
132+
id=1, name="name 1", division="division 1", salary=1.0
133+
)
134+
db_session.add(db_employee)
135+
db_session.flush()
136+
employee = {"id": 2, "name": "name 2", "division": "division 2", "salary": 2.0}
137+
138+
response = client.patch(
139+
"/employee/2",
140+
data=json.dumps(employee),
141+
headers={"Content-Type": "application/json"},
142+
)
143+
144+
assert response.status_code == 404
145+
146+
147+
@pytest.mark.app
148+
def test_patch_id_hit(client, db_session):
149+
"""
150+
GIVEN database with employee
151+
WHEN /employee/{id} PATCH is called with the id of the employee
152+
THEN the employee is updated.
153+
"""
154+
db_employee = models.Employee(
155+
id=1, name="name 1", division="division 1", salary=1.0
156+
)
157+
db_session.add(db_employee)
158+
db_session.flush()
159+
employee = {
160+
"id": db_employee.id,
161+
"name": "name 2",
162+
"division": "division 2",
163+
"salary": 2.0,
164+
}
165+
166+
response = client.patch(
167+
f"/employee/{db_employee.id}",
168+
data=json.dumps(employee),
169+
headers={"Content-Type": "application/json"},
170+
)
171+
172+
assert response.status_code == 200
173+
db_session.refresh(db_employee)
174+
assert db_employee.id == employee["id"]
175+
assert db_employee.name == employee["name"]
176+
assert db_employee.division == employee["division"]
177+
assert db_employee.salary == employee["salary"]
178+
179+
180+
@pytest.mark.app
181+
def test_delete_id_miss(client, db_session):
182+
"""
183+
GIVEN database with employee
184+
WHEN /employee/{id} DELETE is called with a different id
185+
THEN 404 is returned.
186+
"""
187+
db_employee = models.Employee(
188+
id=1, name="name 1", division="division 1", salary=1.0
189+
)
190+
db_session.add(db_employee)
191+
db_session.flush()
192+
193+
response = client.delete("/employee/2")
194+
195+
assert response.status_code == 404
196+
197+
198+
@pytest.mark.app
199+
def test_delete_id_hit(client, db_session):
200+
"""
201+
GIVEN database with employee
202+
WHEN /employee/{id} DELETE is called with the id of the employee
203+
THEN the employee is updated.
204+
"""
205+
db_employee = models.Employee(
206+
id=1, name="name 1", division="division 1", salary=1.0
207+
)
208+
db_session.add(db_employee)
209+
db_session.flush()
210+
211+
response = client.delete(f"/employee/{db_employee.id}")
212+
213+
assert response.status_code == 200
214+
db_employees = db_session.query(models.Employee).all()
215+
assert len(db_employees) == 0

tox.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ deps =
77
pytest
88
pytest-cov
99
pytest-flakes
10+
pytest-flask
11+
pytest-flask-sqlalchemy
1012
typing-extensions
1113
sqlalchemy
14+
connexion
1215
commands =
1316
pytest

0 commit comments

Comments
 (0)