• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

4dn-dcic / dcicwrangling / 13682489429

05 Mar 2025 06:03PM UTC coverage: 33.8%. Remained the same
13682489429

push

github

web-flow
Merge pull request #117 from 4dn-dcic/ajs_upd_dependencies

Ajs upd dependencies

2 of 2 new or added lines in 1 file covered. (100.0%)

22 existing lines in 14 files now uncovered.

1256 of 3716 relevant lines covered (33.8%)

2.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.16
/tests/test_script_utils.py
1
import pytest
6✔
2
from functions import script_utils as scu
6✔
3
import argparse
6✔
4
from collections import OrderedDict
6✔
5

6

7
@pytest.fixture
6✔
8
def eset_json():
6✔
9
    return {
6✔
10
        "schema_version": "2",
11
        "accession": "4DNES4GSP9S4",
12
        "award": "4871e338-b07d-4665-a00a-357648e5bad6",
13
        "alternate_accessions": [],
14
        "aliases": [
15
            "ren:HG00512_repset"
16
        ],
17
        "experimentset_type": "replicate",
18
        "status": "released",
19
        "experiments_in_set": [
20
            "d4b0e597-8c81-43e3-aeda-e9842fc18e8f",
21
            "8d10f11f-95a8-4b8d-8ff2-748ea8631a23"
22
        ],
23
        "lab": "795847de-20b6-4f8c-ba8d-185215469cbf",
24
        "public_release": "2017-06-30",
25
        "uuid": "9eb40c13-cf85-487c-9819-71ef74a22dcc",
26
        "documents": [],
27
        "description": "Dilution Hi-C experiment on HG00512",
28
        "submitted_by": "da4f53e5-4e54-4ae7-ad75-ba47316a8bfa",
29
        "date_created": "2017-04-28T17:46:08.642218+00:00",
30
        "replicate_exps": [
31
            {
32
                "replicate_exp": "d4b0e597-8c81-43e3-aeda-e9842fc18e8f",
33
                "bio_rep_no": 1,
34
                "tec_rep_no": 1
35
            },
36
            {
37
                "replicate_exp": "8d10f11f-95a8-4b8d-8ff2-748ea8631a23",
38
                "bio_rep_no": 2,
39
                "tec_rep_no": 1
40
            }
41
        ],
42
    }
43

44

45
@pytest.fixture
6✔
46
def bs_embed_json():
6✔
47
    return {
6✔
48
        "lab": {
49
            "display_title": "David Gilbert, FSU",
50
            "uuid": "6423b207-8176-4f06-a127-951b98d6a53a",
51
            "link_id": "~labs~david-gilbert-lab~",
52
            "@id": "/labs/david-gilbert-lab/"
53
        },
54
        "display_title": "4DNBSLACJHX1"
55
    }
56

57

58
@pytest.fixture
6✔
59
def profiles():
6✔
60
    return {
6✔
61
        "ExperimentSetReplicate": {
62
            "title": "Replicate Experiments",
63
            "description": "Experiment Set for technical/biological replicates.",
64
            "properties": {
65
                "tags": {"uniqueItems": "true", "description": "Key words that can tag an item - useful for filtering.", "type": "array", "ff_clear": "clone", "items": {"title": "Tag", "description": "A tag for the item.", "type": "string"}, "title": "Tags"},  # noqa: E501
66
                "documents": {"uniqueItems": "true", "description": "Documents that provide additional information (not data file).", "type": "array", "default": [], "comment": "See Documents sheet or collection for existing items.", "title": "Documents", "items": {"title": "Document", "description": "A document that provides additional information (not data file).", "type": "string", "linkTo": "Document"}},  # noqa: E501
67
                "notes": {"exclude_from": ["submit4dn", "FFedit-create"], "title": "Notes", "description": "DCIC internal notes.", "type": "string", "elasticsearch_mapping_index_type": {"title": "Field mapping index type", "description": "Defines one of three types of indexing available", "type": "string", "default": "analyzed", "enum": ["analyzed", "not_analyzed", "no"]}}  # noqa: E501
68
            }
69
        },
70
        "TreatmentChemical": {
71
            "title": "Chemical Treatment",
72
            "description": "A Chemical or Drug Treatment on Biosample.",
73
            "properties": {
74
                "documents": {"uniqueItems": "true", "description": "Documents that provide additional information (not data file).", "type": "array", "default": [], "comment": "See Documents sheet or collection for existing items.", "title": "Documents", "items": {"title": "Document", "description": "A document that provides additional information (not data file).", "type": "string", "linkTo": "Document"}},  # noqa: E501
75
                "public_release": {"anyOf": [{"format": "date-time"}, {"format": "date"}], "exclude_from": ["submit4dn", "FFedit-create"], "description": "The date which the item was released to the public", "permission": "import_items", "type": "string", "comment": "Do not submit, value is assigned when released.", "title": "Public Release Date"},  # noqa: E501
76
            }
77
        }
78
    }
