def test_update_bad_field():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform update
    doc_id = '000000000000000000000002'
    doc = search_by_id(doc_id)
    new_doc_id, error_msg = update(doc_id, remove_doc=False, \
        update_pairs={'bad_field':'val'}, \
        new_meas_objects=[], \
        meas_remove_indices=[] \
    )
    assert new_doc_id == None

    # test that doc did not get transferred
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert oldversion_doc == None

    #test that currversion doc was not inserted
    all_docs = query_for_all_docs()
    for doc in all_docs:
        assert 'bad_field' not in list(doc.keys())
def test_update_new_meas_objects_str_for_val_b():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    new_meas_objects = [{
        'isotope': 'U-235',
        'type': 'range',
        'unit': 'g',
        'value': ['a', 'b']
    }]
    doc_id = '000000000000000000000002'
    orig_doc = search_by_id(doc_id)
    new_doc_id, error_msg = update(doc_id,
                                   remove_doc=False,
                                   new_meas_objects=new_meas_objects)
    assert new_doc_id == None

    # test that doc got transferred
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert oldversion_doc == None

    # test no change to original doc
    new_doc = search_by_id(doc_id)
    assert len(new_doc['measurement']['results']) == len(
        orig_doc['measurement']['results'])
def test_update_new_meas_objects():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    new_meas_objects = [{
        'isotope': 'K-40',
        'type': 'measurement',
        'unit': 'g/cm',
        'value': [0.2]
    }, {
        'isotope': 'U-235',
        'type': 'range',
        'unit': 'g',
        'value': [0.3, 2.1]
    }]
    doc_id = '000000000000000000000002'
    orig_doc = search_by_id(doc_id)
    new_doc_id, error_msg = update(doc_id,
                                   remove_doc=False,
                                   new_meas_objects=new_meas_objects)
    assert new_doc_id != None
    new_doc_id = str(new_doc_id)

    # test that doc got transferred
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert oldversion_doc == orig_doc

    # test new (current version) doc
    new_doc = search_by_id(new_doc_id)

    # test version num
    orig_doc.pop('_version')
    new_version = new_doc.pop('_version')
    assert new_version == 2

    # test parent id
    orig_doc.pop('_id')
    parent_id = new_doc.pop('_parent_id')
    assert parent_id == doc_id

    # test id once more
    new_version_doc_id = str(new_doc.pop('_id'))
    assert new_doc_id == new_version_doc_id

    # test orig doc and curr version doc equality
    len_orig_meas_results = len(orig_doc['measurement'].pop('results'))
    assert new_doc['measurement'].pop(
        'results')[len_orig_meas_results:] == new_meas_objects
    assert orig_doc == new_doc
def test_update_remove_doc():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform update
    doc_id = '000000000000000000000002'
    doc = search_by_id(doc_id)  #, db_obj=db_obj)
    new_doc_id, error_msg = update(doc_id, remove_doc=True)  #, db_obj=db_obj)
    assert new_doc_id == None

    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert doc == oldversion_doc
def test_update_meas_remove_indices():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    remove_indices = [0, 2]  # list len is 3
    doc_id = '000000000000000000000002'
    orig_doc = search_by_id(doc_id, db_obj=db_obj)
    new_doc_id, error_msg = update(doc_id,
                                   remove_doc=False,
                                   meas_remove_indices=remove_indices)
    assert new_doc_id != None
    new_doc_id = str(new_doc_id)

    # test that doc got transferred
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert oldversion_doc == orig_doc

    # test new (current version) doc
    new_doc = search_by_id(new_doc_id)

    # test version num
    orig_doc.pop('_version')
    new_version = new_doc.pop('_version')
    assert new_version == 2

    # test parent id
    orig_doc.pop('_id')
    parent_id = new_doc.pop('_parent_id')
    assert parent_id == doc_id

    # test id once more
    new_version_doc_id = str(new_doc.pop('_id'))
    assert new_doc_id == new_version_doc_id

    # test orig doc and curr version doc equality
    orig_meas_results = orig_doc['measurement'].pop('results')
    new_meas_results = new_doc['measurement'].pop('results')
    assert len(new_meas_results) == 1
    assert new_meas_results[0] == orig_meas_results[1]
    assert orig_doc == new_doc
