a b/qiita_db/test/test_study.py
1
from unittest import TestCase, main
2
from datetime import datetime
3
4
from qiita_core.exceptions import IncompetentQiitaDeveloperError
5
from qiita_core.qiita_settings import qiita_config
6
from qiita_core.util import qiita_test_checker
7
import qiita_db as qdb
8
9
# -----------------------------------------------------------------------------
10
# Copyright (c) 2014--, The Qiita Development Team.
11
#
12
# Distributed under the terms of the BSD 3-clause License.
13
#
14
# The full license is in the file LICENSE, distributed with this software.
15
# -----------------------------------------------------------------------------
16
17
18
@qiita_test_checker()
19
class TestStudyPerson(TestCase):
20
    def setUp(self):
21
        self.studyperson = qdb.study.StudyPerson(1)
22
23
    def test_create_studyperson(self):
24
        new = qdb.study.StudyPerson.create(
25
            'SomeDude', 'somedude@foo.bar', 'affil', '111 fake street',
26
            '111-121-1313')
27
        nid = new.id
28
        self.assertEqual(nid, 4)
29
        with qdb.sql_connection.TRN:
30
            qdb.sql_connection.TRN.add("SELECT * FROM qiita.study_person "
31
                                       "WHERE study_person_id = %d" % nid)
32
            obs = qdb.sql_connection.TRN.execute_fetchindex()
33
        self.assertEqual(obs, [[nid, 'SomeDude', 'somedude@foo.bar', 'affil',
34
                         '111 fake street', '111-121-1313']])
35
36
        qdb.study.StudyPerson.delete(nid)
37
38
    def test_delete(self):
39
        with self.assertRaises(qdb.exceptions.QiitaDBError):
40
            qdb.study.StudyPerson.delete(1)
41
42
        obs = qdb.study.StudyPerson.create(
43
            'SomeDude', 'somedude@foo.bar', 'affil', '111 fake street',
44
            '111-121-1313')
45
46
        self.assertTrue(
47
            qdb.study.StudyPerson.exists('SomeDude', 'affil'))
48
        qdb.study.StudyPerson.delete(obs.id)
49
        self.assertFalse(
50
            qdb.study.StudyPerson.exists('SomeDude', 'affil'))
51
52
    def test_retrieve_non_existant_people(self):
53
        with self.assertRaises(qdb.exceptions.QiitaDBLookupError):
54
            qdb.study.StudyPerson.from_name_and_affiliation('Boaty McBoatFace',
55
                                                            'UCSD')
56
57
        p = qdb.study.StudyPerson.from_name_and_affiliation('LabDude',
58
                                                            'knight lab')
59
        self.assertEqual(p.name, 'LabDude')
60
        self.assertEqual(p.affiliation, 'knight lab')
61
        self.assertEqual(p.address, '123 lab street')
62
        self.assertEqual(p.phone, '121-222-3333')
63
        self.assertEqual(p.email, 'lab_dude@foo.bar')
64
65
    def test_iter(self):
66
        """Make sure that each and every StudyPerson is retrieved"""
67
        expected = [
68
            ('LabDude', 'lab_dude@foo.bar', 'knight lab', '123 lab street',
69
             '121-222-3333'),
70
            ('empDude', 'emp_dude@foo.bar', 'broad', None, '444-222-3333'),
71
            ('PIDude', 'PI_dude@foo.bar', 'Wash U', '123 PI street', None)]
72
        for i, person in enumerate(qdb.study.StudyPerson.iter()):
73
            self.assertEqual(person.id, i+1)
74
            self.assertEqual(person.name, expected[i][0])
75
            self.assertEqual(person.email, expected[i][1])
76
            self.assertEqual(person.affiliation, expected[i][2])
77
            self.assertEqual(person.address, expected[i][3])
78
            self.assertEqual(person.phone, expected[i][4])
79
80
    def test_exists(self):
81
        self.assertTrue(qdb.study.StudyPerson.exists('LabDude', 'knight lab'))
82
        self.assertFalse(qdb.study.StudyPerson.exists(
83
            'AnotherDude', 'knight lab'))
84
        self.assertFalse(qdb.study.StudyPerson.exists(
85
            'LabDude', 'Another lab'))
86
87
    def test_create_studyperson_already_exists(self):
88
        obs = qdb.study.StudyPerson.create(
89
            'LabDude', 'lab_dude@foo.bar', 'knight lab')
90
        self.assertEqual(obs.name, 'LabDude')
91
        self.assertEqual(obs.email, 'lab_dude@foo.bar')
92
93
    def test_retrieve_name(self):
94
        self.assertEqual(self.studyperson.name, 'LabDude')
95
96
    def test_set_name_fail(self):
97
        with self.assertRaises(AttributeError):
98
            self.studyperson.name = 'Fail Dude'
99
100
    def test_retrieve_email(self):
101
        self.assertEqual(self.studyperson.email, 'lab_dude@foo.bar')
102
103
    def test_retrieve_affiliation(self):
104
        self.assertEqual(self.studyperson.affiliation, 'knight lab')
105
106
    def test_set_email_fail(self):
107
        with self.assertRaises(AttributeError):
108
            self.studyperson.email = 'faildude@foo.bar'
109
110
    def test_set_affiliation_fail(self):