79

80

81
@pytest.fixture
6✔
82
def auth():
6✔
83
    return {'key': 'portal_key', 'secret': 'super_secret_access', 'server': 'https://test_portal'}
6✔
84

85

86
def test_authenticate_no_key_or_env():
6✔
87
    with pytest.raises(Exception):
6✔
88
        scu.authenticate()
6✔
89
 
90

91
def test_authenicate_w_key_no_keyfile():
6✔
92
    with pytest.raises(SystemExit):
6✔
93
        scu.authenticate(key='testkey')
6✔
94

95

96
def test_authenticate_w_key_and_keyfile(mocker, auth):
6✔
97
    mocker.patch('functions.script_utils.get_key', return_value=auth)
6✔
98
    test_auth = scu.authenticate(key='testkey', keyfile='test_keyfile')
6✔
99
    assert test_auth == auth
6✔
100

101

102
def test_authenticate_w_env(mocker, auth):
6✔
103
    mocker.patch('functions.script_utils.get_authentication_with_server', return_value=auth)
6✔
104
    test_auth = scu.authenticate(env='testenv')
6✔
105
    assert test_auth == auth
6✔
106

107

108
def test_is_uuid():
6✔
109
    uuids = [
6✔
110
        '231111bc-8535-4448-903e-854af460b254',
111
        '231111bc-8535-4448-903e-854af460b25',
112
        '231111bc85354448903e854af460b254'
113
    ]
114
    for i, u in enumerate(uuids):
6✔
115
        if i == 0:
6✔
116
            assert scu.is_uuid(u)
6✔
117
        else:
118
            assert not scu.is_uuid(u)
6✔
119

120

121
def test_find_uuids_from_eset(eset_json):
6✔
122
    field2uuid = {
6✔
123
        "award": "4871e338-b07d-4665-a00a-357648e5bad6",
124
        "lab": "795847de-20b6-4f8c-ba8d-185215469cbf",
125
        "uuid": "9eb40c13-cf85-487c-9819-71ef74a22dcc",
126
        "submitted_by": "da4f53e5-4e54-4ae7-ad75-ba47316a8bfa"
127
    }
128
    exps = ["d4b0e597-8c81-43e3-aeda-e9842fc18e8f", "8d10f11f-95a8-4b8d-8ff2-748ea8631a23"]
6✔
129
    for field, val in eset_json.items():
6✔
130
        ulist = scu.find_uuids(val)
6✔
131
        if field in field2uuid:
6✔
132
            assert field2uuid[field] == ulist[0]
6✔
133
        elif field in ["experiments_in_set", "replicate_exps"]:
6✔
134
            for u in ulist:
6✔
135
                assert u in exps
6✔
136

137

138
def test_filter_dict_by_value(eset_json):
6✔
139
    to_filter = {
6✔
140
        "schema_version": "2",
141
        "accession": "4DNES4GSP9S4",
142
        "aliases": ["ren:HG00512_repset"]
143
    }
144
    vals = list(to_filter.values())
