'use strict';

var _interopRequire = function (obj) { return obj && obj.__esModule ? obj['default'] : obj; };

var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };

var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };

var _connectToStores = require('../connectToStores');

var connectToStores = _interopRequire(_connectToStores);

var _addContext = require('./addContext');

var addContext = _interopRequire(_addContext);

var _Actions$Store$Flummox = require('../../Flux');

var _React = require('react/addons');

var React = _interopRequire(_React);

var PropTypes = React.PropTypes;
var TestUtils = React.addons.TestUtils;

var TestActions = (function (_Actions) {
  function TestActions() {
    _classCallCheck(this, TestActions);

    if (_Actions != null) {
      _Actions.apply(this, arguments);
    }
  }

  _inherits(TestActions, _Actions);

  TestActions.prototype.getSomething = function getSomething(something) {
    return something;
  };

  return TestActions;
})(_Actions$Store$Flummox.Actions);

var TestStore = (function (_Store) {
  function TestStore(flux) {
    _classCallCheck(this, TestStore);

    _Store.call(this);

    var testActions = flux.getActions('test');
    this.register(testActions.getSomething, this.handleGetSomething);

    this.state = {
      something: null
    };
  }

  _inherits(TestStore, _Store);

  TestStore.prototype.handleGetSomething = function handleGetSomething(something) {
    this.setState({ something: something });
  };

  return TestStore;
})(_Actions$Store$Flummox.Store);

var Flux = (function (_Flummox) {
  function Flux() {
    _classCallCheck(this, Flux);

    _Flummox.call(this);

    this.createActions('test', TestActions);
    this.createStore('test', TestStore, this);
  }

  _inherits(Flux, _Flummox);

  return Flux;
})(_Actions$Store$Flummox.Flummox);

describe('connectToStores (HoC)', function () {
  it('gets Flux from either props or context', function () {
    var flux = new Flux();
    var contextComponent = undefined,
        propsComponent = undefined;

    var BaseComponent = (function (_React$Component) {
      function BaseComponent() {
        _classCallCheck(this, BaseComponent);

        if (_React$Component != null) {
          _React$Component.apply(this, arguments);
        }
      }

      _inherits(BaseComponent, _React$Component);

      BaseComponent.prototype.render = function render() {
        return React.createElement('div', null);
      };

      return BaseComponent;
    })(React.Component);

    var ConnectedComponent = connectToStores(BaseComponent, 'test');

    var ContextComponent = addContext(ConnectedComponent, { flux: flux }, { flux: React.PropTypes.instanceOf(_Actions$Store$Flummox.Flummox) });

    var tree = TestUtils.renderIntoDocument(React.createElement(ContextComponent, null));

    contextComponent = TestUtils.findRenderedComponentWithType(tree, ConnectedComponent);

    propsComponent = TestUtils.renderIntoDocument(React.createElement(ConnectedComponent, { flux: flux }));

    expect(contextComponent.flux).to.be.an['instanceof'](_Actions$Store$Flummox.Flummox);
    expect(propsComponent.flux).to.be.an['instanceof'](_Actions$Store$Flummox.Flummox);
  });

  it('transfers props', function () {
    var flux = new Flux();

    var BaseComponent = (function (_React$Component2) {
      function BaseComponent() {
        _classCallCheck(this, BaseComponent);

        if (_React$Component2 != null) {
          _React$Component2.apply(this, arguments);
        }
      }

      _inherits(BaseComponent, _React$Component2);

      BaseComponent.prototype.render = function render() {
        return React.createElement('div', null);
      };

      return BaseComponent;
    })(React.Component);

    var ConnectedComponent = connectToStores(BaseComponent, 'test');

    var tree = TestUtils.renderIntoDocument(React.createElement(ConnectedComponent, { flux: flux, foo: 'bar', bar: 'baz' }));

    var component = TestUtils.findRenderedComponentWithType(tree, BaseComponent);

    expect(component.props.foo).to.equal('bar');
    expect(component.props.bar).to.equal('baz');
  });

  it('syncs with store after state change', function () {
    var flux = new Flux();

    var BaseComponent = (function (_React$Component3) {
      function BaseComponent() {
        _classCallCheck(this, BaseComponent);

        if (_React$Component3 != null) {
          _React$Component3.apply(this, arguments);
        }
      }

      _inherits(BaseComponent, _React$Component3);

      BaseComponent.prototype.render = function render() {
        return React.createElement('div', null);
      };

      return BaseComponent;
    })(React.Component);

    var ConnectedComponent = connectToStores(BaseComponent, 'test');

    var tree = TestUtils.renderIntoDocument(React.createElement(ConnectedComponent, { flux: flux }));

    var component = TestUtils.findRenderedComponentWithType(tree, BaseComponent);

    var getSomething = flux.getActions('test').getSomething;

    expect(component.props.something).to.be['null'];

    getSomething('do');

    expect(component.props.something).to.equal('do');

    getSomething('re');

    expect(component.props.something).to.equal('re');
  });
});