biosample.tests.test_tasks_submission   A
last analyzed

Complexity

Total Complexity 42

Size/Duplication

Total Lines 781
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 42
eloc 386
dl 0
loc 781
rs 9.0399
c 0
b 0
f 0

39 Methods

Rating   Name   Duplication   Size   Complexity  
A SubmissionHelperTestCase.setUp() 0 16 1
A SubmissionHelperTestCase.test_properties() 0 14 1
A SplitSubmissionTaskTestCase.test_only_samples_in_submission() 0 24 1
A SplitSubmissionMixin.setUp() 0 10 1
A SubmissionHelperTestCase.test_recover_submission_error() 0 21 1
A SubmissionHelperTestCase.test_start_submission() 0 22 1
A SplitSubmissionTaskUpdateTestCase.setUp() 0 8 1
A SplitSubmissionMixin.generic_check() 0 31 2
A SplitSubmissionTaskUpdateTestCase.test_split_submission() 0 8 1
A SplitSubmissionTaskTestCase.test_sample_already_in_submission() 0 11 1
A SplitSubmissionTaskTestCase.test_split_submission() 0 22 1
A SubmissionHelperTestCase.test_read_token() 0 8 1
A SplitSubmissionTaskUpdateTestCase.test_split_submission_issues() 0 16 1
A SubmissionHelperTestCase.test_create_submission() 0 14 1
A SplitSubmissionTaskTestCase.test_split_submission_partial() 0 10 1
A SubmissionHelperTestCase.test_recover_submission() 0 26 1
A SplitSubmissionMixin.tearDown() 0 6 1
A SubmitTaskTestCase.test_unmanaged() 0 13 1
A SubmissionCompleteTaskTestCase.test_unmanaged_exception() 0 19 1
A SubmitTaskTestCase.common_test() 0 20 1
A SubmissionHelperTestCase.test_add_one_sample() 0 14 1
A SubmissionHelperTestCase.test_update_sample() 0 30 2
A SubmissionCompleteTaskTestCase.setUp() 0 14 1
A SubmissionHelperTestCase.test_add_samples_order() 0 23 1
A SubmissionHelperTestCase.test_mark_submission() 0 16 1
A SubmitTaskTestCase.setUp() 0 24 1
A SubmissionCompleteTaskTestCase.test_token_expired() 0 21 1
A SubmissionCompleteTaskTestCase.test_submission_complete() 0 6 1
A SubmissionHelperTestCase.test_read_samples() 0 26 1
A SubmitTaskTestCase.test_submit() 0 9 1
A SubmissionCompleteTaskTestCase.test_error_api_endpoint() 0 19 1
A SubmissionCompleteTaskTestCase.test_empty_submission() 0 13 1
A SubmissionCompleteTaskTestCase.test_error_has_higher_priority() 0 24 1
A SubmitTaskTestCase.test_token_expired() 0 14 1
A SubmissionHelperTestCase.test_create_sample() 0 17 1
A SubmitTaskTestCase.tearDown() 0 8 1
A SubmissionCompleteTaskTestCase.common_check() 0 27 2
A SubmissionHelperTestCase.test_add_samples() 0 14 1
A SubmitTaskTestCase.test_issues_with_api() 0 15 1

How to fix   Complexity   

Complexity

Complex classes like biosample.tests.test_tasks_submission often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Wed Jul 17 10:51:40 2019
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
from pyUSIrest.exceptions import USIConnectionError, TokenExpiredError
10
11
from unittest.mock import patch, PropertyMock, Mock, call
12
13
from django.test import TestCase
14
from django.core import mail
15
16
from common.constants import (
17
    READY, COMPLETED, ERROR, SUBMITTED, WAITING, STATUSES)
18
from uid.models import Submission as UIDSubmission
19
20
from .common import TaskFailureMixin, RedisMixin, BaseMixin
21
from ..models import Submission as USISubmission, SubmissionData
22
from ..tasks.submission import (
23
    SubmissionHelper, SplitSubmissionTask, SubmitTask, SubmissionError,
24
    SubmissionCompleteTask)
25
26
27
class SubmissionFeaturesMixin(BaseMixin):
28
    """Common features for SubmitTask and SubmissionHelper"""
29
30
    # overriding BaseMixin features
