@kineticdata/react
Version:
A React library for the Kinetic Platform
245 lines (244 loc) • 11 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
var _regeneratorRuntime2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/regeneratorRuntime"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/asyncToGenerator"));
var _AuthInterceptor = _interopRequireDefault(require("./AuthInterceptor"));
var _axios = _interopRequireDefault(require("axios"));
jest.mock('axios');
var store;
var unauthenticatedAction = function unauthenticatedAction() {
return {
type: 'TIMED_OUT'
};
};
var authenticatedSelector = function authenticatedSelector(state) {
return state.authenticated;
};
var cancelledSelector = function cancelledSelector(state) {
return state.cancelled;
};
describe('AuthInterceptor', function () {
beforeEach(function () {
store = {
state: {
authenticated: false,
cancelled: false
},
getState: function getState() {
return this.state;
},
dispatch: function dispatch(action) {
this.actions.push(action);
},
subscribe: function subscribe(listener) {
var _this = this;
this.listeners.push(listener);
return function () {
_this.listeners = _this.listeners.filter(function (l) {
return l !== listener;
});
};
},
actions: [],
listeners: []
};
_axios["default"].mockReset();
});
describe('constructor', function () {
test('sets properties', function () {
var authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector);
expect(authInterceptor.store).toBe(store);
expect(authInterceptor.unauthenticatedAction).toBe(unauthenticatedAction);
expect(authInterceptor.authenticatedSelector).toBe(authenticatedSelector);
expect(authInterceptor.cancelledSelector).toBe(cancelledSelector);
});
test('autPromise should be null', function () {
var authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector);
expect(authInterceptor.authPromise).toBeNull();
});
});
describe('handleRejected', function () {
test('returns rejected promise with the given error if not 401', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee() {
var authInterceptor, error;
return (0, _regeneratorRuntime2["default"])().wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector);
error = {
response: {
status: 400
}
};
_context.next = 4;
return expect(authInterceptor.handleRejected(error)).rejects.toBe(error);
case 4:
expect(authInterceptor.authPromise).toBeNull();
case 5:
case "end":
return _context.stop();
}
}, _callee);
})));
test('performs authentication workflow with successful login', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee2() {
var authInterceptor, error, rejectedCall;
return (0, _regeneratorRuntime2["default"])().wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector); // Mock an axios return value.
_axios["default"].mockReturnValue(Promise.resolve('Hello World'));
// Make a call to handleRejected that will trigger the auth functionality.
error = {
response: {
status: 401,
config: {
url: 'foo'
}
}
};
rejectedCall = authInterceptor.handleRejected(error); // It should dispatch the redux action using the action creator passed to
// the controller and start to listen to the store for success or cancel.
expect(store.actions).toEqual([{
type: 'TIMED_OUT'
}]);
expect(store.listeners.length).toBe(1);
expect(authInterceptor.authPromise).not.toBeNull();
// Simulate sucessful authentication and call the listener.
store.state.authenticated = true;
store.listeners[0]();
// The promse should be resolved with the axios resolved value. Also
// ensure that axios was called and that the listener is unsubscribed.
_context2.next = 11;
return expect(rejectedCall).resolves.toBe('Hello World');
case 11:
expect(_axios["default"].mock.calls).toEqual([[{
url: 'foo'
}]]);
expect(store.listeners.length).toBe(0);
expect(authInterceptor.authPromise).toBeNull();
case 14:
case "end":
return _context2.stop();
}
}, _callee2);
})));
test('performs authentication workflow with cancelled login', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee3() {
var authInterceptor, error, rejectedCall;
return (0, _regeneratorRuntime2["default"])().wrap(function _callee3$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector); // Make a call to handleRejected that will trigger the auth functionality.
error = {
response: {
status: 401,
config: {
url: 'foo'
}
}
};
rejectedCall = authInterceptor.handleRejected(error); // It should dispatch the redux action using the action creator passed to
// the controller and start to listen to the store for success or cancel.
expect(store.actions).toEqual([{
type: 'TIMED_OUT'
}]);
expect(store.listeners.length).toBe(1);
expect(authInterceptor.authPromise).not.toBeNull();
// Simulate cancel and call the listener.
store.state.cancelled = true;
store.listeners[0]();
// The promse should be rejected with the original error object. Also
// ensure that axios is not called and that the listener is unsubscribed.
_context3.next = 10;
return expect(rejectedCall).rejects.toBe(error);
case 10:
expect(_axios["default"].mock.calls).toEqual([]);
expect(store.listeners.length).toBe(0);
expect(authInterceptor.authPromise).toBeNull();
case 13:
case "end":
return _context3.stop();
}
}, _callee3);
})));
test('creates one authPromise for multiple calls', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee4() {
var authInterceptor, error, authPromise1, authPromise2;
return (0, _regeneratorRuntime2["default"])().wrap(function _callee4$(_context4) {
while (1) switch (_context4.prev = _context4.next) {
case 0:
authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector); // Should be null initially.
expect(authInterceptor.authPromise).toBeNull();
// Call handleRejected with the error object, should return a promise.
error = {
response: {
status: 401,
config: {
url: 'foo'
}
}
};
authInterceptor.handleRejected(error);
// Should now be set after a call to handleRejected.
authPromise1 = authInterceptor.authPromise;
expect(authPromise1).not.toBeNull();
// Second call to handleRejected should not change the value of the
// authPromise.
authInterceptor.handleRejected(error);
authPromise2 = authInterceptor.authPromise;
expect(authPromise1).toBe(authPromise2);
case 9:
case "end":
return _context4.stop();
}
}, _callee4);
})));
test('returns original error if authenticated selector returns true initially', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee5() {
var authInterceptor, error;
return (0, _regeneratorRuntime2["default"])().wrap(function _callee5$(_context5) {
while (1) switch (_context5.prev = _context5.next) {
case 0:
authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector);
error = {
response: {
status: 401,
config: {
url: 'foo'
}
}
};
store.state.authenticated = true;
_context5.next = 5;
return expect(authInterceptor.handleRejected(error)).rejects.toBe(error);
case 5:
expect(authInterceptor.authPromise).toBeNull();
case 6:
case "end":
return _context5.stop();
}
}, _callee5);
})));
test('returns original error if cancelled selector returns true initially', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee6() {
var authInterceptor, error;
return (0, _regeneratorRuntime2["default"])().wrap(function _callee6$(_context6) {
while (1) switch (_context6.prev = _context6.next) {
case 0:
authInterceptor = new _AuthInterceptor["default"](store, unauthenticatedAction, authenticatedSelector, cancelledSelector);
error = {
response: {
status: 401,
config: {
url: 'foo'
}
}
};
store.state.cancelled = true;
_context6.next = 5;
return expect(authInterceptor.handleRejected(error)).rejects.toBe(error);
case 5:
expect(authInterceptor.authPromise).toBeNull();
case 6:
case "end":
return _context6.stop();
}
}, _callee6);
})));
});
});