Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
caosdb.js.js 18.99 KiB
/**
 * Tests for the high level java script client.
 * @author Alexander Schlemmer
 * Started in 08/2018
 **/



// Module initialization
QUnit.module("caosdb.js", {
    setTestDocument: function(varname, done, xml) {
        var xml_test_document = str2xml(xml);

        transformation.transformEntities(xml_test_document).then(x => {
            this[varname] = x;
            done();
        }, err => {console.log(err);});

    },

    before: function(assert) {
        var done = assert.async(3);
        this.setTestDocument("x", done, `
<Response>
  <Record name="nameofrecord">
    <Parent name="bla" />
    <Property name="A" datatype="TEXT">245</Property>
  </Record>

  <Record>
    <Parent name="bla" />

  </Record>


  <Record name="nameofrec" id="17">
    <Parent name="bla" id="244" />
    <Parent name="bla2" id="217" />

    <Property name="B" datatype="TEXT">245</Property>
    <Property name="A" datatype="DOUBLE">245.0</Property>
    <Property name="A" datatype="TEXT">245</Property>
  </Record>

<Record description="This record has no name.">
    <Parent name="bla" />

    <Property name="B" datatype="Uboot">245</Property>
    <Property name="A" datatype="INTEGER">245</Property>
    <Property name="A" datatype="LIST&#60;INTEGER&#62;"><Value>245</Value></Property>
    <Property name="A" datatype="LIST&#60;INTEGER&#62;"></Property>

    <Property name="A" datatype="LIST&#60;INTEGER&#62;">
      <Value>245</Value>
      <Value>245</Value>
    </Property>

    <Property name="A" datatype="LIST&#60;Uboot&#62;">
      <Value>245</Value>
      <Value>247</Value>
      <Value>
          299
      </Value>
    </Property>
  </Record>

</Response>
`);

            this.setTestDocument("userInfoTest", done, `
<Response>
  <UserInfo username="max" realm="PAM">
    <Roles>
        <Role>administration</Role>
    </Roles>
  </UserInfo>

  <Record name="nameofrecord">
    <Parent name="bla" />
    <Property name="A" datatype="TEXT">245</Property>
  </Record>

</Response>`);
        
        // Test document for unset references
        this.setTestDocument("unsetReferencesTest", done, `
<Response>
  <UserInfo username="max" realm="PAM">
    <Roles>
        <Role>administration</Role>
    </Roles>
  </UserInfo>

  <Record name="nameofrecord">
    <Parent name="bla" />
    <Property name="A" datatype="UBoot"></Property>
  </Record>

  <Record>
    <Parent name="bla" />
    <Property name="A" datatype="UBoot">17</Property>
  </Record>

  <Record name="nameofrecord">
    <Parent name="bla" />
    <Property name="A" datatype="REFERENCE"></Property>
  </Record>

  <Record name="nameofrecord">
    <Parent name="bla" />
    <Property name="A" datatype="REFERENCE">289</Property>
  </Record>
</Response>`);
    }
});

/**
  * @author Alexander Schlemmer
  * Test user info functions in client.
  *
  * TODO: Not possible right now, because transformEntities does not transform UserInfo.
  */
// QUnit.test("userInfo", function(assert) {
//     assert.equal(getUserName(), "max");
// });

QUnit.test("available", function(assert) {
    assert.ok(getProperties, "getProperties");
});
/**
  * @author Alexander Schlemmer
  * Test whether properties are parsed correctly from the document tree.
  */
QUnit.test("getProperties", function(assert) {
    try {
        ps = getProperties();
    }
    catch (e) {
        assert.equal(e.message, "element is undefined");
    }
    try {
        ps = getProperties(undefined);
    }
    catch (e) {
        assert.equal(e.message, "element is undefined");
    }

    assert.equal(this.x.length, 4);

    let ps = getProperties(this.x[0]);
    assert.equal(ps.length, 1);
    assert.equal(ps[0].name, "A");
    assert.equal(ps[0].datatype, "TEXT");
    assert.equal(ps[0].value, 245);

    ps = getProperties(this.x[1]);
    assert.equal(ps.length, 0);

    ps = getProperties(this.x[2]);
    assert.equal(ps.length, 3);
    assert.equal(ps[1].name, ps[2].name);
    assert.notEqual(ps[0].name, ps[2].name);
    assert.notEqual(ps[1].duplicateIndex, ps[2].duplicateIndex);
    assert.equal(ps[0].duplicateIndex, 0);
    assert.notEqual(ps[1].datatype, ps[2].datatype);
    assert.equal(ps[0].datatype, "TEXT");
});

