Skip to content

Commit b9fbac5

Browse files
author
Bailey Pearson
authored
fix(NODE-3705): ReadPreference.fromOptions omitting hedge and maxStalenessSeconds when readPreference is a string (#3060)
1 parent 7b00d0f commit b9fbac5

File tree

4 files changed

+139
-65
lines changed

4 files changed

+139
-65
lines changed

Diff for: CONTRIBUTORS.md

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
- Neal Beeken <<[email protected]>>
5959
- Durran Jordan <<[email protected]>>
6060
- Daria Pardue <<[email protected]>>
61+
- Bailey Pearson <<[email protected]>>
6162

6263
## Community Types
6364

Diff for: src/read_preference.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,10 @@ export class ReadPreference {
156156
}
157157

158158
if (typeof readPreference === 'string') {
159-
return new ReadPreference(readPreference as ReadPreferenceMode, readPreferenceTags);
159+
return new ReadPreference(readPreference as ReadPreferenceMode, readPreferenceTags, {
160+
maxStalenessSeconds: options.maxStalenessSeconds,
161+
hedge: options.hedge
162+
});
160163
} else if (!(readPreference instanceof ReadPreference) && typeof readPreference === 'object') {
161164
const mode = readPreference.mode || readPreference.preference;
162165
if (mode && typeof mode === 'string') {

Diff for: test/functional/readpreference.test.js

-64
Original file line numberDiff line numberDiff line change
@@ -14,70 +14,6 @@ describe('ReadPreference', function () {
1414
return setupDatabase(this.configuration);
1515
});
1616

17-
describe('::constructor', function () {
18-
const maxStalenessSeconds = 1234;
19-
const { PRIMARY, SECONDARY, NEAREST } = ReadPreference;
20-
const TAGS = [{ loc: 'dc' }];
21-
22-
it('should accept (mode)', function () {
23-
expect(new ReadPreference(PRIMARY)).to.be.an.instanceOf(ReadPreference);
24-
});
25-
26-
it('should accept valid (mode, tags)', function () {
27-
expect(new ReadPreference(PRIMARY, [])).to.be.an.instanceOf(ReadPreference);
28-
const p0 = new ReadPreference(NEAREST, TAGS);
29-
expect(p0.mode).to.equal(NEAREST);
30-
});
31-
32-
it('should not accept invalid tags', function () {
33-
expect(() => new ReadPreference(PRIMARY, 'invalid')).to.throw(
34-
'ReadPreference tags must be an array'
35-
);
36-
expect(() => new ReadPreference(PRIMARY, { loc: 'dc' }, { maxStalenessSeconds })).to.throw(
37-
'ReadPreference tags must be an array'
38-
);
39-
});
40-
41-
it('should accept (mode, options)', function () {
42-
const p1 = new ReadPreference(SECONDARY, { maxStalenessSeconds });
43-
expect(p1.mode).to.equal(SECONDARY);
44-
expect(p1.maxStalenessSeconds).to.equal(maxStalenessSeconds);
45-
});
46-
47-
it('should not accept mode=primary + tags', function () {
48-
expect(() => new ReadPreference(PRIMARY, TAGS)).to.throw(
49-
'Primary read preference cannot be combined with tags'
50-
);
51-
});
52-
53-
it('should not accept mode=primary + options.maxStalenessSeconds', function () {
54-
expect(() => new ReadPreference(PRIMARY, null, { maxStalenessSeconds })).to.throw(
55-
'Primary read preference cannot be combined with maxStalenessSeconds'
56-
);
57-
});
58-
59-
it('should accept (mode=secondary, tags=null, options)', function () {
60-
const p2 = new ReadPreference(SECONDARY, null, { maxStalenessSeconds });
61-
expect(p2).to.be.an.instanceOf(ReadPreference);
62-
expect(p2.mode).to.equal(SECONDARY);
63-
expect(p2.maxStalenessSeconds).to.equal(maxStalenessSeconds);
64-
});
65-
66-
it('should accept (mode=secondary, tags, options)', function () {
67-
const p3 = new ReadPreference(SECONDARY, TAGS, { maxStalenessSeconds });
68-
expect(p3).to.be.an.instanceOf(ReadPreference);
69-
expect(p3.mode).to.equal(SECONDARY);
70-
expect(p3.tags).to.eql(TAGS);
71-
expect(p3.maxStalenessSeconds).to.equal(maxStalenessSeconds);
72-
});
73-
74-
it('should not accept (mode, options, tags)', function () {
75-
expect(() => new ReadPreference(PRIMARY, { maxStalenessSeconds }, TAGS)).to.throw(
76-
'ReadPreference tags must be an array'
77-
);
78-
});
79-
});
80-
8117
it('Should correctly apply collection level read Preference to count', {
8218
metadata: { requires: { mongodb: '>=2.6.0', topology: ['single', 'ssl'] } },
8319

Diff for: test/unit/read_preference.test.ts

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { ReadPreference } from '../../src';
2+
import { expect } from 'chai';
3+
4+
describe('class ReadPreference', function () {
5+
const maxStalenessSeconds = 1234;
6+
const { PRIMARY, SECONDARY, NEAREST } = ReadPreference;
7+
const TAGS = [{ loc: 'dc' }];
8+
describe('::constructor', function () {
9+
it('should accept (mode)', function () {
10+
expect(new ReadPreference(PRIMARY)).to.be.an.instanceOf(ReadPreference);
11+
});
12+
13+
it('should accept valid (mode, tags)', function () {
14+
expect(new ReadPreference(PRIMARY, [])).to.be.an.instanceOf(ReadPreference);
15+
const p0 = new ReadPreference(NEAREST, TAGS);
16+
expect(p0).to.have.property('mode', NEAREST);
17+
});
18+
19+
it('should not accept invalid tags', function () {
20+
expect(() => new ReadPreference(PRIMARY, 'invalid' as any)).to.throw(
21+
'ReadPreference tags must be an array'
22+
);
23+
expect(
24+
() => new ReadPreference(PRIMARY, { loc: 'dc' } as any, { maxStalenessSeconds })
25+
).to.throw('ReadPreference tags must be an array');
26+
});
27+
28+
it('should accept (mode, options)', function () {
29+
const p1 = new ReadPreference(SECONDARY, { maxStalenessSeconds } as any);
30+
expect(p1.mode).to.equal(SECONDARY);
31+
expect(p1).to.have.property('maxStalenessSeconds', maxStalenessSeconds);
32+
});
33+
34+
it('should not accept mode=primary + tags', function () {
35+
expect(() => new ReadPreference(PRIMARY, TAGS)).to.throw(
36+
'Primary read preference cannot be combined with tags'
37+
);
38+
});
39+
40+
it('should not accept mode=primary + options.maxStalenessSeconds', function () {
41+
expect(() => new ReadPreference(PRIMARY, null, { maxStalenessSeconds })).to.throw(
42+
'Primary read preference cannot be combined with maxStalenessSeconds'
43+
);
44+
});
45+
46+
it('should not accept mode=primary + options.hedge enabled', function () {
47+
expect(() => new ReadPreference(PRIMARY, null, { hedge: { enabled: true } })).to.throw(
48+
'Primary read preference cannot be combined with hedge'
49+
);
50+
});
51+
52+
it('should accept (mode=secondary, tags=null, options)', function () {
53+
const p2 = new ReadPreference(SECONDARY, null, { maxStalenessSeconds });
54+
expect(p2).to.be.an.instanceOf(ReadPreference);
55+
expect(p2).to.have.property('mode', SECONDARY);
56+
expect(p2).to.have.property('maxStalenessSeconds', maxStalenessSeconds);
57+
});
58+
59+
it('should accept (mode=secondary, tags, options)', function () {
60+
const p3 = new ReadPreference(SECONDARY, TAGS, { maxStalenessSeconds });
61+
expect(p3).to.be.an.instanceOf(ReadPreference);
62+
expect(p3).to.have.property('mode', SECONDARY);
63+
expect(p3.tags).to.deep.equal(TAGS);
64+
expect(p3).to.have.property('maxStalenessSeconds', maxStalenessSeconds);
65+
});
66+
67+
it('should not accept (mode, options, tags)', function () {
68+
expect(
69+
() => new ReadPreference(PRIMARY, { maxStalenessSeconds } as any, TAGS as any)
70+
).to.throw('ReadPreference tags must be an array');
71+
});
72+
});
73+
74+
describe('fromOptions factory method', () => {
75+
it('should return undefined if no options are passed', () => {
76+
const readPreference = ReadPreference.fromOptions();
77+
expect(readPreference).to.be.undefined;
78+
});
79+
80+
context('readPreference is string', () => {
81+
it('should accept { readPreference }', function () {
82+
const readPreference = ReadPreference.fromOptions({
83+
readPreference: PRIMARY
84+
});
85+
expect(readPreference).to.be.an.instanceOf(ReadPreference);
86+
expect(readPreference).to.have.property('mode', PRIMARY);
87+
});
88+
89+
it('should accept { readPreference, readPreferenceTags }', function () {
90+
const readPreference = ReadPreference.fromOptions({
91+
readPreference: SECONDARY,
92+
readPreferenceTags: TAGS
93+
});
94+
expect(readPreference).to.be.an.instanceOf(ReadPreference);
95+
expect(readPreference).to.have.property('mode', SECONDARY);
96+
expect(readPreference.tags).to.deep.equal(TAGS);
97+
});
98+
99+
it('should accept { readPreference, maxStalenessSeconds }', function () {
100+
const readPreference = ReadPreference.fromOptions({
101+
readPreference: SECONDARY,
102+
maxStalenessSeconds: maxStalenessSeconds
103+
});
104+
expect(readPreference).to.be.an.instanceOf(ReadPreference);
105+
expect(readPreference).to.have.property('mode', SECONDARY);
106+
expect(readPreference).to.have.property('maxStalenessSeconds', maxStalenessSeconds);
107+
});
108+
109+
it('should accept { readPreference, hedge }', function () {
110+
const readPreference = ReadPreference.fromOptions({
111+
readPreference: SECONDARY,
112+
hedge: {
113+
enabled: true
114+
}
115+
});
116+
expect(readPreference).to.be.an.instanceOf(ReadPreference);
117+
expect(readPreference).to.have.property('mode', SECONDARY);
118+
expect(readPreference.hedge).to.deep.equal({ enabled: true });
119+
});
120+
});
121+
122+
it('should not accept mode=primary + options.hedge', function () {
123+
expect(() =>
124+
ReadPreference.fromOptions({ readPreference: PRIMARY, hedge: { enabled: true } })
125+
).to.throw('Primary read preference cannot be combined with hedge');
126+
});
127+
128+
it('should not accept mode=primary + options.maxStalenessSeconds', function () {
129+
expect(() =>
130+
ReadPreference.fromOptions({ readPreference: PRIMARY, maxStalenessSeconds })
131+
).to.throw('Primary read preference cannot be combined with maxStalenessSeconds');
132+
});
133+
});
134+
});

0 commit comments

Comments
 (0)