Skip to content

Commit 2ac9e45

Browse files
committed
Added orcid backend tests
1 parent 2a4da5b commit 2ac9e45

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed

tests/satosa/backends/test_orcid.py

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import json
2+
from unittest.mock import Mock
3+
from urllib.parse import urljoin, urlparse, parse_qsl
4+
5+
import pytest
6+
import responses
7+
8+
from saml2.saml import NAMEID_FORMAT_TRANSIENT
9+
10+
from satosa.backends.orcid import OrcidBackend
11+
from satosa.context import Context
12+
from satosa.internal import InternalData
13+
from satosa.response import Response
14+
15+
ORCID_PERSON_ID = "0000-0000-0000-0000"
16+
ORCID_PERSON_GIVEN_NAME = "orcid_given_name"
17+
ORCID_PERSON_FAMILY_NAME = "orcid_family_name"
18+
ORCID_PERSON_NAME = "{} {}".format(ORCID_PERSON_GIVEN_NAME, ORCID_PERSON_FAMILY_NAME)
19+
ORCID_PERSON_EMAIL = "orcid_email"
20+
ORCID_PERSON_COUNTRY = "XX"
21+
22+
class TestOrcidBackend(object):
23+
@pytest.fixture(autouse=True)
24+
def create_backend(self, internal_attributes, backend_config):
25+
self.orcid_backend = OrcidBackend(Mock(), internal_attributes, backend_config, backend_config["base_url"], "orcid")
26+
27+
@pytest.fixture
28+
def backend_config(self):
29+
return {
30+
"authz_page": 'orcid/auth/callback',
31+
"base_url": "https://client.example.com",
32+
"client_config": {"client_id": "orcid_client_id"},
33+
"client_secret": "orcid_secret",
34+
"scope": ["/authenticate"],
35+
"response_type": "code",
36+
"server_info": {
37+
"authorization_endpoint": "https://orcid.org/oauth/authorize",
38+
"token_endpoint": "https://pub.orcid.org/oauth/token",
39+
"user_info": "https://pub.orcid.org/v2.0/"
40+
}
41+
}
42+
43+
@pytest.fixture
44+
def internal_attributes(self):
45+
return {
46+
"attributes": {
47+
"address": { "orcid": ["address"] },
48+
"displayname": { "orcid": ["name"] },
49+
"edupersontargetedid": {"orcid": ["orcid"]},
50+
"givenname": {"orcid": ["givenname"]},
51+
"mail": {"orcid": ["mail"]},
52+
"name": { "orcid": ["name"] },
53+
"surname": {"orcid": ["surname"]},
54+
}
55+
}
56+
57+
@pytest.fixture
58+
def userinfo(self):
59+
return {
60+
"name": {
61+
"given-names": { "value": ORCID_PERSON_GIVEN_NAME },
62+
"family-name": { "value": ORCID_PERSON_FAMILY_NAME },
63+
},
64+
"emails": {
65+
"email": [
66+
{ "email": ORCID_PERSON_EMAIL, "verified": True, "primary": True }
67+
]
68+
},
69+
"addresses": {
70+
"address": [
71+
{ "country": { "value": ORCID_PERSON_COUNTRY } }
72+
]
73+
}
74+
}
75+
76+
@pytest.fixture
77+
def userinfo_private(self):
78+
return {
79+
"name": {
80+
"given-names": { "value": ORCID_PERSON_GIVEN_NAME },
81+
"family-name": { "value": ORCID_PERSON_FAMILY_NAME },
82+
},
83+
"emails": {
84+
"email": [
85+
]
86+
},
87+
"addresses": {
88+
"address": [
89+
]
90+
}
91+
}
92+
93+
94+
def assert_expected_attributes(self, user_claims, actual_attributes):
95+
print(user_claims)
96+
print(actual_attributes)
97+
98+
expected_attributes = {
99+
"address": [ORCID_PERSON_COUNTRY],
100+
"displayname": [ORCID_PERSON_NAME],
101+
"edupersontargetedid": [ORCID_PERSON_ID],
102+
"givenname": [ORCID_PERSON_GIVEN_NAME],
103+
"mail": [ORCID_PERSON_EMAIL],
104+
"name": [ORCID_PERSON_NAME],
105+
"surname": [ORCID_PERSON_FAMILY_NAME],
106+
}
107+
108+
assert actual_attributes == expected_attributes
109+
110+
def setup_token_endpoint(self, token_endpoint_url):
111+
token_response = {
112+
"access_token": "orcid_access_token",
113+
"token_type": "bearer",
114+
"expires_in": 9999999999999,
115+
"name": ORCID_PERSON_NAME,
116+
"orcid": ORCID_PERSON_ID
117+
}
118+
119+
responses.add(responses.POST,
120+
token_endpoint_url,
121+
body=json.dumps(token_response),
122+
status=200,
123+
content_type="application/json")
124+
125+
def setup_userinfo_endpoint(self, userinfo_endpoint_url, userinfo):
126+
responses.add(responses.GET,
127+
urljoin(userinfo_endpoint_url, '{}/person'.format(ORCID_PERSON_ID)),
128+
body=json.dumps(userinfo),
129+
status=200,
130+
content_type="application/json")
131+
132+
@pytest.fixture
133+
def incoming_authn_response(self, context, backend_config):
134+
context.path = backend_config["authz_page"]
135+
context.request = {
136+
"code": "the_orcid_code",
137+
}
138+
139+
return context
140+
141+
def test_start_auth(self, context, backend_config):
142+
auth_response = self.orcid_backend.start_auth(context, None)
143+
assert isinstance(auth_response, Response)
144+
145+
login_url = auth_response.message
146+
parsed = urlparse(login_url)
147+
assert login_url.startswith(backend_config["server_info"]["authorization_endpoint"])
148+
auth_params = dict(parse_qsl(parsed.query))
149+
assert auth_params["scope"] == " ".join(backend_config["scope"])
150+
assert auth_params["response_type"] == backend_config["response_type"]
151+
assert auth_params["client_id"] == backend_config["client_config"]["client_id"]
152+
assert auth_params["redirect_uri"] == backend_config["base_url"] + "/" + backend_config["authz_page"]
153+
154+
@responses.activate
155+
def test_authn_response(self, backend_config, userinfo, incoming_authn_response):
156+
self.setup_token_endpoint(backend_config["server_info"]["token_endpoint"])
157+
self.setup_userinfo_endpoint(backend_config["server_info"]["user_info"], userinfo)
158+
159+
self.orcid_backend._authn_response(incoming_authn_response)
160+
161+
args = self.orcid_backend.auth_callback_func.call_args[0]
162+
assert isinstance(args[0], Context)
163+
assert isinstance(args[1], InternalData)
164+
165+
self.assert_expected_attributes(userinfo, args[1].attributes)
166+
167+
@responses.activate
168+
def test_user_information(self, context, backend_config, userinfo):
169+
self.setup_userinfo_endpoint(backend_config["server_info"]["user_info"], userinfo)
170+
171+
user_attributes = self.orcid_backend.user_information("orcid_access_token", ORCID_PERSON_ID, ORCID_PERSON_NAME)
172+
173+
assert user_attributes["address"] == ORCID_PERSON_COUNTRY
174+
assert user_attributes["displayname"] == ORCID_PERSON_NAME
175+
assert user_attributes["edupersontargetedid"] == ORCID_PERSON_ID
176+
assert user_attributes["orcid"] == ORCID_PERSON_ID
177+
assert user_attributes["mail"] == ORCID_PERSON_EMAIL
178+
assert user_attributes["givenname"] == ORCID_PERSON_GIVEN_NAME
179+
assert user_attributes["surname"] == ORCID_PERSON_FAMILY_NAME
180+
181+
@responses.activate
182+
def test_user_information_private(self, context, backend_config, userinfo_private):
183+
self.setup_userinfo_endpoint(backend_config["server_info"]["user_info"], userinfo_private)
184+
185+
user_attributes = self.orcid_backend.user_information("orcid_access_token", ORCID_PERSON_ID, ORCID_PERSON_NAME)
186+
187+
assert user_attributes["address"] == ""
188+
assert user_attributes["mail"] == ""

0 commit comments

Comments
 (0)