31
    fixtures = [
32
        'biosample/account',
33
        'biosample/managedteam',
34
        'biosample/sample',
35
        'biosample/submission',
36
        'biosample/submissiondata',
37
        'uid/animal',
38
        'uid/dictbreed',
39
        'uid/dictcountry',
40
        'uid/dictrole',
41
        'uid/dictsex',
42
        'uid/dictspecie',
43
        'uid/dictstage',
44
        'uid/dictuberon',
45
        'uid/ontology',
46
        'uid/organization',
47
        'uid/publication',
48
        'uid/submission',
49
        'uid/user'
50
    ]
51
52
53
class SplitSubmissionMixin(TaskFailureMixin, BaseMixin):
54
    """Generic stuff for SplitSubmissionTask tests"""
55
56
    def setUp(self):
57
        # call Mixin method
58
        super().setUp()
59
60
        # setting tasks
61
        self.my_task = SplitSubmissionTask()
62
63
        # patching objects
64
        self.mock_chord_patcher = patch('biosample.tasks.submission.chord')
65
        self.mock_chord = self.mock_chord_patcher.start()
66
67
        # other function are not called since chord is patched
68
69
    def tearDown(self):
70
        # stopping mock objects
71
        self.mock_chord_patcher.stop()
72
73
        # calling base object
74
        super().tearDown()
75
76
    def generic_check(self, res, n_of_submission, n_of_submissiondata):
77
        """Generic check for created data
78
79
        Args:
80
            res (str): the task output
81
            n_of_submission (int): number of biosample.models.Submission
82
                created
83
            n_of_submissiondata (int): number or submission data for each
84
                biosample.models.Submission
85
        """
86
87
        # assert a success with data uploading
88
        self.assertEqual(res, "success")
89
90
        # get usi_submission qs
91
        usi_submissions_qs = USISubmission.objects.all()
92
93
        # asserting two biosample.submission data objects
94
        self.assertEqual(usi_submissions_qs.count(), n_of_submission)
95
96
        # assert two data for each submission
97
        for usi_submission in usi_submissions_qs:
98
            self.assertEqual(usi_submission.status, READY)
99
100
            # grab submission data queryset
101
            submission_data_qs = SubmissionData.objects.filter(
102
                submission=usi_submission)
103
            self.assertEqual(submission_data_qs.count(), n_of_submissiondata)
104
105
        # assert mock objects called
106
        self.assertTrue(self.mock_chord.called)
107
108
109
class SplitSubmissionTaskTestCase(SplitSubmissionMixin, TestCase):
110
    # ovverride MAX_SAMPLES in order to split data
111
    @patch('biosample.tasks.submission.MAX_SAMPLES', 2)
112
    def test_split_submission(self):
113
        """Test splitting submission data"""
114
115
        res = self.my_task.run(submission_id=self.submission_id)
116
117
        self.generic_check(res, n_of_submission=2, n_of_submissiondata=2)
118
        self.assertEqual(self.n_to_submit, SubmissionData.objects.count())
119
120
        # now get data by ids, like SubmissionHelper does
121
        submissiondata_qs = SubmissionData.objects.order_by('id')
122
        names = [submissiondata.content_object.name for submissiondata
123
                 in submissiondata_qs.all()]
124
125
        reference = [
126
            "ANIMAL:::ID:::132713",
127
            "ANIMAL:::ID:::mother",
128
            "ANIMAL:::ID:::son",
129
            "Siems_0722_393449",
130
        ]
131
132
        self.assertEqual(names, reference)
133
134
    # ovverride MAX_SAMPLES in order to split data
135
    @patch('biosample.tasks.submission.MAX_SAMPLES', 2)
136
    def test_split_submission_partial(self):
137
        """Test splitting submission data with some data already submitted"""
138
139
        self.animal_qs.filter(pk=1).update(status=COMPLETED)
140
        self.sample_qs.filter(pk=1).update(status=COMPLETED)
141
142
        res = self.my_task.run(submission_id=self.submission_id)
143
144
        self.generic_check(res, n_of_submission=1, n_of_submissiondata=2)
145
146
    @patch('biosample.tasks.submission.MAX_SAMPLES', 2)
147
    def test_sample_already_in_submission(self):
148
        """Test splitting submission with sample in a opened submission"""
149
150
        # call task once
151
        self.my_task.run(submission_id=self.submission_id)
