diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9b95b44ccc1bb44784266b97f8eda88cd95a1df2..ec03e6c7a3c11967d3ea35491508fb20c45f3af6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,77 +18,6 @@ before_script:
 .build:
   stage: build
 
-build:pip:
-  extends: .build
-  script:
-  - python3 -m build
-  artifacts:
-    paths:
-      - dist/*
-
-build:apt:
-  extends: .build
-  script:
-  - ./debian/create_changelog.py uffd > debian/changelog
-  - export PYBUILD_INSTALL_ARGS="--install-lib=/usr/share/uffd/ --install-scripts=/usr/share/uffd/"
-  - export DEB_BUILD_OPTIONS=nocheck
-  - dpkg-buildpackage -us -uc
-  - mv ../*.deb ./
-  - dpkg-deb -I *.deb
-  - dpkg-deb -c *.deb
-  artifacts:
-    paths:
-    - ./*.deb
-
-db_migrations_updated:
-  stage: test
-  needs: []
-  script:
-  - FLASK_APP=uffd FLASK_ENV=testing flask db upgrade
-  - FLASK_APP=uffd FLASK_ENV=testing flask db migrate 2>&1 | grep -q 'No changes in schema detected'
-
-linter:buster:
-  image: registry.git.cccv.de/uffd/docker-images/buster
-  stage: test
-  needs: []
-  script:
-  - pip3 install $PYLINT_PIN pylint-gitlab pylint-flask-sqlalchemy # this force-updates jinja2 and some other packages!
-  - python3 -m pylint --output-format=pylint_gitlab.GitlabCodeClimateReporter:codeclimate.json,pylint_gitlab.GitlabPagesHtmlReporter:pylint.html,colorized uffd
-  artifacts:
-    when: always
-    paths:
-    - pylint.html
-    reports:
-      codequality: codeclimate.json
-
-linter:bullseye:
-  image: registry.git.cccv.de/uffd/docker-images/bullseye
-  stage: test
-  needs: []
-  script:
-  - pip3 install $PYLINT_PIN pylint-gitlab pylint-flask-sqlalchemy # this force-updates jinja2 and some other packages!
-  - python3 -m pylint --output-format=pylint_gitlab.GitlabCodeClimateReporter:codeclimate.json,pylint_gitlab.GitlabPagesHtmlReporter:pylint.html,colorized uffd
-  artifacts:
-    when: always
-    paths:
-    - pylint.html
-    reports:
-      codequality: codeclimate.json
-
-linter:bookworm:
-  image: registry.git.cccv.de/uffd/docker-images/bookworm
-  stage: test
-  needs: []
-  script:
-  - pip3 install $PYLINT_PIN pylint-gitlab pylint-flask-sqlalchemy # this force-updates jinja2 and some other packages!
-  - python3 -m pylint --output-format=pylint_gitlab.GitlabCodeClimateReporter:codeclimate.json,pylint_gitlab.GitlabPagesHtmlReporter:pylint.html,colorized uffd
-  artifacts:
-    when: always
-    paths:
-    - pylint.html
-    reports:
-      codequality: codeclimate.json
-
 tests:buster:sqlite:
   image: registry.git.cccv.de/uffd/docker-images/buster
   stage: test
@@ -100,18 +29,6 @@ tests:buster:sqlite:
     reports:
       junit: report.xml
 
-tests:buster:mysql:
-  image: registry.git.cccv.de/uffd/docker-images/buster
-  stage: test
-  needs: []
-  script:
-  - service mysql start
-  - TEST_WITH_MYSQL=1 python3 -m pytest --junitxml=report.xml
-  artifacts:
-    when: always
-    reports:
-      junit: report.xml
-
 tests:bullseye:sqlite:
   image: registry.git.cccv.de/uffd/docker-images/bullseye
   stage: test
@@ -123,18 +40,6 @@ tests:bullseye:sqlite:
     reports:
       junit: report.xml
 
-tests:bullseye:mysql:
-  image: registry.git.cccv.de/uffd/docker-images/bullseye
-  stage: test
-  needs: []
-  script:
-  - service mariadb start
-  - TEST_WITH_MYSQL=1 python3 -m pytest --junitxml=report.xml
-  artifacts:
-    when: always
-    reports:
-      junit: report.xml
-
 tests:bookworm:sqlite:
   image: registry.git.cccv.de/uffd/docker-images/bookworm
   stage: test
@@ -162,138 +67,3 @@ tests:bookworm:sqlite:
         path: coverage.xml
       junit: report.xml
   coverage: '/^TOTAL.*\s+(\d+\%)$/'
-
-tests:bookworm:mysql:
-  image: registry.git.cccv.de/uffd/docker-images/bookworm
-  stage: test
-  needs: []
-  script:
-  - service mariadb start
-  - TEST_WITH_MYSQL=1 python3 -m pytest --junitxml=report.xml
-  artifacts:
-    when: always
-    reports:
-      junit: report.xml
-
-html5validator:
-  stage: test
-  needs:
-  - job: tests:bookworm:sqlite
-  script:
-  - html5validator --root pages 2>&1 | tee html5validator.log
-  artifacts:
-    when: on_failure
-    paths:
-    - pages
-    - html5validator.log
-
-.trans:
-  stage: test
-  needs: []
-  script:
-  - ./update_translations.sh $TRANSLATION_LANGUAGE
-  coverage: '/^TOTAL.*\s+(\d+\%)$/'
-trans_de:
-  extends: .trans
-  variables:
-    TRANSLATION_LANGUAGE: de
-
-test:package:pip:buster:
-  image: registry.git.cccv.de/uffd/docker-images/buster
-  stage: test
-  needs:
-  - job: build:pip
-  script:
-  - pip3 install dist/*.tar.gz
-
-test:package:pip:bullseye:
-  image: registry.git.cccv.de/uffd/docker-images/bullseye
-  stage: test
-  needs:
-  - job: build:pip
-  script:
-  - pip3 install dist/*.tar.gz
-
-test:package:pip:bookworm:
-  image: registry.git.cccv.de/uffd/docker-images/bookworm
-  stage: test
-  needs:
-  - job: build:pip
-  script:
-  - pip3 install dist/*.tar.gz
-
-# Since we want to test if the package installs correctly on a fresh Debian
-# install (has correct dependencies, etc.), we don't use uffd/docker-images
-# here
-test:package:apt:buster:
-  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:buster
-  stage: test
-  needs:
-  - job: build:apt
-  before_script: []
-  script:
-  - apt -y update
-  - apt -y install curl ./*.deb
-  - service uwsgi start uffd || ( service uwsgi status uffd ; sleep 15; cat /var/log/uwsgi/app/uffd.log; )
-  - echo "server { listen 127.0.0.1:5000 default_server;  include /etc/uffd/nginx.include.conf; }" > /etc/nginx/sites-enabled/uffd.ini
-  - service nginx start || ( service nginx status; nginx -t; exit 1; )
-  - uffd-admin routes
-  - curl -Lv 127.0.0.1:5000
-
-test:package:apt:bullseye:
-  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:bullseye
-  stage: test
-  needs:
-  - job: build:apt
-  before_script: []
-  script:
-  - apt -y update
-  - apt -y install curl ./*.deb
-  - service uwsgi start uffd || ( service uwsgi status uffd ; sleep 15; cat /var/log/uwsgi/app/uffd.log; )
-  - echo "server { listen 127.0.0.1:5000 default_server;  include /etc/uffd/nginx.include.conf; }" > /etc/nginx/sites-enabled/uffd.ini
-  - service nginx start || ( service nginx status; nginx -t; exit 1; )
-  - uffd-admin routes
-  - curl -Lv 127.0.0.1:5000
-
-test:package:apt:bookworm:
-  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:bookworm
-  stage: test
-  needs:
-  - job: build:apt
-  before_script: []
-  script:
-  - apt -y update
-  - apt -y install curl ./*.deb
-  - service uwsgi start uffd || ( service uwsgi status uffd ; sleep 15; cat /var/log/uwsgi/app/uffd.log; )
-  - echo "server { listen 127.0.0.1:5000 default_server;  include /etc/uffd/nginx.include.conf; }" > /etc/nginx/sites-enabled/uffd.ini
-  - service nginx start || ( service nginx status; nginx -t; exit 1; )
-  - uffd-admin routes
-  - curl -Lv 127.0.0.1:5000
-
-.publish:
-  stage: deploy
-  rules:
-    - if: '$CI_COMMIT_TAG =~ /v[0-9]+[.][0-9]+[.][0-9]+.*/'
-
-publish:pip:
-  extends: .publish
-  script:
-  - TWINE_USERNAME="${GITLABPKGS_USERNAME}" TWINE_PASSWORD="${GITLABPKGS_PASSWORD}" python3 -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
-  - TWINE_USERNAME="${PYPI_USERNAME}" TWINE_PASSWORD="${PYPI_PASSWORD}" python3 -m twine upload dist/*
-  dependencies:
-  - build:pip
-
-publish:apt:
-  extends: .publish
-  script:
-  - export DEBPATH="$(echo *.deb)"
-  - echo Upload deb file, add it to repo and clean up upload
-  - curl --user "${APTLY_API_USER}:${APTLY_API_PW}" -X POST -F file=@"$DEBPATH" "${APT_API_URL}/api/files/${APT_REPO}-ci-upload-${CI_JOB_ID}"
-  - curl --user "${APTLY_API_USER}:${APTLY_API_PW}" -X POST "${APT_API_URL}/api/repos/${APT_REPO}/file/${APT_REPO}-ci-upload-${CI_JOB_ID}"
-  - curl --user "${APTLY_API_USER}:${APTLY_API_PW}" -X DELETE "${APT_API_URL}/api/files/${APT_REPO}-ci-upload-${CI_JOB_ID}"
-  - echo Update published repo for all distros
-  - 'curl --user "${APTLY_API_USER}:${APTLY_API_PW}" -X PUT -H "Content-Type: application/json" --data "{ }" "${APT_API_URL}/api/publish/uffd/buster"'
-  - 'curl --user "${APTLY_API_USER}:${APTLY_API_PW}" -X PUT -H "Content-Type: application/json" --data "{ }" "${APT_API_URL}/api/publish/uffd/bullseye"'
-  - 'curl --user "${APTLY_API_USER}:${APTLY_API_PW}" -X PUT -H "Content-Type: application/json" --data "{ }" "${APT_API_URL}/api/publish/uffd/bookworm"'
-  dependencies:
-  - build:apt
diff --git a/tests/test_jsonify.py b/tests/test_jsonify.py
new file mode 100644
index 0000000000000000000000000000000000000000..3acf077af4291771aca301005f4cb38c0c04acb7
--- /dev/null
+++ b/tests/test_jsonify.py
@@ -0,0 +1,9 @@
+from flask import jsonify
+
+from tests.utils import UffdTestCase
+
+class TestViews(UffdTestCase):
+	def test_jsonify(self):
+		print(repr(jsonify({'foo': 'bar'}).data))
+		print(repr(jsonify({'foo': b'bar'}).data))
+		self.assertTrue(False)
diff --git a/tests/views/test_oauth2.py b/tests/views/test_oauth2.py
index 012ac0849c3d7deecf939ab82d8564ba3ddd7367..741297e23a04c389e1d38cdecd0cf9e76ba4def9 100644
--- a/tests/views/test_oauth2.py
+++ b/tests/views/test_oauth2.py
@@ -566,7 +566,7 @@ class TestOIDCBasicProfile(UffdTestCase):
 		r = self.do_auth_request(response_type='code')
 		args = self.validate_auth_response(r)
 		r = self.do_token_request(grant_type='authorization_code', code=args['code'])
-		print(r, repr(r.response), repr(r.json))
+		print(r, repr(r.data), repr(r.json))
 		self.assertTrue(False)
 		id_token = self.validate_token_response(r)
 		self.assertEqual(id_token['sub'], '10000')
diff --git a/uffd/views/oauth2.py b/uffd/views/oauth2.py
index 8da8a68d593463ef36f0f351a2ea92e02f2ee0ae..d69d6dbe5635590b3ae90817de88ba97d15a31ea 100644
--- a/uffd/views/oauth2.py
+++ b/uffd/views/oauth2.py
@@ -434,10 +434,11 @@ def token():
 	else:
 		# We don't support the refresh_token grant type. Due to limitations of
 		# oauthlib we always returned (disfunctional) refresh tokens in the past.
-		# We still do that for non-OIDC clients to not change behavour for
+		# We still do that for non-OIDC clients to not change behaviour for
 		# existing clients.
 		resp['refresh_token'] = tok.refresh_token
 
+	print('token_pre_jsonify', repr(resp))
 	return jsonify(resp), 200, {'Cache-Control': ['no-store']}
 
 def validate_access_token():