From 8db228bf8fe8e3bbd5c5adcc00add9e8a611b268 Mon Sep 17 00:00:00 2001
From: robban64 <carl@schonfelder.se>
Date: Fri, 16 Apr 2021 19:23:59 +0200
Subject: [PATCH] fix: component and you now get all types by get misc/types

---
 server/app/apis/components.py            | 17 +++++++-
 server/app/apis/misc.py                  | 39 +++++++++--------
 server/app/core/dto.py                   |  3 ++
 server/app/core/parsers.py               |  5 ++-
 server/app/core/rich_schemas.py          |  1 +
 server/app/core/schemas.py               | 34 +++++++++------
 server/app/database/controller/add.py    | 16 ++++++-
 server/app/database/controller/delete.py |  4 ++
 server/app/database/controller/edit.py   | 17 ++++++++
 server/app/database/controller/get.py    | 23 +++++++++-
 server/app/database/models.py            | 45 +++++++-------------
 server/configmodule.py                   |  3 +-
 server/populate.py                       | 25 +++++++----
 server/tests/test_app.py                 | 53 ++++++++++--------------
 server/tests/test_helpers.py             | 30 ++++++++------
 15 files changed, 194 insertions(+), 121 deletions(-)

diff --git a/server/app/apis/components.py b/server/app/apis/components.py
index 73e2a907..da211895 100644
--- a/server/app/apis/components.py
+++ b/server/app/apis/components.py
@@ -1,7 +1,8 @@
+import app.core.http_codes as codes
 import app.database.controller as dbc
 from app.apis import admin_required, item_response, list_response
 from app.core.dto import ComponentDTO
-from app.core.parsers import component_parser
+from app.core.parsers import component_create_parser, component_parser
 from app.database.models import Competition
 from flask.globals import request
 from flask_jwt_extended import jwt_required
@@ -20,6 +21,18 @@ class ComponentByID(Resource):
         item = dbc.get.component(component_id)
         return item_response(schema.dump(item))
 
+    @jwt_required
+    def put(self, CID, SID, component_id):
+        args = component_parser.parse_args()
+        item = dbc.edit.component(**args)
+        return item_response(schema.dump(item))
+
+    @jwt_required
+    def delete(self, CID, SID, component_id):
+        item = dbc.get.component(component_id)
+        dbc.delete.component(item)
+        return {}, codes.NO_CONTENT
+
 
 @api.route("/")
 @api.param("CID, SID")
@@ -31,7 +44,7 @@ class ComponentList(Resource):
 
     @jwt_required
     def post(self, CID, SID):
-        args = component_parser.parse_args()
+        args = component_create_parser.parse_args()
         item_slide = dbc.get.slide(CID, SID)
         item = dbc.add.component(item_slide=item_slide, **args)
         return item_response(schema.dump(item))
diff --git a/server/app/apis/misc.py b/server/app/apis/misc.py
index 7fbb222d..b40f97a8 100644
--- a/server/app/apis/misc.py
+++ b/server/app/apis/misc.py
@@ -1,7 +1,7 @@
 import app.database.controller as dbc
 from app.apis import admin_required, item_response, list_response
 from app.core.dto import MiscDTO
-from app.database.models import City, MediaType, QuestionType, Role
+from app.database.models import City, ComponentType, MediaType, QuestionType, Role, ViewType
 from flask_jwt_extended import jwt_required
 from flask_restx import Resource, reqparse
 
@@ -9,6 +9,9 @@ api = MiscDTO.api
 
 question_type_schema = MiscDTO.question_type_schema
 media_type_schema = MiscDTO.media_type_schema
+component_type_schema = MiscDTO.component_type_schema
+view_type_schema = MiscDTO.view_type_schema
+
 role_schema = MiscDTO.role_schema
 city_schema = MiscDTO.city_schema
 
@@ -17,27 +20,23 @@ name_parser = reqparse.RequestParser()
 name_parser.add_argument("name", type=str, required=True, location="json")
 
 
-@api.route("/media_types")
-class MediaTypeList(Resource):
-    @jwt_required
-    def get(self):
-        items = MediaType.query.all()
-        return list_response(media_type_schema.dump(items))
-
-
-@api.route("/question_types")
-class QuestionTypeList(Resource):
+@api.route("/types")
+class TypesList(Resource):
     @jwt_required
     def get(self):