111
        with self.assertRaises(AttributeError):
112
            self.studyperson.affiliation = 'squire lab'
113
114
    def test_retrieve_address(self):
115
        self.assertEqual(self.studyperson.address, '123 lab street')
116
117
    def test_retrieve_address_null(self):
118
        person = qdb.study.StudyPerson(2)
119
        self.assertEqual(person.address, None)
120
121
    def test_set_address(self):
122
        self.studyperson.address = '123 nonsense road'
123
        self.assertEqual(self.studyperson.address, '123 nonsense road')
124
125
    def test_retrieve_phone(self):
126
        self.assertEqual(self.studyperson.phone, '121-222-3333')
127
128
    def test_retrieve_phone_null(self):
129
        person = qdb.study.StudyPerson(3)
130
        self.assertEqual(person.phone, None)
131
132
    def test_set_phone(self):
133
        self.studyperson.phone = '111111111111111111121'
134
        self.assertEqual(self.studyperson.phone, '111111111111111111121')
135
136
137
@qiita_test_checker()
138
class TestStudy(TestCase):
139
    def setUp(self):
140
        self.study = qdb.study.Study(1)
141
        self.portal = qiita_config.portal
142
143
        self.info = {
144
            "timeseries_type_id": 1,
145
            "metadata_complete": True,
146
            "mixs_compliant": True,
147
            "study_alias": "FCM",
148
            "study_description": "Microbiome of people who eat nothing but "
149
                                 "fried chicken",
150
            "study_abstract": "Exploring how a high fat diet changes the "
151
                              "gut microbiome",
152
            "principal_investigator_id": qdb.study.StudyPerson(3),
153
            "lab_person_id": qdb.study.StudyPerson(1)
154
        }
155
156
        self.infoexp = {
157
            "timeseries_type_id": 1,
158
            "metadata_complete": True,
159
            "mixs_compliant": True,
160
            "study_alias": "FCM",
161
            "study_description": "Microbiome of people who eat nothing but "
162
                                 "fried chicken",
163
            "study_abstract": "Exploring how a high fat diet changes the "
164
                              "gut microbiome",
165
            "principal_investigator": qdb.study.StudyPerson(3),
166
            "lab_person": qdb.study.StudyPerson(1),
167
            'public_raw_download': False
168
        }
169
170
        self.existingexp = {
171
            'mixs_compliant': True,
172
            'metadata_complete': True,
173
            'reprocess': False,
174
            'funding': None,
175
            'vamps_id': None,
176
            'first_contact': datetime(2014, 5, 19, 16, 10),
177
            'principal_investigator': qdb.study.StudyPerson(3),
178
            'timeseries_type_id': 1,
179
            'study_abstract':
180
                "This is a preliminary study to examine the "
181
                "microbiota associated with the Cannabis plant. Soils samples "
182
                "from the bulk soil, soil associated with the roots, and the "
183
                "rhizosphere were extracted and the DNA sequenced. Roots "
184
                "from three independent plants of different strains were "
185
                "examined. These roots were obtained November 11, 2011 from "
186
                "plants that had been harvested in the summer. Future "
187
                "studies will attempt to analyze the soils and rhizospheres "
188
                "from the same location at different time points in the plant "
189
                "lifecycle.",
190
            'spatial_series': False,
191
            'study_description': 'Analysis of the Cannabis Plant Microbiome',
192
            'study_alias': 'Cannabis Soils',
193
            'most_recent_contact': datetime(2014, 5, 19, 16, 11),
194
            'lab_person': qdb.study.StudyPerson(1)}
195
196
    def tearDown(self):
197
        qiita_config.portal = self.portal
198
        self._change_processed_data_status('private')
199
200
    def _change_processed_data_status(self, new_status):
201
        # Change the status of the studies by changing the status of their
202
        # artifacts
203
        id_status = qdb.util.convert_to_id(new_status, 'visibility')
204
        qdb.sql_connection.perform_as_transaction(
205
            "UPDATE qiita.artifact SET visibility_id = %s", (id_status,))
206
207
    def test_from_title(self):
208
        study = qdb.study.Study.from_title(
209
            'Identification of the Microbiomes for Cannabis Soils')
210
        self.assertEqual(study, qdb.study.Study(1))
211
212
        with self.assertRaises(qdb.exceptions.QiitaDBUnknownIDError):
213
            qdb.study.Study.from_title('Study title')
214
215
    def test_get_info(self):
216
        # Test get all info for single study
217
        qiita_config.portal = 'QIITA'
218
        obs = qdb.study.Study.get_info([1])
219
        self.assertEqual(len(obs), 1)
220
        obs = dict(obs[0])
