Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NODE-4273): pass 'comment' option through to distinct command #3339

Merged
merged 8 commits into from
Aug 3, 2022
16 changes: 7 additions & 9 deletions src/operations/distinct.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { Document } from '../bson';
import type { Collection } from '../collection';
import { MongoCompatibilityError } from '../error';
import type { Server } from '../sdam/server';
import type { ClientSession } from '../sessions';
import { Callback, decorateWithCollation, decorateWithReadConcern, maxWireVersion } from '../utils';
import { Callback, decorateWithCollation, decorateWithReadConcern } from '../utils';
import { CommandOperation, CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';

Expand Down Expand Up @@ -61,6 +60,12 @@ export class DistinctOperation extends CommandOperation<any[]> {
cmd.maxTimeMS = options.maxTimeMS;
}

// we check for undefined specifically here to allow falsy values
// eslint-disable-next-line no-restricted-syntax
if (typeof options.comment !== 'undefined') {
cmd.comment = options.comment;
}
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved

// Do we have a readConcern specified
decorateWithReadConcern(cmd, coll, options);

Expand All @@ -71,13 +76,6 @@ export class DistinctOperation extends CommandOperation<any[]> {
return callback(err);
}

if (this.explain && maxWireVersion(server) < 4) {
callback(
new MongoCompatibilityError(`Server ${server.name} does not support explain on distinct`)
);
return;
}

super.executeCommand(server, session, cmd, (err, result) => {
if (err) {
callback(err);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Long } from '../../../src';
import { TestBuilder, UnifiedTestSuiteBuilder } from '../../tools/utils';

const falsyValues = [0, false, '', Long.ZERO, null, NaN] as const;
const falsyToString = (value: typeof falsyValues[number]) => {
export const falsyValues = [0, false, '', Long.ZERO, null, NaN] as const;
dariakp marked this conversation as resolved.
Show resolved Hide resolved
export const falsyToString = (value: typeof falsyValues[number]) => {
if (Number.isNaN(value)) {
return 'NaN';
}
Expand Down
39 changes: 39 additions & 0 deletions test/integration/node-specific/distinct.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expect } from 'chai';

import { Collection, CommandStartedEvent, MongoClient } from '../../../src';
import { falsyToString, falsyValues } from './comment_with_falsy_values.test';

context('command distinct', function () {
let client: MongoClient;
let collection: Collection;
let commands: CommandStartedEvent[] = [];

beforeEach(async function () {
client = this.configuration.newClient({ monitorCommands: true });
client.on('commandStarted', e => commands.push(e));
await client.connect();
collection = await client.db('comment-falsy-values').createCollection('collection');
commands = [];
});

afterEach(async function () {
await collection.drop();
await client.close();
});

context('comment with falsy values', function () {
dariakp marked this conversation as resolved.
Show resolved Hide resolved
for (const falsyValue of falsyValues) {
it(`should send falsy value ${falsyToString(falsyValue)} on the command`, async function () {
await collection.distinct('some-key', {}, { comment: falsyValue }).catch(() => null);

expect(commands).to.have.lengthOf(1);
const distinctCommand = commands.find(command => command.commandName === 'distinct');
expect(distinctCommand).to.exist;

// chai does not narrow types, so TS doesn't know the distinct command exists at this point.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
expect(distinctCommand!.command).to.haveOwnProperty('comment');
});
}
});
});
186 changes: 186 additions & 0 deletions test/spec/crud/unified/distinct-comment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
{
"description": "distinct-comment",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0",
"observeEvents": [
"commandStartedEvent"
]
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "distinct-comment-tests"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"collectionName": "coll0",
"databaseName": "distinct-comment-tests",
"documents": [
{
"_id": 1,
"x": 11
},
{
"_id": 2,
"x": 22
},
{
"_id": 3,
"x": 33
}
]
}
],
"tests": [
{
"description": "distinct with document comment",
"runOnRequirements": [
{
"minServerVersion": "4.4.14"
}
],
"operations": [
{
"name": "distinct",
"object": "collection0",
"arguments": {
"fieldName": "x",
"filter": {},
"comment": {
"key": "value"
}
},
"expectResult": [
11,
22,
33
]
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": {
"distinct": "coll0",
"key": "x",
"query": {},
"comment": {
"key": "value"
}
},
"commandName": "distinct",
"databaseName": "distinct-comment-tests"
}
}
]
}
]
},
{
"description": "distinct with string comment",
"runOnRequirements": [
{
"minServerVersion": "4.4.0"
}
],
"operations": [
{
"name": "distinct",
"object": "collection0",
"arguments": {
"fieldName": "x",
"filter": {},
"comment": "comment"
},
"expectResult": [
11,
22,
33
]
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": {
"distinct": "coll0",
"key": "x",
"query": {},
"comment": "comment"
},
"commandName": "distinct",
"databaseName": "distinct-comment-tests"
}
}
]
}
]
},
{
"description": "distinct with document comment - pre 4.4, server error",
"runOnRequirements": [
{
"minServerVersion": "3.6.0",
"maxServerVersion": "4.4.13"
}
],
"operations": [
{
"name": "distinct",
"object": "collection0",
"arguments": {
"fieldName": "x",
"filter": {},
"comment": {
"key": "value"
}
},
"expectError": {
"isClientError": false
}
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": {
"distinct": "coll0",
"key": "x",
"query": {},
"comment": {
"key": "value"
}
},
"commandName": "distinct",
"databaseName": "distinct-comment-tests"
}
}
]
}
]
}
]
}
98 changes: 98 additions & 0 deletions test/spec/crud/unified/distinct-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
description: "distinct-comment"

