"""Tests for validation module.""" import json from unittest import mock import pytest from werkzeug.datastructures import ImmutableMultiDict from assets.constants import error from assets.constants import field_const from assets.validation import json_schema from assets.validation.schema import query @pytest.fixture def required_params(): """Function that returns list of required arguments for tested schema. Returns: list: required arguments for tested schema """ return ['string_value', 'number_value', 'array_value'] @pytest.fixture def tested_schema(required_params): """Function that returns json-schema for test validation. Returns: dict: schema dict. """ return { '$schema': 'http://json-schema.org/draft-04/schema#', 'title': 'Schema for query validation testing', 'type': 'object', 'properties': { required_params[0]: { 'type': 'string' }, required_params[1]: { 'type': 'number' }, required_params[2]: { 'type': 'array' }, }, 'required': ['string_value', 'number_value', 'array_value'], 'additionalProperties': False } @pytest.fixture def fixture_function(request, schema): """Function to mock real endpoint handler.""" @json_schema.validate_query(request, schema) def function(): return 'test_result' return function() @pytest.fixture def generate_query_params(required_params): """Function that returns valid query params. Returns: ImmutableMultiDict: dictionary of query key-values """ query_params = { required_params[0]: 'string', required_params[1]: 10, required_params[2]: ['value1', 'value2'] } return ImmutableMultiDict(query_params) def test_validate_query_success(generate_query_params, tested_schema): """Assert that validate_query succeeds when query is valid.""" request = mock.Mock() request.args = generate_query_params assert 'test_result' == fixture_function(request, tested_schema) @pytest.mark.parametrize('missing_param', required_params()) def test_post_validate_query_missing_params_fail( missing_param, generate_query_params, tested_schema): """Assert that validate_query fails when params is missing.""" request = mock.Mock() current_args = generate_query_params.to_dict() del current_args[missing_param] request.args = ImmutableMultiDict(current_args) response = fixture_function(request, tested_schema) assert response.status_code == 400 response_json = json.loads(response.data.decode()) assert response_json['code'] == error.ERROR_CODE_QUERY_VALIDATION def test_validate_extra_params_fail(tested_schema, generate_query_params): """Assert that validate_query fails unknown field.""" request = mock.Mock() current_args = generate_query_params.to_dict() current_args['extra_field'] = 'some_string' request.args = ImmutableMultiDict(current_args) response = fixture_function(request, tested_schema) assert response.status_code == 400 response_json = json.loads(response.data.decode()) assert response_json['code'] == error.ERROR_CODE_QUERY_VALIDATION @pytest.mark.parametrize('args', [ {'string_value': 1, 'number_value': 2, 'array_value': ['f']}, {'string_value': 'str', 'number_value': 'FF', 'array_value': ['f']}, {'string_value': 'str', 'number_value': 2, 'array_value': 'f'}]) def test_validate_query_invalid_types_field_fail(args, tested_schema): """Assert that validate_query fails when params types don't match.""" request = mock.Mock() request.args = ImmutableMultiDict(args) response = fixture_function(request, tested_schema) assert response.status_code == 400 response_json = json.loads(response.data.decode()) assert response_json['code'] == error.ERROR_CODE_QUERY_VALIDATION def test_get_assets_status_validate_query_success(): """Assert that validate_query succeeds when query is valid.""" request = mock.Mock() request.args = ImmutableMultiDict({field_const.FILENAME: 'test_file.mp3'}) assert 'test_result' == fixture_function( request, query.get_assets_status_schema) def test_get_assets_status_validate_query_fail(): """Assert that validate_query fails when query is invalid.""" request = mock.Mock() request.args = ImmutableMultiDict({'invalid_key': 'test_file.mp3'}) response = fixture_function(request, query.get_assets_status_schema) assert response.status_code == 400 response_json = json.loads(response.data.decode()) assert response_json['code'] == error.ERROR_CODE_QUERY_VALIDATION