diff --git a/bbcli/cli.py b/bbcli/cli.py
index 0dfb4aa1fbf784234a9e02271568990bf0722961..b76770cce92017ee2a9c724d46109dbf1bdf982b 100644
--- a/bbcli/cli.py
+++ b/bbcli/cli.py
@@ -11,7 +11,7 @@ import click
 from bbcli.commands.courses import list_courses
 from bbcli.commands.announcements import list_announcements, create_announcement, delete_announcement, update_announcement
 from bbcli.commands.contents import create_assignment_from_contents, create_courselink, create_folder, delete_content, list_contents, create_document, create_file, create_web_link, update_content, upload_attachment, get_content
-from bbcli.commands.assignments import get_assignments, submit_attempt, grade_assignment, get_attempts, get_attempt, submit_draft, update_attempt, submit_draft, create_assignment
+from bbcli.commands.assignments import get_assignments, submit_attempt, grade_assignment, get_attempts, get_attempt, submit_draft, submit_draft, create_assignment
 from bbcli.services.authorization_service import login
 import mmap
 
@@ -167,7 +167,7 @@ def attempts(ctx):
 attempts.add_command(get_attempts)
 attempts.add_command(get_attempt)
 attempts.add_command(submit_draft)
-attempts.add_command(update_attempt)
+# attempts.add_command(update_attempt)
 
 """
 CONTENT COMMANDS ENTRY POINT
diff --git a/bbcli/commands/announcements.py b/bbcli/commands/announcements.py
index 9cd4179c2e1bf05a28d1639b5cefde05593f1851..d5f04cecaca828ceb33d8eb195ad637d5339360a 100644
--- a/bbcli/commands/announcements.py
+++ b/bbcli/commands/announcements.py
@@ -1,34 +1,42 @@
 from datetime import datetime
+import json
 import click
 from bbcli.entities.content_builder_entitites import DateInterval
 from bbcli.services import announcements_service
 from bbcli.utils.error_handler import create_exception_handler, delete_exception_handler, list_exception_handler, update_exception_handler
 from bbcli.utils.utils import format_date
-from bbcli.views import announcement_view
+from bbcli.views import announcements_view
 import os
 
 
 @click.command(name='list', help='This command lists your announcements.\nEither all announcements, all announcements from a spesific course, or one announcement.')
 @click.option('-c', '--course', 'course_id', required=False, type=str, help='COURSE ID, list announcements from a spesific course')
 @click.option('-a', '--announcement', 'announcement_id', required=False, type=str, help='ANNONUCEMENT ID, list a spesific announcement from a course.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print data in json format')
 @click.pass_context
 @list_exception_handler
-def list_announcements(ctx, course_id=None, announcement_id=None):
+def list_announcements(ctx, course_id=None, announcement_id=None, print_json=False):
     response = None
 
     if announcement_id:
         response = announcements_service.list_announcement(
             ctx.obj['SESSION'], course_id, announcement_id)
-        announcement_view.print_announcement(response)
+        if not print_json:
+            announcements_view.print_announcement(response)
     elif course_id:
         response = announcements_service.list_course_announcements(
             ctx.obj['SESSION'], course_id)
-        announcement_view.print_course_announcements(response)
+        if not print_json:
+            announcements_view.print_course_announcements(response)
     else:
         user_name = os.getenv('BB_USERNAME')
         response = announcements_service.list_announcements(
             ctx.obj['SESSION'], user_name)
-        announcement_view.print_announcements(response)
+        if not print_json:
+            announcements_view.print_announcements(response)
+    
+    if print_json:
+        click.echo(json.dumps(response, indent=2))
 
 
 @click.command(name='create', help='Creates an announcement. Add --help for all options available.')
@@ -36,9 +44,10 @@ def list_announcements(ctx, course_id=None, announcement_id=None):
 @click.argument('title', required=True, type=str)
 @click.option('--start-date', type=str, help='When to make announcement available. Format: DD/MM/YY HH:MM:SS')
 @click.option('--end-date', type=str, help='When to make announcement unavailable. Format: DD/MM/YY HH:MM:SS')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print response data in json format')
 @click.pass_context
 @create_exception_handler
-def create_announcement(ctx, course_id: str, title: str, start_date: str, end_date: str):
+def create_announcement(ctx, course_id: str, title: str, start_date: str, end_date: str, print_json: bool):
     date_interval = DateInterval()
     if start_date or end_date:
         if start_date:
@@ -48,7 +57,11 @@ def create_announcement(ctx, course_id: str, title: str, start_date: str, end_da
 
     response = announcements_service.create_announcement(
         ctx.obj['SESSION'], course_id, title, date_interval)
-    announcement_view.print_announcement_created(response)
+    if print_json:
+        data = json.loads(response)
+        click.echo(json.dumps(data, indent=2))
+    else:
+        announcements_view.print_announcement_created(response)
 
 
 @click.command(name='delete', help='Deletes an announcement. Add --help for all options available')
@@ -59,15 +72,20 @@ def create_announcement(ctx, course_id: str, title: str, start_date: str, end_da
 def delete_announcement(ctx, course_id: str, announcement_id: str):
     announcements_service.delete_announcement(
         ctx.obj['SESSION'], course_id, announcement_id)
-    announcement_view.print_announcement_deleted()
+    announcements_view.print_announcement_deleted()
 
 
 @click.command(name='update', help='Updates an announcement. Add --help for all options available.')
 @click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID of the course you want to create an announcement in.')
 @click.option('-a', '--announcement', 'announcement_id', required=True, type=str, help='ANNOUNCEMENT ID, of the annonucement you want to update.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print response data in json format')
 @click.pass_context
 @update_exception_handler
-def update_announcement(ctx, course_id: str, announcement_id: str):
+def update_announcement(ctx, course_id: str, announcement_id: str, print_json: bool):
     response = announcements_service.update_announcement(
         ctx.obj['SESSION'], course_id, announcement_id)
-    announcement_view.print_announcement_updated(response)
+    if print_json:
+        data = json.loads(response)
+        click.echo(json.dumps(data, indent=2))
+    else:
+        announcements_view.print_announcement_updated(response)
diff --git a/bbcli/commands/assignments.py b/bbcli/commands/assignments.py
index 5d3a6587741b54ba31ed6d1ae87206eb9b47007a..500f1425170615b5ebea9806c63fccbf221fb454 100644
--- a/bbcli/commands/assignments.py
+++ b/bbcli/commands/assignments.py
@@ -1,9 +1,11 @@
+import json
 import click
 from bbcli.commands.contents import grading_options, set_dates, standard_options
 from bbcli.entities.content_builder_entitites import GradingOptions, StandardOptions
 from bbcli.services import assignment_service, contents_service
 from bbcli.utils.error_handler import create_exception_handler, list_exception_handler, update_exception_handler
 from bbcli.utils.utils import format_date
+from bbcli.views import assignments_view
 
 
 def attempt_options(function):
@@ -28,6 +30,7 @@ def attempt_options(function):
 @click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID, of the folder you want to place the assignment.')
 @click.argument('title', required=True, type=str)
 @click.argument('attachments', required=False, nargs=-1, type=click.Path())
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @grading_options
 @click.pass_context
@@ -36,7 +39,7 @@ def create_assignment(ctx, course_id: str, parent_id: str, title: str,
                       hide_content: bool, reviewable: bool,
                       start_date: str, end_date: str,
                       due_date: str, max_attempts: int, unlimited_attempts: bool, score: int,
-                      attachments: tuple):
+                      attachments: tuple, print_json):
     standard_options = StandardOptions(hide_content, reviewable)
     grading_options = GradingOptions(
         attempts_allowed=max_attempts, is_unlimited_attemps_allowed=unlimited_attempts, score_possible=score)
@@ -46,29 +49,33 @@ def create_assignment(ctx, course_id: str, parent_id: str, title: str,
 
     response = contents_service.create_assignment(
         ctx.obj['SESSION'], course_id, parent_id, title, standard_options, grading_options, attachments)
-    click.echo(response)
-
+    assignments_view.print_created_assignment(json.loads(response), print_json)
 
 @click.command(name='list', help='List all assignments from a course.')
 @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course you want assignments from.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @list_exception_handler
-def get_assignments(ctx, course_id):
+def get_assignments(ctx, course_id, print_json):
     response = assignment_service.get_assignments(ctx.obj['SESSION'], course_id)
-    assignment_service.print_assignments(response)
+    if print_json:
+        click.echo(json.dumps(response, indent=2))
+    else:
+        assignments_view.print_assignments(response)
 
 @click.command(name='list', help='List attempts for an assignment.')
 @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course you want the assignment attempts from')
 @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want attempts from')
 @click.option('--submitted', is_flag=True, help='List only submitted attempts.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @list_exception_handler
-def get_attempts(ctx, course_id, column_id, submitted):
+def get_attempts(ctx, course_id, column_id, submitted, print_json):
     response = assignment_service.get_column_attempts(ctx.obj['SESSION'], course_id, column_id)
     if submitted:
-        assignment_service.print_submitted_attempts(response)
+        assignments_view.print_submitted_attempts(response, print_json)
     else:
-        assignment_service.print_all_attempts(response)
+        assignments_view.print_all_attempts(response, print_json)
 
 
 # TODO: Retrieve the submission w/ attachments.
@@ -76,11 +83,15 @@ def get_attempts(ctx, course_id, column_id, submitted):
 @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course of you want to get attempt from')
 @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want attempts from')
 @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to fetch.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @list_exception_handler
-def get_attempt(ctx, course_id, column_id, attempt_id):
+def get_attempt(ctx, course_id, column_id, attempt_id, print_json):
     response = assignment_service.get_column_attempt(ctx.obj['SESSION'], course_id, column_id, attempt_id)
-    click.echo(response)
+    if print_json:
+        click.echo(response)
+    else:
+        assignments_view.print_get_attempt(json.loads(response))
 
 @click.command(name='submit', help='Submit assignment attempt.')
 @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course to submit an assignment to.')
@@ -89,49 +100,65 @@ def get_attempt(ctx, course_id, column_id, attempt_id):
 @click.option('--student-submission', help='The student submission text associated with this attempt.')
 @click.option('--file', help='Attach a file to an attempt for a Student Submission. Relative path of file.')
 @click.option('--draft', is_flag=True)
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @create_exception_handler
-def submit_attempt(ctx, course_id, column_id, student_comments, student_submission, file, draft):
+def submit_attempt(ctx, course_id, column_id, student_comments, student_submission, file, draft, print_json):
     response = assignment_service.create_column_attempt(
         ctx.obj['SESSION'], course_id, column_id, studentComments=student_comments, studentSubmission=student_submission, dst=file, status='needsGrading', draft=draft)
-    click.echo(response)
+    if print_json:
+        click.echo(response)
+    else:
+        assignments_view.print_submitted_attempt(json.loads(response))
 
 @click.command(name='submit-draft', help='Submit assignment draft.')
 @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.')
 @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want to submit to.')
 @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to update.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @update_exception_handler
-def submit_draft(ctx, course_id, column_id, attempt_id):
+def submit_draft(ctx, course_id, column_id, attempt_id, print_json):
     response = assignment_service.update_column_attempt(
         ctx.obj['SESSION'], course_id=course_id, column_id=column_id, attempt_id=attempt_id, status='needsGrading')
-    click.echo(response)
-
-@click.command(name='update', help='Update assignment.')
-@click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.')
-@click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want to submit to.')
-@click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to update.')
-@attempt_options
-@click.option('--studentComments', help='The student comments associated with this attempt.')
-@click.option('--studentSubmission', help='The student submission text associated with this attempt.')
-@click.pass_context
-@update_exception_handler
-def update_attempt(ctx, course_id, column_id, attempt_id, status, comments, submission, file):
-    response = assignment_service.update_column_attempt(
-        session=ctx.obj['SESSION'], course_id=course_id, column_id=column_id, attempt_id=attempt_id, status=status, studentComments=comments, studentSubmission=submission, dst=file)
-    click.echo(response)
+    if print_json:
+        click.echo(response)
+    else:
+        assignments_view.print_submitted_draft(json.loads(response))
+
+# @click.command(name='update', help='Update assignment.')
+# @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.')
+# @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want to submit to.')
+# @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to update.')
+# @attempt_options
+# @click.option('--student-comments', help='The student comments associated with this attempt.')
+# @click.option('--student-submission', help='The student submission text associated with this attempt.')
+# @click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
+# @click.pass_context
+# @update_exception_handler
+# def update_attempt(ctx, course_id, column_id, attempt_id, status, student_comments, student_submission, file, print_json, exempt, feedback, notes, score, text, file):
+#     response = assignment_service.update_column_attempt(
+#         session=ctx.obj['SESSION'], course_id=course_id, column_id=column_id, attempt_id=attempt_id, status=status, studentComments=student_comments, studentSubmission=student_submission, dst=file)
+#     if print_json:
+#         click.echo(response)
+#     else:
+#         assignments_view.print_updated_attempt(json.loads(response))
 
 @click.command(name='grade', help='Grade an assignment.')
 @click.option('-c', '--course', 'course_id', required=True, help='COURSE ID, of the course where the assignment is.')
 @click.option('-a', '--assignment', 'column_id', required=True, help='ASSIGNMENT ID, of the assignment you want.')
 @click.option('-at', '--attempt', 'attempt_id', required=True, help='ATTEMPT ID, of the attempt you want to grade.')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @attempt_options
 @click.pass_context
 @update_exception_handler
-def grade_assignment(ctx, course_id, column_id, attempt_id, status, score, text, notes, feedback, exempt):
+def grade_assignment(ctx, course_id, column_id, attempt_id, status, score, text, notes, feedback, exempt, print_json):
     if status is None:
         status = 'Completed'
 
     response = assignment_service.update_column_attempt(session=ctx.obj['SESSION'], status=status, course_id=course_id, column_id=column_id,
                                              attempt_id=attempt_id, score=score, text=text, notes=notes, feedback=feedback, exempt=exempt)
-    click.echo(response)
\ No newline at end of file
+    if print_json:
+        click.echo(response)
+    else:
+        assignments_view.print_graded_attempt(json.loads(response))
\ No newline at end of file
diff --git a/bbcli/commands/contents.py b/bbcli/commands/contents.py
index 8aec8c15bf96a5eef66bfcf85e8f4578f4cbc38b..1d764274f98d4f801c006a55d167703e2fd93632 100644
--- a/bbcli/commands/contents.py
+++ b/bbcli/commands/contents.py
@@ -1,3 +1,4 @@
+import json
 from bbcli.utils.utils import format_date
 from bbcli.utils.error_handler import create_exception_handler, delete_exception_handler, list_exception_handler, update_exception_handler
 import click
@@ -106,29 +107,31 @@ def get_content(ctx, course_id: str, node_id: str):
 @click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID of the course where the content is located')
 @click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID of content to attach a file')
 @click.argument('file_path', required=True, type=click.Path(exists=True))
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @create_exception_handler
-def upload_attachment(ctx, course_id: str, content_id: str, file_path: str):
-    contents_service.upload_attachment(
+def upload_attachment(ctx, course_id: str, content_id: str, file_path: str, print_json: bool):
+    response = contents_service.upload_attachment(
         ctx.obj['SESSION'], course_id, content_id, file_path)
-
+    contents_view.print_created_attachment_response(json.loads(response), print_json)
 
 @click.command(name='document', help='Create document content')
 @click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID')
 @click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID')
 @click.argument('title', required=True, type=str)
 @click.argument('attachments', required=False, nargs=-1, type=click.Path())
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @click.pass_context
 @create_exception_handler
-def create_document(ctx, course_id: str, parent_id: str, title: str, hide_content: bool, reviewable: bool, start_date: str = None, end_date: str = None, attachments: tuple = None):
+def create_document(ctx, course_id: str, parent_id: str, title: str, hide_content: bool, reviewable: bool, start_date: str = None, end_date: str = None, attachments: tuple = None, print_json: bool=False):
     standard_options = StandardOptions(
         hide_content=hide_content, reviewable=reviewable)
     set_dates(standard_options, start_date, end_date)
 
     response = contents_service.create_document(
         ctx.obj['SESSION'], course_id, parent_id, title, standard_options, attachments)
-    click.echo(response)
+    contents_view.print_created_content_response(json.loads(response), print_json)
 
 
 @click.command(name='file', help='Create file content')
@@ -137,19 +140,20 @@ def create_document(ctx, course_id: str, parent_id: str, title: str, hide_conten
 @click.argument('title', required=True, type=str)
 @click.argument('file_path', required=True, type=click.Path(exists=True))
 @file_options
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @click.pass_context
 @create_exception_handler
 def create_file(ctx, course_id: str, parent_id: str, title: str, file_path: str,
                 launch_in_new_window: bool, hide_content: bool, reviewable: bool,
-                start_date: str = None, end_date: str = None):
+                start_date: str = None, end_date: str = None, print_json: bool=False):
     file_options = FileOptions(launch_in_new_window)
     standard_options = StandardOptions(
         hide_content=hide_content, reviewable=reviewable)
     set_dates(standard_options, start_date, end_date)
     response = contents_service.create_file(
         ctx.obj['SESSION'], course_id, parent_id, title, file_path, file_options, standard_options)
-    click.echo(response)
+    contents_view.print_created_content_response(json.loads(response), print_json)
 
 
 @click.command(name='web-link', help='Create web link content')
@@ -157,19 +161,20 @@ def create_file(ctx, course_id: str, parent_id: str, title: str, file_path: str,
 @click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID')
 @click.argument('title', required=True, type=str)
 @click.argument('url', required=True, type=str)
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @web_link_options
 @click.pass_context
 @create_exception_handler
 def create_web_link(ctx, course_id: str, parent_id: str, title: str, url: str,
                     launch_in_new_window: bool, hide_content: bool, reviewable: bool,
-                    start_date: str = None, end_date: str = None):
+                    start_date: str = None, end_date: str = None, print_json: bool=False):
     web_link_options = WeblinkOptions(launch_in_new_window)
     standard_options = StandardOptions(hide_content, reviewable)
     set_dates(standard_options, start_date, end_date)
     response = contents_service.create_externallink(
         ctx.obj['SESSION'], course_id, parent_id, title, url, web_link_options, standard_options)
-    click.echo(response)
+    contents_view.print_created_content_response(json.loads(response), print_json)
 
 
 @click.command(name='folder', help='Create folder')
@@ -177,17 +182,18 @@ def create_web_link(ctx, course_id: str, parent_id: str, title: str, url: str,
 @click.option('-f', '--folder', 'parent_id', required=False, type=str, help='FOLDER ID of the parent folder')
 @click.argument('title', required=True, type=str)
 @click.option('--is-bb-page', is_flag=True, help='Make folder a blackboard page')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @click.pass_context
 @create_exception_handler
 def create_folder(ctx, course_id: str, parent_id: str, title: str,
                   hide_content: bool, reviewable: bool, is_bb_page: bool = False,
-                  start_date: str = None, end_date: str = None):
+                  start_date: str = None, end_date: str = None, print_json: bool=False):
     standard_options = StandardOptions(hide_content, reviewable)
     set_dates(standard_options, start_date, end_date)
     response = contents_service.create_folder(
         ctx.obj['SESSION'], course_id, parent_id, title, is_bb_page, standard_options)
-    click.echo(response)
+    contents_view.print_created_content_response(json.loads(response), print_json)
 
 
 @click.command(name='course-link', help='Create course link content\n\nRedirects user to the target content')
@@ -195,17 +201,18 @@ def create_folder(ctx, course_id: str, parent_id: str, title: str,
 @click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID')
 @click.argument('title', required=True, type=str)
 @click.argument('target_id', required=True, type=str)
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @click.pass_context
 @create_exception_handler
 def create_courselink(ctx, course_id: str, parent_id: str, title: str, target_id: str,
                       hide_content: bool, reviewable: bool,
-                      start_date: str = None, end_date: str = None):
+                      start_date: str = None, end_date: str = None, print_json: bool=False):
     standard_options = StandardOptions(hide_content, reviewable)
     set_dates(standard_options, start_date, end_date)
     response = contents_service.create_courselink(
         ctx.obj['SESSION'], course_id, parent_id, title, target_id, standard_options)
-    click.echo(response)
+    contents_view.print_created_content_response(json.loads(response), print_json)
 
 
 @click.command(name='assignment', help='Create assignment')
@@ -213,6 +220,7 @@ def create_courselink(ctx, course_id: str, parent_id: str, title: str, target_id
 @click.option('-f', '--folder', 'parent_id', required=True, type=str, help='FOLDER ID')
 @click.argument('title', required=True, type=str)
 @click.argument('attachments', required=False, nargs=-1, type=click.Path())
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @standard_options
 @grading_options
 @click.pass_context
@@ -221,7 +229,7 @@ def create_assignment_from_contents(ctx, course_id: str, parent_id: str, title:
                                     hide_content: bool, reviewable: bool,
                                     start_date: str, end_date: str,
                                     due_date: str, max_attempts: int, unlimited_attempts: bool, score: int,
-                                    attachments: tuple):
+                                    attachments: tuple, print_json: bool=False):
     """
     Create assignment
     """
@@ -234,7 +242,7 @@ def create_assignment_from_contents(ctx, course_id: str, parent_id: str, title:
 
     response = contents_service.create_assignment(
         ctx.obj['SESSION'], course_id, parent_id, title, standard_options, grading_options, attachments)
-    click.echo(response)
+    contents_view.print_created_content_response(json.loads(response), print_json)
 
 
 # TODO: ADD RESPONSES
@@ -245,9 +253,9 @@ def create_assignment_from_contents(ctx, course_id: str, parent_id: str, title:
 @click.pass_context
 @delete_exception_handler
 def delete_content(ctx, course_id: str, content_id: str, delete_grades: bool):
-    response = contents_service.delete_content(
+    contents_service.delete_content(
         ctx.obj['SESSION'], course_id, content_id, delete_grades)
-    click.echo(response)
+    contents_view.print_deleted_content_response()
 
 # TODO: ADD RESPONSES
 
@@ -255,12 +263,13 @@ def delete_content(ctx, course_id: str, content_id: str, delete_grades: bool):
 @click.command(name='update', help='Update content\n\nEditable content types: document, files, assignments, externallinks, courselinks')
 @click.option('-c', '--course', 'course_id', required=True, type=str, help='COURSE ID.')
 @click.option('-co', '--content', 'content_id', required=True, type=str, help='CONTENT ID')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @update_exception_handler
-def update_content(ctx, course_id: str, content_id: str):
+def update_content(ctx, course_id: str, content_id: str, print_json: bool):
     response = contents_service.update_content(
         ctx.obj['SESSION'], course_id, content_id)
-    click.echo(response)
+    contents_view.print_updated_content_response(json.loads(response), print_json)
 
 
 """
