Skip to content
Snippets Groups Projects
Commit adb9c371 authored by Carl Schönfelder's avatar Carl Schönfelder
Browse files

Resolve "Add more api-methods"

parent 6378858b
No related branches found
No related tags found
1 merge request!36Resolve "Add more api-methods"
Pipeline #38507 passed
Showing with 280 additions and 107 deletions
......@@ -38,13 +38,11 @@ def object_response(items, code=200):
from flask_restx import Api
from .auth import api as ns2
from .competitions import api as ns4
from .slides import api as ns3
from .users import api as ns1
from .auth import api as auth_ns
from .competitions import api as comp_ns
from .users import api as user_ns
flask_api = Api()
flask_api.add_namespace(ns1, path="/api/users")
flask_api.add_namespace(ns3, path="/api/slides")
flask_api.add_namespace(ns2, path="/api/auth")
flask_api.add_namespace(ns4, path="/api/competitions")
flask_api.add_namespace(user_ns, path="/api/users")
flask_api.add_namespace(auth_ns, path="/api/auth")
flask_api.add_namespace(comp_ns, path="/api/competitions")
import app.core.controller as dbc
import app.core.utils.http_codes as codes
from app.apis import admin_required
from app.core.dto import AuthDTO
from app.core.models import User
from app.core.parsers import create_user_parser, login_parser
from flask_jwt_extended import (
......@@ -13,7 +14,8 @@ from flask_jwt_extended import (
)
from flask_restx import Namespace, Resource, cors
api = Namespace("auth")
api = AuthDTO.api
user_model = AuthDTO.model
def get_user_claims(item_user):
......@@ -28,13 +30,13 @@ class AuthSignup(Resource):
args = create_user_parser.parse_args(strict=True)
email = args.get("email")
password = args.get("password")
role = args.get("role")
city = args.get("city")
role_id = args.get("role_id")
city_id = args.get("city_id")
if User.query.filter(User.email == email).count() > 0:
api.abort(codes.BAD_REQUEST, "User already exists")
item_user = dbc.add.user(email, password, role, city)
item_user = dbc.add.default(User(email, password, role_id, city_id))
if not item_user:
api.abort(codes.BAD_REQUEST, "User could not be created")
......@@ -48,7 +50,7 @@ class AuthDelete(Resource):
@cors.crossdomain(origin="*")
def delete(self, ID):
item_user = User.query.filter(User.id == ID).first()
dbc.delete(item_user)
dbc.delete.default(item_user)
if ID == get_jwt_identity():
jti = get_raw_jwt()["jti"]
dbc.add.blacklist(jti)
......
import app.core.controller as dbc
import app.core.utils.http_codes as codes
from app.apis import admin_required
from app.core.models import Competition, User
from app.core.dto import CompetitionDTO
from app.core.models import Competition, Slide, Team
from app.core.parsers import competition_parser, competition_search_parser
from app.core.schemas import competition_schema
from flask_jwt_extended import get_jwt_identity, jwt_required
from flask_restx import Namespace, Resource
from flask_restx import Resource, reqparse
api = Namespace("competitions")
competition_model = api.model(*competition_schema)
api = CompetitionDTO.api
competition_model = CompetitionDTO.model
slide_model = CompetitionDTO.slide_model
team_model = CompetitionDTO.team_model
def get_comp(CID):
return Competition.query.filter(Competition.id == CID).first()
@api.route("/")
class CompetitionBase(Resource):
class CompetitionsList(Resource):
@jwt_required
@api.marshal_with(competition_model)
def post(self):
......@@ -24,7 +30,7 @@ class CompetitionBase(Resource):
style_id = args.get("style_id")
# Add competition
item_competition = dbc.add.competition(name, year, style_id, city_id)
item_competition = dbc.add.default(Competition(name, year, style_id, city_id))
# Add default slide
item_slide = dbc.add.slide(item_competition.id)
......@@ -34,11 +40,11 @@ class CompetitionBase(Resource):
@api.route("/<ID>")
@api.param("ID")
class CompetitionByID(Resource):
class Competitions(Resource):
@jwt_required
@api.marshal_with(competition_model)
def get(self, ID):
item = Competition.query.filter(Competition.id == ID).first()
item = get_comp(ID)
return item
@jwt_required
......@@ -46,7 +52,7 @@ class CompetitionByID(Resource):
def put(self, ID):
args = competition_parser.parse_args(strict=True)
item = Competition.query.filter(Competition.id == ID).first()
item = get_comp(ID)
name = args.get("name")
year = args.get("year")
city_id = args.get("city_id")
......@@ -55,8 +61,8 @@ class CompetitionByID(Resource):
@jwt_required
def delete(self, ID):
item = Competition.query.filter(Competition.id == ID).first()
dbc.delete(item)
item = get_comp(ID)
dbc.delete.competition(item)
return "deleted"
......@@ -73,3 +79,73 @@ class CompetitionSearch(Resource):
page = args.get("page")
page_size = args.get("page_size")
return dbc.get.search_competitions(name, year, city_id, style_id, page, page_size)
@api.route("/<CID>/slides")
@api.param("CID")
class SlidesList(Resource):
@jwt_required
@api.marshal_with(slide_model)
def get(self, CID):
item_comp = get_comp(CID)
return item_comp.slides
@jwt_required
@api.marshal_with(slide_model)
def post(self, CID):
dbc.add.slide(CID)
item_comp = get_comp(CID)
return item_comp.slides
@api.route("/<CID>/slides/<SID>")
@api.param("CID,SID")
class Slides(Resource):
@jwt_required
@api.marshal_with(slide_model)
def get(self, CID, SID):
item_slide = dbc.get.slide(CID, SID)
return item_slide
@jwt_required
def delete(self, CID, SID):
item_slide = dbc.get.slide(CID, SID)
dbc.delete.slide(item_slide)
return "deleted"
@api.route("/<CID>/teams")
@api.param("CID")
class TeamsList(Resource):
@jwt_required
@api.marshal_with(team_model)
def get(self, CID):
item_comp = get_comp(CID)
return item_comp.teams
@jwt_required
@api.marshal_with(team_model)
def post(self, CID):
parser = reqparse.RequestParser()
parser.add_argument("name", type=str, location="json")
args = competition_parser.parse_args(strict=True)
dbc.add.default(Team(args["name"], CID))
item_comp = get_comp(CID)
return item_comp.teams
@api.route("/<CID>/teams/<TID>")
@api.param("CID,TID")
class Teams(Resource):
@jwt_required
@api.marshal_with(team_model)
def get(self, CID, TID):
item_team = dbc.get.team(CID, TID)
return item_team
@jwt_required
def delete(self, CID, TID):
item_team = dbc.get.team(CID, TID)
dbc.delete.team(item_team)
return "deleted"
from flask_restx import Namespace, Resource, fields
api = Namespace("slides")
import app.core.controller as dbc
import app.core.utils.http_codes as codes
from app.apis import admin_required
from app.core.models import Competition, Slide, User
from app.core.parsers import competition_parser, competition_search_parser
from app.core.schemas import competition_schema
from flask_jwt_extended import get_jwt_identity, jwt_required
from flask_restx import Namespace, Resource
import app.core.controller as dbc
import app.core.utils.http_codes as codes
from app.apis import admin_required
from app.core.dto import UserDTO
from app.core.models import User
from app.core.parsers import user_parser, user_search_parser
from app.core.schemas import user_schema
from flask_jwt_extended import get_jwt_identity, jwt_required
from flask_restx import Namespace, Resource
api = Namespace("users")
user_model = api.model(*user_schema)
api = UserDTO.api
user_model = UserDTO.model
def edit_user(item_user, args):
email = args.get("email")
name = args.get("name")
city = args.get("city")
role = args.get("role")
city_id = args.get("city_id")
role_id = args.get("role_id")
if email:
if User.query.filter(User.email == args["email"]).count() > 0:
api.abort(codes.BAD_REQUEST, "Email is already in use")
return dbc.edit.user(item_user, name, email, city, role)
return dbc.edit.user(item_user, name, email, city_id, role_id)
@api.route("/")
class UserBase(Resource):
class UsersList(Resource):
@jwt_required
@api.marshal_list_with(user_model)
def get(self):
......@@ -41,7 +42,7 @@ class UserBase(Resource):
@api.route("/<ID>")
@api.param("ID")
class UserByID(Resource):
class Users(Resource):
@jwt_required
@api.marshal_with(user_model)
def get(self, ID):
......@@ -63,9 +64,9 @@ class UserSearch(Resource):
args = user_search_parser.parse_args(strict=True)
name = args.get("name")
email = args.get("email")
role = args.get("role")
city = args.get("city")
role_id = args.get("role_id")
city_id = args.get("city_id")
page = args.get("page", 1)
page_size = args.get("page_size", 15)
return dbc.get.search_user(email, name, city, role, page, page_size)
return dbc.get.search_user(email, name, city_id, role_id, page, page_size)
# import add, get
from app.core import db
from app.core.controller import add, edit, get
def delete(item):
db.session.delete(item)
db.session.commit()
from app.core.controller import add, delete, edit, get
......@@ -2,35 +2,22 @@ from app.core import db
from app.core.models import Blacklist, City, Competition, Role, Slide, User
def blacklist(jti):
db.session.add(Blacklist(jti))
db.session.commit()
def user(email, plaintext_password, role, city):
item_role = Role.query.filter(Role.name == role).first()
item_city = City.query.filter(City.name == city).first()
new_user = User(email, plaintext_password, item_role.id, item_city.id)
db.session.add(new_user)
def default(item):
db.session.add(item)
db.session.commit()
db.session.refresh(item)
return item
return User.query.filter(User.email == email).first()
def competition(name, year, style_id, city_id):
db.session.add(Competition(name, year, style_id, city_id))
def blacklist(jti):
db.session.add(Blacklist(jti))
db.session.commit()
filters = (Competition.name == name) & (Competition.city_id == city_id)
return Competition.query.filter(filters).first()
def slide(competition_id):
# item_slides = Slide.query.filter(Slide.competition_id == competition_id).order_by(Slide.order).all()
order = Slide.query.filter(Slide.competition_id == competition_id).count()
db.session.add(Slide(order, competition_id))
item = Slide(order, competition_id)
db.session.add(item)
db.session.commit()
filters = (Slide.order == order) & (Slide.competition_id == competition_id)
return Slide.query.filter(filters).first()
db.session.refresh(item)
return item
from app.core import db
from app.core.models import Blacklist, City, Competition, Role, Slide, User
def default(item):
db.session.delete(item)
db.session.commit()
def slide(item):
default(item)
def team(item):
default(item)
def competition(item):
# Remove all slides from competition
for item_slide in item.slides:
slide(item_slide)
# Remove all teams from competition
for item_team in item.teams:
team(item_team)
default(item)
......@@ -17,7 +17,7 @@ def competition(item, name=None, year=None, city_id=None, style_id=None):
return item
def user(item, name=None, email=None, city=None, role=None):
def user(item, name=None, email=None, city_id=None, role_id=None):
if name:
item.name = name.title()
......@@ -25,13 +25,11 @@ def user(item, name=None, email=None, city=None, role=None):
if email:
item.email = email
if city:
item_city = City.query.filter(City.name == city).first()
item.city_id = item_city.id
if city_id:
item.city_id = city_id
if role:
item_role = Role.query.filter(Role.name == role).first()
item.role_id = item_role.id
if role_id:
item.role_id = role_id
db.session.commit()
db.session.refresh(item)
......
from app.core.models import Competition, User
from app.core.models import Competition, Slide, Team, User
def search_user(email=None, name=None, city=None, role=None, page=1, page_size=15):
def slide(CID, SID):
return Slide.query.filter((Slide.competition_id == CID) & (Slide.id == SID)).first()
def team(CID, TID):
return Team.query.filter((Team.competition_id == CID) & (Team.id == TID)).first()
def search_user(email=None, name=None, city_id=None, role_id=None, page=1, page_size=15):
query = User.query
if name:
query = query.filter(User.name.like(f"%{name}%"))
if email:
query = query.filter(User.email.like(f"%{email}%"))
if city:
query = query.filter(User.city.name == city)
if role:
query = query.filter(User.role.name == role)
if city_id:
query = query.filter(User.city_id == city_id)
if role_id:
query = query.filter(User.role_id == role_id)
query = query.limit(page_size).offset(page * page_size)
......
from app.apis import slides
from flask_restx import Namespace, fields
class AuthDTO:
api = Namespace("auth")
model = api.model("Auth", {"id": fields.Integer()})
class UserDTO:
api = Namespace("users")
model = api.model(
"User",
{
"id": fields.Integer(),
"name": fields.String(),
"email": fields.String(),
"role_id": fields.Integer(),
"city_id": fields.Integer(),
},
)
class CompetitionDTO:
api = Namespace("competitions")
model = api.model(
"Competition",
{
"id": fields.Integer(),
"name": fields.String(),
"year": fields.Integer(),
"style_id": fields.Integer(),
"city_id": fields.Integer(),
},
)
slide_model = api.model(
"Slide",
{
"id": fields.Integer(),
"competition_id": fields.Integer(),
"order": fields.Integer(),
},
)
team_model = api.model(
"Team", {"id": fields.Integer(), "name": fields.String(), "competition_id": fields.Integer()}
)
......@@ -13,27 +13,27 @@ login_parser.add_argument("password", required=True, location="json")
###CREATE_USER####
create_user_parser = login_parser.copy()
create_user_parser.add_argument("email", type=inputs.email(), required=True, location="json")
create_user_parser.add_argument("city", required=True, location="json")
create_user_parser.add_argument("role", required=True, location="json")
create_user_parser.add_argument("city_id", type=int, required=True, location="json")
create_user_parser.add_argument("role_id", type=int, required=True, location="json")
###USER####
user_parser = reqparse.RequestParser()
user_parser.add_argument("email", type=inputs.email(), location="json")
user_parser.add_argument("name", location="json")
user_parser.add_argument("city", location="json")
user_parser.add_argument("role", location="json")
user_parser.add_argument("name", type=str, location="json")
user_parser.add_argument("city_id", type=int, location="json")
user_parser.add_argument("role_id", type=int, location="json")
###SEARCH_USER####
user_search_parser = search_parser.copy()
user_search_parser.add_argument("name", default=None, location="args")
user_search_parser.add_argument("email", default=None, location="args")
user_search_parser.add_argument("city", default=None, location="args")
user_search_parser.add_argument("role", default=None, location="args")
user_search_parser.add_argument("name", type=str, default=None, location="args")
user_search_parser.add_argument("email", type=str, default=None, location="args")
user_search_parser.add_argument("city_id", type=int, default=None, location="args")
user_search_parser.add_argument("role_id", type=int, default=None, location="args")
###COMPETIION####
competition_parser = reqparse.RequestParser()
competition_parser.add_argument("name", location="json")
competition_parser.add_argument("name", type=str, location="json")
competition_parser.add_argument("year", type=int, location="json")
competition_parser.add_argument("city_id", type=int, location="json")
competition_parser.add_argument("style_id", type=int, location="json")
......@@ -41,7 +41,7 @@ competition_parser.add_argument("style_id", type=int, location="json")
###SEARCH_COMPETITOIN####
competition_search_parser = search_parser.copy()
competition_search_parser.add_argument("name", default=None, location="args")
competition_search_parser.add_argument("year", default=None, location="args")
competition_search_parser.add_argument("city_id", default=None, location="args")
competition_search_parser.add_argument("style_id", default=None, location="args")
competition_search_parser.add_argument("name", type=str, default=None, location="args")
competition_search_parser.add_argument("year", type=str, default=None, location="args")
competition_search_parser.add_argument("city_id", type=int, default=None, location="args")
competition_search_parser.add_argument("style_id", type=int, default=None, location="args")
......@@ -6,8 +6,8 @@ user_schema = (
"id": fields.Integer(),
"name": fields.String(),
"email": fields.String(),
"role": fields.String(attribute=lambda x: x.role.name),
"city": fields.String(attribute=lambda x: x.city.name),
"role_id": fields.Integer(),
"city_id": fields.Integer(),
},
)
......
......@@ -3,7 +3,7 @@ import json
import app.core.controller as dbc
import pytest
from app.core import db
from app.core.models import City, MediaType, QuestionType, Role, Style
from app.core.models import City, MediaType, QuestionType, Role, Style, User
def add_default_values():
......@@ -35,7 +35,15 @@ def add_default_values():
db.session.commit()
# Add user with role and city
dbc.add.user("test@test.se", "password", "Admin", "Linköping")
dbc.add.default(User("test@test.se", "password", 1, 1))
def get_body(response):
try:
body = json.loads(response.data.decode())
except:
body = None
return body
def post(client, url, data, headers=None):
......@@ -43,13 +51,13 @@ def post(client, url, data, headers=None):
headers = {}
headers["Content-Type"] = "application/json"
response = client.post(url, data=json.dumps(data), headers=headers)
body = json.loads(response.data.decode())
body = get_body(response)
return response, body
def get(client, url, query_string=None, headers=None):
response = client.get(url, query_string=query_string, headers=headers)
body = json.loads(response.data.decode())
body = get_body(response)
return response, body
......@@ -59,13 +67,13 @@ def put(client, url, data, headers=None):
headers["Content-Type"] = "application/json"
response = client.put(url, data=json.dumps(data), headers=headers)
body = json.loads(response.data.decode())
body = get_body(response)
return response, body
def delete(client, url, data, headers=None):
response = client.delete(url, data=json.dumps(data), headers=headers)
body = json.loads(response.data.decode())
body = get_body(response)
return response, body
......
import app.core.controller as dbc
from app import create_app, db
from app.core.models import City, MediaType, QuestionType, Role, Style
from app.core.models import City, MediaType, QuestionType, Role, Style, User
user = {"email": "test@test.se", "password": "password", "role": "Admin", "city": "Linköping"}
media_types = ["Image", "Video"]
......@@ -38,7 +38,7 @@ def _add_items():
db.session.commit()
# Add user with role and city
dbc.add.user("test@test.se", "password", "Admin", "Linköping")
dbc.add.default(User("test@test.se", "password", 1, 1))
db.session.flush()
......
import json
from app.core.utils.test_helpers import add_default_values, get, post, put
from app.core.utils.test_helpers import add_default_values, delete, get, post, put
from tests import app, client, db
......@@ -24,6 +24,24 @@ def test_competition(client):
assert response.status_code == 200
assert body["name"] == "c1"
response, body = post(client, "/api/competitions/1/slides", {}, headers=headers)
assert response.status_code == 200
response, body = get(client, "/api/competitions/1/slides", headers=headers)
assert response.status_code == 200
assert len(body) == 2
response, body = post(client, "/api/competitions/1/teams", {"name": "t1"}, headers=headers)
assert response.status_code == 200
response, body = get(client, "/api/competitions/1/teams", headers=headers)
assert response.status_code == 200
assert len(body) == 1
assert body[0]["name"] == "t1"
response, body = delete(client, "/api/competitions/1", {}, headers=headers)
assert response.status_code == 200
def test_app(client):
add_default_values()
......@@ -34,9 +52,8 @@ def test_app(client):
headers = {"Authorization": "Bearer " + body["access_token"]}
# Create user
register_data = {"email": "test1@test.se", "password": "abc123", "role": "Admin", "city": "Linköping"}
register_data = {"email": "test1@test.se", "password": "abc123", "role_id": 2, "city_id": 1}
response, body = post(client, "/api/auth/signup", register_data, headers)
assert response.status_code == 200
assert body["id"] == 2
assert "password" not in body
......@@ -59,6 +76,11 @@ def test_app(client):
assert response.status_code == 200
assert body["email"] == "test1@test.se"
# Edit current user name
response, body = put(client, "/api/users", {"name": "carl carlsson"}, headers=headers)
assert response.status_code == 200
assert body["name"] == "Carl Carlsson"
# Delete created user
response, body = delete(client, "/api/auth/delete/1", {}, headers=headers)
assert response.status_code == 200
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment