<commit_before>/* jshint expr:true */
import sinon from 'sinon';
import {expect} from 'chai';
import {describe, it} from 'mocha';
import {setupComponentTest} from 'ember-mocha';
import hbs from 'htmlbars-inline-precompile';
import Pretender from 'pretender';
import wait from 'ember-test-helpers/wait';
import {createFile, fileUpload} from '../../helpers/file-upload';
import $ from 'jquery';
import run from 'ember-runloop';
import Service from 'ember-service';
import {UnsupportedMediaTypeError} from 'ghost-admin/services/ajax';

const keyCodes = {
    enter: 13
};

const configStub = Service.extend({
    fileStorage: true
});

const notificationsStub = Service.extend({
    showAPIError(/* error, options */) {
        // noop - to be stubbed
    }
});

const sessionStub = Service.extend({
    isAuthenticated: false,
    authorize(authorizer, block) {
        if (this.get('isAuthenticated')) {
            block('Authorization', 'Bearer token');
        }
    }
});

const stubSuccessfulUpload = function (server, delay = 0) {
    server.post('/ghost/api/v0.1/uploads/', function () {
        return [200, {'Content-Type': 'application/json'}, '"/content/images/test.png"'];
    }, delay);
};

const stubFailedUpload = function (server, code, error, delay = 0) {
    server.post('/ghost/api/v0.1/uploads/', function () {
        return [code, {'Content-Type': 'application/json'}, JSON.stringify({
            errors: [{
                errorType: error,
                message: `Error: ${error}`
            }]
        })];
    }, delay);
};