-        items = QuestionType.query.all()
-        return list_response(question_type_schema.dump(items))
+        result = {}
+        result["media_types"] = media_type_schema.dump(dbc.get.all(MediaType))
+        result["component_types"] = component_type_schema.dump(dbc.get.all(ComponentType))
+        result["question_types"] = question_type_schema.dump(dbc.get.all(QuestionType))
+        result["view_types"] = view_type_schema.dump(dbc.get.all(ViewType))
+        return result
 
 
 @api.route("/roles")
 class RoleList(Resource):
     @jwt_required
     def get(self):
-        items = Role.query.all()
+        items = dbc.get.all(Role)
         return list_response(role_schema.dump(items))
 
 
@@ -45,14 +44,14 @@ class RoleList(Resource):
 class CitiesList(Resource):
     @jwt_required
     def get(self):
-        items = City.query.all()
+        items = dbc.get.all(City)
         return list_response(city_schema.dump(items))
 
     @jwt_required
     def post(self):
         args = name_parser.parse_args(strict=True)
         dbc.add.city(args["name"])
-        items = City.query.all()
+        items = dbc.get.all(City)
         return list_response(city_schema.dump(items))
 
 
@@ -61,16 +60,16 @@ class CitiesList(Resource):
 class Cities(Resource):
     @jwt_required
     def put(self, ID):
-        item = City.query.filter(City.id == ID).first()
+        item = dbc.get.one(City, ID)
         args = name_parser.parse_args(strict=True)
         item.name = args["name"]
         dbc.commit_and_refresh(item)
-        items = City.query.all()
+        items = dbc.get.all(City)
         return list_response(city_schema.dump(items))
 
     @jwt_required
     def delete(self, ID):
-        item = City.query.filter(City.id == ID).first()
+        item = dbc.get.one(City, ID)
         dbc.delete.default(item)
-        items = City.query.all()
+        items = dbc.get.all(City)
         return list_response(city_schema.dump(items))
diff --git a/server/app/core/dto.py b/server/app/core/dto.py
index 3e6b0cda..a6899fc7 100644
--- a/server/app/core/dto.py
+++ b/server/app/core/dto.py
@@ -3,6 +3,7 @@ import app.core.schemas as schemas
 import marshmallow as ma
 from flask_restx import Namespace, fields
 from flask_uploads import IMAGES, UploadSet
+from sqlalchemy.sql.expression import true
 
 
 class ComponentDTO:
@@ -53,6 +54,8 @@ class MiscDTO:
     role_schema = schemas.RoleSchema(many=True)
     question_type_schema = schemas.QuestionTypeSchema(many=True)
     media_type_schema = schemas.MediaTypeSchema(many=True)
+    component_type_schema = schemas.ComponentTypeSchema(many=True)
+    view_type_schema = schemas.ViewTypeSchema(many=True)
     city_schema = schemas.CitySchema(many=True)
 
 
diff --git a/server/app/core/parsers.py b/server/app/core/parsers.py
index a8136c9c..151924ca 100644
--- a/server/app/core/parsers.py
+++ b/server/app/core/parsers.py
@@ -77,4 +77,7 @@ component_parser.add_argument("y", type=int, default=None, location="json")
 component_parser.add_argument("w", type=int, default=None, location="json")
 component_parser.add_argument("h", type=int, default=None, location="json")
 component_parser.add_argument("data", type=dict, default=None, location="json")
-component_parser.add_argument("type_id", type=int, default=None, location="json")
+
+component_create_parser = component_parser.copy()
+component_create_parser.replace_argument("data", type=dict, required=True, location="json")
+component_create_parser.add_argument("type_id", type=int, required=True, location="json")
diff --git a/server/app/core/rich_schemas.py b/server/app/core/rich_schemas.py
index ab1b3abb..8c220e78 100644
--- a/server/app/core/rich_schemas.py
+++ b/server/app/core/rich_schemas.py
@@ -53,6 +53,7 @@ class SlideSchemaRich(RichSchema):
     timer = ma.auto_field()
     competition_id = ma.auto_field()
     questions = fields.Nested(QuestionSchemaRich, many=True)
+    components = fields.Nested(schemas.ComponentSchema, many=True)
 
 
 class CompetitionSchemaRich(RichSchema):