def test_update_nochange():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform update
    doc_id = '000000000000000000000002'
    doc = search_by_id(doc_id)  #, db_obj=db_obj)
    new_doc_id, error_msg = update(doc_id, remove_doc=False, \
        update_pairs={}, \
        new_meas_objects=[], \
        meas_remove_indices=[] \
    )
    assert new_doc_id != None
    assert type(new_doc_id) is ObjectId
    new_doc_id = str(new_doc_id)

    # test value in oldversion database
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert doc == oldversion_doc

    # test currversion doc
    currversion_doc = search_by_id(new_doc_id)  #, db_obj=db_obj)

    # test version num
    doc.pop('_version')
    new_version = currversion_doc.pop('_version')
    assert new_version == 2

    # test parent id
    doc.pop('_id')
    parent_id = currversion_doc.pop('_parent_id')
    assert parent_id == doc_id

    # test id once more
    new_version_doc_id = str(currversion_doc.pop('_id'))
    assert new_doc_id == new_version_doc_id

    # test orig doc and curr version doc equality
    assert doc == currversion_doc
def test_update_meas_remove_indices_bad_idx():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    remove_indices = [4]  # list len is 3
    doc_id = '000000000000000000000002'
    orig_doc = search_by_id(doc_id)
    new_doc_id, error_msg = update(doc_id,
                                   remove_doc=False,
                                   meas_remove_indices=remove_indices)
    assert new_doc_id == None

    # test that doc did not get transferred
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert oldversion_doc == None

    # test no change to original doc
    new_doc = search_by_id(doc_id)
    assert len(new_doc['measurement']['results']) == len(
        orig_doc['measurement']['results'])
def test_insert_partial_doc():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform insert
    sample_name = 'testing sample name'
    sample_description = 'testing sample description'
    data_reference = 'testing data reference'
    data_input_name = 'testing data input name'
    data_input_contact = 'testing data input contact'
    data_input_date = ['2020-02-20']
    measurement_description = 'testing measurement description'
    data_input_notes = 'testing data input notes'

    new_doc_id, error_msg = insert(sample_name, sample_description, data_reference, data_input_name, data_input_contact, data_input_date, \
    measurement_description=measurement_description, data_input_notes=data_input_notes)
    assert new_doc_id != None, error_msg

    new_doc = search_by_id(new_doc_id)  #, db_obj=db_obj)
    assert new_doc['sample']['name'] == sample_name
    assert new_doc['sample']['description'] == sample_description
    assert new_doc['data_source']['reference'] == data_reference
    assert new_doc['data_source']['input']['name'] == data_input_name
    assert new_doc['data_source']['input']['contact'] == data_input_contact
    assert [
        date_obj.strftime('%Y-%m-%d')
        for date_obj in new_doc['data_source']['input']['date']
    ] == data_input_date
    assert new_doc['grouping'] == ''
    assert new_doc['sample']['source'] == ''
    assert new_doc['sample']['id'] == ''
    assert new_doc['sample']['owner']['name'] == ''
    assert new_doc['sample']['owner']['contact'] == ''
    assert new_doc['measurement']['results'] == []
    assert new_doc['measurement']['practitioner']['name'] == ''
    assert new_doc['measurement']['practitioner']['contact'] == ''
    assert new_doc['measurement']['technique'] == ''
    assert new_doc['measurement']['institution'] == ''
    assert new_doc['measurement']['date'] == []
    assert new_doc['measurement']['description'] == measurement_description
    assert new_doc['measurement']['requestor']['name'] == ''
    assert new_doc['measurement']['requestor']['contact'] == ''
    assert new_doc['data_source']['input']['notes'] == data_input_notes
