def test_ocr_on_create_with_cannot_ocr_flag( self, client: Client, settings: SettingsWrapper) -> None: """Verify the OCR process exits early if the cannot_ocr flag is already set.""" settings.ENABLE_OCR = True settings.IMAGE_DOMAINS = ["example.com"] assert Transcription.objects.count() == 0 client, headers, _ = setup_user_client(client) source = get_default_test_source() data = { "original_id": "spaaaaace", "source": source.pk, "content_url": "http://example.com/a.jpg", "cannot_ocr": "True", } with patch("api.models.process_image", return_value={"text": "AAA"}) as mock: # mock it anyway just in case this fails -- we don't want to actually # call OCR result = client.post( reverse("submission-list"), data, content_type="application/json", **headers, ) mock.assert_not_called() assert result.status_code == status.HTTP_201_CREATED assert Transcription.objects.count() == 0
def test_failed_ocr_on_create(self, client: Client, settings: SettingsWrapper) -> None: """Verify that a new submission completes the OCR process.""" settings.ENABLE_OCR = True settings.IMAGE_DOMAINS = ["example.com"] assert Transcription.objects.count() == 0 client, headers, _ = setup_user_client(client) source = get_default_test_source() data = { "original_id": "spaaaaace", "source": source.pk, "content_url": "http://example.com/a.jpg", } with patch("api.models.process_image", return_value=None) as mock: result = client.post( reverse("submission-list"), data, content_type="application/json", **headers, ) mock.assert_called_once() assert result.status_code == status.HTTP_201_CREATED assert Transcription.objects.count() == 0 assert result.json().get("cannot_ocr") is True
def test_get_django_omit_exceptions_priority_1(settings: SettingsWrapper): caches_setting = copy.deepcopy(settings.CACHES) caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = True settings.CACHES = caches_setting settings.DJANGO_REDIS_IGNORE_EXCEPTIONS = False cache = cast(RedisCache, caches["doesnotexist"]) assert cache._ignore_exceptions is True assert cache.get("key") is None
def test_get_django_omit_exceptions_priority_2(settings: SettingsWrapper): caches_setting = copy.deepcopy(settings.CACHES) caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = False settings.CACHES = caches_setting settings.DJANGO_REDIS_IGNORE_EXCEPTIONS = True cache = cast(RedisCache, caches["doesnotexist"]) assert cache._ignore_exceptions is False with pytest.raises(ConnectionError): cache.get("key")
def test_get_metadata_success_with_local_file(settings: SettingsWrapper): """Test get_metadata function to verify if correctly returns path to local metadata file. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = None settings.SAML2_AUTH["METADATA_LOCAL_FILE_PATH"] = "/absolute/path/to/metadata.xml" result = get_metadata() assert result == {"local": ["/absolute/path/to/metadata.xml"]}
def test_get_metadata_success_with_single_metadata_url(settings: SettingsWrapper): """Test get_metadata function to verify if it returns a valid metadata URL with a correct format. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["METADATA_AUTO_CONF_URL"] = METADATA_URL1 settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = None responses.add(responses.GET, METADATA_URL1, body=METADATA1) result = get_metadata() assert result == {"remote": [{"url": METADATA_URL1}]}
def test_get_metadata_failure_with_invalid_metadata_url(settings: SettingsWrapper): """Test get_metadata function to verify if it fails with invalid metadata information. Args: settings (SettingsWrapper): Fixture for django settings """ # HTTP Responses are not mocked, so this will fail. settings.SAML2_AUTH["METADATA_AUTO_CONF_URL"] = METADATA_URL1 settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = None with pytest.raises(SAMLAuthError) as exc_info: get_metadata() assert str(exc_info.value) == "Invalid metadata URL."
def test_get_saml_client_failure_with_invalid_file(settings: SettingsWrapper): """Test get_saml_client function to verify if it raises an exception given an invalid path to metadata file. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["METADATA_LOCAL_FILE_PATH"] = "/invalid/metadata.xml" settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = None with pytest.raises(SAMLAuthError) as exc_info: get_saml_client("example.com", acs) assert str(exc_info.value) == "[Errno 2] No such file or directory: '/invalid/metadata.xml'" assert isinstance(exc_info.value.extra["exc"], FileNotFoundError)
def key_prefix_cache( cache: RedisCache, settings: SettingsWrapper ) -> Iterable[RedisCache]: caches_setting = copy.deepcopy(settings.CACHES) caches_setting["default"]["KEY_PREFIX"] = "*" settings.CACHES = caches_setting yield cache
def test_get_or_create_user_success(settings: SettingsWrapper): """Test get_or_create_user function to verify if it creates a new user and joins it to the correct group based on the given SAML group and its mapping with internal groups. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH = { "ATTRIBUTES_MAP": { "groups": "groups", }, "GROUPS_MAP": { "consumers": "users" } } Group.objects.create(name="users") created, user = get_or_create_user({ "username": "******", "first_name": "John", "last_name": "Doe", "user_identity": { "user.username": "******", "user.first_name": "John", "user.last_name": "Doe", "groups": ["consumers"] } }) assert created assert user.username == "*****@*****.**" assert user.is_active == True assert user.has_usable_password() == False assert user.groups.get(name="users") == Group.objects.get(name="users")
def test_get_or_create_user_trigger_error(settings: SettingsWrapper): """Test get_or_create_user function to verify if it raises an exception in case the CREATE_USER trigger function is nonexistent. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH = { "TRIGGER": { "CREATE_USER": "******", } } with pytest.raises(SAMLAuthError) as exc_info: get_or_create_user({ "username": "******", "first_name": "John", "last_name": "Doe" }) assert str(exc_info.value) == ( "module 'django_saml2_auth.tests.test_user' has no attribute 'nonexistent_trigger'" ) assert isinstance(exc_info.value.extra["exc"], AttributeError)
def test_get_or_create_user_trigger_change_first_name( settings: SettingsWrapper): """Test get_or_create_user function to verify if it correctly triggers the CREATE_USER function and the trigger updates the user's first name. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH = { "TRIGGER": { "CREATE_USER": "******", } } created, user = get_or_create_user({ "username": "******", "first_name": "John", "last_name": "Doe" }) assert created assert user.username == "*****@*****.**" assert user.first_name == "CHANGED_FIRSTNAME" assert user.is_active == True assert user.has_usable_password() == False
def test_check_reddit_for_missing_information( self, client: Client, settings: SettingsWrapper) -> None: """Verify that if information is missing we will check Reddit for it.""" client, _, user = setup_user_client(client) add_social_auth_to_user(user) settings.ENABLE_REDDIT = True class RedditSubmission: class Response: over_18 = True title = "AAA" def submission(self, **kwargs: Any) -> Response: """Return a mocked response from Reddit.""" return self.Response() with patch("app.middleware.configure_reddit", lambda a: RedditSubmission()): submission = create_submission( original_id=int(random.random() * 1000), content_url="http://imgur.com", ) client.get(reverse("choose_transcription")) submission.refresh_from_db() assert submission.title == "AAA" assert submission.nsfw is True
def test_decode_saml_response_success(settings: SettingsWrapper, monkeypatch: "MonkeyPatch"): """Test decode_saml_response function to verify if it correctly decodes the SAML response. Args: settings (SettingsWrapper): Fixture for django settings monkeypatch (MonkeyPatch): PyTest monkeypatch fixture """ responses.add(responses.GET, METADATA_URL1, body=METADATA1) settings.SAML2_AUTH["ASSERTION_URL"] = "https://api.example.com" settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = GET_METADATA_AUTO_CONF_URLS post_request = RequestFactory().post(METADATA_URL1, {"SAMLResponse": "SAML RESPONSE"}) monkeypatch.setattr(Saml2Client, "parse_authn_request_response", mock_parse_authn_request_response) result = decode_saml_response(post_request, acs) assert len(result.get_identity()) > 0
def test_challenge_request(client: Client, settings: SettingsWrapper) -> None: """Test handling of Slack's new endpoint challenge message.""" settings.SLACK_SIGNING_SECRET = SLACK_SIGNING_SECRET data = {"challenge": "asdfasdfasdf"} headers = get_slack_headers(data, settings) result = client.post(reverse("slack"), json.dumps(data), content_type="application/json", **headers) assert result.content == b"asdfasdfasdf"
def test_get_saml_client_success(settings: SettingsWrapper): """Test get_saml_client function to verify if it is correctly instantiated with local metadata file. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["METADATA_LOCAL_FILE_PATH"] = "django_saml2_auth/tests/metadata.xml" result = get_saml_client("example.com", acs) assert isinstance(result, Saml2Client)
def test_close_disconnect_settings( self, cache_client: DefaultClient, settings: SettingsWrapper, mocker: MockerFixture, ): settings.DJANGO_REDIS_CLOSE_CONNECTION = True mock = mocker.patch.object(cache_client.connection_factory, "disconnect") cache_client.close() assert mock.called
def test_get_assertion_url_no_assertion_url(settings: SettingsWrapper): """Test get_assertion_url function to verify if it correctly returns the server's assertion URL based on the incoming request. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["ASSERTION_URL"] = None get_request = RequestFactory().get("/acs/") assertion_url = get_assertion_url(get_request) assert assertion_url == "http://testserver"
def test_get_metadata_success_with_user_id(settings: SettingsWrapper): """Test get_metadata function to verify if it returns a valid metadata URLs given the user_id. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = GET_METADATA_AUTO_CONF_URLS responses.add(responses.GET, METADATA_URL1, body=METADATA1) result = get_metadata("*****@*****.**") assert result == {"remote": [{"url": METADATA_URL1}]}
def test_get_metadata_failure_with_nonexistent_user_id(settings: SettingsWrapper): """Test get_metadata function to verify if it raises an exception given a nonexistent user_id. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = GET_METADATA_AUTO_CONF_URLS with pytest.raises(SAMLAuthError) as exc_info: get_metadata("*****@*****.**") assert str(exc_info.value) == "No metadata URL associated with the given user identifier."
def test_close_disconnect_settings_cache( self, cache_client: DefaultClient, mocker: MockerFixture, settings: SettingsWrapper, ): settings.CACHES[DEFAULT_CACHE_ALIAS]["OPTIONS"]["CLOSE_CONNECTION"] = True cache_client.set("TestClientClose", 0) mock = mocker.patch.object(cache_client.connection_factory, "disconnect") cache_client.close() assert mock.called
def test_get_saml_client_success_with_user_id(settings: SettingsWrapper): """Test get_saml_client function to verify if it is correctly instantiated with remote metadata URL and valid user_id. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = GET_METADATA_AUTO_CONF_URLS responses.add(responses.GET, METADATA_URL1, body=METADATA1) result = get_saml_client("example.com", acs, "*****@*****.**") assert isinstance(result, Saml2Client)
def test_bootstrap_check(settings: SettingsWrapper) -> None: """ Verify that the bootstrap command must be run. Because the bootstrap command auto-runs on every test, we have to manually fake that it _hasn't_ run. """ Post.objects.all().delete() settings.ENVIRONMENT = "prod" with pytest.raises(ImproperlyConfigured): get_additional_context({})
def test_get_metadata_success_with_multiple_metadata_urls(settings: SettingsWrapper): """Test get_metadata function to verify if it returns multiple metadata URLs if the user_id is unknown. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = GET_METADATA_AUTO_CONF_URLS responses.add(responses.GET, METADATA_URL1, body=METADATA1) responses.add(responses.GET, METADATA_URL2, body=METADATA2) result = get_metadata() assert result == {"remote": [{"url": METADATA_URL1}, {"url": METADATA_URL2}]}
def test_get_saml_client_failure_with_missing_metadata_url(settings: SettingsWrapper): """Test get_saml_client function to verify if it raises an exception given a missing non-mocked metadata URL. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["TRIGGER"]["GET_METADATA_AUTO_CONF_URLS"] = GET_METADATA_AUTO_CONF_URLS with pytest.raises(SAMLAuthError) as exc_info: get_saml_client("example.com", acs, "*****@*****.**") assert str(exc_info.value) == "Metadata URL/file is missing."
def test_permissions_override_api_auth(self, rf: RequestFactory, settings: SettingsWrapper) -> None: """Test whether the API does allow superusers without API key access.""" # first, verify that access is denied user = create_user(is_staff=False, is_grafeas_staff=False) request = rf.get("/") request.user = user assert not BlossomApiPermission().has_permission(request, None) # now make sure it works with the flag toggled on settings.OVERRIDE_API_AUTH = True request = rf.get("/") request.user = user assert BlossomApiPermission().has_permission(request, None)
def test_get_default_next_url_no_default_next_url(settings: SettingsWrapper): """Test get_default_next_url function with no default next url for redirection to see if it returns the admin:index route. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH["DEFAULT_NEXT_URL"] = None with pytest.raises(SAMLAuthError) as exc_info: get_default_next_url() # This doesn't happen on a real instance, unless you don't have "admin:index" route assert str(exc_info.value) == "We got a URL reverse issue: ['admin:index']" assert issubclass(exc_info.value.extra["exc_type"], NoReverseMatch)
def test_create_jwt_token_no_secret_no_algorithm(settings: SettingsWrapper): """Test create_jwt_token function by trying to create a JWT token with no secret and algorithm set. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH = {"JWT_SECRET": None, "JWT_ALGORITHM": None} with pytest.raises(SAMLAuthError) as exc_info: create_jwt_token("*****@*****.**") assert str(exc_info.value ) == "Cannot create JWT token. Specify secret and algorithm."
def test_create_new_user_no_group_error(settings: SettingsWrapper): """Test create_new_user function to verify if it creates the user, but fails to join the user to the respective group. Args: settings (SettingsWrapper): Fixture for django settings """ settings.SAML2_AUTH = { "NEW_USER_PROFILE": { "USER_GROUPS": ["users"], } } with pytest.raises(SAMLAuthError) as exc_info: create_new_user("*****@*****.**", "John", "Doe") assert str( exc_info.value) == "There was an error joining the user to the group." assert exc_info.value.extra["exc_type"] == Group.DoesNotExist
def test_custom_key_function(cache: RedisCache, settings: SettingsWrapper): caches_setting = copy.deepcopy(settings.CACHES) caches_setting["default"]["KEY_FUNCTION"] = "test_cache_options.make_key" caches_setting["default"]["REVERSE_KEY_FUNCTION"] = "test_cache_options.reverse_key" settings.CACHES = caches_setting if isinstance(cache.client, ShardClient): pytest.skip("ShardClient doesn't support get_client") for key in ["foo-aa", "foo-ab", "foo-bb", "foo-bc"]: cache.set(key, "foo") res = cache.delete_pattern("*foo-a*") assert bool(res) is True keys = cache.keys("foo*") assert set(keys) == {"foo-bb", "foo-bc"} # ensure our custom function was actually called assert {k.decode() for k in cache.client.get_client(write=False).keys("*")} == ( {"#1#foo-bc", "#1#foo-bb"} )