6✔
145
    included = scu.filter_dict_by_value(eset_json, vals)
6✔
146
    assert len(included) == len(to_filter)
6✔
147
    for f in to_filter.keys():
6✔
148
        assert f in included
6✔
149

150
    excluded = scu.filter_dict_by_value(eset_json, vals, include=False)
6✔
151
    assert len(excluded) == len(eset_json) - len(to_filter)
6✔
152
    for f in to_filter.keys():
6✔
153
        assert f not in excluded
6✔
154

155

156
def test_has_field_value_check_for_field_only(eset_json):
6✔
157
    fieldnames = ['schema_version', 'award', 'alternate_accessions']
6✔
158
    for f in fieldnames:
6✔
159
        assert scu.has_field_value(eset_json, f)
6✔
160

161

162
def test_has_field_value_no_it_doesnt(eset_json):
6✔
163
    fieldnames = ['biosample', 'blah', 'bio_rep_no']
6✔
164
    for f in fieldnames:
6✔
165
        assert not scu.has_field_value(eset_json, f)
6✔
166

167

168
def test_has_field_value_check_for_field_and_value(eset_json):
6✔
169
    fields_w_values = {
6✔
170
        "schema_version": "2",
171
        "accession": "4DNES4GSP9S4",
172
        "aliases": "ren:HG00512_repset"
173
    }
174
    for f, v in fields_w_values.items():
6✔
175
        assert scu.has_field_value(eset_json, f, v)
6✔
176

177

178
def test_has_field_value_check_for_field_w_item(bs_embed_json):
6✔
179
    f = "lab"
6✔
180
    v = "/labs/david-gilbert-lab/"
6✔
181
    assert scu.has_field_value(bs_embed_json, f, v, True)
6✔
182

183

184
def test_has_field_value_check_for_field_w_item_not_found(bs_embed_json):
6✔
185
    f = "lab"
6✔
186
    v = "/labs/nobodys-lab/"
6✔
187
    assert not scu.has_field_value(bs_embed_json, f, v, True)
6✔
188

189

190
def test_has_field_value_check_for_field_w_item_no_dict():
6✔
191
    f = "b"
6✔
192
    v = "/labs/david-gilbert-lab/"
6✔
193
    assert not scu.has_field_value('blah', f, v, True)
6✔
194

195

196
def test_has_field_value_value_not_found_in_list(eset_json):
6✔
197
    not_found = 'unfound'
6✔
198
    assert not scu.has_field_value(eset_json, 'experiments_in_set', not_found)
6✔
199

200

201
def test_has_field_value_value_not_found_as_string(eset_json):
6✔
202
    not_found = 'unfound'
6✔
203
    assert not scu.has_field_value(eset_json, 'status', not_found)
6✔
204

205

206
def test_get_types_that_can_have_field(mocker, profiles):
6✔
207
    field = 'tags'
6✔
208
    mocker.patch('functions.script_utils.get_metadata', return_value=profiles)
6✔
209
    types_w_field = scu.get_types_that_can_have_field('conn', field)
6✔
210
    assert 'ExperimentSetReplicate' in types_w_field
6✔
211
    assert 'TreatmentChemical' not in types_w_field
6✔
212

213

214
def test_get_item_type_from_dict(eset_json):
6✔
215
    eset_json['@type'] = ['ExperimentSetReplicate', 'ExperimentSet', 'Item']
6✔
216
    es_ty = scu.get_item_type('blah', eset_json)
6✔
217
    assert es_ty == 'ExperimentSetReplicate'
6✔
218

219

220
def test_get_item_type_from_id(mocker, auth):
6✔
221
    mocker.patch('functions.script_utils.get_metadata', return_value={'@type': ['ExperimentSetReplicate']})
6✔
222
    result = scu.get_item_type(auth, 'blah')
6✔
223
    assert result == 'ExperimentSetReplicate'
6✔
224

225

226
def test_get_item_type_no_type(mocker, auth, capsys):
6✔
227
    mocker.patch('functions.script_utils.get_metadata', return_value={'description': 'blah'})
