Skip to content

Commit

Permalink
PCC39 pavelekshin
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelekshin committed Mar 26, 2023
1 parent 3ec88e0 commit 331a018
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 0 deletions.
Binary file added 39/pavelekshin/.app.py.swo
Binary file not shown.
Binary file added 39/pavelekshin/.coverage
Binary file not shown.
Binary file added 39/pavelekshin/.test_app.py.un~
Binary file not shown.
96 changes: 96 additions & 0 deletions 39/pavelekshin/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from flask import Flask, jsonify, abort, make_response, request

NOT_FOUND = "Not found"
BAD_REQUEST = "Bad request"

app = Flask(__name__)

items = [
{"id": 1, "name": "laptop", "value": 1000},
{
"id": 2,
"name": "chair",
"value": 300,
},
{
"id": 3,
"name": "book",
"value": 20,
},
]


def _get_item(id):
return [item for item in items if item["id"] == id]


def _record_exists(name):
return [item for item in items if item["name"] == name]


@app.errorhandler(404)
def not_found(error):
return make_response(jsonify({"error": NOT_FOUND}), 404)


@app.errorhandler(400)
def bad_request(error):
return make_response(jsonify({"error": BAD_REQUEST}), 400)


@app.route("/api/v1.0/items", methods=["GET"])
def get_items():
return jsonify({"items": items})


@app.route("/api/v1.0/items/<int:id>", methods=["GET"])
def get_item(id):
item = _get_item(id)
if not item:
abort(404)
return jsonify({"items": item})


@app.route("/api/v1.0/items", methods=["POST"])
def create_item():
if not request.json or "name" not in request.json or "value" not in request.json:
abort(400)
item_id = items[0].get("id") + 1
name = request.json.get("name")
if _record_exists(name):
abort(400)
value = request.json.get("value")
if type(value) is not int:
abort(400)
item = {"id": item_id, "name": name, "value": value}
items.append(item)
return jsonify({"item": item}), 201


@app.route("/api/v1.0/items/<int:id>", methods=["PUT"])
def update_item(id):
item = _get_item(id)
if len(item) == 0:
abort(404)
if not request.json:
abort(400)
name = request.json.get("name", item[0]["name"])
value = request.json.get("value", item[0]["value"])
if type(value) is not int:
abort(400)
item[0]["name"] = name
item[0]["value"] = value
return jsonify({"item": item[0]}), 200


@app.route("/api/v1.0/items/<int:id>", methods=["DELETE"])
def delete_item(id):
item = _get_item(id)
if len(item) == 0:
abort(404)
items.remove(item[0])
return jsonify({}), 204


if __name__ == "__main__":
app.run(debug=True)
38 changes: 38 additions & 0 deletions 39/pavelekshin/curl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import os

tests = """
# get items
curl -i http://127.0.0.1:5000/api/v1.0/items
# item 1
curl -i http://127.0.0.1:5000/api/v1.0/items/1
# item2
curl -i http://127.0.0.1:5000/api/v1.0/items/2
# err: non-existing item
curl -i http://127.0.0.1:5000/api/v1.0/items/4
# err: add item already in items
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"book", "value": 20}' http://127.0.0.1:5000/api/v1.0/items
# err: add item with value not int
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"monitor", "value": "200"}' http://127.0.0.1:5000/api/v1.0/items
# add item with proper values
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"monitor", "value": 200}' http://127.0.0.1:5000/api/v1.0/items
# show items
curl -i http://127.0.0.1:5000/api/v1.0/items
# err: edit non-existing item
curl -i -H "Content-Type: application/json" -X PUT -d '{"value": 30}' http://127.0.0.1:5000/api/v1.0/items/5
# OK: edit existing item
curl -i -H "Content-Type: application/json" -X PUT -d '{"value": 30}' http://127.0.0.1:5000/api/v1.0/items/3
# show items
curl -i http://127.0.0.1:5000/api/v1.0/items
# err: delete non-existing item
curl -i -H "Content-Type: application/json" -X DELETE http://127.0.0.1:5000/api/v1.0/items/5
# OK: delete existing item
curl -i -H "Content-Type: application/json" -X DELETE http://127.0.0.1:5000/api/v1.0/items/3
# show items
curl -i http://127.0.0.1:5000/api/v1.0/items
"""

