0001-api-add-PATCH-action-on-event-endpoint-57305.patch
chrono/api/urls.py | ||
---|---|---|
44 | 44 |
views.recurring_events_list, |
45 | 45 |
name='api-agenda-recurring-events', |
46 | 46 |
), |
47 | 47 |
url( |
48 | 48 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/recurring-events/fillslots/$', |
49 | 49 |
views.recurring_fillslots, |
50 | 50 |
name='api-recurring-fillslots', |
51 | 51 |
), |
52 |
url( |
|
53 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/status/$', |
|
54 |
views.event_status, |
|
55 |
name='api-event-status', |
|
56 |
), |
|
52 | 57 |
url( |
53 | 58 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/status/(?P<event_identifier>[\w:-]+)/$', |
54 | 59 |
views.event_status, |
55 | 60 |
name='api-event-status', |
56 | 61 |
), |
57 | 62 |
url( |
58 | 63 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/bookings/(?P<event_identifier>[\w:-]+)/$', |
59 | 64 |
views.event_bookings, |
60 | 65 |
name='api-event-bookings', |
61 | 66 |
), |
62 | 67 |
url( |
63 | 68 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/check/(?P<event_identifier>[\w:-]+)/$', |
64 | 69 |
views.event_check, |
65 | 70 |
name='api-event-check', |
66 | 71 |
), |
67 |
url( |
|
68 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/add-event/$', |
|
69 |
views.agenda_add_event, |
|
70 |
name='api-agenda-add-event', |
|
71 |
), |
|
72 | 72 |
url( |
73 | 73 |
r'^agenda/meetings/(?P<meeting_identifier>[\w-]+)/datetimes/$', |
74 | 74 |
views.meeting_datetimes, |
75 | 75 |
name='api-agenda-meeting-datetimes-legacy', |
76 | 76 |
), |
77 | 77 |
url(r'^agenda/(?P<agenda_identifier>[\w-]+)/meetings/$', views.meeting_list, name='api-agenda-meetings'), |
78 | 78 |
url( |
79 | 79 |
r'^agenda/(?P<agenda_identifier>[\w-]+)/meetings/(?P<meeting_identifier>[\w-]+)/$', |
chrono/api/views.py | ||
---|---|---|
2161 | 2161 |
return Response(response) |
2162 | 2162 | |
2163 | 2163 | |
2164 | 2164 |
resize_booking = ResizeBooking.as_view() |
2165 | 2165 | |
2166 | 2166 | |
2167 | 2167 |
class EventStatus(APIView): |
2168 | 2168 |
permission_classes = (permissions.IsAuthenticated,) |
2169 |
serializer_class = serializers.EventSerializer |
|
2169 | 2170 | |
2170 | 2171 |
def get_object(self, agenda_identifier, event_identifier): |
2171 | 2172 |
try: |
2172 | 2173 |
agenda = Agenda.objects.get(slug=agenda_identifier, kind='events') |
2173 | 2174 |
except Agenda.DoesNotExist: |
2174 | 2175 |
try: |
2175 | 2176 |
# legacy access by agenda id |
2176 | 2177 |
agenda = Agenda.objects.get(pk=agenda_identifier, kind='events') |
... | ... | |
2190 | 2191 |
def get(self, request, agenda_identifier=None, event_identifier=None, format=None): |
2191 | 2192 |
event = self.get_object(agenda_identifier, event_identifier) |
2192 | 2193 |
response = { |
2193 | 2194 |
'err': 0, |
2194 | 2195 |
} |
2195 | 2196 |
response.update(get_event_detail(request, event)) |
2196 | 2197 |
return Response(response) |
2197 | 2198 | |
2199 |
def post(self, request, agenda_identifier=None, format=None): |
|
2200 |
agenda = get_object_or_404(Agenda, slug=agenda_identifier, kind='events') |
|
2201 | ||
2202 |
serializer = self.serializer_class(data=request.data) |
|
2203 |
if not serializer.is_valid(): |
|
2204 |
raise APIError( |
|
2205 |
_('invalid payload'), |
|
2206 |
err_class='invalid payload', |
|
2207 |
errors=serializer.errors, |
|
2208 |
http_status=status.HTTP_400_BAD_REQUEST, |
|
2209 |
) |
|
2210 |
payload = serializer.validated_data |
|
2211 |
event = Event.objects.create(agenda=agenda, **payload) |
|
2212 |
if event.recurrence_days and event.recurrence_end_date: |
|
2213 |
event.create_all_recurrences() |
|
2214 |
return Response({'err': 0, 'data': get_event_detail(request, event)}) |
|
2215 | ||
2216 |
def patch(self, request, agenda_identifier=None, event_identifier=None, format=None): |
|
2217 |
event = self.get_object(agenda_identifier, event_identifier) |
|
2218 |
serializer = self.serializer_class(event, data=request.data, partial=True) |
|
2219 |
if not serializer.is_valid(): |
|
2220 |
raise APIError( |
|
2221 |
_('invalid payload'), |
|
2222 |
err_class='invalid payload', |
|
2223 |
errors=serializer.errors, |
|
2224 |
http_status=status.HTTP_400_BAD_REQUEST, |
|
2225 |
) |
|
2226 |
event = serializer.save() |
|
2227 |
# TODO: manage recurrencies |
|
2228 |
return Response({'err': 0, 'data': get_event_detail(request, event)}) |
|
2229 | ||
2198 | 2230 | |
2199 | 2231 |
event_status = EventStatus.as_view() |
2200 | 2232 | |
2201 | 2233 | |
2202 | 2234 |
class EventCheck(APIView): |
2203 | 2235 |
permission_classes = (permissions.IsAuthenticated,) |
2204 | 2236 | |
2205 | 2237 |
def get_object(self, agenda_identifier, event_identifier): |
... | ... | |
2416 | 2448 |
'series': series, |
2417 | 2449 |
}, |
2418 | 2450 |
'err': 0, |
2419 | 2451 |
} |
2420 | 2452 |
) |
2421 | 2453 | |
2422 | 2454 | |
2423 | 2455 |
bookings_statistics = BookingsStatistics.as_view() |
2424 | ||
2425 | ||
2426 |
class AgendaAddEventView(APIView): |
|
2427 |
permission_classes = (permissions.IsAuthenticated,) |
|
2428 |
serializer_class = serializers.EventSerializer |
|
2429 | ||
2430 |
def post(self, request, agenda_identifier): |
|
2431 |
agenda = get_object_or_404(Agenda, slug=agenda_identifier, kind='events') |
|
2432 | ||
2433 |
serializer = self.serializer_class(data=request.data) |
|
2434 |
if not serializer.is_valid(): |
|
2435 |
raise APIError( |
|
2436 |
_('invalid payload'), |
|
2437 |
err_class='invalid payload', |
|
2438 |
errors=serializer.errors, |
|
2439 |
http_status=status.HTTP_400_BAD_REQUEST, |
|
2440 |
) |
|
2441 |
payload = serializer.validated_data |
|
2442 |
event = Event.objects.create(agenda=agenda, **payload) |
|
2443 |
if event.recurrence_days and event.recurrence_end_date: |
|
2444 |
event.create_all_recurrences() |
|
2445 |
return Response({'err': 0, 'data': get_event_detail(request, event)}) |
|
2446 | ||
2447 | ||
2448 |
agenda_add_event = AgendaAddEventView.as_view() |
tests/api/test_event.py | ||
---|---|---|
156 | 156 |
agenda.save() |
157 | 157 |
app.post('/api/agenda/%s/check/%s/' % (agenda.slug, event.slug), status=404) |
158 | 158 |
agenda.kind = 'virtual' |
159 | 159 |
agenda.save() |
160 | 160 |
app.post('/api/agenda/%s/check/%s/' % (agenda.slug, event.slug), status=404) |
161 | 161 | |
162 | 162 | |
163 | 163 |
def test_add_event(app, user): |
164 |
api_url = '/api/agenda/%s/add-event/' % ('999')
|
|
164 |
api_url = '/api/agenda/%s/status/' % ('999')
|
|
165 | 165 | |
166 | 166 |
# no authentication |
167 | 167 |
resp = app.post(api_url, status=401) |
168 | 168 |
assert resp.json['detail'] == 'Authentication credentials were not provided.' |
169 | 169 | |
170 | 170 |
# wrong password |
171 | 171 |
app.authorization = ('Basic', ('john.doe', 'wrong')) |
172 | 172 |
resp = app.post(api_url, status=401) |
... | ... | |
176 | 176 | |
177 | 177 |
# missing agenda |
178 | 178 |
resp = app.post(api_url, status=404) |
179 | 179 |
assert resp.json['detail'] == 'Not found.' |
180 | 180 | |
181 | 181 |
# using meeting agenda |
182 | 182 |
meeting_agenda = Agenda(label='Foo bar Meeting', kind='meetings') |
183 | 183 |
meeting_agenda.save() |
184 |
api_url = '/api/agenda/%s/add-event/' % (meeting_agenda.slug)
|
|
184 |
api_url = '/api/agenda/%s/status/' % (meeting_agenda.slug)
|
|
185 | 185 |
resp = app.post(api_url, status=404) |
186 | 186 |
assert resp.json['detail'] == 'Not found.' |
187 | 187 | |
188 | 188 |
agenda = Agenda(label='Foo bar') |
189 | 189 |
agenda.maximal_booking_delay = 0 |
190 | 190 |
agenda.save() |
191 |
api_url = '/api/agenda/%s/add-event/' % (agenda.slug)
|
|
191 |
api_url = '/api/agenda/%s/status/' % (agenda.slug)
|
|
192 | 192 | |
193 | 193 |
# missing fields |
194 | 194 |
resp = app.post(api_url, status=400) |
195 | 195 |
assert resp.json['err'] |
196 | 196 |
assert resp.json['errors'] == { |
197 | 197 |
'start_datetime': ['This field is required.'], |
198 | 198 |
'places': ['This field is required.'], |
199 | 199 |
} |
200 |
- |