source: josm/trunk/test/unit/org/openstreetmap/josm/io/OverpassDownloadReaderTest.java @ 12714

Last change on this file since 12714 was 12714, checked in by Don-vip, 3 weeks ago

fix #15228 - Support missing Overpass Turbo extended shortcuts: {{center}}, {{date:string}}, {{geocodeId:name}}, {{geocodeBbox:name}}, {{geocodeCoords:name}}

File size: 7.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
5import static com.github.tomakehurst.wiremock.client.WireMock.get;
6import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
7import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
8import static org.junit.Assert.assertEquals;
9import static org.junit.Assert.assertNotNull;
10import static org.junit.Assert.assertTrue;
11
12import java.time.LocalDateTime;
13import java.util.regex.Matcher;
14
15import org.junit.Before;
16import org.junit.Rule;
17import org.junit.Test;
18import org.openstreetmap.josm.TestUtils;
19import org.openstreetmap.josm.data.Bounds;
20import org.openstreetmap.josm.io.OverpassDownloadReader.OverpassOutpoutFormat;
21import org.openstreetmap.josm.testutils.JOSMTestRules;
22import org.openstreetmap.josm.tools.OverpassTurboQueryWizard;
23import org.openstreetmap.josm.tools.Utils;
24import org.openstreetmap.josm.tools.date.DateUtils;
25
26import com.github.tomakehurst.wiremock.junit.WireMockRule;
27
28import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
29
30/**
31 * Unit tests of {@link OverpassDownloadReader} class.
32 */
33public class OverpassDownloadReaderTest {
34
35    /**
36     * Base test environment is enough
37     */
38    @Rule
39    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
40    public JOSMTestRules test = new JOSMTestRules().preferences();
41
42    /**
43     * HTTP mock.
44     */
45    @Rule
46    public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort().usingFilesUnderDirectory(TestUtils.getTestDataRoot()));
47
48    private static final String NOMINATIM_URL_PATH = "/search?format=xml&q=";
49
50    /**
51     * Setup test.
52     */
53    @Before
54    public void setUp() {
55        NameFinder.NOMINATIM_URL_PROP.put("http://localhost:" + wireMockRule.port() + NOMINATIM_URL_PATH);
56    }
57
58    private String getExpandedQuery(String search) {
59        final String query = OverpassTurboQueryWizard.getInstance().constructQuery(search);
60        final String request = new OverpassDownloadReader(new Bounds(1, 2, 3, 4), null, query)
61                .getRequestForBbox(1, 2, 3, 4)
62                .substring("interpreter?data=".length());
63        return Utils.decodeUrl(request);
64    }
65
66    /**
67     * Tests evaluating the extended query feature {@code bbox}.
68     */
69    @Test
70    public void testBbox() {
71        final String query = getExpandedQuery("amenity=drinking_water");
72        assertEquals("" +
73                "[out:xml][timeout:25][bbox:2.0,1.0,4.0,3.0];\n" +
74                "(\n" +
75                "  node[\"amenity\"=\"drinking_water\"];\n" +
76                "  way[\"amenity\"=\"drinking_water\"];\n" +
77                "  relation[\"amenity\"=\"drinking_water\"];\n" +
78                ");\n" +
79                "(._;>;);\n" +
80                "out meta;", query);
81    }
82
83    private void stubNominatim(String query) {
84        wireMockRule.stubFor(get(urlEqualTo(NOMINATIM_URL_PATH + query))
85                .willReturn(aResponse()
86                    .withStatus(200)
87                    .withHeader("Content-Type", "text/xml")
88                    .withBodyFile("nominatim/" + query + ".xml")));
89    }
90
91    /**
92     * Tests evaluating the extended query feature {@code date}.
93     */
94    @Test
95    public void testDate() {
96        LocalDateTime from = LocalDateTime.of(2017, 7, 14, 2, 40);
97        assertEquals("2016-07-14T02:40:00Z", OverpassDownloadReader.date("1 year", from));
98        assertEquals("2007-07-14T02:40:00Z", OverpassDownloadReader.date("10years", from));
99        assertEquals("2017-06-14T02:40:00Z", OverpassDownloadReader.date("1 month", from));
100        assertEquals("2016-09-14T02:40:00Z", OverpassDownloadReader.date("10months", from));
101        assertEquals("2017-07-07T02:40:00Z", OverpassDownloadReader.date("1 week", from));
102        assertEquals("2017-05-05T02:40:00Z", OverpassDownloadReader.date("10weeks", from));
103        assertEquals("2017-07-13T02:40:00Z", OverpassDownloadReader.date("1 day", from));
104        assertEquals("2017-07-04T02:40:00Z", OverpassDownloadReader.date("10days", from));
105        assertEquals("2017-07-14T01:40:00Z", OverpassDownloadReader.date("1 hour", from));
106        assertEquals("2017-07-13T16:40:00Z", OverpassDownloadReader.date("10hours", from));
107        assertEquals("2017-07-14T02:39:00Z", OverpassDownloadReader.date("1 minute", from));
108        assertEquals("2017-07-14T02:30:00Z", OverpassDownloadReader.date("10minutes", from));
109        assertEquals("2017-07-14T02:39:59Z", OverpassDownloadReader.date("1 second", from));
110        assertEquals("2017-07-14T02:39:50Z", OverpassDownloadReader.date("10seconds", from));
111
112        assertEquals("2016-07-13T02:40:00Z", OverpassDownloadReader.date("1 year 1 day", from));
113        assertEquals("2016-07-14T02:38:20Z", OverpassDownloadReader.date("1 year 100 seconds", from));
114        assertEquals("2017-07-13T02:38:20Z", OverpassDownloadReader.date("1 day  100 seconds", from));
115    }
116
117    /**
118     * Tests evaluating the extended query feature {@code date} through {@code newer:} operator.
119     */
120    @Test
121    public void testDateNewer() {
122        final String query = getExpandedQuery("type:node and newer:3minutes");
123        String statement = query.substring(query.indexOf("node(newer:\"") + 12, query.lastIndexOf("\");"));
124        assertNotNull(DateUtils.fromString(statement));
125    }
126
127    /**
128     * Tests evaluating the extended query feature {@code geocodeArea}.
129     */
130    @Test
131    public void testGeocodeArea() {
132        stubNominatim("London");
133        final String query = getExpandedQuery("amenity=drinking_water in London");
134        assertEquals("" +
135                "[out:xml][timeout:25];\n" +
136                "area(3600065606)->.searchArea;\n" +
137                "(\n" +
138                "  node[\"amenity\"=\"drinking_water\"](area.searchArea);\n" +
139                "  way[\"amenity\"=\"drinking_water\"](area.searchArea);\n" +
140                "  relation[\"amenity\"=\"drinking_water\"](area.searchArea);\n" +
141                ");\n" +
142                "(._;>;);\n" +
143                "out meta;", query);
144    }
145
146    /**
147     * Tests evaluating the extended query feature {@code geocodeArea}.
148     */
149    @Test
150    public void testGeocodeUnknownArea() {
151        stubNominatim("foo-bar-baz-does-not-exist");
152        final String query = OverpassDownloadReader.expandExtendedQueries("{{geocodeArea:foo-bar-baz-does-not-exist}}");
153        assertEquals("// Failed to evaluate {{geocodeArea:foo-bar-baz-does-not-exist}}\n", query);
154    }
155
156    /**
157     * Tests evaluating the overpass output format statements.
158     */
159    @Test
160    public void testOutputFormatStatement() {
161        for (OverpassOutpoutFormat oof : OverpassOutpoutFormat.values()) {
162            Matcher m = OverpassDownloadReader.OUTPUT_FORMAT_STATEMENT.matcher("[out:"+oof.getDirective()+"]");
163            assertTrue(m.matches());
164            assertEquals(oof.getDirective(), m.group(1));
165        }
166
167        assertTrue(OverpassDownloadReader.OUTPUT_FORMAT_STATEMENT.matcher(
168                "[out:pbf][timeout:25][bbox:{{bbox}}];\n" +
169                "(\n" +
170                "  node[\"amenity\"=\"pharmacy\"];\n" +
171                "  way[\"amenity\"=\"pharmacy\"];\n" +
172                "  relation[\"amenity\"=\"pharmacy\"];\n" +
173                ");\n" +
174                "(._;>;);\n" +
175                "out meta;").matches());
176    }
177}
Note: See TracBrowser for help on using the repository browser.