152
153
        # call a task a second time
154
        res = self.my_task.run(submission_id=self.submission_id)
155
156
        self.generic_check(res, n_of_submission=2, n_of_submissiondata=2)
157
158
    # A very particoular case: I have a submission with only samples,
159
    # since I uploaded a new submission with a new sample
160
    @patch('biosample.tasks.submission.MAX_SAMPLES', 2)
161
    def test_only_samples_in_submission(self):
162
        """Simulate a submission with samples only"""
163
164
        # this is a very limit case. Create a new uid Submission
165
        self.old_submission_obj = UIDSubmission.objects.get(
166
            pk=self.submission_id)
167
168
        uid_submission = self.submission_obj
169
        uid_submission.pk = None
170
        uid_submission.title = "Updated database"
171
        uid_submission.datasource_version = "Updated database"
172
        uid_submission.save()
173
        uid_submission.refresh_from_db()
174
175
        # now move sample to this new submission
176
        self.sample_qs.filter(pk=1).update(submission=uid_submission)
177
178
        # call task with this submission
179
        res = self.my_task.run(submission_id=uid_submission.id)
180
181
        # assert 1 biosample.models.Submission with 1 SubmissionData
182
        self.generic_check(res, n_of_submission=1, n_of_submissiondata=1)
183
        self.assertEqual(1, SubmissionData.objects.count())
184
185
186
class SplitSubmissionTaskUpdateTestCase(
187
        SubmissionFeaturesMixin, SplitSubmissionMixin, TestCase):
188
    """
189
    A particoular test case: I submit data once and then biosample tell me
190
    that there are errors in submission data. So I mark name with need revision
191
    status and the submission is already opened. I can't send data within a
192
    new submission, I need to restore things and submit the data I have (since
193
    to_biosample() is called on user data when submitting, there are no issues
194
    with old data in biosample.models)"""
195
196
    def setUp(self):
197
        # call Mixin method
198
        super().setUp()
199
200
        # ok in this case, my uid.Samples are READY since I passed validation
201
        # after fail into biosample stage. My biosample.submission will be in
202
        # ERROS or NEED_REVISION since is the last status I saw
203
        USISubmission.objects.update(status=ERROR)
204
205
    # ovverride MAX_SAMPLES in order to split data
206
    @patch('biosample.tasks.submission.MAX_SAMPLES', 2)
207
    def test_split_submission(self):
208
        """Test splitting submission data"""
209
210
        res = self.my_task.run(submission_id=self.submission_id)
211
212
        self.generic_check(res, n_of_submission=2, n_of_submissiondata=2)
213
        self.assertEqual(self.n_to_submit, SubmissionData.objects.count())
214
215
    # ovverride MAX_SAMPLES in order to split data
216
    @patch('biosample.tasks.submission.MAX_SAMPLES', 2)
217
    def test_split_submission_issues(self):
218
        """Test splitting submission data with issues"""
219
220
        # add a new submission data with the same sample, just to test
221
        # exception handling
222
        # https://stackoverflow.com/a/4736172/4385116
223
        submission_data = SubmissionData.objects.get(pk=1)
224
        submission_data.pk = None
225
        submission_data.save()
226
227
        self.assertRaisesRegex(
228
            SubmissionError,
229
            "More than one submission opened",
230
            self.my_task.run,
231
            submission_id=self.submission_id)
232
233
234
class SubmissionHelperTestCase(RedisMixin, SubmissionFeaturesMixin, TestCase):
235
236
    def setUp(self):
237
        # call Mixin method
238
        super().setUp()
239
240
        # set my pk
241
        self.usi_submission_id = 1
242
243
        # Instantiating SubmissionHelper with biosample.submission pk
244
        self.submission_helper = SubmissionHelper(self.usi_submission_id)
245
246
        # get a biosample.submission object
247
        self.usi_submission = USISubmission.objects.get(
248
            pk=self.usi_submission_id)
249
250
        # set attributes with class baseMixin class attributes for semplicity
251
        self.submission_helper.root = self.my_root
252
253
    def test_properties(self):
254
        """Asserting read properties"""
255
256
        owner = self.submission_helper.owner
257
        self.assertEqual(owner.username, "test")
258
259
        team_name = self.submission_helper.team_name
260
        self.assertEqual(team_name, "subs.test-team-1")
