Completed
Pull Request — master (#44)
by Paolo
11:03 queued 04:44
created

biosample.tests.common.BaseMixin.setUp()   A

Complexity

Conditions 1

Size

Total Lines 55
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 55
rs 9.28
c 0
b 0
f 0
cc 1
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Mon Jan 21 15:15:09 2019
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import redis
10
import python_jwt
11
12
from billiard.einfo import ExceptionInfo
13
from unittest.mock import patch, PropertyMock
14
15
from django.core import mail
16
from django.conf import settings
17
from django.db.models import Q
18
from django.utils import timezone
19
20
from common.constants import READY, ERROR, WAITING
21
from common.tests import PersonMixinTestCase, WebSocketMixin
22
from image_app.models import Submission, Person, Name
23
24
25
def generate_token(now=None, domains=['subs.test-team-1']):
26
    """A function to generate a 'fake' token"""
27
28
    if not now:
29
        now = int(timezone.now().timestamp())
30
31
    claims = {
32
        'iss': 'https://explore.aai.ebi.ac.uk/sp',
33
        'iat': now,
34
        'exp': now+3600,
35
        'sub': 'usr-f1801430-51e1-4718-8fca-778887087bad',
36
        'email': '[email protected]',
37
        'nickname': 'foo',
38
        'name': 'Foo Bar',
39
        'domains': domains
40
    }
41
42
    return python_jwt.generate_jwt(
43
        claims,
44
        algorithm='RS256')
45
46
47
class BaseMixin(PersonMixinTestCase):
48
    # an attribute for PersonMixinTestCase
49
    person = Person
50
51
    fixtures = [
52
        'biosample/account',
53
        'biosample/managedteam',
54
        'image_app/animal',
55
        'image_app/dictbreed',
56
        'image_app/dictcountry',
57
        'image_app/dictrole',
58
        'image_app/dictsex',
59
        'image_app/dictspecie',
60
        'image_app/dictstage',
61
        'image_app/dictuberon',
62
        'image_app/name',
63
        'image_app/ontology',
64
        'image_app/organization',
65
        'image_app/publication',
66
        'image_app/sample',
67
        'image_app/submission',
68
        'image_app/user'
69
    ]
70
71
    def setUp(self):
72
        # calling my base class setup
73
        super().setUp()
74
75
        # track submission ID
76
        self.submission_id = 1
77
78
        # get a submission object
79
        self.submission_obj = Submission.objects.get(pk=self.submission_id)
80
81
        # set a status which I can submit (equal as calling submit by view)
82
        self.submission_obj.status = WAITING
83
        self.submission_obj.message = "Waiting for biosample submission"
84
        self.submission_obj.save()
85
86
        # get the names I want to submit
87
        self.name_qs = Name.objects.filter(
88
            Q(animal__isnull=False) | Q(sample__isnull=False),
89
            submission=self.submission_obj)
90
91
        # set status for names, like validation does. Update only animal
92
        # and sample names (excluding unkwnon animals)
93
        self.name_qs.update(status=READY)
94
95
        # count number of names in UID for such submission (exclude
96
        # unknown animals)
97
        self.n_to_submit = self.name_qs.count()
98
99
        # starting mocked objects
100
        self.mock_root_patcher = patch('pyUSIrest.client.Root')
101
        self.mock_root = self.mock_root_patcher.start()
102
103
        # start root object
104
        self.my_root = self.mock_root.return_value
105
106
        # mocking chain
107
        self.my_team = self.my_root.get_team_by_name.return_value
108
        self.my_team.name = "subs.test-team-1"
109
110
        # mocking a new submission
111
        self.new_submission = self.my_team.create_submission.return_value
112
        self.new_submission.name = "new-submission"
113
114
        # set status. Because of the way mock attributes are stored you can’t
115
        # directly attach a PropertyMock to a mock object. Instead you can
116
        # attach it to the mock type object:
117
        self.new_submission.propertymock = PropertyMock(return_value='Draft')
118
        type(self.new_submission).status = self.new_submission.propertymock
119
120
        # mocking get_submission_by_name
121
        self.my_submission = self.my_root.get_submission_by_name.return_value
122
        self.my_submission.name = "test-submission"
123
124
        self.my_submission.propertymock = PropertyMock(return_value='Draft')
125
        type(self.my_submission).status = self.my_submission.propertymock
126
127
128
class TaskFailureMixin(WebSocketMixin, BaseMixin):
129 View Code Duplication
    def test_on_failure(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
130
        """Testing on failure methods"""
131
132
        exc = Exception("Test")
133
        task_id = "test_task_id"
134
        args = [self.submission_id]
135
        kwargs = {}
136
        einfo = ExceptionInfo
137
138
        # call on_failure method
139
        self.my_task.on_failure(exc, task_id, args, kwargs, einfo)
140
141
        # check submission status and message
142
        submission = Submission.objects.get(pk=self.submission_id)
143
144
        # check submission.state changed
145
        self.assertEqual(submission.status, ERROR)
146
        self.assertEqual(
147
            submission.message,
148
            "Error in biosample submission: Test")
149
150
        # test email sent
151
        self.assertEqual(len(mail.outbox), 1)
152
153
        # read email
154
        email = mail.outbox[0]
155
156
        self.assertEqual(
157
            "Error in biosample submission %s" % self.submission_id,
158
            email.subject)
159
160
        message = 'Error'
161
        notification_message = 'Error in biosample submission: Test'
162
163
        # calling a WebSocketMixin method
164
        self.check_message(message, notification_message)
165
166
167
class RedisMixin():
168
    """A class to setup a test token in redis database"""
169
170
    # this will be the token key in redis database
171
    submission_key = "token:submission:1:test"
172
173
    @classmethod
174
    def setUpClass(cls):
175
        # calling my base class setup
176
        super().setUpClass()
177
178
        cls.redis = redis.StrictRedis(
179
            host=settings.REDIS_HOST,
180
            port=settings.REDIS_PORT,
181
            db=settings.REDIS_DB)
182
183
        # generate a token
184
        cls.token = generate_token(domains=['subs.test-team-1'])
185
186
        # write token to database
187
        cls.redis.set(cls.submission_key, cls.token, ex=3600)
188
189
    @classmethod
190
    def tearDownClass(cls):
191
        if cls.redis.exists(cls.submission_key):
192
            cls.redis.delete(cls.submission_key)
193
194
        super().tearDownClass()
195