"use strict";

var _tape = _interopRequireDefault(require("tape"));

var _reduxBundler = require("redux-bundler");

var _getOrgEventSourceBundle = _interopRequireDefault(require("./get-org-event-source-bundle"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

const CREATED = 'ORG_EVENT_SOURCE_CREATED';

const getStore = (stubs, bundles, eventSourceConstructor) => (0, _reduxBundler.composeBundlesRaw)((0, _getOrgEventSourceBundle.default)({
  apiUrl: 'https://dev.api.xchart.com',
  orgIdSelector: 'selectSessionOrgIds',
  eventSourceConstructor
}), _reduxBundler.appTimeBundle, _objectSpread({
  name: 'stubs',
  reducer: (state = 'full', {
    type,
    payload
  }) => {
    if (type === 'AUTH_STATE_SET') {
      return payload;
    }

    return state;
  },
  doUpdateAuthState: newState => ({
    type: 'AUTH_STATE_SET',
    payload: newState
  }),
  selectAuthStatus: state => state.stubs,
  selectIsFullyAuthenticated: state => state.stubs === 'full',
  selectHostname: () => 'xchart.com'
}, stubs), ...(bundles ? bundles : []))();

(0, _tape.default)('getOrgEventSourceBundle subscribes/unsubscribes based on authState', t => {
  const store = getStore({
    selectSessionOrgIds: () => ['cfd', 'other'],
    doCreateOrgEventSourceForId: orgId => ({
      dispatch
    }) => {
      dispatch({
        type: CREATED,
        payload: {
          id: orgId,
          eventSource: {
            orgId,
            close: () => {}
          }
        }
      });
    }
  });
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), {
    actionCreator: 'doCreateOrgEventSourceForId',
    args: ['cfd']
  });
  store.doCreateOrgEventSourceForId('cfd');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), {
    actionCreator: 'doCreateOrgEventSourceForId',
    args: ['other']
  });
  store.doCreateOrgEventSourceForId('other');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), undefined);
  store.doUpdateAuthState('none');
  t.deepEqual(store.selectAuthStatus(), 'none', 'auth status should now be "none"');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), {
    actionCreator: 'doRemoveOrgEventSourceForId',
    args: ['cfd']
  });
  store.doRemoveOrgEventSourceForId('cfd');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), {
    actionCreator: 'doRemoveOrgEventSourceForId',
    args: ['other']
  });
  store.doRemoveOrgEventSourceForId('other');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), undefined);
  t.end();
});
(0, _tape.default)('getOrgEventSourceBundle subscribes/unsubscribes based on orgs', t => {
  const closeCalledOn = [];
  const store = getStore({
    selectAuthStatus: () => 'full',
    doCreateOrgEventSourceForId: orgId => ({
      dispatch
    }) => {
      dispatch({
        type: CREATED,
        payload: {
          id: orgId,
          eventSource: {
            orgId,
            close: () => {
              closeCalledOn.push(orgId);
            }
          }
        }
      });
    }
  }, [{
    name: 'sessionOrgs',
    reducer: (state = ['cfd', 'other'], {
      type,
      payload
    }) => {
      if (type === 'UPDATE_SESSION_ORGS') {
        return payload;
      }

      return state;
    },
    doUpdateSessionOrgs: newState => ({
      type: 'UPDATE_SESSION_ORGS',
      payload: newState
    }),
    selectSessionOrgIds: state => state.sessionOrgs
  }]);
  store.doCreateOrgEventSourceForId('cfd');
  store.doCreateOrgEventSourceForId('other');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), undefined);
  store.doUpdateSessionOrgs(['cfd']);
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), {
    actionCreator: 'doRemoveOrgEventSourceForId',
    args: ['other']
  });
  store.doRemoveOrgEventSourceForId('other');
  t.deepEqual(closeCalledOn, ['other'], 'should have called close');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), undefined);
  t.end();
});
(0, _tape.default)('connected selector works', t => {
  class MockEventSource {
    constructor(url) {
      this.readyState = 0;
      this.cbs = {};
      this.orgId = url.split('/')[5];

      if (this.orgId === 'cfd') {
        t.equal(url, 'https://dev.api.xchart.com/fhir-sse/org/cfd');
      }

      if (this.orgId === 'other') {
        t.equal(url, 'https://dev.api.xchart.com/fhir-sse/org/other');
      }

      setTimeout(() => {
        this.open();
      }, 100);
    }

    addEventListener(eventName, cb) {
      this.eventListenerCount = this.eventListenerCount || 0;
      this.eventListenerCount++;

      if (!this.cbs[eventName]) {
        this.cbs[eventName] = [];
      }

      this.cbs[eventName].push(cb);

      if (this.eventListenerCount === 1) {
        t.equal(eventName, 'open');
      }

      if (this.eventListenerCount === 2) {
        t.equal(eventName, 'error');
      }

      if (this.eventListenerCount === 3) {
        t.equal(eventName, 'message');
      }
    }

    dispatchEvent(type, payload) {
      const cbs = this.cbs[type];

      if (cbs) {
        for (const cb of cbs) {
          cb(payload);
        }
      }
    }

    open() {
      this.readyState = 1;
      this.dispatchEvent('open');
    }

  }

  const store = getStore({
    selectAuthStatus: () => 'full',
    selectSessionOrgIds: () => ['cfd', 'other'],
    selectTabId: () => 'TAB',
    selectAuthToken: () => 'TOKEN'
  }, [{
    name: 'sessionOrgs',
    reducer: (state = ['cfd', 'other'], {
      type,
      payload
    }) => {
      if (type === 'UPDATE_SESSION_ORGS') {
        return payload;
      }

      return state;
    },
    doUpdateSessionOrgs: newState => ({
      type: 'UPDATE_SESSION_ORGS',
      payload: newState
    }),
    selectSessionOrgIds: state => state.sessionOrgs
  }], MockEventSource);
  store.doCreateOrgEventSourceForId('cfd');
  store.doCreateOrgEventSourceForId('other');
  t.deepEqual(store.reactShouldCreateRemoveOrgEventSource(), undefined);
  setTimeout(() => {
    t.equal(store.selectOrgEventSourceConnected(), true);
    t.end();
  }, 200);
});