import { List, Map } from 'immutable';

import { ParametersDefaultState, Parameter } from '../../js/immutableRecords/parameters';
import ParametersConstants from '../../js/constants/ParametersConstants';
import parametersReducer from '../../js/reducers/parametersReducer';

const parametersActionPayload = {
  mistralParameters: {
    parameter1: '1'
  },
  parameters: {
    parameter1: {
      default: '3PuRFRBdhHDD49Td4jHJYmD3n',
      type: 'String',
      noEcho: 'true',
      description: 'The password for the glance service and db account',
      label: 'GlancePassword',
      name: 'GlancePassword'
    }
  },
  resources: {
    '1d0e0c81-2dc6-4b39-a9a7-9ef4fab65ecf': {
      nestedParameters: [
        'd1f30e6b-c835-49d8-a21e-2983bde15bab'
      ],
      type: 'OS::TripleO::Services::HeatEngine',
      description: 'Openstack Heat Engine service configured with Puppet\n',
      parameters: [
        'DefaultPasswords',
        'HeatWorkers',
        'ServiceNetMap',
        'HeatAuthEncryptionKey',
        'HeatEngineLoggingSource',
        'EndpointMap',
        'HeatEnableDBPurge',
        'HeatStackDomainAdminPassword',
        'HeatPassword',
        'MonitoringSubscriptionHeatEngine'
      ],
      name: '16',
      id: '1d0e0c81-2dc6-4b39-a9a7-9ef4fab65ecf'
    }
  }
};

describe('parametersReducer', () => {
  describe('FETCH_PARAMETERS_PENDING', () => {
    let state;
    const action = {
      type: ParametersConstants.FETCH_PARAMETERS_PENDING
    };

    beforeEach(() => {
      state = parametersReducer(ParametersDefaultState({
        isFetching: false,
        form: Map({ formErrors: List.of('lorem ipsum'), formFieldErrors: Map({ field: 'foo' })})
      }), action);
    });

    it('sets isFetching to `true`', () => {
      expect(state.isFetching).toBe(true);
    });

    it('resets form', () => {
      expect(state.form).toEqual(Map({
        formErrors: List(),
        formFieldErrors: Map()
      }));
    });
  });

  describe('FETCH_PARAMETERS_SUCCESS', () => {
    let state;
    const action = {
      type: ParametersConstants.FETCH_PARAMETERS_SUCCESS,
      payload: parametersActionPayload
    };

    beforeEach(() => {
      state = parametersReducer(ParametersDefaultState({
        isFetching: true,
        form: Map({ some: 'value' })
      }), action);
    });

    it('sets isFetching to `false`', () => {
      expect(state.isFetching).toBe(false);
    });

    it('resets form', () => {
      expect(state.form).toEqual(Map({
        formErrors: List(),
        formFieldErrors: Map()
      }));
    });

    it('sets parameters', () => {
      expect(state.parameters.size).toEqual(1);
      expect(state.parameters.getIn(['parameter1', 'default']))
        .toEqual('3PuRFRBdhHDD49Td4jHJYmD3n');
      expect(Map.isMap(state.parameters)).toBe(true);
    });

    it('sets resources', () => {
      expect(state.resources.size).toEqual(1);
      expect(state.resources.getIn(['1d0e0c81-2dc6-4b39-a9a7-9ef4fab65ecf', 'parameters']).size)
        .toEqual(10);
      expect(Map.isMap(state.resources)).toBe(true);
    });
  });

  describe('UPDATE_PARAMETERS_FAILED', () => {
    let state;
    const action = {
      type: ParametersConstants.UPDATE_PARAMETERS_FAILED,
      payload: {
        formErrors: [{ foo: 'bar' }],
        formFieldErrors: { field1: 'fail' }
      }
    };

    beforeEach(() => {
      state = parametersReducer(ParametersDefaultState({
        isFetching: true
      }), action);
    });

    it('sets `isFetching` to false', () => {
      expect(state.isFetching).toBe(false);
    });

    it('sets errors in  `form`', () => {
      expect(state.form).toEqual(Map({
        formErrors: List.of({ foo: 'bar' }),
        formFieldErrors: Map({ field1: 'fail' })
      }));
    });
  });

  describe('UPDATE_PARAMETERS_PENDING', () => {
    let state;
    const action = {
      type: ParametersConstants.UPDATE_PARAMETERS_PENDING
    };

    beforeEach(() => {
      state = parametersReducer(ParametersDefaultState({
        isFetching: false
      }), action);
    });

    it('sets `isFetching` to true', () => {
      expect(state.isFetching).toBe(true);
    });
  });

  describe('UPDATE_PARAMETERS_SUCCESS', () => {
    let state;
    const action = {
      type: ParametersConstants.UPDATE_PARAMETERS_SUCCESS,
      payload: { foo: 'bar' }
    };

    beforeEach(() => {
      state = parametersReducer(ParametersDefaultState({
        isFetching: true,
        form: Map({ some: 'value' }),
        parameters: Map({
          foo: new Parameter({
            name: 'foo'
          })
        })
      }), action);
    });

    it('sets isFetching to `false`', () => {
      expect(state.isFetching).toBe(false);
    });

    it('resets form', () => {
      expect(state.form).toEqual(Map({
        formErrors: List(),
        formFieldErrors: Map()
      }));
    });

    it('updates parameters in state with new values', () => {
      expect(state.parameters.get('foo').default).toEqual('bar');
    });
  });
});
