Update tests fix

Fix migration init_db 'id'
Handle app context when needed
Fix conftest fixtures
Rearrange test Dockerfiles
Hide DeprecationWarning during pytest execution
Upgrade all python packages
This commit is contained in:
Ymage 2022-12-22 22:47:02 +01:00
parent 8d849ee2a1
commit 8dd03a4d85
14 changed files with 537 additions and 484 deletions

View File

@ -1,11 +1,11 @@
version: "2.1" version: "3.8"
services: services:
powerdns-admin: powerdns-admin:
image: powerdns-admin-test
build: build:
context: . context: .
dockerfile: docker-test/Dockerfile dockerfile: docker-test/Dockerfile
image: powerdns-admin-test
container_name: powerdns-admin-test container_name: powerdns-admin-test
ports: ports:
- "9191:80" - "9191:80"
@ -17,10 +17,10 @@ services:
- pdns-server - pdns-server
pdns-server: pdns-server:
image: pdns-server-test
build: build:
context: . context: .
dockerfile: docker-test/Dockerfile.pdns dockerfile: docker-test/Dockerfile.pdns
image: pdns-server-test
ports: ports:
- "5053:53" - "5053:53"
- "5053:53/udp" - "5053:53/udp"

View File

@ -1,15 +1,35 @@
FROM debian:stable-slim FROM debian:bullseye-slim
LABEL maintainer="k@ndk.name" LABEL maintainer="k@ndk.name"
ENV LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8
RUN apt-get update -y \ RUN apt-get update -y \
&& apt-get install -y --no-install-recommends apt-transport-https locales locales-all python3-pip python3-setuptools python3-dev curl libsasl2-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev libxmlsec1-openssl pkg-config build-essential libmariadb-dev-compat \ && apt-get install -y --no-install-recommends \
apt-transport-https \
curl \
build-essential \
libffi-dev \
libldap2-dev \
libmariadb-dev-compat \
libsasl2-dev \
libssl-dev \
libxml2-dev \
libxmlsec1-dev \
libxmlsec1-openssl \
libxslt1-dev \
locales \
locales-all \
pkg-config \
python3-dev \
python3-pip \
python3-setuptools \
&& curl -sL https://deb.nodesource.com/setup_lts.x | bash - \ && curl -sL https://deb.nodesource.com/setup_lts.x | bash - \
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& apt-get update -y \ && apt-get update -y \
&& apt-get install -y nodejs yarn \ && apt-get install -y --no-install-recommends \
nodejs \
yarn \
&& apt-get clean -y \ && apt-get clean -y \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
@ -21,8 +41,6 @@ RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt RUN pip3 install -r requirements.txt
COPY . /app COPY . /app
COPY ./docker/entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENV FLASK_APP=powerdnsadmin/__init__.py ENV FLASK_APP=powerdnsadmin/__init__.py
RUN yarn install --pure-lockfile --production \ RUN yarn install --pure-lockfile --production \
@ -31,4 +49,4 @@ RUN yarn install --pure-lockfile --production \
COPY ./docker-test/wait-for-pdns.sh /opt COPY ./docker-test/wait-for-pdns.sh /opt
RUN chmod u+x /opt/wait-for-pdns.sh RUN chmod u+x /opt/wait-for-pdns.sh
CMD ["/opt/wait-for-pdns.sh", "/usr/local/bin/pytest","--capture=no","-vv"] CMD ["/opt/wait-for-pdns.sh", "/usr/local/bin/pytest", "-W", "ignore::DeprecationWarning", "--capture=no", "-vv"]

View File

@ -10,9 +10,9 @@ fi
# Import schema structure # Import schema structure
if [ -e "/data/pdns.sql" ]; then if [ -e "/data/pdns.sql" ]; then
rm /data/pdns.db rm -f /data/pdns.db
cat /data/pdns.sql | sqlite3 /data/pdns.db cat /data/pdns.sql | sqlite3 /data/pdns.db
rm /data/pdns.sql rm -f /data/pdns.sql
echo "Imported schema structure" echo "Imported schema structure"
fi fi

View File

@ -1,8 +1,13 @@
from __future__ import with_statement from __future__ import with_statement
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig
import logging import logging
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from flask import current_app
from alembic import context
# this is the Alembic Config object, which provides # this is the Alembic Config object, which provides
# access to the values within the .ini file in use. # access to the values within the .ini file in use.
@ -17,9 +22,9 @@ logger = logging.getLogger('alembic.env')
# for 'autogenerate' support # for 'autogenerate' support
# from myapp import mymodel # from myapp import mymodel
# target_metadata = mymodel.Base.metadata # target_metadata = mymodel.Base.metadata
from flask import current_app config.set_main_option(
config.set_main_option('sqlalchemy.url', 'sqlalchemy.url',
current_app.config.get('SQLALCHEMY_DATABASE_URI').replace("%","%%")) str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%'))
target_metadata = current_app.extensions['migrate'].db.metadata target_metadata = current_app.extensions['migrate'].db.metadata
# other values from the config, defined by the needs of env.py, # other values from the config, defined by the needs of env.py,
@ -41,7 +46,9 @@ def run_migrations_offline():
""" """
url = config.get_main_option("sqlalchemy.url") url = config.get_main_option("sqlalchemy.url")
context.configure(url=url) context.configure(
url=url, target_metadata=target_metadata, literal_binds=True
)
with context.begin_transaction(): with context.begin_transaction():
context.run_migrations() context.run_migrations()
@ -65,22 +72,23 @@ def run_migrations_online():
directives[:] = [] directives[:] = []
logger.info('No changes in schema detected.') logger.info('No changes in schema detected.')
engine = engine_from_config(config.get_section(config.config_ini_section), connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.', prefix='sqlalchemy.',
poolclass=pool.NullPool) poolclass=pool.NullPool,
)
connection = engine.connect() with connectable.connect() as connection:
context.configure(connection=connection, context.configure(
connection=connection,
target_metadata=target_metadata, target_metadata=target_metadata,
process_revision_directives=process_revision_directives, process_revision_directives=process_revision_directives,
render_as_batch=config.get_main_option('sqlalchemy.url').startswith('sqlite:'), **current_app.extensions['migrate'].configure_args
**current_app.extensions['migrate'].configure_args) )
try:
with context.begin_transaction(): with context.begin_transaction():
context.run_migrations() context.run_migrations()
finally:
connection.close()
if context.is_offline_mode(): if context.is_offline_mode():
run_migrations_offline() run_migrations_offline()

