Completed
Pull Request — devel (#90)
by Paolo
06:31
created

biosample.tests.test_async_biosample   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 123
dl 0
loc 205
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A AsyncBioSamplesTestCase.setUp() 0 18 1
A AsyncBioSamplesTestCase.test_request() 0 24 3
A AsyncBioSamplesTestCase.test_request_with_issues() 0 19 2
A AsyncBioSamplesTestCase.setUpClass() 0 7 1
A AsyncBioSamplesTestCase.tearDownClass() 0 6 1
A PurgeOrphanSampleTestCase.test_purge_orphan_samples() 0 28 2
A PurgeOrphanSampleTestCase.test_purge_orphan_samples_ignore() 0 8 1
A PurgeOrphanSampleTestCase.test_purge_orphan_samples_not_ready() 0 8 1
A PurgeOrphanSampleTestCase.test_purge_orphan_samples_removed() 0 8 1
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Tue Jan 21 10:54:09 2020
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import os
10
import json
11
import types
12
import asynctest
13
14
from aioresponses import aioresponses
15
from django.test import TestCase
16
from unittest.mock import patch, Mock
17
18
from common.constants import BIOSAMPLE_URL, SUBMITTED
19
from uid.models import Animal as UIDAnimal, Sample as UIDSample
20
21
from ..tasks.cleanup import check_samples, get_orphan_samples
22
from ..models import OrphanSample, ManagedTeam
23
24
from .common import generate_token, BioSamplesMixin
25
26
# get my path
27
dir_path = os.path.dirname(os.path.realpath(__file__))
28
29
# define data path
30
DATA_PATH = os.path.join(dir_path, "data")
31
32
33
with open(os.path.join(DATA_PATH, "page_0.json")) as handle:
34
    page0 = handle.read()
35
36
with open(os.path.join(DATA_PATH, "page_1.json")) as handle:
37
    page1 = handle.read()
38
39
with open(os.path.join(DATA_PATH, "issue_page1.json")) as handle:
40
    issue_page1 = handle.read()
41
42
43
class AsyncBioSamplesTestCase(asynctest.TestCase, TestCase):
44
45
    fixtures = [
46
        'biosample/managedteam',
47
        'uid/animal',
48
        'uid/dictbreed',
49
        'uid/dictcountry',
50
        'uid/dictrole',
51
        'uid/dictsex',
52
        'uid/dictspecie',
53
        'uid/dictstage',
54
        'uid/dictuberon',
55
        'uid/ontology',
56
        'uid/organization',
57
        'uid/publication',
58
        'uid/sample',
59
        'uid/submission',
60
        'uid/user'
61
    ]
62
63
    @classmethod
64
    def setUpClass(cls):
65
        # calling my base class setup
66
        super().setUpClass()
67
68
        cls.mock_auth_patcher = patch('pyUSIrest.auth.requests.get')
69
        cls.mock_auth = cls.mock_auth_patcher.start()
70
71
    @classmethod
72
    def tearDownClass(cls):
73
        cls.mock_auth_patcher.stop()
74
75
        # calling base method
76
        super().tearDownClass()
77
78
    def setUp(self):
79
        # calling my base setup
80
        super().setUp()
81
82
        # well, updating data and set two biosample ids. Those are not
83
        # orphans
84
        animal = UIDAnimal.objects.get(pk=1)
85
        animal.biosample_id = "SAMEA6376980"
86
        animal.save()
87
88
        sample = UIDSample.objects.get(pk=1)
89
        sample.biosample_id = "SAMEA6376982"
90
        sample.save()
91
92
        # generate tocken
93
        self.mock_auth.return_value = Mock()
94
        self.mock_auth.return_value.text = generate_token()
95
        self.mock_auth.return_value.status_code = 200
96
97
    async def test_request(self) -> None:
98
        with aioresponses() as mocked:
99
            mocked.get(
100
                '{url}?filter=attr:project:IMAGE&size=20'.format(
101
                    url=BIOSAMPLE_URL),
102
                status=200,
103
                body=page0)
104
            mocked.get(
105
                '{url}?filter=attr:project:IMAGE&page=1&size=20'.format(
106
                    url=BIOSAMPLE_URL),
107
                status=200,
108
                body=page1)
109
110
            await check_samples()
111
112
            # get accessions
113
            reference = ['SAMEA6376991', 'SAMEA6376992']
114
115
            self.assertEqual(OrphanSample.objects.count(), 2)
116
117
            # check objects into UID
118
            for accession in reference:
119
                qs = OrphanSample.objects.filter(biosample_id=accession)
120
                self.assertTrue(qs.exists())
121
122
    async def test_request_with_issues(self) -> None:
123
        """Test a temporary issue with BioSamples reply"""
124
125
        with aioresponses() as mocked:
126
            mocked.get(
127
                '{url}?filter=attr:project:IMAGE&size=20'.format(
128
                    url=BIOSAMPLE_URL),
129
                status=200,
130
                body=page0)
131
            mocked.get(
132
                '{url}?filter=attr:project:IMAGE&page=1&size=20'.format(
133
                    url=BIOSAMPLE_URL),
134
                status=200,
135
                body=issue_page1)
136
137
            await check_samples()
138
139
            # no objects where tracked since issue in response
140
            self.assertEqual(OrphanSample.objects.count(), 0)
141
142
143
class PurgeOrphanSampleTestCase(BioSamplesMixin, TestCase):
144
    fixtures = [
145
        'biosample/managedteam',
146
        'biosample/orphansample',
147
        'uid/dictspecie',
148
    ]
149
150
    def test_purge_orphan_samples(self):
151
        """Test biosample data conversion"""
152
153
        with open(os.path.join(DATA_PATH, "SAMEA6376982.json")) as handle:
154
            data = json.load(handle)
155
156
        self.mock_get.return_value = Mock()
157
        self.mock_get.return_value.json.return_value = data
158
        self.mock_get.return_value.status_code = 200
159
160
        # call my method
161
        samples = get_orphan_samples()
162
163
        # teams is now a generator
164
        self.assertIsInstance(samples, types.GeneratorType)
165
        samples = list(samples)
166
167
        self.assertEqual(len(samples), 2)
168
169
        sample = samples[0]
170
        self.assertIsInstance(sample, dict)
171
172
        sample = samples[1]
173
        self.assertIsInstance(sample, dict)
174
175
        # read the team from data
176
        team = sample['team']
177
        self.assertIsInstance(team, ManagedTeam)
178
179
    def test_purge_orphan_samples_not_ready(self):
180
        """Test not ready orphan samples"""
181
182
        # Simulate a different status
183
        OrphanSample.objects.update(status=SUBMITTED)
184
        orphan_count = sum(1 for orphan in get_orphan_samples())
185
186
        self.assertEqual(orphan_count, 0)
187
188
    def test_purge_orphan_samples_ignore(self):
189
        """Test ignored orphan samples"""
190
191
        # Ignoring samples gives no object
192
        OrphanSample.objects.update(ignore=True)
193
        orphan_count = sum(1 for orphan in get_orphan_samples())
194
195
        self.assertEqual(orphan_count, 0)
196
197
    def test_purge_orphan_samples_removed(self):
198
        """Test removed orphan samples"""
199
200
        # Ignoring samples gives no object
201
        OrphanSample.objects.update(removed=True)
202
        orphan_count = sum(1 for orphan in get_orphan_samples())
203
204
        self.assertEqual(orphan_count, 0)
205