Skip to content

Commit

Permalink
add observation end time api update and basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon committed Aug 27, 2019
1 parent 16e5aec commit 2d72686
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
16 changes: 16 additions & 0 deletions observation_portal/observations/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ class Meta:
fields = ('site', 'enclosure', 'telescope', 'start', 'end', 'priority', 'configuration_statuses', 'request')

def validate(self, data):
if self.context.get('request').method == 'PATCH':
# For a partial update, only validate that the 'end' field is set, and that it is > now
if 'end' not in data:
raise serializers.ValidationError(_('Observation update must include `end` field'))
if data['end'] <= timezone.now():
raise serializers.ValidationError(_('Updated end time must be in the future'))
return data

if data['end'] <= data['start']:
raise serializers.ValidationError(_('End time must be after start time'))

Expand Down Expand Up @@ -321,6 +329,14 @@ def validate(self, data):

return data

def update(self, instance, validated_data):
if validated_data['end'] > instance.start:
# Only update the end time if it is > start time
instance.end = validated_data['end']
instance.save()

return instance

def create(self, validated_data):
configuration_statuses = validated_data.pop('configuration_statuses')
observation = Observation.objects.create(**validated_data)
Expand Down
60 changes: 60 additions & 0 deletions observation_portal/observations/tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from rest_framework.test import APITestCase
from rest_framework import serializers
from observation_portal.common.test_helpers import SetTimeMixin
from django.utils import timezone
from mixer.backend.django import mixer
Expand Down Expand Up @@ -946,6 +947,65 @@ def test_update_summary_triggers_request_status_without_completing(self):
self.assertEqual(self.requestgroup.state, 'PENDING')


class TestUpdateObservationApi(TestObservationApiBase):
def setUp(self):
super().setUp()

def test_update_observation_end_time_succeeds(self):
original_end = datetime(2016, 9, 5, 23, 35, 40).replace(tzinfo=timezone.utc)
observation = self._generate_observation_data(
self.requestgroup.requests.first().id, [self.requestgroup.requests.first().configurations.first().id]
)
self._create_observation(observation)
observation = Observation.objects.first()
self.assertEqual(observation.end, original_end)

new_end = datetime(2016, 9, 5, 23, 47, 22).replace(tzinfo=timezone.utc)
update_data = {"end": datetime.strftime(new_end, '%Y-%m-%dT%H:%M:%SZ')}
self.client.patch(reverse('api:observations-detail', args=(observation.id,)), update_data)
observation.refresh_from_db()
self.assertEqual(observation.end, new_end)

def test_update_observation_end_before_start_does_nothing(self):
original_end = datetime(2016, 9, 5, 23, 35, 40).replace(tzinfo=timezone.utc)
observation = self._generate_observation_data(
self.requestgroup.requests.first().id, [self.requestgroup.requests.first().configurations.first().id]
)
self._create_observation(observation)
observation = Observation.objects.first()

new_end = datetime(2016, 9, 5, 19, 35, 40).replace(tzinfo=timezone.utc)
update_data = {"end": datetime.strftime(new_end, '%Y-%m-%dT%H:%M:%SZ')}
self.client.patch(reverse('api:observations-detail', args=(observation.id,)), update_data)
observation.refresh_from_db()
self.assertEqual(observation.end, original_end)

def test_update_observation_end_must_be_in_future(self):
observation = self._generate_observation_data(
self.requestgroup.requests.first().id, [self.requestgroup.requests.first().configurations.first().id]
)
self._create_observation(observation)
observation = Observation.objects.first()

new_end = datetime(2016, 8, 5, 19, 35, 40).replace(tzinfo=timezone.utc)
update_data = {"end": datetime.strftime(new_end, '%Y-%m-%dT%H:%M:%SZ')}
response = self.client.patch(reverse('api:observations-detail', args=(observation.id,)), update_data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json()['non_field_errors'], ['Updated end time must be in the future'])

def test_update_observation_update_must_include_end(self):
observation = self._generate_observation_data(
self.requestgroup.requests.first().id, [self.requestgroup.requests.first().configurations.first().id]
)
self._create_observation(observation)
observation = Observation.objects.first()

update_data = {'field_1': 'testtest', 'not_end': 2341}
response = self.client.patch(reverse('api:observations-detail', args=(observation.id,)), update_data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json()['non_field_errors'], ['Observation update must include `end` field'])


class TestLastScheduled(TestObservationApiBase):
def setUp(self):
super().setUp()
Expand Down
2 changes: 1 addition & 1 deletion observation_portal/observations/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def get_queryset(self):

class ObservationViewSet(CreateListModelMixin, ListAsDictMixin, viewsets.ModelViewSet):
permission_classes = (IsAdminUser,)
http_method_names = ['get', 'post', 'head', 'options']
http_method_names = ['get', 'post', 'head', 'options', 'patch']
filter_class = ObservationFilter
serializer_class = ObservationSerializer
filter_backends = (
Expand Down

0 comments on commit 2d72686

Please sign in to comment.