diff --git a/server/app/core/schemas.py b/server/app/core/schemas.py
index 058efed7..ee909e4b 100644
--- a/server/app/core/schemas.py
+++ b/server/app/core/schemas.py
@@ -10,12 +10,30 @@ class BaseSchema(ma.SQLAlchemySchema):
         include_relationships = False
 
 
-class QuestionTypeSchema(BaseSchema):
+class IdNameSchema(BaseSchema):
+
+    id = fields.fields.Integer()
+    name = fields.fields.String()
+
+
+class QuestionTypeSchema(IdNameSchema):
     class Meta(BaseSchema.Meta):
         model = models.QuestionType
 
-    id = ma.auto_field()
-    name = ma.auto_field()
+
+class MediaTypeSchema(IdNameSchema):
+    class Meta(BaseSchema.Meta):
+        model = models.MediaType
+
+
+class ComponentTypeSchema(IdNameSchema):
+    class Meta(BaseSchema.Meta):
+        model = models.ComponentType
+
+
+class ViewTypeSchema(IdNameSchema):
+    class Meta(BaseSchema.Meta):
+        model = models.ViewType
 
 
 class QuestionSchema(BaseSchema):
@@ -40,14 +58,6 @@ class QuestionAnswerSchema(BaseSchema):
     team_id = ma.auto_field()
 
 
-class MediaTypeSchema(BaseSchema):
-    class Meta(BaseSchema.Meta):
-        model = models.MediaType
-
-    id = ma.auto_field()
-    name = ma.auto_field()
-
-
 class RoleSchema(BaseSchema):
     class Meta(BaseSchema.Meta):
         model = models.Role
@@ -124,6 +134,6 @@ class ComponentSchema(BaseSchema):
     y = ma.auto_field()
     w = ma.auto_field()
     h = ma.auto_field()
-    data = ma.auto_field()  # TODO: Convert this to dict
+    data = ma.Function(lambda obj: obj.data)
     slide_id = ma.auto_field()
     type_id = ma.auto_field()
