Skip to content

Commit 84bbade

Browse files
add product tests
1 parent 17fddab commit 84bbade

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

tests/test_product.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import pytest
2+
3+
from app.models import Product
4+
from tests import utils
5+
6+
7+
class TestProduct:
8+
TEST_PRODUCT_NAME = "iPhone 13"
9+
TEST_PRODUCT_DESC = "Latest Apple iPhone"
10+
11+
@pytest.fixture(autouse=True)
12+
def setup(self, client):
13+
self.client = client
14+
with client.application.app_context():
15+
assert Product.query.count() == 0
16+
17+
@pytest.fixture
18+
def create_product(self, create_authenticated_headers):
19+
def _create(name, description=None, subcategories=None, headers=None):
20+
if headers is None:
21+
headers = create_authenticated_headers()
22+
payload = {"name": name}
23+
if description is not None:
24+
payload["description"] = description
25+
if subcategories is not None:
26+
payload["subcategories"] = subcategories
27+
return self.client.post(
28+
"/product/create", json=payload, headers=headers
29+
)
30+
return _create
31+
32+
def _count_products(self):
33+
with self.client.application.app_context():
34+
return Product.query.count()
35+
36+
def _verify_product_in_db(self, name, should_exist=True):
37+
with self.client.application.app_context():
38+
product = Product.query.filter_by(name=name).first()
39+
if should_exist:
40+
assert product is not None
41+
assert product.name == name
42+
return product
43+
else:
44+
assert product is None
45+
46+
def test_create_product(self, create_product):
47+
response = create_product(self.TEST_PRODUCT_NAME, self.TEST_PRODUCT_DESC)
48+
49+
assert response.status_code == 201
50+
data = response.get_json()
51+
assert data["name"] == self.TEST_PRODUCT_NAME
52+
assert data["description"] == self.TEST_PRODUCT_DESC
53+
assert "id" in data
54+
self._verify_product_in_db(self.TEST_PRODUCT_NAME)
55+
56+
def test_create_product_duplicate_name(self, create_product):
57+
create_product(self.TEST_PRODUCT_NAME, self.TEST_PRODUCT_DESC)
58+
response = create_product(self.TEST_PRODUCT_NAME, self.TEST_PRODUCT_DESC)
59+
60+
assert response.status_code == 500
61+
assert self._count_products() == 1
62+
self._verify_product_in_db(self.TEST_PRODUCT_NAME)
63+
64+
def test_get_product_by_id(self, create_product):
65+
response = create_product("Pixel 6", "Google phone")
66+
data = response.get_json()
67+
p_id = data["id"]
68+
get_resp = self.client.get(f"/product/{p_id}")
69+
70+
assert get_resp.status_code == 200
71+
data = get_resp.get_json()
72+
assert data["name"] == "Pixel 6"
73+
assert data["id"] == p_id
74+
75+
def test_get_all_products(self, create_product):
76+
create_product("A", "descA")
77+
create_product("B", "descB")
78+
resp = self.client.get("/products")
79+
80+
assert resp.status_code == 200
81+
data = resp.get_json()
82+
assert "products" in data
83+
assert len(data["products"]) == 2
84+
names = [prod["name"] for prod in data["products"]]
85+
assert "A" in names
86+
assert "B" in names
87+
88+
def test_update_product(self, create_authenticated_headers, create_product):
89+
headers = create_authenticated_headers()
90+
response = create_product("OldProduct", "OldDesc", headers=headers)
91+
data = response.get_json()
92+
p_id = data["id"]
93+
update_resp = self.client.put(
94+
f"/product/{p_id}/update", json={"name": "NewProduct", "description": "NewDesc"}, headers=headers
95+
)
96+
97+
assert update_resp.status_code == 201
98+
data = update_resp.get_json()
99+
assert data["name"] == "NewProduct"
100+
assert data["description"] == "NewDesc"
101+
assert data["id"] == p_id
102+
self._verify_product_in_db("NewProduct")
103+
self._verify_product_in_db("OldProduct", should_exist=False)
104+
105+
def test_delete_product(self, create_authenticated_headers, create_product):
106+
headers = create_authenticated_headers()
107+
response = create_product("ToDelete", "desc", headers=headers)
108+
data = response.get_json()
109+
p_id = data["id"]
110+
delete_resp = self.client.delete(f"/product/{p_id}", headers=headers)
111+
112+
assert delete_resp.status_code == 200
113+
get_resp = self.client.get(f"/product/{p_id}")
114+
assert get_resp.status_code == 404
115+
self._verify_product_in_db("ToDelete", should_exist=False)
116+
117+
@pytest.mark.parametrize(
118+
"get_headers, expected_code",
119+
[
120+
(lambda self: utils.get_expired_token_headers(self.client.application.app_context()), "token_expired"),
121+
(lambda self: utils.get_invalid_token_headers(), "invalid_token"),
122+
(lambda self: None, "authorization_required")
123+
]
124+
)
125+
def test_create_product_token_error(self, get_headers, expected_code):
126+
headers = get_headers(self)
127+
response = self.client.post(
128+
"/product/create", json={"name": "CreateTokenError"}, headers=headers
129+
)
130+
utils.verify_token_error_response(response, expected_code)
131+
self._verify_product_in_db("CreateTokenError", should_exist=False)
132+
133+
@pytest.mark.parametrize(
134+
"get_headers, expected_code",
135+
[
136+
(lambda self: utils.get_expired_token_headers(self.client.application.app_context()), "token_expired"),
137+
(lambda self: utils.get_invalid_token_headers(), "invalid_token"),
138+
(lambda self: None, "authorization_required")
139+
]
140+
)
141+
def test_update_product_token_error(self, get_headers, create_product, create_authenticated_headers, expected_code):
142+
headers = create_authenticated_headers()
143+
response = create_product("UpdateTokenError", "desc", headers=headers)
144+
data = response.get_json()
145+
p_id = data["id"]
146+
147+
update_headers = get_headers(self)
148+
update_resp = self.client.put(
149+
f"/product/{p_id}/update",
150+
json={"name": "UpdatedName"},
151+
headers=update_headers,
152+
)
153+
154+
utils.verify_token_error_response(update_resp, expected_code)
155+
self._verify_product_in_db("UpdateTokenError")
156+
self._verify_product_in_db("UpdatedName", should_exist=False)
157+
158+
@pytest.mark.parametrize(
159+
"get_headers, expected_code",
160+
[
161+
(lambda self: utils.get_expired_token_headers(self.client.application.app_context()), "token_expired"),
162+
(lambda self: utils.get_invalid_token_headers(), "invalid_token"),
163+
(lambda self: None, "authorization_required")
164+
]
165+
)
166+
def test_delete_product_token_error(self, get_headers, create_product, create_authenticated_headers, expected_code):
167+
headers = create_authenticated_headers()
168+
response = create_product("DeleteTokenError", "desc", headers=headers)
169+
data = response.get_json()
170+
p_id = data["id"]
171+
172+
delete_headers = get_headers(self)
173+
delete_resp = self.client.delete(f"/product/{p_id}", headers=delete_headers)
174+
175+
utils.verify_token_error_response(delete_resp, expected_code)
176+
self._verify_product_in_db("DeleteTokenError")
177+
178+
def test_products_pagination(self, create_product):
179+
for i in range(15):
180+
create_product(f"Product{i}", f"Description{i}")
181+
182+
# Page 1
183+
resp1 = self.client.get("/products?page=1")
184+
assert resp1.status_code == 200
185+
data1 = resp1.get_json()
186+
assert "products" in data1
187+
assert len(data1["products"]) == 10
188+
189+
# Page 2
190+
resp2 = self.client.get("/products?page=2")
191+
assert resp2.status_code == 200
192+
data2 = resp2.get_json()
193+
assert "products" in data2
194+
assert len(data2["products"]) == 5

0 commit comments

Comments
 (0)