CAT-SOOP is a flexible, programmable learning management system based on the Python programming language. https://catsoop.mit.edu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

149 lines
4.6 KiB

  1. # This file is part of CAT-SOOP
  2. # Copyright (c) 2011-2020 by The CAT-SOOP Developers <catsoop-dev@mit.edu>
  3. #
  4. # This program is free software: you can redistribute it and/or modify it under
  5. # the terms of the GNU Affero General Public License as published by the Free
  6. # Software Foundation, either version 3 of the License, or (at your option) any
  7. # later version.
  8. #
  9. # This program is distributed in the hope that it will be useful, but WITHOUT
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  12. # details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. """
  17. Unit tests for CAT-SOOP
  18. Requires config to be setup, including cs_unit_test_course
  19. """
  20. import cgi
  21. import logging
  22. import unittest
  23. from catsoop import loader
  24. from catsoop import dispatch
  25. from catsoop import lti
  26. from ..test import CATSOOPTest
  27. # -----------------------------------------------------------------------------
  28. class Test_LTI(CATSOOPTest):
  29. """
  30. Test basic LTI functionality
  31. """
  32. def setUp(self):
  33. CATSOOPTest.setUp(self)
  34. context = {}
  35. loader.load_global_data(context)
  36. assert "cs_unit_test_course" in context
  37. self.cname = context["cs_unit_test_course"]
  38. self.ckey = "__test_consumer__"
  39. self.secret = "__test_secret__"
  40. self.cs_lti_config = {
  41. "session_key": "aslkdj12",
  42. "consumers": {self.ckey: {"secret": self.secret}},
  43. }
  44. lgd = loader.load_global_data
  45. def mock_load_global_data(into, check_values=True):
  46. ret = lgd(into, check_values)
  47. into["cs_lti_config"] = self.cs_lti_config
  48. return ret
  49. loader.load_global_data = mock_load_global_data
  50. logging.getLogger("pylti.common").setLevel(1)
  51. def skip_test_lti_auth0(self):
  52. path = "/_lti/%s/structure" % self.cname
  53. host = "localhost:6010"
  54. url = "http://%s%s" % (host, path)
  55. ltic = lti.LTI_Consumer(lti_url=url, consumer_key=self.ckey, secret=self.secret)
  56. data = ltic.lti_context
  57. import requests
  58. ret = requests.post(url, data=data)
  59. assert False
  60. def test_lti_auth1(self):
  61. env = {"PATH_INFO": "/_lti/%s/structure" % self.cname}
  62. status, retinfo, msg = dispatch.main(env)
  63. assert status[0] == "200"
  64. assert "LTI verification failed" in msg
  65. def test_lti_auth2(self):
  66. """
  67. Test successful authentication with LTI protocol
  68. """
  69. path = "/_lti/foo"
  70. host = "localhost:6010"
  71. url = "http://%s%s" % (host, path)
  72. ltic = lti.LTI_Consumer(
  73. lti_url=url,
  74. consumer_key=self.ckey,
  75. secret=self.secret,
  76. username="anltiuser",
  77. )
  78. def retform():
  79. return ltic.lti_context
  80. cgi.FieldStorage = retform # monkey patch
  81. env = {
  82. "PATH_INFO": path,
  83. "wsgi.url_scheme": "http",
  84. "HTTP_HOST": host,
  85. "REQUEST_URI": path,
  86. "REQUEST_METHOD": "POST",
  87. }
  88. status, retinfo, msg = dispatch.main(env)
  89. assert status[0] == "200"
  90. assert "Hello LTI" in msg
  91. context = dispatch.main(env, return_context=True)
  92. cui = context["cs_user_info"]
  93. assert cui["username"] == "lti_anltiuser"
  94. # ensure lti_username_prefix can be set to empty string
  95. self.cs_lti_config["lti_username_prefix"] = ""
  96. context = dispatch.main(env, return_context=True)
  97. cui = context["cs_user_info"]
  98. assert cui["username"] == "anltiuser"
  99. def test_lti_auth3(self):
  100. """
  101. Test LTI access to courseware
  102. """
  103. path = "/_lti/course/%s/structure" % self.cname
  104. host = "localhost:6010"
  105. url = "http://%s%s" % (host, path)
  106. ltic = lti.LTI_Consumer(lti_url=url, consumer_key=self.ckey, secret=self.secret)
  107. def retform():
  108. return ltic.lti_context
  109. cgi.FieldStorage = retform # monkey patch
  110. env = {
  111. "PATH_INFO": path,
  112. "wsgi.url_scheme": "http",
  113. "HTTP_HOST": host,
  114. "REQUEST_URI": path,
  115. "REQUEST_METHOD": "POST",
  116. }
  117. status, retinfo, msg = dispatch.main(env)
  118. assert status[0] == "200"
  119. assert "Page Specification and Loading" in msg.decode("utf8")
  120. # -----------------------------------------------------------------------------
  121. if __name__ == "__main__":
  122. unittest.main()