UNPKG

@leansdk/leanrc

Version:

LeanRC is a MVC framework for creating graceful applications

1,277 lines (1,271 loc) 77.5 kB
EventEmitter = require 'events' { expect, assert } = require 'chai' sinon = require 'sinon' _ = require 'lodash' httpErrors = require 'http-errors' LeanRC = require.main.require 'lib' { AnyT, NilT FuncG, SubsetG, UnionG, ListG, StructG, MaybeG CollectionInterface, RecordInterface, QueryInterface, CursorInterface Resource Utils: { co } } = LeanRC:: describe 'Resource', -> describe '.new', -> it 'should create new command', -> expect -> resource = Resource.new() .to.not.throw Error describe '#keyName', -> it 'should get key name using entity name', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() { keyName } = resource assert.equal keyName, 'test_entity' yield return describe '#itemEntityName', -> it 'should get item name using entity name', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() { itemEntityName } = resource assert.equal itemEntityName, 'test_entity' yield return describe '#listEntityName', -> it 'should get list name using entity name', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() { listEntityName } = resource assert.equal listEntityName, 'test_entities' yield return describe '#collectionName', -> it 'should get collection name using entity name', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() { collectionName } = resource assert.equal collectionName, 'TestEntitiesCollection' yield return describe '#collection', -> facade = null afterEach -> facade?.remove?() it 'should get collection', -> co -> TEST_FACADE = 'TEST_FACADE_001' class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() facade = LeanRC::Facade.getInstance TEST_FACADE resource = TestResource.new() resource.initializeNotifier TEST_FACADE { collectionName } = resource class TestsCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::MemoryCollectionMixin @module Test @initialize() class TestEntityRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestEntityRecord @public init: FuncG([Object, CollectionInterface], NilT), default: -> @super arguments... @type = 'Test::TestEntityRecord' return @initialize() boundCollection = TestsCollection.new collectionName, delegate: 'TestEntityRecord' facade.registerProxy boundCollection { collection } = resource assert.equal collection, boundCollection yield return describe '#action', -> it 'should create actions', -> co -> default1 = -> yield return 'test1' default2 = -> yield return 'test2' default3 = -> yield return 'test3' class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @action @async test1: Function, default: default1 @action @async test2: Function, default: default2 @action @async test3: Function, default: default3 @initialize() { test1 test2 test3 } = TestResource.metaObject.data.actions assert.equal test1.default, default1 assert.equal test1.attr, 'test1' assert.equal test1.attrType, LeanRC::FunctionT assert.equal test1.level, LeanRC::PUBLIC assert.equal test1.async, LeanRC::ASYNC assert.equal test1.pointer, 'test1' assert.equal test2.default, default2 assert.equal test2.attr, 'test2' assert.equal test2.attrType, LeanRC::FunctionT assert.equal test2.level, LeanRC::PUBLIC assert.equal test2.async, LeanRC::ASYNC assert.equal test2.pointer, 'test2' assert.equal test3.default, default3 assert.equal test3.attr, 'test3' assert.equal test3.attrType, LeanRC::FunctionT assert.equal test3.level, LeanRC::PUBLIC assert.equal test3.async, LeanRC::ASYNC assert.equal test3.pointer, 'test3' yield return describe '#actions', -> it 'should get resource actions', -> co -> default1 = -> yield return 'test1' default2 = -> yield return 'test2' default3 = -> yield return 'test3' class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @include LeanRC::QueryableResourceMixin @module Test @public entityName: String, default: 'TestEntity' @action @async test1: Function, default: default1 @action @async test2: Function, default: default2 @action @async test3: Function, default: default3 @initialize() { test1 test2 test3 } = TestResource.actions assert.equal test1.default, default1 assert.equal test1.attr, 'test1' assert.equal test1.attrType, LeanRC::FunctionT assert.equal test1.level, LeanRC::PUBLIC assert.equal test1.async, LeanRC::ASYNC assert.equal test1.pointer, 'test1' assert.equal test2.default, default2 assert.equal test2.attr, 'test2' assert.equal test2.attrType, LeanRC::FunctionT assert.equal test2.level, LeanRC::PUBLIC assert.equal test2.async, LeanRC::ASYNC assert.equal test2.pointer, 'test2' assert.equal test3.default, default3 assert.equal test3.attr, 'test3' assert.equal test3.attrType, LeanRC::FunctionT assert.equal test3.level, LeanRC::PUBLIC assert.equal test3.async, LeanRC::ASYNC assert.equal test3.pointer, 'test3' { actions } = TestResource assert.propertyVal actions.list, 'attr', 'list' assert.propertyVal actions.list, 'level', LeanRC::PUBLIC assert.propertyVal actions.list, 'async', LeanRC::ASYNC assert.propertyVal actions.detail, 'attr', 'detail' assert.propertyVal actions.detail, 'level', LeanRC::PUBLIC assert.propertyVal actions.detail, 'async', LeanRC::ASYNC assert.propertyVal actions.create, 'attr', 'create' assert.propertyVal actions.create, 'level', LeanRC::PUBLIC assert.propertyVal actions.create, 'async', LeanRC::ASYNC assert.propertyVal actions.update, 'attr', 'update' assert.propertyVal actions.update, 'level', LeanRC::PUBLIC assert.propertyVal actions.update, 'async', LeanRC::ASYNC assert.propertyVal actions.delete, 'attr', 'delete' assert.propertyVal actions.delete, 'level', LeanRC::PUBLIC assert.propertyVal actions.delete, 'async', LeanRC::ASYNC ### Moved to -> ModellingResourceMixin assert.propertyVal actions.query, 'attr', 'query' assert.propertyVal actions.query, 'attrType', Function assert.propertyVal actions.query, 'level', LeanRC::PUBLIC assert.propertyVal actions.query, 'async', LeanRC::ASYNC ### yield return describe '#beforeActionHook', -> it 'should parse action params as arguments', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() Reflect.defineProperty resource, 'context', writable: yes value: undefined ctx = Symbol 'ctx' # resource.beforeActionHook.body.call resource, ctx resource.beforeActionHook ctx assert.strictEqual resource.context, ctx, 'beforeActionHook called with context and set it in resource.context' yield return describe '#getQuery', -> it 'should get resource query', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() Reflect.defineProperty resource, 'listQuery', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: query: query: '{"test":"test123"}' # resource.context = # query: query: '{"test":"test123"}' resource.getQuery() assert.deepEqual resource.listQuery, test: 'test123' yield return describe '#getRecordId', -> it 'should get resource record ID', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() Reflect.defineProperty resource, 'recordId', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: pathParams: test_entity: 'ID123456' # resource.context = # pathParams: test_entity: 'ID123456' resource.getRecordId() assert.deepEqual resource.recordId, 'ID123456' # assert.propertyVal resource, 'recordId', 'ID123456' yield return describe '#getRecordBody', -> it 'should get body', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' TestResource.initialize() resource = TestResource.new() Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: request: body: test_entity: test: 'test9' # resource.context = # request: body: test_entity: test: 'test9' resource.getRecordBody() assert.deepEqual resource.recordBody, test: 'test9' yield return describe '#omitBody', -> facade = null afterEach -> facade?.remove?() it 'should clean body from unneeded properties', -> co -> TEST_FACADE = 'TEST_FACADE_002' facade = LeanRC::Facade.getInstance TEST_FACADE class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() class TestsCollection extends LeanRC::Collection @inheritProtected() @module Test @initialize() class TestEntityRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestEntityRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestEntityRecord' # return @initialize() resource = TestResource.new() resource.initializeNotifier TEST_FACADE { collectionName } = resource boundCollection = TestsCollection.new collectionName, delegate: 'TestEntityRecord' facade.registerProxy boundCollection Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: request: body: test_entity: _id: '123', test: 'test9', _space: 'test', type: 'TestEntityRecord' # resource.context = # request: body: test_entity: # _id: '123', test: 'test9', _space: 'test', type: 'TestEntityRecord' resource.getRecordBody() resource.omitBody() assert.deepEqual resource.recordBody, test: 'test9', type: 'Test::TestEntityRecord' yield return describe '#beforeUpdate', -> it 'should get body with ID', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() Reflect.defineProperty resource, 'recordId', writable: yes value: undefined Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: { pathParams: test_entity: 'ID123456' request: body: test_entity: test: 'test9' } # resource.context = # pathParams: test_entity: 'ID123456' # request: body: test_entity: test: 'test9' resource.getRecordId() resource.getRecordBody() resource.beforeUpdate() assert.deepEqual resource.recordBody, {id: 'ID123456', test: 'test9'} yield return describe '#list', -> facade = null afterEach -> facade?.remove?() it 'should list of resource items', -> co -> KEY = 'TEST_RESOURCE_001' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root "#{__dirname}/config/root" @initialize() configs = LeanRC::Configuration.new LeanRC::CONFIGURATION, Test::ROOT facade.registerProxy configs class TestRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestRecord' # return @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() class TestsCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::QueryableCollectionMixin @module Test @public @async parseQuery: FuncG( [UnionG Object, QueryInterface] UnionG Object, String, QueryInterface ), default: (aoQuery) -> yield return aoQuery @public @async takeAll: FuncG([], CursorInterface), default: -> yield LeanRC::Cursor.new @, @getData().data @public @async executeQuery: FuncG( [UnionG Object, String, QueryInterface] CursorInterface ), default: (aoParsedQuery) -> data = _.filter @getData().data, aoParsedQuery.$filter yield return LeanRC::Cursor.new @, data @public @async push: FuncG(RecordInterface, RecordInterface), default: (aoRecord) -> isExist = (id) => (_.find @getData().data, {id})? while isExist key = LeanRC::Utils.uuid.v4() then aoRecord.id = key i = aoRecord.toJSON() @getData().data.push i yield return aoRecord @public @async includes: FuncG([UnionG String, Number], Boolean), default: (id)-> yield return (_.find @getData().data, {id})? @initialize() class TestRouter extends LeanRC::Router @inheritProtected() @module Test @initialize() class MyResponse extends EventEmitter _headers: {} getHeaders: -> LeanRC::Utils.copy @_headers getHeader: (field) -> @_headers[field.toLowerCase()] setHeader: (field, value) -> @_headers[field.toLowerCase()] = value removeHeader: (field) -> delete @_headers[field.toLowerCase()] end: (data, encoding = 'utf-8', callback = ->) -> @finished = yes @emit 'finish', data?.toString? encoding callback() constructor: (args...) -> super args... { @finished, @_headers } = finished: no, _headers: {} req = method: 'GET' url: 'http://localhost:8888/space/SPACE123/test_entitis' headers: 'x-forwarded-for': '192.168.0.1' res = new MyResponse facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER' class TestSwitch extends LeanRC::Switch @inheritProtected() @module Test @public routerName: String, { default: 'TEST_SWITCH_ROUTER' } @initialize() facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR' switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR' COLLECTION_NAME = 'TestEntitiesCollection' facade.registerProxy TestsCollection.new COLLECTION_NAME, delegate: 'TestRecord' # serializer: 'Serializer' data: [] collection = facade.retrieveProxy COLLECTION_NAME yield collection.create test: 'test1' yield collection.create test: 'test2' resource = TestResource.new() resource.initializeNotifier KEY context = Test::Context.new req, res, switchMediator context.query = query: '{}' { items, meta } = yield resource.list context assert.deepEqual meta, pagination: limit: 'not defined' offset: 'not defined' assert.propertyVal items[0], 'test', 'test1' assert.propertyVal items[1], 'test', 'test2' yield return describe '#detail', -> facade = null afterEach -> facade?.remove?() it 'should get resource single item', -> co -> KEY = 'TEST_RESOURCE_002' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root "#{__dirname}/config/root" @initialize() configs = LeanRC::Configuration.new LeanRC::CONFIGURATION, Test::ROOT facade.registerProxy configs class TestRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> Test::TestRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestRecord' # return @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, { default: 'TestEntity' } @initialize() class TestsCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::QueryableCollectionMixin @module Test @public @async parseQuery: FuncG( [UnionG Object, QueryInterface] UnionG Object, String, QueryInterface ), default: (aoQuery) -> yield return aoQuery @public @async executeQuery: FuncG( [UnionG Object, String, QueryInterface] CursorInterface ), default: (aoParsedQuery) -> data = _.filter @getData().data, aoParsedQuery.$filter yield LeanRC::Cursor.new @, data @public @async push: FuncG(RecordInterface, RecordInterface), default: (aoRecord) -> isExist = (id) => (_.find @getData().data, {id})? while isExist key = LeanRC::Utils.uuid.v4() then aoRecord.id = key i = aoRecord.toJSON() @getData().data.push i yield return aoRecord @public @async take: FuncG([UnionG String, Number], RecordInterface), default: (id) -> result = [] if (data = _.find @getData().data, {id})? result.push data cursor = LeanRC::Cursor.new @, result return yield cursor.first() @public @async includes: FuncG([UnionG String, Number], Boolean), default: (id)-> yield return (_.find @getData().data, {id})? @initialize() class TestRouter extends LeanRC::Router @inheritProtected() @module Test @initialize() class MyResponse extends EventEmitter _headers: {} getHeaders: -> LeanRC::Utils.copy @_headers getHeader: (field) -> @_headers[field.toLowerCase()] setHeader: (field, value) -> @_headers[field.toLowerCase()] = value removeHeader: (field) -> delete @_headers[field.toLowerCase()] end: (data, encoding = 'utf-8', callback = ->) -> @finished = yes @emit 'finish', data?.toString? encoding callback() constructor: (args...) -> super args... { @finished, @_headers } = finished: no, _headers: {} req = method: 'GET' url: 'http://localhost:8888/space/SPACE123/test_entitis' headers: 'x-forwarded-for': '192.168.0.1' res = new MyResponse facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER' class TestSwitch extends LeanRC::Switch @inheritProtected() @module Test @public routerName: String, { default: 'TEST_SWITCH_ROUTER' } @initialize() facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR' switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR' COLLECTION_NAME = 'TestEntitiesCollection' facade.registerProxy TestsCollection.new COLLECTION_NAME, delegate: 'TestRecord' serializer: -> LeanRC::Serializer data: [] collection = facade.retrieveProxy COLLECTION_NAME yield collection.create test: 'test1'#, type: 'Test::TestRecord' record = yield collection.create test: 'test2'#, type: 'Test::TestRecord' resource = TestResource.new() resource.initializeNotifier KEY context = Test::Context.new req, res, switchMediator context.pathParams = "#{resource.keyName}": record.id result = yield resource.detail context assert.propertyVal result, 'id', record.id assert.propertyVal result, 'test', 'test2' yield return describe '#create', -> facade = null afterEach -> facade?.remove?() it 'should create resource single item', -> co -> KEY = 'TEST_RESOURCE_003' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestRecord' # return @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, { default: 'TestEntity' } @initialize() class TestsCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::QueryableCollectionMixin @module Test @public @async parseQuery: FuncG( [UnionG Object, QueryInterface] UnionG Object, String, QueryInterface ), default: (aoQuery) -> yield return aoQuery @public @async executeQuery: FuncG( [UnionG Object, String, QueryInterface] CursorInterface ), default: (aoParsedQuery) -> data = _.filter @getData().data, aoParsedQuery.$filter yield return LeanRC::Cursor.new @, data @public @async push: FuncG(RecordInterface, RecordInterface), default: (aoRecord) -> isExist = (id) => (_.find @getData().data, {id})? while isExist key = LeanRC::Utils.uuid.v4() then aoRecord.id = key i = aoRecord.toJSON() @getData().data.push i yield return aoRecord @public @async take: FuncG([UnionG String, Number], RecordInterface), default: (id) -> result = [] if (data = _.find @getData().data, {id})? result.push data cursor = LeanRC::Cursor.new @, result return yield cursor.first() @public @async includes: FuncG([UnionG String, Number], Boolean), default: (id)-> yield return (_.find @getData().data, {id})? @initialize() COLLECTION_NAME = 'TestEntitiesCollection' facade.registerProxy TestsCollection.new COLLECTION_NAME, delegate: 'TestRecord' # serializer: LeanRC::Serializer data: [] collection = facade.retrieveProxy COLLECTION_NAME resource = TestResource.new() resource.initializeNotifier KEY Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: undefined ctx = request: body: test_entity: test: 'test3' result = yield resource.create ctx assert.propertyVal result, 'test', 'test3' yield return describe '#update', -> facade = null afterEach -> facade?.remove?() it 'should update resource single item', -> co -> KEY = 'TEST_RESOURCE_004' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class Test::TestRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestRecord' # return @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, { default: 'TestEntity' } @initialize() class TestCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::QueryableCollectionMixin @module Test @public @async parseQuery: FuncG( [UnionG Object, QueryInterface] UnionG Object, String, QueryInterface ), default: (aoQuery) -> yield return aoQuery @public @async executeQuery: FuncG( [UnionG Object, String, QueryInterface] CursorInterface ), default: (aoParsedQuery) -> data = _.filter @getData().data, aoParsedQuery.$filter yield LeanRC::Cursor.new @, data @public @async push: FuncG(RecordInterface, RecordInterface), default: (aoRecord) -> isExist = (id) => (_.find @getData().data, {id})? while isExist key = LeanRC::Utils.uuid.v4() then aoRecord.id = key i = aoRecord.toJSON() @getData().data.push i yield return aoRecord @public @async override: FuncG([UnionG(String, Number), RecordInterface], RecordInterface), default: (id, aoRecord) -> item = _.find @getData().data, {id} if item? FORBIDDEN = [ '_key', '_id', '_type', '_rev' ] snapshot = _.omit (aoRecord.toJSON?() ? aoRecord ? {}), FORBIDDEN item[key] = value for own key, value of snapshot # yield @take id yield return aoRecord @public @async take: FuncG([UnionG String, Number], RecordInterface), default: (id) -> result = [] if (data = _.find @getData().data, {id})? result.push data cursor = LeanRC::Cursor.new @, result return yield cursor.first() @public @async includes: FuncG([UnionG String, Number], Boolean), default: (id)-> yield return (_.find @getData().data, {id})? @initialize() COLLECTION_NAME = 'TestEntitiesCollection' facade.registerProxy TestCollection.new COLLECTION_NAME, delegate: 'TestRecord' serializer: LeanRC::Serializer data: [] collection = facade.retrieveProxy COLLECTION_NAME resource = TestResource.new() resource.initializeNotifier KEY Reflect.defineProperty resource, 'recordId', writable: yes value: undefined Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'context', writable: yes value: undefined record = yield collection.create test: 'test3' ctx = { type: 'Test::TestRecord' pathParams: test_entity: record.id request: body: test_entity: test: 'test8' } result = yield resource.update ctx assert.propertyVal result, 'test', 'test8' yield return describe '#delete', -> facade = null afterEach -> facade?.remove?() it 'should remove resource single item', -> co -> KEY = 'TEST_RESOURCE_005' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root "#{__dirname}/config/root" @initialize() configs = LeanRC::Configuration.new LeanRC::CONFIGURATION, Test::ROOT facade.registerProxy configs class TestRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestRecord' # return @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, { default: 'TestEntity' } @initialize() class TestsCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::QueryableCollectionMixin @module Test @public @async parseQuery: FuncG( [UnionG Object, QueryInterface] UnionG Object, String, QueryInterface ), default: (aoQuery) -> yield return aoQuery @public @async executeQuery: FuncG( [UnionG Object, String, QueryInterface] CursorInterface ), default: (aoParsedQuery) -> data = _.filter @getData().data, aoParsedQuery.$filter yield LeanRC::Cursor.new @, data @public @async push: FuncG(RecordInterface, RecordInterface), default: (aoRecord) -> isExist = (id) => (_.find @getData().data, {id})? while isExist key = LeanRC::Utils.uuid.v4() then aoRecord.id = key i = aoRecord.toJSON() @getData().data.push i yield return aoRecord @public @async override: FuncG([UnionG(String, Number), RecordInterface], RecordInterface), default: (id, aoRecord) -> item = _.find @getData().data, {id} if item? FORBIDDEN = [ '_key', '_id', '_type', '_rev' ] snapshot = _.omit (aoRecord.toJSON?() ? aoRecord ? {}), FORBIDDEN item[key] = value for own key, value of snapshot # yield @take id yield return aoRecord @public @async take: FuncG([UnionG String, Number], RecordInterface), default: (id) -> result = [] if (data = _.find @getData().data, {id})? result.push data cursor = LeanRC::Cursor.new @, result return yield cursor.first() @public @async includes: FuncG([UnionG String, Number], Boolean), default: (id)-> yield return (_.find @getData().data, {id})? @initialize() class TestRouter extends LeanRC::Router @inheritProtected() @module Test @initialize() class MyResponse extends EventEmitter _headers: {} getHeaders: -> LeanRC::Utils.copy @_headers getHeader: (field) -> @_headers[field.toLowerCase()] setHeader: (field, value) -> @_headers[field.toLowerCase()] = value removeHeader: (field) -> delete @_headers[field.toLowerCase()] end: (data, encoding = 'utf-8', callback = ->) -> @finished = yes @emit 'finish', data?.toString? encoding callback() constructor: (args...) -> super args... { @finished, @_headers } = finished: no, _headers: {} req = method: 'GET' url: 'http://localhost:8888/space/SPACE123/test_entitis' headers: 'x-forwarded-for': '192.168.0.1' res = new MyResponse facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER' class TestSwitch extends LeanRC::Switch @inheritProtected() @module Test @public routerName: String, { default: 'TEST_SWITCH_ROUTER' } @initialize() facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR' switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR' COLLECTION_NAME = 'TestEntitiesCollection' facade.registerProxy TestsCollection.new COLLECTION_NAME, delegate: 'TestRecord' # serializer: LeanRC::Serializer data: [] collection = facade.retrieveProxy COLLECTION_NAME resource = TestResource.new() resource.initializeNotifier KEY context = Test::Context.new req, res, switchMediator record = yield collection.create test: 'test3' context.pathParams = test_entity: record.id result = yield resource.delete context assert.isUndefined result yield return describe '#execute', -> facade = null afterEach -> facade?.remove?() it 'should call execution', -> co -> KEY = 'TEST_RESOURCE_008' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root "#{__dirname}/config/root" @initialize() class TestRecord extends LeanRC::Record @inheritProtected() @module Test @attribute test: String @public @static findRecordByName: FuncG(String, SubsetG RecordInterface), default: (asType) -> TestRecord # @public init: FuncG([Object, CollectionInterface], NilT), # default: -> # @super arguments... # @type = 'Test::TestRecord' # return @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @include LeanRC::QueryableResourceMixin @module Test @public entityName: String, { default: 'TestEntity' } @initialize() configs = LeanRC::Configuration.new LeanRC::CONFIGURATION, Test::ROOT facade.registerProxy configs class TestResque extends LeanRC::Resque @inheritProtected() @module Test @public jobs: Object, { default: {} } @public @async getDelayed: FuncG([], ListG StructG { queueName: String scriptName: String data: AnyT delay: MaybeG Number id: String }), default: -> yield return [] @public init: Function, default: (args...) -> @super args... @jobs = {} @initialize() resque = TestResque.new LeanRC::RESQUE, data: [] facade.registerProxy resque class TestsCollection extends LeanRC::Collection @inheritProtected() @include LeanRC::QueryableCollectionMixin @module Test @public @async parseQuery: FuncG( [UnionG Object, QueryInterface] UnionG Object, String, QueryInterface ), default: (aoQuery) -> voQuery = _.mapKeys aoQuery, (value, key) -> key.replace /^@doc\./, '' voQuery = _.mapValues voQuery, (value, key) -> if value['$eq']? then value['$eq'] else value yield return $filter: voQuery @public @async executeQuery: FuncG( [UnionG Object, String, QueryInterface] CursorInterface ), default: (aoParsedQuery) -> data = _.filter @getData().data, aoParsedQuery.$filter yield LeanRC::Cursor.new @, data @public @async push: FuncG(RecordInterface, RecordInterface), default: (aoRecord) -> isExist = (id) => (_.find @getData().data, {id})? while isExist key = LeanRC::Utils.uuid.v4() then aoRecord.id = key i = aoRecord.toJSON() @getData().data.push i yield return aoRecord @public @async remove: FuncG([UnionG String, Number], NilT), default: (id) -> _.remove @getData().data, {id} yield return @public @async take: FuncG([UnionG String, Number], RecordInterface), default: (id) -> result = [] if (data = _.find @getData().data, {id})? result.push data cursor = LeanRC::Cursor.new @, result return yield cursor.first() @public @async includes: FuncG([UnionG String, Number], Boolean), default: (id)-> yield return (_.find @getData().data, {id})? @initialize() class TestRouter extends LeanRC::Router @inheritProtected() @module Test @initialize() class MyResponse extends EventEmitter _headers: {} getHeaders: -> LeanRC::Utils.copy @_headers getHeader: (field) -> @_headers[field.toLowerCase()] setHeader: (field, value) -> @_headers[field.toLowerCase()] = value removeHeader: (field) -> delete @_headers[field.toLowerCase()] end: (data, encoding = 'utf-8', callback = ->) -> @finished = yes @emit 'finish', data?.toString? encoding callback() constructor: (args...) -> super args... { @finished, @_headers } = finished: no, _headers: {} req = method: 'GET' url: 'http://localhost:8888/space/SPACE123/test_entitis' headers: 'x-forwarded-for': '192.168.0.1' res = new MyResponse facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER' class TestSwitch extends LeanRC::Switch @inheritProtected() @module Test @public routerName: String, { default: 'TEST_SWITCH_ROUTER' } @initialize() facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR' switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR' COLLECTION_NAME = 'TestEntitiesCollection' facade.registerProxy TestsCollection.new COLLECTION_NAME, delegate: 'TestRecord' # serializer: LeanRC::Serializer data: [] facade.registerMediator LeanRC::Mediator.new LeanRC::APPLICATION_MEDIATOR, context: {} collection = facade.retrieveProxy COLLECTION_NAME resource = TestResource.new() resource.initializeNotifier KEY context = Test::Context.new req, res, switchMediator context.query = query: '{"test":{"$eq":"test2"}}' yield collection.create test: 'test1' yield collection.create test: 'test2' yield collection.create test: 'test2' spySendNotitfication = sinon.spy resource, 'sendNotification' testBody = context: context reverse: 'TEST_REVERSE' notification = LeanRC::Notification.new 'TEST_NAME', testBody, 'list' yield resource.execute notification [ name, body, type ] = spySendNotitfication.lastCall.args assert.equal name, LeanRC::HANDLER_RESULT assert.isUndefined body.error, body.error {result, resource:voResource} = body { meta, items } = result assert.deepEqual meta, pagination: limit: 50 offset: 0 assert.deepEqual voResource, resource assert.lengthOf items, 3 assert.equal type, 'TEST_REVERSE' yield return describe '#checkApiVersion', -> facade = null afterEach -> facade?.remove?() it 'should check API version', -> co -> KEY = 'TEST_RESOURCE_001' facade = LeanRC::Facade.getInstance KEY class Test extends LeanRC @inheritProtected() @root "#{__dirname}/config/root" @initialize() configs = LeanRC::Configuration.new LeanRC::CONFIGURATION, Test::ROOT facade.registerProxy configs class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @action test: Function, default: -> @initialize() class TestRouter extends LeanRC::Router @inheritProtected() @module Test @initialize() class MyResponse extends EventEmitter _headers: {} getHeaders: -> LeanRC::Utils.copy @_headers getHeader: (field) -> @_headers[field.toLowerCase()] setHeader: (field, value) -> @_headers[field.toLowerCase()] = value removeHeader: (field) -> delete @_headers[field.toLowerCase()] end: (data, encoding = 'utf-8', callback = ->) -> @finished = yes @emit 'finish', data?.toString? encoding callback() constructor: (args...) -> super args... { @finished, @_headers } = finished: no, _headers: {} req = method: 'GET' url: 'http://localhost:8888/v/v2.0/test_entity/ID123456' headers: 'x-forwarded-for': '192.168.0.1' res = new MyResponse facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER' class TestSwitch extends LeanRC::Switch @inheritProtected() @module Test @public routerName: String, { default: 'TEST_SWITCH_ROUTER' } @initialize() facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR' switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR' resource = TestResource.new() resource.initializeNotifier KEY resource.context = Test::Context.new req, res, switchMediator try resource.context.pathParams = v: 'v1.0' test_entity: 'ID123456' yield resource.checkApiVersion() catch e assert.isDefined e try resource.context.pathParams = v: 'v2.0' test_entity: 'ID123456' yield resource.checkApiVersion() catch e assert.isDefined e yield return describe '#setOwnerId', -> it 'should get owner ID for body', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() Reflect.defineProperty resource, 'recordId', writable: yes value: undefined Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'session', writable: yes value: uid: 'ID123' ctx = { pathParams: test_entity: 'ID123456' request: body: test_entity: test: 'test9' } Reflect.defineProperty resource, 'context', writable: yes value: ctx # resource.session = uid: 'ID123' # resource.context = # pathParams: test_entity: 'ID123456' # request: body: test_entity: test: 'test9' resource.getRecordId() resource.getRecordBody() resource.beforeUpdate() yield resource.setOwnerId() assert.deepEqual resource.recordBody, test: 'test9' id: 'ID123456' ownerId: 'ID123' yield return describe '#protectOwnerId', -> it 'should omit owner ID from body', -> co -> class Test extends LeanRC @inheritProtected() @root __dirname @initialize() class TestResource extends LeanRC::Resource @inheritProtected() @module Test @public entityName: String, default: 'TestEntity' @initialize() resource = TestResource.new() Reflect.defineProperty resource, 'recordId', writable: yes value: undefined Reflect.defineProperty resource, 'recordBody', writable: yes value: undefined Reflect.defineProperty resource, 'session', writable: yes value: uid: 'ID123' ctx = { pathParams: test_entity: 'ID123456' request: body: test_entity: test: 'test9' } Reflect.defineProperty resource, 'context', writable: yes value: ctx # resource.session = uid: 'ID123' # resource.context = # pathParams: test_entity: 'ID123456' # request: body: test_entity: test: 'test9' resource.getRecordId() resource.getRecordBody() resource.beforeUpdate() yield resource.setOwnerId() assert.deepEqual resource.recordBody, test: 'test9' id: 'ID123456' ownerId: 'ID123' yield resource.protectOwnerId() assert.deepEqual resource.