"""JSON Validator Tests. Testing the logic for parsing RAML schemas and constructing validators """ import jsonschema import pytest from product import config from product.constants import header as header_constants from product.validation.schema import json_validators def mock_get_method_spec(mocker): """Mock the get method spec.""" def get_test_method_spec(resource, method): return config.API_TEST_DEFINITION.resources[resource].methods[method] mocker.patch.object( json_validators, 'get_method_spec', get_test_method_spec) def test_raml_header_to_json_schema(): """Test method that converts RAML parsed headers. Should be converted into JSON schema for our Draft3Validator class. """ response = json_validators.raml_header_to_json_schema( config.API_TEST_DEFINITION.resources[ '/test_header'].methods['get'].headers) assert response.get('properties').get( header_constants.CORRELATION_ID).get('type') == 'string' assert response.get('properties').get( header_constants.CONTENT_TYPE).get('type') == 'string' assert response.get('properties').get( header_constants.GRASS_ACCOUNT_TYPE).get('type') == 'string' assert response.get('properties').get( header_constants.GRASS_ACCOUNT_ID).get('type') == 'string' def test_raml_header_to_json_schema_load_draft3_validator(): """Test that the converted RAML to JSON Schema loads. Should be loaded into a Draft3Validator, and that it didn't load any properties set to None """ schema = json_validators.raml_header_to_json_schema( config.API_TEST_DEFINITION.resources[ '/test_header'].methods['get'].headers) # we know we didn't set the pattern property of Correlation-Id validator = jsonschema.Draft3Validator(schema) assert validator.schema.get('properties').get('Correlation-Id').\ get('pattern') is None def test_get_method_spec(monkeypatch): """Test that the expected method spec is returned.""" monkeypatch.setattr(config, 'API_DEFINITION', config.API_TEST_DEFINITION) method_spec = json_validators.get_method_spec('/test_header', 'get') expected_spec = config.API_TEST_DEFINITION.resources[ '/test_header'].methods['get'] assert method_spec == expected_spec def test_get_method_spec_hierarchy(monkeypatch): """Test that the expected method spec is returned.""" monkeypatch.setattr(config, 'API_DEFINITION', config.API_TEST_DEFINITION) method_spec = json_validators.get_method_spec( '/parent/child1/{id}', 'post') expected_spec = config.API_TEST_DEFINITION.resources['/parent']\ .resources['/child1'].resources['/{id}'].methods['post'] assert method_spec == expected_spec def test_get_method_spec_hierarchy_missing(monkeypatch): """Test when no matching spec is found.""" monkeypatch.setattr(config, 'API_DEFINITION', config.API_TEST_DEFINITION) with pytest.raises(KeyError): json_validators.get_method_spec('/parent/dummy', 'post') def test_query_args_validator_with_invalid_args(mocker): """Test that validator is invalid. Should be invalid when passed query params that do not match the RAML spec. """ mock_get_method_spec(mocker) args_validator = json_validators.query_args_validator( '/test_query_params', 'get') invalid_args = {'page_limit': 'a bajillion'} assert args_validator.is_valid(invalid_args) is False def test_query_args_validator_with_valid_args(mocker): """Test that validator is valid. Shoud be valid when passed query params that do match the RAML spec. """ mock_get_method_spec(mocker) args_validator = json_validators.query_args_validator( '/test_query_params', 'get') valid_args = {'page_limit': '100', 'page_offset': '50'} assert args_validator.is_valid(valid_args) is True def test_headers_validator_with_invalid_args(mocker): """Test that validator is invalid. Should be invalid when passed headers that do not match the RAML spec. """ mock_get_method_spec(mocker) headers_validator = json_validators.headers_validator( '/test_header', 'get') invalid_headers = {'Grass-Account-Id': 'five hundred plus infinity'} assert headers_validator.is_valid(invalid_headers) is False def test_headers_validator_with_valid_args(mocker): """Test that validator is valid when passed headers matching RAML spec.""" mock_get_method_spec(mocker) headers_validator = json_validators.headers_validator( '/test_header', 'get') valid_headers = { 'Correlation-Id': 'abc-123', 'Content-Type': 'application/json', 'Grass-Account-Id': '12345', 'Grass-Account-Type': 'vendor'} assert headers_validator.is_valid(valid_headers) is True def test_body_validator_with_invalid_body(mocker): """Test that validator is invalid. Should be invalid when passed body content that does not match the RAML spec. """ mock_get_method_spec(mocker) body_validator = json_validators.body_validator('/test_body', 'post') invalid_body = {'name': 123, 'artist_type': 'a bad one'} assert body_validator.is_valid(invalid_body) is False def test_body_validator_with_valid_body(mocker): """Test that validator is valid. Should be valid when passed body content that matches the RAML spec. """ mock_get_method_spec(mocker) body_validator = json_validators.body_validator('/test_body', 'post') valid_body = {'name': 'Somebody', 'artist_type': 'artist'} assert body_validator.is_valid(valid_body) is True