Skip to content

Commit

Permalink
Check for reversed N & S coords in EMLGeoCoverage
Browse files Browse the repository at this point in the history
- Show validation error when N coord is less than S coord
- Fix the HTML input pattern for decimal degrees (was throwing an error)
- Add a test for reversed coords to the EMLGeoCoverage model spec

Issue #2159
  • Loading branch information
robyngit committed Nov 2, 2023
1 parent 728c3da commit 1e5cf79
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 38 deletions.
40 changes: 33 additions & 7 deletions src/js/models/metadata/eml211/EMLGeoCoverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
case "needPair":
return "Each location description must have at least one coordinate pair.";
break;
case "coordsReversed":
return "The North latitude must be greater than the South latitude.";
break;
default:
return "";
break;
Expand All @@ -277,31 +280,38 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
* the value is valid.
*
* @return {array} An array containing the current state of each
* coordinate box
* coordinate box, including: value (the value of the coordinate converted
* to a number), isSet (whether the coordinate has a value), and isValid
* (whether the value is in the correct range)
*/
getCoordinateStatus: function () {
var north = this.get("north"),
east = this.get("east"),
south = this.get("south"),
west = this.get("west");

const isDefined = (value) =>
typeof value !== "undefined" && value != null && value !== "";

return {
north: {
isSet:
typeof north !== "undefined" && north != null && north !== "",
value: Number(north),
isSet: isDefined(north),
isValid: this.validateCoordinate(north, -90, 90),
},
east: {
isSet: typeof east !== "undefined" && east != null && east !== "",
value: Number(east),
isSet: isDefined(east),
isValid: this.validateCoordinate(east, -180, 180),
},
south: {
isSet:
typeof south !== "undefined" && south != null && south !== "",
value: Number(south),
isSet: isDefined(south),
isValid: this.validateCoordinate(south, -90, 90),
},
west: {
isSet: typeof west !== "undefined" && west != null && west !== "",
value: Number(west),
isSet: isDefined(west),
isValid: this.validateCoordinate(west, -180, 180),
},
};
Expand Down Expand Up @@ -404,6 +414,22 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
else if (!pointStatuses.south.isSet && pointStatuses.east.isSet)
errors.south = this.getErrorMessage("missing");

// Verify latitudes: north should be > south. For longitude, east and
// west can be in any order, depending on whether the location crosses
// the antimeridian
if (
pointStatuses.north.isSet &&
pointStatuses.south.isSet &&
pointStatuses.north.isValid &&
pointStatuses.south.isValid
) {
if (pointStatuses.north.value < pointStatuses.south.value) {
const msg = this.getErrorMessage("coordsReversed");
errors.north = msg;
errors.south = msg;
}
}

if (Object.keys(errors).length) return errors;
else return false;
},
Expand Down
8 changes: 4 additions & 4 deletions src/js/templates/metadata/EMLGeoCoverage.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
<div class="row-fluid">
<div class="span6">
<label class="subtle">Northwest coordinates</label>
<input type="text" value="<%=model.north%>" data-attribute="north" class="coord north" placeholder="Lat" pattern = "(^[+-]?(?:\d+\.?\d*|\d*\.\d+)$)|(-)|(\+)" />
<input type="text" value="<%=model.west%>" data-attribute="west" class="coord west" placeholder="Long" pattern = "(^[+-]?(?:\d+\.?\d*|\d*\.\d+)$)|(-)|(\+)" />
<input type="text" value="<%=model.north%>" data-attribute="north" class="coord north" placeholder="Lat" pattern = "^-?(90(\.0+)?|[1-8]?\d(\.\d+)?)$" title="Enter a valid latitude (-90 to 90)" />
<input type="text" value="<%=model.west%>" data-attribute="west" class="coord west" placeholder="Long" pattern = "^-?(180(\.0+)?|1?[0-7]?\d(\.\d+)?)$" title="Enter a valid longitude (-180 to 180)"/>
</div>
<div class="span6">
<label class="subtle">Southeast coordinates</label>
<input type="text" value="<%=model.south%>" data-attribute="south" class="coord south" placeholder="Lat" pattern = "(^[+-]?(?:\d+\.?\d*|\d*\.\d+)$)|(-)|(\+)"/>
<input type="text" value="<%=model.east%>" data-attribute="east" class="coord east" placeholder="Long" pattern = "(^[+-]?(?:\d+\.?\d*|\d*\.\d+)$)|(-)|(\+)"/>
<input type="text" value="<%=model.south%>" data-attribute="south" class="coord south" placeholder="Lat" pattern = "^-?(90(\.0+)?|[1-8]?\d(\.\d+)?)$" title="Enter a valid latitude (-90 to 90)"/>
<input type="text" value="<%=model.east%>" data-attribute="east" class="coord east" placeholder="Long" pattern = "^-?(180(\.0+)?|1?[0-7]?\d(\.\d+)?)$" title="Enter a valid longitude (-180 to 180)"/>
</div>
</div>
</div>
Expand Down
27 changes: 16 additions & 11 deletions src/js/views/metadata/EMLGeoCoverageView.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ define([
//Are the NW and SE points the same? i.e. is this a single point and not
//a box?
var isSinglePoint =
this.model.get("north") != null &&
this.model.get("north") == this.model.get("south") &&
this.model.get("west") != null &&
this.model.get("west") == this.model.get("east"),
this.model.get("north") != null &&
this.model.get("north") == this.model.get("south") &&
this.model.get("west") != null &&
this.model.get("west") == this.model.get("east"),
hasEmptyInputs =
this.$("[data-attribute='north']").val() == "" ||
this.$("[data-attribute='south']").val() == "" ||
Expand Down Expand Up @@ -205,7 +205,7 @@ define([
} else {
//Find out if we are missing a complete NW or SE point
var isMissingNWPoint =
this.model.get("north") == null && this.model.get("west") == null,
this.model.get("north") == null && this.model.get("west") == null,
isMissingSEPoint =
this.model.get("south") == null && this.model.get("east") == null;

Expand Down Expand Up @@ -290,14 +290,19 @@ define([
this.$el.removeClass("error");
this.$(".notification").empty();

var errorMessages = "";
const errorObj = this.model.validationError;
// Get all of the field keys
const fields = Object.keys(errorObj);
// Get all of the error messages (values). Remove duplicates.
let errorMessages = [...new Set(Object.values(errorObj))];
// Join the error messages into a single string
errorMessages = errorMessages.join(" ");

for (field in this.model.validationError) {
// Highlight the fields that need to be fixed
fields.forEach((field) => {
this.$("[data-attribute='" + field + "']").addClass("error");

errorMessages += this.model.validationError[field] + " ";
}

})
// Show the combined error message
this.$(".notification").text(errorMessages).addClass("error");
},

Expand Down
29 changes: 13 additions & 16 deletions test/js/specs/unit/models/metadata/eml211/EMLGeoCoverage.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,22 @@ define([
);
emlGeoCoverage.set("north", "");
var errors = emlGeoCoverage.validate();
console.log(errors);
errors.north.should.equal("Each coordinate must include a latitude AND longitude.");
});

// it("should give an error if the north and south coordinates are reversed", function () {
// var emlGeoCoverage = new EMLGeoCoverage(
// { objectDOM: this.testEML },
// { parse: true }
// );
// emlGeoCoverage.set("north", "40");
// emlGeoCoverage.set("south", "50");
// var errors = emlGeoCoverage.validate();
// errors.north.should.equal(
// "The Northwest latitude must be between -90 and 90."
// );
// errors.south.should.equal(
// "The Southeast latitude must be between -90 and 90."
// );
// });
it("should give an error if the north and south coordinates are reversed", function () {
var emlGeoCoverage = new EMLGeoCoverage(
{ objectDOM: this.testEML },
{ parse: true }
);
emlGeoCoverage.set("north", "40");
emlGeoCoverage.set("south", "50");
var errors = emlGeoCoverage.validate();
const msg = "The North latitude must be greater than the South latitude.";
errors.north.should.equal(msg);
errors.south.should.equal(msg);
});

});
});
});

0 comments on commit 1e5cf79

Please sign in to comment.