diff --git a/bbcli/commands/courses.py b/bbcli/commands/courses.py
index 39f063c33b7b58b064249095cf1cc617c6ac86ce..d7e26983b4354992985ce67a291818372ceeea67 100644
--- a/bbcli/commands/courses.py
+++ b/bbcli/commands/courses.py
@@ -1,7 +1,7 @@
 import click
 from bbcli.services import courses_service
 from bbcli.utils.error_handler import list_exception_handler
-from bbcli.views import course_view
+from bbcli.views import courses_view
 import os
 import requests
 
@@ -10,15 +10,16 @@ import requests
 @click.command(name='list', help='List courses')
 @click.option('-c', '--course', 'course_id', required=False, type=str, help='[COURSE ID] Get information about a specific course')
 @click.option('-a', '--all/--no-all', 'show_all', default=False, help='List all registered courses on the current user')
+@click.option('-j', '--json', 'print_json', required=False, is_flag=True, help='Print the data in json format')
 @click.pass_context
 @list_exception_handler
-def list_courses(ctx, course_id=None, show_all=False):
+def list_courses(ctx, course_id=None, show_all=False, print_json=False):
     response = None
 
     if course_id:
         response = courses_service.list_course(
             session=ctx.obj['SESSION'], course_id=course_id)
-        course_view.print_course(response)
+        courses_view.print_course(response, print_json)
     else:
         user_name = os.getenv('BB_USERNAME')
         if show_all:
