Skip to content

Commit d10859f

Browse files
committed
Add initial stage test
1 parent e658cb2 commit d10859f

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

tests/test_device.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from unittest import mock
2+
from urllib.parse import urlencode
3+
4+
import django.http.response
5+
import pytest
6+
from django.contrib.auth import get_user_model
7+
from django.test import RequestFactory
8+
from django.urls import reverse
9+
10+
import oauth2_provider.models
11+
from oauth2_provider.models import get_access_token_model, get_application_model, get_device_model
12+
13+
from . import presets
14+
from .common_testing import OAuth2ProviderTestCase as TestCase
15+
16+
17+
Application = get_application_model()
18+
AccessToken = get_access_token_model()
19+
UserModel = get_user_model()
20+
DeviceModel: oauth2_provider.models.Device = get_device_model()
21+
22+
23+
@pytest.mark.usefixtures("oauth2_settings")
24+
@pytest.mark.oauth2_settings(presets.DEFAULT_SCOPES_RW)
25+
class BaseTest(TestCase):
26+
factory = RequestFactory()
27+
28+
@classmethod
29+
def setUpTestData(cls):
30+
cls.test_user = UserModel.objects.create_user("test_user", "[email protected]", "123456")
31+
cls.dev_user = UserModel.objects.create_user("dev_user", "[email protected]", "123456")
32+
33+
cls.application = Application.objects.create(
34+
name="test_client_credentials_app",
35+
user=cls.dev_user,
36+
client_type=Application.CLIENT_PUBLIC,
37+
authorization_grant_type=Application.GRANT_CLIENT_CREDENTIALS,
38+
client_secret="abcdefghijklmnopqrstuvwxyz1234567890",
39+
)
40+
41+
42+
class TestDeviceFlow(BaseTest):
43+
@mock.patch(
44+
"oauthlib.oauth2.rfc8628.endpoints.device_authorization.generate_token",
45+
lambda: "abc",
46+
)
47+
def test_device_flow_authorization_initiation(self):
48+
"""
49+
Tests the initial stage of the flow when the device sends its device authorization
50+
request to the authorization server.
51+
52+
Device Authorization Request(https://datatracker.ietf.org/doc/html/rfc8628#section-3.1)
53+
54+
This request shape:
55+
POST /device_authorization HTTP/1.1
56+
Host: server.example.com
57+
Content-Type: application/x-www-form-urlencoded
58+
59+
client_id=1406020730&scope=example_scope
60+
61+
Should respond with this response shape:
62+
Device Authorization Response (https://datatracker.ietf.org/doc/html/rfc8628#section-3.2)
63+
{
64+
"device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
65+
"user_code": "WDJB-MJHT",
66+
"verification_uri": "https://example.com/device",
67+
"expires_in": 1800,
68+
"interval": 5
69+
}
70+
"""
71+
72+
self.oauth2_settings.OAUTH_DEVICE_VERIFICATION_URI = "example.com/device"
73+
self.oauth2_settings.OAUTH_DEVICE_USER_CODE_GENERATOR = lambda: "xyz"
74+
75+
request_data: dict[str, str] = {
76+
"client_id": self.application.client_id,
77+
}
78+
request_as_x_www_form_urlencoded: str = urlencode(request_data)
79+
80+
response: django.http.response.JsonResponse = self.client.post(
81+
reverse("oauth2_provider:device-authorization"),
82+
data=request_as_x_www_form_urlencoded,
83+
content_type="application/x-www-form-urlencoded",
84+
)
85+
86+
assert response.status_code == 200
87+
88+
# let's make sure the device was created in the db
89+
assert DeviceModel.objects.get(device_code="abc")
90+
91+
assert response.json() == {
92+
"verification_uri": "example.com/device",
93+
"expires_in": 1800,
94+
"user_code": "xyz",
95+
"device_code": "abc",
96+
"interval": 5,
97+
}

0 commit comments

Comments
 (0)