rookeries/tests/server/test_site_management.py

301 lines
10 KiB
Python
Raw Normal View History

"""
Functional tests for the managing sites.
:copyright: Copyright 2013-2017, Dorian Pula <dorian.pula@amber-penguin-software.ca>
:license: AGPL v3+
"""
import http
from unittest import mock
import pytest_bdd as bdd
import requests
from pytest_bdd import parsers
from tests import utils
bdd.scenarios('site_creation.feature')
bdd.scenarios('site_access.feature')
bdd.scenarios('site_modification.feature')
bdd.scenarios('site_deletion.feature')
@bdd.given(parsers.parse('I am an {user_role} user'))
@bdd.given(parsers.parse('I am a {user_role} user'))
def auth_token_headers(user_role, api_base_uri, db_engine):
user = utils.generate_test_user(role=user_role)
utils.save_test_user_in_db(db_engine, user)
token = requests.post(
url=f'{api_base_uri}/auth',
json={
'username': user.username,
'password': user.password,
}
).json()['access_token']
return {'Authorization': f'JWT {token}'}
@bdd.given(parsers.parse('I am a visitor'), target_fixture='auth_token_headers')
def no_auth_token_headers():
return {}
@bdd.given(parsers.parse('I try to create a site'), target_fixture='site_response')
def create_site_response(auth_token_headers, api_base_uri):
test_site = utils.generate_test_site()
site_creation_request = {
'name': test_site.site_name,
'base_url': test_site.base_url,
}
response = requests.post(
url=f'{api_base_uri}/api/sites/',
json=site_creation_request,
headers=auth_token_headers,
)
return utils.ResponseSampleBundle(response, test_site)
@bdd.given(parsers.parse('I try to create a site with the same site name'), target_fixture='site_response')
def recreate_existing_site_response(site_response, auth_token_headers, api_base_uri):
test_site = site_response.sample
site_creation_request = {
'name': test_site.site_name,
'base_url': test_site.base_url,
}
response = requests.post(
url=f'{api_base_uri}/api/sites/',
json=site_creation_request,
headers=auth_token_headers,
)
return utils.ResponseSampleBundle(response, test_site)
@bdd.given(parsers.parse('I try to create a site with a non-json request'), target_fixture='site_response')
def invalid_non_json_create_site_response(auth_token_headers, api_base_uri):
return requests.post(
url=f'{api_base_uri}/api/sites/',
data='',
headers=auth_token_headers,
)
@bdd.given(parsers.parse('I try to create a site with an empty request'), target_fixture='site_response')
def invalid_empty_create_site_response(auth_token_headers, api_base_uri):
return requests.post(
url=f'{api_base_uri}/api/sites/',
json={},
headers=auth_token_headers,
)
@bdd.given(parsers.parse('I try to modify the site with a non-json request'), target_fixture='site_response')
def invalid_non_json_modify_site_response(site_response, auth_token_headers, api_base_uri):
test_site = site_response.sample
return requests.put(
url=f'{api_base_uri}/api/sites/{test_site.site_name}',
data='',
headers=auth_token_headers,
)
@bdd.given(parsers.parse('I try to modify the site with an empty request'), target_fixture='site_response')
def invalid_empty_modify_site_response(site_response, auth_token_headers, api_base_uri):
test_site = site_response.sample
return requests.put(
url=f'{api_base_uri}/api/sites/{test_site.site_name}',
json={},
headers=auth_token_headers,
)
@bdd.given(parsers.parse('I get a {state} site'), target_fixture='site_response')
def get_site_request(state, auth_token_headers, api_base_uri, db_engine):
# TODO: Generate a test site by its state
test_site = utils.generate_test_site()
utils.save_test_site_in_db(db_engine, test_site)
response = requests.get(
url=f'{api_base_uri}/api/sites/{test_site.site_name}',
headers=auth_token_headers,
)
return utils.ResponseSampleBundle(response, test_site)
@bdd.given(parsers.parse('I get a site that does not exist'), target_fixture='site_response')
def get_non_existent_site_request(auth_token_headers, api_base_uri):
return requests.get(
url=f'{api_base_uri}/api/sites/this-does-not-exist',
headers=auth_token_headers,
)
@bdd.then(parsers.parse('I get a valid site'))
def assert_site_response(site_response, api_base_uri):
test_site = site_response.sample
actual_response = utils.extract_response(site_response)
assert actual_response.status_code == http.HTTPStatus.OK
expected_json = {
'name': test_site.site_name,
'base_url': test_site.base_url,
'urls': mock.ANY,
}
assert expected_json == actual_response.json()
assert f'{api_base_uri}/api/sites/{test_site.site_name}' == actual_response.json()['urls']['self']
@bdd.then(parsers.parse('I get a valid new site'))
def assert_new_site_response(site_response, api_base_uri):
test_site = site_response.sample
actual_response = utils.extract_response(site_response)
assert actual_response.status_code == http.HTTPStatus.CREATED
expected_json = {
'name': test_site.site_name,
'base_url': test_site.base_url,
'urls': mock.ANY,
}
assert expected_json == actual_response.json()
assert f'{api_base_uri}/api/sites/{test_site.site_name}' == actual_response.json()['urls']['self']
@bdd.given(parsers.parse('I try to delete the site'), target_fixture='site_response')
def delete_site_response(site_response, auth_token_headers, api_base_uri):
test_site = site_response.sample
response = requests.delete(
url=f'{api_base_uri}/api/sites/{test_site.site_name}',
headers=auth_token_headers,
)
return utils.ResponseSampleBundle(response, test_site)
@bdd.given(parsers.parse('I try to delete the deleted site again'), target_fixture='site_response')
def delete_deleted_site_response(site_response, auth_token_headers, api_base_uri):
return delete_site_response(site_response, auth_token_headers, api_base_uri)
@bdd.given(parsers.parse('I try to modify the site'), target_fixture='site_response')
def modify_site_response(site_response, auth_token_headers, api_base_uri):
test_site = site_response.sample
modified_base_url = f'{test_site.base_url}/new_'
modified_site = utils.generate_test_site(test_site.site_name, modified_base_url)
site_modification_request = {
'name': test_site.site_name,
'base_url': modified_base_url,
}
response = requests.put(
url=f'{api_base_uri}/api/sites/{test_site.site_name}',
json=site_modification_request,
headers=auth_token_headers,
)
return utils.ResponseSampleBundle(response, modified_site)
@bdd.given(parsers.parse('I try to modify a site that does not exist'), target_fixture='site_response')
def modify_non_existent_site_request(auth_token_headers, api_base_uri):
test_site = utils.generate_test_site()
site_modification_request = {
'name': 'this-does-not-exist',
'base_url': test_site.base_url,
}
return requests.put(
url=f'{api_base_uri}/api/sites/this-does-not-exist',
json=site_modification_request,
headers=auth_token_headers,
)
@bdd.then(parsers.parse('my updates are reflected in the site'))
def assert_updated_site_response(site_response, api_base_uri):
test_site = site_response.sample
actual_response = utils.extract_response(site_response)
assert actual_response.status_code == http.HTTPStatus.OK
expected_json = {
'name': test_site.site_name,
'base_url': test_site.base_url,
'urls': mock.ANY,
}
assert expected_json == actual_response.json()
assert f'{api_base_uri}/api/sites/{test_site.site_name}' == actual_response.json()['urls']['self']
@bdd.then(parsers.parse('I get a site can not be found message'))
def assert_resource_not_found_response(site_response):
actual_response = utils.extract_response(site_response)
expected_response_json = {
'error': {
'status_code': http.HTTPStatus.NOT_FOUND.value,
'message': 'Resource not found.',
'resource': actual_response.request.url,
},
}
assert actual_response.status_code == http.HTTPStatus.NOT_FOUND
assert actual_response.json() == expected_response_json
@bdd.then(parsers.parse('I get an unauthorized response'))
def assert_unauthorized_response(site_response):
actual_response = utils.extract_response(site_response)
expected_response_json = {
'error': {
'status_code': http.HTTPStatus.UNAUTHORIZED.value,
'message': 'Not authorized to access this resource.',
'resource': actual_response.request.url,
}
}
assert actual_response.status_code == http.HTTPStatus.UNAUTHORIZED
assert actual_response.json() == expected_response_json
@bdd.then(parsers.parse('I get a conflict response about an existing site'))
def assert_conflicting_resource_found_response(site_response):
actual_response = utils.extract_response(site_response)
expected_response_json = {
'error': {
'status_code': http.HTTPStatus.CONFLICT.value,
'message': 'Existing resource already found. PUT to the resource to update it.',
'resource': actual_response.request.url,
},
}
assert actual_response.status_code == http.HTTPStatus.CONFLICT
assert actual_response.json() == expected_response_json
@bdd.then(parsers.parse('I get a bad request response'))
def assert_bad_request_response(site_response):
actual_response = utils.extract_response(site_response)
expected_response_json = {
'error': {
'status_code': http.HTTPStatus.BAD_REQUEST.value,
'message': mock.ANY,
}
}
assert actual_response.json() == expected_response_json
assert actual_response.status_code == http.HTTPStatus.BAD_REQUEST
@bdd.then(parsers.parse('I get a response indicating the deletion was successful'))
def assert_resource_deleted_response(site_response):
actual_response = utils.extract_response(site_response)
assert actual_response.status_code == http.HTTPStatus.NO_CONTENT
assert not actual_response.content
assert len(actual_response.content) == 0