<commit_before>describe('Sort Code Tests', function () {

    var placeholder = $('#placeholder'),
        template = $('#template'),
        autosave,
        ajaxSpy,
        form,
        firstInput;
    
    beforeEach(function() {
        placeholder.empty('').append(template.html());
        firstInput = $('#placeholder input#transactions_transactionsIn_0_amount').eq(0);
        form = $('#placeholder form').eq(0);
        
        autosave = new GOVUK.AutoSave({
            form: $('#placeholder form.expanding-transaction-table'),
            statusElement: $('#placeholder #info'),
            url: 'test'
        });
        
        ajaxSpy = sinon.stub(jQuery, 'ajax', function(options) {
            options.success({'success': true});
        });
        
    });
    afterEach(function() {
        ajaxSpy.restore();
        placeholder.text('');
    });
    
    describe('Trigger save form', function () {
        
        var saveStub;
        
        beforeEach(function () {
            saveStub = sinon.spy(autosave, 'save');
        });
        afterEach(function () {
            saveStub.restore();
        });
        
        it('should call save then whe user moves off a field after changing something manually', function () {
            validKey(firstInput);
            firstInput.trigger('blur');
            expect(saveStub.callCount).to.equal(1);
        });
        it('should call save then the user moves off a field after changing something through paste', function () {
            firstInput.trigger('paste').trigger('blur');
            expect(saveStub.callCount).to.equal(1);
        });
        it('should call save when a user submits a form', function () {
            validKey(firstInput);
            form.trigger('submit');
            expect(saveStub.callCount).to.equal(1); 
        });
        it('should not call save then whe user moves off a field but did not interact with it', function () {
            firstInput.trigger('blur');
            expect(saveStub.callCount).to.equal(0);
        });
        it('should not call save on form submit if nothing changed', function () {
            form.trigger('submit');
            expect(saveStub.callCount).to.equal(0);
        });
        it('should not call save on form submit if already saved through blur', function () {
            validKey(firstInput);
            firstInput.trigger('blur');
            form.trigger('submit');
            expect(saveStub.callCount).to.equal(1);
        });
        it('should only call save once when you enter a number then press tab', function () {
            validKey(firstInput);
            firstInput.trigger('blur');
            tabKey(firstInput);
            expect(saveStub.callCount).to.equal(1);
        });
    });
    describe('Tell the user what is going on', function () {
        
        var setInfoSpy,
            info;
        
        beforeEach(function() {
            setInfoSpy = sinon.spy(autosave, 'displayStatus');
            info = $('#placeholder #info');
        });
        afterEach(function () {
            setInfoSpy.restore();
        });
        
        it('should change the info indicator to say saving when starts saving', function () {
            autosave.save();
            expect(setInfoSpy.calledWith({label:'Saving...', state:'saving'})).to.be.ok;
        });
        it('should say saved after data has been saved', function () {
            autosave.save();
            expect(setInfoSpy.calledWith({label:'Saved', state:'saved'})).to.be.ok;
            expect($('#placeholder #info').text()).to.equal('Saved');
        });
        it('should say not saved if it received any kind of error', function () {
            ajaxSpy.restore();
            
            ajaxSpy = sinon.stub(jQuery, 'ajax', function(options) {
                options.fail({
                    'success':false,
                    'errors': {
                        errorCode: 1002
                    }    
                });
            });
            
            autosave.save();
            expect(setInfoSpy.calledWith({label:'Not saved', state:'notsaved'})).to.be.ok;
            expect($('#placeholder #info').text()).to.equal('Not saved');
        });
        it('should remove the saved indicator when a user changes something', function () {
            autosave.save();
            expect(info.text()).to.equal('Saved');
            validKey(firstInput);
            expect(info.text()).to.equal('');
        });
        it('should not reset the state when the user enters a none numeric or . key', function () {
            autosave.save();
            expect(info.text()).to.equal('Saved');
            tabKey(firstInput);
            expect(info.text()).to.equal('Saved');
        });
    });
    describe('Tell the user about form validation errors', function () {
        
        var formgroup;
        
        beforeEach(function () {
            ajaxSpy.restore();

            ajaxSpy = sinon.stub(jQuery, 'ajax', function(options) {
                options.fail({
                    'success':false,
                    'errors': {
                        'errorCode': 1001,
                        'errorDescription': 'Form validation error',
                        'fields': {
                            'transactions_transactionsIn_0_amount':'ERROR MESSAGE'
                        }
                    }
                });
            });

            autosave.save();
            formgroup = firstInput.parent();
            
        });
        
        it('should show an error message below a field label if there is a validation error', function () {
            expect(formgroup.find('label').next()).to.have.class('error-message');
        });
        it('should indicate the form group has an error', function () {
            expect(formgroup).to.have.class('error'); 
        });

    });
    describe('Send data to server', function () {
        it('should use a http PUT to send data to the server', function () {
            autosave.save();
            expect(ajaxSpy.firstCall.args[0].type).to.equal('PUT');
        });
        it('should send the contents of the form to the server', function () {
            var data = form.serialize();
            autosave.save();
            expect(ajaxSpy.firstCall.args[0].data).to.equal(data);
        });
        it('should send the data to the url provided', function () {
            autosave.save();
            expect(ajaxSpy.firstCall.args[0].url).to.equal('test');
        });
    });
    
    
    function validKey(element) {
        var e = jQuery.Event("keypress");
        e.which = 50; // # Some key code value
        $(element).trigger(e);
    }
    
    function tabKey(element) {
        var e = jQuery.Event("keypress");
        e.which = 9; // # Some key code value
        $(element).trigger(e);
    }
    
    // update for changed event handler and different error handler and
    // response
    // also test that we clear errors on a good save.
});<commit_msg>Fix errors and add test to check errors are cleared.<commit_after>describe('Sort Code Tests', function () {

    var placeholder = $('#placeholder'),
        template = $('#template'),
        autosave,
        ajaxSpy,
        form,
        firstInput;
    
    beforeEach(function() {
        placeholder.empty('').append(template.html());
        firstInput = $('#placeholder input#transactions_transactionsIn_0_amount').eq(0);
        form = $('#placeholder form').eq(0);
        
        autosave = new GOVUK.AutoSave({
            form: $('#placeholder form.expanding-transaction-table'),
            statusElement: $('#placeholder #info'),
            url: 'test'
        });
        
        ajaxSpy = sinon.stub(jQuery, 'ajax', function(options) {
            options.success({'success': true});
        });
        
    });
    afterEach(function() {
        ajaxSpy.restore();
        placeholder.text('');
    });
    
    describe('Trigger save form', function () {
        
        var saveStub;
        
        beforeEach(function () {
            saveStub = sinon.spy(autosave, 'save');
        });
        afterEach(function () {
            saveStub.restore();
        });
        
        it('should call save then whe user moves off a field after changing something manually', function () {
            validKey(firstInput);
            firstInput.trigger('blur');
            expect(saveStub.callCount).to.equal(1);
        });
        it('should call save then the user moves off a field after changing something through paste', function () {
            firstInput.trigger('paste').trigger('blur');
            expect(saveStub.callCount).to.equal(1);
        });
        it('should call save when a user submits a form', function () {
            validKey(firstInput);
            form.trigger('submit');
            expect(saveStub.callCount).to.equal(1); 
        });
        it('should not call save then whe user moves off a field but did not interact with it', function () {
            firstInput.trigger('blur');
            expect(saveStub.callCount).to.equal(0);
        });
        it('should not call save on form submit if nothing changed', function () {
            form.trigger('submit');
            expect(saveStub.callCount).to.equal(0);
        });
        it('should not call save on form submit if already saved through blur', function () {
            validKey(firstInput);
            firstInput.trigger('blur');
            form.trigger('submit');
            expect(saveStub.callCount).to.equal(1);
        });
        it('should only call save once when you enter a number then press tab', function () {
            validKey(firstInput);
            firstInput.trigger('blur');
            tabKey(firstInput);
            expect(saveStub.callCount).to.equal(1);
        });
    });
    describe('Tell the user what is going on', function () {
        
        var setInfoSpy,
            info;
        
        beforeEach(function() {
            setInfoSpy = sinon.spy(autosave, 'displayStatus');
            info = $('#placeholder #info');
        });
        afterEach(function () {
            setInfoSpy.restore();
        });
        
        it('should change the info indicator to say saving when starts saving', function () {
            autosave.save();
            expect(setInfoSpy.calledWith({label:'Saving...', state:'saving'})).to.be.ok;
        });
        it('should say saved after data has been saved', function () {
            autosave.save();
            expect(setInfoSpy.calledWith({label:'Saved', state:'saved'})).to.be.ok;
            expect($('#placeholder #info').text()).to.equal('Saved');
        });
        it('should say not saved if it received any kind of error', function () {
            ajaxSpy.restore();
            
            ajaxSpy = sinon.stub(jQuery, 'ajax', function(options) {
                options.error({
                    responseJSON: {
                        'success': false,
                        'errors': {
                            errorCode: 1002
                        }
                    }
                });
            });
            
            autosave.save();
            expect(setInfoSpy.calledWith({label:'Not saved', state:'notsaved'})).to.be.ok;
            expect($('#placeholder #info').text()).to.equal('Not saved');
        });
        it('should remove the saved indicator when a user changes something', function () {
            autosave.save();
            expect(info.text()).to.equal('Saved');
            validKey(firstInput);
            expect(info.text()).to.equal('');
        });
        it('should not reset the state when the user enters a none numeric or . key', function () {
            autosave.save();
            expect(info.text()).to.equal('Saved');
            tabKey(firstInput);
            expect(info.text()).to.equal('Saved');
        });
    });
    describe('errors' , function () {
        
        it('should clear errors when you save', function () {

            group = firstInput.parent();
            label = group.find('label').eq(0);

            group.addClass('error');

            $('<span/>')
                .text('this is a fake error')
                .addClass('error-message')
                .insertAfter(label);

            autosave.save();
            
            expect($('#placeholder .error').length).to.equal(0);
            expect($('#placeholder .error-message').length).to.equal(0);
            
            
        });
        
        describe('Tell the user about form validation errors', function () {

            var formgroup;

            beforeEach(function () {
                ajaxSpy.restore();

                ajaxSpy = sinon.stub(jQuery, 'ajax', function(options) {
                    options.error({
                        responseJSON: {
                            'success': false,
                            'errors': {
                                'errorCode': 1001,
                                'errorDescription': 'Form validation error',
                                'fields': {
                                    'transactions_transactionsIn_0_amount': 'ERROR MESSAGE'
                                }
                            }
                        }
                    });
                });

                autosave.save();
                formgroup = firstInput.parent();

            });

            it('should show an error message below a field label if there is a validation error', function () {
                expect(formgroup.find('label').next()).to.have.class('error-message');
            });
            it('should indicate the form group has an error', function () {
                expect(formgroup).to.have.class('error');
            });

        });
    });
    
    describe('Send data to server', function () {
        it('should use a http PUT to send data to the server', function () {
            autosave.save();
            expect(ajaxSpy.firstCall.args[0].type).to.equal('PUT');
        });
        it('should send the contents of the form to the server', function () {
            var data = form.serialize();
            autosave.save();
            expect(ajaxSpy.firstCall.args[0].data).to.equal(data);
        });
        it('should send the data to the url provided', function () {
            autosave.save();
            expect(ajaxSpy.firstCall.args[0].url).to.equal('test');
        });
    });
    
    
    function validKey(element) {
        var e = jQuery.Event("change");
        $(element).trigger(e);
    }
    
    function tabKey(element) {
        var e = jQuery.Event("keypress");
        e.which = 9; // # Some key code value
        $(element).trigger(e);
    }
    
    // also test that we clear errors on a good save.
});
{'fraction_non_alphanumeric': 0.13476654350016795, 'fraction_numerical': 0.003426268055089016, 'mean_word_length': 1.645459392216101, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6411293', 'n_tokens_mistral': 3815, 'n_tokens_neox': 3735, 'n_words': 886}