|
8 | 8 |
|
9 | 9 | import ckan.tests.factories as factories |
10 | 10 | import dclab |
11 | | -from dclab.rtdc_dataset import fmt_http |
| 11 | +from dclab.rtdc_dataset import fmt_dcor, fmt_http |
12 | 12 | import h5py |
| 13 | +import numpy as np |
13 | 14 |
|
14 | 15 | import pytest |
15 | 16 |
|
@@ -606,6 +607,72 @@ def test_api_dcserv_tables(enqueue_job_mock, app): |
606 | 607 | assert "brightness" in names |
607 | 608 |
|
608 | 609 |
|
| 610 | +@pytest.mark.ckan_config('ckan.plugins', 'dcor_schemas dc_serve') |
| 611 | +@pytest.mark.usefixtures('with_plugins', 'clean_db') |
| 612 | +@mock.patch('ckan.plugins.toolkit.enqueue_job', |
| 613 | + side_effect=synchronous_enqueue_job) |
| 614 | +def test_api_dcserv_tables_with_nan(enqueue_job_mock, app, tmp_path): |
| 615 | + """ |
| 616 | + Tables may contain NaN-data. These should be converted into None |
| 617 | + before they are encoded with JSON and sent as response. |
| 618 | + """ |
| 619 | + user = factories.UserWithToken() |
| 620 | + owner_org = factories.Organization(users=[{ |
| 621 | + 'name': user['id'], |
| 622 | + 'capacity': 'admin' |
| 623 | + }]) |
| 624 | + # Note: `call_action` bypasses authorization! |
| 625 | + create_context = {'ignore_auth': False, |
| 626 | + 'user': user['name'], 'api_version': 3} |
| 627 | + |
| 628 | + # generate a resource with nan-valued tables |
| 629 | + path_mod = tmp_path / 'blood_nan.rtdc' |
| 630 | + shutil.copy2(data_path / "cytoshot_blood.rtdc", path_mod) |
| 631 | + |
| 632 | + # generate a table |
| 633 | + table_data = { |
| 634 | + "fox": np.arange(10), |
| 635 | + "peter": np.linspace(-1, 1, 10), |
| 636 | + "deril": np.zeros(10), |
| 637 | + } |
| 638 | + # this is the important bit for this test |
| 639 | + table_data["peter"][2] = np.nan |
| 640 | + |
| 641 | + with dclab.RTDCWriter(path_mod) as hw: |
| 642 | + hw.store_table("nan-array", table_data) |
| 643 | + |
| 644 | + # create a dataset |
| 645 | + ds_dict, res_dict = make_dataset_via_s3( |
| 646 | + create_context=create_context, |
| 647 | + owner_org=owner_org, |
| 648 | + resource_path=path_mod, |
| 649 | + activate=True) |
| 650 | + |
| 651 | + resp = app.get( |
| 652 | + "/api/3/action/dcserv", |
| 653 | + params={"id": res_dict["id"], |
| 654 | + "query": "tables", |
| 655 | + }, |
| 656 | + headers={"Authorization": user["token"]}, |
| 657 | + status=200 |
| 658 | + ) |
| 659 | + jres = json.loads(resp.body) |
| 660 | + assert jres["success"] |
| 661 | + assert "nan-array" in jres["result"] |
| 662 | + names, data = jres["result"]["nan-array"] |
| 663 | + assert "peter" in names |
| 664 | + assert data[1][2] is None |
| 665 | + |
| 666 | + # now open the same dataset with dclab |
| 667 | + host = f"http://{app.config['CKAN_HOST']}:{app.config['CKAN_PORT']}" |
| 668 | + ds = fmt_dcor.RTDC_DCOR( |
| 669 | + url=f"{host}/api/3/action/dcserv?id={res_dict['id']}&query=tables", |
| 670 | + api_key=user["token"]) |
| 671 | + assert "nan-array" in ds.tables |
| 672 | + assert np.isnan(ds.tables["nan-array"]["peter"][2]) |
| 673 | + assert not np.isnan(ds.tables["nan-array"]["peter"][1]) |
| 674 | + |
| 675 | + |
609 | 676 | @pytest.mark.ckan_config('ckan.plugins', 'dcor_schemas dc_serve') |
610 | 677 | @pytest.mark.usefixtures('with_plugins', 'clean_db') |
611 | 678 | @mock.patch('ckan.plugins.toolkit.enqueue_job', |
|
0 commit comments