def test_insert_meas_values_strings_a():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform insert
    sample_name = 'testing sample name'
    sample_description = 'testing sample description'
    data_reference = 'testing data reference'
    data_input_name = 'testing data input name'
    data_input_contact = 'testing data input contact'
    data_input_date = ['2020-02-20']
    measurement_results = [{
        'isotope': 'K-40',
        'type': 'measurement',
        'unit': 'ppm',
        'value': [1.3, 3.1]
    }]

    new_doc_id, error_msg = insert(sample_name, sample_description, data_reference, data_input_name, data_input_contact, data_input_date, \
    measurement_results=measurement_results)
    assert new_doc_id != None, error_msg

    new_doc = search_by_id(new_doc_id)  #, db_obj=db_obj)
    assert new_doc['sample']['name'] == sample_name
    assert new_doc['sample']['description'] == sample_description
    assert new_doc['data_source']['reference'] == data_reference
    assert new_doc['data_source']['input']['name'] == data_input_name
    assert new_doc['data_source']['input']['contact'] == data_input_contact
    assert [
        date_obj.strftime('%Y-%m-%d')
        for date_obj in new_doc['data_source']['input']['date']
    ] == data_input_date
    assert new_doc['measurement']['results'] == measurement_results
Ejemplo n.º 10
0
def update_endpoint():
    """Finds the document with the given ID in the database and updates its fields and values with the fields and values that the user supplies in the form data.

    GET request:
        Renders the page for a user to specify a document ID to search for.
    POST request:
        If the "submit_button" form data value is "find_doc", extract the "doc_id" value, search for it in the database, and return the update page with the found document's fields and values. If the "submit_button" value is "update_doc", extract all the new user-specified fields and values and update the document in the database with them.
        form data:
            * submit_button (str): one of "find_doc" or "update_doc", this field dictates what operation to perform on the back-end
            * doc_id (str): this should only be present if the "find_doc" option is specified
            * grouping (str): the updated value for experiment name
            * sample.name (str): the updated value for concise sample description
            * sample.description (str): the updated value for more detailed sample description
            * sample.source (str): the updated value for where the sample came from
            * sample.id (str): the updated value for sample identification number
            * sample.owner.name (str): the updated value for who owns the sample
            * sample.owner.contact (str): the updated value for email of the person who owns the sample
            * data_source.reference (str): the updated value for where the data came from
            * data_source.input.notes (str): the updated value for input simplifications, assumptions, etc.
            * data_source.input.name (str): the updated value for who performed the data input
            * data_source.input.contact (str): the updated value for email of the person who performed the data input
            * measurement.technique (str): the updated value for technique name
            * measurement.institution (str): the updated value for name of the institution where the measurement was performed
            * measurement.description (str): the updated value for detailed description
            * measurement.date (str): the updated value for date when measurement was performed
            * measurement.results.isotopeX (str): the updated value for the value of the isotope for the measurement X where X is any positive integer.
            * measurement.results.typeX (str): the updated value for the type of the measurement X ("measurement", "range", or "limit") where X is any positive integer.
            * measurement.results.unitX (str): the updated value for the units of the measurement X values where X is any positive integer.
            * measurement.results.valueAX (str): the updated value for the first value of the measurement X where X is any positive integer. If measurement.results.typeX is "measurement", this value is the central value. If measurement.results.typeX is "range", this value is the lower limit. If measurement.results.typeX is "limit", this value is the upper limit.
            * measurement.results.valueBX (str): the updated value for the second value of the measurement X where X is any positive integer. If measurement.results.typeX is "measurement", this value is the symmetric error. If measurement.results.typeX is "range", this value is the upper limit. If measurement.results.typeX is "limit", this value is the confidence level.
            * measurement.results.valueCX (str): the updated value for the third value of the measurement X where X is any positive integer. If measurement.results.typeX is "measurement", this value is the asymmetric error. If measurement.results.typeX is "range", this value is the confidence level. If measurement.results.typeX is "limit", this value should not be present.
            * measurement.requestor.name (str): the updated value for who coordinated the measurement
            * measurement.requestor.contact (str): the updated value for email of the person who coordinated the measurement
            * measurement.practitioner.name (str): the updated value for who performed the measurement
            * measurement.practitioner.contact (str): the updated value for email of the person who performed the measurement
            * current.measurement.results.isotopeX (str): the document's original value of the isotope for the measurement X where X is any positive integer.
            * current.measurement.results.typeX (str): the document's original type of the measurement X ("measurement", "range", or "limit") where X is any positive integer.
            * current.measurement.results.unitX (str): the document's original units of the measurement X values where X is any positive integer.
            * current.measurement.results.valueAX (str): the document's original first value of the measurement X where X is any positive integer.
            * current.measurement.results.valueBX (str): the document's original second value of the measurement X where X is any positive integer.
            * current.measurement.results.valueCX (str): the document's original third value of the measurement X where X is any positive integer.
            * new.measurement.results.isotopeX (str): the value of the isotope for the measurement X where X is any positive integer, and where this value is being added for a measurement result that is not part of the original document
            * new.measurement.results.typeX (str): the type of the measurement X ("measurement", "range", or "limit") where X is any positive integer, and where this value is being added for a measurement result that is not part of the original document
            * new.measurement.results.unitX (str): the units of the measurement X values where X is any positive integer, and where this value is being added for a measurement result that is not part of the original document
            * new.measurement.results.valueAX (str): the first value of the measurement X where X is any positive integer, and where this value is being added for a measurement result that is not part of the original document
            * new.measurement.results.valueBX (str): the second value of the measurement X where X is any positive integer, and where this value is being added for a measurement result that is not part of the original document
            * new.measurement.results.valueCX (str): the third value of the measurement X where X is any positive integer, and where this value is being added for a measurement result that is not part of the original document
            * remove.grouping (str): if present and not an empty string, remove the current value for the grouping field
            * remove.sample.name (str): if present and not an empty string, remove the current value for the sample.name field
            * remove.sample.description (str): if present and not an empty string, remove the current value for the sample.description field
            * remove.sample.source (str): if present and not an empty string, remove the current value for the sample.source field
            * remove.sample.id (str): if present and not an empty string, remove the current value for the sample.id field
            * remove.sample.owner.name (str): if present and not an empty string, remove the current value for the sample.owner.name field
            * remove.sample.owner.contact (str): if present and not an empty string, remove the current value for the sample.owner.contact field
            * remove.data_source.reference (str): if present and not an empty string, remove the current value for the data_source.reference field
            * remove.data_source.input.notes (str): if present and not an empty string, remove the current value for the data_source.input.notes field
            * remove.data_source.input.name (str): if present and not an empty string, remove the current value for the data_source.input.name field
            * remove.data_source.input.contact (str): if present and not an empty string, remove the current value for the data_source.input.contact field
            * remove.measurement.technique (str): if present and not an empty string, remove the current value for the measurement.technique field
            * remove.measurement.institution (str): if present and not an empty string, remove the current value for the measurement.institution field
            * remove.measurement.description (str): if present and not an empty string, remove the current value for the measurement.description field
            * remove.measurement.date (str): if present and not an empty string, remove the current value for the measurement.date field
            * remove.measurement.resultsX (str): if present and not an empty string, remove the entire measurement result at position X in the documents measurement results list where X is a positive integer
            * remove.measurement.results.isotopeX (str): if present and not an empty string, remove the current value for the measurement.results.isotopeX field
            * remove.measurement.results.typeX (str): if present and not an empty string, remove the current value for the measurement.results.typeX field
            * remove.measurement.results.unitX (str): if present and not an empty string, remove the current value for the measurement.results.unitX field
            * remove.measurement.results.valueAX (str): if present and not an empty string, remove the current value for the measurement.results.valueAX field
            * remove.measurement.results.valueBX (str): if present and not an empty string, remove the current value for the measurement.results.valueBX field
            * remove.measurement.results.valueCX (str): if present and not an empty string, remove the current value for the measurement.results.valueCX field
            * remove.measurement.requestor.name (str): if present and not an empty string, remove the current value for the measurement.requestor.name field
            * remove.measurement.requestor.contact (str): if present and not an empty string, remove the current value for the measurement.requestor.contact field
            * remove.measurement.practitioner.name (str): if present and not an empty string, remove the current value for the measurement.practitioner.name field
            * remove.measurement.practitioner.contact (str): if present and not an empty string, remove the current value for the measurement.practitioner.contact field
    """
    if request.method == "GET":
        return render_template('update.html', doc_data=False, message="")

    elif request.form.get("submit_button") == "find_doc":
        doc_id = request.form.get('doc_id', '')
        doc = search_by_id(doc_id, db_obj)

        if doc is None:
            return render_template(
                'update.html',
                doc_data=False,
                message="No document was found with the ID you provided.")

        for i in range(len(doc['measurement']['results'])):
            num_vals = len(doc['measurement']['results'][i]['value'])
            if num_vals == 0:
                doc['measurement']['results'][i]['value'] = []
            if num_vals < 2:
                doc['measurement']['results'][i]['value'].append('')
            if num_vals < 3:
                doc['measurement']['results'][i]['value'].append('')

        return render_template('update.html', doc_data=True, doc_id=doc['_id'], \
                grouping=doc['grouping'], \
                sample_name=doc['sample']['name'], \
                sample_description=doc['sample']['description'], \
                sample_source=doc['sample']['source'], \
                sample_id=doc['sample']['id'], \
                sample_owner_name=doc['sample']['owner']['name'], \
                sample_owner_contact=doc['sample']['owner']['contact'], \
                data_reference=doc['data_source']['reference'], \
                data_input_name=doc['data_source']['input']['name'], \
                data_input_contact=doc['data_source']['input']['contact'], \
                data_input_date=' '.join([convert_date_to_str(date_ele) for date_ele in doc['data_source']['input']['date']]), \
                data_input_notes=doc['data_source']['input']['notes'], \
                measurement_practitioner_name=doc['measurement']['practitioner']['name'], \
                measurement_practitioner_contact=doc['measurement']['practitioner']['contact'], \
                measurement_technique=doc['measurement']['technique'], \
                measurement_institution=doc['measurement']['institution'], \
                measurement_date=' '.join([convert_date_to_str(date_ele) for date_ele in doc['measurement']['date']]), \
                measurement_description=doc['measurement']['description'], \
                measurement_requestor_name=doc['measurement']['requestor']['name'], \
                measurement_requestor_contact=doc['measurement']['requestor']['contact'], \
                measurement_results=doc['measurement']['results']
            )

    elif request.form.get("submit_button") == "update_doc":
        doc_id, remove_doc, update_pairs, meas_remove_indices, meas_add_eles = parse_update(
            request.form)
        new_doc_id, error_msg = perform_update(doc_id, remove_doc,
                                               update_pairs,
                                               meas_remove_indices,
                                               meas_add_eles, db_obj)
        if new_doc_id != None:
            message = "update success. New doc version ID: " + str(new_doc_id)
        else:
            message = 'Error: ' + error_msg
            logger.error(message)
        return render_template('update.html', doc_data=False, message=message)
    return None