describe('Integration: Component: gh-image-uploader', function() {
    setupComponentTest('gh-image-upload', {
        integration: true
    });

    let server;

    beforeEach(function () {
        this.register('service:config', configStub);
        this.register('service:session', sessionStub);
        this.register('service:notifications', notificationsStub);
        this.inject.service('config', {as: 'configService'});
        this.inject.service('session', {as: 'sessionService'});
        this.inject.service('notifications', {as: 'notifications'});
        this.set('update', function () {});
        server = new Pretender();
    });

    afterEach(function () {
        server.shutdown();
    });

    it('renders', function() {
        this.set('image', 'http://example.com/test.png');
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$()).to.have.length(1);
    });

    it('defaults to upload form', function () {
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$('input[type="file"]').length).to.equal(1);
    });

    it('defaults to url form with no filestorage config', function () {
        this.set('configService.fileStorage', false);
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$('input[type="file"]').length).to.equal(0);
        expect(this.$('input[type="text"].url').length).to.equal(1);
    });

    it('can switch between form types', function () {
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$('input[type="file"]').length).to.equal(1);
        expect(this.$('input[type="text"].url').length).to.equal(0);

        this.$('a.image-url').click();

        expect(this.$('input[type="file"]').length, 'upload form is visible after switch to url form')
            .to.equal(0);
        expect(this.$('input[type="text"].url').length, 'url form is visible after switch to url form')
            .to.equal(1);

        this.$('a.image-upload').click();

        expect(this.$('input[type="file"]').length, 'upload form is visible after switch to upload form')
            .to.equal(1);
        expect(this.$('input[type="text"].url').length, 'url form is visible after switch to upload form')
            .to.equal(0);
    });

    it('triggers formChanged action when switching between forms', function () {
        let formChanged = sinon.spy();
        this.set('formChanged', formChanged);

        this.render(hbs`{{gh-image-uploader image=image formChanged=(action formChanged)}}`);

        this.$('a.image-url').click();
        this.$('a.image-upload').click();

        expect(formChanged.calledTwice).to.be.true;
        expect(formChanged.firstCall.args[0]).to.equal('url-input');
        expect(formChanged.secondCall.args[0]).to.equal('upload');
    });

    describe('file upload form', function () {
        it('renders form with supplied alt text', function () {
            this.render(hbs`{{gh-image-uploader image=image altText="text test"}}`);
            expect(this.$('.description').text().trim()).to.equal('Upload image of "text test"');
        });

        it('renders form with supplied text', function () {
            this.render(hbs`{{gh-image-uploader image=image text="text test"}}`);
            expect(this.$('.description').text().trim()).to.equal('text test');
        });

        it('generates request to correct endpoint', function (done) {
            stubSuccessfulUpload(server);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(server.handledRequests.length).to.equal(1);
                expect(server.handledRequests[0].url).to.equal('/ghost/api/v0.1/uploads/');
                expect(server.handledRequests[0].requestHeaders.Authorization).to.be.undefined;
                done();
            });
        });

        it('adds authentication headers to request', function (done) {
            stubSuccessfulUpload(server);

            this.get('sessionService').set('isAuthenticated', true);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                let [request] = server.handledRequests;
                expect(request.requestHeaders.Authorization).to.equal('Bearer token');
                done();
            });
        });

        it('fires update action on successful upload', function (done) {
            let update = sinon.spy();
            this.set('update', update);

            stubSuccessfulUpload(server);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(update.calledOnce).to.be.true;
                expect(update.firstCall.args[0]).to.equal('/content/images/test.png');
                done();
            });
        });

        it('doesn\'t fire update action on failed upload', function (done) {
            let update = sinon.spy();
            this.set('update', update);

            stubFailedUpload(server, 500);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(update.calledOnce).to.be.false;
                done();
            });
        });

        it('fires fileSelected action on file selection', function (done) {
            let fileSelected = sinon.spy();
            this.set('fileSelected', fileSelected);

            stubSuccessfulUpload(server);

            this.render(hbs`{{gh-image-uploader url=image fileSelected=(action fileSelected) update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(fileSelected.calledOnce).to.be.true;
                expect(fileSelected.args[0]).to.not.be.blank;
                done();
            });
        });
<commit_msg>fix gh-image-uploader-test<commit_after>/* jshint expr:true */
import sinon from 'sinon';
import {expect} from 'chai';
import {describe, it} from 'mocha';
import {setupComponentTest} from 'ember-mocha';
import hbs from 'htmlbars-inline-precompile';
import Pretender from 'pretender';
import wait from 'ember-test-helpers/wait';
import {createFile, fileUpload} from '../../helpers/file-upload';
import $ from 'jquery';
import run from 'ember-runloop';
import Service from 'ember-service';
import {UnsupportedMediaTypeError} from 'ghost-admin/services/ajax';

const keyCodes = {
    enter: 13
};

const configStub = Service.extend({
    fileStorage: true
});

const notificationsStub = Service.extend({
    showAPIError(/* error, options */) {
        // noop - to be stubbed
    }
});

const sessionStub = Service.extend({
    isAuthenticated: false,
    authorize(authorizer, block) {
        if (this.get('isAuthenticated')) {
            block('Authorization', 'Bearer token');
        }
    }
});

const stubSuccessfulUpload = function (server, delay = 0) {
    server.post('/ghost/api/v0.1/uploads/', function () {
        return [200, {'Content-Type': 'application/json'}, '"/content/images/test.png"'];
    }, delay);
};

const stubFailedUpload = function (server, code, error, delay = 0) {
    server.post('/ghost/api/v0.1/uploads/', function () {
        return [code, {'Content-Type': 'application/json'}, JSON.stringify({
            errors: [{
                errorType: error,
                message: `Error: ${error}`
            }]
        })];
    }, delay);
};

describe('Integration: Component: gh-image-uploader', function() {
    setupComponentTest('gh-image-upload', {
        integration: true
    });

    let server;

    beforeEach(function () {
        this.register('service:config', configStub);
        this.register('service:session', sessionStub);
        this.register('service:notifications', notificationsStub);
        this.inject.service('config', {as: 'configService'});
        this.inject.service('session', {as: 'sessionService'});
        this.inject.service('notifications', {as: 'notifications'});
        this.set('update', function () {});
        server = new Pretender();
    });

    afterEach(function () {
        server.shutdown();
    });

    it('renders', function() {
        this.set('image', 'http://example.com/test.png');
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$()).to.have.length(1);
    });

    it('defaults to upload form', function () {
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$('input[type="file"]').length).to.equal(1);
    });

    it('defaults to url form with no filestorage config', function () {
        this.set('configService.fileStorage', false);
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$('input[type="file"]').length).to.equal(0);
        expect(this.$('input[type="text"].url').length).to.equal(1);
    });

    it('can switch between form types', function () {
        this.render(hbs`{{gh-image-uploader image=image}}`);
        expect(this.$('input[type="file"]').length).to.equal(1);
        expect(this.$('input[type="text"].url').length).to.equal(0);

        this.$('a.image-url').click();

        expect(this.$('input[type="file"]').length, 'upload form is visible after switch to url form')
            .to.equal(0);
        expect(this.$('input[type="text"].url').length, 'url form is visible after switch to url form')
            .to.equal(1);

        this.$('a.image-upload').click();

        expect(this.$('input[type="file"]').length, 'upload form is visible after switch to upload form')
            .to.equal(1);
        expect(this.$('input[type="text"].url').length, 'url form is visible after switch to upload form')
            .to.equal(0);
    });

    it('triggers formChanged action when switching between forms', function () {
        let formChanged = sinon.spy();
        this.set('formChanged', formChanged);

        this.render(hbs`{{gh-image-uploader image=image formChanged=(action formChanged)}}`);

        this.$('a.image-url').click();
        this.$('a.image-upload').click();

        expect(formChanged.calledTwice).to.be.true;
        expect(formChanged.firstCall.args[0]).to.equal('url-input');
        expect(formChanged.secondCall.args[0]).to.equal('upload');
    });

    describe('file upload form', function () {
        it('renders form with supplied alt text', function () {
            this.render(hbs`{{gh-image-uploader image=image altText="text test"}}`);
            expect(this.$('.description').text().trim()).to.equal('Upload image of "text test"');
        });

        it('renders form with supplied text', function () {
            this.render(hbs`{{gh-image-uploader image=image text="text test"}}`);
            expect(this.$('.description').text().trim()).to.equal('text test');
        });

        it('generates request to correct endpoint', function (done) {
            stubSuccessfulUpload(server);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(server.handledRequests.length).to.equal(1);
                expect(server.handledRequests[0].url).to.equal('/ghost/api/v0.1/uploads/');
                expect(server.handledRequests[0].requestHeaders.Authorization).to.be.undefined;
                done();
            });
        });

        it('adds authentication headers to request', function (done) {
            stubSuccessfulUpload(server);

            this.get('sessionService').set('isAuthenticated', true);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                let [request] = server.handledRequests;
                expect(request.requestHeaders.Authorization).to.equal('Bearer token');
                done();
            });
        });

        it('fires update action on successful upload', function (done) {
            let update = sinon.spy();
            this.set('update', update);

            stubSuccessfulUpload(server);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(update.calledOnce).to.be.true;
                expect(update.firstCall.args[0]).to.equal('/content/images/test.png');
                done();
            });
        });

        it('doesn\'t fire update action on failed upload', function (done) {
            let update = sinon.spy();
            this.set('update', update);

            stubFailedUpload(server, 500);

            this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(update.calledOnce).to.be.false;
                done();
            });
        });

        it('fires fileSelected action on file selection', function (done) {
            let fileSelected = sinon.spy();
            this.set('fileSelected', fileSelected);

            stubSuccessfulUpload(server);

            this.render(hbs`{{gh-image-uploader image=image fileSelected=(action fileSelected) update=(action update)}}`);
            fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});

            wait().then(() => {
                expect(fileSelected.calledOnce).to.be.true;
                expect(fileSelected.args[0]).to.not.be.blank;
                done();
            });
        });

{'fraction_non_alphanumeric': 0.17908463632335253, 'fraction_numerical': 0.004178008482623283, 'mean_word_length': 2.607672984699703, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '375032', 'n_tokens_mistral': 4570, 'n_tokens_neox': 4480, 'n_words': 837}