261
262
        self.assertIsNone(self.submission_helper.usi_submission_name)
263
        self.submission_helper.usi_submission_name = "test"
264
265
        self.usi_submission.refresh_from_db()
266
        self.assertEqual(self.usi_submission.usi_submission_name, "test")
267
268
    def test_read_token(self):
269
        """testing token from redis DB"""
270
271
        token = self.submission_helper.read_token()
272
        self.assertEqual(self.token, token)
273
274
        # assert called mock objects
275
        self.assertTrue(self.mock_root.called)
276
277
    @patch.object(SubmissionHelper, "read_samples")
278
    def test_recover_submission(self, my_helper):
279
        """Testing submission recover"""
280
281
        # base case: no usi_submission_name so False is expected
282
        self.assertFalse(self.submission_helper.recover_submission())
283
284
        # assign a usi_submission_name
285
        self.submission_helper.usi_submission_name = "test-submission"
286
287
        # asserted final returned status
288
        self.assertTrue(self.submission_helper.recover_submission())
289
290
        # assert a recovered document
291
        self.assertEqual(
292
            "test-submission",
293
            self.submission_helper.usi_submission.name)
294
295
        # assert get_samples called functions called
296
        self.assertTrue(my_helper.called)
297
298
        # asserting others mock objects called
299
        self.assertFalse(self.my_root.get_team_by_name.called)
300
        self.assertFalse(self.my_team.create_submission.called)
301
        self.assertTrue(self.my_root.get_submission_by_name.called)
302
        self.assertTrue(self.my_submission.propertymock.called)
303
304
    def test_recover_submission_error(self):
305
        """Testing submission recover for a closed submission"""
306
307
        # assign a usi_submission_name
308
        self.submission_helper.usi_submission_name = "test-submission"
309
310
        # change submission status
311
        self.my_submission.propertymock = PropertyMock(
312
            return_value='Completed')
313
        type(self.my_submission).status = self.my_submission.propertymock
314
315
        self.assertRaisesRegex(
316
            SubmissionError,
317
            "Cannot recover submission",
318
            self.submission_helper.recover_submission)
319
320
        # asserting others mock objects called
321
        self.assertFalse(self.my_root.get_team_by_name.called)
322
        self.assertFalse(self.my_team.create_submission.called)
323
        self.assertTrue(self.my_root.get_submission_by_name.called)
324
        self.assertTrue(self.my_submission.propertymock.called)
325
326
    def test_create_submission(self):
327
        """Testing submission create"""
328
329
        self.submission_helper.create_submission()
330
331
        # assert a new document
332
        self.assertEqual(
333
            "new-submission",
334
            self.submission_helper.usi_submission.name)
335
336
        # asserting others mock objects called
337
        self.assertTrue(self.my_root.get_team_by_name.called)
338
        self.assertTrue(self.my_team.create_submission.called)
339
        self.assertFalse(self.my_root.get_submission_by_name.called)
340
341
    @patch.object(SubmissionHelper, "create_submission")
342
    @patch.object(SubmissionHelper, "recover_submission")
343
    def test_start_submission(self, my_recover, my_create):
344
        """testing start a submission"""
345
346
        def create_submission():
347
            """Simulate create submission (already tested)"""
348
349
            self.submission_helper.usi_submission = self.new_submission
350
            return self.new_submission
351
352
        my_recover.return_value = False
353
        my_create.side_effect = create_submission
354
355
        usi_submission = self.submission_helper.start_submission()
356
357
        # assert a new document
358
        self.assertEqual("new-submission", usi_submission.name)
359
360
        # assert mock methods called
361
        self.assertTrue(my_recover.called)
362
        self.assertTrue(my_create.called)
363
364
    def test_read_samples(self):
365
366
        # creating mock samples
367
        my_samples = [
368
            Mock(**{'alias': 'IMAGEA000000001',
369
                    'title': 'a 4-year old pig organic fed'}),
370
            Mock(**{'alias': 'IMAGES000000001',
371
                    'title': 'semen collected when the animal turns to 4'}),
372
        ]
373
374
        # Ok but now get samples return an iterator object
375
        my_samples = (sample for sample in my_samples)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable sample does not seem to be defined.
Loading history...
376
377
        # mocking set samples
378
        self.my_submission.get_samples.return_value = my_samples