def test_insert_complete_doc():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform insert
    sample_name = 'testing sample name'
    sample_description = 'testing sample description'
    data_reference = 'testing data reference'
    data_input_name = 'testing data input name'
    data_input_contact = 'testing data input contact'
    data_input_date = ['2020-02-20']
    grouping = 'testing grouping'
    sample_source = 'testing sample source'
    sample_id = 'testing sample id'
    sample_owner_name = 'testing sample owner name'
    sample_owner_contact = 'testing sample owner contact'
    measurement_results = [{
        'isotope': 'K-40',
        'type': 'measurement',
        'unit': 'ppm',
        'value': [1.3, 3.1]
    }, {
        'isotope': 'U-235',
        'type': 'limit',
        'unit': 'g',
        'value': [555, 900]
    }]
    measurement_practitioner_name = 'testing measurement practitioner name'
    measurement_practitioner_contact = 'testing measurement practitioner contact'
    measurement_technique = 'testing measurement technique'
    measurement_institution = 'testing measurement institution'
    measurement_date = ['2020-20-02', '1940-20-10']
    measurement_description = 'testing measurement description'
    measurement_requestor_name = 'testing measurement requestor name'
    measurement_requestor_contact = 'testing measurement requestor contact'
    data_input_notes = 'testing data input notes'

    new_doc_id, error_msg = insert(sample_name, sample_description, data_reference, data_input_name, data_input_contact, data_input_date, \
    grouping=grouping, sample_source=sample_source, sample_id=sample_id, sample_owner_name=sample_owner_name, sample_owner_contact=sample_owner_contact, \
    measurement_results=measurement_results, measurement_practitioner_name=measurement_practitioner_name, measurement_practitioner_contact=measurement_practitioner_contact, \
    measurement_technique=measurement_technique, measurement_institution=measurement_institution, measurement_date=measurement_date, measurement_description=measurement_description, \
    measurement_requestor_name=measurement_requestor_name, measurement_requestor_contact=measurement_requestor_contact, data_input_notes=data_input_notes)
    assert new_doc_id != None, error_msg

    new_doc = search_by_id(new_doc_id)  #, db_obj=db_obj)
    assert new_doc['sample']['name'] == sample_name
    assert new_doc['sample']['description'] == sample_description
    assert new_doc['data_source']['reference'] == data_reference
    assert new_doc['data_source']['input']['name'] == data_input_name
    assert new_doc['data_source']['input']['contact'] == data_input_contact
    assert [
        date_obj.strftime('%Y-%m-%d')
        for date_obj in new_doc['data_source']['input']['date']
    ] == data_input_date
    assert new_doc['grouping'] == grouping
    assert new_doc['sample']['source'] == sample_source
    assert new_doc['sample']['id'] == sample_id
    assert new_doc['sample']['owner']['name'] == sample_owner_name
    assert new_doc['sample']['owner']['contact'] == sample_owner_contact
    assert new_doc['measurement']['results'] == measurement_results
    assert new_doc['measurement']['practitioner'][
        'name'] == measurement_practitioner_name
    assert new_doc['measurement']['practitioner'][
        'contact'] == measurement_practitioner_contact
    assert new_doc['measurement']['technique'] == measurement_technique
    assert new_doc['measurement']['institution'] == measurement_institution
    assert [
        date_obj.strftime('%Y-%d-%m')
        for date_obj in new_doc['measurement']['date']
    ] == measurement_date
    assert new_doc['measurement']['description'] == measurement_description
    assert new_doc['measurement']['requestor'][
        'name'] == measurement_requestor_name
    assert new_doc['measurement']['requestor'][
        'contact'] == measurement_requestor_contact
    assert new_doc['data_source']['input']['notes'] == data_input_notes