221
        exp = {
222
            'mixs_compliant': True, 'metadata_complete': True,
223
            'reprocess': False, 'timeseries_type': 'None',
224
            'funding': None, 'vamps_id': None, 'public_raw_download': False,
225
            'first_contact': datetime(2014, 5, 19, 16, 10),
226
            'principal_investigator_id': 3, 'timeseries_type_id': 1,
227
            'publications': [{'f1': '10.100/123456', 'f2': True},
228
                             {'f1': '123456', 'f2': False},
229
                             {'f1': '10.100/7891011', 'f2': True},
230
                             {'f1': '7891011', 'f2': False}],
231
            'study_alias': 'Cannabis Soils',
232
            'spatial_series': False, 'notes': '',
233
            'study_abstract': 'This is a preliminary study to examine the '
234
            'microbiota associated with the Cannabis plant. Soils samples from'
235
            ' the bulk soil, soil associated with the roots, and the '
236
            'rhizosphere were extracted and the DNA sequenced. Roots from '
237
            'three independent plants of different strains were examined. '
238
            'These roots were obtained November 11, 2011 from plants that had '
239
            'been harvested in the summer. Future studies will attempt to '
240
            'analyze the soils and rhizospheres from the same location at '
241
            'different time points in the plant lifecycle.',
242
            'study_description': 'Analysis of the Cannabis Plant Microbiome',
243
            'intervention_type': 'None', 'email': 'test@foo.bar',
244
            'study_id': 1,
245
            'most_recent_contact': datetime(2014, 5, 19, 16, 11),
246
            'lab_person_id': 1,
247
            'study_title': 'Identification of the Microbiomes for Cannabis '
248
            'Soils',
249
            'ebi_submission_status': 'submitted',
250
            'ebi_study_accession': 'EBI123456-BB',
251
            'autoloaded': False}
252
        self.assertDictEqual(obs, exp)
253
254
        # Test get specific keys for single study
255
        exp_keys = ['metadata_complete', 'reprocess', 'timeseries_type',
256
                    'publications', 'study_title']
257
        obs = qdb.study.Study.get_info([1], exp_keys)
258
        self.assertEqual(len(obs), 1)
259
        exp = [{
260
            'metadata_complete': True, 'reprocess': False,
261
            'timeseries_type': 'None',
262
            'publications': [{'f1': '10.100/123456', 'f2': True},
263
                             {'f1': '123456', 'f2': False},
264
                             {'f1': '10.100/7891011', 'f2': True},
265
                             {'f1': '7891011', 'f2': False}],
266
            'study_title': 'Identification of the Microbiomes for Cannabis '
267
            'Soils'}]
268
        self.assertEqual(obs, exp)
269
270
        # Test get specific keys for all studies
271
        info = {
272
            'timeseries_type_id': 1,
273
            'lab_person_id': None,
274
            'principal_investigator_id': 3,
275
            'metadata_complete': False,
276
            'mixs_compliant': True,
277
            'study_description': 'desc',
278
            'study_alias': 'alias',
279
            'study_abstract': 'abstract'}
280
        user = qdb.user.User('test@foo.bar')
281
282
        s = qdb.study.Study.create(user, 'test_study_1', info=info)
283
        obs = qdb.study.Study.get_info(info_cols=exp_keys)
284
        exp = [
285
            {'metadata_complete': True, 'reprocess': False,
286
             'timeseries_type': 'None', 'publications': [
287
                {'f1': '10.100/123456', 'f2': True},
288
                {'f1': '123456', 'f2': False},
289
                {'f1': '10.100/7891011', 'f2': True},
290
                {'f1': '7891011', 'f2': False}],
291
             'study_title': ('Identification of the Microbiomes for '
292
                             'Cannabis Soils')},
293
            {'metadata_complete': False, 'reprocess': False,
294
             'timeseries_type': 'None', 'publications': None,
295
             'study_title': 'test_study_1'}]
296
        self.assertEqual(obs, exp)
297
        qdb.study.Study.delete(s.id)
298
299
        # test portal restriction working
300
        qiita_config.portal = 'EMP'
301
        with self.assertRaises(qdb.exceptions.QiitaDBError):
302
            qdb.study.Study.get_info([1])
303
304
    def test_has_access_public(self):
305
        self._change_processed_data_status('public')
306
307
        qiita_config.portal = 'QIITA'
308
        self.assertTrue(
309
            self.study.has_access(qdb.user.User("demo@microbio.me")))
310
        qiita_config.portal = 'EMP'
311
        with self.assertRaises(qdb.exceptions.QiitaDBError):
312
            qdb.study.Study(1).has_access(qdb.user.User("demo@microbio.me"))
313
314
    def test_has_access_no_public(self):
315
        self._change_processed_data_status('public')
316
        self.assertFalse(
317
            self.study.has_access(qdb.user.User("demo@microbio.me"), True))
318
319
    def test_can_edit(self):
320
        self.assertTrue(self.study.can_edit(qdb.user.User('test@foo.bar')))
321
        self.assertTrue(self.study.can_edit(qdb.user.User('shared@foo.bar')))
322
        self.assertTrue(self.study.can_edit(qdb.user.User('admin@foo.bar')))
323
        self.assertFalse(
324
            self.study.can_edit(qdb.user.User('demo@microbio.me')))
325
326
    def test_owner(self):
327
        self.assertEqual(self.study.owner, qdb.user.User("test@foo.bar"))
328
329
    def test_autoloaded(self):
330
        self.assertFalse(self.study.autoloaded)
331
        self.study.autoloaded = True
332
        self.assertTrue(self.study.autoloaded)
333
        self.study.autoloaded = False
334
        self.assertFalse(self.study.autoloaded)
335
336
    def test_public_raw_download(self):
337
        self.assertFalse(self.study.public_raw_download)
338
        self.study.public_raw_download = True
339
        self.assertTrue(self.study.public_raw_download)
