11import { WebSocket } from 'mock-socket' ;
2- import {
3- Collection ,
4- localCollections ,
5- runObservers ,
6- } from '../../src/Collection' ;
2+ import Mongo from '../../src/Mongo' ;
3+ import { endpoint , props } from '../testHelpers' ;
4+ import { localCollections , runObservers } from '../../src/Collection' ;
75import { expect } from 'chai' ;
86import Data from '../../src/Data' ;
97import DDP from '../../lib/ddp' ;
108import Random from '../../lib/Random' ;
119import { server } from '../hooks/mockServer' ;
10+ import Tracker from '../../src/Tracker' ;
11+
12+ const Collection = Mongo . Collection ;
13+ const objectProps = props ( { } ) ;
14+ const defaultProps = [
15+ '_collection' ,
16+ '_name' ,
17+ '_transform' ,
18+ 'constructor' ,
19+ 'find' ,
20+ 'findOne' ,
21+ 'insert' ,
22+ 'update' ,
23+ 'remove' ,
24+ 'helpers' ,
25+ '__defineGetter__' ,
26+ '__defineSetter__' ,
27+ 'hasOwnProperty' ,
28+ '__lookupGetter__' ,
29+ '__lookupSetter__' ,
30+ 'isPrototypeOf' ,
31+ 'propertyIsEnumerable' ,
32+ 'toString' ,
33+ 'valueOf' ,
34+ '__proto__' ,
35+ 'toLocaleString' ,
36+ ] ;
1237
1338describe ( 'Collection' , function ( ) {
14- const endpoint = 'ws://localhost:3000/websocket' ;
15-
1639 // for proper collection tests we need the server to be active
1740
1841 before ( function ( ) {
1942 if ( ! Data . ddp ) {
2043 Data . ddp = new DDP ( {
2144 SocketConstructor : WebSocket ,
2245 endpoint,
46+ autoConnect : false ,
2347 } ) ;
2448 Data . ddp . socket . on ( 'open' , ( ) => {
2549 Data . ddp . socket . emit ( 'message:in' , { msg : 'connected' } ) ;
@@ -46,12 +70,17 @@ describe('Collection', function () {
4670 } ) ;
4771
4872 describe ( 'constructor' , function ( ) {
73+ it ( 'is exported via Mongo' , ( ) => {
74+ expect ( Mongo . Collection ) . to . equal ( Collection ) ;
75+ } ) ;
4976 it ( 'creates a new collection and one in Minimongo' , function ( ) {
5077 const name = Random . id ( 6 ) ;
5178 const c = new Collection ( name ) ;
5279 expect ( c . _name ) . to . equal ( name ) ;
5380 expect ( c . _transform ) . to . equal ( null ) ;
54- expect ( Data . db . collections [ name ] ) . to . equal ( c . _collection ) ;
81+ expect ( c . _collection ) . to . equal ( Data . db . collections [ name ] ) ;
82+ expect ( c . _collection . name ) . to . equal ( name ) ;
83+ expect ( c . _collection . constructor . name ) . to . equal ( 'Collection' ) ;
5584 } ) ;
5685 it ( 'creates a local collection and a random counterpart in minimongo' , function ( ) {
5786 const c = new Collection ( null ) ;
@@ -85,6 +114,14 @@ describe('Collection', function () {
85114 c = new Collection ( Random . id ( ) , { transform } ) ;
86115 expect ( c . _transform ( { _id } ) ) . to . deep . equal ( { _id, foo : 'bar' } ) ;
87116 } ) ;
117+ it ( 'does not imply prototype pollution' , ( ) => {
118+ objectProps . forEach ( ( name ) => {
119+ expect ( ( ) => new Mongo . Collection ( name ) ) . to . throw (
120+ `Object-prototype property ${ name } is not a supported Collection name`
121+ ) ;
122+ expect ( props ( { } ) ) . to . deep . equal ( objectProps ) ;
123+ } ) ;
124+ } ) ;
88125 } ) ;
89126
90127 describe ( 'insert' , function ( ) {
@@ -173,6 +210,55 @@ describe('Collection', function () {
173210 done ( ) ;
174211 } ) ;
175212 } ) ;
213+ it ( 'triggers a reactive observer' , ( done ) => {
214+ const collectionName = Random . id ( 6 ) ;
215+ const c = new Mongo . Collection ( collectionName ) ;
216+
217+ Tracker . autorun ( ( comp ) => {
218+ const doc = c . findOne ( { foo : 1 } ) ;
219+ if ( doc ) {
220+ comp . stop ( ) ;
221+ done ( ) ;
222+ }
223+ } ) ;
224+
225+ setTimeout ( ( ) => c . insert ( { foo : 1 } ) , 50 ) ;
226+ } ) ;
227+ it ( 'does not imply prototype pollution' , ( done ) => {
228+ const collectionName = Random . id ( 6 ) ;
229+ const c = new Mongo . Collection ( collectionName ) ;
230+ objectProps . forEach ( ( name ) => c . find ( name ) . fetch ( ) ) ;
231+ expect ( props ( { } ) ) . to . deep . equal ( objectProps ) ;
232+ const insertDoc = { } ;
233+ objectProps . forEach ( ( prop ) => {
234+ insertDoc [ prop ] = 'foo' ;
235+ } ) ;
236+
237+ Tracker . autorun ( ( comp ) => {
238+ if ( c . find ( ) . count ( ) < 1 ) {
239+ return ;
240+ }
241+
242+ c . _name = '__proto__' ;
243+ try {
244+ c . find ( insertDoc ) ;
245+ } catch { }
246+ try {
247+ expect ( props ( { } ) ) . to . deep . equal ( objectProps ) ;
248+ } catch ( e ) {
249+ comp . stop ( ) ;
250+ return done ( e ) ;
251+ }
252+
253+ comp . stop ( ) ;
254+ done ( ) ;
255+ } ) ;
256+
257+ setTimeout ( ( ) => {
258+ c . _name = collectionName ;
259+ c . insert ( insertDoc ) ;
260+ } , 50 ) ;
261+ } ) ;
176262 } ) ;
177263
178264 describe ( 'update' , function ( ) {
0 commit comments