schemaVersion: "1.0"

createEntities:
- client:
id: &client0 client0
observeEvents: [ commandStartedEvent ]
- database:
id: &database0 database0
client: *client0
databaseName: &database0Name distinct-comment-tests
- collection:
id: &collection0 collection0
database: *database0
collectionName: &collection0Name coll0

initialData:
- collectionName: *collection0Name
databaseName: *database0Name
documents:
- { _id: 1, x: 11 }
- { _id: 2, x: 22 }
- { _id: 3, x: 33 }

tests:
- description: "distinct with document comment"
runOnRequirements:
# https://jira.mongodb.org/browse/SERVER-44847
# Server supports distinct with comment of any type for comment starting from 4.4.14.
- minServerVersion: "4.4.14"
operations:
- name: distinct
object: *collection0
arguments:
fieldName: &fieldName x
filter: &filter {}
comment: &documentComment { key: "value"}
expectResult: [ 11, 22, 33 ]
expectEvents:
- client: *client0
events:
- commandStartedEvent:
command:
distinct: *collection0Name
key: *fieldName
query: *filter
comment: *documentComment
commandName: distinct
databaseName: *database0Name

- description: "distinct with string comment"
runOnRequirements:
- minServerVersion: "4.4.0"
operations:
- name: distinct
object: *collection0
arguments:
fieldName: *fieldName
filter: *filter
comment: &stringComment "comment"
expectResult: [ 11, 22, 33 ]
expectEvents:
- client: *client0
events:
- commandStartedEvent:
command:
distinct: *collection0Name
key: *fieldName
query: *filter
comment: *stringComment
commandName: distinct
databaseName: *database0Name

- description: "distinct with document comment - pre 4.4, server error"
runOnRequirements:
- minServerVersion: "3.6.0"
maxServerVersion: "4.4.13"
operations:
- name: distinct
object: *collection0
arguments:
fieldName: *fieldName
filter: *filter
comment: *documentComment
expectError:
isClientError: false
expectEvents:
- client: *client0
events:
- commandStartedEvent:
command:
distinct: *collection0Name
key: *fieldName
query: *filter
comment: *documentComment
commandName: distinct
databaseName: *database0Name