340
        self.study.public_raw_download = False
341
        self.assertFalse(self.study.public_raw_download)
342
343
    def test_share(self):
344
        # Clear all sharing associations
345
        self._change_processed_data_status('sandbox')
346
        qdb.sql_connection.perform_as_transaction(
347
            "delete from qiita.study_users")
348
        self.assertEqual(self.study.shared_with, [])
349
350
        # Try to share with the owner, which should not work
351
        self.study.share(qdb.user.User("test@foo.bar"))
352
        self.assertEqual(self.study.shared_with, [])
353
354
        # Then share the study with shared@foo.bar
355
        self.study.share(qdb.user.User("shared@foo.bar"))
356
        self.assertEqual(self.study.shared_with,
357
                         [qdb.user.User("shared@foo.bar")])
358
359
    def test_unshare(self):
360
        self._change_processed_data_status('sandbox')
361
        self.study.unshare(qdb.user.User("shared@foo.bar"))
362
        self.assertEqual(self.study.shared_with, [])
363
364
    def test_has_access_shared(self):
365
        self._change_processed_data_status('sandbox')
366
        self.assertTrue(self.study.has_access(qdb.user.User("shared@foo.bar")))
367
368
    def test_has_access_private(self):
369
        self._change_processed_data_status('sandbox')
370
        self.assertTrue(self.study.has_access(qdb.user.User("test@foo.bar")))
371
372
    def test_has_access_admin(self):
373
        self._change_processed_data_status('sandbox')
374
        self.assertTrue(self.study.has_access(qdb.user.User("admin@foo.bar")))
375
376
    def test_has_access_no_access(self):
377
        self._change_processed_data_status('sandbox')
378
        self.assertFalse(
379
            self.study.has_access(qdb.user.User("demo@microbio.me")))
380
381
    def test_get_by_status(self):
382
        obs = qdb.study.Study.get_by_status('sandbox')
383
        self.assertEqual(obs, set())
384
385
        s = qdb.study.Study.create(
386
            qdb.user.User('test@foo.bar'),
387
            'NOT Identification of the Microbiomes for Cannabis Soils',
388
            self.info)
389
        obs = qdb.study.Study.get_by_status('private')
390
        self.assertEqual(obs, {qdb.study.Study(1)})
391
392
        obs = qdb.study.Study.get_by_status('sandbox')
393
        self.assertEqual(obs, {s})
394
395
        obs = qdb.study.Study.get_by_status('public')
396
        self.assertEqual(obs, set())
397
398
        obs = qdb.study.Study.get_by_status('awaiting_approval')
399
        self.assertEqual(obs, set())
400
401
        qdb.study.Study.delete(s.id)
402
403
    def test_exists(self):
404
        self.assertTrue(qdb.study.Study.exists(
405
            'Identification of the Microbiomes for Cannabis Soils'))
406
        self.assertFalse(qdb.study.Study.exists('Not Cannabis Soils'))
407
408
    def test_create_duplicate(self):
409
        to_test = [
410
            'Identification of the Microbiomes for Cannabis Soils',
411
            'Identification  of  the Microbiomes for Cannabis Soils',
412
            ' Identification of the Microbiomes for Cannabis Soils',
413
            'Identification of the Microbiomes for Cannabis Soils ',
414
            '  Identification of the Microbiomes for Cannabis Soils  '
415
        ]
416
        for tt in to_test:
417
            with self.assertRaises(qdb.exceptions.QiitaDBDuplicateError):
418
                qdb.study.Study.create(
419
                    qdb.user.User('test@foo.bar'), tt, self.info)
420
421
    def test_create_study_min_data(self):
422
        """Insert a study into the database"""
423
        before = datetime.now()
424
        obs = qdb.study.Study.create(
425
            qdb.user.User('test@foo.bar'), "Fried chicken microbiome 1",
426
            self.info)
427
        after = datetime.now()
428
        self.assertEqual(obs.status, 'sandbox')
429
        self.assertEqual(obs.title, "Fried chicken microbiome 1")
430
        obs_info = obs.info
431
        insertion_timestamp = obs_info.pop('first_contact')
432
        exp = {'mixs_compliant': True, 'metadata_complete': True,
433
               'reprocess': False, 'public_raw_download': False,
434
               'funding': None, 'vamps_id': None,
435
               'principal_investigator': qdb.study.StudyPerson(3),
436
               'timeseries_type_id': 1,
437
               'study_abstract': 'Exploring how a high fat diet changes the '
438
                                 'gut microbiome',
439
               'spatial_series': None,
440
               'study_description': 'Microbiome of people who eat nothing but'
441
                                    ' fried chicken',
442
               'study_alias': 'FCM',
443
               'most_recent_contact': None,
444
               'lab_person': qdb.study.StudyPerson(1),
445
               'notes': ''}
446
        self.assertEqual(obs_info, exp)
447
        # Check the timestamp separately, since it is set by the database
448
        # to the microsecond, and we can't predict it a priori
449
        self.assertTrue(before < insertion_timestamp < after)
450
        self.assertEqual(obs.shared_with, [])
451
        self.assertEqual(obs.publications, [])
452
        self.assertEqual(obs.investigation, None)
453
        self.assertEqual(obs.sample_template, None)
454
        self.assertEqual(obs.data_types, [])
