diff --git a/common/djangoapps/third_party_auth/management/commands/tests/test_data/another-testshib-providers.xml b/common/djangoapps/third_party_auth/management/commands/tests/test_data/another-testshib-providers.xml new file mode 100644 index 0000000000..caeaf6627d --- /dev/null +++ b/common/djangoapps/third_party_auth/management/commands/tests/test_data/another-testshib-providers.xml @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + + + + testshib.org + + TestShib Test IdP + TestShib IdP. Use this as a source of attributes + for your test SP. + https://www.testshib.org/testshibtwo.jpg + + + + + + + + + + + MIIDAzCCAeugAwIBAgIVAPX0G6LuoXnKS0Muei006mVSBXbvMA0GCSqGSIb3DQEB + CwUAMBsxGTAXBgNVBAMMEGlkcC50ZXN0c2hpYi5vcmcwHhcNMTYwODIzMjEyMDU0 + WhcNMzYwODIzMjEyMDU0WjAbMRkwFwYDVQQDDBBpZHAudGVzdHNoaWIub3JnMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg9C4J2DiRTEhJAWzPt1S3ryh + m3M2P3hPpwJwvt2q948vdTUxhhvNMuc3M3S4WNh6JYBs53R+YmjqJAII4ShMGNEm + lGnSVfHorex7IxikpuDPKV3SNf28mCAZbQrX+hWA+ann/uifVzqXktOjs6DdzdBn + xoVhniXgC8WCJwKcx6JO/hHsH1rG/0DSDeZFpTTcZHj4S9MlLNUtt5JxRzV/MmmB + 3ObaX0CMqsSWUOQeE4nylSlp5RWHCnx70cs9kwz5WrflnbnzCeHU2sdbNotBEeTH + ot6a2cj/pXlRJIgPsrL/4VSicPZcGYMJMPoLTJ8mdy6mpR6nbCmP7dVbCIm/DQID + AQABoz4wPDAdBgNVHQ4EFgQUUfaDa2mPi24x09yWp1OFXmZ2GPswGwYDVR0RBBQw + EoIQaWRwLnRlc3RzaGliLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEASKKgqTxhqBzR + OZ1eVy++si+eTTUQZU4+8UywSKLia2RattaAPMAcXUjO+3cYOQXLVASdlJtt+8QP + dRkfp8SiJemHPXC8BES83pogJPYEGJsKo19l4XFJHPnPy+Dsn3mlJyOfAa8RyWBS + 80u5lrvAcr2TJXt9fXgkYs7BOCigxtZoR8flceGRlAZ4p5FPPxQR6NDYb645jtOT + MVr3zgfjP6Wh2dt+2p04LG7ENJn8/gEwtXVuXCsPoSCDx9Y0QmyXTJNdV1aB0AhO + RkWPlFYwp+zOyOIR+3m1+pqWFpn0eT/HrxpdKa74FA3R2kq4R7dXe4G0kUgXTdqX + MLRKhDgdmA== + + + + + + + + + + + + + + + urn:mace:shibboleth:1.0:nameIdentifier + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + + + + + + + + + + + + + + MIIDAzCCAeugAwIBAgIVAPX0G6LuoXnKS0Muei006mVSBXbvMA0GCSqGSIb3DQEB + CwUAMBsxGTAXBgNVBAMMEGlkcC50ZXN0c2hpYi5vcmcwHhcNMTYwODIzMjEyMDU0 + WhcNMzYwODIzMjEyMDU0WjAbMRkwFwYDVQQDDBBpZHAudGVzdHNoaWIub3JnMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg9C4J2DiRTEhJAWzPt1S3ryh + m3M2P3hPpwJwvt2q948vdTUxhhvNMuc3M3S4WNh6JYBs53R+YmjqJAII4ShMGNEm + lGnSVfHorex7IxikpuDPKV3SNf28mCAZbQrX+hWA+ann/uifVzqXktOjs6DdzdBn + xoVhniXgC8WCJwKcx6JO/hHsH1rG/0DSDeZFpTTcZHj4S9MlLNUtt5JxRzV/MmmB + 3ObaX0CMqsSWUOQeE4nylSlp5RWHCnx70cs9kwz5WrflnbnzCeHU2sdbNotBEeTH + ot6a2cj/pXlRJIgPsrL/4VSicPZcGYMJMPoLTJ8mdy6mpR6nbCmP7dVbCIm/DQID + AQABoz4wPDAdBgNVHQ4EFgQUUfaDa2mPi24x09yWp1OFXmZ2GPswGwYDVR0RBBQw + EoIQaWRwLnRlc3RzaGliLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEASKKgqTxhqBzR + OZ1eVy++si+eTTUQZU4+8UywSKLia2RattaAPMAcXUjO+3cYOQXLVASdlJtt+8QP + dRkfp8SiJemHPXC8BES83pogJPYEGJsKo19l4XFJHPnPy+Dsn3mlJyOfAa8RyWBS + 80u5lrvAcr2TJXt9fXgkYs7BOCigxtZoR8flceGRlAZ4p5FPPxQR6NDYb645jtOT + MVr3zgfjP6Wh2dt+2p04LG7ENJn8/gEwtXVuXCsPoSCDx9Y0QmyXTJNdV1aB0AhO + RkWPlFYwp+zOyOIR+3m1+pqWFpn0eT/HrxpdKa74FA3R2kq4R7dXe4G0kUgXTdqX + MLRKhDgdmA== + + + + + + + + + + + + + + + urn:mace:shibboleth:1.0:nameIdentifier + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + TestShib Two Identity Provider + TestShib Two + http://www.testshib.org/testshib-two/ + + + Nate + Klingenstein + ndk@internet2.edu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestShib Test SP + TestShib SP. Log into this to test your machine. + Once logged in check that all attributes that you expected have been + released. + https://www.testshib.org/testshibtwo.jpg + + + + + + + + MIIEPjCCAyagAwIBAgIBADANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJVUzEV + MBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMSIwIAYD + VQQKExlUZXN0U2hpYiBTZXJ2aWNlIFByb3ZpZGVyMRgwFgYDVQQDEw9zcC50ZXN0 + c2hpYi5vcmcwHhcNMDYwODMwMjEyNDM5WhcNMTYwODI3MjEyNDM5WjB3MQswCQYD + VQQGEwJVUzEVMBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1 + cmdoMSIwIAYDVQQKExlUZXN0U2hpYiBTZXJ2aWNlIFByb3ZpZGVyMRgwFgYDVQQD + Ew9zcC50ZXN0c2hpYi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB + AQDJyR6ZP6MXkQ9z6RRziT0AuCabDd3x1m7nLO9ZRPbr0v1LsU+nnC363jO8nGEq + sqkgiZ/bSsO5lvjEt4ehff57ERio2Qk9cYw8XCgmYccVXKH9M+QVO1MQwErNobWb + AjiVkuhWcwLWQwTDBowfKXI87SA7KR7sFUymNx5z1aoRvk3GM++tiPY6u4shy8c7 + vpWbVfisfTfvef/y+galxjPUQYHmegu7vCbjYP3On0V7/Ivzr+r2aPhp8egxt00Q + XpilNai12LBYV3Nv/lMsUzBeB7+CdXRVjZOHGuQ8mGqEbsj8MBXvcxIKbcpeK5Zi + JCVXPfarzuriM1G5y5QkKW+LAgMBAAGjgdQwgdEwHQYDVR0OBBYEFKB6wPDxwYrY + StNjU5P4b4AjBVQVMIGhBgNVHSMEgZkwgZaAFKB6wPDxwYrYStNjU5P4b4AjBVQV + oXukeTB3MQswCQYDVQQGEwJVUzEVMBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYD + VQQHEwpQaXR0c2J1cmdoMSIwIAYDVQQKExlUZXN0U2hpYiBTZXJ2aWNlIFByb3Zp + ZGVyMRgwFgYDVQQDEw9zcC50ZXN0c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zAN + BgkqhkiG9w0BAQUFAAOCAQEAc06Kgt7ZP6g2TIZgMbFxg6vKwvDL0+2dzF11Onpl + 5sbtkPaNIcj24lQ4vajCrrGKdzHXo9m54BzrdRJ7xDYtw0dbu37l1IZVmiZr12eE + Iay/5YMU+aWP1z70h867ZQ7/7Y4HW345rdiS6EW663oH732wSYNt9kr7/0Uer3KD + 9CuPuOidBacospDaFyfsaJruE99Kd6Eu/w5KLAGG+m0iqENCziDGzVA47TngKz2v + PVA+aokoOyoz3b53qeti77ijatSEoKjxheBWpO+eoJeGq/e49Um3M2ogIX/JAlMa + Inh+vYSYngQB2sx9LGkR9KHaMKNIGCDehk93Xla4pWJx1w== + + + + + + + + + + + + + + + + + + + + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:mace:shibboleth:1.0:nameIdentifier + + + + + + + + + + + + + + + + + + + + TestShib Two Service Provider + TestShib Two + http://www.testshib.org/testshib-two/ + + + Nate + Klingenstein + ndk@internet2.edu + + + + + + + diff --git a/common/djangoapps/third_party_auth/management/commands/tests/test_data/testshib-providers.xml b/common/djangoapps/third_party_auth/management/commands/tests/test_data/testshib-providers.xml new file mode 100644 index 0000000000..9e7d4ebeb4 --- /dev/null +++ b/common/djangoapps/third_party_auth/management/commands/tests/test_data/testshib-providers.xml @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + + + + testshib.org + + TestShib Test IdP + TestShib IdP. Use this as a source of attributes + for your test SP. + https://www.testshib.org/testshibtwo.jpg + + + + + + + + + + + MIIDAzCCAeugAwIBAgIVAPX0G6LuoXnKS0Muei006mVSBXbvMA0GCSqGSIb3DQEB + CwUAMBsxGTAXBgNVBAMMEGlkcC50ZXN0c2hpYi5vcmcwHhcNMTYwODIzMjEyMDU0 + WhcNMzYwODIzMjEyMDU0WjAbMRkwFwYDVQQDDBBpZHAudGVzdHNoaWIub3JnMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg9C4J2DiRTEhJAWzPt1S3ryh + m3M2P3hPpwJwvt2q948vdTUxhhvNMuc3M3S4WNh6JYBs53R+YmjqJAII4ShMGNEm + lGnSVfHorex7IxikpuDPKV3SNf28mCAZbQrX+hWA+ann/uifVzqXktOjs6DdzdBn + xoVhniXgC8WCJwKcx6JO/hHsH1rG/0DSDeZFpTTcZHj4S9MlLNUtt5JxRzV/MmmB + 3ObaX0CMqsSWUOQeE4nylSlp5RWHCnx70cs9kwz5WrflnbnzCeHU2sdbNotBEeTH + ot6a2cj/pXlRJIgPsrL/4VSicPZcGYMJMPoLTJ8mdy6mpR6nbCmP7dVbCIm/DQID + AQABoz4wPDAdBgNVHQ4EFgQUUfaDa2mPi24x09yWp1OFXmZ2GPswGwYDVR0RBBQw + EoIQaWRwLnRlc3RzaGliLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEASKKgqTxhqBzR + OZ1eVy++si+eTTUQZU4+8UywSKLia2RattaAPMAcXUjO+3cYOQXLVASdlJtt+8QP + dRkfp8SiJemHPXC8BES83pogJPYEGJsKo19l4XFJHPnPy+Dsn3mlJyOfAa8RyWBS + 80u5lrvAcr2TJXt9fXgkYs7BOCigxtZoR8flceGRlAZ4p5FPPxQR6NDYb645jtOT + MVr3zgfjP6Wh2dt+2p04LG7ENJn8/gEwtXVuXCsPoSCDx9Y0QmyXTJNdV1aB0AhO + RkWPlFYwp+zOyOIR+3m1+pqWFpn0eT/HrxpdKa74FA3R2kq4R7dXe4G0kUgXTdqX + MLRKhDgdmA== + + + + + + + + + + + + + + + urn:mace:shibboleth:1.0:nameIdentifier + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + + + + + + + + + + + + + + MIIDAzCCAeugAwIBAgIVAPX0G6LuoXnKS0Muei006mVSBXbvMA0GCSqGSIb3DQEB + CwUAMBsxGTAXBgNVBAMMEGlkcC50ZXN0c2hpYi5vcmcwHhcNMTYwODIzMjEyMDU0 + WhcNMzYwODIzMjEyMDU0WjAbMRkwFwYDVQQDDBBpZHAudGVzdHNoaWIub3JnMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg9C4J2DiRTEhJAWzPt1S3ryh + m3M2P3hPpwJwvt2q948vdTUxhhvNMuc3M3S4WNh6JYBs53R+YmjqJAII4ShMGNEm + lGnSVfHorex7IxikpuDPKV3SNf28mCAZbQrX+hWA+ann/uifVzqXktOjs6DdzdBn + xoVhniXgC8WCJwKcx6JO/hHsH1rG/0DSDeZFpTTcZHj4S9MlLNUtt5JxRzV/MmmB + 3ObaX0CMqsSWUOQeE4nylSlp5RWHCnx70cs9kwz5WrflnbnzCeHU2sdbNotBEeTH + ot6a2cj/pXlRJIgPsrL/4VSicPZcGYMJMPoLTJ8mdy6mpR6nbCmP7dVbCIm/DQID + AQABoz4wPDAdBgNVHQ4EFgQUUfaDa2mPi24x09yWp1OFXmZ2GPswGwYDVR0RBBQw + EoIQaWRwLnRlc3RzaGliLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEASKKgqTxhqBzR + OZ1eVy++si+eTTUQZU4+8UywSKLia2RattaAPMAcXUjO+3cYOQXLVASdlJtt+8QP + dRkfp8SiJemHPXC8BES83pogJPYEGJsKo19l4XFJHPnPy+Dsn3mlJyOfAa8RyWBS + 80u5lrvAcr2TJXt9fXgkYs7BOCigxtZoR8flceGRlAZ4p5FPPxQR6NDYb645jtOT + MVr3zgfjP6Wh2dt+2p04LG7ENJn8/gEwtXVuXCsPoSCDx9Y0QmyXTJNdV1aB0AhO + RkWPlFYwp+zOyOIR+3m1+pqWFpn0eT/HrxpdKa74FA3R2kq4R7dXe4G0kUgXTdqX + MLRKhDgdmA== + + + + + + + + + + + + + + + urn:mace:shibboleth:1.0:nameIdentifier + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + TestShib Two Identity Provider + TestShib Two + http://www.testshib.org/testshib-two/ + + + Nate + Klingenstein + ndk@internet2.edu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestShib Test SP + TestShib SP. Log into this to test your machine. + Once logged in check that all attributes that you expected have been + released. + https://www.testshib.org/testshibtwo.jpg + + + + + + + + MIIEPjCCAyagAwIBAgIBADANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJVUzEV + MBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMSIwIAYD + VQQKExlUZXN0U2hpYiBTZXJ2aWNlIFByb3ZpZGVyMRgwFgYDVQQDEw9zcC50ZXN0 + c2hpYi5vcmcwHhcNMDYwODMwMjEyNDM5WhcNMTYwODI3MjEyNDM5WjB3MQswCQYD + VQQGEwJVUzEVMBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1 + cmdoMSIwIAYDVQQKExlUZXN0U2hpYiBTZXJ2aWNlIFByb3ZpZGVyMRgwFgYDVQQD + Ew9zcC50ZXN0c2hpYi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB + AQDJyR6ZP6MXkQ9z6RRziT0AuCabDd3x1m7nLO9ZRPbr0v1LsU+nnC363jO8nGEq + sqkgiZ/bSsO5lvjEt4ehff57ERio2Qk9cYw8XCgmYccVXKH9M+QVO1MQwErNobWb + AjiVkuhWcwLWQwTDBowfKXI87SA7KR7sFUymNx5z1aoRvk3GM++tiPY6u4shy8c7 + vpWbVfisfTfvef/y+galxjPUQYHmegu7vCbjYP3On0V7/Ivzr+r2aPhp8egxt00Q + XpilNai12LBYV3Nv/lMsUzBeB7+CdXRVjZOHGuQ8mGqEbsj8MBXvcxIKbcpeK5Zi + JCVXPfarzuriM1G5y5QkKW+LAgMBAAGjgdQwgdEwHQYDVR0OBBYEFKB6wPDxwYrY + StNjU5P4b4AjBVQVMIGhBgNVHSMEgZkwgZaAFKB6wPDxwYrYStNjU5P4b4AjBVQV + oXukeTB3MQswCQYDVQQGEwJVUzEVMBMGA1UECBMMUGVubnN5bHZhbmlhMRMwEQYD + VQQHEwpQaXR0c2J1cmdoMSIwIAYDVQQKExlUZXN0U2hpYiBTZXJ2aWNlIFByb3Zp + ZGVyMRgwFgYDVQQDEw9zcC50ZXN0c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zAN + BgkqhkiG9w0BAQUFAAOCAQEAc06Kgt7ZP6g2TIZgMbFxg6vKwvDL0+2dzF11Onpl + 5sbtkPaNIcj24lQ4vajCrrGKdzHXo9m54BzrdRJ7xDYtw0dbu37l1IZVmiZr12eE + Iay/5YMU+aWP1z70h867ZQ7/7Y4HW345rdiS6EW663oH732wSYNt9kr7/0Uer3KD + 9CuPuOidBacospDaFyfsaJruE99Kd6Eu/w5KLAGG+m0iqENCziDGzVA47TngKz2v + PVA+aokoOyoz3b53qeti77ijatSEoKjxheBWpO+eoJeGq/e49Um3M2ogIX/JAlMa + Inh+vYSYngQB2sx9LGkR9KHaMKNIGCDehk93Xla4pWJx1w== + + + + + + + + + + + + + + + + + + + + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:mace:shibboleth:1.0:nameIdentifier + + + + + + + + + + + + + + + + + + + + TestShib Two Service Provider + TestShib Two + http://www.testshib.org/testshib-two/ + + + Nate + Klingenstein + ndk@internet2.edu + + + + + + + diff --git a/common/djangoapps/third_party_auth/management/commands/tests/test_saml.py b/common/djangoapps/third_party_auth/management/commands/tests/test_saml.py index 12d790bd1e..59f28f5817 100644 --- a/common/djangoapps/third_party_auth/management/commands/tests/test_saml.py +++ b/common/djangoapps/third_party_auth/management/commands/tests/test_saml.py @@ -3,11 +3,45 @@ Tests for `saml` management command, this command fetches saml metadata from pro existing data accordingly. """ import unittest +import os +import mock from django.test import TestCase from django.core.management import call_command from django.core.management.base import CommandError from django.conf import settings +from django.utils.six import StringIO + +from requests.models import Response + +from third_party_auth.tests.factories import SAMLConfigurationFactory, SAMLProviderConfigFactory + + +def mock_get(status_code=200): + """ + Args: + status_code (int): integer showing the status code for the response object. + + Returns: + returns a function that can be used as a mock function for requests.get. + """ + def _(url=None, *args, **kwargs): # pylint: disable=unused-argument + """ + mock method for requests.get, this method will read xml file, form a Response object from the + contents of this file, set status code and return the Response object. + """ + url = url.split("/")[-1] if url else "testshib-providers.xml" + + file_path = os.path.dirname(os.path.realpath(__file__)) + "/test_data/{}".format(url) + with open(file_path) as providers: + xml = providers.read() + + response = Response() + response._content = xml # pylint: disable=protected-access + response.status_code = status_code + + return response + return _ @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @@ -15,6 +49,28 @@ class TestSAMLCommand(TestCase): """ Test django management command for fetching saml metadata. """ + def setUp(self): + """ + Setup operations for saml configurations. these operations contain + creation of SAMLConfiguration and SAMLProviderConfig records in database. + """ + super(TestSAMLCommand, self).setUp() + + self.stdout = StringIO() + + # We are creating SAMLConfiguration instance here so that there is always at-least one + # disabled saml configuration instance, this is done to verify that disabled configurations are + # not processed. + SAMLConfigurationFactory.create(enabled=False) + SAMLProviderConfigFactory.create() + + def __create_saml_configurations__(self, saml_config=None, saml_provider_config=None): + """ + Helper method to create SAMLConfiguration and AMLProviderConfig. + """ + SAMLConfigurationFactory.create(enabled=True, **(saml_config or {})) + SAMLProviderConfigFactory.create(enabled=True, **(saml_provider_config or {})) + def test_raises_command_error_for_invalid_arguments(self): """ Test that management command raises `CommandError` with a proper message in case of @@ -29,3 +85,82 @@ class TestSAMLCommand(TestCase): # Call `saml` command without any argument so that it raises a CommandError with self.assertRaisesMessage(CommandError, "Command can only be used with '--pull' option."): call_command("saml", pull=False) + + def test_no_saml_configuration(self): + """ + Test that management command completes without errors and logs correct information when no + saml configurations are enabled/present. + """ + # Capture command output log for testing. + call_command("saml", pull=True, stdout=self.stdout) + + self.assertIn('Done. Fetched 0 total. 0 were updated and 0 failed.', self.stdout.getvalue()) + + @mock.patch("requests.get", mock_get()) + def test_fetch_saml_metadata(self): + """ + Test that management command completes without errors and logs correct information when + one or more saml configurations are enabled. + """ + # Create enabled configurations + self.__create_saml_configurations__() + + # Capture command output log for testing. + call_command("saml", pull=True, stdout=self.stdout) + + self.assertIn('Done. Fetched 1 total. 1 were updated and 0 failed.', self.stdout.getvalue()) + + @mock.patch("requests.get", mock_get(status_code=404)) + def test_fetch_saml_metadata_failure(self): + """ + Test that management command completes with proper message for errors + and logs correct information. + """ + # Create enabled configurations + self.__create_saml_configurations__() + + # Capture command output log for testing. + call_command("saml", pull=True, stdout=self.stdout) + + self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue()) + + @mock.patch("requests.get", mock_get(status_code=200)) + def test_fetch_multiple_providers_data(self): + """ + Test that management command completes with proper message for error or success + and logs correct information when there are multiple providers with their data. + """ + # Create enabled configurations + self.__create_saml_configurations__() + + # Add another set of configurations + self.__create_saml_configurations__( + saml_config={ + "site__domain": "second.testserver.fake", + }, + saml_provider_config={ + "site__domain": "second.testserver.fake", + "idp_slug": "second-test-shib", + "entity_id": "https://idp.testshib.org/idp/another-shibboleth", + "metadata_source": "https://www.testshib.org/metadata/another-testshib-providers.xml", + } + ) + + # Add another set of configurations + self.__create_saml_configurations__( + saml_config={ + "site__domain": "third.testserver.fake", + }, + saml_provider_config={ + "site__domain": "third.testserver.fake", + "idp_slug": "third-test-shib", + # Note: This entity id will not be present in returned response and will cause failed update. + "entity_id": "https://idp.testshib.org/idp/non-existent-shibboleth", + "metadata_source": "https://www.testshib.org/metadata/third/testshib-providers.xml", + } + ) + + # Capture command output log for testing. + call_command("saml", pull=True, stdout=self.stdout) + + self.assertIn('Done. Fetched 3 total. 2 were updated and 1 failed.', self.stdout.getvalue()) diff --git a/common/djangoapps/third_party_auth/tests/factories.py b/common/djangoapps/third_party_auth/tests/factories.py new file mode 100644 index 0000000000..c145f2296c --- /dev/null +++ b/common/djangoapps/third_party_auth/tests/factories.py @@ -0,0 +1,37 @@ +""" +Provides factories for third_party_auth models. +""" +from factory import SubFactory +from factory.django import DjangoModelFactory + +from third_party_auth.models import SAMLConfiguration, SAMLProviderConfig +from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory + + +class SAMLConfigurationFactory(DjangoModelFactory): + """ + Factory or SAMLConfiguration model in third_party_auth app. + """ + class Meta(object): + model = SAMLConfiguration + + site = SubFactory(SiteFactory) + enabled = True + + +class SAMLProviderConfigFactory(DjangoModelFactory): + """ + Factory or SAMLProviderConfig model in third_party_auth app. + """ + class Meta(object): + model = SAMLProviderConfig + django_get_or_create = ('idp_slug', 'metadata_source', "entity_id") + + site = SubFactory(SiteFactory) + + enabled = True + idp_slug = "test-shib" + name = "TestShib College" + + entity_id = "https://idp.testshib.org/idp/shibboleth" + metadata_source = "https://www.testshib.org/metadata/testshib-providers.xml" diff --git a/openedx/core/djangoapps/site_configuration/tests/factories.py b/openedx/core/djangoapps/site_configuration/tests/factories.py index 1e2cfd6359..f9277d1a41 100644 --- a/openedx/core/djangoapps/site_configuration/tests/factories.py +++ b/openedx/core/djangoapps/site_configuration/tests/factories.py @@ -24,6 +24,7 @@ class SiteFactory(DjangoModelFactory): """ class Meta(object): model = Site + django_get_or_create = ('domain',) domain = 'testserver.fake' name = 'testserver.fake'