Skip to content

Commit 331a018

Browse files
committed
PCC39 pavelekshin
1 parent 3ec88e0 commit 331a018

File tree

6 files changed

+264
-0
lines changed

6 files changed

+264
-0
lines changed

39/pavelekshin/.app.py.swo

12 KB
Binary file not shown.

39/pavelekshin/.coverage

52 KB
Binary file not shown.

39/pavelekshin/.test_app.py.un~

49.5 KB
Binary file not shown.

39/pavelekshin/app.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from flask import Flask, jsonify, abort, make_response, request
2+
3+
NOT_FOUND = "Not found"
4+
BAD_REQUEST = "Bad request"
5+
6+
app = Flask(__name__)
7+
8+
items = [
9+
{"id": 1, "name": "laptop", "value": 1000},
10+
{
11+
"id": 2,
12+
"name": "chair",
13+
"value": 300,
14+
},
15+
{
16+
"id": 3,
17+
"name": "book",
18+
"value": 20,
19+
},
20+
]
21+
22+
23+
def _get_item(id):
24+
return [item for item in items if item["id"] == id]
25+
26+
27+
def _record_exists(name):
28+
return [item for item in items if item["name"] == name]
29+
30+
31+
@app.errorhandler(404)
32+
def not_found(error):
33+
return make_response(jsonify({"error": NOT_FOUND}), 404)
34+
35+
36+
@app.errorhandler(400)
37+
def bad_request(error):
38+
return make_response(jsonify({"error": BAD_REQUEST}), 400)
39+
40+
41+
@app.route("/api/v1.0/items", methods=["GET"])
42+
def get_items():
43+
return jsonify({"items": items})
44+
45+
46+
@app.route("/api/v1.0/items/<int:id>", methods=["GET"])
47+
def get_item(id):
48+
item = _get_item(id)
49+
if not item:
50+
abort(404)
51+
return jsonify({"items": item})
52+
53+
54+
@app.route("/api/v1.0/items", methods=["POST"])
55+
def create_item():
56+
if not request.json or "name" not in request.json or "value" not in request.json:
57+
abort(400)
58+
item_id = items[0].get("id") + 1
59+
name = request.json.get("name")
60+
if _record_exists(name):
61+
abort(400)
62+
value = request.json.get("value")
63+
if type(value) is not int:
64+
abort(400)
65+
item = {"id": item_id, "name": name, "value": value}
66+
items.append(item)
67+
return jsonify({"item": item}), 201
68+
69+
70+
@app.route("/api/v1.0/items/<int:id>", methods=["PUT"])
71+
def update_item(id):
72+
item = _get_item(id)
73+
if len(item) == 0:
74+
abort(404)
75+
if not request.json:
76+
abort(400)
77+
name = request.json.get("name", item[0]["name"])
78+
value = request.json.get("value", item[0]["value"])
79+
if type(value) is not int:
80+
abort(400)
81+
item[0]["name"] = name
82+
item[0]["value"] = value
83+
return jsonify({"item": item[0]}), 200
84+
85+
86+
@app.route("/api/v1.0/items/<int:id>", methods=["DELETE"])
87+
def delete_item(id):
88+
item = _get_item(id)
89+
if len(item) == 0:
90+
abort(404)
91+
items.remove(item[0])
92+
return jsonify({}), 204
93+
94+
95+
if __name__ == "__main__":
96+
app.run(debug=True)

39/pavelekshin/curl.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import os
2+
3+
tests = """
4+
# get items
5+
curl -i http://127.0.0.1:5000/api/v1.0/items
6+
# item 1
7+
curl -i http://127.0.0.1:5000/api/v1.0/items/1
8+
# item2
9+
curl -i http://127.0.0.1:5000/api/v1.0/items/2
10+
# err: non-existing item
11+
curl -i http://127.0.0.1:5000/api/v1.0/items/4
12+
# err: add item already in items
13+
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"book", "value": 20}' http://127.0.0.1:5000/api/v1.0/items
14+
# err: add item with value not int
15+
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"monitor", "value": "200"}' http://127.0.0.1:5000/api/v1.0/items
16+
# add item with proper values
17+
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"monitor", "value": 200}' http://127.0.0.1:5000/api/v1.0/items
18+
# show items
19+
curl -i http://127.0.0.1:5000/api/v1.0/items
20+
# err: edit non-existing item
21+
curl -i -H "Content-Type: application/json" -X PUT -d '{"value": 30}' http://127.0.0.1:5000/api/v1.0/items/5
22+
# OK: edit existing item
23+
curl -i -H "Content-Type: application/json" -X PUT -d '{"value": 30}' http://127.0.0.1:5000/api/v1.0/items/3
24+
# show items
25+
curl -i http://127.0.0.1:5000/api/v1.0/items
26+
# err: delete non-existing item
27+
curl -i -H "Content-Type: application/json" -X DELETE http://127.0.0.1:5000/api/v1.0/items/5
28+
# OK: delete existing item
29+
curl -i -H "Content-Type: application/json" -X DELETE http://127.0.0.1:5000/api/v1.0/items/3
30+
# show items
31+
curl -i http://127.0.0.1:5000/api/v1.0/items
32+
"""
33+
34+
for line in tests.strip().split("\n"):
35+
print("\n{}".format(line))
36+
if not line.startswith("#"):
37+
cmd = line.strip()
38+
os.system(cmd)