@@ -27,4 +28,4 @@ def list_courses(ctx, course_id=None, show_all=False):
         else:
             response = courses_service.list_courses(
                 session=ctx.obj['SESSION'], user_name=user_name)
-        course_view.print_courses(response)
+        courses_view.print_courses(response, print_json)
diff --git a/bbcli/services/announcements_service.py b/bbcli/services/announcements_service.py
index f957f0c6f5d1a414b31943451164a3f134cabfe9..071a27dff06a8313c63a313d79e7b03df9df2cfa 100644
--- a/bbcli/services/announcements_service.py
+++ b/bbcli/services/announcements_service.py
@@ -89,7 +89,7 @@ def delete_announcement(session: requests.Session, course_id: str, announcement_
         course_id).add_announcements().add_id(announcement_id).create()
     response = session.delete(url)
     response.raise_for_status()
-    return response
+    return response.text
 
 
 def update_announcement(session: requests.Session, course_id: str, announcement_id: str):
diff --git a/bbcli/services/assignment_service.py b/bbcli/services/assignment_service.py
index cd9afd82ca16a60d8b41c479760b717eb1fc1cdb..e9c018c47c0f5c6c7a5daae261a9d593722fa73a 100644
--- a/bbcli/services/assignment_service.py
+++ b/bbcli/services/assignment_service.py
@@ -21,25 +21,7 @@ def get_assignments(session: requests.Session, course_id):
     results = response['results']
     return results
 
-# TODO: This should be in view
-def print_assignments(assignments):
-    for i in range(len(assignments)):
-        column_id = assignments[i]['id']
-        name = assignments[i]['name']
-        due = 'N/A'
-        if 'grading' in assignments[i]:
-            if 'due' in assignments[i]['grading']:
-                due = assignments[i]['grading']['due']
-                due_datetime = utc_to_local(dateutil.parser.parse(due))
-                date = str(due_datetime.date())
-                time = str(due_datetime.time())
-                due = f'{date} {time}'
 
-        click.echo('{:<12s}{:<40s} due {:<10s}'.format(column_id, name, due))
-
-
-def utc_to_local(utc_dt):
-    return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
 
 
 def get_column_attempts(session: requests.Session, course_id, column_id):
@@ -52,36 +34,6 @@ def get_column_attempts(session: requests.Session, course_id, column_id):
     results = response['results']
     return results
 