QUnit.test("getEntityIdVersion", function(assert) {
    // without version
    var html = $('<div data-entity-id="1234"/>')[0];
    assert.equal(getEntityIdVersion(html), "1234", "id extracted");

    // with version
    html = $('<div data-entity-id="1234" data-version-id="abcd"/>')[0];
    assert.equal(getEntityIdVersion(html), "1234@abcd", "<id>@<version> extracted");

});

/**
  * @author Alexander Schlemmer
  * Test whether parents are retrieved correctly.
  */
QUnit.test("getParents", function(assert) {
    par1 = getParents(this.x[1])
    par2 = getParents(this.x[2])

    assert.equal(par1.length, 1);
    assert.equal(par2.length, 2);

    assert.equal(par1[0].name, "bla")
    assert.equal(par1[0].id, undefined)

    assert.equal(par2[0].name, "bla")
    assert.equal(par2[0].id, "244")
    assert.equal(par2[1].name, "bla2")
    assert.equal(par2[1].id, "217")
});

/**
  * @author Alexander Schlemmer
  * Test whether lists and references are parsed correctly.
  */
QUnit.test("listProperties", function(assert) {
    // console.log(this.x[3]);
    assert.equal(getPropertyElements(this.x[3]).length, 6);
    ps = getProperties(this.x[3]);
    assert.equal(ps.length, 6);
    assert.equal(ps[0].datatype, "Uboot");
    assert.equal(ps[0].reference, true);
    assert.equal(ps[0].list, false);

    assert.equal(ps[1].datatype, "INTEGER");
    assert.equal(ps[1].reference, false);
    assert.equal(ps[1].list, false);

    // console.log(ps[2]);
    assert.equal(ps[2].datatype, "LIST<INTEGER>");
    assert.equal(ps[2].reference, false);
    assert.equal(ps[2].list, true);
    assert.deepEqual(ps[2].value, ["245"]);

    // console.log(ps[3]);
    assert.equal(ps[3].datatype, "LIST<INTEGER>");
    assert.equal(ps[3].reference, false);
    assert.equal(ps[3].list, true);
    assert.deepEqual(ps[3].value, []);

    assert.equal(ps[4].datatype, "LIST<INTEGER>");
    assert.equal(ps[4].reference, false);
    assert.equal(ps[4].list, true);
    assert.deepEqual(ps[4].value, ["245", "245"]);

    assert.equal(ps[5].datatype, "LIST<Uboot>");
    assert.equal(ps[5].reference, true);
    assert.equal(ps[5].list, true);
});

/**
  * @author Alexander Schlemmer
  * Test whether list properties have the attribute listDatatype.
  */
QUnit.test("listProperties", function(assert) {
    // For clarity, duplication of above assertions:
    assert.equal(ps[5].datatype, "LIST<Uboot>");
    assert.equal(ps[5].list, true);
    assert.equal(ps[5].listDatatype, "Uboot");
});

/**
  * @author Alexander Schlemmer
  * Test setting of properties.
  */
QUnit.test("setProperties", function(assert) {
    var newdoc = [];
    for (var i=0; i<this.x.length; i++) {
        newdoc.push(this.x[i].cloneNode(true));
    }

    // Set one property:
    setProperty(newdoc[2], {name: "B", value: 246});
    ps = getProperties(newdoc[2]);
    assert.equal(ps[0].name, "B");
    assert.equal(ps[0].value, "246");

    // Ambiguity:
    setProperty(newdoc[2], {name: "A", value: 246});
    ps = getProperties(newdoc[2]);
    assert.equal(ps[1].name, "A");
    assert.equal(ps[2].name, "A");
    assert.equal(ps[1].value, "246");
    assert.equal(ps[2].value, "246");

    // Better:
    setProperty(newdoc[2], {name: "A", value: 247, duplicateIndex: 0});
    setProperty(newdoc[2], {name: "A", value: -247, duplicateIndex: 1});
    ps = getProperties(newdoc[2]);
    assert.equal(ps[1].name, "A");
    assert.equal(ps[2].name, "A");
    assert.equal(ps[1].value, "247");
    assert.equal(ps[2].value, "-247");
});

