import should from 'should/as-function';
import Syncano from '../../src/syncano';
import {suffix, credentials, createCleaner } from './utils';
import _ from 'lodash';

describe('BatchManager', function() {
  this.timeout(15000);

  const cleaner = createCleaner();
  let connection = null;
  let Class = null;
  let Model = null;
  let Objects = null;
  let Instance = null;
  let Manager = null;
  const instanceName = suffix.get('name');
  const className = suffix.get('class');
  const classData = {
    name: className,
    instanceName,
    schema: [
      { name: 'name', type: 'string'}
    ]
  };

  before(function() {
    connection = Syncano(credentials.getCredentials());
    Instance = connection.Instance;
    Class = connection.Class;
    Model = connection.DataObject;
    Manager = connection.BatchManager({instanceName});

    Objects = _.map(_.range(10), (int) => {
      return { object: Model({ name: `name-${int}`, instanceName, className, id: int+1 }), action: 'create' }
    });

    return Instance.please().create({name: instanceName}).then(() => {
      return Class.please().create(classData);
    });
  });

  after(function() {
    return Instance.please().delete({name: instanceName});
  });

  afterEach(function() {
    Manager.removeObjects();
    return cleaner.clean();
  });

  it('should validate objects added via the #addObjects() method', function() {
    should(() => {
      Manager.addObjects({ something: 'thing' })
    }).throw(/properly formatted object models/);
  });

  it('should validate objects added via the #addSingleObject() method', function() {
    should(() => {
      Manager.addSingleObject({ something: 'thing' }, 'save');
    }).throw(/not a valid model/);
  });

  it('should be able to batch create objects', function() {
    return Manager.addObjects(Objects).batch()
      .then((objects) => {
        should(objects).be.an.Array().with.length(10);
      })
   });

  it('should be able to batch update objects', function() {
   const updateObjects = _.map(_.take(Objects, 2), (obj) => {
     return _.assign({}, obj, { object: Model({instanceName, className, id: obj.object.id, name: 'new_name'}), action: 'update'})
   });
   return new Promise((resolve) => {
     setInterval(() => resolve(), 1000);
   })
   .then(() => {
     return Manager.addObjects(updateObjects).batch()
   })
   .then(() => {
     return Model.please().list({instanceName, className}).pageSize(2);
   })
   .then((objects) => {
     should(objects).be.an.Array().with.length(2);
     should(objects[0]).have.property('name').which.is.String().equal('new_name');
     should(objects[1]).have.property('name').which.is.String().equal('new_name');
   })
  });

  it('should be able to batch different actions', function() {
    const mixedObjects = [
      { object: Objects[0].object, action: 'delete'},
      { object: Model({ instanceName, className, name: 'new_name2', id: 2}), action: 'update'},
      { object: Model({ name: 'created_object', instanceName, className}), action: 'create' }
    ]
    return new Promise((resolve) => {
      setInterval(() => resolve(), 1000);
    })
    .then(() => {
      return Manager.addObjects(mixedObjects).batch()
    })
    .then(() => {
      return Model.please().list({instanceName, className});
    })
    .then((objects) => {
      should(objects).be.an.Array().with.length(10);
      should(objects[0]).have.property('name').which.is.String().equal('new_name2');
      should(objects[9]).have.property('name').which.is.String().equal('created_object');
    })
  });

  it('should be able to batch delete objects', function() {
    const removeObjects = _.map(Objects, (obj) => {
      return _.assign({}, obj, { action: 'delete'})
    })
    .concat({ object: Model({ name: 'created_object', instanceName, className, id: 11}), action: 'delete' })
    return new Promise((resolve) => {
      setInterval(() => resolve(), 1000);
    })
    .then(() => {
      return Manager.addObjects(removeObjects).batch()
    })
    .then(() => {
      return Model.please().list({instanceName, className});
    })
    .then((objects) => {
      should(objects).be.an.Array().with.length(0);
    })
  });
});

@@ -1989,16 +1989,17 @@
 () %7B%0A   
+ 
 const up
@@ -2045,24 +2045,25 @@
  (obj) =%3E %7B%0A
+ 
      return 
@@ -2183,20 +2183,22 @@
 e'%7D)%0A   
+ 
 %7D);%0A
+ 
    retur
@@ -2222,24 +2222,25 @@
 solve) =%3E %7B%0A
+ 
      setInte
@@ -2267,27 +2267,29 @@
 , 1000);%0A   
+ 
 %7D)%0A
+ 
    .then(() 
@@ -2285,32 +2285,33 @@
   .then(() =%3E %7B%0A
+ 
      return Mana
@@ -2348,16 +2348,17 @@
 batch()%0A
+ 
    %7D)%0A  
@@ -2354,24 +2354,25 @@
 )%0A    %7D)%0A   
+ 
 .then(() =%3E 
@@ -2369,24 +2369,25 @@
 hen(() =%3E %7B%0A
+ 
      return 
@@ -2449,19 +2449,21 @@
 (2);%0A   
+ 
 %7D)%0A
+ 
    .then
@@ -2479,24 +2479,25 @@
 ) =%3E %7B%0A     
+ 
 should(objec
@@ -2526,24 +2526,25 @@
 .length(2);%0A
+ 
      should(
@@ -2615,24 +2615,25 @@
 ame');%0A     
+ 
 should(objec
@@ -2698,16 +2698,17 @@
 name');%0A
+ 
    %7D)%0A  

Test indents