diff --git a/server/app/database/controller/add.py b/server/app/database/controller/add.py
index 9e2a8e11..0e955a9e 100644
--- a/server/app/database/controller/add.py
+++ b/server/app/database/controller/add.py
@@ -5,6 +5,7 @@ from app.database.models import (
     City,
     Competition,
     Component,
+    ComponentType,
     Media,
     MediaType,
     Question,
@@ -13,6 +14,7 @@ from app.database.models import (
     Slide,
     Team,
     User,
+    ViewType,
 )
 from flask_restx import abort
 
@@ -33,8 +35,8 @@ def db_add(func):
 
 
 @db_add
-def component(x, y, w, h, data, item_slide, type_id):
-    return Component(x, y, w, h, data, item_slide.id, type_id)
+def component(type_id, item_slide, data, x=0, y=0, w=0, h=0):
+    return Component(item_slide.id, type_id, data, x, y, w, h)
 
 
 @db_add
@@ -83,6 +85,16 @@ def questionType(name):
     return QuestionType(name)
 
 
+@db_add
+def componentType(name):
+    return ComponentType(name)
+
+
+@db_add
+def viewType(name):
+    return ViewType(name)
+
+
 @db_add
 def role(name):
     return Role(name)
diff --git a/server/app/database/controller/delete.py b/server/app/database/controller/delete.py
index 65527ee9..2eb040c9 100644
--- a/server/app/database/controller/delete.py
+++ b/server/app/database/controller/delete.py
@@ -8,6 +8,10 @@ def default(item):
     db.session.commit()
 
 
+def component(item_component):
+    default(item_component)
+
+
 def slide(item_slide):
     for item_question in item_slide.questions:
         question(item_question)
diff --git a/server/app/database/controller/edit.py b/server/app/database/controller/edit.py
index 0a1b190f..3afcb4d4 100644
--- a/server/app/database/controller/edit.py
+++ b/server/app/database/controller/edit.py
@@ -20,6 +20,23 @@ def switch_order(item1, item2):
     return item1
 
 
+def component(item, x, y, w, h, data):
+    if x:
+        item.x = x
+    if y:
+        item.y = y
+    if w:
+        item.w = w
+    if h:
+        item.h = h
+    if data:
+        item.data = data
+
+    db.session.commit()
+    db.session.refresh(item)
+    return item
+
+
 def slide(item, title=None, timer=None):
     if title:
         item.title = title
diff --git a/server/app/database/controller/get.py b/server/app/database/controller/get.py
index fa6914b2..892d251b 100644
--- a/server/app/database/controller/get.py
+++ b/server/app/database/controller/get.py
@@ -1,4 +1,25 @@
-from app.database.models import Competition, Component, Question, Slide, Team, User
+from app.core import db
+from app.database.models import (
+    City,
+    Competition,
+    Component,
+    ComponentType,
+    MediaType,
+    Question,
+    QuestionType,
+    Role,
+    Slide,
+    Team,
+    User,
+)
+
+
+def all(db_type):
+    return db_type.query.all()
+
+
+def one(db_type, id, required=True, error_msg=None):
+    return db_type.query.filter(db_type.id == id).first_extended(required, error_msg)
 
 
 def user_exists(email):
diff --git a/server/app/database/models.py b/server/app/database/models.py
index 29cbe3b5..6396e035 100644
--- a/server/app/database/models.py
+++ b/server/app/database/models.py
@@ -203,7 +203,6 @@ class Dictionary(TypeDecorator):
 
 
 class Component(db.Model):
-    # __mapper_args__ = {"polymorphic_on": type, "polymorphic_identity": "component"}
     id = db.Column(db.Integer, primary_key=True)
     x = db.Column(db.Integer, nullable=False, default=0)
     y = db.Column(db.Integer, nullable=False, default=0)
@@ -213,7 +212,7 @@ class Component(db.Model):
     slide_id = db.Column(db.Integer, db.ForeignKey("slide.id"), nullable=False)
     type_id = db.Column(db.Integer, db.ForeignKey("component_type.id"), nullable=False)
 
-    def __init__(self, x, y, w, h, data, slide_id, type_id):
+    def __init__(self, slide_id, type_id, data, x=0, y=0, w=1, h=1):
         self.x = x
         self.y = y
         self.w = w
@@ -223,33 +222,6 @@ class Component(db.Model):
         self.type_id = type_id
 
 
-"""
-class ImageComponent(Component):
-    __mapper_args__ = {"polymorphic_identity": "image_component"}
-
-    id = db.Column(db.Integer, db.ForeignKey("component.id"), primary_key=True)
-    # id = db.Column(db.Integer, primary_key=True)
-    image_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=False)
-    image = db.relationship("Media", uselist=False)
-
-    def __init__(self, id, image_id, x, y, w, h, slide_id, type):
-        super.__init__(x, y, w, h, slide_id, type)
-        self.id = id
-        self.image_id = image_id
-
-
-class TextComponent(Component):
-    __mapper_args__ = {"polymorphic_identity": "text_component"}
-    id = db.Column(db.Integer, db.ForeignKey("component.id"), primary_key=True)
-    text = db.Column(db.Text, default="", nullable=False)
-
-    def __init__(self, id, text, x, y, w, h, slide_id, type):
-        super.__init__(x, y, w, h, slide_id, type)
-        self.id = id
-        self.text = text
-"""
-
-
 class Code(db.Model):
     table_args = (db.UniqueConstraint("pointer", "type"),)
     id = db.Column(db.Integer, primary_key=True)
@@ -258,18 +230,29 @@ class Code(db.Model):
 
     view_type_id = db.Column(db.Integer, db.ForeignKey("view_type.id"), nullable=False)
 
+    def __init__(self, code, pointer, view_type_id):
+        self.code = code
+        self.pointer = pointer
+        self.view_type_id = view_type_id
+
 
 class ViewType(db.Model):
     id = db.Column(db.Integer, primary_key=True)
-    name = db.Column(db.Text)
+    name = db.Column(db.String(STRING_SIZE), unique=True)
     codes = db.relationship("Code", backref="view_type")
 
+    def __init__(self, name):
+        self.name = name
+
 
 class ComponentType(db.Model):
     id = db.Column(db.Integer, primary_key=True)
-    name = db.Column(db.Text)
+    name = db.Column(db.String(STRING_SIZE), unique=True)
     components = db.relationship("Component", backref="component_type")
 
+    def __init__(self, name):
+        self.name = name
+
 
 class MediaType(db.Model):
     id = db.Column(db.Integer, primary_key=True)
diff --git a/server/configmodule.py b/server/configmodule.py
index fcf23cbf..2d525424 100644
--- a/server/configmodule.py
+++ b/server/configmodule.py
@@ -15,12 +15,13 @@ class Config:
     JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=30)
     UPLOADED_PHOTOS_DEST = "static/images"  # os.getcwd()
     SECRET_KEY = os.urandom(24)
