/**
 * © OpenCORD
 *
 * Created by teone on 5/25/16.
 */

(function () {
  'use strict';

  describe('The xos.helper module', function(){

    describe('The xosField component', () => {
      let element, scope, isolatedScope, rootScope, compile;
      const compileElement = (el) => {
        element = el;

        if(!scope){
          scope = rootScope.$new();
        }
        if(angular.isUndefined(element)){
          element = angular.element('<xos-field name="name" field="field" ng-model="ngModel"></xos-field>');
        }
        compile(element)(scope);
        scope.$digest();
        isolatedScope = element.isolateScope().vm;
      };

      beforeEach(module('xos.helpers'));

      beforeEach(inject(function ($compile, $rootScope) {
        compile = $compile;
        rootScope = $rootScope;
      }));

      it('should throw an error if no name is passed', inject(($compile, $rootScope) => {
        function errorFunctionWrapper(){
          // setup the parent scope
          scope = $rootScope.$new();
          scope.field = {
            label: 'Label',
            type: 'number',
            validators: {}
          };
          scope.ngModel = 1;
          compileElement();
        }
        expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide a field name'));
      }));

      it('should throw an error if no field definition is passed', inject(($compile, $rootScope) => {
        function errorFunctionWrapper(){
          // setup the parent scope
          scope = $rootScope.$new();
          scope.name = 'label';
          scope.ngModel = 1;
          compileElement();
        }
        expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide a field definition'));
      }));

      it('should throw an error if no field type is passed', inject(($compile, $rootScope) => {
        function errorFunctionWrapper(){
          // setup the parent scope
          scope = $rootScope.$new();
          scope.name = 'label';
          scope.ngModel = 1;
          scope.field = {label: 'Label:'}
          compileElement();
        }
        expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide a type in the field definition'));
      }));

      it('should throw an error if no field model is passed', inject(($compile, $rootScope) => {
        function errorFunctionWrapper(){
          // setup the parent scope
          scope = $rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'number',
            validators: {}
          };
          compileElement(angular.element('<xos-field name="name" field="field"></xos-field>'));
        }
        expect(errorFunctionWrapper).toThrow(new Error('[xosField] Please provide an ng-model'));
      }));

      describe('when a text input is passed', () => {
        beforeEach(() => {
          scope = rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'text',
            validators: {
              custom: 'fake'
            }
          };
          scope.ngModel = 'label';
          compileElement();
        });

        it('should print a text field', () => {
          expect($(element).find('[name="label"]')).toHaveAttr('type', 'text');
        });

        it('should attach the custom validator directive', () => {
          let input = $(element).find('[name="label"]');
          expect(input).toHaveAttr('xos-custom-validator');
          expect(input).toHaveAttr('custom-validator', 'vm.field.validators.custom || null');
        });
      });

      describe('when a option is selected in dropdown', () => {
        beforeEach(() => {
          scope = rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'select',
            validators: {},
            options: [
              {
                id: 0,
                label: '---Site---'
              },
              {
                id: 1,
                label: '---Site1---'
              }
            ]
          };
          scope.ngModel = 0;
          compileElement();
        });

        it('No of select elements', () => {
          expect($(element).find('select').children('option').length).toEqual(2);
        });

        it('should show the selected value', () => {
          const elem =  angular.element($(element).find('select').children('option')[0]);
          expect(elem.text()).toEqual('---Site---');
          expect(elem).toHaveAttr('selected');
        });
      });

      describe('when a number input is passed', () => {
        beforeEach(() => {
          scope = rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'number',
            validators: {}
          };
          scope.ngModel = 10;
          compileElement();
        });

        it('should print a number field', () => {
          expect($(element).find('[name="label"]')).toHaveAttr('type', 'number');
        });
      });

      describe('when a boolean input is passed', () => {
        beforeEach(() => {
          scope = rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'boolean',
            validators: {}
          };
          scope.ngModel = true;
          compileElement();
        });

        let setFalse, setTrue;

        beforeEach(() => {
          setFalse= $(element).find('.boolean-field > a:first-child');
          setTrue = $(element).find('.boolean-field > a:last-child');
        });

        it('should print two buttons', () => {
          expect($(element).find('.boolean-field > a').length).toEqual(2)
        });

        it('should change value to false', () => {
          expect(isolatedScope.ngModel).toEqual(true);
          clickElement(setFalse[0]);
          expect(isolatedScope.ngModel).toEqual(false);
        });

        it('should change value to true', () => {
          isolatedScope.ngModel = false;
          scope.$apply();
          expect(isolatedScope.ngModel).toEqual(false);
          clickElement(setTrue[0]);
          expect(isolatedScope.ngModel).toEqual(true);
        });
      });

      describe('when an object input is passed', () => {
        beforeEach(() => {
          scope = rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'object',
            validators: {}
          };
          scope.ngModel = {
            baz: true,
            foo: 'bar',
            foz: 1,
          };
          compileElement();
        });

        it('should print a panel to contain object property field', () => {
          expect($(element).find('.panel.object-field')).toExist()
        });

        it('should print the right input type for each property', () => {
          expect($(element).find('input').length).toBe(2);
          expect($(element).find('.boolean-field > a').length).toEqual(2);
        });

        it('should format labels', () => {
          expect($(element).find('input[name="foo"]').parent().find('label').text()).toBe('Foo:');
        });

        describe('and the model is empty', () => {
          beforeEach(() => {
            scope.ngModel = {
            };
            compileElement();
          });

          it('should not print the panel', () => {
            expect($(element).find('.panel.object-field')).not.toExist()
          });

          describe('but field is configured', () => {
            beforeEach(() => {
              scope.field.properties = {
                foo: {
                  label: 'FooLabel:',
                  type: 'string',
                  validators: {
                    required: true
                  }
                },
                bar: {
                  type: 'number'
                }
              };
              compileElement();
            });
            it('should render panel and configured fields', () => {
              expect($(element).find('.panel.object-field')).toExist();
              expect($(element).find('input[name="foo"]').parent().find('label').text()).toBe('FooLabel:');
              expect($(element).find('input[name="foo"]')).toHaveAttr('type', 'string');
              expect($(element).find('input[name="foo"]')).toHaveAttr('required');

              expect($(element).find('input[name="bar"]').parent().find('label').text()).toBe('Bar:');
              expect($(element).find('input[name="bar"]')).toHaveAttr('type', 'number');

            });
          });
        });
      });

      describe('when an array input is passed', () => {
        beforeEach(() => {
          scope = rootScope.$new();
          scope.name = 'label';
          scope.field = {
            label: 'Label',
            type: 'array',
            validators: {},
            options: ['1', '2', '3', '4', '5']
          };
          scope.ngModel = ['1', '2', '3'];
          compileElement();
        });

        it('should print a panel to contain array values', () => {
          expect($(element).find('.panel.array-field')).toExist()
        });

        it('should print selected values', () => {
          expect($(element).find('.panel.array-field .selected .array-element')).toHaveLength(3)
        });

        it('should print un-selected values', () => {
          expect($(element).find('.panel.array-field .unselected .array-element')).toHaveLength(2)
        });

        describe('when a value is added', () => {
          it('should be removed from unselected', () => {
            isolatedScope.ngModel.push('4');
            scope.$apply();
            expect($(element).find('.panel.array-field .unselected .array-element')).toHaveLength(1)
          });
        });

        describe('when a value is removed', () => {
          it('should be added to unselected', () => {
            isolatedScope.ngModel.pop();
            scope.$apply();
            expect($(element).find('.panel.array-field .unselected .array-element')).toHaveLength(3)
          });
        });
      });

      describe('when validation options are passed', () => {
        let input;
        describe('given a a text field', () => {
          beforeEach(() => {
            scope = rootScope.$new();
            scope.name='label';
            scope.field = {
              label: 'Label',
              type: 'text',
              validators: {
                minlength: 10,
                maxlength: 15,
                required: true
              }
            };

            compileElement();
            scope.$digest();
            input = $(element).find('input');
          });

          it('should validate required', () => {
            scope.ngModel= null;
            scope.$digest();
            expect(input).toHaveClass('ng-invalid-required');

            scope.ngModel= 'not too short';
            scope.$digest();
            expect(input).not.toHaveClass('ng-invalid-required');
            expect(input).not.toHaveClass('ng-invalid');
          });

          it('should validate minlength', () => {
            scope.ngModel= 'short';
            scope.$digest();
            expect(input).toHaveClass('ng-invalid-minlength');

            scope.ngModel= 'not too short';
            scope.$digest();
            expect(input).not.toHaveClass('ng-invalid-minlength');
            expect(input).not.toHaveClass('ng-invalid');
          });

          it('should validate maxlength', () => {
            scope.ngModel= 'this is definitely too long!!';
            scope.$digest();
            expect(input).toHaveClass('ng-invalid-maxlength');

            scope.ngModel= 'not too short';
            scope.$digest();
            expect(input).not.toHaveClass('ng-invalid-maxlength');
            expect(input).not.toHaveClass('ng-invalid');
          });
        });
      });
    });
  });
})();