6✔
228
    result = scu.get_item_type(auth, 'blah')
6✔
229
    out = capsys.readouterr()[0]
6✔
230
    assert out == "Can't find a type for item blah\n"
6✔
231
    assert result is None
6✔
232

233

234
@pytest.fixture
6✔
235
def items_w_uuids():
6✔
236
    return [
6✔
237
        {'name': 'one', 'uuid': 'a'},
238
        {'name': 'two', 'uuid': 'b'},
239
        {'name': 'three', 'uuid': 'c'},
240
    ]
241

242

243
def test_get_item_ids_from_list(auth):
6✔
244
    ids = ['a', 'b', 'c']
6✔
245
    result = scu.get_item_ids_from_args(ids, auth)
6✔
246
    for a in [i in ids for i in result]:
6✔
247
        assert a
6✔
248

249

250
def test_get_item_ids_from_search(mocker, auth, items_w_uuids):
6✔
251
    ids = ['a', 'b', 'c']
6✔
252
    mocker.patch('functions.script_utils.search_metadata', return_value=[])
6✔
253
    mocker.patch('functions.script_utils.get_metadata', return_value=items_w_uuids)
6✔
254
    result = scu.get_item_ids_from_args('search', auth, True)
6✔
255
    for a in [i in ids for i in result]:
6✔
256
        assert a
×
257

258

259
def test_get_item_uuid_w_uuid(auth):
6✔
260
    uid = '7868f960-50ac-11e4-916c-0800200c9a66'
6✔
261
    result = scu.get_item_uuid(uid, auth)
6✔
262
    assert result == uid
6✔
263

264

265
def test_get_item_uuid_w_atid(mocker, auth):
6✔
266
    atid = '/labs/test-lab'
6✔
267
    mt = mocker.patch('functions.script_utils.get_metadata', return_value={'uuid': 'test_uuid'})
6✔
268
    result = scu.get_item_uuid(atid, auth)
6✔
269
    mt.assert_called_with(atid, auth)
6✔
270
    assert result == 'test_uuid'
6✔
271

272

273
def test_get_item_uuid_not_found(mocker, auth):
6✔
274
    atid = '/labs/non-lab'
6✔
275
    mt = mocker.patch('functions.script_utils.get_metadata', return_value={'status': 'error'})
6✔
276
    result = scu.get_item_uuid(atid, auth)
6✔
277
    mt.assert_called_with(atid, auth)
6✔
278
    assert result is None
6✔
279

280

281
def test_create_ff_arg_parser(capsys):
6✔
282
    helpout = ['--env', '--key', '--dbupdate']
6✔
283
    parser = scu.create_ff_arg_parser()
6✔
284
    assert isinstance(parser, argparse.ArgumentParser)
6✔
285
    parser.print_help()
6✔
286
    out = capsys.readouterr()[0]
6✔
287
    for o in helpout:
6✔
288
        assert o in out
6✔
289

290

291
def test_create_input_arg_parser(capsys):
6✔
292
    helpout = ['input', '--search']
6✔
293
    parser = scu.create_input_arg_parser()
6✔
294
    assert isinstance(parser, argparse.ArgumentParser)
6✔
295
    parser.print_help()
6✔
296
    out = capsys.readouterr()[0]
6✔
297
    for o in helpout:
6✔
298
        assert o in out
6✔
299

300

301
def test_convert_key_arg_to_dict_good_key():
6✔
302
    inkey = "{'key': 'ABCDEF', 'secret': 'supersecret', 'server': 'https://data.4dnucleome.org'}"
6✔
303
    outkey = scu.convert_key_arg_to_dict(inkey)
6✔
304
    assert outkey == {'key': 'ABCDEF', 'secret': 'supersecret', 'server': 'https://data.4dnucleome.org'}
6✔
305

306

307
def test_convert_key_arg_to_dict_bad_key(capsys):
6✔
308
    inkey = "{'key': 'ABCDEF', 'secret': 'supersecret'}"
