WebCryptoAPI: use all public usages combinations for import tests (#41771)

diff --git a/WebCryptoAPI/import_export/ec_importKey.https.any.js b/WebCryptoAPI/import_export/ec_importKey.https.any.js
index 25defa3..31f062e 100644
--- a/WebCryptoAPI/import_export/ec_importKey.https.any.js
+++ b/WebCryptoAPI/import_export/ec_importKey.https.any.js
@@ -71,7 +71,7 @@
             [true, false].forEach(function(extractable) {
 
                 // Test public keys first
-                [[]].forEach(function(usages) { // Only valid usages argument is empty array
+                allValidUsages(vector.publicUsages, true).forEach(function(usages) {
                     ['spki', 'spki_compressed', 'jwk', 'raw', 'raw_compressed'].forEach(function(format) {
                         var algorithm = {name: vector.name, namedCurve: curve};
                         var data = keyData[curve];
@@ -88,7 +88,7 @@
                 ['pkcs8', 'jwk'].forEach(function(format) {
                     var algorithm = {name: vector.name, namedCurve: curve};
                     var data = keyData[curve];
-                    allValidUsages(vector.privateUsages, []).forEach(function(usages) {
+                    allValidUsages(vector.privateUsages).forEach(function(usages) {
                         testFormat(format, algorithm, data, curve, usages, extractable);
                     });
                     testEmptyUsages(format, algorithm, data, curve, extractable);
@@ -219,46 +219,6 @@
         return base64String.replace(/=/g, "");
     }
 
-    // Want to test every valid combination of usages. Start by creating a list
-    // of all non-empty subsets to possible usages.
-    function allNonemptySubsetsOf(arr) {
-        var results = [];
-        var firstElement;
-        var remainingElements;
-
-        for(var i=0; i<arr.length; i++) {
-            firstElement = arr[i];
-            remainingElements = arr.slice(i+1);
-            results.push([firstElement]);
-
-            if (remainingElements.length > 0) {
-                allNonemptySubsetsOf(remainingElements).forEach(function(combination) {
-                    combination.push(firstElement);
-                    results.push(combination);
-                });
-            }
-        }
-
-        return results;
-    }
-
-    // Return a list of all valid usage combinations, given the possible ones
-    // and the ones that are required for a particular operation.
-    function allValidUsages(possibleUsages, requiredUsages) {
-        var allUsages = [];
-
-        allNonemptySubsetsOf(possibleUsages).forEach(function(usage) {
-            for (var i=0; i<requiredUsages.length; i++) {
-                if (!usage.includes(requiredUsages[i])) {
-                    return;
-                }
-            }
-            allUsages.push(usage);
-        });
-
-        return allUsages;
-    }
-
     // Convert method parameters to a string to uniquely name each test
     function parameterString(format, compressed, data, algorithm, extractable, usages) {
         if ("byteLength" in data) {
@@ -311,4 +271,3 @@
 
         return "{" + keyValuePairs.join(", ") + "}";
     }
-
diff --git a/WebCryptoAPI/import_export/okp_importKey.https.any.js b/WebCryptoAPI/import_export/okp_importKey.https.any.js
index 2257a5f..a0ec3e8 100644
--- a/WebCryptoAPI/import_export/okp_importKey.https.any.js
+++ b/WebCryptoAPI/import_export/okp_importKey.https.any.js
@@ -72,7 +72,7 @@
         [true, false].forEach(function(extractable) {
 
             // Test public keys first
-            [[]].forEach(function(usages) { // Only valid usages argument is empty array
+            allValidUsages(vector.publicUsages, true).forEach(function(usages) {
                 ['spki', 'jwk', 'raw'].forEach(function(format) {
                     var algorithm = {name: vector.name};
                     var data = keyData[vector.name];
@@ -86,7 +86,7 @@
             });
 
             // Next, test private keys
-            allValidUsages(vector.privateUsages, []).forEach(function(usages) {
+            allValidUsages(vector.privateUsages).forEach(function(usages) {
                 ['pkcs8', 'jwk'].forEach(function(format) {
                     var algorithm = {name: vector.name};
                     var data = keyData[vector.name];
@@ -194,46 +194,6 @@
         return base64String.replace(/=/g, "");
     }
 
-    // Want to test every valid combination of usages. Start by creating a list
-    // of all non-empty subsets to possible usages.
-    function allNonemptySubsetsOf(arr) {
-        var results = [];
-        var firstElement;
-        var remainingElements;
-
-        for(var i=0; i<arr.length; i++) {
-            firstElement = arr[i];
-            remainingElements = arr.slice(i+1);
-            results.push([firstElement]);
-
-            if (remainingElements.length > 0) {
-                allNonemptySubsetsOf(remainingElements).forEach(function(combination) {
-                    combination.push(firstElement);
-                    results.push(combination);
-                });
-            }
-        }
-
-        return results;
-    }
-
-    // Return a list of all valid usage combinations, given the possible ones
-    // and the ones that are required for a particular operation.
-    function allValidUsages(possibleUsages, requiredUsages) {
-        var allUsages = [];
-
-        allNonemptySubsetsOf(possibleUsages).forEach(function(usage) {
-            for (var i=0; i<requiredUsages.length; i++) {
-                if (!usage.includes(requiredUsages[i])) {
-                    return;
-                }
-            }
-            allUsages.push(usage);
-        });
-
-        return allUsages;
-    }
-
     // Convert method parameters to a string to uniquely name each test
     function parameterString(format, data, algorithm, extractable, usages) {
         if ("byteLength" in data) {
diff --git a/WebCryptoAPI/import_export/rsa_importKey.https.any.js b/WebCryptoAPI/import_export/rsa_importKey.https.any.js
index 5582b2f..c0917ca 100644
--- a/WebCryptoAPI/import_export/rsa_importKey.https.any.js
+++ b/WebCryptoAPI/import_export/rsa_importKey.https.any.js
@@ -78,7 +78,7 @@
                 [true, false].forEach(function(extractable) {
 
                     // Test public keys first
-                    allValidUsages(vector.publicUsages, []).forEach(function(usages) {
+                    allValidUsages(vector.publicUsages, true).forEach(function(usages) {
                         ['spki', 'jwk'].forEach(function(format) {
                             var algorithm = {name: vector.name, hash: hash};
                             var data = keyData[size];
@@ -95,7 +95,7 @@
                     ['pkcs8', 'jwk'].forEach(function(format) {
                         var algorithm = {name: vector.name, hash: hash};
                         var data = keyData[size];
-                        allValidUsages(vector.privateUsages, []).forEach(function(usages) {
+                        allValidUsages(vector.privateUsages).forEach(function(usages) {
                             testFormat(format, algorithm, data, size, usages, extractable);
                         });
                         testEmptyUsages(format, algorithm, data, size, extractable);
@@ -217,46 +217,6 @@
         return base64String.replace(/=/g, "");
     }
 
-    // Want to test every valid combination of usages. Start by creating a list
-    // of all non-empty subsets to possible usages.
-    function allNonemptySubsetsOf(arr) {
-        var results = [];
-        var firstElement;
-        var remainingElements;
-
-        for(var i=0; i<arr.length; i++) {
-            firstElement = arr[i];
-            remainingElements = arr.slice(i+1);
-            results.push([firstElement]);
-
-            if (remainingElements.length > 0) {
-                allNonemptySubsetsOf(remainingElements).forEach(function(combination) {
-                    combination.push(firstElement);
-                    results.push(combination);
-                });
-            }
-        }
-
-        return results;
-    }
-
-    // Return a list of all valid usage combinations, given the possible ones
-    // and the ones that are required for a particular operation.
-    function allValidUsages(possibleUsages, requiredUsages) {
-        var allUsages = [];
-
-        allNonemptySubsetsOf(possibleUsages).forEach(function(usage) {
-            for (var i=0; i<requiredUsages.length; i++) {
-                if (!usage.includes(requiredUsages[i])) {
-                    return;
-                }
-            }
-            allUsages.push(usage);
-        });
-
-        return allUsages;
-    }
-
     // Convert method parameters to a string to uniquely name each test
     function parameterString(format, data, algorithm, extractable, usages) {
         if ("byteLength" in data) {
diff --git a/WebCryptoAPI/import_export/symmetric_importKey.https.any.js b/WebCryptoAPI/import_export/symmetric_importKey.https.any.js
index a9ce9be..01b3180 100644
--- a/WebCryptoAPI/import_export/symmetric_importKey.https.any.js
+++ b/WebCryptoAPI/import_export/symmetric_importKey.https.any.js
@@ -49,7 +49,7 @@
                         data = jwkData(keyData, algorithm);
                     }
                     // Generate all combinations of valid usages for testing
-                    allValidUsages(vector.legalUsages, []).forEach(function(usages) {
+                    allValidUsages(vector.legalUsages).forEach(function(usages) {
                         testFormat(format, algorithm, data, keyData.length * 8, usages, extractable);
                     });
                     testEmptyUsages(format, algorithm, data, keyData.length * 8, extractable);
@@ -173,46 +173,6 @@
         return base64String.replace(/=/g, "");
     }
 
-    // Want to test every valid combination of usages. Start by creating a list
-    // of all non-empty subsets to possible usages.
-    function allNonemptySubsetsOf(arr) {
-        var results = [];
-        var firstElement;
-        var remainingElements;
-
-        for(var i=0; i<arr.length; i++) {
-            firstElement = arr[i];
-            remainingElements = arr.slice(i+1);
-            results.push([firstElement]);
-
-            if (remainingElements.length > 0) {
-                allNonemptySubsetsOf(remainingElements).forEach(function(combination) {
-                    combination.push(firstElement);
-                    results.push(combination);
-                });
-            }
-        }
-
-        return results;
-    }
-
-    // Return a list of all valid usage combinations, given the possible ones
-    // and the ones that are required for a particular operation.
-    function allValidUsages(possibleUsages, requiredUsages) {
-        var allUsages = [];
-
-        allNonemptySubsetsOf(possibleUsages).forEach(function(usage) {
-            for (var i=0; i<requiredUsages.length; i++) {
-                if (!usage.includes(requiredUsages[i])) {
-                    return;
-                }
-            }
-            allUsages.push(usage);
-        });
-
-        return allUsages;
-    }
-
     // Convert method parameters to a string to uniquely name each test
     function parameterString(format, data, algorithm, extractable, usages) {
         var result = "(" +
diff --git a/WebCryptoAPI/util/helpers.js b/WebCryptoAPI/util/helpers.js
index ce240a1..bda9700 100644
--- a/WebCryptoAPI/util/helpers.js
+++ b/WebCryptoAPI/util/helpers.js
@@ -235,7 +235,7 @@
         }
     });
 
-    if (emptyIsValid) {
+    if (emptyIsValid && validUsages.length !== 0) {
         okaySubsets.push([]);
     }