14
14
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
from model_mommy import mommy
17
from model_mommy.recipe import Recipe, seq
17
18
from ci_utils.tastypie.test import TastypieTestCase
18
from ticket.models import (Artifact, SourcePackageUpload, SubTicket,
19
from project.models import SourcePackage
20
from ticket.models import (TicketArtifact, SourcePackageUpload, SubTicket,
19
21
SubTicketWorkflowStep, SubTicketWorkflowStepStatus,
20
Ticket, TicketWorkflowStep,
22
Ticket, TicketWorkflowStep, SubTicketArtifact,
21
23
TicketWorkflowStepStatus)
24
from project.models import BinaryPackage
27
def create_ticket(added=None, removed=None):
28
return mommy.make('Ticket', removed_binaries=removed, added_binaries=added)
31
sourcepackage_recipe = Recipe(SourcePackage, name=seq('foobar'))
24
34
class APICreateTicketResourceTest(TastypieTestCase):
27
37
super(APICreateTicketResourceTest, self).setUp('/api/v1')
28
self.ticket = mommy.make('Ticket')
38
self.ticket = create_ticket()
29
39
self.resource = 'ticket/'
30
40
self.detail_url = self.resource + '{0}/'.format(self.ticket.pk)
31
41
self.post_ticket_data = {
152
164
self.assertHttpMethodNotAllowed(resp)
155
class APICreateArtifactResourceTest(TastypieTestCase):
158
super(APICreateArtifactResourceTest, self).setUp('/api/v1')
159
self.subticket = mommy.make('SubTicket')
160
self.artifact = mommy.make('Artifact', subticket=self.subticket)
161
self.resource = 'artifact/'
167
class APICreateTicketArtifactResourceTest(TastypieTestCase):
170
super(APICreateTicketArtifactResourceTest, self).setUp('/api/v1')
171
self.ticket = mommy.make('Ticket')
172
self.artifact = mommy.make('TicketArtifact',
174
self.resource = 'ticketartifact/'
175
self.detail_url = self.resource + '{0}/'.format(self.artifact.pk)
176
self.ticket_uri = '/api/v1/ticket/{0}/'.format(self.ticket.pk)
177
self.post_artifact_data_ticket = {
179
'name': 'my_artifact',
180
'ticket': self.ticket_uri,
181
'reference': 'http://www.example.com/m1CTLg5FHY',
184
def test_post_artifact_ticket(self):
186
Test creating an artifact for a ticket via the API
188
# Check how many are there first.
189
self.assertEqual(TicketArtifact.objects.count(), 1)
190
self.post(resource=self.resource,
191
params=self.post_artifact_data_ticket)
192
# Verify a new one has been added.
193
self.assertEqual(TicketArtifact.objects.count(), 2)
195
def test_patch_detail(self):
196
# Grab the current data & modify it slightly.
197
original_data = self.getResource(self.detail_url)
198
new_data = original_data.copy()
199
new_data['name'] = 'my_upload'
201
self.assertEqual(TicketArtifact.objects.count(), 1)
202
resp = self.client.patch('/api/v1/' + self.detail_url, data=new_data)
203
self.assertHttpMethodNotAllowed(resp)
204
# Make sure the count hasn't changed & we did an update.
205
self.assertEqual(TicketArtifact.objects.count(), 1)
206
# Check for updated data.
207
self.assertEqual(TicketArtifact.objects.get(
208
pk=self.artifact.pk).name, self.artifact.name)
210
def test_delete_artifact_not_allowed(self):
211
resp = self.delete(resource=self.detail_url)
212
self.assertHttpMethodNotAllowed(resp)
215
class APICreateSubTicketArtifactResourceTest(TastypieTestCase):
218
super(APICreateSubTicketArtifactResourceTest, self).setUp('/api/v1')
219
self.sourcepackage = sourcepackage_recipe.make()
220
self.spu = mommy.make('SourcePackageUpload',
221
sourcepackage=self.sourcepackage)
222
self.ticket = mommy.make('Ticket')
223
self.subticket = mommy.make('SubTicket', ticket=self.ticket,
224
source_package_upload=self.spu)
225
self.artifact = mommy.make('SubTicketArtifact',
226
subticket=self.subticket)
227
self.resource = 'subticketartifact/'
162
228
self.detail_url = self.resource + '{0}/'.format(self.artifact.pk)
163
229
self.subticket_uri = '/api/v1/subticket/{0}/'.format(self.subticket.pk)
164
self.post_artifact_data = {
230
self.post_artifact_data_subticket = {
166
232
'name': 'my_artifact',
167
233
'subticket': self.subticket_uri,
168
'reference': 'm1CTLg5FHY',
234
'reference': 'http://www.example.com/m1CTLg5FHY',
171
def test_post_artifact(self):
237
def test_post_artifact_subticket(self):
239
Test creating an artifact for a subticket via the API
172
241
# Check how many are there first.
173
self.assertEqual(Artifact.objects.count(), 1)
174
self.post(resource=self.resource, params=self.post_artifact_data)
242
self.assertEqual(SubTicketArtifact.objects.count(), 1)
243
self.post(resource=self.resource,
244
params=self.post_artifact_data_subticket)
175
245
# Verify a new one has been added.
176
self.assertEqual(Artifact.objects.count(), 2)
246
self.assertEqual(SubTicketArtifact.objects.count(), 2)
178
248
def test_patch_detail(self):
179
249
# Grab the current data & modify it slightly.
201
271
super(APIUpdateTicketStatuses, self).setUp('/api/v1')
202
self.ticket = mommy.make('Ticket')
203
self.ticket_detail_url = 'updateticketstatus/{0}/'.format(self.ticket.pk)
272
mommy.make('BinaryPackage', name='binary3')
273
mommy.make('BinaryPackage', name='binary4')
274
mommy.make('BinaryPackage', name='binary5')
275
self.ticket = create_ticket(added='binary1,binary2,binary6',
276
removed='binary3,binary4')
277
self.ticket_detail_url = 'updateticketstatus/{0}/'.format(
205
280
def test_patch_ticket_status(self):
207
'current_workflow_step': int(TicketWorkflowStep.IMAGE_BUILDING),
208
'status': int(TicketWorkflowStepStatus.IMAGE_BUILDING_COMPLETED),
282
'current_workflow_step': str(
283
TicketWorkflowStep.IMAGE_BUILDING.value),
285
TicketWorkflowStepStatus.IMAGE_BUILDING_COMPLETED.value),
210
287
self.assertEqual(Ticket.objects.count(), 1)
211
self.patch('/api/v1/' + self.ticket_detail_url,
288
self.assertEqual(BinaryPackage.objects.count(), 3)
289
binaries = BinaryPackage.objects.all()
290
self.assertQuerysetEqual(binaries,
291
["<BinaryPackage: binary3>",
292
"<BinaryPackage: binary4>",
293
"<BinaryPackage: binary5>"], ordered=False)
294
self.patch('/api/v1/' + self.ticket_detail_url, new_data)
213
295
# Make sure the count hasn't changed & we did an update.
214
296
self.assertEqual(Ticket.objects.count(), 1)
215
297
# Check for updated data.
298
self.assertEqual(BinaryPackage.objects.count(), 3)
299
binaries = BinaryPackage.objects.all()
300
self.assertQuerysetEqual(binaries,
301
["<BinaryPackage: binary3>",
302
"<BinaryPackage: binary4>",
303
"<BinaryPackage: binary5>"], ordered=False)
216
304
self.assertEqual(Ticket.objects.get(
217
305
pk=self.ticket.pk).current_workflow_step,
218
306
int(TicketWorkflowStep.IMAGE_BUILDING))
220
308
Ticket.objects.get(pk=self.ticket.pk).status,
221
309
int(TicketWorkflowStepStatus.IMAGE_BUILDING_COMPLETED))
311
def test_update_ticket_status_complete(self):
313
"current_workflow_step": TicketWorkflowStep.COMPLETED.value,
314
"status": TicketWorkflowStepStatus.COMPLETED.value,
316
self.assertEqual(Ticket.objects.count(), 1)
317
self.assertEqual(BinaryPackage.objects.count(), 3)
318
binaries = BinaryPackage.objects.all()
319
self.assertQuerysetEqual(binaries,
320
["<BinaryPackage: binary3>",
321
"<BinaryPackage: binary4>",
322
"<BinaryPackage: binary5>"], ordered=False)
323
self.assertEqual(Ticket.objects.get(
324
pk=self.ticket.pk).current_workflow_step,
325
self.ticket.current_workflow_step)
326
self.assertEqual(Ticket.objects.get(
327
pk=self.ticket.pk).status,
329
self.patch('/api/v1/' + self.ticket_detail_url, new_data)
330
self.assertEqual(Ticket.objects.count(), 1)
331
self.assertEqual(BinaryPackage.objects.count(), 4)
332
binaries = BinaryPackage.objects.all()
333
self.assertQuerysetEqual(binaries,
334
["<BinaryPackage: binary1>",
335
"<BinaryPackage: binary2>",
336
"<BinaryPackage: binary5>",
337
"<BinaryPackage: binary6>"], ordered=False)
338
self.assertEqual(Ticket.objects.get(
339
pk=self.ticket.pk).current_workflow_step,
340
int(TicketWorkflowStep.COMPLETED))
341
self.assertEqual(Ticket.objects.get(
342
pk=self.ticket.pk).status,
343
int(TicketWorkflowStepStatus.COMPLETED))
345
def test_update_ticket_status_failed(self):
346
'''Ensure we fail a ticket properly
348
Let's not assume users of this API will update the ticket-status to
349
failed when a workflow step fails. Ensure the API corrects this for
353
"current_workflow_step": str(TicketWorkflowStep.COMPLETED.value),
354
"status": TicketWorkflowStepStatus.PKG_BUILDING_FAILED.value,
356
self.assertEqual(Ticket.objects.count(), 1)
357
self.assertEqual(Ticket.objects.get(
358
pk=self.ticket.pk).current_workflow_step,
359
self.ticket.current_workflow_step)
360
self.assertEqual(Ticket.objects.get(
361
pk=self.ticket.pk).status,
363
self.patch('/api/v1/' + self.ticket_detail_url, new_data)
364
self.assertEqual(Ticket.objects.count(), 1)
365
self.assertEqual(Ticket.objects.get(
366
pk=self.ticket.pk).current_workflow_step,
367
int(TicketWorkflowStep.FAILED))
368
self.assertEqual(Ticket.objects.get(
369
pk=self.ticket.pk).status,
370
int(TicketWorkflowStepStatus.PKG_BUILDING_FAILED))
372
def test_try_adding_binary_already_in_list(self):
374
Test what happens when a ticket attempts to add a binary to the master
375
list that is already in the master list
378
"current_workflow_step": TicketWorkflowStep.COMPLETED.value,
379
"status": TicketWorkflowStepStatus.COMPLETED.value,
381
self.ticket_2 = create_ticket(added='binary1,binary2,binary3')
382
self.assertEqual(Ticket.objects.count(), 2)
383
self.assertEqual(BinaryPackage.objects.count(), 3)
384
binaries = BinaryPackage.objects.all()
385
self.assertQuerysetEqual(binaries,
386
["<BinaryPackage: binary3>",
387
"<BinaryPackage: binary4>",
388
"<BinaryPackage: binary5>"], ordered=False)
389
self.client.patch('/api/v1/updateticketstatus/{0}/'.format(
390
self.ticket_2.pk), data=new_data)
391
self.assertEqual(BinaryPackage.objects.count(), 5)
392
binaries = BinaryPackage.objects.all()
393
self.assertQuerysetEqual(binaries,
394
["<BinaryPackage: binary1>",
395
"<BinaryPackage: binary2>",
396
"<BinaryPackage: binary3>",
397
"<BinaryPackage: binary4>",
398
"<BinaryPackage: binary5>"], ordered=False)
400
def test_try_removing_binary_not_in_list(self):
402
Test what happens when a ticket attempts to remove a binary from the
403
master list when it isn't in the master list
406
"current_workflow_step": TicketWorkflowStep.COMPLETED.value,
407
"status": TicketWorkflowStepStatus.COMPLETED.value,
409
self.ticket_2 = create_ticket(removed='binary2,binary3')
410
self.assertEqual(Ticket.objects.count(), 2)
411
self.assertEqual(BinaryPackage.objects.count(), 3)
412
binaries = BinaryPackage.objects.all()
413
self.assertQuerysetEqual(binaries,
414
["<BinaryPackage: binary3>",
415
"<BinaryPackage: binary4>",
416
"<BinaryPackage: binary5>"], ordered=False)
417
self.client.patch('/api/v1/updateticketstatus/{0}/'.format(
418
self.ticket_2.pk), data=new_data)
419
binaries = BinaryPackage.objects.all()
420
self.assertEqual(BinaryPackage.objects.count(), 2)
421
self.assertQuerysetEqual(binaries,
422
["<BinaryPackage: binary4>",
423
"<BinaryPackage: binary5>"], ordered=False)
425
def test_update_ticket_status_complete_404(self):
427
Test trying to complete the status of a ticket that doesn't exist
430
"current_workflow_step": str(TicketWorkflowStep.COMPLETED.value),
431
"status": str(TicketWorkflowStepStatus.COMPLETED.value),
433
self.assertEqual(Ticket.objects.count(), 1)
434
self.assertEqual(BinaryPackage.objects.count(), 3)
435
binaries = BinaryPackage.objects.all()
436
self.assertQuerysetEqual(binaries,
437
["<BinaryPackage: binary3>",
438
"<BinaryPackage: binary4>",
439
"<BinaryPackage: binary5>"], ordered=False)
440
self.assertEqual(Ticket.objects.get(
441
pk=self.ticket.pk).current_workflow_step,
442
self.ticket.current_workflow_step)
443
self.assertEqual(Ticket.objects.get(
444
pk=self.ticket.pk).status,
446
resp = self.client.patch('updateticketstatus/17394/', data=new_data)
447
self.assertEqual(Ticket.objects.count(), 1)
448
self.assertEqual(BinaryPackage.objects.count(), 3)
449
binaries = BinaryPackage.objects.all()
450
self.assertQuerysetEqual(binaries,
451
["<BinaryPackage: binary3>",
452
"<BinaryPackage: binary4>",
453
"<BinaryPackage: binary5>"], ordered=False)
454
self.assertEqual(resp.status_code, 404)
456
def test_delete_ticket_not_allowed(self):
457
resp = self.delete(resource=self.ticket_detail_url)
458
self.assertHttpMethodNotAllowed(resp)
224
461
class APIUpdateSubTicketStatuses(TastypieTestCase):
227
464
super(APIUpdateSubTicketStatuses, self).setUp('/api/v1')
228
self.subticket = mommy.make('SubTicket')
465
self.sourcepackage = sourcepackage_recipe.make()
466
self.spu = mommy.make('SourcePackageUpload',
467
sourcepackage=self.sourcepackage)
468
self.subticket = mommy.make('SubTicket',
469
source_package_upload=self.spu)
229
470
self.subticket_detail_url = (
230
471
'updatesubticketstatus/{0}/'.format(self.subticket.pk))