View File

@ -56,9 +56,9 @@ def seed_data():
op.bulk_insert(template_table, op.bulk_insert(template_table,
[ [
{id: 1, 'name': 'basic_template_1', 'description': 'Basic Template #1'}, {'id': 1, 'name': 'basic_template_1', 'description': 'Basic Template #1'},
{id: 2, 'name': 'basic_template_2', 'description': 'Basic Template #2'}, {'id': 2, 'name': 'basic_template_2', 'description': 'Basic Template #2'},
{id: 3, 'name': 'basic_template_3', 'description': 'Basic Template #3'} {'id': 3, 'name': 'basic_template_3', 'description': 'Basic Template #3'}
] ]
) )

View File

@ -1,34 +1,41 @@
Flask==1.1.2 mysqlclient==2.1.1
Flask-Assets==2.0
Flask-Login==0.5.0
Flask-SQLAlchemy==2.4.4
Flask-Migrate==2.5.3
SQLAlchemy==1.3.19
mysqlclient==2.0.1
configobj==5.0.6 configobj==5.0.6
bcrypt>=3.1.7 bcrypt==4.0.1
requests==2.24.0 requests==2.28.1
python-ldap==3.4.2 python-ldap==3.4.3
pyotp==2.4.0 pyotp==2.8.0
qrcode==6.1 qrcode==7.3.1
dnspython>=1.16.0 dnspython>=1.16.0
gunicorn==20.0.4 gunicorn==20.1.0
python3-saml python3-saml==1.14.0
pytz==2020.1 pytz==2022.7
cssmin==0.2.0 cssmin==0.2.0
rjsmin==1.2.0 rjsmin==1.2.1
Authlib==0.15 Authlib==1.2.0
Flask-SeaSurf==1.1.1 Flask-SeaSurf==1.1.1
bravado-core==5.17.0 bravado-core==5.17.1
jsonschema[format]>=2.5.1,<4.0.0 # until https://github.com/Yelp/bravado-core/pull/385 jsonschema[format]>=2.5.1,<4.0.0 # until https://github.com/Yelp/bravado-core/pull/385
lima==0.5 lima==0.5
pytest==6.2.5
pytimeparse==1.1.8 pytimeparse==1.1.8
PyYAML==5.4 alembic==1.9.0
Flask-SSLify==0.1.5 certifi==2022.12.7
cffi==1.15.1
passlib==1.7.4
pyasn1==0.4.8
webcolors==1.12
zipp==3.11.0
Flask==2.2.2
Flask-Assets==2.0
Flask-Login==0.6.2
Flask-SQLAlchemy==3.0.2
Flask-Migrate==4.0.0
SQLAlchemy==1.4.45
pyOpenSSL==22.1.0
Authlib==1.2.0
Flask-SeaSurf==1.1.1
PyYAML==6.0
Flask-Mail==0.9.1 Flask-Mail==0.9.1
flask-session==0.3.2 Flask-SSLify==0.1.5
Jinja2==3.0.3 Flask-Session==0.4.0
itsdangerous==2.0.1 lxml==4.6.5
werkzeug==2.0.3 pytest==7.2.0
cryptography==36.0.2

View File