455
        self.assertEqual(obs.owner, qdb.user.User('test@foo.bar'))
456
        self.assertEqual(obs.environmental_packages, [])
457
        self.assertEqual(obs._portals, ['QIITA'])
458
        self.assertEqual(obs.ebi_study_accession, None)
459
        self.assertEqual(obs.ebi_submission_status, "not submitted")
460
        qdb.study.Study.delete(obs.id)
461
462
    def test_create_nonqiita_portal(self):
463
        qiita_config.portal = "EMP"
464
        s = qdb.study.Study.create(
465
            qdb.user.User('test@foo.bar'), "NEW!", self.info,
466
            qdb.investigation.Investigation(1))
467
468
        # make sure portal is associated
469
        with qdb.sql_connection.TRN:
470
            qdb.sql_connection.TRN.add(
471
                "SELECT * from qiita.study_portal WHERE study_id = %s", [s.id])
472
            obs = qdb.sql_connection.TRN.execute_fetchindex()
473
        self.assertEqual(obs, [[s.id, 2], [s.id, 1]])
474
        qdb.study.Study.delete(s.id)
475
476
    def test_create_study_with_investigation(self):
477
        """Insert a study into the database with an investigation"""
478
        new = qdb.study.Study.create(
479
            qdb.user.User('test@foo.bar'), "Fried chicken microbiome 2",
480
            self.info, qdb.investigation.Investigation(1))
481
        # check the investigation was assigned
482
        with qdb.sql_connection.TRN:
483
            qdb.sql_connection.TRN.add(
484
                "SELECT * from qiita.investigation_study WHERE study_id = %s",
485
                [new.id])
486
            obs = qdb.sql_connection.TRN.execute_fetchindex()
487
        self.assertEqual(obs, [[1, new.id]])
488
489
        # testing Study.iter()
490
        self.assertCountEqual(list(qdb.study.Study.iter()),
491
                              [qdb.study.Study(1), new])
492
493
        qdb.study.Study.delete(new.id)
494
495
    def test_create_study_all_data(self):
496
        """Insert a study into the database with every info field"""
497
        self.info.update({
498
            'vamps_id': 'MBE_1111111',
499
            'funding': 'FundAgency',
500
            'spatial_series': True,
501
            'metadata_complete': False,
502
            'reprocess': True,
503
            'first_contact': "10/24/2014 12:47PM",
504
            'study_id': 3827,
505
            'notes': 'an analysis was performed \n here and \n here'
506
            })
507
        obs = qdb.study.Study.create(
508
            qdb.user.User('test@foo.bar'), "Fried chicken microbiome 3",
509
            self.info)
510
        self.assertEqual(obs.id, 3827)
511
        self.assertEqual(obs.status, 'sandbox')
512
        self.assertEqual(obs.title, "Fried chicken microbiome 3")
513
        exp = {'mixs_compliant': True, 'metadata_complete': False,
514
               'reprocess': True, 'public_raw_download': False,
515
               'funding': 'FundAgency', 'vamps_id': 'MBE_1111111',
516
               'first_contact': datetime(2014, 10, 24, 12, 47),
517
               'principal_investigator': qdb.study.StudyPerson(3),
518
               'timeseries_type_id': 1,
519
               'study_abstract': 'Exploring how a high fat diet changes the '
520
                                 'gut microbiome',
521
               'spatial_series': True,
522
               'study_description': 'Microbiome of people who eat nothing '
523
                                    'but fried chicken',
524
               'study_alias': 'FCM',
525
               'most_recent_contact': None,
526
               'lab_person': qdb.study.StudyPerson(1),
527
               'notes': 'an analysis was performed \n here and \n here'}
528
        self.assertEqual(obs.info, exp)
529
        self.assertEqual(obs.shared_with, [])
530
        self.assertEqual(obs.publications, [])
531
        self.assertEqual(obs.investigation, None)
532
        self.assertEqual(obs.sample_template, None)
533
        self.assertEqual(obs.data_types, [])
534
        self.assertEqual(obs.owner, qdb.user.User('test@foo.bar'))
535
        self.assertEqual(obs.environmental_packages, [])
536
        self.assertEqual(obs._portals, ['QIITA'])
537
        self.assertEqual(obs.ebi_study_accession, None)
538
        self.assertEqual(obs.ebi_submission_status, "not submitted")
539
540
        # testing Study.iter()
541
        self.assertCountEqual(list(qdb.study.Study.iter()),
542
                              [qdb.study.Study(1), obs])
543
544
        qdb.study.Study.delete(obs.id)
545
546
    def test_create_missing_required(self):
547
        """ Insert a study that is missing a required info key"""
548
        self.info.pop("study_alias")
549
        with self.assertRaises(qdb.exceptions.QiitaDBColumnError):
550
            qdb.study.Study.create(
551
                qdb.user.User('test@foo.bar'), "Fried Chicken Microbiome 4",
552
                self.info)
553
554
    def test_create_study_with_not_allowed_key(self):
555
        """Insert a study with key from _non_info present"""
556
        self.info.update({"email": "wooo@sup.net"})
557
        with self.assertRaises(qdb.exceptions.QiitaDBColumnError):
558
            qdb.study.Study.create(
559
                qdb.user.User('test@foo.bar'), "Fried Chicken Microbiome 6",
560
                self.info)
