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
|
// META: script=resources/test-helpers.js
promise_test(async t => {
await promise_rejects_dom(t, 'SecurityError', self.showOpenFilePicker());
}, 'showOpenFilePicker: Showing a picker requires user activation.');
promise_test(async t => {
await promise_rejects_dom(t, 'SecurityError', self.showSaveFilePicker());
}, 'showSaveFilePicker: Showing a picker requires user activation.');
promise_test(async t => {
await promise_rejects_dom(t, 'SecurityError', self.showDirectoryPicker());
}, 'showDirectoryPicker: Showing a picker requires user activation.');
// TODO(mek): Add tests for cross-origin iframes, opaque origins, etc.
define_file_picker_error_tests('showOpenFilePicker');
define_file_picker_error_tests('showSaveFilePicker');
function define_file_picker_error_tests(showPickerMethod) {
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({excludeAcceptAllOption: true, types: []}));
}, showPickerMethod + ': File picker requires at least one accepted type.');
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({types: [{accept: {'': ['.foo']}}]}));
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({types: [{accept: {' ': ['.foo']}}]}));
}, showPickerMethod + ': MIME type can\'t be an empty string.');
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({types: [{accept: {'image': ['.foo']}}]}));
}, showPickerMethod + ': MIME type must have subtype.');
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({types: [{accept: {' /plain': ['.foo']}}]}));
}, showPickerMethod + ': MIME type can\'t have empty type.');
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({types: [{accept: {'image/ ': ['.foo']}}]}));
}, showPickerMethod + ': MIME type can\'t have empty subtype.');
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod](
{types: [{accept: {'text/plain;charset=utf8': ['.txt']}}]}));
}, showPickerMethod + ': MIME type can\'t have parameters.');
promise_test(async t => {
await promise_rejects_js(t, TypeError, self[showPickerMethod]({
types: [{accept: {'text>foo/plain': ['.txt']}}]
}));
}, showPickerMethod + ': MIME type can\'t have invalid characters in type.');
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod]({types: [{accept: {'text / plain': ['.txt']}}]}));
}, showPickerMethod + ': MIME type can\'t have whitespace in the middle.');
promise_test(
async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod](
{types: [{accept: {'text/plain>foo': ['.txt']}}]}));
},
showPickerMethod +
': MIME type can\'t have invalid characters in subtype.');
promise_test(async t => {
await promise_rejects_js(t, TypeError, self[showPickerMethod]({
startIn: 'secrets',
}));
}, showPickerMethod + ': unknown well-known starting directory.');
promise_test(async t => {
await promise_rejects_js(t, TypeError, self[showPickerMethod]({
startIn: '',
}));
}, showPickerMethod + ': starting directory can\t be empty.');
promise_test(async t => {
await promise_rejects_js(t, TypeError, self[showPickerMethod]({
startIn: null,
}));
}, showPickerMethod + ': starting directory can\t be null.');
promise_test(async t => {
await promise_rejects_js(t, TypeError, self[showPickerMethod]({
id: "inv*l:d\\ chara<ters",
}));
}, showPickerMethod + ': starting directory ID contains invalid characters.');
promise_test(async t => {
await promise_rejects_js(t, TypeError, self[showPickerMethod]({
id: "id-length-cannot-exceed-32-characters",
}));
}, showPickerMethod + ': starting directory ID cannot exceed 32 characters.');
const invalid_extensions = {
'.extensiontoolong': 'extension length more than 16.',
'.txt.': 'extenstion ends with "."',
'txt': 'extenstion does not start with "."',
'.$txt' : 'illegal character "$"',
'.t<xt': 'illegal character "<"',
'.t/xt': 'illegal character "\"',
'.\txt': 'illegal character "/"',
'.txt\\': 'illegal characters "\\"',
'.txt?': 'illegal character "?"',
'.txt*': 'illegal character "*"',
'.{txt': 'illegal character "{"',
'.}txt': 'illegal character "}"',
' .txt': 'illegal whitespace at front of extension',
'. txt': 'illegal whitespace in extension',
'.txt ': 'illegal whitespace at end of extension',
'.\u202etxt\u202e' : 'illegal RTL character',
'.t\u00E6xt': 'non-ASCII character "æ"',
'.קום': 'non-ASCII character "קום"',
'.txt🙂': 'non-ASCII character "🙂"',
'.{txt}': 'illegal characters "{" and "}"',
}
for (const [extension, description] of Object.entries(invalid_extensions)) {
define_file_picker_extension_error_test(showPickerMethod, extension, description)
}
}
function define_file_picker_extension_error_test(showPickerMethod, extension, description) {
promise_test(async t => {
await promise_rejects_js(
t, TypeError,
self[showPickerMethod](
{ types: [{ accept: { 'text/plain': ['.txt', extension] } }] }));
}, showPickerMethod + ': invalid extension "' + extension + '". ' + description + ".");
}
|