Skip to content

Commit f23f0ea

Browse files
committed
wip: add back sync mock mongo methods for tests
1 parent 061b4ba commit f23f0ea

File tree

2 files changed

+80
-7
lines changed

2 files changed

+80
-7
lines changed

meteor/__mocks__/mongo.ts

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { AnyBulkWriteOperation } from 'mongodb'
99
import {
1010
FindOneOptions,
1111
FindOptions,
12+
MongoCursor,
1213
MongoReadOnlyCollection,
1314
ObserveCallbacks,
1415
ObserveChangesCallbacks,
@@ -44,6 +45,7 @@ export namespace MongoMock {
4445
const mockCollections: MockCollections<any> = {}
4546
export class Collection<T extends CollectionObject> implements Omit<MinimalMeteorMongoCollection<T>, 'find'> {
4647
public _name: string
48+
private _isTemporaryCollection: boolean
4749
private _options: any = {}
4850
// @ts-expect-error used in test to check that it's a mock
4951
private _isMock = true as const
@@ -54,11 +56,15 @@ export namespace MongoMock {
5456
constructor(name: string | null, options?: { transform?: never }) {
5557
this._options = options || {}
5658
this._name = name || getRandomString() // If `null`, then its an in memory unique collection
59+
this._isTemporaryCollection = name === null
5760

5861
if (this._options.transform) throw new Error('document transform is no longer supported')
5962
}
6063

61-
find(query: any, options?: FindOptions<T>): MinimalMongoCursor<T> & { _fetchRaw: () => T[] } {
64+
find(
65+
query: any,
66+
options?: FindOptions<T>
67+
): MinimalMongoCursor<T> & { _fetchRaw: () => T[] } & Pick<MongoCursor<T>, 'fetch' | 'forEach'> {
6268
if (_.isString(query)) query = { _id: query }
6369
query = query || {}
6470

@@ -97,6 +103,12 @@ export namespace MongoMock {
97103

98104
return clone(docs)
99105
},
106+
fetch: () => {
107+
if (!this._isTemporaryCollection)
108+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
109+
110+
return clone(docs)
111+
},
100112
countAsync: async () => {
101113
// Force this to be performed async
102114
await MeteorMock.sleepNoFakeTimers(0)
@@ -140,9 +152,12 @@ export namespace MongoMock {
140152
},
141153
}
142154
},
143-
// async forEachAsync(f: any) {
144-
// docs.forEach(f)
145-
// },
155+
forEach: (f: any) => {
156+
if (!this._isTemporaryCollection)
157+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
158+
159+
docs.forEach(f)
160+
},
146161
// async mapAsync(f: any) {
147162
// return docs.map(f)
148163
// },
@@ -152,10 +167,28 @@ export namespace MongoMock {
152167
const docs = await this.find(query, options).fetchAsync()
153168
return docs[0]
154169
}
170+
findOne(query: MongoQuery<T>, options?: FindOneOptions<T>) {
171+
if (!this._isTemporaryCollection)
172+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
173+
174+
const docs = this.find(query, options).fetch()
175+
return docs[0]
176+
}
177+
155178
async updateAsync(query: any, modifier: any, options?: UpdateOptions): Promise<number> {
156179
// Force this to be performed async
157180
await MeteorMock.sleepNoFakeTimers(0)
158181

182+
return this.updateRaw(query, modifier, options)
183+
}
184+
update(query: any, modifier: any, options?: UpdateOptions): number {
185+
if (!this._isTemporaryCollection)
186+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
187+
188+
return this.updateRaw(query, modifier, options)
189+
}
190+
191+
private updateRaw(query: any, modifier: any, options?: UpdateOptions): number {
159192
const unimplementedUsedOptions = _.without(_.keys(options), 'multi')
160193
if (unimplementedUsedOptions.length > 0) {
161194
throw new Error(`update being performed using unimplemented options: ${unimplementedUsedOptions}`)
@@ -189,10 +222,20 @@ export namespace MongoMock {
189222

190223
return docs.length
191224
}
225+
192226
async insertAsync(doc: any): Promise<string> {
193227
// Force this to be performed async
194228
await MeteorMock.sleepNoFakeTimers(0)
195229

230+
return this.insertRaw(doc)
231+
}
232+
insert(doc: any): string {
233+
if (!this._isTemporaryCollection)
234+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
235+
236+
return this.insertRaw(doc)
237+
}
238+
private insertRaw(doc: any): string {
196239
const d = _.clone(doc)
197240
if (!d._id) d._id = protectString(RandomMock.id())
198241

@@ -221,6 +264,7 @@ export namespace MongoMock {
221264

222265
return d._id
223266
}
267+
224268
async upsertAsync(
225269
query: any,
226270
modifier: any,
@@ -229,23 +273,50 @@ export namespace MongoMock {
229273
// Force this to be performed async
230274
await MeteorMock.sleepNoFakeTimers(0)
231275

276+
return this.upsertRaw(query, modifier, options)
277+
}
278+
upsert(
279+
query: any,
280+
modifier: any,
281+
options?: UpsertOptions
282+
): { numberAffected: number | undefined; insertedId: string | undefined } {
283+
if (!this._isTemporaryCollection)
284+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
285+
286+
return this.upsertRaw(query, modifier, options)
287+
}
288+
private upsertRaw(
289+
query: any,
290+
modifier: any,
291+
options?: UpsertOptions
292+
): { numberAffected: number | undefined; insertedId: string | undefined } {
232293
const id = _.isString(query) ? query : query._id
233294

234295
const docs = this.find(id)._fetchRaw()
235296

236297
if (docs.length) {
237-
const count = await this.updateAsync(docs[0]._id, modifier, options)
298+
const count = this.updateRaw(docs[0]._id, modifier, options)
238299
return { insertedId: undefined, numberAffected: count }
239300
} else {
240301
const doc = mongoModify<T>(query, { _id: id } as any, modifier)
241-
const insertedId = await this.insertAsync(doc)
302+
const insertedId = this.insertRaw(doc)
242303
return { insertedId: insertedId, numberAffected: undefined }
243304
}
244305
}
306+
245307
async removeAsync(query: any): Promise<number> {
246308
// Force this to be performed async
247309
await MeteorMock.sleepNoFakeTimers(0)
248310

311+
return this.removeRaw(query)
312+
}
313+
remove(query: any): number {
314+
if (!this._isTemporaryCollection)
315+
throw new Meteor.Error(500, 'sync methods can only be used for unnamed collections')
316+
317+
return this.removeRaw(query)
318+
}
319+
private removeRaw(query: any): number {
249320
const docs = this.find(query)._fetchRaw()
250321

251322
_.each(docs, (doc) => {

meteor/server/api/__tests__/userActions/general.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '../../../../__mocks__/_extendJest'
22
import { setupDefaultStudioEnvironment } from '../../../../__mocks__/helpers/database'
33
import { hashSingleUseToken } from '../../deviceTriggers/triggersContext'
4-
import { getCurrentTime } from '../../../lib/lib'
4+
import { getCurrentTime, sleep } from '../../../lib/lib'
55
import { MeteorCall } from '../../methods'
66
import { ClientAPI } from '@sofie-automation/meteor-lib/dist/api/client'
77
import { UserActionsLog } from '../../../collections'
@@ -50,6 +50,7 @@ describe('User Actions - General', () => {
5050
await expect(MeteorCall.userAction.guiFocused('click', getCurrentTime())).resolves.toMatchObject({
5151
success: 200,
5252
})
53+
await sleep(0)
5354
const logs0 = await UserActionsLog.findFetchAsync({
5455
method: 'guiFocused',
5556
})
@@ -61,6 +62,7 @@ describe('User Actions - General', () => {
6162
await expect(MeteorCall.userAction.guiBlurred('click', getCurrentTime())).resolves.toMatchObject({
6263
success: 200,
6364
})
65+
await sleep(0)
6466
const logs1 = await UserActionsLog.findFetchAsync({
6567
method: 'guiBlurred',
6668
})

0 commit comments

Comments
 (0)