@ -1,26 +1,28 @@
import os import os
import pytest
import flask_migrate
from base64 import b64encode from base64 import b64encode
from powerdnsadmin import create_app import pytest
from powerdnsadmin.models.base import db from flask_migrate import upgrade as flask_migrate_upgrade
from powerdnsadmin.models.user import User
from powerdnsadmin.models.setting import Setting
from powerdnsadmin.models.api_key import ApiKey
from powerdnsadmin import create_app
from powerdnsadmin.models.api_key import ApiKey
from powerdnsadmin.models.base import db
from powerdnsadmin.models.setting import Setting
from powerdnsadmin.models.user import User
@pytest.fixture(scope="session")
def app():
app = create_app('../configs/test.py') app = create_app('../configs/test.py')
ctx = app.app_context() yield app
ctx.push()
@pytest.fixture @pytest.fixture
def client(): def client(app):
app.config['TESTING'] = True app.config['TESTING'] = True
client = app.test_client() client = app.test_client()
yield client yield client
def load_data(setting_name, *args, **kwargs): def load_data(setting_name, *args, **kwargs):
if setting_name == 'maintenance': if setting_name == 'maintenance':
return 0 return 0
@ -41,17 +43,17 @@ def load_data(setting_name, *args, **kwargs):
@pytest.fixture @pytest.fixture
def test_admin_user(): def test_admin_user(app):
return app.config.get('TEST_ADMIN_USER') return app.config.get('TEST_ADMIN_USER')
@pytest.fixture @pytest.fixture
def test_user(): def test_user(app):
return app.config.get('TEST_USER') return app.config.get('TEST_USER')
@pytest.fixture @pytest.fixture
def basic_auth_admin_headers(): def basic_auth_admin_headers(app):
test_admin_user = app.config.get('TEST_ADMIN_USER') test_admin_user = app.config.get('TEST_ADMIN_USER')
test_admin_pass = app.config.get('TEST_ADMIN_PASSWORD') test_admin_pass = app.config.get('TEST_ADMIN_PASSWORD')
user_pass = "{0}:{1}".format(test_admin_user, test_admin_pass) user_pass = "{0}:{1}".format(test_admin_user, test_admin_pass)
@ -63,7 +65,7 @@ def basic_auth_admin_headers():
@pytest.fixture @pytest.fixture
def basic_auth_user_headers(): def basic_auth_user_headers(app):
test_user = app.config.get('TEST_USER') test_user = app.config.get('TEST_USER')
test_user_pass = app.config.get('TEST_USER_PASSWORD') test_user_pass = app.config.get('TEST_USER_PASSWORD')
user_pass = "{0}:{1}".format(test_user, test_user_pass) user_pass = "{0}:{1}".format(test_user, test_user_pass)
@ -75,7 +77,8 @@ def basic_auth_user_headers():
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def initial_data(): def initial_data(app):
pdns_proto = os.environ['PDNS_PROTO'] pdns_proto = os.environ['PDNS_PROTO']
pdns_host = os.environ['PDNS_HOST'] pdns_host = os.environ['PDNS_HOST']
pdns_port = os.environ['PDNS_PORT'] pdns_port = os.environ['PDNS_PORT']
@ -85,9 +88,9 @@ def initial_data():
api_key_setting = Setting('pdns_api_key', os.environ['PDNS_API_KEY']) api_key_setting = Setting('pdns_api_key', os.environ['PDNS_API_KEY'])
allow_create_domain_setting = Setting('allow_user_create_domain', True) allow_create_domain_setting = Setting('allow_user_create_domain', True)
with app.app_context():
try: try:
flask_migrate.upgrade() flask_migrate_upgrade(directory="migrations")
db.session.add(api_url_setting) db.session.add(api_url_setting)
db.session.add(api_key_setting) db.session.add(api_key_setting)
db.session.add(allow_create_domain_setting) db.session.add(allow_create_domain_setting)
@ -100,31 +103,29 @@ def initial_data():
admin_user = User(username=test_admin_user, admin_user = User(username=test_admin_user,
plain_text_password=test_admin_pass, plain_text_password=test_admin_pass,
email="admin@admin.com") email="admin@admin.com")
msg = admin_user.create_local_user() ret = admin_user.create_local_user()
if not msg: if not ret['status']:
raise Exception("Error occurred creating user {0}".format(msg)) raise Exception("Error occurred creating user {0}".format(ret['msg']))
ordinary_user = User(username=test_user, ordinary_user = User(username=test_user,
plain_text_password=test_user_pass, plain_text_password=test_user_pass,
email="test@test.com") email="test@test.com")
msg = ordinary_user.create_local_user() ret = ordinary_user.create_local_user()
if not msg: if not ret['status']:
raise Exception("Error occurred creating user {0}".format(msg)) raise Exception("Error occurred creating user {0}".format(ret['msg']))
except Exception as e: except Exception as e:
print("Unexpected ERROR: {0}".format(e)) print("Unexpected ERROR: {0}".format(e))
raise e raise e
yield yield
db.session.close()
os.unlink(app.config['TEST_DB_LOCATION']) os.unlink(app.config['TEST_DB_LOCATION'])
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def initial_apikey_data(): def initial_apikey_data(app):
pdns_proto = os.environ['PDNS_PROTO'] pdns_proto = os.environ['PDNS_PROTO']
pdns_host = os.environ['PDNS_HOST'] pdns_host = os.environ['PDNS_HOST']
pdns_port = os.environ['PDNS_PORT'] pdns_port = os.environ['PDNS_PORT']
@ -135,9 +136,9 @@ def initial_apikey_data():
allow_create_domain_setting = Setting('allow_user_create_domain', True) allow_create_domain_setting = Setting('allow_user_create_domain', True)
allow_remove_domain_setting = Setting('allow_user_remove_domain', True) allow_remove_domain_setting = Setting('allow_user_remove_domain', True)
with app.app_context():
try: try:
flask_migrate.upgrade() flask_migrate_upgrade(directory="migrations")
db.session.add(api_url_setting) db.session.add(api_url_setting)
db.session.add(api_key_setting) db.session.add(api_key_setting)
db.session.add(allow_create_domain_setting) db.session.add(allow_create_domain_setting)
@ -169,8 +170,6 @@ def initial_apikey_data():
raise e raise e
yield yield
db.session.close()
os.unlink(app.config['TEST_DB_LOCATION']) os.unlink(app.config['TEST_DB_LOCATION'])
@ -187,61 +186,51 @@ def zone_data():
@pytest.fixture @pytest.fixture
def created_zone_data(): def created_zone_data():
data = { data = {
'url': 'url': '/api/v1/servers/localhost/zones/example.org.',
'/api/v1/servers/localhost/zones/example.org.', 'soa_edit_api': 'DEFAULT',
'soa_edit_api': 'last_check': 0,
'DEFAULT',
'last_check':
0,
'masters': [], 'masters': [],
'dnssec': 'dnssec': False,
False, 'notified_serial': 0,
'notified_serial': 'nsec3narrow': False,
0, 'serial': 2019013101,
'nsec3narrow': 'nsec3param': '',
False, 'soa_edit': '',
'serial': 'api_rectify': False,
2019013101, 'kind': 'Native',
'nsec3param':
'',
'soa_edit':
'',
'api_rectify':
False,
'kind':
'Native',
'rrsets': [{ 'rrsets': [{
'comments': [], 'comments': [],
'type': 'type': 'SOA',
'SOA', 'name': 'example.org.',
'name': 'ttl': 3600,
'example.org.',
'ttl':
3600,
'records': [{ 'records': [{
'content': 'content': 'a.misconfigured.powerdns.server. hostmaster.example.org. 2019013101 10800 3600 604800 3600',
'a.misconfigured.powerdns.server. hostmaster.example.org. 2019013101 10800 3600 604800 3600',
'disabled': False 'disabled': False
}] }]
}, { }, {
'comments': [], 'comments': [],
'type': 'type': 'NS',
'NS', 'name': 'example.org.',
'name': 'ttl': 3600,
'example.org.',
'ttl':
3600,
'records': [{ 'records': [{
'content': 'ns1.example.org.', 'content': 'ns1.example.org.',
'disabled': False 'disabled': False
}] }]
}], }],
'name': 'name': 'example.org.',
'example.org.', 'account': '',
'account': 'id': 'example.org.'
'', }
'id': return data
'example.org.'
def user_data(app):
test_user = app.config.get('TEST_USER')
test_user_pass = app.config.get('TEST_USER_PASSWORD')
data = {
"username": test_user,
"plain_text_password": test_user_pass,
"email": "test@test.com"
} }
return data return data
@ -261,21 +250,22 @@ def admin_apikey_data():
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def user_apikey_integration(): def user_apikey_integration(app):
test_user_apikey = app.config.get('TEST_USER_APIKEY') test_user_apikey = app.config.get('TEST_USER_APIKEY')
headers = create_apikey_headers(test_user_apikey) headers = create_apikey_headers(test_user_apikey)
return headers return headers
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def admin_apikey_integration(): def admin_apikey_integration(app):
test_user_apikey = app.config.get('TEST_ADMIN_APIKEY') test_user_apikey = app.config.get('TEST_ADMIN_APIKEY')
headers = create_apikey_headers(test_user_apikey) headers = create_apikey_headers(test_user_apikey)
return headers return headers
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def user_apikey(): def user_apikey(app):
with app.app_context():
data = user_apikey_data() data = user_apikey_data()
api_key = ApiKey(desc=data['description'], api_key = ApiKey(desc=data['description'],
role_name=data['role'], role_name=data['role'],
@ -285,7 +275,8 @@ def user_apikey():
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def admin_apikey(): def admin_apikey(app):
with app.app_context():
data = admin_apikey_data() data = admin_apikey_data()
api_key = ApiKey(desc=data['description'], api_key = ApiKey(desc=data['description'],
role_name=data['role'], role_name=data['role'],

View File

@ -8,7 +8,7 @@ from tests.conftest import user_apikey_data, admin_apikey_data
class TestIntegrationApiApiKeyAdminUser(object): class TestIntegrationApiApiKeyAdminUser(object):
def test_empty_get(self, client, initial_data, basic_auth_admin_headers): def test_empty_get(self, initial_data, client, basic_auth_admin_headers):
res = client.get("/api/v1/pdnsadmin/apikeys", res = client.get("/api/v1/pdnsadmin/apikeys",
headers=basic_auth_admin_headers) headers=basic_auth_admin_headers)
data = res.get_json(force=True) data = res.get_json(force=True)
@ -18,7 +18,7 @@ class TestIntegrationApiApiKeyAdminUser(object):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"apikey_data", "apikey_data",
[user_apikey_data(), admin_apikey_data()]) [user_apikey_data(), admin_apikey_data()])
def test_create_apikey(self, client, initial_data, apikey_data, zone_data, def test_create_apikey(self, initial_data, client, apikey_data, zone_data,
basic_auth_admin_headers): basic_auth_admin_headers):
res = client.post("/api/v1/pdnsadmin/zones", res = client.post("/api/v1/pdnsadmin/zones",
headers=basic_auth_admin_headers, headers=basic_auth_admin_headers,
@ -53,7 +53,7 @@ class TestIntegrationApiApiKeyAdminUser(object):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"apikey_data", "apikey_data",
[user_apikey_data(), admin_apikey_data()]) [user_apikey_data(), admin_apikey_data()])
def test_get_multiple_apikey(self, client, initial_data, apikey_data, def test_get_multiple_apikey(self, initial_data, client, apikey_data,
zone_data, basic_auth_admin_headers): zone_data, basic_auth_admin_headers):
res = client.post("/api/v1/pdnsadmin/zones", res = client.post("/api/v1/pdnsadmin/zones",
headers=basic_auth_admin_headers, headers=basic_auth_admin_headers,
@ -102,7 +102,7 @@ class TestIntegrationApiApiKeyAdminUser(object):
@pytest.mark.parametrize( @pytest.mark.parametrize(
"apikey_data", "apikey_data",
[user_apikey_data(), admin_apikey_data()]) [user_apikey_data(), admin_apikey_data()])
def test_delete_apikey(self, client, initial_data, apikey_data, zone_data, def test_delete_apikey(self, initial_data, client, apikey_data, zone_data,
basic_auth_admin_headers): basic_auth_admin_headers):
res = client.post("/api/v1/pdnsadmin/zones", res = client.post("/api/v1/pdnsadmin/zones",
headers=basic_auth_admin_headers, headers=basic_auth_admin_headers,

View File

@ -5,7 +5,7 @@ from powerdnsadmin.lib.validators import validate_zone
from powerdnsadmin.lib.schema import DomainSchema from powerdnsadmin.lib.schema import DomainSchema
class TestIntegrationApiZoneUser(object): class TestIntegrationApiApiKeyUser(object):
def test_empty_get(self, initial_data, client, basic_auth_user_headers): def test_empty_get(self, initial_data, client, basic_auth_user_headers):
res = client.get("/api/v1/pdnsadmin/zones", res = client.get("/api/v1/pdnsadmin/zones",
headers=basic_auth_user_headers) headers=basic_auth_user_headers)

View File

@ -1,4 +1,3 @@
import json import json
from . import IntegrationApiManagement from . import IntegrationApiManagement
@ -6,58 +5,58 @@ from . import IntegrationApiManagement
class TestIntegrationApiManagementUser(IntegrationApiManagement): class TestIntegrationApiManagementUser(IntegrationApiManagement):
def test_accounts_empty_get( def test_accounts_empty_get(self, initial_data, client, # noqa: F811
self, client, initial_data, # noqa: F811
basic_auth_user_headers): # noqa: F811 basic_auth_user_headers): # noqa: F811
res = client.get("/api/v1/pdnsadmin/accounts", res = client.get("/api/v1/pdnsadmin/accounts",
headers=basic_auth_user_headers) headers=basic_auth_user_headers)
assert res.status_code == 401 assert res.status_code == 401
def test_users_empty_get( def test_users_empty_get(self, initial_data, client, # noqa: F811
self, client, initial_data, # noqa: F811
test_admin_user, test_user, # noqa: F811 test_admin_user, test_user, # noqa: F811
basic_auth_user_headers): # noqa: F811 basic_auth_user_headers): # noqa: F811
res = client.get("/api/v1/pdnsadmin/users", res = client.get("/api/v1/pdnsadmin/users",
headers=basic_auth_user_headers) headers=basic_auth_user_headers)
assert res.status_code == 401 assert res.status_code == 401
def test_self_get( def test_self_get(self, initial_data, client, basic_auth_user_headers, test_user): # noqa: F811
self, initial_data, client, test_user, # noqa: F811
basic_auth_user_headers): # noqa: F811
self.user = None
res = client.get("/api/v1/pdnsadmin/users/{}".format(test_user), res = client.get("/api/v1/pdnsadmin/users/{}".format(test_user),
headers=basic_auth_user_headers) headers=basic_auth_user_headers)
data = res.get_json(force=True) data = res.get_json(force=True)
assert res.status_code == 200 assert res.status_code == 200
assert data assert data
self.user = [data]
def test_accounts( def test_create_account_fail(self, client, initial_data, account_data, # noqa: F811
self, client, initial_data, # noqa: F811 basic_auth_user_headers): # noqa: F811
account_data, # noqa: F811
basic_auth_admin_headers, basic_auth_user_headers): # noqa: F811 # Create account (should fail)
res = client.post("/api/v1/pdnsadmin/accounts",
headers=basic_auth_user_headers,
data=json.dumps(account_data),
content_type="application/json")
assert res.status_code == 401
def test_create_account_as_admin(self, app, initial_data, client, account_data, # noqa: F811
basic_auth_admin_headers): # noqa: F811
self.client = client self.client = client
self.basic_auth_admin_headers = basic_auth_admin_headers self.basic_auth_admin_headers = basic_auth_admin_headers
# Create account (should fail) with app.test_request_context():
res = client.post(
"/api/v1/pdnsadmin/accounts",
headers=basic_auth_user_headers,
data=json.dumps(account_data),
content_type="application/json",
)
assert res.status_code == 401
# Create account (as admin) # Create account (as admin)
res = client.post( res = client.post("/api/v1/pdnsadmin/accounts",
"/api/v1/pdnsadmin/accounts",
headers=basic_auth_admin_headers, headers=basic_auth_admin_headers,
data=json.dumps(account_data), data=json.dumps(account_data),
content_type="application/json", content_type="application/json")
)
data = res.get_json(force=True) data = res.get_json(force=True)
assert res.status_code == 201 assert res.status_code == 201
def test_update_account_fail(
self, initial_data, client, # noqa: F811
account_data, # noqa: F811
basic_auth_user_headers,
basic_auth_admin_headers): # noqa: F811
self.client = client
self.basic_auth_admin_headers = basic_auth_admin_headers
# Check account # Check account
data = self.check_account(account_data) data = self.check_account(account_data)
account_id = data["id"] account_id = data["id"]
@ -71,6 +70,18 @@ class TestIntegrationApiManagementUser(IntegrationApiManagement):
) )
assert res.status_code == 401 assert res.status_code == 401
def test_delete_account_fail(
self, initial_data, client, # noqa: F811
account_data, # noqa: F811
basic_auth_user_headers,
basic_auth_admin_headers): # noqa: F811
self.client = client
self.basic_auth_admin_headers = basic_auth_admin_headers
# Check account
data = self.check_account(account_data)
account_id = data["id"]
# Delete account (should fail) # Delete account (should fail)
res = client.delete( res = client.delete(
"/api/v1/pdnsadmin/accounts/{}".format(account_id), "/api/v1/pdnsadmin/accounts/{}".format(account_id),
@ -80,6 +91,17 @@ class TestIntegrationApiManagementUser(IntegrationApiManagement):
) )
assert res.status_code == 401 assert res.status_code == 401
def test_delete_account_as_admin(
self, client, initial_data, # noqa: F811
account_data, # noqa: F811
basic_auth_admin_headers): # noqa: F811
self.client = client
self.basic_auth_admin_headers = basic_auth_admin_headers
# Check account
data = self.check_account(account_data)
account_id = data["id"]
# Cleanup (delete account as admin) # Cleanup (delete account as admin)
res = client.delete( res = client.delete(
"/api/v1/pdnsadmin/accounts/{}".format(account_id), "/api/v1/pdnsadmin/accounts/{}".format(account_id),

View File

@ -15,7 +15,8 @@ from tests.conftest import admin_apikey_data, load_data
class TestUnitApiZoneAdminApiKey(object): class TestUnitApiZoneAdminApiKey(object):
@pytest.fixture @pytest.fixture
def common_data_mock(self): def common_data_mock(self, app):
with app.app_context():
self.google_setting_patcher = patch( self.google_setting_patcher = patch(
'powerdnsadmin.services.google.Setting', 'powerdnsadmin.services.google.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)

View File

@ -13,7 +13,8 @@ from tests.conftest import load_data
class TestUnitApiZoneAdminUser(object): class TestUnitApiZoneAdminUser(object):
@pytest.fixture @pytest.fixture
def common_data_mock(self): def common_data_mock(self, app, initial_data):
self.google_setting_patcher = patch( self.google_setting_patcher = patch(
'powerdnsadmin.services.google.Setting', 'powerdnsadmin.services.google.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
@ -26,17 +27,11 @@ class TestUnitApiZoneAdminUser(object):
self.oidc_setting_patcher = patch( self.oidc_setting_patcher = patch(
'powerdnsadmin.services.oidc.Setting', 'powerdnsadmin.services.oidc.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.api_setting_patcher = patch(
'powerdnsadmin.routes.api.Setting',
spec=powerdnsadmin.models.setting.Setting)
self.base_route_user_patcher = patch(
'powerdnsadmin.routes.base.User',
spec=powerdnsadmin.models.user.User)
self.helpers_setting_patcher = patch( self.helpers_setting_patcher = patch(
'powerdnsadmin.lib.helper.Setting', 'powerdnsadmin.lib.helper.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.models_setting_patcher = patch( self.models_setting_patcher = patch(
'powerdnsadmin.models.Setting', 'powerdnsadmin.models.setting.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.domain_model_setting_patcher = patch( self.domain_model_setting_patcher = patch(
'powerdnsadmin.models.domain.Setting', 'powerdnsadmin.models.domain.Setting',
@ -47,15 +42,23 @@ class TestUnitApiZoneAdminUser(object):
self.server_model_setting_patcher = patch( self.server_model_setting_patcher = patch(
'powerdnsadmin.models.server.Setting', 'powerdnsadmin.models.server.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.decorators_setting_patcher = patch( self.mock_user_patcher = patch(
'powerdnsadmin.decorators.Setting', 'powerdnsadmin.decorators.User',
spec=powerdnsadmin.models.setting.Setting)
self.mock_user_patcher = patch('powerdnsadmin.decorators.User',
spec=powerdnsadmin.models.user.User) spec=powerdnsadmin.models.user.User)
self.mock_hist_patcher = patch( self.mock_hist_patcher = patch(
'powerdnsadmin.routes.api.History', 'powerdnsadmin.routes.api.History',
spec=powerdnsadmin.models.history.History) spec=powerdnsadmin.models.history.History)
self.mock_setting_patcher = patch(
'powerdnsadmin.routes.api.Setting',
spec=powerdnsadmin.models.setting.Setting)
self.mock_decorators_setting_patcher = patch(
'powerdnsadmin.decorators.Setting',
spec=powerdnsadmin.models.setting.Setting)
self.base_route_user_patcher = patch(
'powerdnsadmin.routes.base.User',
spec=powerdnsadmin.models.user.User)
with app.app_context():
self.mock_google_setting = self.google_setting_patcher.start() self.mock_google_setting = self.google_setting_patcher.start()
self.mock_github_setting = self.github_setting_patcher.start() self.mock_github_setting = self.github_setting_patcher.start()
self.mock_azure_setting = self.azure_setting_patcher.start() self.mock_azure_setting = self.azure_setting_patcher.start()
@ -69,10 +72,10 @@ class TestUnitApiZoneAdminUser(object):
) )
self.mock_server_model_setting = self.server_model_setting_patcher.start( self.mock_server_model_setting = self.server_model_setting_patcher.start(
) )
self.decorators_setting = self.decorators_setting_patcher.start()
self.api_setting = self.api_setting_patcher.start()
self.mock_user = self.mock_user_patcher.start() self.mock_user = self.mock_user_patcher.start()
self.mock_hist = self.mock_hist_patcher.start() self.mock_hist = self.mock_hist_patcher.start()
self.mock_setting = self.mock_setting_patcher.start()
self.mock_decorators_setting = self.mock_decorators_setting_patcher.start()
self.mock_google_setting.return_value.get.side_effect = load_data self.mock_google_setting.return_value.get.side_effect = load_data
self.mock_github_setting.return_value.get.side_effect = load_data self.mock_github_setting.return_value.get.side_effect = load_data
@ -83,8 +86,8 @@ class TestUnitApiZoneAdminUser(object):
self.mock_domain_model_setting.return_value.get.side_effect = load_data self.mock_domain_model_setting.return_value.get.side_effect = load_data
self.mock_record_model_setting.return_value.get.side_effect = load_data self.mock_record_model_setting.return_value.get.side_effect = load_data
self.mock_server_model_setting.return_value.get.side_effect = load_data self.mock_server_model_setting.return_value.get.side_effect = load_data
self.decorators_setting.return_value.get.side_effect = load_data self.mock_decorators_setting.return_value.get.side_effect = load_data
self.api_setting.return_value.get.side_effect = load_data self.mock_setting.return_value.get.side_effect = load_data
self.mockk = MagicMock() self.mockk = MagicMock()
self.mockk.role.name = "Administrator" self.mockk.role.name = "Administrator"
@ -107,10 +110,10 @@ class TestUnitApiZoneAdminUser(object):
self.domain_model_setting_patcher, self.domain_model_setting_patcher,
self.record_model_setting_patcher, self.record_model_setting_patcher,
self.server_model_setting_patcher, self.server_model_setting_patcher,
self.decorators_setting_patcher,
self.api_setting_patcher,
self.mock_user_patcher, self.mock_user_patcher,
self.mock_hist_patcher, self.mock_hist_patcher,
self.mock_setting_patcher,
self.mock_decorators_setting_patcher,
]: ]:
patcher.stop() patcher.stop()
@ -159,8 +162,7 @@ class TestUnitApiZoneAdminUser(object):
headers=basic_auth_admin_headers) headers=basic_auth_admin_headers)
data = res.get_json(force=True) data = res.get_json(force=True)
fake_domain = namedtuple("Domain", fake_domain = namedtuple("Domain", data[0].keys())(*data[0].values())
data[0].keys())(*data[0].values())
domain_schema = DomainSchema(many=True) domain_schema = DomainSchema(many=True)
json.dumps(domain_schema.dump([fake_domain])) json.dumps(domain_schema.dump([fake_domain]))

View File

@ -13,7 +13,8 @@ from tests.conftest import load_data
class TestUnitApiZoneUser(object): class TestUnitApiZoneUser(object):
@pytest.fixture @pytest.fixture
def common_data_mock(self): def common_data_mock(self, app, initial_data):
self.google_setting_patcher = patch( self.google_setting_patcher = patch(
'powerdnsadmin.services.google.Setting', 'powerdnsadmin.services.google.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
@ -26,17 +27,11 @@ class TestUnitApiZoneUser(object):
self.oidc_setting_patcher = patch( self.oidc_setting_patcher = patch(
'powerdnsadmin.services.oidc.Setting', 'powerdnsadmin.services.oidc.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.api_setting_patcher = patch(
'powerdnsadmin.routes.api.Setting',
spec=powerdnsadmin.models.setting.Setting)
self.base_route_user_patcher = patch(
'powerdnsadmin.routes.base.User',
spec=powerdnsadmin.models.user.User)
self.helpers_setting_patcher = patch( self.helpers_setting_patcher = patch(
'powerdnsadmin.lib.helper.Setting', 'powerdnsadmin.lib.helper.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.models_setting_patcher = patch( self.models_setting_patcher = patch(
'powerdnsadmin.models.Setting', 'powerdnsadmin.models.setting.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.domain_model_setting_patcher = patch( self.domain_model_setting_patcher = patch(
'powerdnsadmin.models.domain.Setting', 'powerdnsadmin.models.domain.Setting',
@ -47,15 +42,23 @@ class TestUnitApiZoneUser(object):
self.server_model_setting_patcher = patch( self.server_model_setting_patcher = patch(
'powerdnsadmin.models.server.Setting', 'powerdnsadmin.models.server.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
self.decorators_setting_patcher = patch( self.mock_user_patcher = patch(
'powerdnsadmin.decorators.Setting', 'powerdnsadmin.decorators.User',
spec=powerdnsadmin.models.setting.Setting)
self.mock_user_patcher = patch('powerdnsadmin.decorators.User',
spec=powerdnsadmin.models.user.User) spec=powerdnsadmin.models.user.User)
self.mock_hist_patcher = patch( self.mock_hist_patcher = patch(
'powerdnsadmin.routes.api.History', 'powerdnsadmin.routes.api.History',
spec=powerdnsadmin.models.history.History) spec=powerdnsadmin.models.history.History)
self.mock_setting_patcher = patch(
'powerdnsadmin.routes.api.Setting',
spec=powerdnsadmin.models.setting.Setting)
self.mock_decorators_setting_patcher = patch(
'powerdnsadmin.decorators.Setting',
spec=powerdnsadmin.models.setting.Setting)
self.base_route_user_patcher = patch(
'powerdnsadmin.routes.base.User',
spec=powerdnsadmin.models.user.User)
with app.app_context():
self.mock_google_setting = self.google_setting_patcher.start() self.mock_google_setting = self.google_setting_patcher.start()
self.mock_github_setting = self.github_setting_patcher.start() self.mock_github_setting = self.github_setting_patcher.start()
self.mock_azure_setting = self.azure_setting_patcher.start() self.mock_azure_setting = self.azure_setting_patcher.start()
@ -69,10 +72,10 @@ class TestUnitApiZoneUser(object):
) )
self.mock_server_model_setting = self.server_model_setting_patcher.start( self.mock_server_model_setting = self.server_model_setting_patcher.start(
) )
self.decorators_setting = self.decorators_setting_patcher.start()
self.api_setting = self.api_setting_patcher.start()
self.mock_user = self.mock_user_patcher.start() self.mock_user = self.mock_user_patcher.start()
self.mock_hist = self.mock_hist_patcher.start() self.mock_hist = self.mock_hist_patcher.start()
self.mock_setting = self.mock_setting_patcher.start()
self.mock_decorators_setting = self.mock_decorators_setting_patcher.start()
self.mock_google_setting.return_value.get.side_effect = load_data self.mock_google_setting.return_value.get.side_effect = load_data
self.mock_github_setting.return_value.get.side_effect = load_data self.mock_github_setting.return_value.get.side_effect = load_data
@ -83,8 +86,8 @@ class TestUnitApiZoneUser(object):
self.mock_domain_model_setting.return_value.get.side_effect = load_data self.mock_domain_model_setting.return_value.get.side_effect = load_data
self.mock_record_model_setting.return_value.get.side_effect = load_data self.mock_record_model_setting.return_value.get.side_effect = load_data
self.mock_server_model_setting.return_value.get.side_effect = load_data self.mock_server_model_setting.return_value.get.side_effect = load_data
self.decorators_setting.return_value.get.side_effect = load_data self.mock_decorators_setting.return_value.get.side_effect = load_data
self.api_setting.return_value.get.side_effect = load_data self.mock_setting.return_value.get.side_effect = load_data
self.mockk = MagicMock() self.mockk = MagicMock()
self.mockk.role.name = "User" self.mockk.role.name = "User"
@ -107,10 +110,10 @@ class TestUnitApiZoneUser(object):
self.domain_model_setting_patcher, self.domain_model_setting_patcher,
self.record_model_setting_patcher, self.record_model_setting_patcher,
self.server_model_setting_patcher, self.server_model_setting_patcher,
self.decorators_setting_patcher,
self.api_setting_patcher,
self.mock_user_patcher, self.mock_user_patcher,
self.mock_hist_patcher, self.mock_hist_patcher,
self.mock_setting_patcher,
self.mock_decorators_setting_patcher,
]: ]:
patcher.stop() patcher.stop()
@ -139,6 +142,7 @@ class TestUnitApiZoneUser(object):
with patch('powerdnsadmin.routes.api.get_user_domains') as mock_user_domains: with patch('powerdnsadmin.routes.api.get_user_domains') as mock_user_domains:
test_domain = Domain(1, name=zone_data['name'].rstrip(".")) test_domain = Domain(1, name=zone_data['name'].rstrip("."))
mock_user_domains.return_value = [test_domain] mock_user_domains.return_value = [test_domain]
res = client.get("/api/v1/pdnsadmin/zones", res = client.get("/api/v1/pdnsadmin/zones",
headers=basic_auth_user_headers) headers=basic_auth_user_headers)
data = res.get_json(force=True) data = res.get_json(force=True)
@ -151,7 +155,7 @@ class TestUnitApiZoneUser(object):
def test_delete_zone(self, client, common_data_mock, zone_data, def test_delete_zone(self, client, common_data_mock, zone_data,
basic_auth_user_headers): basic_auth_user_headers):
with patch('powerdnsadmin.lib.utils.requests.request') as mock_delete, \ with patch('powerdnsadmin.lib.helper.requests.request') as mock_delete, \
patch('powerdnsadmin.routes.api.Domain') as mock_domain, \ patch('powerdnsadmin.routes.api.Domain') as mock_domain, \
patch('powerdnsadmin.routes.api.get_user_domains') as mock_user_domains: patch('powerdnsadmin.routes.api.get_user_domains') as mock_user_domains:
test_domain = Domain(1, name=zone_data['name'].rstrip(".")) test_domain = Domain(1, name=zone_data['name'].rstrip("."))

View File

@ -15,7 +15,8 @@ from tests.conftest import user_apikey_data, load_data
class TestUnitApiZoneUserApiKey(object): class TestUnitApiZoneUserApiKey(object):
@pytest.fixture @pytest.fixture
def common_data_mock(self): def common_data_mock(self, app):
with app.app_context():
self.google_setting_patcher = patch( self.google_setting_patcher = patch(
'powerdnsadmin.services.google.Setting', 'powerdnsadmin.services.google.Setting',
spec=powerdnsadmin.models.setting.Setting) spec=powerdnsadmin.models.setting.Setting)
@ -143,8 +144,7 @@ class TestUnitApiZoneUserApiKey(object):
headers=user_apikey) headers=user_apikey)
data = res.get_json(force=True) data = res.get_json(force=True)
fake_domain = namedtuple("Domain", fake_domain = namedtuple("Domain", data[0].keys())(*data[0].values())
data[0].keys())(*data[0].values())
domain_schema = DomainSchema(many=True) domain_schema = DomainSchema(many=True)
json.dumps(domain_schema.dump([fake_domain])) json.dumps(domain_schema.dump([fake_domain]))