def test_successful_json_fetch(monkeypatch) -> None:
    """
    Tests that a file is fetched successfully.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': json_path})
    base = LoadStaticSchema('api/v1/trucks/correct', 'GET', status_code=200)
    content = base.get_schema()
    assert 'title' in content
def test_successful_parse_undocumented_endpoints(monkeypatch) -> None:
    """
    Asserts that a schema section is returned successfully.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': yml_path})
    monkeypatch.setattr('django_swagger_tester.static_schema.loader.LoadStaticSchema.get_schema', ret_schema)
    for url in ['/api/v1/cars/incorrect/', '/api/v1/trucks/incorrect/']:
        base = LoadStaticSchema(url, 'get', status_code=200)
        base.get_response_schema()
def test_non_existent_file(caplog, monkeypatch) -> None:
    """
    Asserts that a non-existent file will raise an error.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': 'test'})
    base = LoadStaticSchema('api/v1/trucks/correct', 'GET', status_code=200)
    with pytest.raises(
            ImproperlyConfigured,
            match=
            'The path `test` does not point to a valid file. Make sure to point to the specification file.',
    ):
        base.get_schema()
        assert 'Path `test` does not resolve as a valid file.' in caplog.records
def test_successful_parse_documented_endpoints(monkeypatch) -> None:
    """
    Asserts that a schema section is returned successfully.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': yml_path})
    monkeypatch.setattr('django_swagger_tester.static_schema.loader.LoadStaticSchema.get_schema', ret_schema)
    documented_endpoints = [
        {
            'url': '/api/v1/cars/correct/',
            'expected': {
                'title': 'Success',
                'type': 'array',
                'items': {
                    'title': 'Success',
                    'type': 'object',
                    'properties': {
                        'name': {'description': 'A swedish car?', 'type': 'string', 'example': 'Saab'},
                        'color': {'description': 'The color of the car.', 'type': 'string', 'example': 'Yellow'},
                        'height': {'description': 'How tall the car is.', 'type': 'string', 'example': 'Medium height'},
                        'width': {'description': 'How wide the car is.', 'type': 'string', 'example': 'Very wide'},
                        'length': {'description': 'How long the car is.', 'type': 'string', 'example': '2 meters'},
                    },
                },
            },
        },
        {
            'url': '/api/v1/trucks/correct/',
            'expected': {
                'title': 'Success',
                'type': 'array',
                'items': {
                    'title': 'Success',
                    'type': 'object',
                    'properties': {
                        'name': {'description': 'A swedish truck?', 'type': 'string', 'example': 'Saab'},
                        'color': {'description': 'The color of the truck.', 'type': 'string', 'example': 'Yellow'},
                        'height': {
                            'description': 'How tall the truck is.',
                            'type': 'string',
                            'example': 'Medium height',
                        },
                        'width': {'description': 'How wide the truck is.', 'type': 'string', 'example': 'Very wide'},
                        'length': {'description': 'How long the truck is.', 'type': 'string', 'example': '2 meters'},
                    },
                },
            },
        },
    ]
    for item in documented_endpoints:
        base = LoadStaticSchema(item['url'], 'get', status_code=200)  # type: ignore
        assert base.get_response_schema() == item['expected']
def test_bad_filetype(monkeypatch) -> None:
    """
    Asserts that an appropriate exception is raised when a function tries to pass a non yml/json schema.
    """
    monkeypatch.setattr(
        django_settings, 'SWAGGER_TESTER',
        {'PATH': settings.BASE_DIR + '/demo_project/settings.py'})
    base = LoadStaticSchema('api/v1/trucks/correct', 'GET', status_code=200)
    with pytest.raises(
            ImproperlyConfigured,
            match=
            'The specified file path does not seem to point to a JSON or YAML file.'
    ):
        base.get_schema()
def test_validation(monkeypatch):
    """
    Verify that validation runs successfully for the demo project.
    """
    path = django_settings.BASE_DIR + '/demo_project/openapi-schema.yml'
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': path})
    base = LoadStaticSchema('api/v1/trucks/correct', 'get', status_code=200)
    assert base.path == path
def test_no_matching_routes(monkeypatch) -> None:
    """
    Asserts that the right exception is raised when an endpoint is not documented in the schema.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': yml_path})
    monkeypatch.setattr('django_swagger_tester.static_schema.loader.LoadStaticSchema.get_schema', ret_bad_schema)
    with pytest.raises(ValueError, match='Could not resolve path'):
        LoadStaticSchema('apsi/v1/trucks/correct', 'get', status_code=200)
def test_bad_path_type(monkeypatch):
    """
    Verify that validation runs successfully for the demo project.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': 2})
    with pytest.raises(
        ImproperlyConfigured, match='`PATH` needs to be a string. Please update your SWAGGER_TESTER settings.'
    ):
        LoadStaticSchema('api/v1/trucks/correct', 'get', status_code=200)
def test_missing_path(monkeypatch):
    """
    Verify that validation runs successfully for the demo project.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {})
    with pytest.raises(
        ImproperlyConfigured,
        match='\`PATH\` is required when testing static schemas. ' 'Please update your SWAGGER_TESTER settings.',
    ):
        LoadStaticSchema('api/v1/trucks/correct', 'get', status_code=200)
def test_unreadable_file(monkeypatch, caplog) -> None:
    """
    Asserts that the appropriate error is raised when we fail to read a file.
    """
    def mocked_isfile(*args, **kwargs):
        return True

    monkeypatch.setattr(
        'django_swagger_tester.static_schema.loader.os.path.isfile',
        mocked_isfile)

    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER',
                        {'PATH': yml_path + 's'})
    base = LoadStaticSchema('api/v1/trucks/correct', 'GET', status_code=200)
    with pytest.raises(
            ImproperlyConfigured,
            match=
            'Unable to read the schema file. Please make sure the path setting is correct.'
    ):
        base.get_schema()
def test_method_missing_from_schema(monkeypatch) -> None:
    """
    Asserts that a non-existent method raises the appropriate exception.
    """
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': yml_path})
    monkeypatch.setattr('django_swagger_tester.static_schema.loader.LoadStaticSchema.get_schema', ret_schema)
    with pytest.raises(
        ImproperlyConfigured,
        match='Method \`gets\` is invalid. Should be one of: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD.',
    ):
        LoadStaticSchema('api/v1/trucks/correct', 'gets', status_code=200)
def test_drf_yasg_not_installed(monkeypatch):
    """
    Verify that validation raises an exception if the package isnt installed.
    """
    path = django_settings.BASE_DIR + '/demo_project/openapi-schema.yml'
    monkeypatch.setattr(django_settings, 'SWAGGER_TESTER', {'PATH': path})
    import sys

    # Mock away the drf_yasg dependency
    temp = sys.modules['yaml']
    sys.modules['yaml'] = None

    with pytest.raises(
        ImproperlyConfigured,
        match='The package `PyYAML` is required for parsing yaml files. '
        'Please run `pip install PyYAML` to install it.',
    ):
        LoadStaticSchema('api/v1/trucks/correct', 'get', status_code=200)

    sys.modules['yaml'] = temp