Skip to content

Commit

Permalink
Add support for the distribution url function attr
Browse files Browse the repository at this point in the history
Include tests for parsing and updating the DOM when there's a url function

Issue #1380
  • Loading branch information
robyngit committed Jul 31, 2023
1 parent 7262f66 commit 44d2aab
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 21 deletions.
81 changes: 69 additions & 12 deletions src/js/models/metadata/eml211/EMLDistribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,42 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
) {
/**
* @class EMLDistribution
* @classdesc Information on how the resource is distributed online and offline
* @classdesc Information on how the resource is distributed online and
* offline
* @classcategory Models/Metadata/EML211
* @see https://eml.ecoinformatics.org/schema/eml-resource_xsd.html#DistributionType
* @see
* https://eml.ecoinformatics.org/schema/eml-resource_xsd.html#DistributionType
* @extends Backbone.Model
* @constructor
*/
var EMLDistribution = Backbone.Model.extend({
/**
* Default values for an EML 211 Distribution model. This is essentially a
* flattened version of the EML 2.1.1 DistributionType, including nodes and
* node attributes. Not all nodes are supported by this model yet.
* @type {Object}
* @property {string} type - The name of the top-level XML element that this
* model represents (distribution)
* @property {string} objectXML - The XML string representation of the
* distribution
* @property {Element} objectDOM - The DOM representation of the
* distribution
* @property {string} mediumName - The name of the medium on which the
* offline distribution is stored
* @property {string} mediumVolume - The volume number of the medium on
* which the offline distribution is stored
* @property {string} mediumFormat - The format of the medium on which the
* offline distribution is stored
* @property {string} mediumNote - A note about the medium on which the
* offline distribution is stored
* @property {string} url - The URL of the online distribution
* @property {string} urlFunction - The purpose of the URL. May be either
* "information" or "download".
* @property {string} onlineDescription - A description of the online
* distribution
* @property {EML211} parentModel - The parent model of this distribution
* model
*/
defaults: {
type: "distribution",
objectXML: null,
Expand All @@ -23,6 +52,7 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
mediumFormat: null,
mediumNote: null,
url: null,
urlFunction: null,
onlineDescription: null,
parentModel: null,
},
Expand All @@ -37,19 +67,28 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
distLocations: ["offline", "online"],

/**
* lower-case EML node names that belong within the <offline> node. These must be in the correct order.
* lower-case EML node names that belong within the <offline> node. These
* must be in the correct order.
* @type {string[]}
* @since x.x.x
*/
offlineNodes: ["mediumname", "mediumvolume", "mediumformat", "mediumnote"],

/**
* lower-case EML node names that belong within the <online> node. These must be in the correct order.
* lower-case EML node names that belong within the <online> node. These
* must be in the correct order.
* @type {string[]}
* @since x.x.x
*/
onlineNodes: ["url"],

/**
* the allowed values for the urlFunction attribute
* @type {string[]}
* @since x.x.x
*/
urlFunctionTypes: ["information", "download"],

/**
* Initializes this EMLDistribution object
* @param {Object} options - A literal object with options to pass to the
Expand Down Expand Up @@ -106,6 +145,12 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
}
});

// Check for a urlFunction attribute if there is a url node
const url = $objectDOM.find("url");
if (url.length) {
attributes.urlFunction = url.attr("function") || null;
}

return attributes;
},

Expand Down Expand Up @@ -201,17 +246,29 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
$objectDOM.find(`${distLocation} > ${nodeName}`).remove();
}
});

// Add the urlFunction attribute if one is set in the model. Remove it if
// it's not set.
const url = $objectDOM.find("url")
if (url) {
const urlFunction = this.get("urlFunction");
if (urlFunction) {
url.attr("function", urlFunction);
} else {
url.removeAttr("function");
}
}


return objectDOM;
},

/*
* Returns the node in the object DOM that the given node type should be
* inserted after.
* @param {string} nodeName - The name of the node to find the position for
* @return {jQuery} - The jQuery object of the node that the given node
* should be inserted after, or false if the node is not supported by this
* model.
* @since x.x.x
* inserted after. @param {string} nodeName - The name of the node to find
* the position for @return {jQuery} - The jQuery object of the node that
* the given node should be inserted after, or false if the node is not
* supported by this model. @since x.x.x
*/
getEMLPosition: function (objectDOM, nodeName) {
// If this is a top level node, return false since it should be inserted
Expand All @@ -225,8 +282,8 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
const siblingNodes = $(objectDOM).find(distLocation).children();
let position = nodeOrder.indexOf(nodeName);
if (position > -1) {
// Go through each node in the node list and find the position where this
// node will be inserted after
// Go through each node in the node list and find the position where
// this node will be inserted after
for (var i = position - 1; i >= 0; i--) {
const checkNode = siblingNodes.filter(nodeOrder[i]);
if (checkNode.length) {
Expand Down
75 changes: 66 additions & 9 deletions test/js/specs/unit/models/metadata/eml211/EMLDistribution.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ define([
var expect = chai.expect;

describe("EMLDistribution Test Suite", function () {
/* Set up */
beforeEach(function () {
this.emlDistribution = new EMLDistribution();
});

/* Tear down */
afterEach(function () {
delete this.emlDistribution;
});

describe("Initialization", function () {
it("should create a EMLDistribution instance", function () {
Expand Down Expand Up @@ -68,6 +59,26 @@ define([
emlDistribution.get("mediumFormat").should.equal("ISO9660");
emlDistribution.get("mediumNote").should.equal("Some notes");
});

it("should parse the url function attribute", function () {
var objectDOM = new DOMParser().parseFromString(
"<distribution>" +
" <online>" +
" <url function='information'>http://www.dataone.org</url>" +
" </online>" +
"</distribution>",
"text/xml"
).documentElement;

var emlDistribution = new EMLDistribution(
{
objectDOM: objectDOM,
},
{ parse: true }
);

emlDistribution.get("urlFunction").should.equal("information");
});
});

describe("Update DOM", function () {
Expand Down Expand Up @@ -184,6 +195,52 @@ define([
expect(updatedDOM.getAttribute("system")).to.equal("eml");
expect(updatedDOM.getAttribute("scope")).to.equal("system");
});

it("should add the url function attribute", function () {
var objectDOM = new DOMParser().parseFromString(
"<distribution>" +
" <online>" +
" <url>http://www.dataone.org</url>" +
" </online>" +
"</distribution>",
"text/xml"
).documentElement;

var emlDistribution = new EMLDistribution(
{
objectDOM: objectDOM,
},
{ parse: true }
);

emlDistribution.set("urlFunction", "information");

var updatedDOM = emlDistribution.updateDOM();
updatedDOM.querySelector("url").getAttribute("function").should.equal("information");
});

it("should remove the url function attribute if the value is empty", function () {
var objectDOM = new DOMParser().parseFromString(
"<distribution>" +
" <online>" +
" <url function='information'>http://www.dataone.org</url>" +
" </online>" +
"</distribution>",
"text/xml"
).documentElement;

var emlDistribution = new EMLDistribution(
{
objectDOM: objectDOM,
},
{ parse: true }
);

emlDistribution.set("urlFunction", "");

var updatedDOM = emlDistribution.updateDOM();
expect(updatedDOM.querySelector("url").getAttribute("function")).to.equal(null);
});
});
});
});

0 comments on commit 44d2aab

Please sign in to comment.