6✔
309
    with pytest.raises(SystemExit):
6✔
310
        scu.convert_key_arg_to_dict(inkey)
6✔
311
        out = capsys.readouterr()[0]
×
UNCOV
312
        assert out == "You included a key argument but it appears to be malformed or missing required info - see --help"
1✔
313

314

315
def test_get_linked_items_w_item_in_found(auth):
6✔
316
    itemid = 'itemid'
6✔
317
    found_items = {itemid: 1}
6✔
318
    iid = scu.get_linked_items(auth, itemid, found_items)
6✔
319
    assert itemid in iid
6✔
320

321

322
def test_get_linked_items_w_error_status(auth, mocker):
6✔
323
    mocker.patch('functions.script_utils.get_metadata', return_value={'status': 'error'})
6✔
324
    iids = scu.get_linked_items(auth, 'test_id')
6✔
325
    assert not iids
6✔
326

327

328
def test_get_linked_items_w_no_type(auth, mocker):
6✔
329
    mocker.patch('functions.script_utils.get_metadata',
6✔
330
                 side_effect=[{'status': 'released'}, {'field': 'value'}])
331
    iids_emp = scu.get_linked_items(auth, 'test_id')
6✔
332
    assert not iids_emp
6✔
333

334

335
def test_get_linked_items_w_type_in_no_children(auth, mocker):
6✔
336
    mocker.patch('functions.script_utils.get_metadata',
6✔
337
                 side_effect=[{'status': 'current'}, {'@type': ['Publication']}])
338
    iids = scu.get_linked_items(auth, 'test_id')
6✔
339
    assert iids['test_id'] == 'Publication'
6✔
340

341

342
def test_get_linked_items_w_linked_items(auth, mocker):
6✔
343
    goodids = ['test_id', '7256801c-9c6e-4563-a97a-a295fccf5f07']
6✔
344
    badids = ['6256801c-9c6e-4563-a97a-a295fccf5f07']
6✔
345
    resp1 = {
6✔
346
        'status': 'released',
347
        '@type': ['Biosample', 'Item'],
348
        'biosource': '7256801c-9c6e-4563-a97a-a295fccf5f07',
349
        'attachment': '6256801c-9c6e-4563-a97a-a295fccf5f07'
350
    }
351
    found = {'7256801c-9c6e-4563-a97a-a295fccf5f07': 'Biosource'}
6✔
352
    mocker.patch('functions.script_utils.get_metadata', side_effect=[resp1, {'@type': ['Biosample']}])
6✔
353
    mocker.patch('functions.script_utils.find_uuids', return_value=['7256801c-9c6e-4563-a97a-a295fccf5f07'])
6✔
354
    iids = scu.get_linked_items(auth, 'test_id', found)
6✔
355
    for i in iids:
6✔
356
        assert i in goodids
6✔
357
        assert i not in badids
6✔
358

359

360
def test_get_linked_items_w_no_linked_foundids(auth, mocker):
6✔
361
    goodids = ['test_id']
6✔
362
    badids = ['6256801c-9c6e-4563-a97a-a295fccf5f07']
6✔
363
    resp1 = {
6✔
364
        'status': 'released',
365
        '@type': ['Biosample', 'Item'],
366
        'biosource': '7256801c-9c6e-4563-a97a-a295fccf5f07',
367
        'attachment': '6256801c-9c6e-4563-a97a-a295fccf5f07'
368
    }
369
    found = {}
6✔
370
    mocker.patch('functions.script_utils.get_metadata', side_effect=[resp1, {'@type': ['Biosample']}])
6✔
371
    mocker.patch('functions.script_utils.find_uuids', return_value=None)
6✔
372
    iids = scu.get_linked_items(auth, 'test_id', found)
6✔
373
    for i in iids:
6✔
374
        assert i in goodids
6✔
375
        assert i not in badids
6✔
376

377

378
def test_get_linked_item_ids_w_recursive(auth, mocker):
6✔
379
    goodids = ['test_id', '7256801c-9c6e-4563-a97a-a295fccf5f07', '5256801c-9c6e-4563-a97a-a295fccf5f07']