379
        self.submission_helper.usi_submission = self.my_submission
380
381
        # calling function
382
        submitted_samples = self.submission_helper.read_samples()
383
384
        self.assertIsInstance(submitted_samples, dict)
385
        self.assertEqual(len(submitted_samples), 2)
386
387
        keys = submitted_samples.keys()
388
        self.assertIn('IMAGEA000000001', keys)
389
        self.assertIn('IMAGES000000001', keys)
390
391
    def test_create_sample(self):
392
        # get a model object
393
        submission_data = SubmissionData.objects.get(pk=1)
394
        model = submission_data.content_object
395
396
        # get a biosample submission
397
        self.submission_helper.usi_submission = self.my_submission
398
399
        # add model to biosample submission
400
        self.submission_helper.create_or_update_sample(model)
401
402
        # assert status
403
        self.assertEqual(model.status, SUBMITTED)
404
405
        # testing things
406
        self.assertEqual(
407
            self.my_submission.create_sample.call_count, 1)
408
409
    def test_update_sample(self):
410
        # creating mock samples
411
        my_samples = [
412
            Mock(**{'alias': 'IMAGEA000000001',
413
                    'title': 'a 4-year old pig organic fed'}),
414
        ]
415
416
        # Ok but now get samples return an iterator object
417
        my_samples = (sample for sample in my_samples)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable sample does not seem to be defined.
Loading history...
418
419
        # mocking set samples
420
        self.my_submission.get_samples.return_value = my_samples
421
        self.submission_helper.usi_submission = self.my_submission
422
423
        # read samples through function (already tested)
424
        self.submission_helper.read_samples()
425
426
        # get a model object
427
        submission_data = SubmissionData.objects.get(pk=1)
428
        model = submission_data.content_object
429
430
        # add model to biosample submission
431
        self.submission_helper.create_or_update_sample(model)
432
433
        # assert status
434
        self.assertEqual(model.status, SUBMITTED)
435
436
        # testing patch
437
        for sample in my_samples:
438
            self.assertTrue(sample.patch.called)
439
440
    @patch.object(SubmissionHelper, "create_or_update_sample")
441
    def test_add_one_sample(self, my_create):
442
        """Test adding one sample"""
443
444
        # simulate a submission recover: mark an animal as already submitted
445
        submission_data = SubmissionData.objects.get(pk=1)
446
        submission_data.content_object.status = SUBMITTED
447
        submission_data.content_object.save()
448
449
        # calling method
450
        self.submission_helper.add_samples()
451
452
        # assert create sample in biosample called once
453
        my_create.assert_called_once()
454
455
    @patch.object(SubmissionHelper, "create_or_update_sample")
456
    def test_add_samples(self, my_create):
457
        """Test adding samples in correct order"""
458
459
        # getting submission data an mock called arguments
460
        data = list(self.usi_submission.submission_data.order_by('id'))
461
        data = [call(el.content_object) for el in data]
462
463
        # calling method
464
        self.submission_helper.add_samples()
465
466
        # assert num called and arguments
467
        self.assertEqual(my_create.call_count, 2)
468
        self.assertEqual(my_create.call_args_list, data)
469
470
    @patch.object(SubmissionHelper, "create_or_update_sample")
471
    def test_add_samples_order(self, my_create):
472
        """Test adding samples in different order"""
473
474
        # now create another animal object as a copy of the previous one
475
        # and save it into database,
476
        el = self.usi_submission.submission_data.order_by('id').first()
477
        el.pk = None
478
        el.save()
479
480
        # remove the first and check that order is maintaned
481
        self.usi_submission.submission_data.order_by('id').first().delete()
482
483
        # getting submission data an mock called arguments
484
        data = list(self.usi_submission.submission_data.order_by('id'))
485
        data = [call(el.content_object) for el in data]
486
487
        # calling method
488
        self.submission_helper.add_samples()
489
490
        # assert num called and arguments
491
        self.assertEqual(my_create.call_count, 2)
492
        self.assertEqual(my_create.call_args_list, data)
493
494
    def test_mark_submission(self):
495
        """test adding status message to submission"""
496
497
        self.submission_helper.mark_fail(message="test")
498
499
        self.usi_submission.refresh_from_db()
500
        self.assertEqual(self.usi_submission.status, ERROR)
