mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
b4cdc85a59
refs https://github.com/TryGhost/Ghost/issues/6949 Handle version mismatch errors by: - displaying an alert asking the user to copy any data and refresh - disabling navigation so that unsaved data is not accidentally lost Detailed changes: - add `error` action to application route for global route-based error handling - remove 404-handler mixin, move logic into app route error handler - update `.catch` in validation-engine so that promises are rejected with the original error objects - add `VersionMismatchError` and `isVersionMismatchError` to ajax service - add `upgrade-status` service - has a method to trigger the alert and toggle the "upgrade required" mode - is injected into all routes by default so that it can be checked before transitioning - add `Route` override - updates the `willTransition` hook to check the `upgrade-status` service and abort the transition if we're in "upgrade required" mode - update notifications `showAPIError` method to handle version mismatch errors - update any areas where we were catching ajax errors manually so that the version mismatch error handling is obeyed - fix redirect tests in editor acceptance test - fix mirage's handling of 404s for unknown posts in get post requests - adjust alert z-index to to appear above modal backgrounds
180 lines
5.2 KiB
JavaScript
180 lines
5.2 KiB
JavaScript
import { expect } from 'chai';
|
|
import {
|
|
describeModule,
|
|
it
|
|
} from 'ember-mocha';
|
|
import Pretender from 'pretender';
|
|
import {
|
|
isAjaxError,
|
|
isUnauthorizedError
|
|
} from 'ember-ajax/errors';
|
|
import {
|
|
isVersionMismatchError,
|
|
isRequestEntityTooLargeError,
|
|
isUnsupportedMediaTypeError
|
|
} from 'ghost-admin/services/ajax';
|
|
import config from 'ghost-admin/config/environment';
|
|
|
|
function stubAjaxEndpoint(server, response = {}, code = 200) {
|
|
server.get('/test/', function () {
|
|
return [
|
|
code,
|
|
{'Content-Type': 'application/json'},
|
|
JSON.stringify(response)
|
|
];
|
|
});
|
|
}
|
|
|
|
describeModule(
|
|
'service:ajax',
|
|
'Integration: Service: ajax',
|
|
{
|
|
integration: true
|
|
},
|
|
function () {
|
|
let server;
|
|
|
|
beforeEach(function () {
|
|
server = new Pretender();
|
|
});
|
|
|
|
afterEach(function () {
|
|
server.shutdown();
|
|
});
|
|
|
|
it('adds Ghost version header to requests', function (done) {
|
|
let {version} = config.APP;
|
|
let ajax = this.subject();
|
|
|
|
stubAjaxEndpoint(server, {});
|
|
|
|
ajax.request('/test/').then(() => {
|
|
let [request] = server.handledRequests;
|
|
expect(request.requestHeaders['X-Ghost-Version']).to.equal(version);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('correctly parses single message response text', function (done) {
|
|
let error = {message: 'Test Error'};
|
|
stubAjaxEndpoint(server, error, 500);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true();
|
|
}).catch((error) => {
|
|
expect(error.errors).to.equal('Test Error');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('correctly parses single error response text', function (done) {
|
|
let error = {error: 'Test Error'};
|
|
stubAjaxEndpoint(server, error, 500);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true();
|
|
}).catch((error) => {
|
|
expect(error.errors).to.equal('Test Error');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('correctly parses multiple error messages', function (done) {
|
|
let error = {errors: ['First Error', 'Second Error']};
|
|
stubAjaxEndpoint(server, error, 500);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true();
|
|
}).catch((error) => {
|
|
expect(error.errors).to.deep.equal([
|
|
{message: 'First Error'},
|
|
{message: 'Second Error'}
|
|
]);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('returns default error object for non built-in error', function (done) {
|
|
stubAjaxEndpoint(server, {}, 500);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true;
|
|
}).catch((error) => {
|
|
expect(isAjaxError(error)).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('handles error checking for built-in errors', function (done) {
|
|
stubAjaxEndpoint(server, '', 401);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true;
|
|
}).catch((error) => {
|
|
expect(isUnauthorizedError(error)).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('handles error checking for VersionMismatchError', function (done) {
|
|
server.get('/test/', function () {
|
|
return [
|
|
400,
|
|
{'Content-Type': 'application/json'},
|
|
JSON.stringify({
|
|
errors: [{
|
|
errorType: 'VersionMismatchError',
|
|
statusCode: 400
|
|
}]
|
|
})
|
|
];
|
|
});
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true;
|
|
}).catch((error) => {
|
|
expect(isVersionMismatchError(error)).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('handles error checking for RequestEntityTooLargeError on 413 errors', function (done) {
|
|
stubAjaxEndpoint(server, {}, 413);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true;
|
|
}).catch((error) => {
|
|
expect(isRequestEntityTooLargeError(error)).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('handles error checking for UnsupportedMediaTypeError on 415 errors', function (done) {
|
|
stubAjaxEndpoint(server, {}, 415);
|
|
|
|
let ajax = this.subject();
|
|
|
|
ajax.request('/test/').then(() => {
|
|
expect(false).to.be.true;
|
|
}).catch((error) => {
|
|
expect(isUnsupportedMediaTypeError(error)).to.be.true;
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
);
|