Crud operations for hierarchy levels implemented
Only name changing implemented under hierarchy_levels url. Whole hierarchy change should be performed throught environment update. Cascade deletion added to hierarchy levels on environment deletion. Order of hierarchy levels fixed for environments GET requests. Module levels_hierarchy was renamed to hierarchy_levels. Change-Id: I0642892b517357ebc95427617413048f4db6fba3
This commit is contained in:
parent
7f3faa3336
commit
f25a724ade
@ -19,6 +19,7 @@ from tuning_box import db
|
||||
from tuning_box import errors
|
||||
from tuning_box.library import components
|
||||
from tuning_box.library import environments
|
||||
from tuning_box.library import hierarchy_levels
|
||||
from tuning_box.library import resource_definitions
|
||||
from tuning_box.library import resource_overrides
|
||||
from tuning_box.library import resource_values
|
||||
@ -86,6 +87,17 @@ api.add_resource(
|
||||
'/environments/<int:environment_id>'
|
||||
)
|
||||
|
||||
# Hierarchy levels
|
||||
api.add_resource(
|
||||
hierarchy_levels.EnvironmentHierarchyLevelsCollection,
|
||||
'/environments/<int:environment_id>/hierarchy_levels'
|
||||
)
|
||||
api.add_resource(
|
||||
hierarchy_levels.EnvironmentHierarchyLevels,
|
||||
'/environments/<int:environment_id>/hierarchy_levels/'
|
||||
'<string:level>'
|
||||
)
|
||||
|
||||
|
||||
def handle_integrity_error(exc):
|
||||
response = flask.jsonify(msg=exc.args[0])
|
||||
|
@ -16,11 +16,14 @@ import re
|
||||
|
||||
import flask
|
||||
import flask_sqlalchemy
|
||||
import sqlalchemy
|
||||
import sqlalchemy.event
|
||||
import sqlalchemy.ext.declarative as sa_decl
|
||||
from sqlalchemy.orm import exc as orm_exc
|
||||
from sqlalchemy import types
|
||||
|
||||
from tuning_box import errors
|
||||
|
||||
try:
|
||||
from importlib import reload
|
||||
except ImportError:
|
||||
@ -152,8 +155,12 @@ class Environment(ModelMixin, db.Model):
|
||||
|
||||
|
||||
class EnvironmentHierarchyLevel(ModelMixin, db.Model):
|
||||
environment_id = fk(Environment)
|
||||
environment = db.relationship(Environment, backref='hierarchy_levels')
|
||||
environment_id = fk(Environment, ondelete='CASCADE')
|
||||
environment = db.relationship(
|
||||
Environment,
|
||||
backref=sqlalchemy.orm.backref('hierarchy_levels',
|
||||
cascade="all, delete-orphan")
|
||||
)
|
||||
name = db.Column(db.String(128))
|
||||
|
||||
@sa_decl.declared_attr
|
||||
@ -245,3 +252,21 @@ def prefix_tables(module, prefix):
|
||||
def unprefix_tables(module):
|
||||
ModelMixin.table_prefix = ""
|
||||
reload(module)
|
||||
|
||||
|
||||
def get_or_404(cls, ident):
|
||||
result = cls.query.get(ident)
|
||||
if result is None:
|
||||
raise errors.TuningboxNotFound(
|
||||
"{0} not found by {1}".format(cls.__name__, ident)
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def find_or_404(cls, **attrs):
|
||||
item = cls.query.filter_by(**attrs).one_or_none()
|
||||
if not item:
|
||||
raise errors.TuningboxNotFound(
|
||||
"{0} not found by {1}".format(cls.__name__, attrs)
|
||||
)
|
||||
return item
|
||||
|
@ -14,7 +14,7 @@ from sqlalchemy.orm import exc as sa_exc
|
||||
|
||||
from tuning_box import db
|
||||
from tuning_box import errors
|
||||
from tuning_box.library import levels_hierarchy
|
||||
from tuning_box.library import hierarchy_levels
|
||||
|
||||
|
||||
def load_objects(model, ids):
|
||||
@ -75,7 +75,7 @@ def get_resource_definition(id_or_name, environment_id):
|
||||
|
||||
|
||||
def get_resource_values(environment, levels, res_def):
|
||||
level_value = levels_hierarchy.get_environment_level_value(
|
||||
level_value = hierarchy_levels.get_environment_level_value(
|
||||
environment, levels)
|
||||
res_values = db.ResourceValues.query.filter_by(
|
||||
environment_id=environment.id,
|
||||
|
@ -29,7 +29,15 @@ class EnvironmentsCollection(flask_restful.Resource):
|
||||
method_decorators = [flask_restful.marshal_with(environment_fields)]
|
||||
|
||||
def get(self):
|
||||
return db.Environment.query.all()
|
||||
envs = db.Environment.query.all()
|
||||
result = []
|
||||
for env in envs:
|
||||
hierarchy_levels = db.EnvironmentHierarchyLevel.\
|
||||
get_for_environment(env)
|
||||
# Proper order of levels can't be provided by ORM backref
|
||||
result.append({'id': env.id, 'components': env.components,
|
||||
'hierarchy_levels': hierarchy_levels})
|
||||
return result, 200
|
||||
|
||||
def _check_components(self, components):
|
||||
identities = set()
|
||||
@ -72,7 +80,12 @@ class Environment(flask_restful.Resource):
|
||||
method_decorators = [flask_restful.marshal_with(environment_fields)]
|
||||
|
||||
def get(self, environment_id):
|
||||
return db.Environment.query.get_or_404(environment_id)
|
||||
env = db.Environment.query.get_or_404(environment_id)
|
||||
hierarchy_levels = db.EnvironmentHierarchyLevel.\
|
||||
get_for_environment(env)
|
||||
# Proper order of levels can't be provided by ORM backref
|
||||
return {'id': env.id, 'components': env.components,
|
||||
'hierarchy_levels': hierarchy_levels}, 200
|
||||
|
||||
def _update_components(self, environment, components):
|
||||
if components is not None:
|
||||
@ -80,14 +93,29 @@ class Environment(flask_restful.Resource):
|
||||
db.Component, components)
|
||||
environment.components = new_components
|
||||
|
||||
def _update_hierarchy_levels(self, environment, hierarchy_levels):
|
||||
if hierarchy_levels is not None:
|
||||
new_hierarchy_levels = library.load_objects_by_id_or_name(
|
||||
db.EnvironmentHierarchyLevel, hierarchy_levels)
|
||||
parent = None
|
||||
def _update_hierarchy_levels(self, environment, hierarchy_levels_names):
|
||||
if hierarchy_levels_names is not None:
|
||||
old_hierarchy_levels = db.EnvironmentHierarchyLevel.query.filter(
|
||||
db.EnvironmentHierarchyLevel.environment_id == environment.id
|
||||
).all()
|
||||
|
||||
new_hierarchy_levels = []
|
||||
|
||||
for level_name in hierarchy_levels_names:
|
||||
level = db.get_or_create(
|
||||
db.EnvironmentHierarchyLevel,
|
||||
name=level_name,
|
||||
environment=environment
|
||||
)
|
||||
new_hierarchy_levels.append(level)
|
||||
|
||||
parent_id = None
|
||||
for level in new_hierarchy_levels:
|
||||
level.parent = parent
|
||||
parent = level
|
||||
level.parent_id = parent_id
|
||||
parent_id = level.id
|
||||
for old_level in old_hierarchy_levels:
|
||||
if old_level not in new_hierarchy_levels:
|
||||
db.db.session.delete(old_level)
|
||||
environment.hierarchy_levels = new_hierarchy_levels
|
||||
|
||||
@db.with_transaction
|
||||
|
85
tuning_box/library/hierarchy_levels.py
Normal file
85
tuning_box/library/hierarchy_levels.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import flask
|
||||
import werkzeug
|
||||
|
||||
import flask_restful
|
||||
from flask_restful import fields
|
||||
|
||||
from tuning_box import db
|
||||
|
||||
|
||||
def iter_environment_level_values(environment, levels):
|
||||
env_levels = db.EnvironmentHierarchyLevel.get_for_environment(environment)
|
||||
level_pairs = zip(env_levels, levels)
|
||||
for env_level, (level_name, level_value) in level_pairs:
|
||||
if env_level.name != level_name:
|
||||
raise werkzeug.exceptions.BadRequest(
|
||||
"Unexpected level name '{0}'. Expected '{1}'.".format(
|
||||
level_name, env_level.name))
|
||||
level_value_db = db.get_or_create(
|
||||
db.EnvironmentHierarchyLevelValue,
|
||||
level=env_level,
|
||||
value=level_value,
|
||||
)
|
||||
yield level_value_db
|
||||
|
||||
|
||||
def get_environment_level_value(environment, levels):
|
||||
level_value = None
|
||||
for level_value in iter_environment_level_values(environment, levels):
|
||||
pass
|
||||
return level_value
|
||||
|
||||
|
||||
environment_hierarchy_level_fields = {
|
||||
'name': fields.String,
|
||||
'environment_id': fields.Integer,
|
||||
'parent': fields.String(attribute='parent.name')
|
||||
}
|
||||
|
||||
|
||||
class EnvironmentHierarchyLevelsCollection(flask_restful.Resource):
|
||||
method_decorators = [
|
||||
flask_restful.marshal_with(environment_hierarchy_level_fields)
|
||||
]
|
||||
|
||||
def get(self, environment_id):
|
||||
env = db.get_or_404(db.Environment, environment_id)
|
||||
return db.EnvironmentHierarchyLevel.get_for_environment(env)
|
||||
|
||||
|
||||
class EnvironmentHierarchyLevels(flask_restful.Resource):
|
||||
method_decorators = [
|
||||
flask_restful.marshal_with(environment_hierarchy_level_fields)
|
||||
]
|
||||
|
||||
def get(self, environment_id, level):
|
||||
level = db.find_or_404(db.EnvironmentHierarchyLevel,
|
||||
environment_id=environment_id,
|
||||
name=level)
|
||||
return level
|
||||
|
||||
@db.with_transaction
|
||||
def _do_update(self, environment_id, level):
|
||||
level = db.find_or_404(db.EnvironmentHierarchyLevel,
|
||||
environment_id=environment_id,
|
||||
name=level)
|
||||
level.name = flask.request.json.get('name', level.name)
|
||||
|
||||
def put(self, environment_id, level):
|
||||
return self.patch(environment_id, level)
|
||||
|
||||
def patch(self, environment_id, level):
|
||||
self._do_update(environment_id, level)
|
||||
return None, 204
|
@ -1,38 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import werkzeug
|
||||
|
||||
from tuning_box import db
|
||||
|
||||
|
||||
def iter_environment_level_values(environment, levels):
|
||||
env_levels = db.EnvironmentHierarchyLevel.get_for_environment(environment)
|
||||
level_pairs = zip(env_levels, levels)
|
||||
for env_level, (level_name, level_value) in level_pairs:
|
||||
if env_level.name != level_name:
|
||||
raise werkzeug.exceptions.BadRequest(
|
||||
"Unexpected level name '{0}'. Expected '{1}'.".format(
|
||||
level_name, env_level.name))
|
||||
level_value_db = db.get_or_create(
|
||||
db.EnvironmentHierarchyLevelValue,
|
||||
level=env_level,
|
||||
value=level_value,
|
||||
)
|
||||
yield level_value_db
|
||||
|
||||
|
||||
def get_environment_level_value(environment, levels):
|
||||
level_value = None
|
||||
for level_value in iter_environment_level_values(environment, levels):
|
||||
pass
|
||||
return level_value
|
@ -15,7 +15,7 @@ import flask_restful
|
||||
|
||||
from tuning_box import db
|
||||
from tuning_box import library
|
||||
from tuning_box.library import levels_hierarchy
|
||||
from tuning_box.library import hierarchy_levels
|
||||
from tuning_box.library import resource_keys_operation
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ class ResourceOverrides(flask_restful.Resource):
|
||||
resource_id_or_name=res_def.id,
|
||||
), code=308)
|
||||
|
||||
level_value = levels_hierarchy.get_environment_level_value(
|
||||
level_value = hierarchy_levels.get_environment_level_value(
|
||||
environment, levels)
|
||||
esv = db.get_or_create(
|
||||
db.ResourceValues,
|
||||
@ -61,7 +61,7 @@ class ResourceOverrides(flask_restful.Resource):
|
||||
)
|
||||
return flask.redirect(url, code=308)
|
||||
|
||||
level_value = levels_hierarchy.get_environment_level_value(
|
||||
level_value = hierarchy_levels.get_environment_level_value(
|
||||
environment, levels)
|
||||
res_values = db.ResourceValues.query.filter_by(
|
||||
resource_definition=res_def,
|
||||
|
@ -16,7 +16,7 @@ import itertools
|
||||
|
||||
from tuning_box import db
|
||||
from tuning_box import library
|
||||
from tuning_box.library import levels_hierarchy
|
||||
from tuning_box.library import hierarchy_levels
|
||||
from tuning_box.library import resource_keys_operation
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ class ResourceValues(flask_restful.Resource):
|
||||
resource_id_or_name=res_def.id,
|
||||
), code=308)
|
||||
|
||||
level_value = levels_hierarchy.get_environment_level_value(
|
||||
level_value = hierarchy_levels.get_environment_level_value(
|
||||
environment, levels)
|
||||
esv = db.get_or_create(
|
||||
db.ResourceValues,
|
||||
@ -66,7 +66,7 @@ class ResourceValues(flask_restful.Resource):
|
||||
url += '?' + qs
|
||||
return flask.redirect(url, code=308)
|
||||
|
||||
level_values = list(levels_hierarchy.iter_environment_level_values(
|
||||
level_values = list(hierarchy_levels.iter_environment_level_values(
|
||||
environment, levels))
|
||||
|
||||
if 'effective' in flask.request.args:
|
||||
|
@ -0,0 +1,59 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Level cascade deletion on environment removal
|
||||
|
||||
Revision ID: adf671eddeb4
|
||||
Revises: a86472389a70
|
||||
Create Date: 2016-08-19 16:39:46.745113
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'adf671eddeb4'
|
||||
down_revision = 'a86472389a70'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
from alembic import context
|
||||
from alembic import op
|
||||
|
||||
|
||||
def upgrade():
|
||||
table_prefix = context.config.get_main_option('table_prefix')
|
||||
table_name = table_prefix + 'environment_hierarchy_level'
|
||||
|
||||
with op.batch_alter_table(table_name) as batch:
|
||||
batch.drop_constraint(
|
||||
table_prefix + 'environment_hierarchy_level_environment_id_fkey',
|
||||
type_='foreignkey'
|
||||
)
|
||||
batch.create_foreign_key(
|
||||
table_prefix + 'environment_hierarchy_level_environment_id_fkey',
|
||||
table_prefix + 'environment',
|
||||
['environment_id'], ['id'], ondelete='CASCADE'
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
table_prefix = context.config.get_main_option('table_prefix')
|
||||
table_name = table_prefix + 'environment_hierarchy_level'
|
||||
with op.batch_alter_table(table_name) as batch:
|
||||
batch.drop_constraint(
|
||||
table_prefix + 'environment_hierarchy_level_environment_id_fkey',
|
||||
type_='foreignkey'
|
||||
)
|
||||
batch.create_foreign_key(
|
||||
table_prefix + 'environment_hierarchy_level_environment_id_fkey',
|
||||
table_prefix + 'environment',
|
||||
['environment_id'], ['id']
|
||||
)
|
@ -166,11 +166,24 @@ class TestEnvironments(BaseTest):
|
||||
def test_delete_environment(self):
|
||||
self._fixture()
|
||||
env_id = 9
|
||||
res = self.client.delete(self.object_url.format(env_id))
|
||||
self.assertEqual(res.status_code, 204)
|
||||
env_url = self.object_url.format(env_id)
|
||||
res = self.client.get(env_url)
|
||||
self.assertEqual(200, res.status_code)
|
||||
levels = ['lvl1', 'lvl2']
|
||||
self.assertEqual(levels, res.json['hierarchy_levels'])
|
||||
|
||||
res = self.client.delete(env_url)
|
||||
self.assertEqual(204, res.status_code)
|
||||
self.assertEqual(res.data, b'')
|
||||
self._assert_not_in_db(db.Environment, 9)
|
||||
|
||||
with self.app.app_context():
|
||||
for name in levels:
|
||||
obj = db.EnvironmentHierarchyLevel.query.filter(
|
||||
db.EnvironmentHierarchyLevel.name == name
|
||||
).first()
|
||||
self.assertIsNone(obj)
|
||||
|
||||
def test_delete_environment_404(self):
|
||||
env_id = 9
|
||||
res = self.client.delete(self.object_url.format(env_id))
|
||||
@ -260,11 +273,42 @@ class TestEnvironments(BaseTest):
|
||||
self.assertEqual(expected_levels, actual['hierarchy_levels'])
|
||||
self.check_hierarchy_levels(actual['hierarchy_levels'])
|
||||
|
||||
def test_put_environment_level_not_found(self):
|
||||
def test_put_environment_hierarchy_levels_reverse(self):
|
||||
self._fixture()
|
||||
env_id = 9
|
||||
env_url = self.object_url.format(env_id)
|
||||
initial = self.client.get(env_url).json
|
||||
expected_levels = initial['hierarchy_levels']
|
||||
expected_levels.reverse()
|
||||
|
||||
# Updating hierarchy levels
|
||||
res = self.client.put(
|
||||
self.object_url.format(env_id),
|
||||
data={'hierarchy_levels': [None]}
|
||||
env_url,
|
||||
data={'hierarchy_levels': expected_levels}
|
||||
)
|
||||
self.assertEqual(404, res.status_code)
|
||||
self.assertEqual(204, res.status_code)
|
||||
actual = self.client.get(env_url).json
|
||||
self.assertEqual(expected_levels, actual['hierarchy_levels'])
|
||||
self.check_hierarchy_levels(actual['hierarchy_levels'])
|
||||
|
||||
def test_put_environment_hierarchy_levels_with_new_level(self):
|
||||
self._fixture()
|
||||
env_id = 9
|
||||
env_url = self.object_url.format(env_id)
|
||||
initial = self.client.get(env_url).json
|
||||
expected_levels = ['root'] + initial['hierarchy_levels']
|
||||
|
||||
res = self.client.put(
|
||||
env_url,
|
||||
data={'hierarchy_levels': expected_levels}
|
||||
)
|
||||
self.assertEqual(204, res.status_code)
|
||||
|
||||
res = self.client.get('/environments/9/hierarchy_levels')
|
||||
self.assertEqual(200, res.status_code)
|
||||
|
||||
res = self.client.get(env_url)
|
||||
self.assertEqual(200, res.status_code)
|
||||
actual = res.json
|
||||
self.assertEqual(expected_levels, actual['hierarchy_levels'])
|
||||
self.check_hierarchy_levels(actual['hierarchy_levels'])
|
||||
|
118
tuning_box/tests/library/test_hierarchy_levels.py
Normal file
118
tuning_box/tests/library/test_hierarchy_levels.py
Normal file
@ -0,0 +1,118 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import werkzeug
|
||||
|
||||
from tuning_box import db
|
||||
from tuning_box.library import hierarchy_levels
|
||||
from tuning_box.tests.test_app import BaseTest
|
||||
|
||||
|
||||
class TestLevelsHierarchy(BaseTest):
|
||||
|
||||
collection_url = '/environments/{0}/hierarchy_levels'
|
||||
object_url = collection_url + '/{1}'
|
||||
|
||||
def test_get_environment_level_value_root(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
level_value = hierarchy_levels.get_environment_level_value(
|
||||
db.Environment(id=9),
|
||||
[],
|
||||
)
|
||||
self.assertIsNone(level_value)
|
||||
|
||||
def test_get_environment_level_value_deep(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
level_value = hierarchy_levels.get_environment_level_value(
|
||||
db.Environment(id=9),
|
||||
[('lvl1', 'val1'), ('lvl2', 'val2')],
|
||||
)
|
||||
self.assertIsNotNone(level_value)
|
||||
self.assertEqual(level_value.level.name, 'lvl2')
|
||||
self.assertEqual(level_value.value, 'val2')
|
||||
level = level_value.level.parent
|
||||
self.assertIsNotNone(level)
|
||||
self.assertEqual(level.name, 'lvl1')
|
||||
self.assertIsNone(level.parent)
|
||||
|
||||
def test_get_environment_level_value_bad_level(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
exc = self.assertRaises(
|
||||
werkzeug.exceptions.BadRequest,
|
||||
hierarchy_levels.get_environment_level_value,
|
||||
db.Environment(id=9),
|
||||
[('lvlx', 'val1')],
|
||||
)
|
||||
self.assertEqual(
|
||||
exc.description,
|
||||
"Unexpected level name 'lvlx'. Expected 'lvl1'.",
|
||||
)
|
||||
|
||||
def test_get_hierarchy_levels(self):
|
||||
self._fixture()
|
||||
environment_id = 9
|
||||
expected_levels = ['lvl1', 'lvl2']
|
||||
res = self.client.get(self.collection_url.format(environment_id))
|
||||
self.assertEqual(200, res.status_code)
|
||||
self.assertEqual(expected_levels, [d['name'] for d in res.json])
|
||||
|
||||
def test_get_hierarchy_levels_not_found(self):
|
||||
environment_id = 9
|
||||
res = self.client.get(self.collection_url.format(environment_id))
|
||||
self.assertEqual(404, res.status_code)
|
||||
|
||||
def test_get_hierarchy_level(self):
|
||||
self._fixture()
|
||||
environment_id = 9
|
||||
levels = ['lvl1', 'lvl2']
|
||||
for level in levels:
|
||||
res = self.client.get(self.object_url.format(environment_id,
|
||||
level))
|
||||
self.assertEqual(200, res.status_code)
|
||||
self.assertEqual(level, res.json['name'])
|
||||
|
||||
def test_get_hierarchy_level_not_found(self):
|
||||
levels = ['lvl1', 'lvl2']
|
||||
for level in levels:
|
||||
res = self.client.get(self.object_url.format(9, level))
|
||||
self.assertEqual(404, res.status_code)
|
||||
|
||||
def test_put_hierarchy_level(self):
|
||||
self._fixture()
|
||||
environment_id = 9
|
||||
level = 'lvl1'
|
||||
new_name = 'new_{0}'.format(level)
|
||||
res = self.client.put(self.object_url.format(environment_id, level),
|
||||
data={'name': new_name})
|
||||
self.assertEqual(204, res.status_code)
|
||||
|
||||
res = self.client.get(self.object_url.format(environment_id, new_name))
|
||||
self.assertEqual(200, res.status_code)
|
||||
self.assertEqual(new_name, res.json['name'])
|
||||
|
||||
def test_put_hierarchy_level_not_found(self):
|
||||
self._fixture()
|
||||
environment_id = 9
|
||||
res = self.client.put(self.object_url.format(environment_id, 'xx'),
|
||||
data={'name': 'new_name'})
|
||||
self.assertEqual(404, res.status_code)
|
||||
|
||||
res = self.client.put(self.object_url.format(1, 'lvl1'),
|
||||
data={'name': 'new_name'})
|
||||
self.assertEqual(404, res.status_code)
|
||||
|
||||
res = self.client.put(self.object_url.format(1, 'xx'),
|
||||
data={'name': 'new_name'})
|
||||
self.assertEqual(404, res.status_code)
|
@ -1,58 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import werkzeug
|
||||
|
||||
from tuning_box import db
|
||||
from tuning_box.library import levels_hierarchy
|
||||
from tuning_box.tests.test_app import BaseTest
|
||||
|
||||
|
||||
class TestLevelsHierarchy(BaseTest):
|
||||
|
||||
def test_get_environment_level_value_root(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
level_value = levels_hierarchy.get_environment_level_value(
|
||||
db.Environment(id=9),
|
||||
[],
|
||||
)
|
||||
self.assertIsNone(level_value)
|
||||
|
||||
def test_get_environment_level_value_deep(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
level_value = levels_hierarchy.get_environment_level_value(
|
||||
db.Environment(id=9),
|
||||
[('lvl1', 'val1'), ('lvl2', 'val2')],
|
||||
)
|
||||
self.assertIsNotNone(level_value)
|
||||
self.assertEqual(level_value.level.name, 'lvl2')
|
||||
self.assertEqual(level_value.value, 'val2')
|
||||
level = level_value.level.parent
|
||||
self.assertIsNotNone(level)
|
||||
self.assertEqual(level.name, 'lvl1')
|
||||
self.assertIsNone(level.parent)
|
||||
|
||||
def test_get_environment_level_value_bad_level(self):
|
||||
self._fixture()
|
||||
with self.app.app_context(), db.db.session.begin():
|
||||
exc = self.assertRaises(
|
||||
werkzeug.exceptions.BadRequest,
|
||||
levels_hierarchy.get_environment_level_value,
|
||||
db.Environment(id=9),
|
||||
[('lvlx', 'val1')],
|
||||
)
|
||||
self.assertEqual(
|
||||
exc.description,
|
||||
"Unexpected level name 'lvlx'. Expected 'lvl1'.",
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user