/**
 * Start controller test cases
 * @author Simon Willan <simon.willan@claromentis.com>
 */
(function () {
    'use strict';

    describe('Nav directive', function () {

        var $scope, $isolate, $httpBackend, element, quizTracker;

        // load quiz
        beforeEach(angular.mock.module('cla.quiz'));

        // load dynamic templates module (configured in karma conf)
        beforeEach(angular.mock.module('quiz.templates'));

        // load injections, compile directive
        beforeEach(angular.mock.inject(function ($injector) {

            var $root = $injector.get("$rootScope");
            var $compile = $injector.get("$compile");

            $httpBackend = $injector.get('$httpBackend');
            quizTracker = $injector.get('quizTracker');

            setupQuizTracker(quizTracker);

            $scope = $root.$new();

            element = angular.element('<cla-quiz-nav quiz_id="1"></cla-quiz-nav>');
            element = $compile(element)($scope);

            $scope.$digest();
            $isolate = element.isolateScope();
        }));

        it('should compile successfully', function () {
            var content = element.html();
            expect(content).not.toBeNull();
            expect(content).not.toEqual(undefined);
        });

        /**
         * visibility tests
         */
        describe('button visibility / status', function () {

            // test next button disabled when an answer isn't yet selected
            it('should be able to enable and disable the next button', function () {

                // test question 1 is enabled
                var disabled = $isolate.nav.isNextDisabled();
                expect(disabled).toBe(false);

                // set question 2 as the current question
                quizTracker.question = 1;

                // test question 2 is disabled
                disabled = $isolate.nav.isNextDisabled();
                expect(disabled).toBe(true);
            });

            // test previous button is hidden when on the first question
            it('should be able to hide and show the previous button', function () {

                // first question
                var hidden = $isolate.nav.isPrevHidden();
                expect(hidden).toBe(true);

                // next (or any other) question
                quizTracker.question = 1;
                hidden = $isolate.nav.isPrevHidden();
                expect(hidden).toBe(false);
            })

        });

        /**
         * test the next() method
         */
        describe('.next()', function () {

            // test without save
            it('should move the question on to the next without updating chosen ' +
                'question. (no answer selected)', function () {
                // run next()
                $isolate.nav.next();

                // test if the question has moved on and current has been updated
                expect(quizTracker.question).toBe(1);
                expect(quizTracker.current).toEqual(quizTracker.questions[1]);
            });

            // test with save
            it('should move the question on to the next, and make a request to ' +
                'submit question endpoint.', function () {

                // expect a post to the submit question endpoint
                $httpBackend.expectPOST('/api/quiz/v1/1/questions/1/answer').respond({});

                // run next with save
                $isolate.nav.next(true);

                // flush endpoint. No need to make any assertions, if flush fails then the request
                // was never executed, and thus a failure.
                $httpBackend.flush();
            });

        });

        /**
         * Test finish quiz
         */
        describe('.finish()', function () {

            it('should make a request to the finish endpoint, and update the results property of quizTracker', function () {

                // expect a post to the quiz finish endpoint
                $httpBackend.expectPOST('/api/quiz/v1/1/finish')
                    .respond({status: 1, results: {passed: true}});

                // finish the quiz
                $isolate.nav.finish();

                var results = quizTracker.results;

                // flush the endpoint.
                $httpBackend.flush();

                // assert results have been set, the promise is resolved and complete is true.
                expect(quizTracker.results).not.toBe(results);
                expect(quizTracker.results.passed).toBe(true);
            });

        });

        /**
         * Test navigation events fired by angular
         */
        describe('navigation events', function () {

            it('should be able to execute navigation next()', function () {

                // expect a post to the submit question endpoint
                $httpBackend.expectPOST('/api/quiz/v1/1/questions/1/answer').respond({});

                quizTracker.question = 0;

                $scope.$broadcast('quiz.next');

                expect(quizTracker.question).toBe(1);

                // flush endpoint. No need to make another assertion, if flush fails then the request
                // was never executed, and thus a failure.
                $httpBackend.flush();
            });

            it('should be able to execute navigation previous()', function () {

                quizTracker.question = 1;

                $scope.$broadcast('quiz.previous');

                expect(quizTracker.question).toBe(0);
            });

            it('should be able to execute navigation skip()', function () {

                quizTracker.question = 0;

                $scope.$broadcast('quiz.skip');

                expect(quizTracker.question).toBe(1);
                expect(quizTracker.current).toEqual(quizTracker.questions[1]);
            });

            it('should be able to execute navigation goto()', function () {

                quizTracker.question = 0;

                $scope.$broadcast('quiz.goto', {num: 2});

                expect(quizTracker.question).toBe(2);
            });
        });
    });

    /**
     * Setup quizTracker test case
     * @param quizTracker
     */
    function setupQuizTracker(quizTracker) {
        quizTracker.init([
            {id: '1', text: 'Why is a raven like a writing desk?'},
            {id: '2', text: 'What is the speed of dark as night falls?'},
            {id: '3', text: 'Why is a mouse when it spins?'}
        ]);

        // only 1 question answered on load.
        quizTracker.question = 0;
        quizTracker.current = quizTracker.questions[0];
        quizTracker.chosen = {
            0: {submitted: true}
        }
    }

}());