/**
  * @author Alexander Schlemmer
  * Test creating XML representations.
  */
QUnit.test("createXML", function(assert) {
    var done = assert.async();
    let doc = createResponse(
        createEntityXML("Record", "bla", undefined,
                        [{name: "blubb", value: 779}, {name: "zuzuz", value: 42}]));
    transformation.transformEntities(doc).then (x => {
        ps = getProperties(x[0]);
        assert.equal(ps[0].name, "blubb");
        assert.equal(ps[1].value, 42);
        done();
    });
});



/**
  * @author Alexander Schlemmer
  * Test obtaining names and IDs.
  */
QUnit.test("namesAndIDs", function(assert) {
    assert.equal(getEntityName(this.x[0]), "nameofrecord");
    assert.equal(getEntityID(this.x[0]), "");
    assert.equal(getEntityName(this.x[2]), "nameofrec");
    assert.equal(getEntityID(this.x[2]), "17");
    assert.equal(getEntityName(this.x[3]), "");
    assert.equal(getEntityID(this.x[3]), "");
});


/**
  * @author Alexander Schlemmer
  * Test heading attributes and descriptions.
  */
QUnit.test("headingAttributes", function(assert) {
    assert.equal(getEntityDescription(this.x[0]), undefined);
    assert.equal(getEntityDescription(this.x[1]), undefined);
    assert.equal(getEntityDescription(this.x[2]), undefined);
    assert.equal(getEntityDescription(this.x[3]), "This record has no name.");
});


/**
  * @author Alexander Schlemmer
  * Test replication of entities.
  */
QUnit.test("replicationOfEntities", function(assert) {
    var done = assert.async();

    var reptest = function(ent, respxml) {
        var oldprops = getProperties(ent);
        var oldpars = getParents(ent);
        var doc = createResponse(
            createEntityXML(getEntityRole(ent), getEntityName(ent), getEntityID(ent),
                            getProperties(ent), getParents(ent)));
        assert.equal(xml2str(doc), respxml);


        doc = createResponse(
            createEntityXML(getEntityRole(ent), getEntityName(ent), getEntityID(ent),
                            getProperties(ent), getParents(ent), true));
        transformation.transformEntities(doc).then (x => {
            ps = getProperties(x[0]);
            pars = getParents(x[0]);

            assert.equal(getEntityRole(ent), getEntityRole(x[0]));
            assert.equal(getEntityName(ent), getEntityName(x[0]));
            assert.equal(getEntityID(ent), getEntityID(x[0]));
            assert.equal(ps.length, oldprops.length);
            for (var i=0; i<ps.length; i++) {
                assert.equal(ps[i].name, oldprops[i].name);
                assert.deepEqual(ps[i].value, oldprops[i].value);
                assert.equal(ps[i].datatype, oldprops[i].datatype);
                assert.equal(ps[i].list, oldprops[i].list);
                assert.equal(ps[i].reference, oldprops[i].reference);
            }
            assert.equal(pars.length, oldpars.length);
            for (var i=0; i<pars.length; i++) {
                assert.equal(pars[i].name, oldpars[i].name);
                assert.equal(pars[i].id, oldpars[i].id);
            }
            funj += 1;
            // console.log(funj, maxfunccall);
            if (funj == maxfunccall) {
                done();
            }
        });
    };

    var respxmls = [
        '<Response><Record name="nameofrecord"><Parent name="bla"/><Property name="A">245</Property></Record></Response>',
        '<Response><Record><Parent name="bla"/></Record></Response>',
        '<Response><Record id="17" name="nameofrec"><Parent id="244" name="bla"/><Parent id="217" name="bla2"/><Property name="B">245</Property><Property name="A">245.0</Property><Property name="A">245</Property></Record></Response>',
        '<Response><Record><Parent name="bla"/><Property name="B">245</Property><Property name="A">245</Property><Property name="A"><Value>245</Value></Property><Property name="A"/><Property name="A"><Value>245</Value><Value>245</Value></Property><Property name="A"><Value>245</Value><Value>247</Value><Value>299</Value></Property></Record></Response>'];

    var funj = 0;
    var maxfunccall = this.x.length;
    for (var i=0; i<this.x.length; i++) {
        reptest(this.x[i], respxmls[i]);
    }
});


