#!/usr/bin/env python
"""Tests for the ``data_containers`` module in the ``jwql`` web
application.
Authors
-------
- Matthew Bourque
- Mees Fix
- Bryan Hilbert
- Bradley Sappington
- Melanie Clarke
Use
---
These tests can be run via the command line (omit the -s to
suppress verbose output to stdout):
::
pytest -s test_data_containers.py
"""
import glob
import json
import os
import numpy as np
import pandas as pd
import pytest
from jwql.utils.constants import ON_GITHUB_ACTIONS, DEFAULT_MODEL_CHARFIELD
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jwql.website.jwql_proj.settings")
# Skip testing this module if on Github Actions
from jwql.website.apps.jwql import data_containers # noqa: E402 (module level import not at top of file)
from jwql.tests.resources import MockSessionFileAnomaly, MockSessionGroupAnomaly # noqa: E402 (module level import not at top of file)
from jwql.tests.resources import MockGetRequest, MockPostRequest # noqa: E402 (module level import not at top of file)
from jwql.utils import constants # noqa: E402 (module level import not at top of file)
if not ON_GITHUB_ACTIONS:
from jwql.utils.utils import get_config # noqa: E402 (module level import not at top of file)
from jwql.website.apps.jwql.models import RootFileInfo
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_build_table():
tab = data_containers.build_table('filesystem_general')
assert isinstance(tab, pd.DataFrame)
assert len(tab['date']) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
@pytest.mark.parametrize('filter_keys',
[{'instrument': 'NIRSpec', 'proposal': '2589',
'obsnum': '006', 'look': 'All'},
{'instrument': 'NIRCam', 'detector': 'NRCBLONG',
'proposal': '2733', 'obsnum': '001'},
{'instrument': 'MIRI', 'exp_type': 'MIR_IMAGE',
'proposal': '1524', 'obsnum': '015'},
{'instrument': 'FGS', 'cat_type': 'COM',
'proposal': '1155'}
])
def test_filter_root_files(filter_keys):
rfi = data_containers.filter_root_files(**filter_keys)
assert len(rfi) > 0
assert len(rfi) < 100
for key, value in filter_keys.items():
if str(value).strip().lower() == 'all':
continue
elif key in ['cat_type', 'obsnum']:
# values returned are foreign keys
continue
else:
rf_test = [str(rf[key]) == str(value) for rf in rfi]
assert all(rf_test)
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_filter_root_files_sorting():
filter_keys = {'instrument': 'NIRSpec', 'proposal': '2589',
'obsnum': '006'}
rfi = data_containers.filter_root_files(**filter_keys, sort_as='Ascending')
assert len(rfi) > 3
for i, rf in enumerate(rfi[1:]):
assert rf['root_name'] > rfi[i]['root_name']
rfi = data_containers.filter_root_files(**filter_keys, sort_as='Descending')
for i, rf in enumerate(rfi[1:]):
assert rf['root_name'] < rfi[i]['root_name']
rfi = data_containers.filter_root_files(**filter_keys, sort_as='Recent')
for i, rf in enumerate(rfi[1:]):
assert rf['expstart'] <= rfi[i]['expstart']
rfi = data_containers.filter_root_files(**filter_keys, sort_as='Oldest')
for i, rf in enumerate(rfi[1:]):
assert rf['expstart'] >= rfi[i]['expstart']
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_create_archived_proposals_context(tmp_path, mocker):
# write to a temporary directory
mocker.patch.object(data_containers, 'OUTPUT_DIR', str(tmp_path))
archive_dir = tmp_path / 'archive_page'
os.mkdir(archive_dir)
data_containers.create_archived_proposals_context('nirspec')
context_file = str(archive_dir / 'NIRSpec_archive_context.json')
assert os.path.isfile(context_file)
with open(context_file, 'r') as obj:
context = json.load(obj)
assert context['inst'] == 'NIRSpec'
assert context['num_proposals'] > 0
[docs]
def test_get_acknowledgements():
"""Tests the ``get_acknowledgements`` function."""
acknowledgements = data_containers.get_acknowledgements()
assert isinstance(acknowledgements, list)
assert len(acknowledgements) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_get_additional_exposure_info():
"""Tests ``get_additional_exposure_info`` function."""
# Test an exposure-level case
group_root = 'jw01068002001_02102_00008'
image_info = data_containers.get_image_info(group_root)
root_file_info = RootFileInfo.objects.filter(root_name__startswith=group_root)
basic, additional = data_containers.get_additional_exposure_info(root_file_info, image_info)
expected_basic = {'exp_type': 'NRC_IMAGE',
'category': 'COM',
'visit_status': 'SUCCESSFUL',
'subarray': 'SUB320',
'pupil': 'CLEAR'}
# We can only test a subset of the keys in additional, since things like the pipeline version,
# crds context, etc can change over time.
expected_additional = {'READPATT': 'RAPID',
'TITLE': 'NIRCam Subarray-Mode Commissioning, CAR NIRCam-019',
'NGROUPS': 10,
'PI_NAME': 'Hilbert, Bryan',
'NINTS': 10,
'TARGNAME': 'GP2-JMAG14-STAR-OFFSET',
'EXPTIME': 106.904,
'EXPSTART': 59714.6163261875}
for key in expected_basic:
assert basic[key] == expected_basic[key]
for key in expected_additional:
assert additional[key] == expected_additional[key]
# Test an image-level case
file_root = 'jw01022016001_03101_00001_nrs1'
image_info = data_containers.get_image_info(file_root)
root_file_info = RootFileInfo.objects.get(root_name=file_root)
basic, additional = data_containers.get_additional_exposure_info(root_file_info, image_info)
expected_basic = {'exp_type': 'NRS_IFU',
'category': 'COM',
'visit_status': 'SUCCESSFUL',
'subarray': 'FULL',
'filter': 'F100LP',
'grating': 'G140H'}
expected_additional = {'READPATT': 'NRSRAPID',
'TITLE': 'CAR FGS-017 Straylight for Moving Targets (All SIs)',
'NGROUPS': 13,
'PI_NAME': 'Stansberry, John A.',
'NINTS': 2,
'TARGNAME': 'JUPITER',
'EXPTIME': 279.156,
'EXPSTART': 59764.77659749352}
assert basic == expected_basic
for key in expected_additional:
assert additional[key] == expected_additional[key]
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_all_proposals():
"""Tests the ``get_all_proposals`` function."""
proposals = data_containers.get_all_proposals()
assert isinstance(proposals, list)
assert len(proposals) > 0
[docs]
@pytest.mark.parametrize('untracked,input_suffixes,expected',
[(True, [], ([], set())),
(True, ['rate', 'uncal', 'bad'],
(['uncal', 'rate', 'bad'], {'bad'})),
(False, ['rate', 'uncal', 'bad'],
['uncal', 'rate', 'bad']),
(True, ['rate', 'uncal', 'bad', 'o006_crfints', 'o001_crf'],
(['uncal', 'rate', 'o001_crf', 'o006_crfints', 'bad'], {'bad'})),
(False, ['rate', 'uncal', 'bad', 'o006_crfints', 'o001_crf'],
['uncal', 'rate', 'o001_crf', 'o006_crfints', 'bad'])])
def test_get_available_suffixes(untracked, input_suffixes, expected):
result = data_containers.get_available_suffixes(
input_suffixes, return_untracked=untracked)
assert result == expected
# TODO - These tests will need to be refactored to account for Django Models
# TODO - We will need to implement django based testing to account for all Model based tests.
"""
def test_get_current_flagged_anomalies(mocker):
# get a sample query group with 2 files
rootname = 'jw02589006001_04101_00001-seg001'
instrument = 'NIRSpec'
# mock a single shared anomaly type
mocker.patch.object(data_containers.di, 'session', MockSessionGroupAnomaly())
result = data_containers.get_current_flagged_anomalies(
rootname, instrument, n_match=2)
assert result == ['persistence']
# get a sample query for 1 file
rootname = 'jw02589006001_04101_00001-seg001_nrs1'
# mock two anomalies for this file
mocker.patch.object(data_containers.di, 'session', MockSessionFileAnomaly())
result = data_containers.get_current_flagged_anomalies(
rootname, instrument, n_match=1)
assert result == ['persistence', 'crosstalk']
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_get_anomaly_form_get(mocker):
request = MockGetRequest()
inst = 'NIRSpec'
file_root = 'jw02589006001_04101_00001-seg001_nrs1'
# mock two anomalies for this file
mocker.patch.object(data_containers.di, 'session',
MockSessionFileAnomaly())
form = data_containers.get_anomaly_form(request, inst, file_root)
# form should contain all anomaly options and two should be checked
html = str(form)
for anomaly in constants.ANOMALY_CHOICES_NIRSPEC:
assert anomaly[1] in html
assert html.count('checked') == 2
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_get_anomaly_form_post(mocker):
request = MockPostRequest()
inst = 'NIRSpec'
file_root = 'jw02589006001_04101_00001-seg001_nrs1'
# mock two anomalies for this file
mocker.patch.object(data_containers.di, 'session',
MockSessionFileAnomaly())
# post a different selection: others are deselected
request.POST['anomaly_choices'] = ['new_short']
# mock form validity and update functions
mocker.patch.object(data_containers.InstrumentAnomalySubmitForm,
'is_valid', return_value=True)
update_mock = mocker.patch.object(
data_containers.InstrumentAnomalySubmitForm, 'update_anomaly_table')
form = data_containers.get_anomaly_form(request, inst, file_root)
# form should contain all anomaly options and only
# the chosen one should be checked
html = str(form)
for anomaly in constants.ANOMALY_CHOICES_NIRSPEC:
assert anomaly[1] in html
assert html.count('checked') == 1
# message should indicate success, update should have been called
assert 'Anomaly submitted successfully' in request._messages.messages
assert update_mock.call_count == 1
# mock invalid form
mocker.patch.object(data_containers.InstrumentAnomalySubmitForm,
'is_valid', return_value=False)
data_containers.get_anomaly_form(request, inst, file_root)
# messages indicate failure, update is not called again
assert 'Failed to submit anomaly' in request._messages.messages
assert update_mock.call_count == 1
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_get_anomaly_form_post_group(mocker):
request = MockPostRequest()
inst = 'NIRSpec'
file_root = 'jw02589006001_04101_00001-seg001'
# mock anomalies for the group
mocker.patch.object(data_containers.di, 'session',
MockSessionGroupAnomaly())
# post a different selection: others are deselected,
# unless they belong only to the file, not to the group
# as a whole
request.POST['anomaly_choices'] = ['new_short']
# mock form validity and update functions
mocker.patch.object(data_containers.InstrumentAnomalySubmitForm,
'is_valid', return_value=True)
update_mock = mocker.patch.object(
data_containers.InstrumentAnomalySubmitForm, 'update_anomaly_table')
form = data_containers.get_anomaly_form(request, inst, file_root)
# form should contain all anomaly options and only
# the chosen one should be checked
html = str(form)
for anomaly in constants.ANOMALY_CHOICES_NIRSPEC:
assert anomaly[1] in html
assert html.count('checked') == 1
# message should indicate success, update should have been
# called for both files
assert 'Anomaly submitted successfully' in request._messages.messages
assert update_mock.call_count == 2
# mock invalid form
mocker.patch.object(data_containers.InstrumentAnomalySubmitForm,
'is_valid', return_value=False)
data_containers.get_anomaly_form(request, inst, file_root)
# messages indicate failure, update is not called again
assert 'Failed to submit anomaly' in request._messages.messages
assert update_mock.call_count == 2
"""
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
def test_get_dashboard_components():
request = MockPostRequest()
# empty POST
dash = data_containers.get_dashboard_components(request)
assert dash.delta_t is None
# POST contains time delta
request.POST['time_delta_value'] = True
# all time = None
request.POST['timedelta'] = 'All Time'
dash = data_containers.get_dashboard_components(request)
assert dash.delta_t is None
# specific value
request.POST['timedelta'] = '1 Day'
dash = data_containers.get_dashboard_components(request)
assert dash.delta_t == pd.DateOffset(days=1)
[docs]
@pytest.mark.parametrize('inst,fileroot,value',
[('NIRCam',
'jw01068001001_02102_00001_nrcb1', 59714),
('NIRSpec',
'jw02589006001_04101_00001-seg002_nrs2', 59777),
('NIRSpec', 'bad_filename', 0)])
def test_get_expstart(inst, fileroot, value):
"""Tests the ``get_expstart`` function."""
expstart = data_containers.get_expstart(inst, fileroot)
# if mast query failed, it will return 0
# otherwise, it should have a known value for this file
assert np.isclose(expstart, value, atol=1)
[docs]
def test_get_filenames_by_instrument():
"""Tests the ``get_filenames_by_instrument`` function."""
# queries MAST; should not need central storage
filepaths = data_containers.get_filenames_by_instrument('NIRCam', '1068')
assert isinstance(filepaths, list)
assert len(filepaths) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_filenames_by_proposal():
"""Tests the ``get_filenames_by_proposal`` function."""
pid = '2589'
filenames = data_containers.get_filenames_by_proposal(pid)
assert isinstance(filenames, list)
assert len(filenames) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_filenames_by_rootname():
"""Tests the ``get_filenames_by_rootname`` function."""
rname = 'jw02589006001_04101_00001-seg002_nrs2'
filenames = data_containers.get_filenames_by_rootname(rname)
assert isinstance(filenames, list)
assert len(filenames) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
@pytest.mark.parametrize('pid,rname,success',
[('2589', None, True),
(None, 'jw02589006001_04101_00001-seg002_nrs2', True),
('2589', 'jw02589006001_04101_00001-seg002_nrs2', True),
(None, None, False)])
def test_get_filesystem_filenames(pid, rname, success):
"""Tests the ``get_filesystem_filenames`` function."""
filenames = data_containers.get_filesystem_filenames(
proposal=pid, rootname=rname)
assert isinstance(filenames, list)
if not success:
assert len(filenames) == 0
else:
assert len(filenames) > 0
# check specific file_types
fits_files = [f for f in filenames if f.endswith('.fits')]
assert len(fits_files) < len(filenames)
fits_filenames = data_containers.get_filesystem_filenames(
proposal=pid, rootname=rname, file_types=['fits'])
assert isinstance(fits_filenames, list)
assert len(fits_filenames) > 0
assert len(fits_filenames) == len(fits_files)
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_filesystem_filenames_options():
"""Tests the ``get_filesystem_filenames`` function."""
pid = '2589'
# basenames only
filenames = data_containers.get_filesystem_filenames(
proposal=pid, full_path=False, file_types=['fits'])
assert not os.path.isfile(filenames[0])
# full path
filenames = data_containers.get_filesystem_filenames(
proposal=pid, full_path=True, file_types=['fits'])
assert os.path.isfile(filenames[0])
# sorted
sorted_filenames = data_containers.get_filesystem_filenames(
proposal=pid, sort_names=True, file_types=['fits'])
unsorted_filenames = data_containers.get_filesystem_filenames(
proposal=pid, sort_names=False, file_types=['fits'])
assert sorted_filenames != unsorted_filenames
assert sorted_filenames == sorted(unsorted_filenames)
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_image_info():
"""Tests the ``get_image_info`` function."""
image_info = data_containers.get_image_info('jw01068001001_02102_00001_nrcb1')
assert isinstance(image_info, dict)
keys = ['all_jpegs', 'suffixes', 'num_ints', 'all_files']
for key in keys:
assert key in image_info
[docs]
def test_get_instrument_proposals():
"""Tests the ``get_instrument_proposals`` function."""
# queries MAST, no need for central storage
proposals = data_containers.get_instrument_proposals('Fgs')
assert isinstance(proposals, list)
assert len(proposals) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to django models.')
@pytest.mark.parametrize('keys,viewed,sort_as,exp_type,cat_type',
[(None, None, None, None, None),
(None, 'viewed', None, None, None),
(None, 'Viewed', None, None, None),
(None, 'new', None, None, None),
(None, 'New', None, None, None),
(None, None, None, 'NRS_MSATA', None),
# (None, None, None, None, 'CAL'), # cat_type not implemented yet
(['expstart'], 'new', 'ascending', None, None),
(['expstart'], 'new', 'descending', None, None),
(['expstart'], 'new', 'recent', None, None),
([], 'viewed', None, None, None),
([], 'new', None, None, None),
([], None, None, None, None),
(['proposal', 'obsnum', 'other',
'prop_id', 'expstart'], 'viewed', None, None, None),
(['proposal', 'obsnum', 'other',
'prop_id', 'expstart'], 'new', None, None, None),
(['proposal', 'obsnum', 'other',
'prop_id', 'expstart'], None, None, None, None)])
def test_get_instrument_looks(keys, viewed, sort_as, exp_type, cat_type):
"""Tests the ``get_instrument_looks`` function."""
return_keys, looks = data_containers.get_instrument_looks(
'nirspec', additional_keys=keys, look=viewed, sort_as=sort_as,
exp_type=exp_type, cat_type=cat_type)
assert isinstance(return_keys, list)
assert isinstance(looks, list)
# returned keys always contains at least root name
assert len(return_keys) > 1
assert 'root_name' in return_keys
assert 'viewed' in return_keys
# they may also contain some keys from the instrument
# and any additional keys specified
if keys is not None:
assert len(return_keys) >= 1 + len(keys)
# viewed depends on local database, so may or may not have results
if not str(viewed).lower() == 'viewed':
assert len(looks) > 0
first_file = looks[0]
assert first_file['root_name'] != ''
assert isinstance(first_file['viewed'], bool)
assert len(first_file) == len(return_keys)
for key in return_keys:
assert key in first_file
last_file = looks[-1]
if sort_as == 'ascending':
assert last_file['root_name'] > first_file['root_name']
elif sort_as == 'recent':
assert last_file['expstart'] < first_file['expstart']
else:
assert last_file['root_name'] < first_file['root_name']
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_preview_images_by_proposal():
"""Tests the ``get_preview_images_by_proposal`` function."""
preview_images = data_containers.get_preview_images_by_proposal('1033')
assert isinstance(preview_images, list)
assert len(preview_images) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_preview_images_by_rootname():
"""Tests the ``get_preview_images_by_rootname`` function."""
preview_images = data_containers.get_preview_images_by_rootname('jw02589001001_02101_00001-seg001_nis')
assert isinstance(preview_images, list)
assert len(preview_images) > 0
[docs]
def test_get_proposals_by_category():
"""Tests the ``get_proposals_by_category`` function."""
# MAST query, no need for central storage
proposals_by_category = data_containers.get_proposals_by_category('fgs')
assert isinstance(proposals_by_category, dict)
assert len(proposals_by_category) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_proposal_info():
"""Tests the ``get_proposal_info`` function."""
filepaths = glob.glob(os.path.join(get_config()['filesystem'], 'jw01068', '*.fits'))
proposal_info = data_containers.get_proposal_info(filepaths)
assert isinstance(proposal_info, dict)
keys = ['num_proposals', 'proposals', 'thumbnail_paths', 'num_files']
for key in keys:
assert key in proposal_info
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_thumbnails_by_proposal():
"""Tests the ``get_thumbnails_by_proposal`` function."""
preview_images = data_containers.get_thumbnails_by_proposal('01033')
assert isinstance(preview_images, list)
assert len(preview_images) > 0
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_get_thumbnail_by_rootname():
"""Tests the ``get_thumbnail_by_rootname`` function."""
preview_images = data_containers.get_thumbnail_by_rootname('jw02589001001_02101_00001-seg001_nis')
assert isinstance(preview_images, str)
assert len(preview_images) > 0
assert preview_images != 'none'
preview_images = data_containers.get_thumbnail_by_rootname('invalid_rootname')
assert isinstance(preview_images, str)
assert len(preview_images) > 0
assert preview_images == 'none'
[docs]
def test_mast_query_by_rootname():
"""Tests the ``mast_query_by_rootname`` function."""
instrument = 'NIRCam'
rootname1 = 'jw02767002001_02103_00005_nrcb4'
dict_stuff = data_containers.mast_query_by_rootname(instrument, rootname1)
defaults = dict(filter=dict_stuff.get('filter', DEFAULT_MODEL_CHARFIELD),
detector=dict_stuff.get('detector', DEFAULT_MODEL_CHARFIELD),
exp_type=dict_stuff.get('exp_type', DEFAULT_MODEL_CHARFIELD),
read_pat=dict_stuff.get('readpatt', DEFAULT_MODEL_CHARFIELD),
grating=dict_stuff.get('grating', DEFAULT_MODEL_CHARFIELD),
patt_num=dict_stuff.get('patt_num', 0),
aperture=dict_stuff.get('apername', DEFAULT_MODEL_CHARFIELD),
subarray=dict_stuff.get('subarray', DEFAULT_MODEL_CHARFIELD),
pupil=dict_stuff.get('pupil', DEFAULT_MODEL_CHARFIELD))
assert isinstance(defaults, dict)
rootname2 = 'jw02084001001_04103_00001-seg003_nrca3'
dict_stuff = data_containers.mast_query_by_rootname(instrument, rootname2)
defaults = dict(filter=dict_stuff.get('filter', DEFAULT_MODEL_CHARFIELD),
detector=dict_stuff.get('detector', DEFAULT_MODEL_CHARFIELD),
exp_type=dict_stuff.get('exp_type', DEFAULT_MODEL_CHARFIELD),
read_pat=dict_stuff.get('readpatt', DEFAULT_MODEL_CHARFIELD),
grating=dict_stuff.get('grating', DEFAULT_MODEL_CHARFIELD),
patt_num=dict_stuff.get('patt_num', 0),
aperture=dict_stuff.get('apername', DEFAULT_MODEL_CHARFIELD),
subarray=dict_stuff.get('subarray', DEFAULT_MODEL_CHARFIELD),
pupil=dict_stuff.get('pupil', DEFAULT_MODEL_CHARFIELD))
assert isinstance(defaults, dict)
instrument2 = 'FGS'
rootname3 = 'jw01029003001_06201_00001_guider2'
dict_stuff = data_containers.mast_query_by_rootname(instrument2, rootname3)
defaults = dict(filter=dict_stuff.get('filter', DEFAULT_MODEL_CHARFIELD),
detector=dict_stuff.get('detector', DEFAULT_MODEL_CHARFIELD),
exp_type=dict_stuff.get('exp_type', DEFAULT_MODEL_CHARFIELD),
read_pat=dict_stuff.get('readpatt', DEFAULT_MODEL_CHARFIELD),
grating=dict_stuff.get('grating', DEFAULT_MODEL_CHARFIELD),
patt_num=dict_stuff.get('patt_num', 0),
aperture=dict_stuff.get('apername', DEFAULT_MODEL_CHARFIELD),
subarray=dict_stuff.get('subarray', DEFAULT_MODEL_CHARFIELD),
pupil=dict_stuff.get('pupil', DEFAULT_MODEL_CHARFIELD))
assert isinstance(defaults, dict)
[docs]
@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Requires access to central storage.')
def test_thumbnails_ajax():
"""Tests the ``get_thumbnails_ajax`` function."""
thumbnail_dict = data_containers.thumbnails_ajax('NIRCam', '1068')
assert isinstance(thumbnail_dict, dict)
keys = ['inst', 'file_data', 'tools', 'dropdown_menus', 'prop']
for key in keys:
assert key in thumbnail_dict