1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
// META: script=resources/nfc-helpers.js
// NDEFReader.makeReadOnly method
// https://w3c.github.io/web-nfc/#dom-ndefreader-makereadonly
'use strict';
const invalid_signals = ['string', 123, {}, true, Symbol(), () => {}, self];
nfc_test(async t => {
await test_driver.set_permission({name: 'nfc'}, 'denied');
const ndef = new NDEFReader();
await promise_rejects_dom(t, 'NotAllowedError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail if user permission is not granted.');
// We do not provide NFC mock here to simulate that there has no available
// implementation for NFC Mojo interface.
nfc_test(async (t, mockNFC) => {
mockNFC.simulateClosedPipe();
const ndef = new NDEFReader();
await promise_rejects_dom(t, 'NotSupportedError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail if no implementation for NFC Mojo interface is available.');
nfc_test(async (t, mockNFC) => {
const ndef = new NDEFReader();
const controller = new AbortController();
// Make sure makeReadOnly is pending
mockNFC.setPendingMakeReadOnlyCompleted(false);
const p = ndef.makeReadOnly({signal: controller.signal});
const rejected = promise_rejects_dom(t, 'AbortError', p);
let callback_called = false;
await new Promise(resolve => {
t.step_timeout(() => {
callback_called = true;
controller.abort();
resolve();
}, 10);
});
await rejected;
assert_true(callback_called, 'timeout should have caused the abort');
}, 'NDEFReader.makeReadOnly should fail if request is aborted before makeReadOnly happends.');
nfc_test(async t => {
const ndef = new NDEFReader();
const controller = new AbortController();
assert_false(controller.signal.aborted);
controller.abort();
assert_true(controller.signal.aborted);
await promise_rejects_dom(
t, 'AbortError', ndef.makeReadOnly({signal: controller.signal}));
}, 'NDEFReader.makeReadOnly should fail if signal is already aborted.');
nfc_test(async t => {
const ndef = new NDEFReader();
const promises = [];
invalid_signals.forEach(invalid_signal => {
promises.push(promise_rejects_js(
t, TypeError, ndef.makeReadOnly({signal: invalid_signal})));
});
await Promise.all(promises);
}, 'NDEFReader.write should fail if signal is not an AbortSignal.');
nfc_test(async (t, mockNFC) => {
const ndef1 = new NDEFReader();
const ndef2 = new NDEFReader();
const controller = new AbortController();
const p1 = ndef1.makeReadOnly({signal: controller.signal});
// Even though makeReadOnly request is grantable,
// this abort should be processed synchronously.
controller.abort();
await promise_rejects_dom(t, 'AbortError', p1);
await ndef2.makeReadOnly();
}, 'Synchronously signaled abort.');
nfc_test(async (t, mockNFC) => {
const ndef = new NDEFReader();
mockNFC.setHWStatus(NFCHWStatus.DISABLED);
await promise_rejects_dom(t, 'NotReadableError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail when NFC HW is disabled.');
nfc_test(async (t, mockNFC) => {
const ndef = new NDEFReader();
mockNFC.setHWStatus(NFCHWStatus.NOT_SUPPORTED);
await promise_rejects_dom(t, 'NotSupportedError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail when NFC HW is not supported.');
nfc_test(async () => {
await new Promise((resolve, reject) => {
const iframe = document.createElement('iframe');
iframe.srcdoc = `<script>
window.onmessage = async (message) => {
if (message.data === "Ready") {
try {
const ndef = new NDEFReader();
await ndef.makeReadOnly();
parent.postMessage("Failure", "*");
} catch (error) {
if (error.name == "InvalidStateError") {
parent.postMessage("Success", "*");
} else {
parent.postMessage("Failure", "*");
}
}
}
};
</script>`;
iframe.onload = () => iframe.contentWindow.postMessage('Ready', '*');
document.body.appendChild(iframe);
window.onmessage = message => {
if (message.data == 'Success') {
resolve();
} else if (message.data == 'Failure') {
reject();
}
}
});
}, 'Test that WebNFC API is not accessible from iframe context.');
nfc_test(async () => {
const ndef = new NDEFReader();
await ndef.makeReadOnly();
}, 'NDEFReader.makeReadOnly should succeed when NFC HW is enabled');
nfc_test(async (t, mockNFC) => {
const ndef1 = new NDEFReader();
const ndef2 = new NDEFReader();
// Make sure the first makeReadOnly will be pending.
mockNFC.setPendingMakeReadOnlyCompleted(false);
const p1 = ndef1.makeReadOnly();
const p2 = ndef2.makeReadOnly();
await promise_rejects_dom(t, 'AbortError', p1);
await p2;
}, 'NDEFReader.makeReadOnly should replace all previously configured makeReadOnly operations.');
nfc_test(async () => {
const ndef = new NDEFReader();
const controller1 = new AbortController();
await ndef.makeReadOnly({signal: controller1.signal});
const controller2 = new AbortController();
const promise = ndef.makeReadOnly({signal: controller2.signal});
controller1.abort();
await promise;
}, 'NDEFReader.makeReadOnly signals are independent.');
nfc_test(async (t, mockNFC) => {
// Make sure the makeReadOnly will be pending in the mock.
mockNFC.setPendingMakeReadOnlyCompleted(false);
const ndef1 = new NDEFReader();
const promise = ndef1.makeReadOnly();
// Just to make sure the makeReadOnly() request has already reached to the
// mock.
const ndef2 = new NDEFReader();
await ndef2.scan();
mockNFC.simulateNonNDEFTagDiscovered();
await promise_rejects_dom(t, 'NotSupportedError', promise);
}, 'NDEFReader.makeReadOnly should fail when the NFC device coming up does not expose \
NDEF technology.');
nfc_test(async (t, mockNFC) => {
const ndef = new NDEFReader();
mockNFC.simulateDataTransferFails();
await promise_rejects_dom(t, 'NetworkError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail with NetworkError when NFC data transfer fails.');
|