Skip to content

Commit

Permalink
Merge e339d20 into e4f504b
Browse files Browse the repository at this point in the history
  • Loading branch information
kholdaway committed Feb 22, 2018
2 parents e4f504b + e339d20 commit e858e13
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 238 deletions.
23 changes: 23 additions & 0 deletions quipucords/api/common/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"""Util for common operations."""

import logging
from rest_framework.serializers import ValidationError


# Get an instance of a logger
Expand Down Expand Up @@ -64,6 +65,28 @@ def convert_to_boolean(value):
return value.lower() == 'true'


def check_for_existing_name(queryset, name, error_message, search_id=None):
"""Look for existing (different object) with same name.
:param queryset: Queryset used in searches
:param name: Name of scan to look for
:param error_message: message to display
:param search_id: ID to exclude from search for existing
"""
if search_id is None:
# Look for existing with same name (create)
existing = queryset.filter(name=name).first()
else:
# Look for existing. Same name, different id (update)
existing = queryset.filter(
name=name).exclude(id=search_id).first()
if existing is not None:
error = {
'name': [error_message]
}
raise ValidationError(error)


class CSVHelper:
"""Helper for CSV serialization of list/dict values."""

Expand Down
37 changes: 12 additions & 25 deletions quipucords/api/credential/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from api.models import Credential
import api.messages as messages
from api.common.serializer import NotEmptySerializer, ValidStringChoiceField
from api.common.util import check_for_existing_name


def expand_filepath(filepath):
Expand Down Expand Up @@ -60,8 +61,11 @@ class Meta:

def create(self, validated_data):
"""Create host credential."""
CredentialSerializer.check_for_existing_name(
name=validated_data.get('name'))
name = validated_data.get('name')
check_for_existing_name(
Credential.objects,
name,
_(messages.HC_NAME_ALREADY_EXISTS % name))

