"""Tests for validation module.""" import json import flask import pytest from salessheets import handlers from salessheets.constants import error from salessheets.constants import features as feature_constants from salessheets.constants import field_const from salessheets.constants import salessheets from salessheets.validation import json_schema from salessheets.validation.schema import header from salessheets.validation.schema import pdf_generation_body app = flask.Flask(__name__) json_headers = {'Content-Type': 'application/json'} def test_validate_headers_fail(): """Assert that validate_headers fails when required field missing.""" headers = {field_const.GRASS_ACCOUNT_TYPE: 'vendor', field_const.GRASS_ACCOUNT_ID: '123'} @json_schema.validate_headers(header.schema) def function(): pass with app.test_request_context(headers=headers): response = function() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.HEADER_VALIDATION_ERROR == response_json[field_const.CODE] assert "'{}' is a required property".format( field_const.ORCHARD_USER_ID) in response_json[field_const.MESSAGE] def test_validate_headers_success(valid_headers): """Assert that validate_headers succeeds when headers valid.""" @json_schema.validate_headers(header.schema) def function(): return 42 with app.test_request_context(headers=valid_headers): assert 42 == function() def test_validate_headers_if_alw_fflag_true_success(valid_headers): """Assert validate_headers succeeds for OA user if alw fflag is on.""" @json_schema.validate_headers(header.schema) def function(): return 42 with app.test_request_context(headers=valid_headers): assert 42 == function() def test_validate_alw_headers_on_success(valid_alw_headers): """Assert validate_headers succeeds for ALW user if alw fflag is on.""" @json_schema.validate_headers(header.schema) def function(): return 42 with app.test_request_context(headers=valid_alw_headers): assert 42 == function() @pytest.mark.parametrize('key, value, error_message', [ (field_const.ORCHARD_USER_ID, 'invalid_prefix:123456', "'invalid_prefix:123456' does not match '^(oa:|alw:)'"), (field_const.GRASS_ACCOUNT_ID, 'invalid_id_contains_letters:123456', "invalid_id_contains_letters:123456' does not match '^\\\\d+$"), (field_const.GRASS_ACCOUNT_TYPE, 'invalid_type', "'invalid_type' does not match '^(vendor|subaccount)$'"), ]) def test_validate_headers_for_alw_user_fail( valid_alw_headers, key, value, error_message): """Assert that validate_headers fails when inappropriate params passed.""" valid_alw_headers[key] = value @json_schema.validate_headers(header.schema) def function(): pass with app.test_request_context(headers=valid_alw_headers): response = function() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.HEADER_VALIDATION_ERROR == response_json[field_const.CODE] assert error_message in response_json[field_const.MESSAGE] def test_validate_headers_for_alw_user_grass_account_type_fail( alw_headers_missing_grass_account_type): """Assert that validate_headers fails without Grass-Account-Type.""" @json_schema.validate_headers(header.schema) def function(): pass with app.test_request_context( headers=alw_headers_missing_grass_account_type): response = function() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.HEADER_VALIDATION_ERROR == response_json[field_const.CODE] assert "'Grass-Account-Type' is a required property" in response_json[ field_const.MESSAGE] def test_validate_headers_for_alw_user_grass_account_id_fail( alw_headers_missing_grass_account_id): """Assert that validate_headers fails without Grass-Account-Id.""" @json_schema.validate_headers(header.schema) def function(): pass with app.test_request_context( headers=alw_headers_missing_grass_account_id): response = function() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.HEADER_VALIDATION_ERROR == response_json[field_const.CODE] assert "'Grass-Account-Id' is a required property" in response_json[ field_const.MESSAGE] def test_validate_empty_headers_if_alw_fflag_true_success(): """Assert validate_headers succeeds if no header if alw fflag is on.""" @json_schema.validate_headers(header.schema) def function(): return 42 with app.test_request_context(): assert 42 == function() def test_validate_body_pdf_generation_body_schema_fail(): """Assert that validate_body fails. Assert that validate_body with pdf_generation_body_schema fails when required field missing. """ @json_schema.validate_body(pdf_generation_body.schema) def func(): pass with app.test_request_context(data='{}', headers=json_headers): response = func() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.BODY_VALIDATION_ERROR == response_json[field_const.CODE] assert "'{}' is a required property".format( salessheets.GENERATION_METHOD) in response_json[field_const.MESSAGE] def test_validate_body_pdf_generation_body_schema_success(): """Assert that validate_body succeeds when body valid. Assert that validate_body with pdf_generation_body_schema succeeds when required field filled. """ data = json.dumps({ salessheets.GENERATION_METHOD: salessheets.ALLOWED_GENERATION_METHODS[1], salessheets.UPCS: [1234123]}) @json_schema.validate_body(pdf_generation_body.schema) def func(): return 42 with app.test_request_context(data=data, headers=json_headers): assert 42 == func() def test_validate_body_pdf_generation_body_duplicate_upc_success( valid_headers): """Assert that validate_body succeeds when body is valid. Assert that validate_body with pdf_generation_body.schema_duplicate_upc succeeds when required fields are present. """ data = json.dumps({ salessheets.GENERATION_METHOD: salessheets.ALLOWED_GENERATION_METHODS[1], salessheets.CONTEXT: ['1234123']}) @json_schema.validate_body(pdf_generation_body.schema_duplicate_upc) def func(): return 42 with app.test_request_context(data=data, headers=json_headers): assert 42 == func() def test_validate_body_duplicate_upc_if_select_template_enabled_success( features_mock): """Assert that validate_body succeeds when body is valid. Assert that validate_body with pdf_generation_body.schema_duplicate_upc succeeds when select template feature is enabled and required fields are present. """ features_mock.force_flag( feature_constants.SALES_SHEETS_SELECT_TEMPLATE, True) data = json.dumps({ salessheets.GENERATION_METHOD: salessheets.ALLOWED_GENERATION_METHODS[1], salessheets.CONTEXT: ['1234123'], salessheets.TEMPLATE_TYPE: 'orchard'}) @json_schema.validate_body( pdf_generation_body.schema_duplicate_upc, schema_tweaks=handlers.post_validation_schema_tweaks) def func(): return 42 with app.test_request_context(data=data, headers=json_headers): assert 42 == func() def test_validate_body_if_localized_sales_sheets_enabled_success( valid_headers, features_mock): """Assert that validate_body succeeds when body is valid. Assert that validate_body with pdf_generation_body.schema_duplicate_upc succeeds when localized sales sheets feature is enabled and required fields are present. """ features_mock.force_flag( feature_constants.LOCALIZED_SALES_SHEETS, True) data = json.dumps({ salessheets.GENERATION_METHOD: salessheets.ALLOWED_GENERATION_METHODS[1], salessheets.CONTEXT: ['1234123'], salessheets.LOCALIZED_TEMPLATE_TYPE_ID: 1}) @json_schema.validate_body( pdf_generation_body.schema_duplicate_upc, schema_tweaks=handlers.post_validation_schema_tweaks) def func(): return 42 with app.test_request_context(data=data, headers=json_headers): assert 42 == func() def test_validate_body_pdf_generation_body_duplicate_upc_schema_fail(): """Assert that validate_body fails. Assert that validate_body with pdf_generation_body.schema_duplicate_upc fails when required field missing. """ @json_schema.validate_body(pdf_generation_body.schema_duplicate_upc) def func(): pass with app.test_request_context(data='{}', headers=json_headers): response = func() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.BODY_VALIDATION_ERROR == response_json[field_const.CODE] assert "'{}' is a required property".format( salessheets.GENERATION_METHOD) in response_json[field_const.MESSAGE] def test_validate_body_duplicate_upc_if_select_template_enabled_schema_fail( features_mock): """Assert that validate_body fails. Assert that validate_body with pdf_generation_body.schema_duplicate_upc fails when template type invalid. """ features_mock.force_flag( feature_constants.SALES_SHEETS_SELECT_TEMPLATE, True) data = json.dumps({ salessheets.GENERATION_METHOD: salessheets.ALLOWED_GENERATION_METHODS[1], salessheets.CONTEXT: ['1234123'], salessheets.TEMPLATE_TYPE: 'invalid_type'}) @json_schema.validate_body( pdf_generation_body.schema_duplicate_upc, schema_tweaks=handlers.post_validation_schema_tweaks) def func(): pass with app.test_request_context(data=data, headers=json_headers): response = func() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.BODY_VALIDATION_ERROR == response_json[field_const.CODE] assert "'invalid_type' is not one of ['orchard', 'redessential']" \ in response_json[field_const.MESSAGE] def test_validate_body_if_localized_sales_sheets_enabled_schema_fail(features_mock): """Assert that validate_body fails. Assert that validate_body with pdf_generation_body.schema_duplicate_upc fails when localized template type id is invalid. """ features_mock.force_flag( feature_constants.LOCALIZED_SALES_SHEETS, True) data = json.dumps({ salessheets.GENERATION_METHOD: salessheets.ALLOWED_GENERATION_METHODS[1], salessheets.CONTEXT: ['1234123'], salessheets.LOCALIZED_TEMPLATE_TYPE_ID: 'invalid_type'}) @json_schema.validate_body( pdf_generation_body.schema_duplicate_upc, schema_tweaks=handlers.post_validation_schema_tweaks) def func(): pass with app.test_request_context(data=data, headers=json_headers): response = func() assert flask.Response == type(response) response_json = json.loads(response.data.decode()) assert 400 == response.status_code assert error.BODY_VALIDATION_ERROR == response_json[field_const.CODE] assert ( "'invalid_type' is not of type 'integer'" in response_json[field_const.MESSAGE])