-
-def print_submitted_attempts(attempts):
-    table = {'id': [], 'user id': [], 'status': [], 'score': [], 'created': []}
-    statuses = ['NeedsGrading', 'Completed']
-    for attempt in attempts:
-        for status in statuses:
-            if (status == attempt['status']):
-                append_to_table(attempt, table)
-                continue
-
-    click.echo(tabulate(table, headers='keys'))
-
-
-def print_all_attempts(attempts):
-    table = {'id': [], 'user id': [], 'status': [], 'score': [], 'created': []}
-    for attempt in attempts:
-        append_to_table(attempt, table)
-    click.echo(tabulate(table, headers='keys'))
-
-
-def append_to_table(attempt, table):
-    table['id'].append(attempt['id'])
-    table['user id'].append(attempt['userId'])
-    table['status'].append(attempt['status'])
-    table['score'].append(
-        attempt['score']) if 'score' in attempt else table['score'].append('N/A')
-    created = utc_to_local(dateutil.parser.parse(attempt['created']))
-    table['created'].append(created)
-
-
 def get_column_attempt(session: requests.Session, course_id, column_id, attempt_id):
     url = url_builder.base_v2().add_courses().add_id(course_id).add_gradebook(
     ).add_columns().add_id(column_id).add_attempts().add_id(attempt_id).create()
