Ensure actions are setup before pre_approve

Fixes an issue where a failure during pre_approve will
incorrectly setup a task that can be revalidated and approved,
but should not be since actions will be missing.

Change-Id: I733f947851ec1dc6492ed2055df95d838d381e67
Closes-bug: bug/1745053
This commit is contained in:
Adrian Turjak 2018-01-24 12:27:03 +13:00
parent 6ea0993e34
commit 88cfb3c48b
2 changed files with 39 additions and 2 deletions

View File

@ -179,16 +179,19 @@ class TaskView(APIViewWithLogger):
task.save()
# Instantiate actions with serializers
action_instances = []
for i, action in enumerate(action_serializer_list):
data = action['serializer'].validated_data
# construct the action class
action_instance = action['action'](
action_instances.append(action['action'](
data=data,
task=task,
order=i
)
))
# We run pre_approve on the actions once we've setup all of them.
for action_instance in action_instances:
try:
action_instance.pre_approve()
except Exception as e:

View File

@ -15,11 +15,13 @@
import mock
from django.test.utils import override_settings
from django.conf import settings
from django.core import mail
from rest_framework import status
from adjutant.api.models import Task, Token
from adjutant.api.v1.tasks import CreateProject
from adjutant.common.tests.fake_clients import (
FakeManager, setup_identity_cache)
from adjutant.common.tests import fake_clients
@ -1364,3 +1366,35 @@ class TaskViewTests(AdjutantAPITestCase):
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json(), {'errors': ['actions invalid']})
self.assertEqual(len(mail.outbox), 0)
@mock.patch('adjutant.common.tests.fake_clients.FakeManager.find_project')
def test_all_actions_setup(self, mocked_find):
"""
Ensures that all actions have been setup before pre_approve is
run on any actions, even if we have a pre_approve failure.
Deals with: bug/1745053
"""
setup_identity_cache()
mocked_find.side_effect = KeyError()
url = "/v1/actions/CreateProject"
data = {'project_name': "test_project", 'email': "test@example.com"}
response = self.client.post(url, data, format='json')
self.assertEqual(
response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
new_task = Task.objects.all()[0]
class_conf = settings.TASK_SETTINGS.get(
CreateProject.task_type, settings.DEFAULT_TASK_SETTINGS)
expected_action_names = (
class_conf.get('default_actions', []) or
CreateProject.default_actions[:])
expected_action_names += class_conf.get('additional_actions', [])
actions = new_task.actions
observed_action_names = [a.action_name for a in actions]
self.assertEqual(observed_action_names, expected_action_names)