def test_update_all():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    update_pairs = {
        'grouping': 'new test value',
        'data_source.input.contact': '*****@*****.**',
        'measurement.results.0.unit': 'g',
        'measurement.date': ['2020-10-21']
    }
    new_meas_objects = [{
        'isotope': 'K-40',
        'type': 'measurement',
        'unit': 'g/cm',
        'value': [0.2]
    }, {
        'isotope': 'U-235',
        'type': 'range',
        'unit': 'g',
        'value': [0.3, 2.1]
    }]
    remove_indices = [1, 2]
    doc_id = '000000000000000000000002'
    orig_doc = search_by_id(doc_id)
    new_doc_id, error_msg = update(doc_id,
                                   remove_doc=False,
                                   update_pairs=update_pairs,
                                   new_meas_objects=new_meas_objects,
                                   meas_remove_indices=remove_indices)
    assert new_doc_id != None
    new_doc_id = str(new_doc_id)

    # test that doc got transferred
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert oldversion_doc == orig_doc

    # test new (current version) doc
    new_doc = search_by_id(new_doc_id)

    # test version num
    orig_doc.pop('_version')
    new_version = new_doc.pop('_version')
    assert new_version == 2

    # test parent id
    orig_doc.pop('_id')
    parent_id = new_doc.pop('_parent_id')
    assert parent_id == doc_id

    # test id once more
    new_version_doc_id = str(new_doc.pop('_id'))
    assert new_doc_id == new_version_doc_id

    # correct the date values to be datetime objects now, not strings
    for update_key in ['measurement.date', 'data_source.input.date']:
        if update_key in list(update_pairs.keys()):
            for i in range(len(update_pairs[update_key])):
                update_pairs[update_key][i] = convert_str_to_date(
                    update_pairs[update_key][i])

    # test orig doc and curr version doc equality
    for update_key in update_pairs:
        new_val = update_pairs[update_key]
        key_parts = update_key.split('.')
        if len(key_parts) == 1:
            orig_doc.pop(key_parts[0])
            assert new_doc.pop(key_parts[0]) == new_val
        elif len(key_parts) == 2:
            orig_doc[key_parts[0]].pop(key_parts[1])
            assert new_doc[key_parts[0]].pop(key_parts[1]) == new_val
        elif len(key_parts) == 3:
            orig_doc[key_parts[0]][key_parts[1]].pop(key_parts[2])
            assert new_doc[key_parts[0]][key_parts[1]].pop(
                key_parts[2]) == new_val
        elif len(key_parts) == 4:
            try:
                key_parts_2 = int(key_parts[2])
            except:
                key_parts_2 = key_parts[2]
            orig_doc[key_parts[0]][key_parts[1]][key_parts_2].pop(key_parts[3])
            assert new_doc[key_parts[0]][key_parts[1]][key_parts_2].pop(
                key_parts[3]) == new_val
        else:
            assert 0 == 1

    orig_meas = orig_doc['measurement'].pop('results')
    meas_eles = new_doc['measurement'].pop('results')
    for new_meas in new_meas_objects:
        assert new_meas in meas_eles
    for removed_meas in [orig_meas[1], orig_meas[2]]:
        assert removed_meas not in meas_eles

    assert orig_doc == new_doc
