import openapi_spec_validator as osv


def test_openapi_fields(app, client):
    openapi_version = '3.0.2'
    description = 'My API'
    tags = [
        {
            'name': 'foo',
            'description': 'some description for foo',
            'externalDocs': {
                'description': 'Find more info about foo here',
                'url': 'https://docs.example.com/',
            },
        },
        {'name': 'bar', 'description': 'some description for bar'},
    ]
    contact = {
        'name': 'API Support',
        'url': 'http://www.example.com/support',
        'email': 'support@example.com',
    }
    license = {'name': 'Apache 2.0', 'url': 'http://www.apache.org/licenses/LICENSE-2.0.html'}
    terms_of_service = 'http://example.com/terms/'
    external_docs = {'description': 'Find more info here', 'url': 'https://docs.example.com/'}
    servers = [
        {'url': 'http://localhost:5000/', 'description': 'Development server'},
        {'url': 'https://api.example.com/', 'description': 'Production server'},
    ]
    app.config['OPENAPI_VERSION'] = openapi_version
    app.config['DESCRIPTION'] = description
    app.config['TAGS'] = tags
    app.config['CONTACT'] = contact
    app.config['LICENSE'] = license
    app.config['TERMS_OF_SERVICE'] = terms_of_service
    app.config['EXTERNAL_DOCS'] = external_docs
    app.config['SERVERS'] = servers

    rv = client.get('/openapi.json')
    assert rv.status_code == 200
    osv.validate(rv.json)
    assert rv.json['openapi'] == openapi_version
    assert rv.json['tags'] == tags
    assert rv.json['servers'] == servers
    assert rv.json['externalDocs'] == external_docs
    assert rv.json['info']['description'] == description
    assert rv.json['info']['contact'] == contact
    assert rv.json['info']['license'] == license
    assert rv.json['info']['termsOfService'] == terms_of_service


def test_info(app, client):
    app.config['INFO'] = {
        'description': 'My API',
        'termsOfService': 'http://example.com',
        'contact': {
            'name': 'API Support',
            'url': 'http://www.example.com/support',
            'email': 'support@example.com',
        },
        'license': {'name': 'Apache 2.0', 'url': 'http://www.apache.org/licenses/LICENSE-2.0.html'},
    }

    rv = client.get('/openapi.json')
    assert rv.status_code == 200
    osv.validate(rv.json)
    assert rv.json['info']['description'] == app.config['INFO']['description']
    assert rv.json['info']['termsOfService'] == app.config['INFO']['termsOfService']
    assert rv.json['info']['contact'] == app.config['INFO']['contact']
    assert rv.json['info']['license'] == app.config['INFO']['license']


def test_overwrite_info(app, client):
    app.config['INFO'] = {
        'description': 'Not set',
        'termsOfService': 'Not set',
        'contact': {'name': 'Not set', 'url': 'Not set', 'email': 'Not set'},
        'license': {'name': 'Not set', 'url': 'Not set'},
    }

    app.config['DESCRIPTION'] = 'My API'
    app.config['CONTACT'] = {
        'name': 'API Support',
        'url': 'http://www.example.com/support',
        'email': 'support@example.com',
    }
    app.config['LICENSE'] = {
        'name': 'Apache 2.0',
        'url': 'http://www.apache.org/licenses/LICENSE-2.0.html',
    }
    app.config['TERMS_OF_SERVICE'] = 'http://example.com/terms/'

    rv = client.get('/openapi.json')
    assert rv.status_code == 200
    osv.validate(rv.json)
    assert rv.json['info']['description'] == app.config['DESCRIPTION']
    assert rv.json['info']['termsOfService'] == app.config['TERMS_OF_SERVICE']
    assert rv.json['info']['contact'] == app.config['CONTACT']
    assert rv.json['info']['license'] == app.config['LICENSE']


def test_security_schemes(app, client):
    app.config['SECURITY_SCHEMES'] = {
        'ApiKeyAuth': {'type': 'apiKey', 'in': 'header', 'name': 'X-API-Key'},
        'BasicAuth': {
            'type': 'http',
            'scheme': 'basic',
        },
    }

    rv = client.get('/openapi.json')
    assert rv.status_code == 200
    osv.validate(rv.json)
    assert len(rv.json['components']['securitySchemes']) == 2
    assert (
        rv.json['components']['securitySchemes']['ApiKeyAuth']
        == app.config['SECURITY_SCHEMES']['ApiKeyAuth']
    )
    assert (
        rv.json['components']['securitySchemes']['BasicAuth']
        == app.config['SECURITY_SCHEMES']['BasicAuth']
    )