/**
  * @author Alexander Schlemmer
  * Test replication of entities.
  * This test uses createEntityXML with the append_datatype option disabled.
  * This causes the function to create XML without datatype attributes.
  * The generated XML should be valid, but the XSLT is currently not able
  * to generate valid HTML for list properties. See bug: #3
  */
QUnit.skip("replicationOfEntitiesNoDatatype", function(assert) {
    var done = assert.async();

    var reptest = function(ent) {
        var oldprops = getProperties(ent);
        var oldpars = getParents(ent);
        var doc = createResponse(
            createEntityXML(getEntityRole(ent), getEntityName(ent), getEntityID(ent),
                            getProperties(ent), getParents(ent)));
        transformation.transformEntities(doc).then (x => {
            ps = getProperties(x[0]);
            pars = getParents(x[0]);

            assert.equal(getEntityRole(ent), getEntityRole(x[0]));
            assert.equal(getEntityName(ent), getEntityName(x[0]));
            assert.equal(getEntityID(ent), getEntityID(x[0]));
            assert.equal(ps.length, oldprops.length);
            for (var i=0; i<ps.length; i++) {
                assert.equal(ps[i].name, oldprops[i].name);
                assert.deepEqual(ps[i].value, oldprops[i].value);
            }
            assert.equal(pars.length, oldpars.length);
            for (var i=0; i<pars.length; i++) {
                assert.equal(pars[i].name, oldpars[i].name);
                assert.equal(pars[i].id, oldpars[i].id);
            }
            done();
        });

    };

    reptest(this.x[3]);
});

QUnit.test("getProperty", function(assert) {
    assert.ok(getProperty, "available");
    var testCase = this.x[0];
    assert.equal(getProperty(testCase, "A", case_sensitive=true), "245");
    assert.notOk(getProperty(testCase, "a", case_sensitive=true));
    assert.equal(getProperty(testCase, "A", case_sensitive=false), "245");
    assert.equal(getProperty(testCase, "a", case_sensitive=false), "245");
});

QUnit.test("getEntityRole", function(assert) {
    var records = [
        $('<div data-entity-role="record"/>'),
        $('<div><div data-entity-role="record"/></div>'),
        $('<div><div class="caosdb-f-entity-role">record</div></div>'),
        $('<div class="caosdb-f-entity-role">record</div>')];
    for (const record of records) {
        assert.equal(getEntityRole(record), "record", "role detected");
    }

});


QUnit.test("getEntityUnit", function(assert) {
    var property1 = $(`<div><p class="caosdb-entity-heading-attr"><em
        class="caosdb-entity-heading-attr-name">unit:</em>m</p></div>`);
    assert.equal(getEntityUnit(property1[0]), "m");

    var property2 = $(`<div><input type="text" class="caosdb-f-entity-unit"
        value="m/s"/><div>`);
    assert.equal(getEntityUnit(property2[0]), "m/s");
});


// Test for bug #53
// https://gitlab.com/caosdb/caosdb-webui/issues/53
QUnit.test("unset_entity_references", function(assert) {
    console.log(this.unsetReferencesTest);
    for (var i=0; i<this.unsetReferencesTest.length; i++) {
        console.log(i);
        var r = this.unsetReferencesTest[i];
        assert.equal(getProperties(r)[0].reference, true);
    }
});


