|
1 | 1 | from django.conf import settings |
2 | 2 |
|
3 | 3 | import pytest |
| 4 | +from rest_framework.authtoken.models import Token |
4 | 5 |
|
5 | 6 | from aiarena.core.models import Bot, CompetitionParticipation, Match, MatchParticipation |
6 | 7 | from aiarena.core.tests.base import GraphQLTest |
@@ -895,3 +896,68 @@ def test_cannot_specify_attributes_not_in_input(self, user, bot): |
895 | 896 | # Verify bot was not updated |
896 | 897 | bot.refresh_from_db() |
897 | 898 | assert bot.bot_zip_publicly_downloadable != "new name pls" |
| 899 | + |
| 900 | + |
| 901 | +class TestRegenerateApiToken(GraphQLTest): |
| 902 | + mutation_name = "regenerateApiToken" |
| 903 | + mutation = """ |
| 904 | + mutation { |
| 905 | + regenerateApiToken { |
| 906 | + viewer { |
| 907 | + apiToken |
| 908 | + } |
| 909 | + errors { |
| 910 | + messages |
| 911 | + field |
| 912 | + } |
| 913 | + } |
| 914 | + } |
| 915 | + """ |
| 916 | + |
| 917 | + def test_generates_token_when_missing(self, user): |
| 918 | + """A user with no token gets one created, and it's returned to them.""" |
| 919 | + assert not Token.objects.filter(user=user).exists() |
| 920 | + |
| 921 | + response = self.mutate(login_user=user, expected_status=200) |
| 922 | + |
| 923 | + token = Token.objects.get(user=user) |
| 924 | + returned_token = response["regenerateApiToken"]["viewer"]["apiToken"] |
| 925 | + assert returned_token == token.key |
| 926 | + |
| 927 | + def test_regenerates_existing_token(self, user): |
| 928 | + """Regenerating replaces the existing token: old key gone, new key differs, still exactly one.""" |
| 929 | + old_token = Token.objects.create(user=user) |
| 930 | + old_key = old_token.key |
| 931 | + |
| 932 | + response = self.mutate(login_user=user, expected_status=200) |
| 933 | + |
| 934 | + assert Token.objects.filter(user=user).count() == 1 |
| 935 | + new_token = Token.objects.get(user=user) |
| 936 | + assert new_token.key != old_key |
| 937 | + assert not Token.objects.filter(key=old_key).exists() |
| 938 | + assert response["regenerateApiToken"]["viewer"]["apiToken"] == new_token.key |
| 939 | + |
| 940 | + def test_not_logged_in_does_not_create_token(self, user): |
| 941 | + """An unauthenticated caller cannot mint a token.""" |
| 942 | + assert not Token.objects.filter(user=user).exists() |
| 943 | + |
| 944 | + self.mutate( |
| 945 | + expected_status=200, |
| 946 | + expected_validation_errors={"__all__": ["You are not signed in"]}, |
| 947 | + ) |
| 948 | + |
| 949 | + assert not Token.objects.exists() |
| 950 | + |
| 951 | + def test_only_affects_own_token(self, user, other_user): |
| 952 | + """Regenerating one user's token must not touch another user's token.""" |
| 953 | + other_token = Token.objects.create(user=other_user) |
| 954 | + other_key = other_token.key |
| 955 | + |
| 956 | + self.mutate(login_user=user, expected_status=200) |
| 957 | + |
| 958 | + # The caller got a fresh token... |
| 959 | + assert Token.objects.filter(user=user).exists() |
| 960 | + # ...and the other user's token is completely untouched. |
| 961 | + other_token.refresh_from_db() |
| 962 | + assert other_token.key == other_key |
| 963 | + assert Token.objects.filter(user=other_user).count() == 1 |
0 commit comments