561
562
    def test_create_unknown_db_col(self):
563
        """ Insert a study with an info key not in the database"""
564
        self.info["SHOULDNOTBEHERE"] = "BWAHAHAHAHAHA"
565
        with self.assertRaises(qdb.exceptions.QiitaDBColumnError):
566
            qdb.study.Study.create(
567
                qdb.user.User('test@foo.bar'), "Fried Chicken Microbiome 7",
568
                self.info)
569
570
    def test_delete(self):
571
        title = "Fried chicken microbiome 8"
572
        # the study is assigned to investigation 1
573
        study = qdb.study.Study.create(
574
            qdb.user.User('test@foo.bar'), title, self.info,
575
            qdb.investigation.Investigation(1))
576
        # sharing with other user
577
        study.share(qdb.user.User("shared@foo.bar"))
578
        study.delete(study.id)
579
        self.assertFalse(study.exists(title))
580
581
        with self.assertRaises(qdb.exceptions.QiitaDBError):
582
            qdb.study.Study.delete(1)
583
584
        with self.assertRaises(qdb.exceptions.QiitaDBUnknownIDError):
585
            qdb.study.Study.delete(41)
586
587
    def test_retrieve_title(self):
588
        self.assertEqual(self.study.title, 'Identification of the Microbiomes'
589
                         ' for Cannabis Soils')
590
591
    def test_set_title(self):
592
        new = qdb.study.Study.create(
593
            qdb.user.User('test@foo.bar'),
594
            'NOT Identification of the Microbiomes for Cannabis Soils 1',
595
            self.info)
596
        new.title = "Cannabis soils"
597
        self.assertEqual(new.title, "Cannabis soils")
598
        qdb.study.Study.delete(new.id)
599
600
    def test_portals(self):
601
        self.assertEqual(self.study._portals, ['QIITA'])
602
603
    def test_ebi_study_accession(self):
604
        self.assertEqual(self.study.ebi_study_accession, 'EBI123456-BB')
605
        new = qdb.study.Study.create(
606
            qdb.user.User('test@foo.bar'),
607
            'NOT Identification of the Microbiomes for Cannabis Soils 4',
608
            self.info)
609
        self.assertEqual(new.ebi_study_accession, None)
610
        qdb.study.Study.delete(new.id)
611
612
    def test_ebi_study_accession_setter(self):
613
        new = qdb.study.Study.create(
614
            qdb.user.User('test@foo.bar'), 'Test', self.info)
615
        self.assertEqual(new.ebi_study_accession, None)
616
        new.ebi_study_accession = 'EBI654321-BB'
617
        self.assertEqual(new.ebi_study_accession, 'EBI654321-BB')
618
619
        # Raises an error if the study already has an EBI study accession
620
        with self.assertRaises(qdb.exceptions.QiitaDBError):
621
            self.study.ebi_study_accession = 'EBI654321-BB'
622
623
        qdb.study.Study.delete(new.id)
624
625
    def test_ebi_submission_status(self):
626
        self.assertEqual(self.study.ebi_submission_status, 'submitted')
627
628
        # let's test that even with a failed job nothing changes
629
        # add a failed job for an artifact (2) that can be submitted
630
        user = qdb.user.User('test@foo.bar')
631
        qp = qdb.software.Software.from_name_and_version('Qiita', 'alpha')
632
        cmd = qp.get_command('submit_to_EBI')
633
        params = qdb.software.Parameters.load(cmd, values_dict={
634
            'artifact': 2, 'submission_type': 'ADD'})
635
        job = qdb.processing_job.ProcessingJob.create(user, params, True)
636
        job._set_error('Killed by Admin')
637
        # and just to be careful add a failed job for an artifact (1) that
638
        # cannot be submitted
639
        qp = qdb.software.Software.from_name_and_version('Qiita', 'alpha')
640
        cmd = qp.get_command('submit_to_EBI')
641
        params = qdb.software.Parameters.load(cmd, values_dict={
642
            'artifact': 1, 'submission_type': 'ADD'})
643
        job = qdb.processing_job.ProcessingJob.create(user, params, True)
644
        job._set_error('Killed by Admin')
645
        # should still return submited
646
        self.assertEqual(self.study.ebi_submission_status, 'submitted')
647
648
        new = qdb.study.Study.create(
649
            qdb.user.User('test@foo.bar'),
650
            'NOT Identification of the Microbiomes for Cannabis Soils 5',
651
            self.info)
652
        self.assertEqual(new.ebi_submission_status, 'not submitted')
653
        qdb.study.Study.delete(new.id)
654
655
    def test_set_info(self):
656
        """Set info in a study"""
657
        newinfo = {
658
            "timeseries_type_id": 2,
659
            "metadata_complete": False,
660
            "lab_person_id": qdb.study.StudyPerson(2),
661
            "vamps_id": 'MBE_111222',
662
            'notes': 'These are my notes!!! \n ... and more notes ...'
663
        }
664
        self.info['first_contact'] = "6/11/2014"
665
        new = qdb.study.Study.create(
666
            qdb.user.User('test@foo.bar'),
667
            'NOT Identification of the Microbiomes for Cannabis Soils 6',
668
            self.info)
669
        self.infoexp.update(newinfo)
670
        new.info = newinfo
