mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
validate suspicious names using the user's language (#9522)
This commit is contained in:
@@ -51,6 +51,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
#### :white_check_mark: Validation
|
||||
* Add warning if aeroways cross each other, buildings or highways ([#9315], thanks [@k-yle])
|
||||
* Warn when a way with more than the maximum allowed number of nodes is to be uploaded and provide a way to fix it ([#7381])
|
||||
* The Suspicious Names validator warning now compares the Name field to the preset’s name in the user’s language, not just the raw tag value (typically in British English). ([#9522], thanks [@k-yle])
|
||||
* Revalidate ways that are connected to the currently edited way to also properly update/catch _disconnected way_s and _impossible oneway_ errors ([#8911], thanks [@andrewpmk])
|
||||
#### :bug: Bugfixes
|
||||
* Prevent degenerate ways caused by deleting a corner of a triangle ([#10003], thanks [@k-yle])
|
||||
@@ -71,6 +72,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
|
||||
[#7381]: https://github.com/openstreetmap/iD/issues/7381
|
||||
[#8911]: https://github.com/openstreetmap/iD/pull/8911
|
||||
[#9522]: https://github.com/openstreetmap/iD/issues/9522
|
||||
[#9634]: https://github.com/openstreetmap/iD/pull/9634
|
||||
[#9635]: https://github.com/openstreetmap/iD/pull/9635
|
||||
[#10003]: https://github.com/openstreetmap/iD/pull/10003
|
||||
|
||||
@@ -5,7 +5,7 @@ import { t, localizer } from '../core/localizer';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
|
||||
|
||||
export function validationSuspiciousName() {
|
||||
export function validationSuspiciousName(context) {
|
||||
const type = 'suspicious_name';
|
||||
const keysToTestForGenericValues = [
|
||||
'aerialway', 'aeroway', 'amenity', 'building', 'craft', 'highway',
|
||||
@@ -45,9 +45,17 @@ export function validationSuspiciousName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isGenericName(name, tags) {
|
||||
/** @param {string} name @param {string} presetName */
|
||||
function nameMatchesPresetName(name, presetName) {
|
||||
if (!presetName) return false;
|
||||
|
||||
return name.toLowerCase() === presetName.toLowerCase();
|
||||
}
|
||||
|
||||
/** @param {string} name @param {string} presetName */
|
||||
function isGenericName(name, tags, presetName) {
|
||||
name = name.toLowerCase();
|
||||
return nameMatchesRawTag(name, tags) || isGenericMatchInNsi(tags);
|
||||
return nameMatchesRawTag(name, tags) || nameMatchesPresetName(name, presetName) || isGenericMatchInNsi(tags);
|
||||
}
|
||||
|
||||
function makeGenericNameIssue(entityId, nameKey, genericName, langCode) {
|
||||
@@ -105,6 +113,8 @@ export function validationSuspiciousName() {
|
||||
|
||||
let issues = [];
|
||||
|
||||
const presetName = presetManager.match(entity, context.graph()).name();
|
||||
|
||||
for (let key in tags) {
|
||||
const m = key.match(/^name(?:(?::)([a-zA-Z_-]+))?$/);
|
||||
if (!m) continue;
|
||||
@@ -112,7 +122,7 @@ export function validationSuspiciousName() {
|
||||
const langCode = m.length >= 2 ? m[1] : null;
|
||||
const value = tags[key];
|
||||
|
||||
if (isGenericName(value, tags)) {
|
||||
if (isGenericName(value, tags, presetName)) {
|
||||
issues.provisional = _waitingForNsi; // retry later if we are waiting on NSI to finish loading
|
||||
issues.push(makeGenericNameIssue(entity.id, key, value, langCode));
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ describe('iD.validations.suspicious_name', function () {
|
||||
iD.fileFetcher.cache().nsi_generics = {
|
||||
genericWords: ['^stores?$']
|
||||
};
|
||||
iD.fileFetcher.cache().preset_presets = {
|
||||
'Velero': { tags: { craft: 'sailmaker' }, geometry: ['line'] },
|
||||
'Constructor de barco': { tags: { craft: 'boatbuilder' }, geometry: ['line'] },
|
||||
};
|
||||
});
|
||||
|
||||
after(function() {
|
||||
@@ -183,4 +187,29 @@ describe('iD.validations.suspicious_name', function () {
|
||||
done();
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it('flags feature with a name that matches the preset name', async () => {
|
||||
await iD.presetManager.ensureLoaded(true);
|
||||
createWay({ craft: 'sailmaker', 'name:ca': 'Velero' });
|
||||
const validator = iD.validationSuspiciousName(context);
|
||||
|
||||
const issues = validate(validator);
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
expect(issues[0].type).to.eql('suspicious_name');
|
||||
expect(issues[0].hash).to.eql('name:ca=Velero');
|
||||
});
|
||||
|
||||
it('flags feature with a name that matches the preset name and tag name', async () => {
|
||||
await iD.presetManager.ensureLoaded(true);
|
||||
createWay({ craft: 'boatbuilder', 'name:mi': 'boatbuilder', name: 'cOnStRuCtOr de barco' });
|
||||
const validator = iD.validationSuspiciousName(context);
|
||||
|
||||
const issues = validate(validator);
|
||||
expect(issues).to.have.lengthOf(2);
|
||||
expect(issues[0].type).to.eql('suspicious_name');
|
||||
expect(issues[0].hash).to.eql('name:mi=boatbuilder');
|
||||
|
||||
expect(issues[1].type).to.eql('suspicious_name');
|
||||
expect(issues[1].hash).to.eql('name=cOnStRuCtOr de barco');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user