UNPKG

spincycle

Version:

A reactive message router and object manager that lets clients subscribe to object property changes on the server

1,078 lines (965 loc) 37.6 kB
expect = require('chai').expect SuperModel = require('../lib/SuperModel') ResolveModule = require('../lib/ResolveModule') DB = require('../lib/DB') OStore = require('../lib/OStore') request = require('request') unirest = require('unirest') AuthenticationManager = require('../example/AuthenticationManager') express = require("express") bodyParser = require("body-parser") app = express() app.use(bodyParser.urlencoded({ extended: true })) app.use(bodyParser.json()) app.use(bodyParser()); SpinCycle = require('../lib/MessageRouter') ClientEndpoints = require('../lib/ClientEndpoints') describe 'Spincycle Model Tests', -> this.timeout(500000); authMgr = undefined messageRouter = undefined httpMethod = undefined record = _rev: 99101020202030303404 id: '17' name: 'foo' f1record = _rev: 'f10101020202030303404' id: 'f117' name: 'foo' f2record = _rev: 'f20101020202030303404' id: 'f217' name: 'foo' f3record = _rev: 'f30101020202030303404' id: 'f317' name: 'foo' f4record = _rev: 'f40101020202030303404' id: 'f417' name: 'foo' f5record = _rev: 'f50101020202030303404' id: 'f517' name: 'foo' record2 = _rev: 77788877788899900099 id: '4711' name: 'xyzzy' theFoo: '17' foos: ['17'] footable: ['17'] class Foo extends SuperModel @type = 'Foo' @model= [ {name: 'name', value: 'name', default:'foo', public: true} ] constructor:(@record={})-> return super ResolveModule.modulecache['Foo'] = Foo class DFoo extends SuperModel @type = 'DFoo' @model= [ {name: 'name', value: 'name', default:'foo'} {name: 'someProp', value: 'someProp', default:'xyzzy'} ] constructor:(@record={})-> return super class Bar extends SuperModel @type = 'Bar' @model= [ {name: 'name', public: true, value: 'name', default: 'yohoo'} {name: 'theFoo', value: 'theFoo', public: true, type: 'Foo' } {name: 'foos', public: true, array: true, ids: 'foos', type: 'Foo'} {name: 'footable', hashtable: true, ids: 'footable', type: 'Foo'} ] constructor: (@record={}) -> return super class HashBar extends SuperModel @type = 'HashBar' @model= [ {name: 'name', public: true, value: 'name', default: 'yohoo'} {name: 'theFoo', value: 'theFoo', type: 'Foo' } {name: 'foos', public: true, array: true, ids: 'foos', type: 'Foo'} {name: 'footable', hashtable: true, ids: 'footable', type: 'Foo', keyproperty: 'id'} ] constructor: (@record={}) -> return super ResolveModule.modulecache['Bar'] = Bar ResolveModule.modulecache['HashBar'] = HashBar class Fooznaz extends SuperModel @type = 'Fooznaz' @model= [ {name: 'name', value: 'name', default:'fooznaz', public: true} {name: 'things', ids: 'things', array: true, type: 'Bar', public: true} ] constructor:(@record={})-> return super class DirectBar extends SuperModel @type = 'DirectBar' @model= [ {name: 'name', public: true, value: 'name', default: 'directyohoo'} {name: 'theFoo', value: 'theFoo', type: 'DFoo', storedirectly: true } {name: 'foos', public: true, type: 'DFoo', array: true, ids: 'foos', storedirectly: true} {name: 'footable', hashtable: true, ids: 'footable', type: 'DFoo', storedirectly: true} ] constructor: (@record={}) -> return super class VeryBar extends SuperModel @type = 'VeryBar' @model= [ {name: 'name', public: true, value: 'name', default: 'directyohoo'} {name: 'theFoo', value: 'theFoo', type: 'DFoo', storedirectly: true } {name: 'foos', public: true, type: 'Foo', array: true, ids: 'foos'} {name: 'bars', public: true, type: 'Bar', array: true, ids: 'bars'} {name: 'dfoos', public: true, type: 'DFoo', array: true, ids: 'dfoos'} ] constructor: (@record={}) -> return super before (done)-> #console.log '------------------------------------- before called' authMgr = new AuthenticationManager() messageRouter = undefined #messageRouter = new SpinCycle(authMgr, null, 10, app, 'mongodb') new SpinCycle(authMgr, null, 10, app, 'rethinkdb').then (mr)=> messageRouter = mr """ options = { api_key: "8a8c68a6193ac76c501f49b08e3a105f", app_key: "1b9c45f6638bd01d8ef4c474ec87e15487f644a2", #api_version: 'v1.5', api_host: 'app.datadoghq.com' } messageRouter = new SpinCycle(authMgr, null, 10, app, 'google', options) """ httpMethod = new SpinCycle.HttpMethod(messageRouter, app, '/api/') app.listen(8008) ResolveModule.modulecache['foo'] = Foo ResolveModule.modulecache['bar'] = Bar ResolveModule.modulecache['dfoo'] = DFoo ResolveModule.modulecache['directbar'] = DirectBar ResolveModule.modulecache['verybar'] = VeryBar ResolveModule.modulecache['hashbar'] = HashBar ResolveModule.modulecache['fooznaz'] = Fooznaz DB.createDatabases(['foo','bar','dfoo','directbar','hashbar','fooznaz', 'verybar']).then () -> console.log '++++++++++++++++++++++++++++++++++++spec dbs created' messageRouter.open() done() return false #----------------------------------------------------------------------- postCreateState = -1 @record3 = id:'42' name: 'xyzzy' shoesize: '42' @record4= id:'667' name: 'Neihgbor of the beast' hatsize: '42' @record5= id:'9' name: 'Neihgbor of the beast' shirtsize: '42' class Baz extends SuperModel @model= [ {name: 'name', value: 'name', default:'baz'} {name: 'shoesize', value: 'shoesize', default:'-1'} ] constructor: (@record={}) -> #console.log ' Baz constructor' postCreateState = 3 return super class Quux extends SuperModel @model= [ {name: 'name', value: 'name', default:'baz'} {name: 'hatsize', value: 'hatsize', default:'0'} ] constructor: (@record={}) -> #console.log ' Quux constructor' postCreateState = 2 return super postCreate: (q) => #console.log ' Quux postcreate. Creating new Baz manually' postCreateState = 1 new Baz(@record3).then (baz) => postCreateState = 4 #console.log ' Quux post-Baz creation' q.resolve(@) class Ezra extends SuperModel @model= [ {name: 'name', value: 'name', default:'baz'} {name: 'shirtsize', value: 'shirtsize', default:'7'} {name: 'thequux', value: 'thequux', type:'Quux'} ] constructor: (@record={}) -> #console.log 'Ezra constructor ' postCreateState = 0 return super postCreate: (q) => #console.log ' Ezra postcreate. Creating new Quux manually' postCreateStatee = 1 new Quux(@record4).then (quux) => @thequux = quux postCreateState = 5 #console.log ' Ezra post-Quux creation' q.resolve(@) #------------------------------------------------------------------------- it 'should retain _rev property from record', ()-> new Foo(record).then (o) -> expect(o._rev).to.equal(record._rev) it 'should get back basic values when creating record', ()-> new Foo(f1record).then (o) -> rv = o.getRecord() expect(rv.name).to.equal(record.name) it 'should get resolve direct reference values from record', ()-> new Foo(f2record).then (foo) -> new Bar(record2).then (bar) -> #console.dir bar expect(bar.theFoo).to.exist it 'should not spill over old array contents from one object creation to another', ()-> new Bar().then (bar) -> bar.foos.push '123456789' bar.serialize().then ()-> console.dir bar new Bar({name: 'a bar'}).then (bar2) -> console.dir bar2 expect(bar2.foos[0]).to.not.exist it 'should create an object that has a direct reference and be able to set and update that reference', (done)-> new Foo({id:'12345'}).then (o) -> #console.log 'got new foo' #console.dir o #console.log 'trying to serialize...' o.serialize().then ()-> new Bar().then (bar) -> #console.log 'got new bar' #console.dir bar bar.theFoo = '12345' umsg = obj: bar.toClient() user: isAdmin: true email: 'foo@bar.com' name: 'Mr. Xyzzy' replyFunc: (ureply)-> #console.log 'update reply was' #console.dir(ureply) expect(ureply.status).to.equal('SUCCESS') done() messageRouter.objectManager._updateObject(umsg) it 'should get back id from direct reference when creating record', ()-> new Foo(f1record).then (foo) -> OStore.storeObject(foo) new Bar(record2).then (bar) -> rv = bar.getRecord() expect(rv.theFoo).to.equal(record.id) it 'should be able to create a hashtable property from record', ()-> new Bar(record2).then (bar) -> #console.dir bar expect(bar.footable).to.exist it 'should be able to persist newly added hashtable references and still have them after serializing and reloading from record', (done)-> new Bar(record2).then (bar) -> OStore.storeObject(bar) new Foo(f4record).then (foo) -> OStore.storeObject(foo) bar.footable[foo.name] = foo foo.serialize().then ()-> bar.serialize().then ()-> DB.get('Bar', ['4711']).then (newbars) -> newbar = newbars[0] #console.dir newbar expect(newbar.footable).to.exist setTimeout( ()-> done() ,400 ) it 'should be able to use custom properties for hashtable keys', ()-> record222 = _rev: 71299900099 id: '174711' type: 'Bar' name: 'BAR xyzzy' theFoo: '17' foos: ['17'] new HashBar(record222).then (bar) -> OStore.storeObject(bar) new Foo(f4record).then (foo) -> OStore.storeObject(foo) bar.footable[foo.id] = foo foo.serialize() bar.serialize() DB.get('HashBar', ['174711']).then (newbars) -> newbar = newbars[0] new HashBar(newbar).then (nbobj) -> expect(nbobj.footable[foo.id]).to.equal(foo) it 'should get back array of ids from array reference when creating record', ()-> new Foo(f5record).then (afoo) -> OStore.storeObject(afoo) new Bar(record2).then (bar) -> OStore.storeObject(bar) c = 10 for i in [1..10] new Foo().then (foo) -> OStore.storeObject(foo) bar.foos.push(foo) if --c == 0 rv = bar.getRecord() #console.dir rv expect(rv.foos.length).to.be(10) it 'should filter record properties to only show those that are public when calling toClient', ()-> new Bar(record2).then (bar) -> rv = bar.toClient() #console.dir rv expect(rv.footable).to.not.exist expect(rv.name).to.exist it 'should call postCreate, when defined, in serial order down the references', ()-> new Ezra(@record5).then (ezra) -> expect(postCreateState).to.equal(5) it 'should retain hashtable key name and values after persistence', ()-> new Foo(record).then (foo) -> OStore.storeObject(foo) new Bar(record2).then (bar) -> OStore.storeObject(bar) bar.serialize().then () -> DB.get('Bar', ['4711']).then (bar_records)-> bar_record = bar_records[0] new Bar(bar_record).then (newbar)-> same = false keys1 = [] keys2 = [] vals1 = [] vals2 = [] for k,v of newbar.footable keys1.push k vals1.push v for kk,vv of bar.footable keys2.push k vals2.push v for k,i in keys1 if keys1[i] and keys1[i] != keys2[i] then same = false else same = true if vals1[i] and vals1[i] != vals2[i] then same = false else same = true expect(same).to.equal(true) it 'should resolve cold array references to objects not yet in ostore, only in db', (done)-> foo = {id: '99008877', name: 'fooname', value: 'name', default:'foo', type: 'Foo'} DB.set 'Foo', foo, (sres) -> bar = type: 'Bar' id: '444174711' name: 'BAR xyzzy' theFoo: '' foos: ['99008877'] DB.set 'Bar', bar, (bres) -> messageRouter.objectManager.getObjectPullThrough('444174711', 'Bar').then (barobj)-> expect(barobj.foos.length).to.equal(1) done() it 'should resolve multiple cold array references to objects not yet in ostore, only in db', (done)-> console.log '--------------------------------------------------------------------- cold array test start' foo = {id: '11008877', name: 'fooname', value: 'name', default:'foo', type: 'Foo'} foo2 = {id: '77778877', name: 'fooname', value: 'name2', default:'foo2', type: 'Foo'} DB.set 'Foo', foo, (sres) -> DB.set 'Foo', foo2, (sres2) -> bar = type: 'Bar' id: 'foobarbaz' name: 'ANOTHER BAR xyzzyqq' theFoo: '' foos: ['11008877', '77778877'] DB.set 'Bar', bar, (bres) -> messageRouter.objectManager.getObjectPullThrough('foobarbaz', 'Bar').then (barobj)-> expect(barobj.foos.length).to.equal(2) done() it 'should have multiple cold array references to objects not yet in ostore, and get right amount of references in arrays of search results', (done)-> console.log '--------------------------------------------------------------------- cold array test start 2' foo = {id: '21008877', name: 'fooname', value: 'namexxxx', default:'foox', type: 'Foo'} foo2 = {id: '27778877', name: 'fooname', value: 'nameyyyy', default:'fooy', type: 'Foo'} DB.set 'Foo', foo, (sres) -> DB.set 'Foo', foo2, (sres2) -> bar = type: 'Bar' id: 'xyzzy17' name: 'YET ANOTHER BAR' theFoo: '' foos: ['21008877', '27778877'] DB.set 'Bar', bar, (bres) -> msg = type: 'Bar' user: isAdmin: true replyFunc: (reply)-> expect(reply.payload.length).to.gt(0) done() messageRouter.objectManager._listObjects(msg) it 'should cold load an object with a large amount of references in arrays of search results', (done)-> foorefs = [] max = 29 count = max-1 count++ for _x in [0..max] ((x)-> foo = {id: 'foo_'+x+'_21008877', name: 'fooname', value: 'name_'+x, type: 'Foo'} DB.set 'Foo', foo, (sres) -> foorefs.push foo.id if --count == 0 bar = type: 'Bar' id: '4711xyzzy17' name: 'SON OF YET ANOTHER BAR' theFoo: '' foos: foorefs DB.set 'Bar', bar, (bres) -> msg = type: 'Bar' user: isAdmin: true replyFunc: (reply)-> reply.payload.forEach (bb)-> if bb.name == bar.name expect(bb.foos.length).to.equal(foorefs.length) done() messageRouter.objectManager._listObjects(msg) )(_x) it 'should filter out crap values in arrays when updating', ()-> new Fooznaz().then (fz) -> record = fz.toClient() record.things.push null record.things.push "null" record.things.push "undefined" record.things.push undefined new Fooznaz(record).then (fz2)-> expect(fz2.things.length).to.equal(0) it 'should always return an array from listObjects', (done)-> msg = type: 'Foo' user: isAdmin: true replyFunc: (reply)-> #console.log '--------------testing if listObject always returns an array' #console.dir reply expect(reply.payload.length).to.gt(0) done() setTimeout( ()-> messageRouter.objectManager._listObjects(msg) ,200 ) it 'should include whole objects when using storedirectly', (done)-> #console.log '------------------------------------------------trying to make a foo' record7= id: 'aaa3' type: 'DFoo' name: 'BolarsKolars' ResolveModule.modulecache['DFoo'] = DFoo ResolveModule.modulecache['DirectBar'] = DirectBar new DFoo(record7).then (dfoo) -> #console.dir(dfoo) #console.log 'trying to make a dbar' new DirectBar().then (dbar) -> dbar.theFoo = dfoo dbar.foos.push dfoo dbar.footable[dfoo.name] = dfoo #console.log 'trying to serialize dbar' dbar.serialize().then () -> #console.log 'trying to recreate dbar' DB.get('DirectBar', [dbar.id]).then (dbar_records)-> #console.log 'created new directbar!' #console.dir dbar_records bar_record = dbar_records[0] new DirectBar(bar_record).then (newdbar)-> #console.log 'new direct bar-----------------------------' #console.dir newdbar expect(newdbar.theFoo.name).to.equal(dfoo.name) done() it 'should be able to update sparse object with arrays', (done)-> new Foo().then (foo) -> new DFoo().then (dfoo) -> new Bar().then (bar)-> new VeryBar().then (vbar)-> vbar.foos.push foo vbar.dfoos.push dfoo vbar.serialize() msg1 = type: 'VeryBar' id: vbar.id obj: id: vbar.id type: 'VeryBar' user: isAdmin: true replyFunc: (ureply)-> #console.log 'get reply for verybar was' #console.dir(ureply) record = {id:vbar.id, type:'VeryBar',bars:[]} record.bars.push bar.id msg2 = obj: record user: isAdmin: true replyFunc: (ureply2)-> console.log 'update reply for verybar was' console.dir ureply2 msg3 = type: 'VeryBar' id: vbar.id obj: id: vbar.id type: 'VeryBar' user: isAdmin: true replyFunc: (ureply3)-> console.log 'get again reply for verybar was' console.dir(ureply3) expect(ureply3.payload.foos.length).to.equal(1) done() messageRouter.objectManager._getObject(msg3) #console.log '--- sparse test updating object' messageRouter.objectManager._updateObject(msg2) messageRouter.objectManager._getObject(msg1) it 'should be able to do a search on a property', (done)-> record7= id: 'bbb456' type: 'DFoo' name: 'BolarsKolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record7).then (dfoo) -> dfoo.serialize().then ()-> query = {sort:'name', property: 'name', value: 'BolarsKolars'} DB.findQuery('DFoo', query).then (records) => expect(records.length).to.equal(1) done() it 'should not get any hits when using part of a string value to search on a property, and not using wildcard', (done)-> record7= id: 'bbb456' type: 'DFoo' name: 'aaaaabbbbb' new DFoo(record7).then (dfoo) -> dfoo.serialize().then ()-> query = {sort:'name', property: 'name', value: 'aaaaa'} DB.findQuery('DFoo', query).then (records) => console.dir records expect(records.length).to.equal(0) done() it 'should not get any results when searching on the wrong property', (done)-> record7= id: 'bbb456' type: 'DFoo' name: 'BolarsKolars2' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record7).then (dfoo) -> dfoo.serialize().then ()-> query = {sort:'name', property: 'id', value: 'BolarsKolars2'} DB.findQuery('DFoo', query).then (records) => expect(records.length).to.equal(0) done() it 'should be able to search on a wildcard property', (done)-> record8= id: 'bbb456' type: 'DFoo' name: 'MehmetBolarsKolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record8).then (dfoo) -> dfoo.serialize().then ()-> query = {sort:'name', property: 'name', value: 'Meh', wildcard: true} DB.findQuery('DFoo', query).then (records) => expect(records.length).to.equal(1) done() it 'should be able to get two hits on a wildcard property', (done)-> record9= id: 'bbb4567' type: 'DFoo' name: 'Myfflan sKolars' record10= id: 'bbb45677' type: 'DFoo' name: 'MyhmetBolarsKolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record9).then (dfoo1) -> dfoo1.serialize().then ()-> new DFoo(record10).then (dfoo2) -> dfoo2.serialize().then ()-> query = {sort:'name', property: 'name', value: 'My', wildcard: true} DB.findQuery('DFoo', query).then (records) => expect(records.length).to.equal(2) done() it 'should be able to get two hits on a specific property search', (done)-> record9= id: 'bbb4567' type: 'DFoo' createdBy: 'a945872c-cd42-48e7-9d73-703df1e82f1c' name: 'fyffe sKolars' record10= id: 'bbb45677' type: 'DFoo' createdBy: 'a945872c-cd42-48e7-9d73-703df1e82f1c' name: 'affo Kolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record9).then (dfoo1) -> dfoo1.serialize().then ()-> new DFoo(record10).then (dfoo2) -> dfoo2.serialize().then ()-> query = {property: 'createdBy', value: 'a945872c-cd42-48e7-9d73-703df1e82f1c'} DB.findQuery('DFoo', query).then (records) => expect(records.length).to.equal(2) done() it 'should not bomb on searches with wildcard characters', (done)-> record11= id: 'bb3356' type: 'DFoo' name: 'ArnelarsKolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record11).then (dfoo) -> dfoo.serialize().then ()-> query = {sort:'name', property: 'name', value: 'Arne*', wildcard: true} DB.findQuery('DFoo', query).then (records) => expect(records.length).to.equal(1) done() it 'should not bomb on specific searches with faulty values', (done)-> record12= id: 'b44b3356' type: 'DFoo' name: 'MixnelarsKolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record12).then (dfoo) -> dfoo.serialize().then ()-> query = {sort:'name', property: 'id', value: '[Object object]'} DB.findQuery('DFoo', query).then (records) => #console.log 'bomb query got back' #console.dir records expect(records.length).to.equal(0) done() it 'should be able to limit search results', (done)-> query = {sort:'name', property: 'name', value: 'M', limit: 1, wildcard:true} DB.findQuery('DFoo', query).then (records) => console.log 'limit query got back' console.dir records expect(records.length).to.equal(1) done() it 'should be able to limit all search results', (done)-> query = {sort:'name', limit: 2} DB.all 'DFoo', query,(records) => console.log 'limit query got back' console.dir records expect(records.length).to.equal(2) done() it 'should be able to do specific searches', (done)-> record12= id: 'b44rrb3356' type: 'DFoo' name: 'AlohaMixnelarsKolars' ResolveModule.modulecache['DFoo'] = DFoo new DFoo(record12).then (dfoo) -> dfoo.serialize().then ()-> DB.findMany('DFoo', 'id', 'b44rrb3356').then (records) => #console.log '--------------------- specific search recods ' #console.dir records expect(records.length).to.equal(1) done() it 'should be able to do an ordered search', (done)-> foorefs = [] max = 10 count = max-1 count++ for _x in [0..max] ((x)-> foo = {id: 'order_foo_'+x, name: 'order_foo_'+x, value: 'name_'+x, type: 'Foo'} new Foo(foo).then (sres) -> sres.serialize().then ()-> if --count == 0 query = {sort:'createdBy', skip:0, limit:'10'} DB.all 'Foo', query, (records) => console.log '---------------------orderBy search result' console.dir records done() )(_x) it 'should get an error message when sending too many requests per second', (done)-> user = { name: 'foo', id:'17'} count = 12 failure = false for i in [0..12] msg = target: 'listcommands' user: user replyFunc: (reply)-> #console.log 'reply was '+reply.info #console.dir reply if reply.status == 'NOT_ALLOWED' then failure = true if --count == 0 expect(failure).to.equal(true) done() messageRouter.routeMessage(msg) it 'should update an array on an object with a reference and have that reference be present in the array when searching for the object', (done)-> new Bar().then (bar) -> bar.serialize() new Foo().then (foo) -> foo.serialize().then ()-> umsg = obj: id: bar.id type: 'Bar' foos: [foo.id] user: isAdmin: true replyFunc: (ureply)-> console.log 'update reply was' console.dir(ureply) messageRouter.objectManager._updateObject(umsg) msg = type: 'Bar' user: isAdmin: true replyFunc: (reply)-> #reply.payload.forEach (obj) -> if obj.id == bar.id then console.dir obj expect(reply.payload.length).to.gt(0) done() messageRouter.objectManager._listObjects(msg) it 'should be able to resolve object graphs properly', (done)-> messageRouter.objectManager.resolveReferences(record2, Bar.model).then (result)-> #console.log '---------------- resolvereferences results ------------------' #console.dir result done() it 'should be able to update scalars without trashing array references', (done)-> new Bar().then (bar) -> new Foo().then (foo) -> foo.serialize().then ()-> bar.foos.push foo bar.serialize().then ()-> brecord = bar.toClient() brecord.name = 'Doctored Bar object' messageRouter.objectManager.resolveReferences(brecord, Bar.model).then (result)-> #console.log '---------------- resolvereferences results ------------------' #console.dir result expect(result.foos.length).to.gt(0) done() it 'should be able to get correct array references to an object update subscriber', (done)-> new Bar().then (bar) -> new Foo().then (foo) -> foo.serialize().then ()-> bar.foos.push foo bar.serialize().then ()-> console.log '------------------------- initial bar object foos is ' console.dir bar.foos ClientEndpoints.registerEndpoint 'fooclient',(reply)-> console.log '--__--__--__ object update __--__--__--' console.dir reply expect(reply.payload.foos.length).to.equal(0) done() msg = type: 'Bar' client: 'fooclient' obj:{id: bar.id, type: 'Bar'} user: isAdmin: true replyFunc: (reply)->#console.log "we're listening to "+bar.id messageRouter.objectManager.onRegisterForUpdatesOn(msg) brecord = bar.toClient() brecord.name = '*** Extra Doctored Bar object' brecord.foos = [] umsg = obj: brecord user: isAdmin: true replyFunc: (ureply)-> messageRouter.objectManager._updateObject(umsg) it 'should be able to update an array reference with one less object reference', (done)-> new Bar().then (bar) -> new Foo().then (foo) -> foo.serialize().then ()-> new Foo().then (foo2) -> foo.serialize().then ()-> bar.foos.push foo bar.foos.push foo2 bar.serialize().then ()-> #console.log '------------------------- initial bar object foos is ' #console.dir bar.foos brecord = bar.toClient() brecord.name = '*** one less Doctored Bar object' brecord.foos = [foo2.id] umsg = obj: brecord user: isAdmin: true replyFunc: (ureply)-> console.log 'one less object update is '+ureply console.dir ureply msg1 = type: 'Bar' id: bar.id obj: id: bar.id type: 'Bar' user: isAdmin: true replyFunc: (ureply2)-> console.log 'one less after update _get is..' console.dir ureply2 expect(ureply2.payload.foos.length).to.equal(1) done() messageRouter.objectManager._getObject(msg1) messageRouter.objectManager._updateObject(umsg) it 'should be able to get an object with all array references of that of the object in db', (done)-> new Bar().then (bar) -> new Foo().then (foo) -> new Foo().then (foo2) -> foo.serialize().then ()-> bar.foos.push foo bar.foos.push foo2 bar.serialize().then ()-> console.log '------------------------- initial bar object foos is ' console.dir bar.foos msg = type: 'Bar' obj:{id: bar.id, type: 'Bar'} user: isAdmin: true replyFunc: (reply)-> console.log '--__--__--__ object get result __--__--__--' console.dir reply expect(reply.payload.foos.length).to.equal(2) done() messageRouter.objectManager._getObject(msg) return false it 'should be able to get population change callbacks on create', (done)-> ClientEndpoints.registerEndpoint 'updateclient',(reply)-> #console.log '--__--__--__ update client got population change __--__--__--' #console.dir reply expect(reply.payload.added).to.exist ClientEndpoints.removeEndpoint 'updateclient' done() msg = type: 'Bar' id:'11992299' client: 'updateclient' user: isAdmin: true replyFunc: (reply)-> new Bar().then (bar) -> #console.log 'bar created. waiting for population change' messageRouter.objectManager.onRegisterForPopulationChanges(msg) it 'should be able to get population change callbacks on delete', (done)-> ClientEndpoints.registerEndpoint 'updateclient2',(reply)-> #console.log '--__--__--__ update client got population change __--__--__--' #console.dir reply expect(reply.payload.removed).to.exist ClientEndpoints.removeEndpoint 'updateclient2' done() new Bar({id:'11992299', type: 'Bar'}).then (bar) -> umsg = obj: {type:'Bar', id:'11992299'} type: 'Bar' client: 'updateclient2' user: isAdmin: true replyFunc: (ureply)-> msg = type: 'Bar' client: 'updateclient2' user: isAdmin: true replyFunc: (reply)-> messageRouter.objectManager._deleteObject(umsg) messageRouter.objectManager.onRegisterForPopulationChanges(msg) it 'should be able call listcommands through HttpMethod', (done)-> request.get 'http://localhost:8008/api/?target=listcommands', (req,res,_body)-> #console.log('listcommands returns '+body) body = JSON.parse(_body) #console.dir arguments expect(body.status).to.equal('SUCCESS') done() it 'should be able to expose an object and access _listObject through HttpMethod', (done)-> messageRouter.objectManager.expose('Foo') request.get 'http://localhost:8008/api/?target=_listFoos', (req,res,_body)-> #console.log('listcommands returns '+_body) body = JSON.parse(_body) #console.dir arguments expect(body.status).to.equal('SUCCESS') done() it 'should be able to restify an already exposed object and access /rest/Object through HttpMethod', (done)-> messageRouter.makeRESTful('Foo') request.get 'http://localhost:8008/rest/Foo', (req,res,_body)-> #console.log('listcommands returns '+_body) body = JSON.parse(_body) #console.dir arguments expect(body.status).to.equal('SUCCESS') done() it 'should be able to access a restified object through /rest/Object/:id and HttpMethod', (done)-> #messageRouter.makeRESTful('Foo') request.get 'http://localhost:8008/rest/Foo/21008877', (req,res,_body)-> #console.log('listcommands returns '+_body) body = JSON.parse(_body) #console.dir arguments expect(body.status).to.equal('SUCCESS') done() it 'should be able to update a restified object through put /rest/Object/:id and HttpMethod', (done)-> #messageRouter.makeRESTful('Foo') record = type: 'Foo' abc: 123 obj:{name: 'xxxxx17', type: 'Foo'} new Foo(record).then (fobj)-> fobj.serialize().then ()-> record2 = obj:{name: 'qfoobar17', type: 'Foo', id: fobj.id} console.log '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' #console.dir fobj request.put {url:'http://localhost:8008/rest/Foo/'+fobj.id+'/?apitoken=abcdef123456', headers:{"Content-Type": "application/x-www-form-urlencoded"}, form: record2, body: record2}, (req,res,_body)=> console.log('put returns '+_body) request.get 'http://localhost:8008/rest/Foo/'+fobj.id, (req2,res2,_body2)=> console.log('rest get returns '+_body2) res = JSON.parse(_body2) console.dir res.payload expect(res.payload.name).to.equal('qfoobar17') done() it 'should be able to delete a restified object through delete /rest/Object/:id and HttpMethod', (done)-> #messageRouter.makeRESTful('Foo') request.delete 'http://localhost:8008/rest/Foo/21008877', (req,res,_body)-> #console.log('listcommands returns '+_body) body = JSON.parse(_body) #console.dir arguments expect(body.status).to.equal('SUCCESS') done() it 'should be able to create a new restified object through post /rest/Object/:id and HttpMethod', (done)-> #messageRouter.makeRESTful('Foo') record = id: 'f117' name: 'foobarbaz' request.post {url:'http://localhost:8008/rest/Foo', headers:{"Content-Type": "application/json"}, body:JSON.stringify(record)}, (req,res,_body)-> #console.log('put returns '+_body) body = JSON.parse(_body) #console.dir arguments expect(body.status).to.equal('SUCCESS') done() it 'should be able to extend a model with a new property', (done)-> Foo.model.push {name:'xyzzy4', public: true, value:'xyzzy', default:'quux'} DB.extendSchemaIfNeeded(DB.DataStore, 'Foo').then ()=> DB.get('foo',['f417']).then (res)=> #console.log 'DB.get got back '+res #console.dir res expect(res[0].xyzzy2).to.equal('quux') done() it 'should be able to tag a model', (done)-> new Bar({id:'f0f04b4b'}).then (bar) -> messageRouter.setTag('Bar', bar.id, 'footag').then (res)-> #console.log 'tagged a model' done() it 'should be able to get all tags for a model', (done)-> messageRouter.getTagsFor('Bar', 'f0f04b4b').then (res)-> #console.log 'tags for tagged Bar obj is '+res expect(res.indexOf('footag')).to.not.equal(-1) done() it 'should be able to search for all models with a tag', (done)-> messageRouter.searchForTags('Bar', ['footag']).then (res)-> #console.log 'models returned from searching for footag tags is '+res expect(res[0]).to.equal('f0f04b4b') done()