Skip to content

Commit be6bbb3

Browse files
committed
chore(e2e-tests): add queryable encryption suffix/prefix/substring tests MONGOSH-1351
1 parent bf53fba commit be6bbb3

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

packages/e2e-tests/test/e2e-fle.spec.ts

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,173 @@ describe('FLE tests', function () {
914914
});
915915
});
916916

917+
context('8.2+', function () {
918+
skipIfServerVersion(testServer, '< 8.2');
919+
920+
context(
921+
'Queryable Encryption Prefix/Suffix/Substring Support',
922+
function () {
923+
// Substring prefix support is enterprise-only 8.2+
924+
skipIfCommunityServer(testServer);
925+
926+
let shell: TestShell;
927+
let uri: string;
928+
929+
const testCollection = 'qeSubstringTest';
930+
931+
before(async function () {
932+
shell = this.startTestShell({
933+
args: ['--nodb', `--cryptSharedLibPath=${cryptLibrary}`],
934+
});
935+
uri = JSON.stringify(await testServer.connectionString());
936+
await shell.waitForPrompt();
937+
938+
// Shared setup for all substring search tests - create collection once
939+
await shell.executeLine(`{
940+
opts = {
941+
keyVaultNamespace: '${dbname}.__keyVault',
942+
kmsProviders: { local: { key: 'A'.repeat(128) } },
943+
bypassQueryAnalysis: false
944+
};
945+
946+
autoMongo = Mongo(${uri}, { ...opts });
947+
autoMongo.getDB('${dbname}').test.drop();
948+
949+
keyId = autoMongo.getKeyVault().createKey('local');
950+
951+
substringOptions = {
952+
strMinQueryLength: 2,
953+
strMaxQueryLength: 10,
954+
strMaxLength: 60,
955+
};
956+
957+
autoMongo.getClientEncryption().createEncryptedCollection('${dbname}', '${testCollection}', {
958+
provider: 'local',
959+
createCollectionOptions: {
960+
encryptedFields: {
961+
fields: [{
962+
keyId,
963+
path: 'data',
964+
bsonType: 'string',
965+
queries: [{
966+
queryType: 'substringPreview',
967+
...substringOptions,
968+
caseSensitive: false,
969+
diacriticSensitive: false,
970+
contention: 4
971+
}]
972+
}]
973+
}
974+
}
975+
});
976+
977+
coll = autoMongo.getDB('${dbname}').${testCollection};
978+
979+
// Setup explicit encryption client
980+
explicitMongo = Mongo(${uri}, { ...opts, bypassQueryAnalysis: true });
981+
ce = explicitMongo.getClientEncryption();
982+
ecoll = explicitMongo.getDB('${dbname}').${testCollection};
983+
984+
explicitOpts = {
985+
algorithm: 'TextPreview',
986+
contentionFactor: 4,
987+
textOptions: { caseSensitive: false, diacriticSensitive: false, substring: substringOptions }
988+
};
989+
}`);
990+
});
991+
992+
after(async function () {
993+
await shell.executeLine(`${testCollection}.drop()`);
994+
});
995+
996+
afterEach(async function () {
997+
await shell.executeLine(`${testCollection}.deleteMany({})`);
998+
});
999+
1000+
it('allows queryable encryption with prefix searches', async function () {
1001+
// Insert test data for prefix searches
1002+
await shell.executeLine(`{
1003+
coll.insertOne({ data: 'admin_user_123.txt' });
1004+
coll.insertOne({ data: 'admin_super_456.pdf' });
1005+
coll.insertOne({ data: 'user_regular_789.pdf' });
1006+
coll.insertOne({ data: 'guest_access_000.txt' });
1007+
1008+
// Add explicit encryption data
1009+
ecoll.insertOne({ data: ce.encrypt(keyId, 'admin_explicit_test.pdf', explicitOpts) });
1010+
}`);
1011+
const prefixResults = await shell.executeLine(
1012+
'coll.find({$expr: { $and: [{$encStrContains: {substring: "admin_", input: "$data"}}] }}, { __safeContent__: 0 }).toArray()'
1013+
);
1014+
expect(prefixResults).to.have.length(2);
1015+
expect(prefixResults).to.include('admin_user_123.txt');
1016+
expect(prefixResults).to.include('admin_super_456.pdf');
1017+
expect(prefixResults).to.include('admin_explicit_test.pdf');
1018+
});
1019+
1020+
it('allows queryable encryption with suffix searches', async function () {
1021+
// Insert test data for suffix searches
1022+
await shell.executeLine(`{
1023+
coll.insertOne({ data: 'admin_user_123.txt' });
1024+
coll.insertOne({ data: 'admin_super_456.pdf' });
1025+
coll.insertOne({ data: 'user_regular_789.pdf' });
1026+
coll.insertOne({ data: 'guest_access_000.txt' });
1027+
1028+
// Add explicit encryption data
1029+
ecoll.insertOne({ data: ce.encrypt(keyId, 'admin_explicit_test.pdf', explicitOpts) });
1030+
}`);
1031+
1032+
const suffixResults = await shell.executeLine(
1033+
'coll.find({$expr: { $and: [{$encStrContains: {substring: ".pdf", input: "$data"}}] }}, { __safeContent__: 0 }).toArray()'
1034+
);
1035+
expect(suffixResults).to.have.length(3);
1036+
expect(suffixResults).to.include('admin_super_456.pdf');
1037+
expect(suffixResults).to.include('user_regular_789.pdf');
1038+
expect(suffixResults).to.include('admin_explicit_test.pdf');
1039+
});
1040+
1041+
it('allows queryable encryption with substring searches', async function () {
1042+
// Insert test data for substring searches
1043+
// Insert test data for prefix searches
1044+
await shell.executeLine(`{
1045+
coll.insertOne({ data: 'admin_user_123.txt' });
1046+
coll.insertOne({ data: 'admin_super_456.pdf' });
1047+
coll.insertOne({ data: 'user_regular_789.pdf' });
1048+
coll.insertOne({ data: 'guest_access_000.txt' });
1049+
1050+
// Add explicit encryption data
1051+
ecoll.insertOne({ data: ce.encrypt(keyId, 'explicit_user', explicitOpts) });
1052+
}`);
1053+
// Test substring search returning multiple documents
1054+
const substringResults = await shell.executeLine(
1055+
'coll.find({$expr: { $and: [{$encStrContains: {substring: "user", input: "$data"}}] }}, { __safeContent__: 0 }).toArray()'
1056+
);
1057+
expect(substringResults).to.have.length(2);
1058+
expect(substringResults).to.include('user_regular_789.pdf');
1059+
expect(substringResults).to.include('admin_user_123.txt');
1060+
1061+
const testingSubstringResult = await shell.executeLine(
1062+
'coll.find({$expr: { $and: [{$encStrContains: {substring: "user", input: "$data"}}] }}, { __safeContent__: 0 }).toArray()'
1063+
);
1064+
expect(testingSubstringResult).to.have.length(3);
1065+
expect(testingSubstringResult).to.include('user_regular_789.pdf');
1066+
expect(testingSubstringResult).to.include('admin_user_123.txt');
1067+
expect(testingSubstringResult).to.include('explicit_user');
1068+
1069+
// Test explicit encryption substring search
1070+
const explicitSubstringResult = await shell.executeLine(`
1071+
ecoll.findOne({$expr: { $and: [{$encStrContains: {substring:
1072+
ce.encrypt(keyId, 'user', { ...explicitOpts, queryType: 'substringPreview' }), input: '$data'}}] }},
1073+
{ __safeContent__: 0 })
1074+
`);
1075+
expect(explicitSubstringResult).to.have.length(3);
1076+
expect(explicitSubstringResult).to.include('user_regular_789.pdf');
1077+
expect(explicitSubstringResult).to.include('admin_user_123.txt');
1078+
expect(explicitSubstringResult).to.include('explicit_user');
1079+
});
1080+
}
1081+
);
1082+
});
1083+
9171084
context('pre-6.0', function () {
9181085
skipIfServerVersion(testServer, '>= 6.0'); // FLE2 available on 6.0+
9191086

0 commit comments

Comments
 (0)