-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic functional test for DeepLinking launches #6918
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
import contextlib | ||
import functools | ||
import json | ||
import os | ||
import re | ||
from os import environ | ||
from urllib.parse import urlencode | ||
|
||
import httpretty | ||
import oauthlib.oauth1 | ||
import pytest | ||
from _pytest.monkeypatch import MonkeyPatch | ||
from h_matchers import Any | ||
|
@@ -13,9 +16,10 @@ | |
|
||
from lms import db | ||
from lms.app import create_app | ||
from tests import factories | ||
from tests.conftest import TEST_SETTINGS | ||
|
||
TEST_SETTINGS["database_url"] = environ["DATABASE_URL"] | ||
TEST_SETTINGS["database_url"] = os.environ["DATABASE_URL"] | ||
|
||
TEST_ENVIRONMENT = { | ||
key.upper(): value for key, value in TEST_SETTINGS.items() if isinstance(value, str) | ||
|
@@ -25,6 +29,14 @@ | |
) | ||
|
||
|
||
@pytest.fixture | ||
def environ(): | ||
environ = dict(os.environ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixture to make easier to access the os.environ version that contains all TEST_ENVIROMENT values. |
||
environ.update(TEST_ENVIRONMENT) | ||
|
||
return environ | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def clean_database(db_engine): | ||
"""Delete any data added by the previous test.""" | ||
|
@@ -71,24 +83,52 @@ def db_session(db_engine, db_sessionfactory): | |
connection.close() | ||
|
||
|
||
def _lti_v11_launch(app, url, post_params, get_params=None, **kwargs): | ||
if get_params: | ||
url += f"?{urlencode(get_params)}" | ||
|
||
return app.post( | ||
url, | ||
params=post_params, | ||
headers={ | ||
"Accept": "text/html", | ||
"Content-Type": "application/x-www-form-urlencoded", | ||
}, | ||
**kwargs, | ||
) | ||
|
||
|
||
@pytest.fixture | ||
def do_lti_launch(app): | ||
def do_lti_launch(post_params, get_params=None, **kwargs): | ||
url = "/lti_launches" | ||
if get_params: | ||
url += f"?{urlencode(get_params)}" | ||
|
||
return app.post( | ||
url, | ||
params=post_params, | ||
headers={ | ||
"Accept": "text/html", | ||
"Content-Type": "application/x-www-form-urlencoded", | ||
}, | ||
**kwargs, | ||
) | ||
return functools.partial(_lti_v11_launch, app, "/lti_launches") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor this fixture a bit to be able to reuse it for deep linking launches. |
||
|
||
|
||
@pytest.fixture | ||
def do_deep_link_launch(app): | ||
return functools.partial(_lti_v11_launch, app, "/content_item_selection") | ||
|
||
|
||
@pytest.fixture | ||
def get_client_config(): | ||
def _get_client_config(response): | ||
return json.loads(response.html.find("script", {"class": "js-config"}).string) | ||
|
||
return _get_client_config | ||
|
||
return do_lti_launch | ||
|
||
@pytest.fixture | ||
def application_instance(db_session): # noqa: ARG001 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Common fixtures between basic launch and deep linking launch moved here. |
||
return factories.ApplicationInstance( | ||
tool_consumer_instance_guid="IMS Testing", | ||
organization=factories.Organization(), | ||
) | ||
|
||
|
||
@pytest.fixture | ||
def oauth_client(application_instance): | ||
return oauthlib.oauth1.Client( | ||
application_instance.consumer_key, application_instance.shared_secret | ||
) | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
import json | ||
import time | ||
from urllib.parse import urlencode | ||
|
||
|
@@ -9,7 +8,6 @@ | |
|
||
from lms.models import Assignment | ||
from lms.resources._js_config import JSConfig | ||
from tests import factories | ||
|
||
|
||
class TestBasicLTILaunch: | ||
|
@@ -23,33 +21,35 @@ def test_requests_with_no_oauth_signature_are_forbidden( | |
assert response.headers["Content-Type"] == Any.string.matching("^text/html") | ||
assert response.html | ||
|
||
def test_unconfigured_basic_lti_launch(self, lti_params, do_lti_launch): | ||
def test_unconfigured_basic_lti_launch( | ||
self, lti_params, do_lti_launch, get_client_config | ||
): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A few changes to accommodate get_client_config being now a fixture instead of a local function. |
||
response = do_lti_launch( | ||
post_params=lti_params, | ||
status=200, | ||
) | ||
|
||
assert self.get_client_config(response)["mode"] == JSConfig.Mode.FILE_PICKER | ||
assert get_client_config(response)["mode"] == JSConfig.Mode.FILE_PICKER | ||
|
||
def test_db_configured_basic_lti_launch( | ||
self, lti_params, assignment, do_lti_launch | ||
self, lti_params, assignment, do_lti_launch, get_client_config | ||
): | ||
response = do_lti_launch(post_params=lti_params, status=200) | ||
|
||
js_config = self.get_client_config(response) | ||
js_config = get_client_config(response) | ||
assert js_config["mode"] == JSConfig.Mode.BASIC_LTI_LAUNCH | ||
assert urlencode({"url": assignment.document_url}) in js_config["viaUrl"] | ||
|
||
def test_basic_lti_launch_canvas_deep_linking_url( | ||
self, do_lti_launch, url_launch_params, db_session | ||
self, do_lti_launch, url_launch_params, db_session, get_client_config | ||
): | ||
get_params, post_params = url_launch_params | ||
|
||
response = do_lti_launch( | ||
get_params=get_params, post_params=post_params, status=200 | ||
) | ||
|
||
js_config = self.get_client_config(response) | ||
js_config = get_client_config(response) | ||
assert js_config["mode"] == JSConfig.Mode.BASIC_LTI_LAUNCH | ||
assert ( | ||
urlencode({"url": "https://url-configured.com/document.pdf"}) | ||
|
@@ -63,15 +63,15 @@ def test_basic_lti_launch_canvas_deep_linking_url( | |
) | ||
|
||
def test_basic_lti_launch_canvas_deep_linking_canvas_file( | ||
self, do_lti_launch, db_session, canvas_file_launch_params | ||
self, do_lti_launch, db_session, canvas_file_launch_params, get_client_config | ||
): | ||
get_params, post_params = canvas_file_launch_params | ||
|
||
response = do_lti_launch( | ||
get_params=get_params, post_params=post_params, status=200 | ||
) | ||
|
||
js_config = self.get_client_config(response) | ||
js_config = get_client_config(response) | ||
assert js_config["mode"] == JSConfig.Mode.BASIC_LTI_LAUNCH | ||
assert ( | ||
js_config["api"]["viaUrl"]["path"] | ||
|
@@ -84,13 +84,6 @@ def test_basic_lti_launch_canvas_deep_linking_canvas_file( | |
== 1 | ||
) | ||
|
||
@pytest.fixture(autouse=True) | ||
def application_instance(self, db_session): # noqa: ARG002 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to conftest.py |
||
return factories.ApplicationInstance( | ||
tool_consumer_instance_guid="IMS Testing", | ||
organization=factories.Organization(), | ||
) | ||
|
||
@pytest.fixture | ||
def assignment(self, db_session, application_instance, lti_params): | ||
assignment = Assignment( | ||
|
@@ -104,12 +97,6 @@ def assignment(self, db_session, application_instance, lti_params): | |
|
||
return assignment | ||
|
||
@pytest.fixture | ||
def oauth_client(self, application_instance): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same, moved to conftest.py |
||
return oauthlib.oauth1.Client( | ||
application_instance.consumer_key, application_instance.shared_secret | ||
) | ||
|
||
@pytest.fixture | ||
def lti_params(self, application_instance, sign_lti_params): | ||
params = { | ||
|
@@ -184,6 +171,3 @@ def _sign(params): | |
return params | ||
|
||
return _sign | ||
|
||
def get_client_config(self, response): | ||
return json.loads(response.html.find("script", {"class": "js-config"}).string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing setting on the tests fixture.