+    SQLALCHEMY_ECHO = False
 
 
 class DevelopmentConfig(Config):
     DEBUG = True
     SQLALCHEMY_DATABASE_URI = "sqlite:///database.db"
-    SQLALCHEMY_ECHO = True
+    SQLALCHEMY_ECHO = False
 
 
 class TestingConfig(Config):
diff --git a/server/populate.py b/server/populate.py
index e2ca4776..45eb6005 100644
--- a/server/populate.py
+++ b/server/populate.py
@@ -8,21 +8,30 @@ from app.database.models import City, Competition, MediaType, QuestionType, Role
 def _add_items():
     media_types = ["Image", "Video"]
     question_types = ["Boolean", "Multiple", "Text"]
+    component_types = ["Text", "Image"]
+    view_types = ["Team", "Judge", "Audience"]
+
     roles = ["Admin", "Editor"]
     cities = ["Linköping", "Stockholm", "Norrköping", "Örkelljunga"]
     teams = ["Gymnasieskola A", "Gymnasieskola B", "Gymnasieskola C"]
 
-    for team_name in media_types:
-        dbc.add.mediaType(team_name)
+    for name in media_types:
+        dbc.add.mediaType(name)
+
+    for name in question_types:
+        dbc.add.questionType(name)
+
+    for name in component_types:
+        dbc.add.componentType(name)
 
-    for team_name in question_types:
-        dbc.add.questionType(team_name)
+    for name in view_types:
+        dbc.add.viewType(name)
 
-    for team_name in roles:
-        dbc.add.role(team_name)
+    for name in roles:
+        dbc.add.role(name)
 
-    for team_name in cities:
-        dbc.add.city(team_name)
+    for name in cities:
+        dbc.add.city(name)
 
     admin_id = Role.query.filter(Role.name == "Admin").one().id
     editor_id = Role.query.filter(Role.name == "Editor").one().id
diff --git a/server/tests/test_app.py b/server/tests/test_app.py
index 1cbacc33..67dbac72 100644
--- a/server/tests/test_app.py
+++ b/server/tests/test_app.py
@@ -2,8 +2,7 @@ import app.core.http_codes as codes
 from app.database.models import Slide
 
 from tests import app, client, db
-from tests.test_helpers import (add_default_values, change_order_test, delete,
-                                get, post, put)
+from tests.test_helpers import add_default_values, change_order_test, delete, get, post, put
 
 
 def test_misc_api(client):
@@ -14,6 +13,14 @@ def test_misc_api(client):
     assert response.status_code == codes.OK
     headers = {"Authorization": "Bearer " + body["access_token"]}
 
+    # Get types
+    response, body = get(client, "/api/misc/types", headers=headers)
+    assert response.status_code == codes.OK
+    assert len(body["media_types"]) >= 2
+    assert len(body["question_types"]) >= 3
+    assert len(body["component_types"]) >= 2
+    assert len(body["view_types"]) >= 2
+
     ## Get misc
     response, body = get(client, "/api/misc/roles", headers=headers)
     assert response.status_code == codes.OK
@@ -21,44 +28,33 @@ def test_misc_api(client):
 
     response, body = get(client, "/api/misc/cities", headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] == 2
-    assert body["items"][0]["name"] == "Linköping"
-    assert body["items"][1]["name"] == "Testköping"
-
-    response, body = get(client, "/api/misc/media_types", headers=headers)
-    assert response.status_code == codes.OK
     assert body["count"] >= 2
-
-    response, body = get(client, "/api/misc/question_types", headers=headers)
-    assert response.status_code == codes.OK
-    assert body["count"] >= 3
+    assert body["items"][0]["name"] == "Linköping" and body["items"][1]["name"] == "Testköping"
 
     ## Cities
     response, body = post(client, "/api/misc/cities", {"name": "Göteborg"}, headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] >= 2
-    assert body["items"][2]["name"] == "Göteborg"
+    assert body["count"] >= 2 and body["items"][2]["name"] == "Göteborg"
 
     # Rename city
     response, body = put(client, "/api/misc/cities/3", {"name": "Gbg"}, headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] >= 2