6✔
380
    badids = ['6256801c-9c6e-4563-a97a-a295fccf5f07']
6✔
381
    resp1 = {
6✔
382
        'status': 'released',
383
        '@type': ['Biosample', 'Item'],
384
        'biosource': '7256801c-9c6e-4563-a97a-a295fccf5f07',
385
        'attachment': '6256801c-9c6e-4563-a97a-a295fccf5f07'
386
    }
387
    resp1 = OrderedDict(sorted(resp1.items(), key=lambda t: t[0]))
6✔
388
    resp2 = {
6✔
389
        'status': 'released',
390
        '@type': ['Biosource', 'Item'],
391
        'biosource_vendor': '5256801c-9c6e-4563-a97a-a295fccf5f07'
392
    }
393
    resp2 = OrderedDict(sorted(resp2.items(), key=lambda t: t[0]))
6✔
394
    resp3 = {
6✔
395
        'status': 'released',
396
    }
397
    mocker.patch('functions.script_utils.get_metadata', side_effect=[
6✔
398
        resp1, {'@type': ['Biosample']},
399
        resp2, {'@type': ['Biosource']},
400
        resp3, {'@type': ['Vendor']}
401
    ])
402
    mocker.patch('functions.script_utils.find_uuids', side_effect=[
6✔
403
        None,
404
        ['7256801c-9c6e-4563-a97a-a295fccf5f07'],
405
        None,
406
        None,
407
        ['5256801c-9c6e-4563-a97a-a295fccf5f07'],
408
        None,
409
        None
410
    ])
411
    iids = scu.get_linked_items(auth, 'test_id')
6✔
412
    for i in iids:
6✔
413
        assert i in goodids
6✔
414
        assert i not in badids
6✔
415

416

417
@pytest.fixture
6✔
418
def cell_line_json():
6✔
419
    return {
6✔
420
        "is_slim_for": "cell",
421
        "namespace": "http://www.ebi.ac.uk/efo",
422
        "term_id": "EFO:0000322",
423
        "term_name": "cell line",
424
        "source_ontology": "530006bc-8535-4448-903e-854af460b254",
425
        "term_url": "http://www.ebi.ac.uk/efo/EFO_0000322"
426
    }
427

428

429
def test_get_item_if_you_can_json_w_uuid(auth, eset_json):
6✔
430
    result = scu.get_item_if_you_can(auth, eset_json)
6✔
431
    assert result == eset_json
6✔
432

433

434
def test_get_item_if_you_can_w_uuid(mocker, auth, eset_json):
6✔
435
    mocker.patch('functions.script_utils.get_metadata', return_value=eset_json)
6✔
436
    result = scu.get_item_if_you_can(auth, eset_json['uuid'])
6✔
437
    assert result == eset_json
6✔
438

439

440
def test_get_item_if_you_can_w_termname_and_itype(mocker, auth, cell_line_json):
6✔
441
    mocker.patch('functions.script_utils.get_metadata', side_effect=[None, cell_line_json])
6✔
442
    result = scu.get_item_if_you_can(auth, cell_line_json['term_name'], 'OntologyTerm')
6✔
443
    assert result == cell_line_json
6✔
444

445

446
def test_get_item_if_you_can_w_termname_and_no_itype_no_item(mocker, auth, cell_line_json):
6✔
447
    mocker.patch('functions.script_utils.get_metadata', side_effect=[None, None])
6✔
448
    result = scu.get_item_if_you_can(auth, cell_line_json['term_name'])
6✔
449
    assert result is None
6✔
450

451

452
def test_get_item_if_you_can_w_fakename_and_itype_no_item(mocker, auth):
6✔
453
    mocker.patch('functions.script_utils.get_metadata', side_effect=[None, None])
6✔
454
    result = scu.get_item_if_you_can(auth, 'fake name', 'OntologyTerm')
6✔
455
    assert result is None
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc