UNPKG

8.19 kBJavaScriptView Raw
1var test = require('tape')
2var contentType = require('content-type')
3var parsexml = require('xml-parser')
4var hyperquest = require('hyperquest')
5var concat = require('concat-stream')
6var createServer = require('./lib/test_server.js')
7
8var base, server, changeId
9
10test('bbox.js: setup changeset server', function (t) {
11 createServer(function (d) {
12 base = d.base
13 server = d.server
14 t.end()
15 })
16})
17
18test('create bbox', function (t) {
19 t.plan(4)
20 var href = base + 'changeset/create'
21 var hq = hyperquest.put(href, {
22 headers: { 'content-type': 'text/xml' }
23 })
24 hq.once('response', function (res) {
25 t.equal(res.statusCode, 200, 'create 200 ok')
26 var contentObj = contentType.parse(res)
27 t.equal(contentObj.type, 'text/plain', 'media type correct')
28 t.equal(contentObj.parameters.charset.toLowerCase(), 'utf-8', 'charset correct')
29 })
30 hq.pipe(concat({ encoding: 'string' }, function (body) {
31 changeId = body.trim()
32 t.ok(/^[0-9A-Fa-f]+$/.test(changeId), 'expected changeset id response')
33 }))
34 hq.end('<osm><changeset></changeset></osm>')
35})
36
37var uploaded = {}
38var SIZE = 100
39test('add docs to changeset', function (t) {
40 t.plan(4)
41 var docs = []
42 for (var i = 0; i < SIZE; i++) {
43 docs.push({
44 type: 'node',
45 id: 0 - i - 1,
46 lat: 64 + i / SIZE,
47 lon: -121 - i / SIZE,
48 changeset: changeId
49 })
50 }
51 docs.push({
52 type: 'way',
53 id: 0 - i - 1,
54 changeset: changeId,
55 refs: docs.map(function (d, i) { return 0 - (i + 1) })
56 })
57 var kdocs = {}
58 docs.forEach(function (doc, i) {
59 kdocs[0 - i - 1] = doc
60 })
61
62 var href = base + 'changeset/' + changeId + '/upload'
63 var hq = hyperquest.post(href, {
64 headers: { 'content-type': 'text/xml' }
65 })
66 hq.once('response', function (res) {
67 t.equal(res.statusCode, 200)
68 var contentObj = contentType.parse(res)
69 t.equal(contentObj.type, 'text/xml', 'media type correct')
70 t.equal(contentObj.parameters.charset.toLowerCase(), 'utf-8', 'charset correct')
71 })
72 hq.pipe(concat({ encoding: 'string' }, function (body) {
73 var xml = parsexml(body)
74 t.equal(xml.root.name, 'diffResult')
75 xml.root.children.forEach(function (node, i) {
76 var id = node.attributes.new_id
77 uploaded[id] = kdocs[0 - i - 1]
78 uploaded[id].id = id
79 if (node.name === 'way') {
80 uploaded[id].refs = uploaded[id].refs.map(function (ref) {
81 return kdocs[ref].id
82 })
83 }
84 })
85 }))
86 hq.end(`<osmChange version="1.0">
87 <create>
88 ${docs.map(function (doc) {
89 return `<${doc.type} changeset="${doc.changeset}"
90 id="${doc.id}"
91 ${doc.lat ? `lat="${doc.lat}"` : ''}
92 ${doc.lon ? `lon="${doc.lon}"` : ''}>
93 ${(doc.refs || []).map(function (ref) {
94 return `<nd ref="${ref}"/>`
95 }).join('\n')}
96 </${doc.type}>`
97 }).join('\n')}
98 </create>
99 </osmChange>`)
100})
101
102test('bbox', function (t) {
103 t.plan(8 + SIZE * 3)
104 var href = base + 'map?bbox=-123,63,-120,66'
105 var hq = hyperquest(href)
106 hq.once('response', function (res) {
107 t.equal(res.statusCode, 200)
108 t.equal(res.headers['content-type'].split(/\s*;\s*/)[0], 'text/xml')
109 })
110 hq.pipe(concat({ encoding: 'string' }, function (body) {
111 var xml = parsexml(body)
112 t.equal(xml.root.name, 'osm')
113 t.equal(xml.root.children[0].name, 'bounds')
114 t.deepEqual(xml.root.children[0].attributes, { maxlat: '66', maxlon: '-120', minlat: '63', minlon: '-123' }, 'bounds matches request')
115 t.ok(orderedTypes(xml.root.children.map(function (c) {
116 return c.name
117 })), 'ordered types')
118
119 for (var i = 1; i < xml.root.children.length; i++) {
120 var c = xml.root.children[i]
121 var node = uploaded[c.attributes.id]
122 if (c.name === 'node') {
123 t.equal(c.attributes.changeset, node.changeset)
124 t.equal(c.attributes.lat, String(node.lat))
125 t.equal(c.attributes.lon, String(node.lon))
126 } else if (c.name === 'way') {
127 t.equal(c.children.length, SIZE, 'way')
128 t.deepEqual(c.children.map(function (nd) {
129 return nd.attributes.ref
130 }), node.refs, 'way refs')
131 }
132 }
133 }))
134})
135
136test('missing bbox', function (t) {
137 t.plan(4)
138 var href = base + 'map'
139 var hq = hyperquest(href)
140 hq.once('response', function (res) {
141 t.equal(res.statusCode, 400)
142 var contentObj = contentType.parse(res)
143 t.equal(contentObj.type, 'text/plain', 'media type correct')
144 t.equal(contentObj.parameters.charset.toLowerCase(), 'utf-8', 'charset correct')
145 })
146 hq.pipe(concat({ encoding: 'string' }, function (body) {
147 t.equal(body, 'Missing bbox query string parameter')
148 }))
149})
150
151test('invalid bbox', function (t) {
152 t.plan(4)
153 var href = base + 'map?bbox=invalid'
154 var hq = hyperquest(href)
155 hq.once('response', function (res) {
156 t.equal(res.statusCode, 400)
157 var contentObj = contentType.parse(res)
158 t.equal(contentObj.type, 'text/plain', 'media type correct')
159 t.equal(contentObj.parameters.charset.toLowerCase(), 'utf-8', 'charset correct')
160 })
161 hq.pipe(concat({ encoding: 'string' }, function (body) {
162 t.equal(body, 'Invalid bbox query string parameter')
163 }))
164})
165
166test('out of range bbox', function (t) {
167 t.plan(4)
168 var href = base + 'map?bbox=-181,1,2,2'
169 var hq = hyperquest(href)
170 hq.once('response', function (res) {
171 t.equal(res.statusCode, 400)
172 var contentObj = contentType.parse(res)
173 t.equal(contentObj.type, 'text/plain', 'media type correct')
174 t.equal(contentObj.parameters.charset.toLowerCase(), 'utf-8', 'charset correct')
175 })
176 hq.pipe(concat({ encoding: 'string' }, function (body) {
177 t.equal(body, 'Invalid bbox query string parameter')
178 }))
179})
180
181test('bbox json', function (t) {
182 t.plan(7 + SIZE * 3)
183 var href = base + 'map?bbox=-123,63,-120,66'
184 var hq = hyperquest(href, {headers: { 'Accept': 'application/json' }})
185 hq.once('response', function (res) {
186 t.equal(res.statusCode, 200)
187 t.equal(res.headers['content-type'].split(/\s*;\s*/)[0], 'application/json')
188 })
189 hq.pipe(concat({ encoding: 'string' }, function (body) {
190 var json = JSON.parse(body)
191 t.equal(json.version, 0.6)
192 t.deepEqual(json.bounds, { maxlat: 66, maxlon: -120, minlat: 63, minlon: -123 }, 'bounds matches request')
193 t.ok(orderedTypes(json.elements.map(function (c) {
194 return c.type
195 })), 'ordered types')
196
197 for (var i = 0; i < json.elements.length; i++) {
198 var c = json.elements[i]
199 var node = uploaded[c.id]
200 if (c.type === 'node') {
201 t.equal(c.changeset, node.changeset)
202 t.equal(c.lat, node.lat)
203 t.equal(c.lon, node.lon)
204 } else if (c.type === 'way') {
205 t.equal(c.nodes.length, SIZE, 'way')
206 t.deepEqual(c.nodes, node.refs, 'way refs')
207 }
208 }
209 }))
210})
211
212test('bbox json /w forks', function (t) {
213 t.plan(7 + SIZE * 3)
214 var href = base + 'map?bbox=-123,63,-120,66&forks=true'
215 var hq = hyperquest(href, {headers: { 'Accept': 'application/json' }})
216 hq.once('response', function (res) {
217 t.equal(res.statusCode, 200)
218 t.equal(res.headers['content-type'].split(/\s*;\s*/)[0], 'application/json')
219 })
220 hq.pipe(concat({ encoding: 'string' }, function (body) {
221 var json = JSON.parse(body)
222 t.equal(json.version, 0.6)
223 t.deepEqual(json.bounds, { maxlat: 66, maxlon: -120, minlat: 63, minlon: -123 }, 'bounds matches request')
224 t.ok(orderedTypes(json.elements.map(function (c) {
225 return c.type
226 })), 'ordered types')
227
228 for (var i = 0; i < json.elements.length; i++) {
229 var c = json.elements[i]
230 var node = uploaded[c.id]
231 if (c.type === 'node') {
232 t.equal(c.changeset, node.changeset)
233 t.equal(c.lat, node.lat)
234 t.equal(c.lon, node.lon)
235 } else if (c.type === 'way') {
236 t.equal(c.nodes.length, SIZE, 'way')
237 t.deepEqual(c.nodes, node.refs, 'way refs')
238 }
239 }
240 }))
241})
242
243test('bbox.js: teardown server', function (t) {
244 server.cleanup(function () {
245 t.end()
246 })
247})
248
249function orderedTypes (types) {
250 var order = { bounds: 0, node: 0, way: 1, relation: 2 }
251 for (var i = 1; i < types.length; i++) {
252 if (order[types[i - 1]] > order[types[i]]) return false
253 }
254 return true
255}