501
        self.assertEqual(self.usi_submission.message, "test")
502
503
        self.submission_helper.mark_success()
504
505
        self.usi_submission.refresh_from_db()
506
        self.assertEqual(self.usi_submission.status, SUBMITTED)
507
        self.assertEqual(
508
            self.usi_submission.message,
509
            "Waiting for biosample validation")
510
511
512
class SubmitTaskTestCase(SubmissionFeaturesMixin, TestCase):
513
    """Test submission task"""
514
515
    def setUp(self):
516
        # call Mixin method
517
        super().setUp()
518
519
        # setting tasks
520
        self.my_task = SubmitTask()
521
522
        # set my pk
523
        self.usi_submission_id = 1
524
525
        # get a biosample.submission object
526
        self.usi_submission = USISubmission.objects.get(
527
            pk=self.usi_submission_id)
528
529
        # starting mocked objects
530
        self.mock_read_patcher = patch.object(SubmissionHelper, "read_token")
531
        self.mock_read = self.mock_read_patcher.start()
532
533
        self.mock_start_patcher = patch.object(
534
            SubmissionHelper, "start_submission")
535
        self.mock_start = self.mock_start_patcher.start()
536
537
        self.mock_add_patcher = patch.object(SubmissionHelper, "add_samples")
538
        self.mock_add = self.mock_add_patcher.start()
539
540
    def tearDown(self):
541
        # stopping mock objects
542
        self.mock_read_patcher.stop()
543
        self.mock_start_patcher.stop()
544
        self.mock_add_patcher.stop()
545
546
        # calling base object
547
        super().tearDown()
548
549
    def common_test(self, task_result, message, status):
550
        # assert a success with data uploading
551
        self.assertEqual(task_result, ("success", self.usi_submission_id))
552
553
        # check submission status and message
554
        self.usi_submission.refresh_from_db()
555
556
        # check submission.status changed
557
        self.assertEqual(self.usi_submission.status, status)
558
        self.assertIn(message, self.usi_submission.message)
559
560
        # no status changes for UID submission (will callback change status)
561
        self.assertEqual(self.submission_obj.status, WAITING)
562
        self.assertEqual(
563
            self.submission_obj.message,
564
            "Waiting for biosample submission")
565
566
        self.assertTrue(self.mock_read.called)
567
        self.assertTrue(self.mock_start.called)
568
        self.assertTrue(self.mock_add.called)
569
570
    def test_submit(self):
571
        """Test submitting into biosample"""
572
573
        # NOTE that I'm calling the function directly, without delay
574
        # (AsyncResult). I've patched the time consuming task
575
        # Remeber that submission_id will be biosample.models.Submission.id
576
        res = self.my_task.run(usi_submission_id=self.usi_submission_id)
577
578
        self.common_test(res, "Waiting for biosample validation", SUBMITTED)
579
580
    def test_issues_with_api(self):
581
        """Test errors with submission API"""
582
583
        # Set a side effect on the patched methods
584
        # so that they raise the errors we want.
585
        self.mock_add.side_effect = USIConnectionError()
586
587
        # call task. No retries with issues at EBI
588
        res = self.my_task.run(usi_submission_id=self.usi_submission_id)
589
590
        # this is the message I want
591
        message = "Errors in EBI API endpoints. Please try again later"
592
593
        # assert anyway a success
594
        self.common_test(res, message, READY)
595
596
    def test_token_expired(self):
597
        """Testing token expiring during a submission"""
598
599
        # simulating a token expiring during a submission
600
        self.mock_add.side_effect = TokenExpiredError("Your token is expired")
601
602
        # calling task
603
        res = self.my_task.run(usi_submission_id=self.usi_submission_id)
604
605
        message = (
606
            "Your token is expired: please submit again to resume submission")
607
608
        # assert anyway a success
609
        self.common_test(res, message, READY)
610
611
    def test_unmanaged(self):
612
        """Testing unmanaged Exception"""
613
614
        # simulating a token expiring during a submission
615
        self.mock_add.side_effect = Exception("Unmanaged")
616
617
        # calling task
618
        res = self.my_task.run(usi_submission_id=self.usi_submission_id)
619
620
        message = "Exception: Unmanaged"
621
622
        # assert anyway a success
623
        self.common_test(res, message, ERROR)
