OLD | NEW |
1 'use strict'; | 1 'use strict'; |
2 | 2 |
3 var test_text_data = 'Test text data.'; | 3 var test_text_data = 'Test text data.'; |
4 var test_text_byte_array = new TextEncoder('utf-8').encode(test_text_data); | 4 var test_text_byte_array = new TextEncoder('utf-8').encode(test_text_data); |
5 var test_number_data = 42; | 5 var test_number_data = 42; |
6 var test_json_data = {level: 1, score: 100, label: 'Game'}; | 6 var test_json_data = {level: 1, score: 100, label: 'Game'}; |
7 var test_url_data = 'https://w3c.github.io/web-nfc/'; | 7 var test_url_data = 'https://w3c.github.io/web-nfc/'; |
8 var test_message_origin = 'https://127.0.0.1:8443'; | 8 var test_message_origin = 'https://127.0.0.1:8443'; |
9 var test_buffer_data = new ArrayBuffer(test_text_byte_array.length); | 9 var test_buffer_data = new ArrayBuffer(test_text_byte_array.length); |
10 var test_buffer_view = new Uint8Array(test_buffer_data).set(test_text_byte_array
); | 10 var test_buffer_view = new Uint8Array(test_buffer_data).set(test_text_byte_array
); |
11 | 11 |
12 var NFCHWStatus = {}; | 12 var NFCHWStatus = {}; |
13 NFCHWStatus.ENABLED = 1; | 13 NFCHWStatus.ENABLED = 1; |
14 NFCHWStatus.NOT_SUPPORTED = NFCHWStatus.ENABLED + 1; | 14 NFCHWStatus.NOT_SUPPORTED = NFCHWStatus.ENABLED + 1; |
15 NFCHWStatus.DISABLED = NFCHWStatus.NOT_SUPPORTED + 1; | 15 NFCHWStatus.DISABLED = NFCHWStatus.NOT_SUPPORTED + 1; |
16 | 16 |
| 17 function noop() {} |
| 18 |
17 function assertRejectsWithError(promise, name) { | 19 function assertRejectsWithError(promise, name) { |
18 return promise.then(() => { | 20 return promise.then(() => { |
19 assert_unreached('expected promise to reject with ' + name); | 21 assert_unreached('expected promise to reject with ' + name); |
20 }, error => { | 22 }, error => { |
21 assert_equals(error.name, name); | 23 assert_equals(error.name, name); |
22 }); | 24 }); |
23 } | 25 } |
24 | 26 |
25 function createMessage(records) { | 27 function createMessage(records) { |
26 if (records !== undefined) { | 28 if (records !== undefined) { |
(...skipping 11 matching lines...) Expand all Loading... |
38 record.mediaType = mediaType; | 40 record.mediaType = mediaType; |
39 if (data !== undefined) | 41 if (data !== undefined) |
40 record.data = data; | 42 record.data = data; |
41 return record; | 43 return record; |
42 } | 44 } |
43 | 45 |
44 function createNFCPushOptions(target, timeout, ignoreRead) { | 46 function createNFCPushOptions(target, timeout, ignoreRead) { |
45 return { target, timeout, ignoreRead }; | 47 return { target, timeout, ignoreRead }; |
46 } | 48 } |
47 | 49 |
| 50 function createNFCWatchOptions(url, recordType, mediaType, mode) { |
| 51 return { url, recordType, mediaType, mode}; |
| 52 } |
| 53 |
48 function createTextRecord(text) { | 54 function createTextRecord(text) { |
49 return createRecord('text', 'text/plain', text); | 55 return createRecord('text', 'text/plain', text); |
50 } | 56 } |
51 | 57 |
52 function createJsonRecord(json) { | 58 function createJsonRecord(json) { |
53 return createRecord('json', 'application/json', json); | 59 return createRecord('json', 'application/json', json); |
54 } | 60 } |
55 | 61 |
56 function createOpaqueRecord(buffer) { | 62 function createOpaqueRecord(buffer) { |
57 return createRecord('opaque', 'application/octet-stream', buffer); | 63 return createRecord('opaque', 'application/octet-stream', buffer); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 return nfc.NFCPushTarget.ANY; | 95 return nfc.NFCPushTarget.ANY; |
90 case 'peer': | 96 case 'peer': |
91 return nfc.NFCPushTarget.PEER; | 97 return nfc.NFCPushTarget.PEER; |
92 case 'tag': | 98 case 'tag': |
93 return nfc.NFCPushTarget.TAG; | 99 return nfc.NFCPushTarget.TAG; |
94 } | 100 } |
95 | 101 |
96 return nfc.NFCPushTarget.ANY; | 102 return nfc.NFCPushTarget.ANY; |
97 } | 103 } |
98 | 104 |
| 105 function toMojoNFCWatchMode(mode) { |
| 106 if (mode === 'web-nfc-only') |
| 107 return nfc.NFCWatchMode.WEBNFC_ONLY; |
| 108 return nfc.NFCWatchMode.ANY; |
| 109 } |
| 110 |
| 111 // Converts between NFCMessage https://w3c.github.io/web-nfc/#dom-nfcmessage |
| 112 // and mojo::NFCMessage structure, so that nfc.watch function can be tested. |
| 113 function toMojoNFCMessage(message) { |
| 114 let nfcMessage = new nfc.NFCMessage(); |
| 115 nfcMessage.url = message.url; |
| 116 nfcMessage.data = []; |
| 117 for (let record of message.data) |
| 118 nfcMessage.data.push(toMojoNFCRecord(record)); |
| 119 return nfcMessage; |
| 120 } |
| 121 |
| 122 function toMojoNFCRecord(record) { |
| 123 let nfcRecord = new nfc.NFCRecord(); |
| 124 nfcRecord.record_type = toMojoNFCRecordType(record.recordType); |
| 125 nfcRecord.media_type = record.mediaType; |
| 126 nfcRecord.data = toByteArray(record.data); |
| 127 return nfcRecord; |
| 128 } |
| 129 |
99 function toByteArray(data) { | 130 function toByteArray(data) { |
100 // Convert JS objects to byte array | 131 // Convert JS objects to byte array |
101 let byteArray; | 132 let byteArray; |
102 let tmpData = data; | 133 let tmpData = data; |
103 | 134 |
104 if (tmpData instanceof ArrayBuffer) | 135 if (tmpData instanceof ArrayBuffer) |
105 byteArray = new Uint8Array(tmpData); | 136 byteArray = new Uint8Array(tmpData); |
106 else if (typeof tmpData === 'object' || typeof tmpData === 'number') | 137 else if (typeof tmpData === 'object' || typeof tmpData === 'number') |
107 tmpData = JSON.stringify(tmpData); | 138 tmpData = JSON.stringify(tmpData); |
108 | 139 |
(...skipping 17 matching lines...) Expand all Loading... |
126 provided = createMessage([createTextRecord(providedMessage)]); | 157 provided = createMessage([createTextRecord(providedMessage)]); |
127 | 158 |
128 assert_equals(provided.data.length, receivedMessage.data.length, | 159 assert_equals(provided.data.length, receivedMessage.data.length, |
129 'NFCMessages must have same number of NFCRecords'); | 160 'NFCMessages must have same number of NFCRecords'); |
130 | 161 |
131 // Compare contents of each individual NFCRecord | 162 // Compare contents of each individual NFCRecord |
132 for (let i = 0; i < provided.data.length; ++i) | 163 for (let i = 0; i < provided.data.length; ++i) |
133 compareNFCRecords(provided.data[i], receivedMessage.data[i]); | 164 compareNFCRecords(provided.data[i], receivedMessage.data[i]); |
134 } | 165 } |
135 | 166 |
| 167 // Used to compare two WebNFC messages, one that is provided to mock NFC |
| 168 // service through triggerWatchCallback and another that is received by |
| 169 // callback that is provided to navigator.nfc.watch function. |
| 170 function assertWebNFCMessagesEqual(a, b) { |
| 171 assert_equals(a.url, b.url); |
| 172 assert_equals(a.data.length, b.data.length); |
| 173 for(let i in a.data) { |
| 174 let recordA = a.data[i]; |
| 175 let recordB = b.data[i]; |
| 176 assert_equals(recordA.recordType, recordB.recordType); |
| 177 assert_equals(recordA.mediaType, recordB.mediaType); |
| 178 |
| 179 if (recordA.data instanceof ArrayBuffer) { |
| 180 assert_array_equals(new Uint8Array(recordA.data), |
| 181 new Uint8Array(recordB.data)); |
| 182 } else if (typeof recordA.data === 'object') { |
| 183 assert_object_equals(recordA.data, recordB.data); |
| 184 } |
| 185 |
| 186 if (typeof recordA.data === 'number' |
| 187 || typeof recordA.data === 'string') { |
| 188 assert_true(recordA.data == recordB.data); |
| 189 } |
| 190 } |
| 191 } |
| 192 |
136 // Compares NFCRecords that were provided / received by the mock service. | 193 // Compares NFCRecords that were provided / received by the mock service. |
137 function compareNFCRecords(providedRecord, receivedRecord) { | 194 function compareNFCRecords(providedRecord, receivedRecord) { |
138 assert_equals(toMojoNFCRecordType(providedRecord.recordType), | 195 assert_equals(toMojoNFCRecordType(providedRecord.recordType), |
139 receivedRecord.record_type); | 196 receivedRecord.record_type); |
140 | 197 |
141 // Compare media types without charset. | 198 // Compare media types without charset. |
142 // Charset should be compared when watch method is implemented, in order | 199 // Charset should be compared when watch method is implemented, in order |
143 // to check that written and read strings are equal. | 200 // to check that written and read strings are equal. |
144 assert_equals(providedRecord.mediaType, | 201 assert_equals(providedRecord.mediaType, |
145 receivedRecord.media_type.substring(0, providedRecord.mediaType.length
)); | 202 receivedRecord.media_type.substring(0, providedRecord.mediaType.length
)); |
(...skipping 17 matching lines...) Expand all Loading... |
163 assert_equals(provided.timeout, received.timeout); | 220 assert_equals(provided.timeout, received.timeout); |
164 else | 221 else |
165 assert_equals(received.timeout, Infinity); | 222 assert_equals(received.timeout, Infinity); |
166 | 223 |
167 if (provided.target !== undefined) | 224 if (provided.target !== undefined) |
168 assert_equals(toMojoNFCPushTarget(provided.target), received.target); | 225 assert_equals(toMojoNFCPushTarget(provided.target), received.target); |
169 else | 226 else |
170 assert_equals(received.target, nfc.NFCPushTarget.ANY); | 227 assert_equals(received.target, nfc.NFCPushTarget.ANY); |
171 } | 228 } |
172 | 229 |
| 230 // Compares NFCWatchOptions structures that were provided to API and |
| 231 // received by the mock mojo service. |
| 232 function assertNFCWatchOptionsEqual(provided, received) { |
| 233 if (provided.url !== undefined) |
| 234 assert_equals(provided.url, received.url); |
| 235 else |
| 236 assert_equals(received.url, ''); |
| 237 |
| 238 if (provided.mediaType !== undefined) |
| 239 assert_equals(provided.mediaType, received.media_type); |
| 240 else |
| 241 assert_equals(received.media_type, ''); |
| 242 |
| 243 if (provided.mode !== undefined) |
| 244 assert_equals(toMojoNFCWatchMode(provided.mode), received.mode); |
| 245 else |
| 246 assert_equals(received.mode, nfc.NFCWatchMode.WEBNFC_ONLY); |
| 247 |
| 248 if (provided.recordType !== undefined) { |
| 249 assert_equals(!+received.record_filter, true); |
| 250 assert_equals(toMojoNFCRecordType(provided.recordType), |
| 251 received.record_filter.record_type); |
| 252 } |
| 253 } |
| 254 |
173 function createNFCError(type) { | 255 function createNFCError(type) { |
174 return { error: type ? | 256 return { error: type ? |
175 new nfc.NFCError({ error_type: type }) : null }; | 257 new nfc.NFCError({ error_type: type }) : null }; |
176 } | 258 } |
177 | 259 |
178 class MockNFC { | 260 class MockNFC { |
179 constructor() { | 261 constructor() { |
180 this.hw_status_ = NFCHWStatus.ENABLED; | 262 this.hw_status_ = NFCHWStatus.ENABLED; |
181 this.pushed_message_ = null; | 263 this.pushed_message_ = null; |
182 this.push_options_ = null; | 264 this.push_options_ = null; |
183 this.pending_promise_func_ = null; | 265 this.pending_promise_func_ = null; |
184 this.push_timeout_id_ = null; | 266 this.push_timeout_id_ = null; |
185 this.push_completed_ = true; | 267 this.push_completed_ = true; |
| 268 this.client_ = null; |
| 269 this.watch_id_ = 0; |
| 270 this.watchers_ = []; |
186 } | 271 } |
187 | 272 |
188 // NFC.stubClass delegate functions | 273 // NFC.stubClass delegate functions |
189 push(message, options) { | 274 push(message, options) { |
190 let error = this.isReady(); | 275 let error = this.isReady(); |
191 if (error) | 276 if (error) |
192 return Promise.resolve(error); | 277 return Promise.resolve(error); |
193 | 278 |
194 this.pushed_message_ = message; | 279 this.pushed_message_ = message; |
195 this.push_options_ = options; | 280 this.push_options_ = options; |
(...skipping 14 matching lines...) Expand all Loading... |
210 | 295 |
211 cancelPush(target) { | 296 cancelPush(target) { |
212 if (this.push_options_ && ((target === nfc.NFCPushTarget.ANY) || | 297 if (this.push_options_ && ((target === nfc.NFCPushTarget.ANY) || |
213 (this.push_options_.target === target))) { | 298 (this.push_options_.target === target))) { |
214 this.cancelPendingPushOperation(); | 299 this.cancelPendingPushOperation(); |
215 } | 300 } |
216 | 301 |
217 return Promise.resolve(createNFCError(null)); | 302 return Promise.resolve(createNFCError(null)); |
218 } | 303 } |
219 | 304 |
| 305 setClient(client) { |
| 306 this.client_ = client; |
| 307 } |
| 308 |
| 309 watch(options) { |
| 310 let error = this.isReady(); |
| 311 if (error) { |
| 312 error.id = 0; |
| 313 return Promise.resolve(error); |
| 314 } |
| 315 |
| 316 let retVal = createNFCError(null); |
| 317 retVal.id = ++this.watch_id_; |
| 318 this.watchers_.push({id: this.watch_id_, options: options}); |
| 319 return Promise.resolve(retVal); |
| 320 } |
| 321 |
| 322 cancelWatch(id) { |
| 323 let index = this.watchers_.findIndex(value => value.id === id); |
| 324 if (index === -1) { |
| 325 return Promise.resolve(createNFCError(nfc.NFCErrorType.NOT_FOUND)); |
| 326 } |
| 327 |
| 328 this.watchers_.splice(index, 1); |
| 329 return Promise.resolve(createNFCError(null)); |
| 330 } |
| 331 |
| 332 cancelAllWatches() { |
| 333 if (this.watchers_.length === 0) { |
| 334 return Promise.resolve(createNFCError(nfc.NFCErrorType.NOT_FOUND)); |
| 335 } |
| 336 |
| 337 this.watchers_.splice(0, this.watchers_.length); |
| 338 return Promise.resolve(createNFCError(null)); |
| 339 } |
| 340 |
| 341 |
220 // Mock utility functions | 342 // Mock utility functions |
221 bindToPipe(pipe) { | 343 bindToPipe(pipe) { |
222 this.stub_ = connection.bindHandleToStub( | 344 this.stub_ = connection.bindHandleToStub( |
223 pipe, nfc.NFC); | 345 pipe, nfc.NFC); |
224 bindings.StubBindings(this.stub_).delegate = this; | 346 bindings.StubBindings(this.stub_).delegate = this; |
225 } | 347 } |
226 | 348 |
227 isReady() { | 349 isReady() { |
228 if (this.hw_status_ === NFCHWStatus.DISABLED) | 350 if (this.hw_status_ === NFCHWStatus.DISABLED) |
229 return createNFCError(nfc.NFCErrorType.DEVICE_DISABLED); | 351 return createNFCError(nfc.NFCErrorType.DEVICE_DISABLED); |
230 if (this.hw_status_ === NFCHWStatus.NOT_SUPPORTED) | 352 if (this.hw_status_ === NFCHWStatus.NOT_SUPPORTED) |
231 return createNFCError(nfc.NFCErrorType.NOT_SUPPORTED); | 353 return createNFCError(nfc.NFCErrorType.NOT_SUPPORTED); |
232 return null; | 354 return null; |
233 } | 355 } |
234 | 356 |
235 setHWStatus(status) { | 357 setHWStatus(status) { |
236 this.hw_status_ = status; | 358 this.hw_status_ = status; |
237 } | 359 } |
238 | 360 |
239 pushedMessage() { | 361 pushedMessage() { |
240 return this.pushed_message_; | 362 return this.pushed_message_; |
241 } | 363 } |
242 | 364 |
243 pushOptions() { | 365 pushOptions() { |
244 return this.push_options_; | 366 return this.push_options_; |
245 } | 367 } |
246 | 368 |
| 369 watchOptions() { |
| 370 assert_not_equals(this.watchers_.length, 0); |
| 371 return this.watchers_[this.watchers_.length - 1].options; |
| 372 } |
| 373 |
247 setPendingPushCompleted(result) { | 374 setPendingPushCompleted(result) { |
248 this.push_completed_ = result; | 375 this.push_completed_ = result; |
249 } | 376 } |
250 | 377 |
251 reset() { | 378 reset() { |
252 this.hw_status_ = NFCHWStatus.ENABLED; | 379 this.hw_status_ = NFCHWStatus.ENABLED; |
253 this.push_completed_ = true; | 380 this.push_completed_ = true; |
| 381 this.watch_id_ = 0; |
| 382 this.watchers_ = []; |
254 this.cancelPendingPushOperation(); | 383 this.cancelPendingPushOperation(); |
255 } | 384 } |
256 | 385 |
257 cancelPendingPushOperation() { | 386 cancelPendingPushOperation() { |
258 if (this.push_timeout_id_) { | 387 if (this.push_timeout_id_) { |
259 window.clearTimeout(this.push_timeout_id_); | 388 window.clearTimeout(this.push_timeout_id_); |
260 } | 389 } |
261 | 390 |
262 if (this.pending_promise_func_) { | 391 if (this.pending_promise_func_) { |
263 this.pending_promise_func_(createNFCError(nfc.NFCErrorType.OPERATION_C
ANCELLED)); | 392 this.pending_promise_func_(createNFCError(nfc.NFCErrorType.OPERATION_C
ANCELLED)); |
264 } | 393 } |
265 | 394 |
266 this.pushed_message_ = null; | 395 this.pushed_message_ = null; |
267 this.push_options_ = null; | 396 this.push_options_ = null; |
268 this.pending_promise_func_ = null; | 397 this.pending_promise_func_ = null; |
269 } | 398 } |
| 399 |
| 400 triggerWatchCallback(id, message) { |
| 401 assert_true(this.client_ !== null); |
| 402 if (this.watchers_.length > 0) { |
| 403 this.client_.onWatch([id], toMojoNFCMessage(message)); |
| 404 } |
| 405 } |
270 } | 406 } |
271 | 407 |
272 let mockNFC = new MockNFC; | 408 let mockNFC = new MockNFC; |
273 mojo.frameInterfaces.addInterfaceOverrideForTesting( | 409 mojo.frameInterfaces.addInterfaceOverrideForTesting( |
274 nfc.NFC.name, | 410 nfc.NFC.name, |
275 pipe => { | 411 pipe => { |
276 mockNFC.bindToPipe(pipe); | 412 mockNFC.bindToPipe(pipe); |
277 }); | 413 }); |
278 | 414 |
279 return Promise.resolve({ | 415 return Promise.resolve({ |
280 mockNFC: mockNFC, | 416 mockNFC: mockNFC, |
281 assertNFCMessagesEqual: assertNFCMessagesEqual, | 417 assertNFCMessagesEqual: assertNFCMessagesEqual, |
282 assertNFCPushOptionsEqual: assertNFCPushOptionsEqual, | 418 assertNFCPushOptionsEqual: assertNFCPushOptionsEqual, |
| 419 assertWebNFCMessagesEqual: assertWebNFCMessagesEqual, |
| 420 assertNFCWatchOptionsEqual: assertNFCWatchOptionsEqual, |
283 }); | 421 }); |
284 }); | 422 }); |
285 } | 423 } |
286 | 424 |
287 function nfc_test(func, name, properties) { | 425 function nfc_test(func, name, properties) { |
288 mojo_test(mojo => nfc_mocks(mojo).then(nfc => { | 426 mojo_test(mojo => nfc_mocks(mojo).then(nfc => { |
289 let result = Promise.resolve(func(nfc)); | 427 let result = Promise.resolve(func(nfc)); |
290 let cleanUp = () => nfc.mockNFC.reset(); | 428 let cleanUp = () => nfc.mockNFC.reset(); |
291 result.then(cleanUp, cleanUp); | 429 result.then(cleanUp, cleanUp); |
292 return result; | 430 return result; |
293 }), name, properties); | 431 }), name, properties); |
294 } | 432 } |
OLD | NEW |