-    assert body["items"][2]["name"] == "Gbg"
+    assert body["count"] >= 2 and body["items"][2]["name"] == "Gbg"
 
     # Delete city
     # First checks current cities
     response, body = get(client, "/api/misc/cities", headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] == 3
+    assert body["count"] >= 3
     assert body["items"][0]["name"] == "Linköping"
     assert body["items"][1]["name"] == "Testköping"
     assert body["items"][2]["name"] == "Gbg"
+
     # Deletes city
     response, body = delete(client, "/api/misc/cities/3", headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] == 2
-    assert body["items"][0]["name"] == "Linköping"
-    assert body["items"][1]["name"] == "Testköping"
+    assert body["count"] >= 2
+    assert body["items"][0]["name"] == "Linköping" and body["items"][1]["name"] == "Testköping"
 
 
 def test_competition_api(client):
@@ -152,8 +148,7 @@ def test_auth_and_user_api(client):
     response, body = put(client, "/api/users", {"name": "carl carlsson", "city_id": 2, "role_id": 1}, headers=headers)
     assert response.status_code == codes.OK
     assert body["name"] == "Carl Carlsson"
-    assert body["city"]["id"] == 2
-    assert body["role"]["id"] == 1
+    assert body["city"]["id"] == 2 and body["role"]["id"] == 1
 
     # Find other user
     response, body = get(
@@ -244,16 +239,14 @@ def test_slide_api(client):
 
     # Get slides
     CID = 2
-    num_slides = 3
     response, body = get(client, f"/api/competitions/{CID}/slides", headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] == num_slides
+    assert body["count"] == 3
 
     # Add slide
     response, body = post(client, f"/api/competitions/{CID}/slides", headers=headers)
-    num_slides += 1
     assert response.status_code == codes.OK
-    assert body["count"] == num_slides
+    assert body["count"] == 4
 
     # Get slide
     SID = 1
@@ -286,21 +279,19 @@ def test_slide_api(client):
 
     # Delete slide
     response, _ = delete(client, f"/api/competitions/{CID}/slides/{SID}", headers=headers)
-    num_slides -= 1
     assert response.status_code == codes.NO_CONTENT
     # Checks that there are fewer slides
     response, body = get(client, f"/api/competitions/{CID}/slides", headers=headers)
     assert response.status_code == codes.OK
-    assert body["count"] == num_slides
+    assert body["count"] == 3
 
     # Tries to delete slide again
     response, _ = delete(client, f"/api/competitions/{CID}/slides/{SID}", headers=headers)
     assert response.status_code == codes.NOT_FOUND
 
     # Changes the order to the same order
-    i = 0
-    SID = body["items"][i]["id"]
-    order = body["items"][i]["order"]
+    SID = body["items"][0]["id"]
+    order = body["items"][0]["order"]
     response, _ = put(client, f"/api/competitions/{CID}/slides/{SID}/order", {"order": order}, headers=headers)
     assert response.status_code == codes.OK
 
diff --git a/server/tests/test_helpers.py b/server/tests/test_helpers.py
index 7cbdec87..6b6bf7a0 100644
--- a/server/tests/test_helpers.py
+++ b/server/tests/test_helpers.py
@@ -9,23 +9,29 @@ from app.database.models import City, Role
 def add_default_values():
     media_types = ["Image", "Video"]
     question_types = ["Boolean", "Multiple", "Text"]
+    component_types = ["Text", "Image"]
+    view_types = ["Team", "Judge", "Audience"]
+
     roles = ["Admin", "Editor"]
     cities = ["Linköping", "Testköping"]
 
-    # Add media types
-    for item in media_types:
-        dbc.add.mediaType(item)
+    for name in media_types:
+        dbc.add.mediaType(name)
+
+    for name in question_types:
+        dbc.add.questionType(name)
+
+    for name in component_types:
+        dbc.add.componentType(name)
+
+    for name in view_types:
+        dbc.add.viewType(name)
 
-    # Add question types
-    for item in question_types:
-        dbc.add.questionType(item)
+    for name in roles:
+        dbc.add.role(name)
 
-    # Add roles
-    for item in roles:
-        dbc.add.role(item)
-    # Add cities
-    for item in cities:
-        dbc.add.city(item)
+    for name in cities:
+        dbc.add.city(name)
 
     item_admin = Role.query.filter(Role.name == "Admin").one()
     item_city = City.query.filter(City.name == "Linköping").one()
-- 
GitLab