| <!doctype html> |
| <meta charset="utf-8"> |
| <title>Tests for PaymentInstruments interface</title> |
| <link rel="help" href="https://w3c.github.io/payment-handler/#paymentinstruments-interface"> |
| <link rel="manifest" href="basic-card.json"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="register-and-activate-service-worker.js"></script> |
| <script> |
| function runTests(registration) { |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set('instrument-key-1', { |
| name: 'Instrument Name 1', |
| }); |
| await registration.paymentManager.instruments.set('instrument-key-2', { |
| name: 'Instrument Name 2', |
| }); |
| await registration.paymentManager.instruments.delete('instrument-key-1'); |
| await registration.paymentManager.instruments.set('instrument-key-1', { |
| name: 'Instrument Name 1', |
| }); |
| const keys = await registration.paymentManager.instruments.keys(); |
| assert_array_equals(keys, ['instrument-key-2', 'instrument-key-1']); |
| }, 'Instrument keys are returned in the original insertion order'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set( |
| 'existing-instrument-key', |
| { |
| name: 'Instrument Name', |
| }, |
| ); |
| const result = await registration.paymentManager.instruments.delete( |
| 'existing-instrument-key', |
| ); |
| assert_true(result); |
| }, 'Deleting an existing instrument returns true'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set( |
| 'existing-instrument-key', |
| { |
| name: 'Instrument Name', |
| }, |
| ); |
| await registration.paymentManager.instruments.delete( |
| 'existing-instrument-key', |
| ); |
| const result = await registration.paymentManager.instruments.delete( |
| 'existing-instrument-key', |
| ); |
| assert_false(result); |
| }, 'Deleting an existing instrument the second time returns false'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const result = await registration.paymentManager.instruments.delete( |
| 'non-existing-instrument-key', |
| ); |
| assert_false(result); |
| }, 'Deleting a non-existing instrument returns false'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set( |
| 'existing-instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '256x256', |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| capabilities: {supportedNetworks: ['mir']}, |
| }, |
| ); |
| const result = await registration.paymentManager.instruments.get( |
| 'existing-instrument-key', |
| ); |
| assert_equals(result.name, 'Instrument Name'); |
| }, 'Getting an existing instrument returns the instrument'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const result = await registration.paymentManager.instruments.get( |
| 'non-existing-instrument-key', |
| ); |
| assert_equals(result, undefined); |
| }, 'Getting a non-existing instrument returns undefined'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set( |
| 'existing-instrument-key', |
| { |
| name: 'Instrument Name v1', |
| icons: [ |
| {src: '/images/green-16x16.png', sizes: '16x16', type: 'image/png'}, |
| ], |
| method: 'basic-card', |
| capabilities: {supportedNetworks: ['mir']}, |
| }, |
| ); |
| let result = await registration.paymentManager.instruments.get( |
| 'existing-instrument-key', |
| ); |
| assert_equals(result.name, 'Instrument Name v1'); |
| assert_equals(result.icons.length, 1); |
| assert_equals( |
| result.icons[0].src, |
| new URL('/images/green-16x16.png', window.location.href).href, |
| ); |
| assert_equals(result.icons[0].sizes, '16x16'); |
| assert_equals(result.icons[0].type, 'image/png'); |
| assert_equals(result.method, 'basic-card'); |
| assert_array_equals(result.capabilities.supportedNetworks, ['mir']); |
| await registration.paymentManager.instruments.set( |
| 'existing-instrument-key', |
| { |
| name: 'Instrument Name v2', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '256x256', |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| capabilities: {supportedNetworks: ['visa']}, |
| }, |
| ); |
| result = await registration.paymentManager.instruments.get( |
| 'existing-instrument-key', |
| ); |
| assert_equals(result.name, 'Instrument Name v2'); |
| assert_equals(result.icons.length, 1); |
| assert_equals( |
| result.icons[0].src, |
| new URL('/images/rgrg-256x256.png', window.location.href).href, |
| ); |
| assert_equals(result.icons[0].sizes, '256x256'); |
| assert_equals(result.icons[0].type, 'image/png'); |
| assert_equals(result.method, 'basic-card'); |
| assert_array_equals(result.capabilities.supportedNetworks, ['visa']); |
| }, 'Resetting an existing instrument updates the instrument'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set( |
| 'existing-instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '256x256', |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| capabilities: {supportedNetworks: ['mir']}, |
| }, |
| ); |
| await registration.paymentManager.instruments.clear(); |
| const result = await registration.paymentManager.instruments.get( |
| 'existing-instrument-key', |
| ); |
| assert_equals(result, undefined); |
| }, 'Clearing the instruments'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const setPromise = registration.paymentManager.instruments.set( |
| 'instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '256x256', |
| type: 'image/jif', |
| }, |
| ], |
| method: 'basic-card', |
| }, |
| ); |
| return promise_rejects(t, new TypeError(), setPromise); |
| }, 'Cannot register instruments with invalid icon media type image/jif'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const setPromise = registration.paymentManager.instruments.set( |
| 'instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '256x256', |
| type: 'image/pn' + 'g'.repeat(1000), |
| }, |
| ], |
| method: 'basic-card', |
| }, |
| ); |
| return promise_rejects(t, new TypeError(), setPromise); |
| }, "Don't crash when registering instruments with very long icon media type image/pngggggg..."); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| return registration.paymentManager.instruments.set('instrument-key', { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '8'.repeat(100000) + 'x' + '8'.repeat(100000), |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| }); |
| }, "Don't crash when registering an instrument with a very long icon size 888...x888..."); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const setPromise = registration.paymentManager.instruments.set( |
| 'instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rgrg-256x256.png', |
| sizes: '256 256', |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| }, |
| ); |
| return promise_rejects(t, new TypeError(), setPromise); |
| }, 'Cannot register instruments with invalid icon size "256 256" (missing "x")'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const setPromise = registration.paymentManager.instruments.set( |
| 'instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: '/images/rg\0rg-256x256.png', |
| sizes: '256x256', |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| }, |
| ); |
| return promise_rejects(t, new TypeError(), setPromise); |
| }, 'Cannot register instruments with invalid icon URL (has a null character)'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const setPromise = registration.paymentManager.instruments.set( |
| 'instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: 'http://test.example/images/rgrg-256x256.png', |
| sizes: '256x256', |
| type: 'image/png', |
| }, |
| ], |
| method: 'basic-card', |
| }, |
| ); |
| return promise_rejects(t, new TypeError(), setPromise); |
| }, 'Cannot register instruments with non-existing non-https icon URL'); |
| |
| promise_test(async t => { |
| await registration.paymentManager.instruments.clear(); |
| const setPromise = registration.paymentManager.instruments.set( |
| 'instrument-key', |
| { |
| name: 'Instrument Name', |
| icons: [ |
| { |
| src: |
| 'http://www.chromium.org/_/rsrc/1438879449147/config/customLogo.gif', |
| sizes: '48x48', |
| type: 'image/gif', |
| }, |
| ], |
| method: 'basic-card', |
| }, |
| ); |
| return promise_rejects(t, new TypeError(), setPromise); |
| }, 'Cannot register instruments with an existing non-https icon URL'); |
| |
| async function testUnusualStrings(existingKey, nonExistingKey) { |
| await registration.paymentManager.instruments.clear(); |
| await registration.paymentManager.instruments.set(existingKey, { |
| name: existingKey, |
| icons: [ |
| {src: '/images/rgrg-256x256.png', sizes: '256x256', type: 'image/png'}, |
| ], |
| method: existingKey, |
| capabilities: {aCapabilityName: existingKey}, |
| }); |
| const hasExistingInstrument = await registration.paymentManager.instruments.has( |
| existingKey, |
| ); |
| assert_true(hasExistingInstrument); |
| const hasNonExistingInstrument = await registration.paymentManager.instruments.has( |
| nonExistingKey, |
| ); |
| assert_false(hasNonExistingInstrument); |
| const existingInstrument = await registration.paymentManager.instruments.get( |
| existingKey, |
| ); |
| assert_equals(existingInstrument.name, existingKey); |
| const nonExistingInstrument = await registration.paymentManager.instruments.get( |
| nonExistingKey, |
| ); |
| assert_equals(nonExistingInstrument, undefined); |
| const deletedExistingInstrument = await registration.paymentManager.instruments.delete( |
| existingKey, |
| ); |
| assert_true(deletedExistingInstrument); |
| const deletedNonExistingInstrument = await registration.paymentManager.instruments.delete( |
| nonExistingKey, |
| ); |
| assert_false(deletedNonExistingInstrument); |
| } |
| |
| promise_test(async t => { |
| const length = 100000; |
| await testUnusualStrings('0'.repeat(length), '1'.repeat(length)); |
| }, "Don't crash on very long key, name, method, and capability strings."); |
| |
| promise_test(async t => { |
| await testUnusualStrings('foo\0bar', 'foo\0baz'); |
| }, "Don't crash on null characters in key, name, method, and capability strings."); |
| } |
| |
| registerAndActiveServiceWorker('basic-card.js', 'payment-app/', runTests); |
| </script> |