QUnit.test("_constructXpaths", function (assert) {
    assert.propEqual(
      _constructXpaths([["id"], ["longitude"], ["latitude"]]),
      ["@id", "Property[@name='longitude']", "Property[@name='latitude']"]
    );
    assert.propEqual(
      _constructXpaths([["Geo Location", "longitude"], ["latitude"]]),
      ["Property[@name='Geo Location']//Property[@name='longitude']", "Property[@name='latitude']"]
    );
    assert.propEqual(
      _constructXpaths([["", "longitude"], ["latitude"]]),
      ["Property//Property[@name='longitude']", "Property[@name='latitude']"]
    );
    assert.propEqual(
      _constructXpaths([["", "Geo Location", "", "longitude"]]),
      ["Property//Property[@name='Geo Location']//Property//Property[@name='longitude']"]
    );
});


QUnit.test("getPropertyValues", function (assert) {
    const test_response = str2xml(`
<Response srid="851d063d-121b-4b67-98d4-6e5ad4d31e72" timestamp="1606214042274" baseuri="https://localhost:10443" count="8">
  <Query string="select Campaign.responsible.firstname from icecore" results="8">
    <ParseTree>(cq select (prop_sel (prop_subsel (selector_txt   C a m p a i g n) . (prop_subsel (selector_txt r e s p o n s i b l e) . (prop_subsel (selector_txt f i r s t n a m e  ))))) from (entity icecore) &lt;EOF&gt;)</ParseTree>
    <Role/>
    <Entity>icecore</Entity>
    <Selection>
      <Selector name="Campaign.responsible.firstname"/>
    </Selection>
  </Query>
  <Record id="6525" name="Test_IceCore_1">
    <Permissions/>
    <Property datatype="Campaign" id="6430" name="Campaign">
      <Record id="6516" name="Test-2020_Camp1">
        <Permissions/>
        <Property datatype="REFERENCE" id="168" name="responsible">
          <Record id="6515" name="Test_Scientist">
            <Permissions/>
            <Property datatype="DOUBLE" id="151" name="latitude" importance="FIX">
              1.34
              <Permissions/>
            </Property>
            <Property datatype="DOUBLE" id="151" name="longitude" importance="FIX">
              2
              <Permissions/>
            </Property>
          </Record>
          <Permissions/>
        </Property>
      </Record>
      <Permissions/>
    </Property>
  </Record>
  <Record id="6526" name="Test_IceCore_2">
    <Permissions/>
    <Property datatype="Campaign" id="6430" name="Campaign">
      <Record id="6516" name="Test-2020_Camp1">
        <Permissions/>
        <Property datatype="REFERENCE" id="168" name="responsible">
          <Record id="6515" name="Test_Scientist">
            <Permissions/>
            <Property datatype="DOUBLE" id="151" name="latitude" importance="FIX">
              3
              <Permissions/>
            </Property>
            <Property datatype="DOUBLE" id="151" name="longitude" importance="FIX">
              4.8345
              <Permissions/>
            </Property>
          </Record>
          <Permissions/>
        </Property>
      </Record>
      <Permissions/>
    </Property>
  </Record>
</Response>`);

    assert.propEqual(
      getPropertyValues(test_response, [["id"], ["", "latitude"],["", "longitude"]]),
      [["6525" ,"1.34", "2"], ["6526", "3", "4.8345"]]);
});

// Test for bug 103
// If role is File when creating XML for entities, checksum, path and size must be given.
QUnit.test("unset_file_attributes", function(assert) {
    // This should run:
    var res1 = createEntityXML("Record", "test", 103, {}, {});
    assert.equal(xml2str(res1), "<Record id=\"103\" name=\"test\"/>");
    // This must throw an exception:
    assert.throws(function () {
        createEntityXML("File", "test", 103, {}, {});
    });
    // This should produce a valid XML.
    var res2 = createEntityXML("File", "test", 103, {}, {},
                               false, undefined, undefined, undefined,
                               "testfile.txt", "blablabla", 0);
    assert.equal(xml2str(res2), "<File id=\"103\" name=\"test\" path=\"testfile.txt\" checksum=\"blablabla\" size=\"0\"/>");

    var res3 = createFileXML("test", 103, {},
                             "testfile.txt", "blablabla", 0,
                             undefined);
    assert.equal(xml2str(res3), "<File id=\"103\" name=\"test\" path=\"testfile.txt\" checksum=\"blablabla\" size=\"0\"/>");
});