 
 
 
-    it "should provide some typical http-operations", (done) ->
+    it "should detect when an filter matches no objects on getOne", (done) ->
+      api = manikin.create()
+
+      model =
+        table:
+          fields:
+            v1: 'string'
+
+      promise(api).connect(connectionData, model, noErr())
+      .getOne('table', { filter: { v1: '123' } }, (err, data) ->
+        err.should.eql new Error()
+        err.toString().should.eql 'Error: No match'
+        should.not.exist data
+      ).then ->
+        api.close(done)
+
+
+    it "should detect when an filter matches no objects on delOne", (done) ->
+      api = manikin.create()
+
+      model =
+        table:
+          fields:
+            v1: 'string'
+
+      promise(api).connect(connectionData, model, noErr())
+      .delOne('table', { v1: '123' }, (err, data) ->
+        err.should.eql new Error()
+        err.toString().should.eql 'Error: No such id'
+        should.not.exist data
+      ).then ->
+        api.close(done)
+
+
+
+    it "should be possible to specifiy the owner together with the fields when creating an object", (done) ->
       api = manikin.create()
 
       model =




    it "should raise an error if a putOne attempts to put non-existing fields", (done) ->
      api = manikin.create()

      model =
        accounts:
          fields:
            name: { type: 'string', default: '' }

      api.connect connectionData, model, noErr ->
        api.post 'accounts', { name: 'a1' }, noErr (account) ->
          api.putOne 'accounts', { name: 'n1', age: 10, desc: 'test' }, { id: account.id }, (err, data) ->
            err.should.eql new Error()
            err.toString().should.eql 'Error: Invalid fields: age, desc'
            api.close(done)



    it "should raise an error if a putOne attempts to put using an id from another collection", (done) ->
      api = manikin.create()

      model =
        accounts:
          fields:
            name: { type: 'string', default: '' }
        other:
          fields:
            name: { type: 'string', default: '' }

      api.connect connectionData, model, noErr ->
        api.post 'other', { name: 'a1' }, noErr (other) ->
          api.post 'accounts', { name: 'a1' }, noErr (account) ->
            api.putOne 'accounts', { name: 'n1' }, { id: other.id }, (err, data) ->
              err.should.eql new Error()
              err.toString().should.eql 'Error: No such id'
              api.close(done)



    it "should raise an error if a putOne attempts to put using an id from another collection", (done) ->
      api = manikin.create()

      model =
        accounts:
          fields:
            name: { type: 'string', default: '' }

      api.connect connectionData, model, noErr ->
        api.post 'accounts', { name: 'a1' }, noErr (account) ->
          api.putOne 'accounts', { name: 'n1' }, { id: 1 }, (err, data) ->
            err.should.eql new Error()
            err.toString().should.eql 'Error: No such id'
            api.close(done)



    it "should allow undefined values", (done) ->
      api = manikin.create()

      model =
        pizzas:
          owners: {}
          fields:
            name:
              type: 'string'

      api.connect connectionData, model, noErr ->
        api.post 'pizzas', { name: 'jakob' }, noErr (res) ->
          api.putOne 'pizzas', { name: undefined }, { id: res.id }, noErr (res) ->
            should.not.exist res.name
            api.close(done)



    it "should allow custom validators", (done) ->
      api = manikin.create()

      model =
        pizzas:
          owners: {}
          fields:
            name:
              type: 'string'
              validate: (apiRef, value, callback) ->
                api.should.eql apiRef
                callback(value.length % 2 == 0)

      indata = [
        name: 'jakob'
        response: 'something wrong'
      ,
        name: 'tobias'
        response: null
      ]

      api.connect connectionData, model, noErr ->
        async.forEach indata, (d, callback) ->
          api.post 'pizzas', { name: d.name }, (err, res) ->
            if d.response != null
              err.message.should.eql 'Validation failed'
              err.errors.name.path.should.eql 'name'
            callback()
        , ->
          api.close(done)




      .list('companies2', {}, noErr ((res) -> res.length.should.eql 2))
      .list('accounts', {}, noErr ((res) -> res.length.should.eql 1))

      .then -> api.close(done)



    it "should delete owned objects when deleting ancestors", (done) ->
       api = manikin.create()

       model =
         accounts:
           owners: {}
           fields:
             name: { type: 'string', default: '' }

         companies2:
           owners:
             account: 'accounts'
           fields:
             name: { type: 'string', default: '' }
             orgnr: { type: 'string', default: '' }

         contacts:
           owners:
             company: 'companies2'
           fields:
             email: { type: 'string', default: '' }
             phone: { type: 'string', default: '' }

         pets:
           owners:
             contact: 'contacts'
           fields:
             race: { type: 'string', default: '' }

       saved = {}

       promise(api).connect(connectionData, model, noErr())
       .post('accounts', { name: 'a1', bullshit: 123 }, noErr (account) ->
         saved.account = account
       ).then('post', -> @ 'companies2', { name: 'n', orgnr: 'nbr', account: saved.account.id }, noErr (company) ->
         saved.company = company
       ).then('post', -> @ 'companies2', { name: 'n2', orgnr: 'nbr', account: saved.account.id }, noErr (company2) ->
         saved.company2 = company2
       ).then('post', -> @ 'contacts', { email: '@', phone: '112', company: saved.company.id }, noErr (contact) ->
         saved.contact = contact
       ).then('post', -> @ 'contacts', { email: '@2', phone: '911', company: saved.company2.id }, noErr (contact2) ->
         saved.contact2 = contact2
       ).then('post', -> @ 'pets', { race: 'dog', contact: saved.contact.id }, noErr (pet) ->
       ).then('post', -> @ 'pets', { race: 'dog', contact: saved.contact2.id }, noErr (pet) ->
       ).list('pets', {}, noErr ((res) -> res.length.should.eql 2))
       .list('contacts', {}, noErr ((res) -> res.length.should.eql 2))
       .list('companies2', {}, noErr ((res) -> res.length.should.eql 2))
       .list('accounts', {}, noErr ((res) -> res.length.should.eql 1))
       .then('delOne', -> @ 'companies2', { id: saved.company.id }, noErr())
       .list('pets', {}, noErr ((res) -> res.length.should.eql 1))
       .list('contacts', {}, noErr ((res) -> res.length.should.eql 1))
       .list('companies2', {}, noErr ((res) -> res.length.should.eql 1))
       .list('accounts', {}, noErr ((res) -> res.length.should.eql 1))
       .then -> api.close(done)



    it "should raise an error if a putOne attempts to put using an id from another collection", (done) ->
      api = manikin.create()

      model =
        accounts:
          fields:
            name: { type: 'string', default: '' }

      api.connect connectionData, model, noErr ->
        api.post 'accounts', { name: 'a1' }, noErr (account) ->
          api.putOne 'accounts', { name: 'n1' }, { id: 1 }, (err, data) ->
            err.should.eql new Error()
            err.toString().should.eql 'Error: No such id'
            api.close(done)



    it "should allow undefined values", (done) ->
      api = manikin.create()

      model =
        pizzas:
          owners: {}
          fields:
            name:
              type: 'string'

      api.connect connectionData, model, noErr ->
        api.post 'pizzas', { name: 'jakob' }, noErr (res) ->
          api.putOne 'pizzas', { name: undefined }, { id: res.id }, noErr (res) ->
            should.not.exist res.name
            api.close(done)



    it "should allow custom validators", (done) ->
      api = manikin.create()

      model =
        pizzas:
          owners: {}
          fields:
            name:
              type: 'string'
              validate: (apiRef, value, callback) ->
                api.should.eql apiRef
                callback(value.length % 2 == 0)

      indata = [
        name: 'jakob'
        response: 'something wrong'
      ,
        name: 'tobias'
        response: null
      ]

      api.connect connectionData, model, noErr ->
        async.forEach indata, (d, callback) ->
          api.post 'pizzas', { name: d.name }, (err, res) ->
            if d.response != null
              err.message.should.eql 'Validation failed'
              err.errors.name.path.should.eql 'name'
            callback()
        , ->
          api.close(done)
































    it "should delete many-to-many-relations when objects are deleted", (done) ->
      api = manikin.create()

      model =
        petsY:
          fields:
            name: 'string'

        foodsY:
          fields:
            name: 'string'
            eatenBy: { type: 'hasMany', model: 'petsY', inverseName: 'eats' }

      saved = {}

      promise(api).connect(connectionData, model, noErr())
      .then('post', -> @('petsY', { name: 'pet1' }, noErr (res) -> saved.pet1 = res))
      .then('post', -> @('foodsY', { name: 'food1' }, noErr (res) -> saved.food1 = res))
      .then('postMany', -> @('foodsY', saved.food1.id, 'eatenBy', saved.pet1.id, noErr()))
      .then('getMany', -> @('petsY', saved.pet1.id, 'eats', noErr((data) -> data.length.should.eql 1)))
      .then('delOne', -> @('petsY', { id: saved.pet1.id }, noErr()))
      .then('list', -> @('petsY', { }, noErr((data) -> data.length.should.eql 0)))
      .then('list', -> @('foodsY', { }, noErr (data) -> data.should.eql [
        id: saved.food1.id
        name: 'food1'
        eatenBy: []
      ]))
      .then -> api.close(done)



    it "should be possible to query many-to-many-relationships", (done) ->
      api = manikin.create()

      model =
        people:
          owners: {}
          fields:
            name: { type: 'string', default: '' }
            boundDevices: { type: 'hasMany', model: 'devices', inverseName: 'boundPeople' }

        devices:
          owners: {}
          fields:
            name: { type: 'string', default: '' }

      saved = {}

      promise(api).connect(connectionData, model, noErr())
      .post('people', { name: 'q1' }, noErr (q1) ->
        saved.q1 = q1
      ).post('people', { name: 'q2' }, noErr (q2) ->
        saved.q2 = q2
      ).post('devices', { name: 'd1' }, noErr (d1) ->
        saved.d1 = d1
      ).post('devices', { name: 'd2' }, noErr (d2) ->
        saved.d2 = d2
      ).then 'postMany', -> @('people',  saved.q1.id, 'boundDevices', saved.d1.id, noErr())
      .then 'postMany', -> @('people',  saved.q1.id, 'boundDevices', saved.d2.id, noErr())
      .then 'getMany',  -> @('people',  saved.q1.id, 'boundDevices', noErr((data) -> data.length.should.eql 2))
      .then 'getMany',  -> @('people',  saved.q1.id, 'boundDevices', { name: 'd1' }, noErr((data) -> data.length.should.eql 1))
      .then 'getMany',  -> @('people',  saved.q1.id, 'boundDevices', { name: 'd2' }, noErr((data) -> data.length.should.eql 1))
      .then 'getMany',  -> @('people',  saved.q1.id, 'boundDevices', { name: 'd3' }, noErr((data) -> data.length.should.eql 0))
      .then 'getMany',  -> @('people',  saved.q2.id, 'boundDevices', noErr((data) -> data.length.should.eql 0))
      .then 'getMany',  -> @('devices', saved.d1.id, 'boundPeople',  noErr((data) -> data.length.should.eql 1))
      .then 'getMany',  -> @('devices', saved.d2.id, 'boundPeople',  noErr((data) -> data.length.should.eql 1))
      .then 'delMany',  -> @('people',  saved.q1.id, 'boundDevices', saved.d1.id, noErr())
      .then 'getMany',  -> @('people',  saved.q1.id, 'boundDevices', noErr((data) -> data.length.should.eql 1))
      .then 'getMany',  -> @('people',  saved.q2.id, 'boundDevices', noErr((data) -> data.length.should.eql 0))
      .then 'getMany',  -> @('devices', saved.d1.id, 'boundPeople',  noErr((data) -> data.length.should.eql 0))
      .then 'getMany',  -> @('devices', saved.d2.id, 'boundPeople',  noErr((data) -> data.length.should.eql 1))

      .then -> api.close(done)




    it "should delete many-to-many-relations even when owners of the related objects are deleted", (done) ->
      api = manikin.create()

      model =
        peopleX:
          fields:
            name: 'string'

        petsX:
          owners: { person: 'peopleX' }
          fields:
            name: 'string'

        foodsX:
          owners: {}
          fields:
            name: 'string'
            eatenBy: { type: 'hasMany', model: 'petsX', inverseName: 'eats' }

      saved = {}

      promise(api).connect(connectionData, model, noErr())
      .post('peopleX', { name: 'p1' }, noErr (res) ->
        saved.person = res
      ).then 'post', -> @('petsX', { person: saved.person.id, name: 'pet1' }, noErr (res) -> saved.pet1 = res)
      .then 'post', -> @('foodsX', { name: 'food1' }, noErr (res) -> saved.food1 = res)
      .then 'postMany', -> @('foodsX',  saved.food1.id, 'eatenBy', saved.pet1.id, noErr())
      .then 'getMany',  -> @('petsX', saved.pet1.id, 'eats', noErr((data) -> data.length.should.eql 1))
      .then 'delOne',  -> @('peopleX', { id: saved.person.id }, noErr())
      .then 'list',  -> @('peopleX', { }, noErr((data) -> data.length.should.eql 0))
      .then 'list',  -> @('petsX', { }, noErr((data) -> data.length.should.eql 0))
      .then 'list',  -> @('foodsX', { }, noErr (data) -> data.should.eql [
        id: saved.food1.id
        name: 'food1'
        eatenBy: []
      ])
      .then -> api.close(done)



    it "should prevent duplicate many-to-many values, even when data is posted in parallel", (done) ->
      api = manikin.create()

      model =
        typeA:
          fields:
            name: 'string'

        typeB:
          fields:
            name: 'string'
            belongsTo: { type: 'hasMany', model: 'typeA', inverseName: 'belongsTo2' }

      saved = {}
      resultStatuses = {}

      api.connect connectionData, model, noErr ->
        api.post 'typeA', { name: 'a1' }, noErr (a1) ->
          api.post 'typeB', { name: 'b1' }, noErr (b1) ->
            async.forEach [1,2,3], (item, callback) ->
              api.postMany 'typeB', b1.id, 'belongsTo', a1.id, noErr (result) ->
                resultStatuses[result.status] = resultStatuses[result.status] || 0
                resultStatuses[result.status]++
                callback()
            , ->
              resultStatuses['inserted'].should.eql 1
              resultStatuses['insert already in progress'].should.eql 2
              api.list 'typeA', {}, noErr (x) ->
                x[0].belongsTo2.length.should.eql 1
                api.close(done)



    it "should prevent duplicate many-to-many values, even when data is posted in parallel, to both end-points", (done) ->
      api = manikin.create()

      model =
        typeC:
          fields:
            name: 'string'

        typeD:
          fields:
            name: 'string'
            belongsTo: { type: 'hasMany', model: 'typeC', inverseName: 'belongsTo2' }

      saved = {}
      resultStatuses = {}

      api.connect connectionData, model, noErr ->
        api.post 'typeC', { name: 'c1' }, noErr (c1) ->
          api.post 'typeD', { name: 'd1' }, noErr (d1) ->
            async.forEach [['typeC', c1.id, 'belongsTo2', d1.id], ['typeD', d1.id, 'belongsTo', c1.id]], (item, callback) ->
              f = noErr (result) ->
                resultStatuses[result.status] = resultStatuses[result.status] || 0
                resultStatuses[result.status]++
                callback()
              api.postMany.apply(api, item.concat([f]))
            , ->
              resultStatuses['inserted'].should.eql 1
              resultStatuses['insert already in progress'].should.eql 1
              api.list 'typeC', {}, noErr (x) ->
                x[0].belongsTo2.length.should.eql 1
                api.close(done)



    it "should raise an error on posts to invalid many to many-properties", (done) ->
      api = manikin.create()

      model =
        typeA:
          fields:
            name: 'string'

        typeB:
          fields:
            name: 'string'
            belongsTo: { type: 'hasMany', model: 'typeA' }

      saved = {}
      api.connect connectionData, model, noErr ->
        api.post 'typeA', { name: 'a' }, noErr (a) ->
          api.post 'typeB', { name: 'b' }, noErr (b) ->
            api.postMany 'typeA', a.id, 'relation-that-does-not-exist', b.id, (err) ->
              err.should.eql new Error()
              err.toString().should.eql 'Error: Invalid many-to-many property'
              api.close(done)



    it "should raise an error on deletes to invalid many to many-properties", (done) ->
      api = manikin.create()

      model =
        typeA:
          fields:
            name: 'string'

        typeB:
          fields:
            name: 'string'
            belongsTo: { type: 'hasMany', model: 'typeA' }

      saved = {}
      api.connect connectionData, model, noErr ->
        api.post 'typeA', { name: 'a' }, noErr (a) ->
          api.post 'typeB', { name: 'b' }, noErr (b) ->
            api.delMany 'typeA', a.id, 'relation-that-does-not-exist', b.id, (err) ->
              err.should.eql new Error()
              err.toString().should.eql 'Error: Invalid many-to-many property'
              api.close(done)



    it "should raise an error if a putOne attempts to put non-existing fields", (done) ->
      api = manikin.create()

      model =
        accounts:
          fields:
            name: { type: 'string', default: '' }

      api.connect connectionData, model, noErr ->
        api.post 'accounts', { name: 'a1' }, noErr (account) ->
          api.putOne 'accounts', { name: 'n1', age: 10, desc: 'test' }, { id: account.id }, (err, data) ->
            err.should.eql new Error()
            err.toString().should.eql 'Error: Invalid fields: age, desc'
            api.close(done)



    it "should raise an error if a putOne attempts to put using an id from another collection", (done) ->
      api = manikin.create()

      model =
        accounts:
          fields:
            name: { type: 'string', default: '' }
        other:
          fields:
            name: { type: 'string', default: '' }

      api.connect connectionData, model, noErr ->
        api.post 'other', { name: 'a1' }, noErr (other) ->
          api.post 'accounts', { name: 'a1' }, noErr (account) ->
            api.putOne 'accounts', { name: 'n1' }, { id: other.id }, (err, data) ->
              err.should.eql new Error()
              err.toString().should.eql 'Error: No such id'
              api.close(done)



    it "should provide has-one-relations", (done) ->