624
625
626
class SubmissionCompleteTaskTestCase(
627
        SubmissionFeaturesMixin, TaskFailureMixin, BaseMixin, TestCase):
628
629
    """Test class for SubmissionCompleteTask"""
630
631
    def setUp(self):
632
        # call Mixin method
633
        super().setUp()
634
635
        # setting tasks
636
        self.my_task = SubmissionCompleteTask()
637
638
        # these will be the tasks arguments, indipendently by status etc
639
        self.my_tasks_args = ([("success", 1), ("success", 2)], )
640
641
        # update statuses for biosample.models.Submission
642
        USISubmission.objects.update(
643
            status=SUBMITTED,
644
            message='Waiting for biosample validation')
645
646
    def common_check(self, status, message, update_db=True):
647
        """Common check for tests"""
648
649
        # update an object
650
        if update_db:
651
            usi_submission = USISubmission.objects.get(pk=1)
652
            usi_submission.status = status
653
            usi_submission.message = message
654
            usi_submission.save()
655
656
        # calling task
657
        result = self.my_task.run(
658
            *self.my_tasks_args,
659
            uid_submission_id=self.submission_id)
660
661
        # assert a success with data uploading
662
        self.assertEqual(result, "success")
663
664
        # check status and messages
665
        self.submission_obj.refresh_from_db()
666
        self.assertEqual(self.submission_obj.status, status)
667
        self.assertEqual(self.submission_obj.message, message)
668
669
        # calling a WebSocketMixin method
670
        self.check_message(
671
            STATUSES.get_value_display(status),
672
            message)
673
674
    def test_submission_complete(self):
675
        """test no issues after a submission"""
676
677
        self.common_check(
678
            SUBMITTED,
679
            'Waiting for biosample validation')
680
681
    def test_empty_submission(self):
682
        """An empty submission is marked as COMPLETED"""
683
684
        # delete USISubmission objects
685
        USISubmission.objects.all().delete()
686
687
        # updating task args like a result for an empty submission
688
        self.my_tasks_args = ([], )
689
690
        # check status and messages
691
        status = ERROR
692
        message = "Submission %s is empty!" % self.submission_obj
693
        self.common_check(status, message, update_db=False)
694
695
    def test_error_api_endpoint(self):
696
        """test issues with API endpoint"""
697
698
        status = READY
699
        message = "Errors in EBI API endpoints. Please try again later"
700
701
        self.common_check(
702
            status,
703
            message)
704
705
        # test email sent
706
        self.assertEqual(len(mail.outbox), 1)
707
708
        # read email
709
        email = mail.outbox[0]
710
711
        self.assertEqual(
712
            "Temporary error in biosample submission 1",
713
            email.subject)
714
715
    def test_token_expired(self):
716
        """test a token expired during submission"""
717
718
        status = READY
719
        message = (
720
            "Your token is expired: please submit again to resume "
721
            "submission")
722
723
        self.common_check(
724
            status,
725
            message)
726
727
        # test email sent
728
        self.assertEqual(len(mail.outbox), 1)
729
730
        # read email
731
        email = mail.outbox[0]
732
733
        self.assertEqual(
734
            "Temporary error in biosample submission 1",
735
            email.subject)
736
737
    def test_unmanaged_exception(self):
738
        """test an unmanaged exception"""
739
740
        status = ERROR
741
        message = "Exception: Unmanaged"
742
743
        self.common_check(
744
            status,
745
            message)
746
747
        # test email sent
748
        self.assertEqual(len(mail.outbox), 1)
749
750
        # read email
751
        email = mail.outbox[0]
752
753
        self.assertEqual(
754
            "Error in biosample submission 1",
755
            email.subject)
756
757
    def test_error_has_higher_priority(self):
758
        # update an object with a ready status
759
        usi_submission = USISubmission.objects.get(pk=2)
760
        usi_submission.status = READY
761
        usi_submission.message = "a message"
762
        usi_submission.save()
763
764
        # then raise a generi error
765
        status = ERROR
766
        message = "Exception: Unmanaged"
767
768
        self.common_check(
769
            status,
770
            message)
771
772
        # test email sent
773
        self.assertEqual(len(mail.outbox), 1)
774
775
        # read email
776
        email = mail.outbox[0]
777
778
        self.assertEqual(
779
            "Error in biosample submission 1",
780
            email.subject)
781