671
        # add missing table cols
672
        self.infoexp["funding"] = None
673
        self.infoexp["spatial_series"] = None
674
        self.infoexp["most_recent_contact"] = None
675
        self.infoexp["reprocess"] = False
676
        self.infoexp["first_contact"] = datetime(2014, 6, 11)
677
        self.infoexp["lab_person"] = qdb.study.StudyPerson(2)
678
        del self.infoexp["lab_person_id"]
679
680
        self.assertEqual(new.info, self.infoexp)
681
        qdb.study.Study.delete(new.id)
682
683
    def test_set_info_public(self):
684
        """Tests for fail if editing info of a public study"""
685
        self.study.info = {"vamps_id": "12321312"}
686
687
    def test_set_info_public_error(self):
688
        """Tests for fail if trying to modify timeseries of a public study"""
689
        with self.assertRaises(qdb.exceptions.QiitaDBStatusError):
690
            self.study.info = {"timeseries_type_id": 2}
691
692
    def test_set_info_disallowed_keys(self):
693
        """Tests for fail if sending non-info keys in info dict"""
694
        new = qdb.study.Study.create(
695
            qdb.user.User('test@foo.bar'),
696
            'NOT Identification of the Microbiomes for Cannabis Soils 7',
697
            self.info)
698
        with self.assertRaises(qdb.exceptions.QiitaDBColumnError):
699
            new.info = {"email": "fail@fail.com"}
700
        qdb.study.Study.delete(new.id)
701
702
    def test_info_empty(self):
703
        new = qdb.study.Study.create(
704
            qdb.user.User('test@foo.bar'),
705
            'NOT Identification of the Microbiomes for Cannabis Soils 8',
706
            self.info)
707
        with self.assertRaises(IncompetentQiitaDeveloperError):
708
            new.info = {}
709
        qdb.study.Study.delete(new.id)
710
711
    def test_retrieve_status(self):
712
        self.assertEqual(self.study.status, "private")
713
714
    def test_retrieve_shared_with(self):
715
        self.assertEqual(self.study.shared_with,
716
                         [qdb.user.User('shared@foo.bar')])
717
718
    def test_retrieve_publications_empty(self):
719
        new = qdb.study.Study.create(
720
            qdb.user.User('test@foo.bar'),
721
            'NOT Identification of the Microbiomes for Cannabis Soils 9',
722
            self.info)
723
        self.assertEqual(new.publications, [])
724
725
    def test_publication_setter(self):
726
        new = qdb.study.Study.create(
727
            qdb.user.User('test@foo.bar'), 'New study', self.info)
728
        self.assertEqual(new.publications, [])
729
730
        new_values = [['10.100/654321', True],
731
                      ['10.100/1101987', True],
732
                      ['1101987', False]]
733
        new.publications = new_values
734
        self.assertEqual(new.publications, new_values)
735
        qdb.study.Study.delete(new.id)
736
737
    def test_publications_setter_typeerror(self):
738
        with self.assertRaises(TypeError):
739
            self.study.publications = '123456'
740
741
    def test_retrieve_investigation(self):
742
        self.assertEqual(self.study.investigation,
743
                         qdb.investigation.Investigation(1))
744
745
    def test_retrieve_investigation_empty(self):
746
        new = qdb.study.Study.create(
747
            qdb.user.User('test@foo.bar'),
748
            'NOT Identification of the Microbiomes for Cannabis Soils 10',
749
            self.info)
750
        self.assertEqual(new.investigation, None)
751
        qdb.study.Study.delete(new.id)
752
753
    def test_retrieve_sample_template(self):
754
        self.assertEqual(
755
            self.study.sample_template,
756
            qdb.metadata_template.sample_template.SampleTemplate(1))
757
758
    def test_retrieve_data_types(self):
759
        self.assertEqual(self.study.data_types, ['18S'])
760
761
    def test_retrieve_data_types_none(self):
762
        new = qdb.study.Study.create(
763
            qdb.user.User('test@foo.bar'),
764
            'NOT Identification of the Microbiomes for Cannabis Soils 11',
765
            self.info)
766
        self.assertEqual(new.data_types, [])
767
        qdb.study.Study.delete(new.id)
768
769
    def test_retrieve_artifacts(self):
770
        exp = [qdb.artifact.Artifact(1),
771
               qdb.artifact.Artifact(2),
772
               qdb.artifact.Artifact(3),
773
               qdb.artifact.Artifact(4),
774
               qdb.artifact.Artifact(5),
775
               qdb.artifact.Artifact(6),
776
               qdb.artifact.Artifact(7)]
777
        self.assertEqual(self.study.artifacts(), exp)
778
        self.assertEqual(self.study.artifacts(dtype="16S"), exp[-2:])
779
        self.assertEqual(self.study.artifacts(dtype="18S"), exp[:-2])
780
781
        self.assertEqual(self.study.artifacts(artifact_type="BIOM"),
782
                         [qdb.artifact.Artifact(4),
783
                          qdb.artifact.Artifact(5),
784
                          qdb.artifact.Artifact(6),
785
                          qdb.artifact.Artifact(7)])
786
787
        self.assertEqual(self.study.artifacts(dtype="18S",
788
                                              artifact_type="BIOM"),
789
                         [qdb.artifact.Artifact(4),
790
                          qdb.artifact.Artifact(5)])
