diff --git a/src/js/collections/metadata/eml/EMLAnnotations.js b/src/js/collections/metadata/eml/EMLAnnotations.js index 7aa92950e..92d30c0d1 100644 --- a/src/js/collections/metadata/eml/EMLAnnotations.js +++ b/src/js/collections/metadata/eml/EMLAnnotations.js @@ -49,24 +49,27 @@ define(["underscore", "backbone", "models/metadata/eml211/EMLAnnotation"], ( * @since 0.0.0 */ getDuplicates() { - const duplicates = []; - this.forEach((annotation) => { - const propertyURI = annotation.get("propertyURI"); - const valueURI = annotation.get("valueURI"); - const propertyLabel = annotation.get("propertyLabel"); - const valueLabel = annotation.get("valueLabel"); - - const found = this.filter( - (a) => - a.get("propertyURI") === propertyURI && - a.get("valueURI") === valueURI && - a.get("propertyLabel") === propertyLabel && - a.get("valueLabel") === valueLabel && - a.id !== annotation.id, - ); - - if (found.length) { - duplicates.push(...found); + const groups = {}; + let duplicates = []; + + // Group models by their serialized attributes + this.each((model) => { + // Serialize the model's attributes to create a unique key + const key = JSON.stringify(model.attributes); + + // Group models by the serialized key + if (groups[key]) { + groups[key].push(model); + } else { + groups[key] = [model]; + } + }); + + // Identify duplicates in each group + Object.values(groups).forEach((group) => { + if (group.length > 1) { + // Add all but one model from each group to the duplicates array + duplicates = duplicates.concat(group.slice(1)); } }); diff --git a/test/js/specs/unit/collections/metadata/eml/EMLAnnotations.spec.js b/test/js/specs/unit/collections/metadata/eml/EMLAnnotations.spec.js index 1f92cd742..f5dc1d4a0 100644 --- a/test/js/specs/unit/collections/metadata/eml/EMLAnnotations.spec.js +++ b/test/js/specs/unit/collections/metadata/eml/EMLAnnotations.spec.js @@ -111,5 +111,38 @@ define([ state.annotations.updateCanonicalDataset("http://example.com"); state.annotations.length.should.equal(3); }); + + it("returns null if there are no validation errors", () => { + const errors = state.annotations.validate(); + expect(errors).to.be.null; + }); + + it("shows validation errors if canonical dataset is not a valid URI", () => { + state.annotations.addCanonicalDatasetAnnotation("not-a-valid-uri"); + const errors = state.annotations.validate(); + expect(errors).to.be.an("array"); + expect(errors.length).to.equal(1); + expect(errors[0].attr).to.equal("canonicalDataset"); + }); + + it("removes duplicates during validation", () => { + state.annotations.add([ + { + propertyLabel: "Property Label", + propertyURI: "http://example.com/property", + valueLabel: "Value Label", + valueURI: "http://example.com/value", + }, + { + propertyLabel: "Property Label", + propertyURI: "http://example.com/property", + valueLabel: "Value Label", + valueURI: "http://example.com/value", + }, + ]); + const errors = state.annotations.validate(); + expect(errors).to.be.null; + expect(state.annotations.length).to.equal(1); + }); }); });