diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index c8cfb83bce..362d12853b 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -363,7 +363,7 @@ export class Changes { } - private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): { + public CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): { newObjects: OsmObject[], modifiedObjects: OsmObject[] deletedObjects: OsmObject[] diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts index b62f9374b6..5b07a0faf4 100644 --- a/Logic/Osm/ChangesetHandler.ts +++ b/Logic/Osm/ChangesetHandler.ts @@ -51,13 +51,14 @@ export class ChangesetHandler { } /** + * Inplace rewrite of extraMetaTags * If the metatags contain a special motivation of the format ":node/-", this method will rewrite this negative number to the actual ID * The key is changed _in place_; true will be returned if a change has been applied * @param extraMetaTags * @param rewriteIds * @private */ - private static rewriteMetaTags(extraMetaTags: ChangesetTag[], rewriteIds: Map) { + static rewriteMetaTags(extraMetaTags: ChangesetTag[], rewriteIds: Map) { let hasChange = false; for (const tag of extraMetaTags) { const match = tag.key.match(/^([a-zA-Z0-9_]+):(node\/-[0-9])$/) @@ -92,6 +93,8 @@ export class ChangesetHandler { if (!extraMetaTags.some(tag => tag.key === "comment") || !extraMetaTags.some(tag => tag.key === "theme")) { throw "The meta tags should at least contain a `comment` and a `theme`" } + + extraMetaTags = [...extraMetaTags, ...this.defaultChangesetTags()] if (this.userDetails.data.csCount == 0) { // The user became a contributor! @@ -112,7 +115,7 @@ export class ChangesetHandler { openChangeset.setData(csId); const changeset = generateChangeXML(csId); console.trace("Opened a new changeset (openChangeset.data is undefined):", changeset); - const changes = await this.AddChange(csId, changeset) + const changes = await this.UploadChange(csId, changeset) const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes) if(hasSpecialMotivationChanges){ // At this point, 'extraMetaTags' will have changed - we need to set the tags again @@ -139,11 +142,12 @@ export class ChangesetHandler { return; } - const rewritings = await this.AddChange( + const rewritings = await this.UploadChange( csId, generateChangeXML(csId)) - await this.RewriteTagsOf(extraMetaTags, rewritings, oldChangesetMeta) + const rewrittenTags = this.RewriteTagsOf(extraMetaTags, rewritings, oldChangesetMeta) + await this.UpdateTags(csId, rewrittenTags) } catch (e) { console.warn("Could not upload, changeset is probably closed: ", e); @@ -153,13 +157,13 @@ export class ChangesetHandler { } /** - * Updates the metatag of a changeset - + * Given an existing changeset with metadata and extraMetaTags to add, will fuse them to a new set of metatags + * Does not yet send data * @param extraMetaTags: new changeset tags to add/fuse with this changeset + * @param rewriteIds: the mapping of ids * @param oldChangesetMeta: the metadata-object of the already existing changeset - * @constructor - * @private */ - private async RewriteTagsOf(extraMetaTags: ChangesetTag[], + public RewriteTagsOf(extraMetaTags: ChangesetTag[], rewriteIds: Map, oldChangesetMeta: { open: boolean, @@ -167,9 +171,8 @@ export class ChangesetHandler { uid: number, // User ID changes_count: number, tags: any - }) { + }) : ChangesetTag[] { - const csId = oldChangesetMeta.id // Note: extraMetaTags is where all the tags are collected into @@ -214,10 +217,8 @@ export class ChangesetHandler { ChangesetHandler.rewriteMetaTags(extraMetaTags, rewriteIds) - - await this.UpdateTags(csId, extraMetaTags) - - + return extraMetaTags + } private handleIdRewrite(node: any, type: string): [string, string] { @@ -295,7 +296,7 @@ export class ChangesetHandler { }) } - private async GetChangesetMeta(csId: number): Promise<{ + async GetChangesetMeta(csId: number): Promise<{ id: number, open: boolean, uid: number, @@ -340,21 +341,30 @@ export class ChangesetHandler { }); }) } + + private defaultChangesetTags() : ChangesetTag[]{ + return [ ["created_by", `MapComplete ${Constants.vNumber}`], + ["locale", Locale.language.data], + ["host", `${window.location.origin}${window.location.pathname}`], + ["source", this.changes.state["currentUserLocation"]?.features?.data?.length > 0 ? "survey" : undefined], + ["imagery", this.changes.state["backgroundLayer"]?.data?.id]].map(([key, value]) => ({ + key, value, aggretage: false + })) + } + /** + * Opens a changeset with the specified tags + * @param changesetTags + * @constructor + * @private + */ private OpenChangeset( changesetTags: ChangesetTag[] ): Promise { const self = this; return new Promise(function (resolve, reject) { - const metadata = [ - ["created_by", `MapComplete ${Constants.vNumber}`], - ["locale", Locale.language.data], - ["host", `${window.location.origin}${window.location.pathname}`], - ["source", self.changes.state["currentUserLocation"]?.features?.data?.length > 0 ? "survey" : undefined], - ["imagery", self.changes.state["backgroundLayer"]?.data?.id], - ...changesetTags.map(cstag => [cstag.key, cstag.value]) - ] + const metadata = changesetTags.map(cstag => [cstag.key, cstag.value]) .filter(kv => (kv[1] ?? "") !== "") .map(kv => ``) .join("\n") @@ -382,7 +392,7 @@ export class ChangesetHandler { /** * Upload a changesetXML */ - private AddChange(changesetId: number, + private UploadChange(changesetId: number, changesetXML: string): Promise> { const self = this; return new Promise(function (resolve, reject) { diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index 6c6b62bf5a..b8eff0c6e7 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -291,7 +291,20 @@ "it": "Accessibile pubblicamente", "de": "Zugänglich für die Allgemeinheit", "fr": "Accessible au public" - } + }, + "addExtraTags": [ + "fee=no" + ] + }, + { + "if": "fee=yes", + "then": { + "en": "This is a paid playground", + "nl": "Er moet betaald worden om deze speeltuin te mogen gebruiken" + }, + "addExtraTags": [ + "access=customers" + ] }, { "if": "access=customers", @@ -301,7 +314,10 @@ "it": "Accessibile solamente ai clienti dell’attività che lo gestisce", "de": "Nur für Kunden des Betreibers zugänglich", "fr": "Réservée aux clients" - } + }, + "addExtraTags": [ + "fee=no" + ] }, { "if": "access=students", @@ -312,7 +328,10 @@ "de": "Nur für Schüler der Schule zugänglich", "fr": "Réservée aux élèves de l’école" }, - "hideInAnswer": true + "hideInAnswer": true, + "addExtraTags": [ + "fee=no" + ] }, { "if": "access=private", diff --git a/langs/fr.json b/langs/fr.json index 02c5fb932c..f11e9df0af 100644 --- a/langs/fr.json +++ b/langs/fr.json @@ -11,7 +11,8 @@ "delete": "Supprimer", "explanations": { "hardDelete": "Ce point sera supprimé d’OpenStreetmap. Il pourra être restauré par des méthodes avancées", - "selectReason": "Sélectionner pourquoi cet élément devrait être supprimé" + "selectReason": "Sélectionner pourquoi cet élément devrait être supprimé", + "softDelete": "Cet objet sera mis à jour et caché de l'application. {reason}" }, "isDeleted": "Cet objet est supprimé", "isntAPoint": "Seul les points peuvent être supprimés, l'objet sélectionné est une ligne, un polygone ou une relation.", @@ -56,7 +57,12 @@ "title": "Ajouter un nouveau point ?", "warnVisibleForEveryone": "Votre ajout sera visible", "zoomInFurther": "Rapprochez vous pour ajouter un point.", - "zoomInMore": "Zoomez pour importer cet élément" + "zoomInMore": "Zoomez pour importer cet élément", + "import": { + "howToTest": "Pour essayer, ajouter test=true ou backend=osm-test à l'adresse de la page. Le groupe de modifications sera affiché dans la console. Merci d'ouvrir un PR pour officialiser ce thème et ainsi activer le bouton d'import.", + "importTags": "L'objet recevra {tags}", + "hasBeenImported": "Cet objet a été importé" + } }, "attribution": { "attributionContent": "

Toutes les données sont fournies par OpenStreetMap, librement réutilisables sous Open DataBase License.

", @@ -283,4 +289,4 @@ "split": "Couper", "splitTitle": "Choisissez sur la carte où couper cette route" } -} \ No newline at end of file +} diff --git a/langs/layers/de.json b/langs/layers/de.json index c9d9bdfa12..8191260255 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -2334,13 +2334,13 @@ "0": { "then": "Zugänglich für die Allgemeinheit" }, - "1": { + "2": { "then": "Nur für Kunden des Betreibers zugänglich" }, - "2": { + "3": { "then": "Nur für Schüler der Schule zugänglich" }, - "3": { + "4": { "then": "Nicht zugänglich" } }, diff --git a/langs/layers/en.json b/langs/layers/en.json index 28db106a2d..4cccc8f62d 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -3944,12 +3944,15 @@ "then": "Accessible to the general public" }, "1": { - "then": "Only accessible for clients of the operating business" + "then": "This is a paid playground" }, "2": { - "then": "Only accessible to students of the school" + "then": "Only accessible for clients of the operating business" }, "3": { + "then": "Only accessible to students of the school" + }, + "4": { "then": "Not accessible" } }, diff --git a/langs/layers/fr.json b/langs/layers/fr.json index b4abbdfb95..4102259e54 100644 --- a/langs/layers/fr.json +++ b/langs/layers/fr.json @@ -210,7 +210,8 @@ "render": "Espace entre deux barrières successives : {width:separation} m" }, "Width of opening (cyclebarrier)": { - "render": "Largeur de l'ouverture : {width:opening} m" + "render": "Largeur de l'ouverture : {width:opening} m", + "question": "Quelle est la largeur d'ouverture la plus petite près de la barrière ?" }, "bicycle=yes/no": { "mappings": { @@ -220,6 +221,17 @@ "1": { "then": "Un cycliste ne peut pas franchir ceci." } + }, + "question": "Est-ce qu'un vélo peut franchir cette barrière ?" + }, + "barrier_type": { + "mappings": { + "0": { + "then": "C'est un plot unique sur la route" + }, + "1": { + "then": "C'est une barrière visant à ralentir les vélos" + } } } }, @@ -323,7 +335,8 @@ }, "title": { "render": "Banc" - } + }, + "description": "Un banc est une surface en bois, métal, pierre... sur laquelle un humain peut s'asseoir. Cette couche permet de les visualiser et pose des questions à leur sujet." }, "bench_at_pt": { "name": "Bancs des arrêts de transport en commun", @@ -339,7 +352,8 @@ "2": { "then": "Il n'y a pas de banc ici" } - } + }, + "question": "Quel type de banc est-ce ?" }, "bench_at_pt-name": { "render": "{name}" @@ -355,7 +369,8 @@ } }, "render": "Banc" - } + }, + "description": "Une couche montrant tous les arrêts de transports publics qui ont un banc" }, "bicycle_library": { "description": "Un lieu où des vélos peuvent être empruntés pour un temps plus long", @@ -1599,13 +1614,13 @@ "0": { "then": "Accessible au public" }, - "1": { + "2": { "then": "Réservée aux clients" }, - "2": { + "3": { "then": "Réservée aux élèves de l’école" }, - "3": { + "4": { "then": "Non accessible" } }, @@ -2381,5 +2396,18 @@ }, "watermill": { "name": "Moulin à eau" + }, + "bicycle_rental": { + "name": "Location de vélo", + "description": "Station de location de vélo", + "presets": { + "0": { + "description": "Un magasin avec employé(s) consacré à la location de vélos", + "title": "magasin de location de vélos" + }, + "1": { + "title": "location de vélos" + } + } } -} \ No newline at end of file +} diff --git a/langs/layers/id.json b/langs/layers/id.json index 5c30356901..195ee3b890 100644 --- a/langs/layers/id.json +++ b/langs/layers/id.json @@ -11,8 +11,17 @@ "0": { "then": "Bangunan ini tidak memiliki nomor rumah" } - } + }, + "question": "Berapa nomor rumah ini?", + "render": "Nomor rumah ini {addr:housenumber}" + }, + "street": { + "question": "Alamat ini di jalan apa?", + "render": "Alamat ini ada di jalan {addr:street}" } + }, + "title": { + "render": "Alamat yang diketahui" } }, "artwork": { @@ -377,5 +386,14 @@ }, "watermill": { "name": "Kincir Air" + }, + "ambulancestation": { + "name": "Peta stasiun ambulans", + "presets": { + "0": { + "description": "Tambahkan stasiun ambulans ke peta", + "title": "Stasiun ambulans" + } + } } -} \ No newline at end of file +} diff --git a/langs/layers/it.json b/langs/layers/it.json index b17dc48715..e54e68e674 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -1287,13 +1287,13 @@ "0": { "then": "Accessibile pubblicamente" }, - "1": { + "2": { "then": "Accessibile solamente ai clienti dell’attività che lo gestisce" }, - "2": { + "3": { "then": "Accessibile solamente agli studenti della scuola" }, - "3": { + "4": { "then": "Non accessibile" } }, diff --git a/langs/layers/nl.json b/langs/layers/nl.json index fdaebe8f80..d4966b4ecb 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -3753,12 +3753,15 @@ "then": "Vrij toegankelijk voor het publiek" }, "1": { - "then": "Enkel toegankelijk voor klanten van de bijhorende zaak" + "then": "Er moet betaald worden om deze speeltuin te mogen gebruiken" }, "2": { - "then": "Enkel toegankelijk voor scholieren van de bijhorende school" + "then": "Enkel toegankelijk voor klanten van de bijhorende zaak" }, "3": { + "then": "Enkel toegankelijk voor scholieren van de bijhorende school" + }, + "4": { "then": "Niet vrij toegankelijk" } }, diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 610d194804..8c43934aa5 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -1078,7 +1078,7 @@ }, "playground-access": { "mappings": { - "3": { + "4": { "then": "Недоступно" } } diff --git a/langs/shared-questions/fr.json b/langs/shared-questions/fr.json index d764695cb6..ef22e40128 100644 --- a/langs/shared-questions/fr.json +++ b/langs/shared-questions/fr.json @@ -36,6 +36,9 @@ }, "3": { "then": "Premier étage" + }, + "4": { + "then": "Sous-sol" } }, "question": "À quel étage se situe l’élément ?", @@ -111,6 +114,18 @@ } }, "question": "Quel est l’élément Wikipédia correspondant ?" + }, + "payment-options-advanced": { + "override": { + "mappings+": { + "0": { + "then": "Paiement via une application" + }, + "1": { + "then": "Paiement via une carte de membre" + } + } + } } } -} \ No newline at end of file +} diff --git a/langs/themes/fr.json b/langs/themes/fr.json index 79c8fc9bd9..417528dad5 100644 --- a/langs/themes/fr.json +++ b/langs/themes/fr.json @@ -561,6 +561,26 @@ "override": { "=name": "Institutions d'éducation sans origine étymologique" } + }, + "5": { + "override": { + "=name": "Lieux touristiques sans origine étymologique" + } + }, + "4": { + "override": { + "=name": "Lieux culturels sans origine étymologique" + } + }, + "6": { + "override": { + "=name": "Établissements sociaux ou de soins sans origine étymologique" + } + }, + "7": { + "override": { + "=name": "Lieux sportifs sans origine étymologique" + } } }, "shortDescription": "Quelle est l'origine de ce toponyme ?", @@ -778,5 +798,10 @@ "description": "Cartographions tous les arbres !", "shortDescription": "Carte des arbres", "title": "Arbres" + }, + "bicycle_rental": { + "shortDescription": "Une carte avec des stations et magasins de location de vélos", + "title": "Location de vélos", + "description": "Vous trouverez sur cette carte toutes les stations de location de vélo telles qu'elles sont référencées dans OpenStreetMap" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 0c5268bbda..04452053b7 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css", "test": "ts-node test/TestAll.ts", "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", - "add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote update weblate-layers", + "add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote add weblate-core https://hosted.weblate.org/git/mapcomplete/layer-core/; git remote add weblate-themes https://hosted.weblate.org/git/mapcomplete/layer-themes/; git remote add weblate-github git@github.com:weblate/MapComplete.git", "fix-weblate": "git remote update weblate-layers; git merge weblate-layers/master", "generate:editor-layer-index": "ts-node scripts/downloadFile.ts https://osmlab.github.io/editor-layer-index/imagery.geojson assets/editor-layer-index.json", "generate:polygon-features": "ts-node scripts/downloadFile.ts https://raw.githubusercontent.com/tyrasd/osm-polygon-features/master/polygon-features.json assets/polygon-features.json", diff --git a/test/Changes.spec.ts b/test/Changes.spec.ts new file mode 100644 index 0000000000..2466be54ae --- /dev/null +++ b/test/Changes.spec.ts @@ -0,0 +1,51 @@ +import T from "./TestHelper"; +import {Changes} from "../Logic/Osm/Changes"; +import {ChangeDescription, ChangeDescriptionTools} from "../Logic/Osm/Actions/ChangeDescription"; + +export default class ChangesSpec extends T { + + constructor() { + super([ + ["Generate preXML from changeDescriptions", () => { + const changeDescrs: ChangeDescription[] = [ + { + type: "node", + id: -1, + changes: { + lat: 42, + lon: -8 + }, + tags: [{k: "someKey", v: "someValue"}], + meta: { + changeType: "create", + theme: "test" + } + }, + { + type: "node", + id: -1, + tags: [{k: 'foo', v: 'bar'}], + meta: { + changeType: "answer", + theme: "test" + } + } + ] + const c = new Changes() + const descr = c.CreateChangesetObjects( + changeDescrs, + [] + ) + T.equals(0, descr.modifiedObjects.length) + T.equals(0, descr.deletedObjects.length) + T.equals(1, descr.newObjects.length) + const ch = descr.newObjects[0] + T.equals("bar", ch.tags["foo"]) + T.equals("someValue", ch.tags["someKey"]) + }] + ]); + + } + + +} \ No newline at end of file diff --git a/test/ChangesetHandler.spec.ts b/test/ChangesetHandler.spec.ts new file mode 100644 index 0000000000..8e0ee713b9 --- /dev/null +++ b/test/ChangesetHandler.spec.ts @@ -0,0 +1,181 @@ +import T from "./TestHelper"; +import {ChangesetHandler, ChangesetTag} from "../Logic/Osm/ChangesetHandler"; +import {UIEventSource} from "../Logic/UIEventSource"; +import {OsmConnection} from "../Logic/Osm/OsmConnection"; +import {ElementStorage} from "../Logic/ElementStorage"; +import {Changes} from "../Logic/Osm/Changes"; + +export default class ChangesetHandlerSpec extends T { + + private static asDict(tags: {key: string, value: string | number}[]) : Map{ + const d= new Map() + + for (const tag of tags) { + d.set(tag.key, tag.value) + } + + return d + } + + constructor() { + super([ + [ + "Test rewrite tags", () => { + const cs = new ChangesetHandler(new UIEventSource(true), + new OsmConnection({}), + new ElementStorage(), + new Changes(), + new UIEventSource(undefined) + ); + + + const oldChangesetMeta = { + "type": "changeset", + "id": 118443748, + "created_at": "2022-03-13T19:52:10Z", + "closed_at": "2022-03-13T20:54:35Z", + "open": false, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "minlat": 51.0361902, + "minlon": 3.7092939, + "maxlat": 51.0364194, + "maxlon": 3.7099520, + "comments_count": 0, + "changes_count": 3, + "tags": { + "answer": "5", + "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", + "created_by": "MapComplete 0.16.6", + "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", + "imagery": "osm", + "locale": "nl", + "source": "survey", + "source:node/-1":"note/1234", + "theme": "toerisme_vlaanderen", + } + } + let rewritten = cs.RewriteTagsOf( + [{ + key: "newTag", + value: "newValue", + aggregate: false + }], + new Map(), + oldChangesetMeta) + let d = ChangesetHandlerSpec.asDict(rewritten) + T.equals(10, d.size) + T.equals("5", d.get("answer")) + T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment")) + T.equals("MapComplete 0.16.6", d.get("created_by")) + T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host")) + T.equals("osm", d.get("imagery")) + T.equals("survey", d.get("source")) + T.equals("note/1234", d.get("source:node/-1")) + T.equals("toerisme_vlaanderen", d.get("theme")) + + T.equals("newValue", d.get("newTag")) + + + + + rewritten = cs.RewriteTagsOf( + [{ + key: "answer", + value: "37", + aggregate: true + }], + new Map(), + oldChangesetMeta) + d = ChangesetHandlerSpec.asDict(rewritten) + + T.equals(9, d.size) + T.equals("42", d.get("answer")) + T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment")) + T.equals("MapComplete 0.16.6", d.get("created_by")) + T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host")) + T.equals("osm", d.get("imagery")) + T.equals("survey", d.get("source")) + T.equals("note/1234", d.get("source:node/-1")) + T.equals("toerisme_vlaanderen", d.get("theme")) + + rewritten = cs.RewriteTagsOf( + [], + new Map([["node/-1", "node/42"]]), + oldChangesetMeta) + d = ChangesetHandlerSpec.asDict(rewritten) + + T.equals(9, d.size) + T.equals("5", d.get("answer")) + T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment")) + T.equals("MapComplete 0.16.6", d.get("created_by")) + T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host")) + T.equals("osm", d.get("imagery")) + T.equals("survey", d.get("source")) + T.equals("note/1234", d.get("source:node/42")) + T.equals("toerisme_vlaanderen", d.get("theme")) + + }, + ],[ + "Test rewrite on special motivation", () => { + + + const cs = new ChangesetHandler(new UIEventSource(true), + new OsmConnection({}), + new ElementStorage(), + new Changes(), + new UIEventSource(undefined) + ); + + + const oldChangesetMeta = { + "type": "changeset", + "id": 118443748, + "created_at": "2022-03-13T19:52:10Z", + "closed_at": "2022-03-13T20:54:35Z", + "open": false, + "user": "Pieter Vander Vennet", + "uid": 3818858, + "minlat": 51.0361902, + "minlon": 3.7092939, + "maxlat": 51.0364194, + "maxlon": 3.7099520, + "comments_count": 0, + "changes_count": 3, + "tags": { + "answer": "5", + "comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen", + "created_by": "MapComplete 0.16.6", + "host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html", + "imagery": "osm", + "locale": "nl", + "source": "survey", + "source:-1":"note/1234", + "theme": "toerisme_vlaanderen", + } + } + + const extraMetaTags : ChangesetTag[] = [ + { + key: "created_by", + value:"mapcomplete" + }, + { + key: "source:node/-1", + value:"note/1234" + } + ] + const changes = new Map([["node/-1","node/42"]]) + const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes) + T.isTrue(hasSpecialMotivationChanges, "Special rewrite did not trigger") + // Rewritten inline by rewriteMetaTags + T.equals("source:node/42", extraMetaTags[1].key) + T.equals("note/1234", extraMetaTags[1].value) + T.equals("created_by", extraMetaTags[0].key) + T.equals("mapcomplete", extraMetaTags[0].value) + } + + ] + ]); + } +} \ No newline at end of file diff --git a/test/TestAll.ts b/test/TestAll.ts index 37f4082200..9dc045cf90 100644 --- a/test/TestAll.ts +++ b/test/TestAll.ts @@ -21,11 +21,16 @@ import ValidatedTextFieldTranslationsSpec from "./ValidatedTextFieldTranslations import CreateCacheSpec from "./CreateCache.spec"; import CodeQualitySpec from "./CodeQuality.spec"; import ImportMultiPolygonSpec from "./ImportMultiPolygon.spec"; +import {ChangesetHandler} from "../Logic/Osm/ChangesetHandler"; +import ChangesetHandlerSpec from "./ChangesetHandler.spec"; +import ChangesSpec from "./Changes.spec"; async function main() { const allTests: T[] = [ + new ChangesSpec(), + new ChangesetHandlerSpec(), new OsmObjectSpec(), new TagSpec(), new ImageAttributionSpec(), @@ -45,7 +50,7 @@ async function main() { new ValidatedTextFieldTranslationsSpec(), new CreateCacheSpec(), new CodeQualitySpec(), - new ImportMultiPolygonSpec() + new ImportMultiPolygonSpec(), ] ScriptUtils.fixUtils(); const realDownloadFunc = Utils.externalDownloadFunction;