diff --git a/.gitignore b/.gitignore index 597be97..391f3a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ __pycache__ test.db +.coverage +report.xml +coverage.xml \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8b9a1f0 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +ENV=dev +VER=2 +TAG=${ENV}-${VER} +REGISTRY=kube-reg.fairfaxmedia.net +SVC=papi/svc1 +DOCK_IMG=${REGISTRY}/${SVC}:${TAG} +clean: + rm -rf .pytest_cache + rm -rf .coverage + rm -rf report.xml + rm -rf test.db +coverage: clean + pytest --cov=papi test_papi.py --junitxml=report.xml --cov-report=html --cov-report=xml --cov-report=term --cov-fail-under 90 +docker-img: coverage + docker build -t ${DOCK_IMG} . +docker-push: docker-img + docker push ${DOCK_IMG} +deploy: docker-push + helm upgrade papi ./papi-helm/ -f ./papi-helm/v.${ENV}.yaml --set image.tag=${TAG} \ No newline at end of file diff --git a/hopscotch_collection.json b/hopscotch_collection.json new file mode 100644 index 0000000..42c3ab5 --- /dev/null +++ b/hopscotch_collection.json @@ -0,0 +1 @@ +{"v":1,"name":"test_assignment","folders":[{"v":1,"name":"users","folders":[],"requests":[{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/users","name":"list_users","params":[],"headers":[],"method":"GET","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":null,"body":null}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/users","name":"create_user","params":[],"headers":[],"method":"POST","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"name\":\"test2\",\n \"email\":\"mynameisdeleted@gmail.com\",\n \"password\":\"pass2\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/users/1","name":"update_user","params":[],"headers":[],"method":"PUT","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"name\":\"new name\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/users/1","name":"delete_user","params":[],"headers":[],"method":"DELETE","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"name\":\"new name\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/users/1","name":"get_user","params":[],"headers":[],"method":"GET","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":null,"body":null}}]},{"v":1,"name":"posts","folders":[],"requests":[{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/posts","name":"list_posts","params":[],"headers":[],"method":"GET","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"name\":\"new name\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/posts","name":"create_post","params":[],"headers":[],"method":"POST","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"title\":\"test title\",\n \"content\":\"testing123\",\n \"author_id\":\"1\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/posts/1","name":"get_post","params":[],"headers":[],"method":"GET","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"name\":\"new name\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/posts/1","name":"update_post","params":[],"headers":[],"method":"PUT","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"title\":\"new title\"\n}"}},{"v":"1","endpoint":"https://papi.kube-dev.fairfaxmedia.net/posts/1","name":"delete_post","params":[],"headers":[],"method":"DELETE","auth":{"authType":"none","authActive":true},"preRequestScript":"","testScript":"","body":{"contentType":"application/json","body":"{\n \"title\":\"new title\"\n}"}}]}],"requests":[]} \ No newline at end of file diff --git a/papi.py b/papi.py index 3b4fbd9..4925f3c 100644 --- a/papi.py +++ b/papi.py @@ -2,9 +2,8 @@ from fastapi import FastAPI, Depends import uvicorn from sqlalchemy import create_engine, Column, Integer,String, ForeignKey -from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.engine import URL -from sqlalchemy.orm import sessionmaker, Session +from sqlalchemy.orm import sessionmaker, Session, declarative_base @@ -30,6 +29,7 @@ class User(Base): email = Column(String, unique=True, index=True) password = Column(String) + class Post(Base): __tablename__ = "posts" id = Column(Integer, primary_key=True, index=True) @@ -50,10 +50,11 @@ async def root(): @app.get("/users") async def get_users(db: Session = Depends(get_db)): return db.query(User).all() - #return [{"id":"asdf1234"}] + @app.get("/users/{id}") -async def get_user(id: str): - return {"id": id} +async def get_user(id: str,db: Session = Depends(get_db)): + db_user = db.query(User).filter(User.id == id).first() + return db_user @app.post("/users") async def create_user(user: dict,db: Session = Depends(get_db)): @@ -64,6 +65,30 @@ async def create_user(user: dict,db: Session = Depends(get_db)): db.refresh(db_user) return {"message":"User created successfully","user":db_user} +@app.put("/users/{id}") +async def update_user(id: str, user: dict,db: Session = Depends(get_db)): + db_user = db.query(User).filter(User.id == id).first() + if "name" in user: + db_user.name = user["name"] + if "email" in user: + db_user.email = user["email"] + if "password" in user: + db_user.password = user["password"] + db.commit() + db.refresh(db_user) + return {"message":"User updated successfully","user":db_user} + + + +@app.delete("/users/{id}") +async def delete_user(id: str, db: Session = Depends(get_db)): + db_user = db.query(User).filter(User.id == id).first() + db.delete(db_user) + db.commit() + return {"message":"User deleted successfully","user":db_user} + + + @app.get("/posts") async def get_posts(db: Session = Depends(get_db)): return db.query(Post).all() @@ -93,18 +118,13 @@ async def update_post(id: str, post: dict,db: Session = Depends(get_db)): return {"message":"Post updated successfully","post":db_post} @app.delete("/posts/{id}") -async def delete_post(id: str, post: dict,db: Session = Depends(get_db)): +async def delete_post(id: str, db: Session = Depends(get_db)): db_post = db.query(Post).filter(Post.id == id).first() db.delete(db_post) db.commit() return {"message":"Post deleted successfully","post":db_post} -@app.get("/hello/{name}") -async def say_hello(name: str): - return {"message": f"Hello {name}"} - - if __name__ == "__main__": uvicorn.run("papi:app", host="0.0.0.0", port=8912, reload=True, log_level="debug", diff --git a/test_papi.py b/test_papi.py index a244f7d..3856a74 100644 --- a/test_papi.py +++ b/test_papi.py @@ -2,11 +2,78 @@ from fastapi.testclient import TestClient -import papi -client = TestClient(papi) +from papi import app +client = TestClient(app) def test_read_main(): response = client.get("/") assert response.status_code == 200 - assert response.json() == {"message": "Hello World"} \ No newline at end of file + assert response.json() == {"message": "Hello World"} + +def test_read_users(): + response = client.get("/users") + assert response.status_code == 200 + assert response.json() == [] + + +def test_create_read_delete_user(): + + response = client.post("/users",json={"name":"test","email":"mynameisdeleted@gmail.com","password":"pass2"}) + assert response.status_code == 200 + user=response.json()['user'] + user_id = str(user['id']) + response = client.get("/users/"+user_id) + assert response.status_code == 200 + assert response.json() == user + + update_response = client.put("/users/"+user_id,json={"name":"updated name"}) + #assert update_respose.status_code == 200 + put_user = update_response.json()['user'] + assert put_user['name'] == "updated name" + + update_response = client.put("/users/"+user_id,json={"email":"updated@gmail.com"}) + + put_user = update_response.json()['user'] + assert put_user['email'] == "updated@gmail.com" + + + response = client.delete("/users/"+user_id) + assert response.status_code == 200 + + response = client.get("/users") + assert response.status_code == 200 + assert response.json() == [] + + + + +def test_create_read_delete_post(): + + + response = client.post("/posts",json={"title":"test title","content":"testing123","author_id":"1"}) + assert response.status_code == 200 + post=response.json()['post'] + post_id = str(post['id']) + response = client.get("/posts/"+post_id) + assert response.status_code == 200 + assert response.json() == post + + update_response = client.put("/posts/"+post_id,json={"title":"test title updated"}) + #assert update_respose.status_code == 200 + put_post = update_response.json()['post'] + assert put_post['title'] == "test title updated" + + + update_response = client.put("/posts/"+post_id,json={"content":"updated content"}) + #assert update_respose.status_code == 200 + put_post = update_response.json()['post'] + assert put_post['title'] == "test title updated" + assert put_post['content'] == "updated content" + + response = client.delete("/posts/"+post_id) + assert response.status_code == 200 + + response = client.get("/posts") + assert response.status_code == 200 + assert response.json() == [] \ No newline at end of file