mongo/jstests/aggregation/expressions/convert_bindata.js

285 lines
8.4 KiB
JavaScript

/**
* Tests behavior of BinData $convert.
* @tags: [
* # BinData $convert was added in v8.0.
* requires_fcv_81,
* ]
*/
import {runConvertTests} from "jstests/libs/query/convert_shared.js";
const kUUIDSubtype = 4;
const kNonUUIDSubtype = 0;
const coll = db.expression_convert_bindata;
coll.drop();
const requiresFCV80 = true;
//
// One test document for each possible conversion. Edge cases for these conversions are tested
// in expression_convert_test.cpp.
//
const conversionTestDocs = [
// 'to' can also be a sub-document describing the type.
{_id: 1, input: 1.9, target: {type: "double"}, expected: 1.9},
{_id: 2, input: 1.9, target: {type: "string"}, expected: "1.9"},
{_id: 3, input: 1.9, target: {type: "bool"}, expected: true},
{_id: 4, input: 1.9, target: {type: "date"}, expected: ISODate("1970-01-01T00:00:00.001Z")},
{_id: 5, input: 1.9, target: {type: "int"}, expected: NumberInt(1)},
{_id: 6, input: 1.9, target: {type: "long"}, expected: NumberLong(1)},
{_id: 7, input: 1.9, target: {type: "decimal"}, expected: NumberDecimal(1.9)},
// Test conversions from string to BinData.
{
_id: 8,
input: "867dee52-c331-484e-92d1-c56479b8e67e",
target: {type: "binData", subtype: kUUIDSubtype},
format: "uuid",
expected: BinData(kUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 9,
input: "hn3uUsMxSE6S0cVkebjmfg==",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "base64",
expected: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 10,
input: "hn3uUsMxSE6S0cVkebjmfg",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "base64url",
expected: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 11,
input: "867DEE52C331484E92D1C56479B8E67E",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "hex",
expected: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 12,
input: "🙂😎",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "utf8",
expected: BinData(kNonUUIDSubtype, "8J+ZgvCfmI4="),
},
// Test conversions from BinData to string.
{
_id: 13,
input: UUID("867dee52-c331-484e-92d1-c56479b8e67e"),
target: "string",
format: "uuid",
expected: "867dee52-c331-484e-92d1-c56479b8e67e",
},
{
_id: 14,
input: BinData(kUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: "string",
format: "auto",
expected: "867dee52-c331-484e-92d1-c56479b8e67e",
},
{
_id: 15,
input: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: "string",
format: "auto",
expected: "hn3uUsMxSE6S0cVkebjmfg==",
},
{
_id: 16,
input: BinData(kUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: "string",
format: "base64",
expected: "hn3uUsMxSE6S0cVkebjmfg==",
},
{
_id: 17,
input: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: "string",
format: "base64url",
expected: "hn3uUsMxSE6S0cVkebjmfg",
},
{
_id: 18,
input: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: "string",
format: "hex",
expected: "867DEE52C331484E92D1C56479B8E67E",
},
{
_id: 19,
input: BinData(kNonUUIDSubtype, "8J+ZgvCfmI4="),
target: "string",
format: "utf8",
expected: "🙂😎",
},
// Test BinData identity conversions.
{
_id: 20,
input: UUID("867dee52-c331-484e-92d1-c56479b8e67e"),
target: {type: "binData", subtype: kUUIDSubtype},
expected: BinData(kUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 21,
input: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: {type: "binData", subtype: kNonUUIDSubtype},
expected: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 22,
input: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
// 'subtype' defaults to 0 (generic BinData).
target: "binData",
expected: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
];
//
// Unsupported conversions.
//
const illegalConversionTestDocs = [
// Can only convert string (or BinData) to BinData.
{
_id: 3,
input: ObjectId("0123456789abcdef01234567"),
target: {type: "binData", subtype: kUUIDSubtype},
},
{
_id: 4,
input: ObjectId("0123456789abcdef01234567"),
target: {type: "binData", subtype: kNonUUIDSubtype},
},
// Can't convert UUID string to non-UUID BinData.
{
_id: 5,
input: "867dee52-c331-484e-92d1-c56479b8e67e",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "uuid",
},
// Input is not a valid UUID, base64, hex or utf8 string.
{
_id: 6,
input: "867dee--52-c331-484e-",
target: {type: "binData", subtype: kUUIDSubtype},
format: "uuid",
},
{
_id: 7,
input: "867dee--52-c331-484e-",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "base64",
},
{
_id: 8,
input: "867dee--52-c331-484e-",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "base64url",
},
{
_id: 9,
input: "867dee--52-c331-484e-zx",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "hex",
},
// When converting from string to BinData, the "auto" format is not allowed, and the "uuid"
// format is allowed iff the subtype is UUID.
{
_id: 10,
input: "867dee52-c331-484e-92d1-c56479b8e67e",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "uuid",
},
{
_id: 11,
input: "867dee52-c331-484e-92d1-c56479b8e67e",
target: {type: "binData", subtype: kNonUUIDSubtype},
format: "auto",
},
{
_id: 12,
input: "hn3uUsMxSE6S0cVkebjmfg==",
target: {type: "binData", subtype: kUUIDSubtype},
format: "base64",
},
{
_id: 13,
input: "hn3uUsMxSE6S0cVkebjmfg==",
target: {type: "binData", subtype: kUUIDSubtype},
format: "auto",
},
// Forbidden conversions between different binData subtypes
{
_id: 14,
input: UUID("867dee52-c331-484e-92d1-c56479b8e67e"),
target: {type: "binData", subtype: kNonUUIDSubtype},
expected: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
},
{
_id: 15,
input: BinData(kNonUUIDSubtype, "hn3uUsMxSE6S0cVkebjmfg=="),
target: {type: "binData", subtype: kUUIDSubtype},
},
{
_id: 16,
input: UUID("867dee52-c331-484e-92d1-c56479b8e67e"),
target: {type: "binData", subtype: 255},
},
{
_id: 17,
input: BinData(255, "hn3uUsMxSE6S0cVkebjmfg=="),
target: {type: "binData", subtype: 0},
},
];
//
// Conversions with invalid 'to' argument.
//
const invalidArgumentValueDocs = [
// Valid subtype is required when converting to BinData.
{
_id: 1,
input: "hn3uUsMxSE6S0cVkebjmfg==",
target: {type: "binData", subtype: -1},
format: "base64",
expectedCode: 4341107,
},
{
_id: 2,
input: "hn3uUsMxSE6S0cVkebjmfg==",
target: {type: "binData", subtype: 1000},
format: "base64",
expectedCode: 4341107,
},
{
_id: 3,
input: "hn3uUsMxSE6S0cVkebjmfg==",
// User-defined subtypes must be between 128-255.
target: {type: "binData", subtype: 256},
format: "base64",
expectedCode: 4341107,
},
{
_id: 4,
input: "hn3uUsMxSE6S0cVkebjmfg==",
// User-defined subtypes must be between 128-255.
target: {type: "binData", subtype: 127},
format: "base64",
expectedCode: 4341107,
},
// Invalid type.
{_id: 5, input: 123, target: {type: -2}, expectedCode: ErrorCodes.FailedToParse},
{_id: 6, input: 123, target: -2, expectedCode: ErrorCodes.FailedToParse},
];
runConvertTests({coll, requiresFCV80, conversionTestDocs, illegalConversionTestDocs, invalidArgumentValueDocs});