@@ -115,7 +67,7 @@ def create_column_attempt(session: requests.Session, course_id, column_id, stude
         update_column_attempt(session, course_id, column_id,
                               attempt_id, status='NeedsGrading')
 
-    return response_json
+    return json.dumps(response_json, indent=2)
 
 
 def update_column_attempt(session: requests.Session, course_id, column_id, attempt_id, status=None, score=None, text=None, notes=None, feedback=None, studentComments=None, studentSubmission=None, exempt=None, dst=None):
@@ -135,7 +87,7 @@ def update_column_attempt(session: requests.Session, course_id, column_id, attem
     if dst is not None:
         attach_file(session, course_id, attempt_id, dst)
 
-    return response
+    return json.dumps(response, indent=2)
 
 def attach_file(session: requests.Session, course_id, attempt_id, dst: str):
     url = url_builder.base_v1().add_courses().add_id(
diff --git a/bbcli/services/contents_service.py b/bbcli/services/contents_service.py
index b252889e53773bf241e90bc4d5ef318234fadbf6..bf88206baa02c1eac4499d0571ee17c9d1174716 100644
--- a/bbcli/services/contents_service.py
+++ b/bbcli/services/contents_service.py
@@ -88,6 +88,7 @@ def upload_attachment(session: requests.Session, course_id: str, content_id: str
         course_id).add_contents().add_id(content_id).add_attachments().create()
     response = session.post(url, data=data)
     response.raise_for_status()
+    return response.text
 
 
 def create_document(session: requests.Session, course_id: str, parent_id: str, title: str, standard_options: StandardOptions = None, attachments: tuple = None):
diff --git a/bbcli/services/courses_service.py b/bbcli/services/courses_service.py
index 2f5454bffc9ad148372df9fb9d9a79aa012107e4..1699bea1dc98c0938090dc8f1446baf49035593b 100644
--- a/bbcli/services/courses_service.py
+++ b/bbcli/services/courses_service.py
@@ -19,14 +19,10 @@ def list_courses(session: requests.Session, user_name: str) -> Any:
     course_memberships = get_course_memberships(session, user_name)
 
     courses = get_courses_from_course_memberships(session, course_memberships)
-
     course_list = []
     for course in courses:    
         if course['termId'] == term_1['id'] or course['termId'] == term_2['id']:
-            course_list.append({
-                'id': course['id'],
-                'name': course['name']
-            })
+            course_list.append(course)
         else:
             break
     
@@ -47,7 +43,6 @@ def list_course(session: requests.Session, course_id: str) -> Any:
     response.raise_for_status()
     return json.loads(response.text)
 
-
 """
 
 HELPER FUNCTIONS
@@ -88,7 +83,7 @@ def get_courses_from_course_memberships(session: requests.Session, course_member
     for course in course_memberships:
         url = url_builder.base_v3().add_courses().add_id(
             course['courseId']).create()
-        response = session.get(url, params={'fields': 'id, name, termId'})
+        response = session.get(url)
         response.raise_for_status()
         response = json.loads(response.text)
         courses.append(response)
diff --git a/bbcli/utils/utils.py b/bbcli/utils/utils.py
index 071dabea6f80852769fcd4bf29269459a3759607..590d919782e9e6ce087151d0fd1b3cafb0ae2f6f 100644
--- a/bbcli/utils/utils.py
+++ b/bbcli/utils/utils.py
@@ -1,7 +1,7 @@
 import os
 from datetime import datetime
 import mmap
-from typing import List
+from typing import Dict, List
 from requests import Session
 import html2text
 import click
@@ -108,4 +108,11 @@ def handle_fish_shell_completion():
     if is_activated == False:
         with open(path, 'a') as f:
             f.write(f'\n{append_text}\n')
-            click.echo('Shell completion activated! Restart shell to load the changes.')
\ No newline at end of file
+            click.echo('Shell completion activated! Restart shell to load the changes.')
+
+def print_keys_in_dict(dictionary: Dict):
+    for key in dictionary:
+        if isinstance(dictionary[key], dict):
+            print_keys_in_dict(dictionary[key])
+        elif dictionary[key] != None:
+            click.echo('{:<20} {:20}'.format(f'{key}:', str(dictionary[key])))
\ No newline at end of file
diff --git a/bbcli/views/announcement_view.py b/bbcli/views/announcements_view.py
similarity index 74%
rename from bbcli/views/announcement_view.py
rename to bbcli/views/announcements_view.py
index 26fce2b84c56292621e8f18223af989cd132d951..323e5b11907a443eb3e23f97f28e8308f4ec78fc 100644
--- a/bbcli/views/announcement_view.py
+++ b/bbcli/views/announcements_view.py
@@ -1,6 +1,7 @@
+import json
 import click
 from typing import Dict, List
-from bbcli.utils.utils import html_to_text
+from bbcli.utils.utils import html_to_text, print_keys_in_dict
 
 def print_announcement(announcement: Dict):
     announcement_id = announcement['id']
@@ -21,13 +22,22 @@ def print_announcements(announcements: List):
 def print_course_announcements(course_announcements: List, course_name: str = None):
     course_announcements = course_announcements['results']
     course_announcements.reverse()
+    
+    click.echo('\n')
+    table = {'id': [], 'title': [], 'body': [], 'date': []}
     for announcement in course_announcements:
         if 'body' in announcement:
+
             announcement_id = announcement['id']
             title = announcement['title']
             body = html_to_text(announcement['body'])
             created = announcement['created'].split('T')[0]
 
+            table['id'].append(announcement_id)
+            table['title'].append(title)
+            table['body'].append(body)
+            table['date'].append(created)
+            
             click.echo('----------------------------------------------------------------------\n')
             if course_name:
                 click.echo(f'{course_name}\n')
@@ -37,11 +47,16 @@ def print_course_announcements(course_announcements: List, course_name: str = No
             click.echo('\n{:<15}\n'.format(body))
 
 def print_announcement_created(announcement):
-    click.echo('\nAnnouncement sucessfully created:\n\n' + announcement)
+    data = json.loads(announcement)
+    click.echo('\nAnnouncement sucessfully created:\n')
+    print_keys_in_dict(data)
 
 
 def print_announcement_deleted():
     click.echo('\nAnnouncement sucessfully deleted.\n')
 
 def print_announcement_updated(announcement):
-    click.echo('\nAnnouncement sucessfully updated:\n\n' + announcement)
+    data = json.loads(announcement)
+    click.echo('\nAnnouncement sucessfully updated:\n')
+    print_keys_in_dict(data)
+        
\ No newline at end of file
diff --git a/bbcli/views/assignments_view.py b/bbcli/views/assignments_view.py
new file mode 100644
index 0000000000000000000000000000000000000000..b5fef147744d85a73423bbb3b90a1bde19351c25
--- /dev/null
+++ b/bbcli/views/assignments_view.py
@@ -0,0 +1,97 @@
+import json
+import click
+from datetime import timezone
+import dateutil.parser
+from bbcli.utils.utils import print_keys_in_dict
+from tabulate import tabulate
+
+
+def print_created_assignment(response, print_json):
+    if print_json:
+        click.echo(json.dumps(response, indent=2))
+    else:
+        click.echo('\nAssignment successfully created: \n')
+        print_keys_in_dict(response)
+
+
+def print_assignments(assignments):
+    click.echo('\n')
+    table = {'id': [], 'title': [], 'due': []}
+    for i in range(len(assignments)):
+        column_id = assignments[i]['id']
+        name = assignments[i]['name']
+        due = 'N/A'
+        if 'grading' in assignments[i]:
+            if 'due' in assignments[i]['grading']:
+                due = assignments[i]['grading']['due']
+                due_datetime = utc_to_local(dateutil.parser.parse(due))
+                date = str(due_datetime.date())
+                time = str(due_datetime.time())
+                due = f'{date} {time}'
+        table['id'].append(column_id)
+        table['title'].append(name)
+        table['due'].append(due)
+
+    click.echo(tabulate(table, headers=['Id', 'Title', 'Due date']))
+    click.echo('\n')
+
+
+def utc_to_local(utc_dt):
+    return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
+
+def print_submitted_attempts(attempts, print_json):
+    if print_json:
+        for attempt in attempts:
+            if attempt['status'] == 'InProgress':
+                attempts.remove(attempt)
+
+        click.echo(json.dumps(attempts, indent=2))
+    else:
+        table = {'id': [], 'user_id': [], 'status': [], 'score': [], 'created': []}
+        statuses = ['NeedsGrading', 'Completed']
+        for attempt in attempts:
+            for status in statuses:
+                if (status == attempt['status']):
+                    append_to_table(attempt, table)
+                    continue
+
+        click.echo(tabulate(table, headers=['Id', 'User Id', 'Status', 'Score', 'Created']))
+
+
+def print_all_attempts(attempts, print_json):
+    if print_json:
+        click.echo(json.dumps(attempts, indent=2))
+    else:
+        table = {'id': [], 'user_id': [], 'status': [], 'score': [], 'created': []}
+        for attempt in attempts:
+            append_to_table(attempt, table)
+        click.echo(tabulate(table, headers=['Id', 'User Id', 'Status', 'Score', 'Created']))
+
+
+def append_to_table(attempt, table):
+    table['id'].append(attempt['id'])
+    table['user_id'].append(attempt['userId'])
+    table['status'].append(attempt['status'])
+    table['score'].append(
+        attempt['score']) if 'score' in attempt else table['score'].append('N/A')
+    created = utc_to_local(dateutil.parser.parse(attempt['created']))
+    table['created'].append(created)
+
+def print_get_attempt(attempt):
+    print_keys_in_dict(attempt)
+
+def print_submitted_attempt(attempt):
+    click.echo('\nAssignment successfully submitted: \n')
+    print_keys_in_dict(attempt)
+
+def print_submitted_draft(attempt):
+    click.echo('\nAssignment draft successfully submitted: \n')
+    print_keys_in_dict(attempt)
+
+def print_updated_attempt(attempt):
+    click.echo('\nAttempt successfully updated: \n')
+    print_keys_in_dict(attempt)
+
+def print_graded_attempt(attempt):
+    click.echo('\nAttempt successfully graded: \n')
+    print_keys_in_dict(attempt)
\ No newline at end of file
diff --git a/bbcli/views/contents_view.py b/bbcli/views/contents_view.py
index 39f320edbddc7c33796cfb224550e30bf028ad9c..e24ffea0c3f21ba73b3847a81c5a827cfbe96586 100644
--- a/bbcli/views/contents_view.py
+++ b/bbcli/views/contents_view.py
@@ -1,6 +1,7 @@
+import json
 from anytree import Node as Nd, RenderTree
 from colorama import Fore, Style
-from bbcli.utils.utils import html_to_text
+from bbcli.utils.utils import html_to_text, print_keys_in_dict
 import click
 import tempfile, os
 from subprocess import call
@@ -44,3 +45,26 @@ def open_less_page(str):
     pydoc.pager(str)
 
 
+def print_created_attachment_response(response, print_json):
+    if print_json:
+        click.echo(json.dumps(response, indent=2))
+    else:
+        click.echo('\nAttachment successfully uploaded: \n')
+        print_keys_in_dict(response)
+
+def print_created_content_response(response, print_json):
+    if print_json:
+        click.echo(json.dumps(response, indent=2))
+    else:
+        click.echo('\nContent successfully created: \n')
+        print_keys_in_dict(response)
+
+def print_deleted_content_response():
+    click.echo('\nContent successfully deleted.\n')
+
+def print_updated_content_response(response, print_json):
+    if print_json:
+        click.echo(json.dumps(response, indent=2))
+    else:
+        click.echo('\nContent successfully updated: \n')
+        print_keys_in_dict(response)
\ No newline at end of file
diff --git a/bbcli/views/course_view.py b/bbcli/views/course_view.py
deleted file mode 100644
index 2320342b5c914adba28da36c3b9f6f99d7270c9d..0000000000000000000000000000000000000000
--- a/bbcli/views/course_view.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import click
-
-def print_courses(courses):
-    click.echo('\n{:<12} {:<5}\n'.format('Id', 'Course Name'))
-    for course in courses:
-        course_id = course['id']
-        name = course['name']
-        click.echo('{:<12} {:<5}'.format(course_id, name))
-    click.echo('\n\n')
-
-def print_course(course):
-
-    primary_id = course['id']
-    course_id = course['courseId']
-    name = course['name']
-
-    click.echo('\n{:<12} {:<12}'.format('Id:', primary_id))
-    click.echo('{:<12} {:<12}'.format('Course Id:', course_id))
-    click.echo('{:<12} {:<12}\n'.format('Name:', name))
\ No newline at end of file
diff --git a/bbcli/views/courses_view.py b/bbcli/views/courses_view.py
new file mode 100644
index 0000000000000000000000000000000000000000..be832182f4a6b238f77ba8e3c63dfdfee3ec9a1f
--- /dev/null
+++ b/bbcli/views/courses_view.py
@@ -0,0 +1,28 @@
+import json
+import click
+from tabulate import tabulate
+
+def print_courses(courses, print_json):
+    if print_json:
+        click.echo(json.dumps(courses, indent=2))
+    else:
+        click.echo('\n')
+        table = {'id': [], 'course_name': []}
+        for course in courses:
+            table['id'].append(course['id'])
+            table['course_name'].append(course['name'])
+
+        click.echo(tabulate(table, headers=['Id', 'Course Name']))
+        click.echo('\n')
+
+def print_course(course, print_json):
+    if print_json:
+        click.echo(json.dumps(course, indent=2))
+    else:
+        primary_id = course['id']
+        course_id = course['courseId']
+        name = course['name']
+
+        click.echo('\n{:<12} {:<12}'.format('Id:', primary_id))
+        click.echo('{:<12} {:<12}'.format('Course Id:', course_id))
+        click.echo('{:<12} {:<12}\n'.format('Name:', name))
\ No newline at end of file
diff --git a/tests/test_services/test_announcements_services.py b/tests/test_services/test_announcements_services.py
index db18c09e2dc36fbf674df19d0631490ce5834091..16cf33aa3ece388ac2f05522b4e3fde982c20cb2 100644
--- a/tests/test_services/test_announcements_services.py
+++ b/tests/test_services/test_announcements_services.py
@@ -160,10 +160,11 @@ class TestAnnouncementsServices(object):
         mock_delete = mock_delete_patcher.start()
         mock_delete.return_value.ok = True
         mock_delete.return_value.status_code = 204
+        mock_delete.return_value.text = ''
 
         response = delete_announcement(self.test_session, 'test_course_id', 'test_announcement_id')
-        
-        assert_equal(response.status_code, 204)
+
+        assert_equal(response, '')
 
     @raises(requests.exceptions.HTTPError)
     def test_delete_announcement_with_wrong_announcement_id(self):
diff --git a/tests/test_services/test_assignments_services.py b/tests/test_services/test_assignments_services.py
index 8aa6ca74ac6d3b0ed3021fc2915c652da013b491..07f846b4b0e847f4316e07530989788727f4f3ec 100644
--- a/tests/test_services/test_assignments_services.py
+++ b/tests/test_services/test_assignments_services.py
@@ -105,5 +105,5 @@ class TestAssignmentsServices(object):
 
         response = update_column_attempt(self.test_session, 'test_course_id', 'test_column_id', 'test_attempt_id')
 
-        assert_equal(response, TEST_GRADE_ATTEMPT)
+        assert_equal(json.loads(response), TEST_GRADE_ATTEMPT)
 
diff --git a/tests/test_services/test_courses_services.py b/tests/test_services/test_courses_services.py
index c5620de0e33a6a9d3ae36b464bee5f337a9bc572..ee2fc81cf50eb80040f5d1e360062c2a64d8c687 100644
--- a/tests/test_services/test_courses_services.py
+++ b/tests/test_services/test_courses_services.py
@@ -38,12 +38,12 @@ TEST_COURSE = {
         'externalAccessUrl':'https://ntnu.blackboard.com/ultra/courses/_33050_1/cl/outline'
     }
     
-TEST_COURSE_LIST = [{'id': '_33050_1', 'name': 'Donn Alexander Morrison testrom', 'termId': '_108_1'}, {'id': '_32909_1', 'name': 'Sammenslått - Ingeniørfaglig systemtenkning INGA2300 INGG2300 INGT2300 (2022 VÅR)', 'termId': '_108_1'}, {'id': '_31606_1', 'name': 'INGT2300 Ingeniørfaglig systemtenkning (2022 VÅR)', 'termId': '_108_1'}, {'id': '_32736_1', 'name': 'Sammenslått - Matematiske metoder 3 for dataingeniører IMAX2150 (2021 HØST)', 'termId': '_107_1'}, {'id': '_28936_1', 'name': 'IMAT2150 Matematiske metoder 3 for dataingeniører (2021 HØST)', 'termId': '_107_1'}, {'id': '_27251_1', 'name': 'IDATT2900 Bacheloroppgave  (start 2021 HØST)', 'termId': '_107_1'}, {'id': '_26748_1', 'name': 'Sammenslått - Fysikk/kjemi (2021 vår)', 'termId': '_64_1'}, {'id': '_21080_1', 'name': 'IFYT1001 Fysikk (2021 VÅR)', 'termId': '_64_1'}, {'id': '_22151_1', 'name': 'IDATT2106 Systemutvikling 2 med smidig prosjekt (2021 VÅR)', 'termId': '_64_1'}, {'id': '_22056_1', 'name': 'IDATT2105 Full-stack applikasjonsutvikling (2021 VÅR)', 'termId': '_64_1'}, {'id': '_22212_1', 'name': 'IDATT2104 Nettverksprogrammering (2021 VÅR)', 'termId': '_64_1'}, {'id': '_7921_1', 'name': 'Lab IIR', 'termId': '_28_1'}, {'id': '_26511_1', 'name': 'Dataingeniør Trondheim (BIDATA): Kull 2020', 'termId': '_63_1'}, {'id': '_26287_1', 'name': 'Sammenslått - Statistikk ISTX1001 ISTX1002 ISTX1003 (2020 HØST)', 'termId': '_63_1'}, {'id': '_21671_1', 'name': 'ISTT1003 Statistikk (2020 HØST)', 'termId': '_63_1'}, {'id': '_26170_1', 'name': 'IDATT2202 Operativsystemer (2020 HØST)', 'termId': '_63_1'}, {'id': '_22259_1', 'name': 'IDATT2103 Databaser (2020 HØST)', 'termId': '_63_1'}, {'id': '_22398_1', 'name': 'IDATT2101 Algoritmer og datastrukturer (2020 HØST)', 'termId': '_63_1'}, {'id': '_20124_1', 'name': 'IMAT2021 Matematiske metoder 2 for Dataingeniør (2020 VÅR)', 'termId': '_49_1'}, {'id': '_18976_1', 'name': 'IDATT2001 Programmering 2 (2020 VÅR)', 'termId': '_49_1'}, {'id': '_19418_1', 'name': 'IDATT1002 Systemutvikling (2020 VÅR)', 'termId': '_49_1'}, {'id': '_20377_1', 'name': 'Bachelor i Dataingeniør 2019-2022', 'termId': '_46_1'}, {'id': '_18715_1', 'name': 'HMS0002 HMS-kurs for 1. årsstudenter (2019 HØST)', 'termId': '_46_1'}, {'id': '_20187_1', 'name': 'Sammenslått - Ingeniørfaglig innføringsemne (2019 HØST)', 'termId': '_46_1'}, {'id': '_16575_1', 'name': 'INGT1001 Ingeniørfaglig innføringsemne (2019 HØST)', 'termId': '_46_1'}, {'id': '_20275_1', 'name': 'Sammenslått - Matematiske metoder 1 (2019 HØST)', 'termId': '_46_1'}, {'id': '_20016_1', 'name': 'IMAT1001 Matematiske metoder 1 (2019 HØST)', 'termId': '_46_1'}, {'id': '_19119_1', 'name': 'IDATT1001 Programmering 1 (2019 HØST)', 'termId': '_46_1'}]
+TEST_COURSE_LIST = [{'id': '_33050_1', 'uuid': '909cbb1f296140f3ab307df8bc1a0ee3', 'externalId': '194_DAMTEST_2022V_1', 'dataSourceId': '_209_1', 'courseId': '194_DAMTEST_2022V_1', 'name': 'Donn Alexander Morrison testrom', 'created': '2022-02-03T14:10:39.451Z', 'modified': '2022-02-03T14:10:45.960Z', 'organization': False, 'ultraStatus': 'Classic', 'allowGuests': False, 'allowObservers': False, 'closedComplete': False, 'termId': '_108_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'id': 'en_US', 'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_33050_1/cl/outline'}, {'id': '_32909_1', 'courseId': 'MERGE_INGA2300_INGG2300_INGT2300_V22', 'name': 'Sammenslått - Ingeniørfaglig systemtenkning INGA2300 INGG2300 INGT2300 (2022 VÅR)', 'modified': '2022-01-26T23:19:18.859Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_108_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_32909_1/cl/outline'}, {'id': '_31606_1', 'courseId': '194_INGT2300_1_2022_V_1', 'name': 'INGT2300 Ingeniørfaglig systemtenkning (2022 VÅR)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_108_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_32736_1', 'courseId': 'MERGE_IMAT2150_IMAG2150_IMAA2150_H21', 'name': 'Sammenslått - Matematiske metoder 3 for dataingeniører IMAX2150 (2021 HØST)', 'modified': '2021-08-18T05:58:44.953Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_107_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_32736_1/cl/outline'}, {'id': '_28936_1', 'courseId': '194_IMAT2150_1_2021_H_1', 'name': 'IMAT2150 Matematiske metoder 3 for dataingeniører (2021 HØST)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_107_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_27251_1', 'courseId': '194_IDATT2900_1_2021_H_1', 'name': 'IDATT2900 Bacheloroppgave  (start 2021 HØST)', 'modified': '2022-04-24T02:15:13.555Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_107_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_27251_1/cl/outline'}, {'id': '_26748_1', 'courseId': 'MERGE_IFYKJA100X_IFYKJG100X_IFYKJT100X_V21', 'name': 'Sammenslått - Fysikk/kjemi (2021 vår)', 'modified': '2021-12-14T05:55:57.716Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_64_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_26748_1/cl/outline'}, {'id': '_21080_1', 'courseId': '194_IFYT1001_1_2021_V_1', 'name': 'IFYT1001 Fysikk (2021 VÅR)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_64_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_22151_1', 'courseId': '194_IDATT2106_1_2021_V_1', 'name': 'IDATT2106 Systemutvikling 2 med smidig prosjekt (2021 VÅR)', 'modified': '2021-09-16T07:23:19.806Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_64_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_22151_1/cl/outline'}, {'id': '_22056_1', 'courseId': '194_IDATT2105_1_2021_V_1', 'name': 'IDATT2105 Full-stack applikasjonsutvikling (2021 VÅR)', 'modified': '2021-09-16T07:23:20.422Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_64_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_22056_1/cl/outline'}, {'id': '_22212_1', 'courseId': '194_IDATT2104_1_2021_V_1', 'name': 'IDATT2104 Nettverksprogrammering (2021 VÅR)', 'modified': '2021-09-16T07:23:19.778Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_64_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_22212_1/cl/outline'}, {'id': '_7921_1', 'courseId': '017AU_004DA_006EK_001', 'name': 'Lab IIR', 'description': 'Program: 017AU_004DA_006EK Type organisasjon: Program Enhet: IE-IIR', 'modified': '2021-07-01T05:06:30.725Z', 'organization': True, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_28_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_7921_1/cl/outline'}, {'id': '_26511_1', 'courseId': 'BIDATA_2020_H_001', 'name': 'Dataingeniør Trondheim (BIDATA): Kull 2020', 'description': 'Program: BIDATA Organisasjon: KULL Enhet: IE-IDI', 'modified': '2021-07-01T05:12:33.492Z', 'organization': True, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_63_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_26511_1/cl/outline'}, {'id': '_26287_1', 'courseId': 'MERGE_ISTX1001_ISTX1002_ISTX1003_H20', 'name': 'Sammenslått - Statistikk ISTX1001 ISTX1002 ISTX1003 (2020 HØST)', 'modified': '2021-08-11T07:00:32.233Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_63_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_26287_1/cl/outline', 'guestAccessUrl': 'https://ntnu.blackboard.com/webapps/login?action=guest_login&new_loc=/ultra/courses/_26287_1/cl/outline'}, {'id': '_21671_1', 'courseId': '194_ISTT1003_1_2020_H_1', 'name': 'ISTT1003 Statistikk (2020 HØST)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_63_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_26170_1', 'courseId': '194_IDATT2202_1_2020_H_1', 'name': 'IDATT2202 Operativsystemer (2020 HØST)', 'modified': '2021-07-01T05:12:02.694Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_63_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'id': 'en_US', 'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_26170_1/cl/outline'}, {'id': '_22259_1', 'courseId': '194_IDATT2103_1_2020_H_1', 'name': 'IDATT2103 Databaser (2020 HØST)', 'modified': '2021-07-01T05:19:34.676Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_63_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_22259_1/cl/outline'}, {'id': '_22398_1', 'courseId': '194_IDATT2101_1_2020_H_1', 'name': 'IDATT2101 Algoritmer og datastrukturer (2020 HØST)', 'modified': '2021-07-01T05:18:39.655Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_63_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_22398_1/cl/outline'}, {'id': '_20124_1', 'courseId': '194_IMAT2021_1_2020_V_1', 'name': 'IMAT2021 Matematiske metoder 2 for Dataingeniør (2020 VÅR)', 'modified': '2021-07-01T05:10:15.667Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_49_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_20124_1/cl/outline'}, {'id': '_18976_1', 'courseId': '194_IDATT2001_1_2020_V_1', 'name': 'IDATT2001 Programmering 2 (2020 VÅR)', 'modified': '2021-07-01T05:17:08.560Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_49_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_18976_1/cl/outline'}, {'id': '_19418_1', 'courseId': '194_IDATT1002_1_2020_V_1', 'name': 'IDATT1002 Systemutvikling (2020 VÅR)', 'modified': '2021-07-01T05:17:51.960Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_49_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_19418_1/cl/outline'}, {'id': '_20377_1', 'courseId': 'BIDATA_2019_H_001', 'name': 'Bachelor i Dataingeniør 2019-2022', 'description': 'Program: BIDATA Type organisasjon: KULL Program Enhet: IE-IDI', 'modified': '2021-07-01T05:10:39.409Z', 'organization': True, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_20377_1/cl/outline'}, {'id': '_18715_1', 'courseId': '194_HMS0002_1_2019_H_1', 'name': 'HMS0002 HMS-kurs for 1. årsstudenter (2019 HØST)', 'modified': '2021-07-01T05:19:08.996Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_18715_1/cl/outline'}, {'id': '_20187_1', 'courseId': 'MERGE_INGA1001_INGG1001_INGT1001_H19', 'name': 'Sammenslått - Ingeniørfaglig innføringsemne (2019 HØST)', 'modified': '2021-07-01T05:08:29.664Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_20187_1/cl/outline'}, {'id': '_16575_1', 'courseId': '194_INGT1001_1_2019_H_1', 'name': 'INGT1001 Ingeniørfaglig innføringsemne (2019 HØST)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_20275_1', 'courseId': 'MERGE_IMAT1001_IMAG1001_IMAA1001_H19', 'name': 'Sammenslått - Matematiske metoder 1 (2019 HØST)', 'modified': '2021-07-01T05:10:47.819Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_20275_1/cl/outline'}, {'id': '_20016_1', 'courseId': '194_IMAT1001_1_2019_H_1', 'name': 'IMAT1001 Matematiske metoder 1 (2019 HØST)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_19119_1', 'courseId': '194_IDATT1001_1_2019_H_1', 'name': 'IDATT1001 Programmering 1 (2019 HØST)', 'modified': '2021-07-01T05:18:06.952Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_46_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_19119_1/cl/outline'}]
 
 TEST_TERMS_LIST = [{'id': '_22_1', 'name': 'Andre', 'description': '<p>Emner som ikke faller i vanlige semester-terminologi. F.eks. test-emner, sommerkurs o.l.</p>', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_40_1', 'name': 'Høst 2013', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2013-08-14T22:00:00.000Z', 'end': '2014-01-01T22:59:59.000Z'}}}, {'id': '_41_1', 'name': 'Høst 2014', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2014-08-14T22:00:00.000Z', 'end': '2015-01-01T22:59:59.000Z'}}}, {'id': '_31_1', 'name': 'Høst 2015', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2015-08-14T22:00:00.000Z', 'end': '2016-01-01T22:59:59.000Z'}}}, {'id': '_23_1', 'name': 'Høst 2016', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2016-08-14T22:00:00.000Z', 'end': '2017-01-01T22:59:59.000Z'}}}, {'id': '_28_1', 'name': 'Høst 2017', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2017-08-14T22:00:00.000Z', 'end': '2018-01-01T22:59:59.000Z'}}}, {'id': '_35_1', 'name': 'Høst 2018', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2018-08-14T22:00:00.000Z', 'end': '2019-01-01T22:59:59.000Z'}}}, {'id': '_46_1', 'name': 'Høst 2019', 'description': '<p>2019 HØST</p>', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2019-06-30T22:00:00.000Z', 'end': '2020-01-01T22:59:59.000Z'}}}, {'id': '_63_1', 'name': 'Høst 2020', 'description': '2020 HØST', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2020-06-30T22:00:00.000Z', 'end': '2021-01-01T22:59:59.000Z'}}}, {'id': '_107_1', 'name': 'Høst 2021', 'description': '2021 HØST', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2021-06-30T22:00:00.000Z', 'end': '2022-01-01T22:59:59.000Z'}}}, {'id': '_47_1', 'name': 'Vår 2013', 'description': '2013 VÅR', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2012-12-31T23:00:00.000Z', 'end': '2013-08-15T21:59:59.000Z'}}}, {'id': '_48_1', 'name': 'Vår 2014', 'description': '2014 VÅR', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2013-12-31T23:00:00.000Z', 'end': '2014-08-15T21:59:59.000Z'}}}, {'id': '_39_1', 'name': 'Vår 2015', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2014-12-31T23:00:00.000Z', 'end': '2015-08-15T21:59:59.000Z'}}}, {'id': '_30_1', 'name': 'Vår 2016', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2015-12-31T23:00:00.000Z', 'end': '2016-08-15T21:59:59.000Z'}}}, {'id': '_25_1', 'name': 'Vår 2017', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2016-12-31T23:00:00.000Z', 'end': '2017-08-15T21:59:59.000Z'}}}, {'id': '_29_1', 'name': 'Vår 2018', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2017-12-31T23:00:00.000Z', 'end': '2018-08-15T21:59:59.000Z'}}}, {'id': '_37_1', 'name': 'Vår 2019', 'description': '<p>Vår 2019</p>', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2018-12-31T23:00:00.000Z', 'end': '2019-08-15T21:59:59.000Z'}}}, {'id': '_49_1', 'name': 'Vår 2020', 'description': '2020 VÅR', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2019-12-31T23:00:00.000Z', 'end': '2020-08-15T21:59:59.000Z'}}}, {'id': '_64_1', 'name': 'Vår 2021', 'description': '2021 VÅR', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2020-12-31T23:00:00.000Z', 'end': '2021-08-15T21:59:59.000Z'}}}, {'id': '_108_1', 'name': 'Vår 2022', 'description': '2022 VÅR', 'availability': {'available': 'Yes', 'duration': {'type': 'DateRange', 'start': '2021-12-31T23:00:00.000Z', 'end': '2022-08-15T21:59:59.000Z'}}}]
 TEST_COURSE_MEMBERSHIPS_LIST = [{'id': '_2202371_1', 'userId': '_140040_1', 'courseId': '_33050_1', 'dataSourceId': '_2_1', 'created': '2022-02-03T14:21:22.934Z', 'modified': '2022-04-07T10:41:10.608Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Instructor', 'lastAccessed': '2022-04-14T07:41:56.840Z'}, {'id': '_2170002_1', 'userId': '_140040_1', 'courseId': '_32909_1', 'childCourseId': '_31606_1', 'dataSourceId': '_190_1', 'created': '2022-01-10T13:52:35.968Z', 'modified': '2022-01-10T13:52:35.968Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-12T08:03:47.568Z'}, {'id': '_2170001_1', 'userId': '_140040_1', 'courseId': '_31606_1', 'dataSourceId': '_190_1', 'created': '2022-01-10T13:52:35.968Z', 'modified': '2022-01-10T13:52:40.055Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-12T08:09:50.538Z'}, {'id': '_1950113_1', 'userId': '_140040_1', 'courseId': '_32736_1', 'childCourseId': '_28936_1', 'dataSourceId': '_189_1', 'created': '2021-06-16T14:48:23.886Z', 'modified': '2021-08-22T03:39:59.747Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-13T08:44:48.605Z'}, {'id': '_1799061_1', 'userId': '_140040_1', 'courseId': '_28936_1', 'dataSourceId': '_189_1', 'created': '2021-06-16T14:48:23.886Z', 'modified': '2021-08-18T05:58:25.413Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-13T08:44:50.836Z'}, {'id': '_1799010_1', 'userId': '_140040_1', 'courseId': '_27251_1', 'dataSourceId': '_189_1', 'created': '2021-06-16T14:48:17.698Z', 'modified': '2021-07-01T21:44:55.485Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-13T18:49:48.217Z'}, {'id': '_1698193_1', 'userId': '_140040_1', 'courseId': '_26748_1', 'childCourseId': '_21080_1', 'dataSourceId': '_137_1', 'created': '2020-12-01T13:48:27.469Z', 'modified': '2021-07-01T18:56:35.176Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-02-24T12:46:33.685Z'}, {'id': '_1578419_1', 'userId': '_140040_1', 'courseId': '_21080_1', 'dataSourceId': '_137_1', 'created': '2020-12-01T13:48:27.469Z', 'modified': '2021-07-01T18:36:24.374Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student'}, {'id': '_1578296_1', 'userId': '_140040_1', 'courseId': '_22151_1', 'dataSourceId': '_137_1', 'created': '2020-12-01T13:48:17.232Z', 'modified': '2021-07-01T18:33:54.962Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-02-24T12:47:30.901Z'}, {'id': '_1578292_1', 'userId': '_140040_1', 'courseId': '_22056_1', 'dataSourceId': '_137_1', 'created': '2020-12-01T13:48:16.815Z', 'modified': '2021-07-01T21:02:13.469Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-02-23T12:02:28.245Z'}, {'id': '_1578288_1', 'userId': '_140040_1', 'courseId': '_22212_1', 'dataSourceId': '_137_1', 'created': '2020-12-01T13:48:16.419Z', 'modified': '2021-07-01T22:00:31.942Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-06T07:11:32.061Z'}, {'id': '_1576797_1', 'userId': '_140040_1', 'courseId': '_7921_1', 'dataSourceId': '_2_1', 'created': '2020-12-01T08:18:46.350Z', 'modified': '2021-07-01T21:52:45.398Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-01-29T12:29:44.448Z'}, {'id': '_1471353_1', 'userId': '_140040_1', 'courseId': '_26511_1', 'dataSourceId': '_2_1', 'created': '2020-08-12T08:00:27.724Z', 'modified': '2021-07-01T18:05:27.249Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-01-27T23:14:36.786Z'}, {'id': '_1355366_1', 'userId': '_140040_1', 'courseId': '_26287_1', 'childCourseId': '_21671_1', 'dataSourceId': '_136_1', 'created': '2020-06-24T12:46:53.972Z', 'modified': '2021-07-01T21:46:01.545Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-01-30T20:14:48.151Z'}, {'id': '_1355365_1', 'userId': '_140040_1', 'courseId': '_21671_1', 'dataSourceId': '_136_1', 'created': '2020-06-24T12:46:53.972Z', 'modified': '2021-07-01T21:47:37.536Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student'}, {'id': '_1355339_1', 'userId': '_140040_1', 'courseId': '_26170_1', 'dataSourceId': '_136_1', 'created': '2020-06-24T12:46:50.584Z', 'modified': '2021-07-01T17:50:03.902Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-03-04T12:17:07.070Z'}, {'id': '_1355336_1', 'userId': '_140040_1', 'courseId': '_22259_1', 'dataSourceId': '_136_1', 'created': '2020-06-24T12:46:50.328Z', 'modified': '2021-07-01T20:49:45.419Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-02-27T10:06:08.755Z'}, {'id': '_1355334_1', 'userId': '_140040_1', 'courseId': '_22398_1', 'dataSourceId': '_136_1', 'created': '2020-06-24T12:46:50.156Z', 'modified': '2021-07-01T20:41:06.878Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-02-22T11:16:48.492Z'}, {'id': '_1157613_1', 'userId': '_140040_1', 'courseId': '_20124_1', 'dataSourceId': '_115_1', 'created': '2019-12-05T11:58:57.000Z', 'modified': '2021-07-01T20:30:11.616Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-11-03T12:11:21.815Z'}, {'id': '_1157600_1', 'userId': '_140040_1', 'courseId': '_18976_1', 'dataSourceId': '_115_1', 'created': '2019-12-05T11:58:55.000Z', 'modified': '2021-07-01T20:23:45.086Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-04-06T07:25:32.063Z'}, {'id': '_1157598_1', 'userId': '_140040_1', 'courseId': '_19418_1', 'dataSourceId': '_115_1', 'created': '2019-12-05T11:58:54.000Z', 'modified': '2021-07-01T18:06:54.921Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-02-22T11:16:48.492Z'}, {'id': '_1092393_1', 'userId': '_140040_1', 'courseId': '_20377_1', 'dataSourceId': '_2_1', 'created': '2019-09-06T06:46:20.000Z', 'modified': '2021-07-01T20:19:28.268Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-01-29T12:29:44.448Z'}, {'id': '_1041298_1', 'userId': '_140040_1', 'courseId': '_18715_1', 'dataSourceId': '_113_1', 'created': '2019-08-15T12:49:52.000Z', 'modified': '2021-07-01T21:38:11.204Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-01-29T12:29:44.448Z'}, {'id': '_1017688_1', 'userId': '_140040_1', 'courseId': '_20187_1', 'childCourseId': '_16575_1', 'dataSourceId': '_113_1', 'created': '2019-08-12T10:49:52.000Z', 'modified': '2021-07-01T21:40:08.101Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2022-02-24T12:50:33.685Z'}, {'id': '_1017687_1', 'userId': '_140040_1', 'courseId': '_16575_1', 'dataSourceId': '_113_1', 'created': '2019-08-12T10:49:52.000Z', 'modified': '2021-07-01T17:52:59.620Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student'}, {'id': '_1017686_1', 'userId': '_140040_1', 'courseId': '_20275_1', 'childCourseId': '_20016_1', 'dataSourceId': '_113_1', 'created': '2019-08-12T10:49:52.000Z', 'modified': '2021-07-01T17:19:27.132Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-02-22T11:16:48.492Z'}, {'id': '_1017685_1', 'userId': '_140040_1', 'courseId': '_20016_1', 'dataSourceId': '_113_1', 'created': '2019-08-12T10:49:52.000Z', 'modified': '2021-07-01T20:12:10.899Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student'}, {'id': '_1017684_1', 'userId': '_140040_1', 'courseId': '_19119_1', 'dataSourceId': '_113_1', 'created': '2019-08-12T10:49:52.000Z', 'modified': '2021-07-01T19:41:17.783Z', 'availability': {'available': 'Yes'}, 'courseRoleId': 'Student', 'lastAccessed': '2021-02-22T11:16:48.492Z'}]
 
-TEST_COURSE_LIST_SORTED_AND_SHORTENED = [{'id': '_33050_1', 'name': 'Donn Alexander Morrison testrom'}, {'id': '_32909_1', 'name': 'Sammenslått - Ingeniørfaglig systemtenkning INGA2300 INGG2300 INGT2300 (2022 VÅR)'}, {'id': '_31606_1', 'name': 'INGT2300 Ingeniørfaglig systemtenkning (2022 VÅR)'}, {'id': '_32736_1', 'name': 'Sammenslått - Matematiske metoder 3 for dataingeniører IMAX2150 (2021 HØST)'}, {'id': '_28936_1', 'name': 'IMAT2150 Matematiske metoder 3 for dataingeniører (2021 HØST)'}, {'id': '_27251_1', 'name': 'IDATT2900 Bacheloroppgave  (start 2021 HØST)'}]
+TEST_COURSE_LIST_SORTED_AND_SHORTENED = [{'id': '_33050_1', 'uuid': '909cbb1f296140f3ab307df8bc1a0ee3', 'externalId': '194_DAMTEST_2022V_1', 'dataSourceId': '_209_1', 'courseId': '194_DAMTEST_2022V_1', 'name': 'Donn Alexander Morrison testrom', 'created': '2022-02-03T14:10:39.451Z', 'modified': '2022-02-03T14:10:45.960Z', 'organization': False, 'ultraStatus': 'Classic', 'allowGuests': False, 'allowObservers': False, 'closedComplete': False, 'termId': '_108_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'id': 'en_US', 'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_33050_1/cl/outline'}, {'id': '_32909_1', 'courseId': 'MERGE_INGA2300_INGG2300_INGT2300_V22', 'name': 'Sammenslått - Ingeniørfaglig systemtenkning INGA2300 INGG2300 INGT2300 (2022 VÅR)', 'modified': '2022-01-26T23:19:18.859Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_108_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_32909_1/cl/outline'}, {'id': '_31606_1', 'courseId': '194_INGT2300_1_2022_V_1', 'name': 'INGT2300 Ingeniørfaglig systemtenkning (2022 VÅR)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_108_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_32736_1', 'courseId': 'MERGE_IMAT2150_IMAG2150_IMAA2150_H21', 'name': 'Sammenslått - Matematiske metoder 3 for dataingeniører IMAX2150 (2021 HØST)', 'modified': '2021-08-18T05:58:44.953Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_107_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_32736_1/cl/outline'}, {'id': '_28936_1', 'courseId': '194_IMAT2150_1_2021_H_1', 'name': 'IMAT2150 Matematiske metoder 3 for dataingeniører (2021 HØST)', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_107_1', 'availability': {'available': 'No', 'duration': {'type': 'Continuous'}}}, {'id': '_27251_1', 'courseId': '194_IDATT2900_1_2021_H_1', 'name': 'IDATT2900 Bacheloroppgave  (start 2021 HØST)', 'modified': '2022-04-24T02:15:13.555Z', 'organization': False, 'ultraStatus': 'Classic', 'closedComplete': False, 'termId': '_107_1', 'availability': {'available': 'Yes', 'duration': {'type': 'Continuous'}}, 'enrollment': {'type': 'InstructorLed'}, 'locale': {'force': False}, 'externalAccessUrl': 'https://ntnu.blackboard.com/ultra/courses/_27251_1/cl/outline'}]
 
 class TestCoursesServices(object):
     @classmethod