if 'cred_type' not in validated_data:
error = {
Expand All @@ -84,9 +88,12 @@ def create(self, validated_data):

def update(self, instance, validated_data):
"""Update a host credential."""
CredentialSerializer.check_for_existing_name(
name=validated_data.get('name'),
cred_id=instance.id)
name = validated_data.get('name')
check_for_existing_name(
Credential.objects,
name,
_(messages.HC_NAME_ALREADY_EXISTS % name),
search_id=instance.id)

if 'cred_type' in validated_data:
error = {
Expand All @@ -96,26 +103,6 @@ def update(self, instance, validated_data):

return super().update(instance, validated_data)

@staticmethod
def check_for_existing_name(name, cred_id=None):
"""Look for existing (different object) with same name.
:param name: Name of credential to look for
:param cred_id: Host credential to exclude
"""
if cred_id is None:
# Look for existing with same name (create)
existing = Credential.objects.filter(name=name).first()
else:
# Look for existing. Same name, different id (update)
existing = Credential.objects.filter(
name=name).exclude(id=cred_id).first()
if existing is not None:
error = {
'name': [_(messages.HC_NAME_ALREADY_EXISTS % name)]
}
raise ValidationError(error)

def validate(self, attrs):
"""Validate the attributes."""
cred_type = 'cred_type' in attrs and attrs['cred_type']
Expand Down
37 changes: 12 additions & 25 deletions quipucords/api/scan/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
ValidStringChoiceField,
CustomJSONField)
from api.scantasks.serializer import SourceField
from api.common.util import check_for_existing_name


class ScanOptionsSerializer(NotEmptySerializer):
Expand Down Expand Up @@ -74,8 +75,11 @@ class Meta:
@transaction.atomic
def create(self, validated_data):
"""Create a scan."""
self.check_for_existing_name(
name=validated_data.get('name'))
name = validated_data.get('name')
check_for_existing_name(
Scan.objects,
name,
_(messages.SCAN_NAME_ALREADY_EXISTS % name))

options = validated_data.pop('options', None)
scan = super().create(validated_data)
Expand All @@ -95,9 +99,12 @@ def update(self, instance, validated_data):
# If we ever add optional fields to Scan, we need to
# add logic here to clear them on full update even if they are
# not supplied.
self.check_for_existing_name(
name=validated_data.get('name'),
scan_id=instance.id)
name = validated_data.get('name')
check_for_existing_name(
Scan.objects,
name,
_(messages.HC_NAME_ALREADY_EXISTS % name),
search_id=instance.id)

name = validated_data.pop('name', None)
scan_type = validated_data.pop('scan_type', None)
Expand Down Expand Up @@ -132,23 +139,3 @@ def validate_sources(sources):
raise ValidationError(_(messages.SJ_REQ_SOURCES))

return sources

@staticmethod
def check_for_existing_name(name, scan_id=None):
"""Look for existing (different object) with same name.
:param name: Name of scan to look for
:param scan_id: Scan to exclude
"""
if scan_id is None:
# Look for existing with same name (create)
existing = Scan.objects.filter(name=name).first()
else:
# Look for existing. Same name, different id (update)
existing = Scan.objects.filter(
name=name).exclude(id=scan_id).first()
if existing is not None:
error = {
'name': [_(messages.SCAN_NAME_ALREADY_EXISTS % name)]
}
raise ValidationError(error)
165 changes: 82 additions & 83 deletions quipucords/api/scan/tests_scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,89 +276,88 @@ def test_retrieve_bad_id(self):
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

# def test_update(self):
# """Completely update a scan."""
# data_discovery = {'name': 'test',
# 'sources': [self.source.id],
# 'scan_type': ScanTask.SCAN_TYPE_CONNECT,
# 'options': {'disable_optional_products':
# {'jboss_eap': True,
# 'jboss_fuse': True,
# 'jboss_brms': True}}}
# initial = self.create_expect_201(data_discovery)

# data = {'name': 'test',
# 'sources': [self.source.id],
# 'scan_type': ScanTask.SCAN_TYPE_INSPECT,
# 'options': {'disable_optional_products':
# {'jboss_eap': True,
# 'jboss_fuse': True,
# 'jboss_brms': True}}}
# url = reverse('scan-detail', args=(initial['id'],))
# response = self.client.put(url,
# json.dumps(data),
# content_type='application/json',
# format='json')
# self.assertEqual(response.status_code,
# status.HTTP_200_OK)

# @patch('api.scanjob.view.start_scan', side_effect=dummy_start)
# def test_update_not_allowed_disable_optional_products(self, start_scan):
# """Completely update a Source & fail due to disable_opt_products."""
# data_discovery = {'sources': [self.source.id],
# 'scan_type': ScanTask.SCAN_TYPE_CONNECT,
# 'options': {'disable_optional_products':
# {'jboss_eap': True,
# 'jboss_fuse': True,
# 'jboss_brms': True}}}
# initial = self.create_expect_201(data_discovery)

# data = {'sources': [self.source.id],
# 'scan_type': ScanTask.SCAN_TYPE_INSPECT,
# 'options': {'disable_optional_products': 'bar'}}
# url = reverse('scan-detail', args=(initial['id'],))
# response = self.client.put(url,
# json.dumps(data),
# content_type='application/json',
# format='json')
# self.assertEqual(response.status_code,
# status.HTTP_405_METHOD_NOT_ALLOWED)

# @patch('api.scanjob.view.start_scan', side_effect=dummy_start)
# def test_partial_update(self, start_scan):
# """Partially update a ScanJob is not supported."""
# data_discovery = {'sources': [self.source.id],
# 'scan_type': ScanTask.SCAN_TYPE_CONNECT,
# 'options': {'disable_optional_products':
# {'jboss_eap': True,
# 'jboss_fuse': True,
# 'jboss_brms': True}}}
# initial = self.create_expect_201(data_discovery)

# data = {'scan_type': ScanTask.SCAN_TYPE_INSPECT}
# url = reverse('scan-detail', args=(initial['id'],))
# response = self.client.patch(url,
# json.dumps(data),
# content_type='application/json',
# format='json')
# self.assertEqual(response.status_code,
# status.HTTP_405_METHOD_NOT_ALLOWED)

# def test_delete(self):
# """Delete a Scan is not supported."""
# data_discovery = {'name': 'test',
# 'sources': [self.source.id],
# 'scan_type': ScanTask.SCAN_TYPE_CONNECT,
# 'options': {'disable_optional_products':
# {'jboss_eap': True,
# 'jboss_fuse': True,
# 'jboss_brms': True}}}
# response = self.create_expect_201(data_discovery)

# url = reverse('scan-detail', args=(response['id'],))
# response = self.client.delete(url, format='json')
# self.assertEqual(response.status_code,
# status.HTTP_204_NO_CONTENT)
def test_update(self):
"""Completely update a scan."""
data_discovery = {'name': 'test',
'sources': [self.source.id],
'scan_type': ScanTask.SCAN_TYPE_CONNECT,
'options': {'disable_optional_products':
{'jboss_eap': True,
'jboss_fuse': True,
'jboss_brms': True}}}
initial = self.create_expect_201(data_discovery)

data = {'name': 'test2',
'sources': [self.source.id],
'scan_type': ScanTask.SCAN_TYPE_INSPECT,
'options': {'disable_optional_products':
{'jboss_eap': False,
'jboss_fuse': True,
'jboss_brms': True}}}
url = reverse('scan-detail', args=(initial['id'],))
response = self.client.put(url,
json.dumps(data),
content_type='application/json',
format='json')
response_json = response.json()
self.assertEqual(response.status_code,
status.HTTP_200_OK)
self.assertEqual(response_json.get('scan_type'),
ScanTask.SCAN_TYPE_INSPECT)
self.assertEqual(response_json.get('name'), 'test2')
self.assertFalse(response_json.get('options').get('jboss_eap'))

def test_partial_update(self):
"""Test partial update a scan."""
data_discovery = {'name': 'test',
'sources': [self.source.id],
'scan_type': ScanTask.SCAN_TYPE_CONNECT,
'options': {'disable_optional_products':
{'jboss_eap': True,
'jboss_fuse': True,
'jboss_brms': True}}}
initial = self.create_expect_201(data_discovery)

data = {'scan_type': ScanTask.SCAN_TYPE_INSPECT}
url = reverse('scan-detail', args=(initial['id'],))
response = self.client.patch(url,
json.dumps(data),
content_type='application/json',
format='json')
response_json = response.json()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response_json.get('scan_type'),
ScanTask.SCAN_TYPE_INSPECT)
data = {'name': 'test2',
'options': {'disable_optional_products':
{'jboss_eap': False,
'jboss_fuse': True,
'jboss_brms': True}}}
response = self.client.patch(url,
json.dumps(data),
content_type='application/json',
format='json')
response_json = response.json()
self.assertEqual(response.status_code,
status.HTTP_200_OK)
self.assertEqual(response_json.get('name'), 'test2')
self.assertFalse(response_json.get('options').get('jboss_eap'))

def test_delete(self):
"""Delete a scan."""
data_discovery = {'name': 'test',
'sources': [self.source.id],
'scan_type': ScanTask.SCAN_TYPE_CONNECT,
'options': {'disable_optional_products':
{'jboss_eap': True,
'jboss_fuse': True,
'jboss_brms': True}}}
response = self.create_expect_201(data_discovery)

url = reverse('scan-detail', args=(response['id'],))
response = self.client.delete(url, format='json')
self.assertEqual(response.status_code,
status.HTTP_204_NO_CONTENT)

def test_expand_scan(self):
"""Test view expand_scan."""
Expand Down
Loading

0 comments on commit e858e13

Please sign in to comment.