Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
* *Describe scheme changes here.*

### Code/API changes
* [OSDEV-1453](https://opensupplyhub.atlassian.net/browse/OSDEV-1453) - The `detail` keyword instead of `message` has been applied in error response objects for V1 endpoints.
* [OSDEV-1346](https://opensupplyhub.atlassian.net/browse/OSDEV-1346) - Disabled null values from the response of the OpenSearch. Disabled possible null `os_id`, `claim_id` and `source` from `PATCH api/v1/moderation-events/{moderation_id}` response.

### Architecture/Environment changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def to_internal_value(self, data):
if status is None:
raise ValidationError({
"field": "status",
"message": "This field is required."
"detail": "This field is required."
})

self.__validate_status(status)
Expand All @@ -54,7 +54,7 @@ def __validate_status(self, value):
]:
raise ValidationError({
"field": "status",
"message": (
"detail": (
"Moderation status must be one of "
"PENDING, APPROVED or REJECTED."
)
Expand Down
4 changes: 2 additions & 2 deletions src/django/api/serializers/v1/moderation_events_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
countries_validator import CountryValidator
from api.serializers.v1.opensearch_common_validators. \
date_range_validator import DateRangeValidator
from api.views.v1.utils import COMMON_ERROR_MESSAGE
from api.views.v1.utils import COMMON_ERROR_DETAIL


class ModerationEventsSerializer(Serializer):
Expand Down Expand Up @@ -86,7 +86,7 @@ def validate(self, data):
if errors:
# [OSDEV-1441] Pass error msg to the Rollbar here
raise ValidationError({
"message": COMMON_ERROR_MESSAGE,
"detail": COMMON_ERROR_DETAIL,
"errors": errors
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ def validate_opensearch_params(self, data) -> List[dict]:
(lat is None and lng is not None)):
errors.append({
"field": "coordinates",
"message": "Both latitude and longitude must be provided."
"detail": "Both latitude and longitude must be provided."
})

if lat is not None:
if not (-90 <= lat <= 90):
errors.append({
"field": "coordinates",
"message": "Latitude must be between -90 and 90 degrees."
"detail": "Latitude must be between -90 and 90 degrees."
})

if lng is not None:
if not (-180 <= lng <= 180):
errors.append({
"field": "coordinates",
"message":
"detail":
"Longitude must be between -180 and 180 degrees."
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def validate_opensearch_params(self, data) -> List[dict]:
if not re.match(valid_country_value_regexp, country):
errors.append({
"field": "country",
"message":
"detail":
f"'{country}' is not a valid alpha-2 country code."
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def validate_opensearch_params(self, data) -> List[dict]:
if date_gte and date_lt and date_gte > date_lt:
errors.append({
"field": "date_gte",
"message": (
"detail": (
"The 'date_gte' must be "
"less than or equal to 'date_lt'."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ def validate_opensearch_params(self, data) -> List[dict]:
if invalid_ids:
errors.append({
"field": "moderation_id",
"message": f"Invalid UUID(s): {', '.join(invalid_ids)}.",
"detail": f"Invalid UUID(s): {', '.join(invalid_ids)}.",
})
elif isinstance(moderation_id, str):
if not self.is_valid_uuid(moderation_id):
errors.append({
"field": "moderation_id",
"message": f"Invalid UUID: {moderation_id}.",
"detail": f"Invalid UUID: {moderation_id}.",
})
else:
errors.append({
"field": "moderation_id",
"message": (
"detail": (
"moderation_id must be a valid UUID or a list of UUIDs."
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def validate_opensearch_params(self, data) -> List[dict]:
(min_value is None and max_value is not None)):
errors.append({
"field": "number_of_workers",
"message": (
"detail": (
"The value must be a valid object with `min` and `max` "
"properties."
)
Expand All @@ -24,7 +24,7 @@ def validate_opensearch_params(self, data) -> List[dict]:
min_value > max_value):
errors.append({
"field": "number_of_workers",
"message": (
"detail": (
"Minimum value must be less than or equal "
"to maximum value."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def validate_opensearch_params(self, data) -> List[dict]:
percent_female_workers_max is not None):
errors.append({
"field": "percent_female_workers",
"message": "Both min and max percentages must be provided."
"detail": "Both min and max percentages must be provided."
})

if percent_female_workers_min is not None and \
Expand All @@ -25,12 +25,12 @@ def validate_opensearch_params(self, data) -> List[dict]:
0 < percent_female_workers_max <= 100):
errors.append({
"field": "percent_female_workers",
"message": "Percentages must be between 0 and 100."
"detail": "Percentages must be between 0 and 100."
})
if percent_female_workers_min > percent_female_workers_max:
errors.append({
"field": "percent_female_workers",
"message": (
"detail": (
"Minimum percentage must be less than or equal to "
"maximum percentage."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def validate_opensearch_params(self, data) -> List[dict]:
if request_type not in valid_request_types:
errors.append({
"field": "request_type",
"message": f"'{request_type}' is not a valid request_type. \
"detail": f"'{request_type}' is not a valid request_type. \
Allowed values are 'CREATE', 'UPDATE' or 'CLAIM'."
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ def validate_opensearch_params(self, data) -> List[dict]:
if size <= 0 or size > size_limit:
errors.append({
"field": "size",
"message": (
"detail": (
f"Size must be a positive integer less than or equal "
f"to {size_limit}."
)
})
except ValueError:
errors.append({
"field": "size",
"message": "Size must be a valid integer."
"detail": "Size must be a valid integer."
})

return errors
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ def validate_opensearch_params(self, data) -> List[dict]:
if not isinstance(source, list):
errors.append({
"field": "source",
"message": "Source must be a list of values."
"detail": "Source must be a list of values."
})
elif not all(item in self.VALID_SOURCES for item in source):
invalid_sources = [item for item in source if
item not in self.VALID_SOURCES]
errors.append({
"field": "source",
"message": (
"detail": (
f"Invalid source(s) {invalid_sources}. "
"Allowed values are 'SLC' or 'API'."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ def validate_opensearch_params(self, data) -> List[dict]:
if not isinstance(status, list):
errors.append({
"field": "status",
"message": "Status must be a list of values."
"detail": "Status must be a list of values."
})
elif not all(item in self.VALID_STATUSES for item in status):
invalid_statuses = [item for item in status if
item not in self.VALID_STATUSES]
errors.append({
"field": "status",
"message": (
f"Invalid source(s) {invalid_statuses}. "
"detail": (
f"Invalid status(es) {invalid_statuses}. "
"Allowed values are 'PENDING','APPROVED' or 'REJECTED'."
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
percent_of_female_workers_validator import PercentOfFemaleWorkersValidator
from api.serializers.v1.opensearch_common_validators. \
coordinates_validator import CoordinatesValidator
from api.views.v1.utils import COMMON_ERROR_MESSAGE
from api.views.v1.utils import COMMON_ERROR_DETAIL


class ProductionLocationsSerializer(Serializer):
Expand Down Expand Up @@ -61,7 +61,7 @@ def validate(self, data):
if errors:
# [OSDEV-1441] Pass error msg to the Rollbar here
raise ValidationError({
"message": COMMON_ERROR_MESSAGE,
"detail": COMMON_ERROR_DETAIL,
"errors": errors
})

Expand Down
6 changes: 3 additions & 3 deletions src/django/api/services/opensearch/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
class OpenSearchServiceException(Exception):
def __init__(
self,
message="An unexpected error occurred while processing the request."
detail="An unexpected error occurred while processing the request."
):
self.message = message
super().__init__(self.message)
self.detail = detail
super().__init__(self.detail)


class OpenSearchService(SearchInterface):
Expand Down
4 changes: 2 additions & 2 deletions src/django/api/tests/test_production_locations_view_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ def test_get_single_production_location_not_found(self):
self.search_index_mock.return_value = {}
url = f"/api/v1/production-locations/{self.os_id}/"
api_res = self.client.get(url)
message = {"detail": "The location with the given id was not found."}
self.assertEqual(api_res.data, message)
detail = {"detail": "The location with the given id was not found."}
self.assertEqual(api_res.data, detail)
self.assertEqual(api_res.status_code, status.HTTP_404_NOT_FOUND)
12 changes: 6 additions & 6 deletions src/django/api/tests/test_v1_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,20 @@ def test_serialize_params_invalid(self):
serialize_params(TestProductionLocationsSerializer, query_dict)
self.assertIsNotNone(error_response)
self.assertEqual(
error_response['message'],
error_response['detail'],
"The request query is invalid."
)
self.assertIn(
{
'field': 'number_of_workers_min',
'message': 'A Valid Integer Is Required.'
'detail': 'A Valid Integer Is Required.'
},
error_response['errors']
)
self.assertIn(
{
'field': 'size',
'message': 'A Valid Integer Is Required.'
'detail': 'A Valid Integer Is Required.'
},
error_response['errors']
)
Expand All @@ -139,18 +139,18 @@ def test_handle_value_error(self):
self.assertIsInstance(response, Response)
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.data['message'],
response.data['detail'],
"The request query is invalid."
)
self.assertEqual(response.data['errors'][0]['field'], "general")
self.assertIn(
"There was a problem processing your request.",
response.data['errors'][0]['message']
response.data['errors'][0]['detail']
)

def test_handle_opensearch_exception(self):
exception = OpenSearchServiceException("OpenSearch error")
response = handle_opensearch_exception(exception)
self.assertIsInstance(response, Response)
self.assertEqual(response.status_code, 500)
self.assertEqual(response.data['message'], "OpenSearch error")
self.assertEqual(response.data['detail'], "OpenSearch error")
8 changes: 4 additions & 4 deletions src/django/api/views/v1/moderation_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def retrieve(self, _, pk=None):
if not ModerationIdValidator.is_valid_uuid(pk):
return handle_path_error(
field="moderation_id",
message="Invalid UUID format.",
detail="Invalid UUID format.",
status_code=status.HTTP_400_BAD_REQUEST
)

Expand All @@ -89,7 +89,7 @@ def patch(self, request, pk=None):
if not ModerationIdValidator.is_valid_uuid(pk):
return handle_path_error(
field="moderation_id",
message="Invalid UUID format.",
detail="Invalid UUID format.",
status_code=status.HTTP_400_BAD_REQUEST
)

Expand All @@ -98,7 +98,7 @@ def patch(self, request, pk=None):
except ModerationEvent.DoesNotExist:
return handle_path_error(
field="moderation_id",
message="Moderation event not found.",
detail="Moderation event not found.",
status_code=status.HTTP_404_NOT_FOUND
)

Expand All @@ -114,7 +114,7 @@ def patch(self, request, pk=None):

return Response(
{
"message": 'The request body contains '
"detail": 'The request body contains '
'invalid or missing fields.',
"error": [serializer.errors]
},
Expand Down
Loading