def test_update_update_pairs_update_twice():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # PERFORM AND TEST FIRST UPDATE
    u1_doc_id = '000000000000000000000002'
    u1_doc = search_by_id(u1_doc_id)
    u1_update_pairs = {
        'grouping': 'new test value',
        'data_source.input.contact': '*****@*****.**',
        'measurement.results.0.unit': 'g',
        'measurement.date': ['2020-10-21']
    }
    u1_new_doc_id, u1_error_msg = update(u1_doc_id, remove_doc=False, \
        update_pairs=u1_update_pairs, \
        new_meas_objects=[], \
        meas_remove_indices=[] \
    )
    assert u1_new_doc_id != None
    u1_new_doc_id = str(u1_new_doc_id)

    # test value in oldversion database
    u1_oldversion_doc = search_by_id(u1_doc_id, coll_type='old_versions')
    assert (u1_doc == u1_oldversion_doc)

    # test new (current version) doc
    u1_new_doc = search_by_id(u1_new_doc_id)

    # test version num
    u1_doc.pop('_version')
    u1_new_version = u1_new_doc.pop('_version')
    assert u1_new_version == 2

    # test parent id
    u1_doc.pop('_id')
    u1_parent_id = u1_new_doc.pop('_parent_id')
    assert u1_parent_id == u1_doc_id

    # test id once more
    u1_new_version_doc_id = str(u1_new_doc.pop('_id'))
    assert u1_new_doc_id == u1_new_version_doc_id

    # test orig doc and curr version doc equality
    u1_doc.pop('grouping')
    u1_doc['data_source']['input'].pop('contact')
    u1_doc['measurement']['results'][0].pop('unit')
    u1_doc['measurement'].pop('date')
    assert u1_new_doc.pop('grouping') == 'new test value'
    assert u1_new_doc['data_source']['input'].pop(
        'contact') == '*****@*****.**'
    assert u1_new_doc['measurement']['results'][0].pop('unit') == 'g'
    assert u1_new_doc['measurement'].pop('date') == [
        datetime.datetime(2020, 10, 21)
    ]
    assert u1_doc == u1_new_doc

    # PERFORM AND TEST SECOND UPDATE
    u2_doc_id = u1_new_version_doc_id
    u2_doc = search_by_id(u2_doc_id)
    u2_update_pairs = {'grouping': 'test value two'}
    u2_new_doc_id, u2_error_msg = update(u2_doc_id,
                                         remove_doc=False,
                                         update_pairs=u2_update_pairs)
    assert u2_new_doc_id != None
    u2_new_doc_id = str(u2_new_doc_id)

    u2_oldversion_doc = search_by_id(u2_doc_id, coll_type='old_versions')
    assert u2_doc == u2_oldversion_doc

    u2_new_doc = search_by_id(u2_new_doc_id)

    u2_doc.pop('_version')
    u2_new_version = u2_new_doc.pop('_version')
    assert u2_new_version == 3

    u2_doc.pop('_id')
    u2_parent_id = u2_new_doc.pop('_parent_id')
    assert u2_parent_id == u2_doc_id

    u2_new_doc.pop('_id')
    u2_doc.pop('grouping')
    assert u2_new_doc.pop('grouping') == 'test value two'
