type: string
format: iso8601
readOnly: true
+ actor:
+ type: object
+ title: Actor
+ description: The user that caused/created this event.
+ readOnly: true
+ allOf:
+ - $ref: '#/components/schemas/UserEmbedded'
payload:
type: object
EventCoverCreated:
type: string
format: iso8601
readOnly: true
+{% if version >= (1, 2) %}
+ actor:
+ type: object
+ title: Actor
+ description: The user that caused/created this event.
+ readOnly: true
+ allOf:
+ - $ref: '#/components/schemas/UserEmbedded'
+{% endif %}
payload:
type: object
EventCoverCreated:
type: string
format: iso8601
readOnly: true
+ actor:
+ type: object
+ title: Actor
+ description: The user that caused/created this event.
+ readOnly: true
+ allOf:
+ - $ref: '#/components/schemas/UserEmbedded'
payload:
type: object
EventCoverCreated:
``date``
When this event was created
+``actor``
+ The user, if any, that caused/created this event
+
``payload``
Additional information
class EventSerializer(ModelSerializer):
project = ProjectSerializer(read_only=True)
+ actor = UserSerializer()
patch = PatchSerializer(read_only=True)
series = SeriesSerializer(read_only=True)
cover = CoverLetterSerializer(read_only=True)
data = super(EventSerializer, self).to_representation(instance)
payload = OrderedDict()
kept_fields = self._category_map[instance.category] + [
- 'id', 'category', 'project', 'date']
+ 'id', 'category', 'project', 'date', 'actor']
for field in [x for x in data]:
if field not in kept_fields:
class Meta:
model = Event
- fields = ('id', 'category', 'project', 'date', 'patch', 'series',
- 'cover', 'previous_state', 'current_state',
+ fields = ('id', 'category', 'project', 'date', 'actor', 'patch',
+ 'series', 'cover', 'previous_state', 'current_state',
'previous_delegate', 'current_delegate', 'created_check')
read_only_fields = fields
+ versioned_fields = {
+ '1.2': ('actor', ),
+ }
class EventList(ListAPIView):
class Meta:
model = Event
- fields = ('project', 'category', 'series', 'patch', 'cover')
+ fields = ('project', 'category', 'series', 'patch', 'cover', 'actor')
+ versioned_fields = {
+ '1.2': ('actor', ),
+ }
class BundleFilterSet(BaseFilterSet):
def assertSerialized(self, event_obj, event_json):
self.assertEqual(event_obj.id, event_json['id'])
self.assertEqual(event_obj.category, event_json['category'])
+ if event_obj.actor is None:
+ self.assertIsNone(event_json['actor'])
# nested fields
self.assertEqual(event_obj.project.id,
event_json['project']['id'])
+ if event_obj.actor is not None:
+ self.assertEqual(event_obj.actor.id,
+ event_json['actor']['id'])
# TODO(stephenfin): Check other fields
# check-created
create_check(patch=patch)
# patch-delegated, patch-state-changed
+ actor = create_maintainer(project=patch.project)
user = create_maintainer(project=patch.project)
state = create_state()
patch.delegate = user
patch.state = state
+ self.assertTrue(patch.is_editable(actor))
patch.save()
return Event.objects.all()
resp = self.client.get(self.api_url(), {'series': 999999})
self.assertEqual(0, len(resp.data))
+ def test_list_filter_actor(self):
+ """Filter events by actor."""
+ events = self._create_events()
+
+ # The final two events (patch-delegated, patch-state-changed)
+ # have an actor set
+ actor = events[0].actor
+ resp = self.client.get(self.api_url(), {'actor': actor.pk})
+ self.assertEqual(2, len(resp.data))
+
+ resp = self.client.get(self.api_url(), {'actor': 'foo-bar'})
+ self.assertEqual(0, len(resp.data))
+
+ def test_list_filter_actor_version_1_1(self):
+ """Filter events by actor using API v1.1."""
+ events = self._create_events()
+
+ # we still see all the events since the actor field is ignored
+ resp = self.client.get(self.api_url(version='1.1'),
+ {'actor': 'foo-bar'})
+ self.assertEqual(len(events), len(resp.data))
+
def test_order_by_date_default(self):
"""Assert the default ordering is by date descending."""
self._create_events()