791
792
    def test_retrieve_artifacts_none(self):
793
        new = qdb.study.Study.create(
794
            qdb.user.User('test@foo.bar'),
795
            'NOT Identification of the Microbiomes for Cannabis Soils 12',
796
            self.info)
797
        self.assertEqual(new.artifacts(), [])
798
        qdb.study.Study.delete(new.id)
799
800
    def test_retrieve_prep_templates(self):
801
        self.assertCountEqual(
802
            self.study.prep_templates(),
803
            [qdb.metadata_template.prep_template.PrepTemplate(1),
804
             qdb.metadata_template.prep_template.PrepTemplate(2)])
805
806
    def test_retrieve_prep_templates_none(self):
807
        new = qdb.study.Study.create(
808
            qdb.user.User('test@foo.bar'),
809
            'NOT Identification of the Microbiomes for Cannabis Soils 13',
810
            self.info)
811
        self.assertEqual(new.prep_templates(), [])
812
        qdb.study.Study.delete(new.id)
813
814
    def test_analyses(self):
815
        new = qdb.study.Study.create(
816
            qdb.user.User('test@foo.bar'),
817
            'NOT Identification of the Microbiomes for Cannabis Soils 13',
818
            self.info)
819
820
        self.assertEqual(qdb.study.Study(1).analyses(), [
821
            qdb.analysis.Analysis(1), qdb.analysis.Analysis(2),
822
            qdb.analysis.Analysis(3)])
823
824
        self.assertEqual(qdb.study.Study(2).analyses(), [])
825
826
        qdb.study.Study.delete(new.id)
827
828
    def test_environmental_packages(self):
829
        obs = self.study.environmental_packages
830
        exp = ['soil', 'plant-associated']
831
        self.assertEqual(sorted(obs), sorted(exp))
832
833
    def test_environmental_packages_setter(self):
834
        new = qdb.study.Study.create(
835
            qdb.user.User('test@foo.bar'),
836
            'NOT Identification of the Microbiomes for Cannabis Soils 14',
837
            self.info)
838
        obs = new.environmental_packages
839
        exp = []
840
        self.assertEqual(obs, exp)
841
842
        new_values = ['air', 'human-oral']
843
        new.environmental_packages = new_values
844
        obs = new.environmental_packages
845
        self.assertEqual(sorted(obs), sorted(new_values))
846
        qdb.study.Study.delete(new.id)
847
848
    def test_environmental_packages_setter_typeerror(self):
849
        new = qdb.study.Study.create(
850
            qdb.user.User('test@foo.bar'),
851
            'NOT Identification of the Microbiomes for Cannabis Soils 15',
852
            self.info)
853
        with self.assertRaises(TypeError):
854
            new.environmental_packages = 'air'
855
        qdb.study.Study.delete(new.id)
856
857
    def test_environmental_packages_setter_valueerror(self):
858
        new = qdb.study.Study.create(
859
            qdb.user.User('test@foo.bar'),
860
            'NOT Identification of the Microbiomes for Cannabis Soils 16',
861
            self.info)
862
        with self.assertRaises(ValueError):
863
            new.environmental_packages = ['air', 'not a package']
864
        qdb.study.Study.delete(new.id)
865
866
    def test_environmental_packages_sandboxed(self):
867
        with self.assertRaises(qdb.exceptions.QiitaDBStatusError):
868
            self.study.environmental_packages = ['air']
869
870
    def test_study_tags(self):
871
        # testing empty tags
872
        obs = qdb.study.Study.get_tags()
873
        self.assertEqual(obs, {'admin': [], 'user': []})
874
875
        # inserting new tags
876
        user = qdb.user.User('test@foo.bar')
877
        tags = ['this is my tag', 'I want GOLD!!', 'this is my tag']
878
        qdb.study.Study.insert_tags(user, tags)
879
        # now as admin
880
        admin = qdb.user.User('admin@foo.bar')
881
        admin_tags = ['actual GOLD!', 'this is my tag']
882
        qdb.study.Study.insert_tags(admin, admin_tags)
883
884
        # testing that insertion went fine
885
        obs = qdb.study.Study.get_tags()
886
        exp = {'user': ['I want GOLD!!', 'this is my tag'],
887
               'admin': ['actual GOLD!']}
888
        self.assertEqual(obs, exp)
889
890
        # assigning the tags to study as user
891
        study = qdb.study.Study(1)
892
        tags = ['this is my tag', 'actual GOLD!']
893
        message = study.update_tags(user, tags)
894
        self.assertCountEqual(study.tags, tags[:1])
895
        self.assertEqual(message, 'Only admins can assign: actual GOLD!')
896
        # now like admin
897
        message = study.update_tags(admin, tags)
898
        self.assertCountEqual(study.tags, tags)
899
        self.assertEqual(message, '')
900
901
        # cleaning tags
902
        message = study.update_tags(user, [])
903
        self.assertEqual(study.tags, ['actual GOLD!'])
904
        self.assertEqual(message, 'You cannot remove: actual GOLD!')
905
        message = study.update_tags(admin, [])
906
        self.assertEqual(study.tags, [])
907
        self.assertEqual(message, '')
908
909
910
if __name__ == "__main__":
911
    main()