diff --git a/server/app/database/controller/add.py b/server/app/database/controller/add.py
index de0135f2f514745017b85f654f4afc3203b69975..be7a773e9e579669393dadd83527ad779726e8cc 100644
--- a/server/app/database/controller/add.py
+++ b/server/app/database/controller/add.py
@@ -140,20 +140,36 @@ def slide(item_competition):
 
 
 def competition(name, year, city_id):
-    """ Adds a competition to the database using the provided arguments. """
+    """
+    Adds a competition to the database using the
+    provided arguments. Also adds slide and codes.
+    """
 
-    item_competition = db_add(Competition(name, year, city_id))
+    item_competition = _competition(name, year, city_id)
 
     # Add one slide for the competition
     slide(item_competition)
 
+    # TODO: Add two teams
+
+    return item_competition
+
+
+def _competition(name, year, city_id, font=None):
+    """
+    Internal function. Adds a competition to the database
+    using the provided arguments. Also adds codes.
+    """
+
+    item_competition = db_add(Competition(name, year, city_id))
+    if font:
+        item_competition.font = font
+
     # Add code for Judge view
     code(item_competition.id, 2)
 
     # Add code for Audience view
     code(item_competition.id, 3)
 
-    # TODO: Add two teams
-
     utils.refresh(item_competition)
     return item_competition
diff --git a/server/app/database/controller/copy.py b/server/app/database/controller/copy.py
index de4f8c1edcb7b8ddc9a40c7a8aad07e58ac01922..dabd0d7807025f9c908a6840e9e0a64c40b64a57 100644
--- a/server/app/database/controller/copy.py
+++ b/server/app/database/controller/copy.py
@@ -2,8 +2,8 @@
 This file contains functionality to copy and duplicate data to the database.
 """
 
-from app.database.controller import add, utils
-from app.database.models import Question, Slide
+from app.database.controller import add, get, search, utils
+from app.database.models import Question
 
 
 def _question(item_question_old, slide_id):
@@ -51,10 +51,18 @@ def slide(item_slide_old):
     Does not copy team, question answers or alternatives.
     """
 
-    order = Slide.query.filter(
-        Slide.competition_id == item_slide_old.competition_id
-    ).count()  # first element has index 0
-    item_slide_new = add.db_add(Slide(order, item_slide_old.competition_id))
+    item_competition = get.competition(item_slide_old.competition_id)
+
+    return slide_to_competition(item_slide_old, item_competition)
+
+
+def slide_to_competition(item_slide_old, item_competition):
+    """
+    Deep copies a slide to the provided competition.
+    Does not copy team, question answers or alternatives.
+    """
+
+    item_slide_new = add.slide(item_competition)
 
     # Copy all fields
     item_slide_new.title = item_slide_old.title
@@ -72,3 +80,29 @@ def slide(item_slide_old):
 
     utils.commit_and_refresh(item_slide_new)
     return item_slide_new
+
+
+def competition(item_competition_old):
+    """
+    Adds a deep-copy of the provided competition.
+    Will not copy teams, question answers or alternatives.
+    """
+
+    name = "Kopia av " + item_competition_old.name
+    item_competition, total = search.competition(name=name)
+    if item_competition:
+        print(f"{item_competition[total-1].name}, {total=}")
+        name = "Kopia av " + item_competition[total - 1].name
+
+    item_competition_new = add._competition(
+        name,
+        item_competition_old.year,
+        item_competition_old.city_id,
+        item_competition_old.font,
+    )
+    # TODO: Add background image
+
+    for item_slide in item_competition_old.slides:
+        slide_to_competition(item_slide, item_competition_new)
+
+    return item_competition_new
diff --git a/server/tests/test_db.py b/server/tests/test_db.py
index 3d68bc3e807462574fba47db01ec812e8708334a..7d162065c8857a24a137b1f55c610f969045fd60 100644
--- a/server/tests/test_db.py
+++ b/server/tests/test_db.py
@@ -45,23 +45,39 @@ def test_copy(client):
 
     # Fetches an empty competition
     list_item_competitions, _ = dbc.search.competition(name="Tävling 1")
-    item_competition = list_item_competitions[0]
+    item_competition_original = list_item_competitions[0]
 
     # Fetches the first slide in that competition
     num_slides = 3
-    item_slides, total = dbc.search.slide(competition_id=item_competition.id)
-    assert total == 3
+    item_slides, total = dbc.search.slide(competition_id=item_competition_original.id)
+    assert total == num_slides
     item_slide_original = item_slides[0]
 
-    # Copies the slide and double checks the results
-    item_slide_copy = dbc.copy.slide(item_slide_original)
-    num_slides += 1
-    assert item_slide_copy.order == num_slides - 1  # 0 indexing
+    # Inserts several copies of the same slide
+    num_copies = 10
+    for _ in range(num_copies):
+        item_slide_copy = dbc.copy.slide(item_slide_original)
+        num_slides += 1
+        check_slides_copy(item_slide_original, item_slide_copy, num_slides, num_slides - 1)
+        assert item_slide_copy.competition_id == item_slide_original.competition_id
+
+    # Copies competition
+    num_copies = 3
+    for _ in range(num_copies):
+        item_competition_copy = dbc.copy.competition(item_competition_original)
+        for order, item_slide in enumerate(item_competition_copy.slides):
+            item_slide_original = item_competition_original.slides[order]
+            check_slides_copy(item_slide_original, item_slide, num_slides, order)
+            assert item_slide.competition_id != item_slide_original.competition_id
+
+
+def check_slides_copy(item_slide_original, item_slide_copy, num_slides, order):
+    """ Checks that two slides are correct copies of each other. Looks big but is quite fast. """
+    assert item_slide_copy.order == order  # 0 indexing
     assert item_slide_copy.title == item_slide_original.title
     assert item_slide_copy.body == item_slide_original.body
     assert item_slide_copy.timer == item_slide_original.timer
     assert item_slide_copy.settings == item_slide_original.settings
-    assert item_slide_copy.competition_id == item_slide_original.competition_id
 
     # Checks that all components were correctly copied
     assert len(item_slide_copy.components) == len(item_slide_original.components)
@@ -90,21 +106,12 @@ def test_copy(client):
         # TODO: Assert alternatives
 
     # Checks that the copy put the slide in the database
-    item_slides, total = dbc.search.slide(competition_id=item_competition.id)
+    item_slides, total = dbc.search.slide(
+        competition_id=item_slide_copy.competition_id,
+        # page_size=num_slides + 1, # Use this total > 15
+    )
     assert total == num_slides
-    assert item_slide_copy == item_slides[num_slides - 1]
-
-    # Inserts several copies of the same slide
-    num_copies = 10
-    for i in range(num_copies):
-        # The order must be correct
-        item_slide_original = dbc.copy.slide(item_slide_original)
-        assert item_slide_original.order == i + num_slides
-
-    # Checks that the last slide is correct
-    item_slides, total = dbc.search.slide(competition_id=item_competition.id)
-    assert total == num_copies + num_slides
-    assert item_slide_original == item_slides[num_copies + num_slides - 1]
+    assert item_slide_copy == item_slides[order]
 
 
 """