describe('Component vnDialog', () => {
    let $element;
    let $scope;
    let controller;

    beforeEach(ngModule('vnCore'));

    beforeEach(angular.mock.inject(($rootScope, $compile) => {
        $scope = $rootScope.$new();
        $element = $compile('<vn-dialog><tpl-body>Body</tpl-body></vn-dialog>')($scope);
        controller = $element.controller('vnDialog');
        controller.emit = jasmine.createSpy('emit');
    }));

    afterEach(() => {
        $scope.$destroy();
        $element.remove();
    });

    describe('show()', () => {
        it(`should call the show handler when response is given`, () => {
            let called;
            let showHandler = () => called = true;

            controller.show(showHandler);
            controller.respond();

            expect(called).toBeTruthy();
        });

        it(`should not hide the dialog when false is returned from response handler`, () => {
            controller.show(() => false);
            spyOn(controller, 'hide');
            controller.respond('answer');

            expect(controller.hide).not.toHaveBeenCalled();
        });
    });

    describe('hide()', () => {
        it(`should resolve the promise returned by show`, () => {
            let resolved = true;
            controller.show().then(() => resolved = true);
            controller.hide();
            $scope.$apply();

            expect(resolved).toBeTruthy();
        });
    });

    describe('respond()', () => {
        it(`should do nothing if dialog is already hidden`, () => {
            controller.onResponse = () => {};
            spyOn(controller, 'onResponse');
            controller.respond();

            expect(controller.onResponse).not.toHaveBeenCalledWith();
        });

        it(`should call onResponse() if it's defined`, () => {
            controller.onResponse = () => {};
            spyOn(controller, 'onResponse');

            controller.show();
            controller.respond();

            expect(controller.onResponse).toHaveBeenCalledWith(jasmine.any(Object));
        });

        it(`should call onResponse() with the response`, () => {
            controller.onResponse = () => {};
            spyOn(controller, 'onResponse');

            controller.show();
            controller.respond('response');

            expect(controller.onResponse).toHaveBeenCalledWith({$response: 'response'});
        });

        it(`should call onAccept() when accept response is given`, () => {
            controller.onAccept = () => {};
            spyOn(controller, 'onAccept');

            controller.show();
            controller.respond('accept');

            expect(controller.onAccept).toHaveBeenCalledWith({$response: 'accept'});
        });

        it(`should resolve the promise returned by show() with response`, () => {
            let response;
            controller.show().then(res => response = res);
            controller.respond('response');
            $scope.$apply();

            expect(response).toEqual('response');
        });
    });
});