Skip to content

Commit d4eb7e4

Browse files
author
Brian Chen
authored
Validate operator enum in Query.where() calls (#1677)
1 parent 96ab56b commit d4eb7e4

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

packages/firestore/src/api/database.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import {
7070
validateOptionalArgType,
7171
validateOptionalArrayElements,
7272
validateOptionNames,
73+
validateStringEnum,
7374
valueDescription
7475
} from '../util/input_validation';
7576
import * as log from '../util/log';
@@ -1352,8 +1353,10 @@ export class Query implements firestore.Query {
13521353
value: unknown
13531354
): firestore.Query {
13541355
validateExactNumberOfArgs('Query.where', arguments, 3);
1355-
validateArgType('Query.where', 'non-empty string', 2, opStr);
13561356
validateDefined('Query.where', 3, value);
1357+
// Enumerated from the WhereFilterOp type in index.d.ts.
1358+
const whereFilterOpEnums = ['<', '<=', '==', '>=', '>', 'array-contains'];
1359+
validateStringEnum('Query.where', whereFilterOpEnums, 2, opStr);
13571360
let fieldValue;
13581361
const fieldPath = fieldPathFromArgument('Query.where', field);
13591362
const relationOp = RelationOp.fromString(opStr);

packages/firestore/src/util/input_validation.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
1817
import { fail } from './assert';
1918
import { Code, FirestoreError } from './error';
2019
import * as obj from './obj';
@@ -292,6 +291,30 @@ export function validateNamedOptionalPropertyEquals<T>(
292291
}
293292
}
294293

294+
/**
295+
* Validates that the provided argument is a valid enum.
296+
*
297+
* @param functionName Function making the validation call.
298+
* @param enums Array containing all possible values for the enum.
299+
* @param position Position of the argument in `functionName`.
300+
* @param argument Arugment to validate.
301+
*/
302+
export function validateStringEnum<T>(
303+
functionName: string,
304+
enums: string[],
305+
position: number,
306+
argument: unknown
307+
): void {
308+
if (!enums.some(element => element === argument)) {
309+
throw new FirestoreError(
310+
Code.INVALID_ARGUMENT,
311+
`Invalid value ${valueDescription(argument)} provided to function ` +
312+
`${functionName}() for its ${ordinal(position)} argument. Acceptable ` +
313+
`values: ${enums.join(', ')}`
314+
);
315+
}
316+
}
317+
295318
/** Helper to validate the type of a provided input. */
296319
function validateType(
297320
functionName: string,

packages/firestore/test/integration/api/validation.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,14 @@ apiDescribe('Validation:', persistence => {
800800
);
801801
});
802802

803+
validationIt(persistence, 'enum', db => {
804+
const collection = db.collection('test') as any;
805+
expect(() => collection.where('a', 'foo' as any, 'b')).to.throw(
806+
'Invalid value "foo" provided to function Query.where() for its second argument. ' +
807+
'Acceptable values: <, <=, ==, >=, >, array-contains'
808+
);
809+
});
810+
803811
validationIt(
804812
persistence,
805813
'with null or NaN non-equality filters fail',

0 commit comments

Comments
 (0)