
import chai from 'chai'
import sinon from 'sinon'
import sinonChai from 'sinon-chai'
import Repository from '../src/repository'
import Model from '../src/model'

chai.use(sinonChai)

const { expect } = chai

describe('Repository', () => {

  let api

  beforeEach(() => {
    const actions = [ 'read', 'replace', 'create', 'update', 'destroy' ]
    api = actions.reduce((api, method) => {
      return Object.assign(api, { [method]: sinon.stub() })
    }, {})
  })

  describe('create(data)', () => {

    let repository, SpyModel

    beforeEach(() => {
      SpyModel = sinon.spy()
      class TestRepository extends Repository {
        constructor(api) { super(api) }
        get Model() { return SpyModel }
      }
      repository = new TestRepository(api)
    })

    context('when (data) is not an Array', () => {
      it('instantiates the base Model with (data)', () => {
        const data = {}
        const model = repository.create(data)
        expect(SpyModel).to.have.been.calledWithExactly(data)
        expect(model).to.be.instanceOf(SpyModel)
      })
    })

    context('when (data) is an array', () => {
      it('instantiates an array of base models', () => {
        const data = [{}, {}]
        const models = repository.create(data)
        expect(models).to.be.instanceOf(Array)
        models.forEach(model => {
          expect(model).to.be.instanceOf(SpyModel)
        })
      })
    })

  })


  describe('sync(action, path, payload, query)', () => {

    let repository

    beforeEach(() => repository = new Repository(api, Model))

    it('calls (action) on #api with (...args)', () => {
      api.read.returns(Promise.resolve())
      const args = ['test', {}, {}]
      return repository.sync('read', ...args)
        .then(() => {
          expect(api.read).to.have.been.calledWithExactly('test', {}, {})
        })
    })

  })

  describe('serialize(model)', () => {

    it('returns (model)#data', () => {
      class TestRepository extends Repository {
        constructor(api) {
          super(api)
        }
        get Model() { return Model }
      }
      const repository = new TestRepository(api)
      const model = repository.create()
      const data = repository.serialize(model)
      expect(data).to.deep.equal(model.data)
    })

  })

})

@@ -262,24 +262,37 @@
 ach(() =%3E %7B%0A
+    api = %7B%7D%0A
     const ac
@@ -355,22 +355,16 @@
 y' %5D%0A   
- api =
  actions
@@ -368,103 +368,52 @@
 ons.
-reduce((api, method) =%3E %7B%0A      return Object.assign(api, %7B %5Bmethod%5D: sinon.stub() %7D)%0A    %7D, %7B%7D
+forEach(action =%3E api%5Baction%5D = sinon.stub()
 )%0A  
@@ -1973,26 +1973,16 @@
 r(api) %7B
-%0A         
  super(a
@@ -1984,24 +1984,16 @@
 per(api)
-%0A       
  %7D%0A     

Update repository.test.js