for line in tests.strip().split("\n"):
print("\n{}".format(line))
if not line.startswith("#"):
cmd = line.strip()
os.system(cmd)
130 changes: 130 additions & 0 deletions 39/pavelekshin/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import pytest
import json

from app import app

BASE_URL = "http://127.0.0.1:5000/api/v1.0/items"
BAD_ITEM_URL = "{}/5".format(BASE_URL)
GOOD_ITEM_URL = "{}/3".format(BASE_URL)


def setUp():
backup_items = deepcopy(app.items)
app = app.test_client()
assert app.testing == False


def test_get_items():
with app.test_client() as tc:
# get items
response = tc.get(BASE_URL)
assert response.status_code == 200
data = json.loads(response.data)
# items count in response
assert len(data["items"]) == 3


def test_get_item():
with app.test_client() as tc:
# get one non exist item
response = tc.get(BAD_ITEM_URL)
assert response.status_code == 404
# get one exist item
response = tc.get(GOOD_ITEM_URL)
data = json.loads(response.data)
assert response.status_code == 200
assert len(data["items"]) == 1


def test_not_found():
with app.test_client() as tc:
response = tc.get(BAD_ITEM_URL)
assert response.status_code == 404


def test_bad_request():
item = {"name": "laptop", "some-value": "1000"}
# item wrong request body
with app.test_client() as tc:
response = tc.post(
BASE_URL, data=json.dumps(item), content_type="application/json"
)
assert response.status_code == 400


def test_create_item():
with app.test_client() as tc:
# wrong request body
item = {"name": "laptop", "some-value": "1000"}
response = tc.post(
BASE_URL, data=json.dumps(item), content_type="application/json"
)
assert response.status_code == 400
# item exist
item = {"name": "laptop", "value": int(1)}
response = tc.post(
BASE_URL, data=json.dumps(item), content_type="application/json"
)
assert response.status_code == 400
# item wrong request value type
item = {"name": "monitor", "value": str(1)}
response = tc.post(
BASE_URL, data=json.dumps(item), content_type="application/json"
)
assert response.status_code == 400
# create item
item = {"name": "printer", "value": 100}
reponse = tc.post(
BASE_URL, data=json.dumps(item), content_type="application/json"
)


def test_update_item():
item = {"name": "laptop", "some-value": "1000"}
# item wrong request body
with app.test_client() as tc:
response = tc.post(
BASE_URL, data=json.dumps(item), content_type="application/json"
)
assert response.status_code == 400


def test_update_item():
with app.test_client() as tc:
# update non exist item
response = tc.put(BAD_ITEM_URL)
assert response.status_code == 404
# empty request body
response = tc.put(
GOOD_ITEM_URL, data=json.dumps({}), content_type="application/json"
)
assert response.status_code == 400
# request body contains str instead of int value
response = tc.put(
GOOD_ITEM_URL,
data=json.dumps({"name": "book", "value": str(10)}),
content_type="application/json",
)
assert response.status_code == 400
# correct request
response = tc.put(
GOOD_ITEM_URL,
data=json.dumps({"name": "book", "value": int(10)}),
content_type="application/json",
)
assert response.status_code == 200


def test_delete_item():
with app.test_client() as tc:
# delete non exist item
response = tc.delete(BAD_ITEM_URL)
assert response.status_code == 404
# delete exist item
response = tc.delete(GOOD_ITEM_URL)
assert response.status_code == 204


def setDown():
# reset state
app.items = backup_items

0 comments on commit 331a018

Please sign in to comment.