def test_update_update_pairs_all():
    os.environ[
        'TOOLKIT_CONFIG_NAME'] = '../dunetoolkit/toolkit_config_test.json'

    # set up database to be updated
    teardown_db_for_test()
    db_obj = set_up_db_for_test()

    # perform update
    doc_id = '000000000000000000000002'
    doc = search_by_id(doc_id)
    update_pairs = {
        'grouping': 'new test value',
        'sample.name': 'testing sample name',
        'sample.description': 'test descrip',
        'sample.source': 'example src',
        'sample.id': '123456test',
        'sample.owner.name': 'test',
        'sample.owner.contact': '*****@*****.**',
        'measurement.results.0.isotope': 'K-40',
        'measurement.results.0.type': 'range',
        'measurement.results.0.unit': 'g',
        'measurement.results.0.value': [10.3, 12.9],
        'measurement.practitioner.name': 'tester',
        'measurement.practitioner.contact': '*****@*****.**',
        'measurement.technique': 'test',
        'measurement.institution': 'test place',
        'measurement.date': ['2020-10-21'],
        'measurement.description': 'test descrip',
        'measurement.requestor.name': 'test requestor',
        'measurement.requestor.contact': '*****@*****.**',
        'data_source.reference': 'testing',
        'data_source.input.name': 'testing',
        'data_source.input.contact': '*****@*****.**',
        'data_source.input.date': ['2010/18/02', '2020-10-21'],
        'data_source.input.notes': 'test test test',
    }
    new_doc_id, error_msg = update(doc_id, remove_doc=False, \
        update_pairs=update_pairs, \
        new_meas_objects=[], \
        meas_remove_indices=[] \
    )
    assert new_doc_id != None
    new_doc_id = str(new_doc_id)

    # test value in oldversion database
    oldversion_doc = search_by_id(doc_id, coll_type='old_versions')
    assert (doc == oldversion_doc)

    # test currversion doc
    currversion_doc = search_by_id(new_doc_id)

    # test version num
    doc.pop('_version')
    new_version = currversion_doc.pop('_version')
    assert new_version == 2

    # test parent id
    doc.pop('_id')
    parent_id = currversion_doc.pop('_parent_id')
    assert parent_id == doc_id

    # test id once more
    new_version_doc_id = str(currversion_doc.pop('_id'))
    assert new_doc_id == new_version_doc_id

    # correct the date values to be datetime objects now, not strings
    for update_key in ['measurement.date', 'data_source.input.date']:
        for i in range(len(update_pairs[update_key])):
            update_pairs[update_key][i] = convert_str_to_date(
                update_pairs[update_key][i])

    # test orig doc and curr version doc equality
    for update_key in update_pairs:
        new_val = update_pairs[update_key]
        key_parts = update_key.split('.')

        if len(key_parts) == 1:
            doc.pop(key_parts[0])
            assert currversion_doc.pop(key_parts[0]) == new_val
        elif len(key_parts) == 2:
            doc[key_parts[0]].pop(key_parts[1])
            assert currversion_doc[key_parts[0]].pop(key_parts[1]) == new_val
        elif len(key_parts) == 3:
            doc[key_parts[0]][key_parts[1]].pop(key_parts[2])
            assert currversion_doc[key_parts[0]][key_parts[1]].pop(
                key_parts[2]) == new_val
        elif len(key_parts) == 4:
            try:
                key_parts_2 = int(key_parts[2])
            except:
                key_parts_2 = key_parts[2]
            doc[key_parts[0]][key_parts[1]][key_parts_2].pop(key_parts[3])
            assert currversion_doc[key_parts[0]][
                key_parts[1]][key_parts_2].pop(key_parts[3]) == new_val
        else:
            assert 0 == 1