39/pavelekshin/test_app.py

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import pytest
2+
import json
3+
4+
from app import app
5+
6+
BASE_URL = "http://127.0.0.1:5000/api/v1.0/items"
7+
BAD_ITEM_URL = "{}/5".format(BASE_URL)
8+
GOOD_ITEM_URL = "{}/3".format(BASE_URL)
9+
10+
11+
def setUp():
12+
backup_items = deepcopy(app.items)
13+
app = app.test_client()
14+
assert app.testing == False
15+
16+
17+
def test_get_items():
18+
with app.test_client() as tc:
19+
# get items
20+
response = tc.get(BASE_URL)
21+
assert response.status_code == 200
22+
data = json.loads(response.data)
23+
# items count in response
24+
assert len(data["items"]) == 3
25+
26+
27+
def test_get_item():
28+
with app.test_client() as tc:
29+
# get one non exist item
30+
response = tc.get(BAD_ITEM_URL)
31+
assert response.status_code == 404
32+
# get one exist item
33+
response = tc.get(GOOD_ITEM_URL)
34+
data = json.loads(response.data)
35+
assert response.status_code == 200
36+
assert len(data["items"]) == 1
37+
38+
39+
def test_not_found():
40+
with app.test_client() as tc:
41+
response = tc.get(BAD_ITEM_URL)
42+
assert response.status_code == 404
43+
44+
45+
def test_bad_request():
46+
item = {"name": "laptop", "some-value": "1000"}
47+
# item wrong request body
48+
with app.test_client() as tc:
49+
response = tc.post(
50+
BASE_URL, data=json.dumps(item), content_type="application/json"
51+
)
52+
assert response.status_code == 400
53+
54+
55+
def test_create_item():
56+
with app.test_client() as tc:
57+
# wrong request body
58+
item = {"name": "laptop", "some-value": "1000"}
59+
response = tc.post(
60+
BASE_URL, data=json.dumps(item), content_type="application/json"
61+
)
62+
assert response.status_code == 400
63+
# item exist
64+
item = {"name": "laptop", "value": int(1)}
65+
response = tc.post(
66+
BASE_URL, data=json.dumps(item), content_type="application/json"
67+
)
68+
assert response.status_code == 400
69+
# item wrong request value type
70+
item = {"name": "monitor", "value": str(1)}
71+
response = tc.post(
72+
BASE_URL, data=json.dumps(item), content_type="application/json"
73+
)
74+
assert response.status_code == 400
75+
# create item
76+
item = {"name": "printer", "value": 100}
77+
reponse = tc.post(
78+
BASE_URL, data=json.dumps(item), content_type="application/json"
79+
)
80+
81+
82+
def test_update_item():
83+
item = {"name": "laptop", "some-value": "1000"}
84+
# item wrong request body
85+
with app.test_client() as tc:
86+
response = tc.post(
87+
BASE_URL, data=json.dumps(item), content_type="application/json"
88+
)
89+
assert response.status_code == 400
90+
91+
92+
def test_update_item():
93+
with app.test_client() as tc:
94+
# update non exist item
95+
response = tc.put(BAD_ITEM_URL)
96+
assert response.status_code == 404
97+
# empty request body
98+
response = tc.put(
99+
GOOD_ITEM_URL, data=json.dumps({}), content_type="application/json"
100+
)
101+
assert response.status_code == 400
102+
# request body contains str instead of int value
103+
response = tc.put(
104+
GOOD_ITEM_URL,
105+
data=json.dumps({"name": "book", "value": str(10)}),
106+
content_type="application/json",
107+
)
108+
assert response.status_code == 400
109+
# correct request
110+
response = tc.put(
111+
GOOD_ITEM_URL,
112+
data=json.dumps({"name": "book", "value": int(10)}),
113+
content_type="application/json",
114+
)
115+
assert response.status_code == 200
116+
117+
118+
def test_delete_item():
119+
with app.test_client() as tc:
120+
# delete non exist item
121+
response = tc.delete(BAD_ITEM_URL)
122+
assert response.status_code == 404
123+
# delete exist item
124+
response = tc.delete(GOOD_ITEM_URL)
125+
assert response.status_code == 204
126+
127+
128+
def setDown():
129+
# reset state
130+
app.items = backup_items

0 commit comments

Comments
 (0)