diff --git a/__tests__/managers/ConnectionManager.test.js b/__tests__/managers/ConnectionManager.test.js index ace2273..848676c 100644 --- a/__tests__/managers/ConnectionManager.test.js +++ b/__tests__/managers/ConnectionManager.test.js @@ -6,6 +6,129 @@ let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS b const c = ConnectionManager.getInstance(); +afterEach(() => { + jest.restoreAllMocks(); +}); + +test('recoverLogin error crypto', () => { + jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => { + return Promise.reject(); + }); + return expect(c.recoverLogin()).rejects.toBe(false); +}); + +test('recoverLogin success crypto', () => { + jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => { + return Promise.resolve('token1'); + }); + return expect(c.recoverLogin()).resolves.toBe('token1'); +}); + +test('saveLogin success', () => { + jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { + return Promise.resolve(); + }); + return expect(c.saveLogin('email', 'token2')).resolves.toBeTruthy(); +}); + +test('saveLogin error', () => { + jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { + return Promise.reject(); + }); + return expect(c.saveLogin('email', 'token3')).rejects.toBeFalsy(); +}); + +test('recoverLogin error crypto with saved token', () => { + jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => { + return Promise.reject(); + }); + return expect(c.recoverLogin()).resolves.toBe('token2'); +}); + +test('recoverLogin success saved', () => { + return expect(c.recoverLogin()).resolves.toBe('token2'); +}); + +test('isRequestResponseValid', () => { + let json = { + state: true, + data: {} + }; + expect(c.isRequestResponseValid(json)).toBeTrue(); + json = { + state: false, + data: {} + }; + expect(c.isRequestResponseValid(json)).toBeTrue(); + json = { + state: false, + message: 'coucou', + data: {truc: 'machin'} + }; + expect(c.isRequestResponseValid(json)).toBeTrue(); + json = { + message: 'coucou' + }; + expect(c.isRequestResponseValid(json)).toBeFalse(); + json = { + state: 'coucou' + }; + expect(c.isRequestResponseValid(json)).toBeFalse(); + json = { + state: true, + }; + expect(c.isRequestResponseValid(json)).toBeFalse(); +}); + +test("isConnectionResponseValid", () => { + let json = { + state: true, + message: 'Connexion confirmée', + token: 'token' + }; + expect(c.isConnectionResponseValid(json)).toBeTrue(); + json = { + state: true, + token: 'token' + }; + expect(c.isConnectionResponseValid(json)).toBeTrue(); + json = { + state: false, + }; + expect(c.isConnectionResponseValid(json)).toBeTrue(); + + json = { + state: true, + message: 'Connexion confirmée', + token: '' + }; + expect(c.isConnectionResponseValid(json)).toBeFalse(); + json = { + state: true, + message: 'Connexion confirmée', + }; + expect(c.isConnectionResponseValid(json)).toBeFalse(); + json = { + state: 'coucou', + message: 'Connexion confirmée', + token: 'token' + }; + expect(c.isConnectionResponseValid(json)).toBeFalse(); + json = { + state: true, + message: 'Connexion confirmée', + token: 2 + }; + expect(c.isConnectionResponseValid(json)).toBeFalse(); + json = { + coucou: 'coucou', + message: 'Connexion confirmée', + token: 'token' + }; + expect(c.isConnectionResponseValid(json)).toBeFalse(); +}); + + test("connect bad credentials", () => { jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ @@ -26,7 +149,7 @@ test("connect good credentials", () => { jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { + return { state: true, message: 'Connexion confirmée', token: 'token' @@ -34,7 +157,7 @@ test("connect good credentials", () => { }, }) }); - jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { + c.saveLogin = jest.fn(() => { return Promise.resolve(true); }); return expect(c.connect('email', 'password')).resolves.toBeTruthy(); @@ -44,7 +167,7 @@ test("connect good credentials, fail save token", () => { jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { + return { state: true, message: 'Connexion confirmée', token: 'token' @@ -52,7 +175,7 @@ test("connect good credentials, fail save token", () => { }, }) }); - jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { + c.saveLogin = jest.fn(() => { return Promise.reject(false); }); return expect(c.connect('email', 'password')).rejects.toBe(ERROR_TYPE.SAVE_TOKEN); @@ -70,7 +193,7 @@ test("connect bogus response 1", () => { jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { + return { thing: true, wrong: '', } @@ -81,63 +204,74 @@ test("connect bogus response 1", () => { .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); }); -test("connect bogus response 2", () => { + +test("authenticatedRequest success", () => { + c.recoverLogin = jest.fn(() => { + return Promise.resolve('token'); + }); jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { - state: true, - message: '', - } + return {state: true, message: 'Connexion vérifiée', data: {coucou: 'toi'}} }, }) }); - return expect(c.connect('email', 'password')) - .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); + return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')) + .resolves.toStrictEqual({coucou: 'toi'}); }); -test("connect bogus response 3", () => { +test("authenticatedRequest error wrong token", () => { + c.recoverLogin = jest.fn(() => { + return Promise.resolve('token'); + }); jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { - state: false, - message: '', - } + return {state: false, message: 'Le champ token sélectionné est invalide.'} }, }) }); - return expect(c.connect('email', 'password')) + return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')) .rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS); }); -test("connect bogus response 4", () => { +test("authenticatedRequest error bogus response", () => { + c.recoverLogin = jest.fn(() => { + return Promise.resolve('token'); + }); jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { - message: '', - token: '', - } + return {state: true, message: 'Connexion vérifiée'} }, }) }); - return expect(c.connect('email', 'password')) + return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')) .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); }); -test("connect bogus response 5", () => { +test("authenticatedRequest connection error", () => { + c.recoverLogin = jest.fn(() => { + return Promise.resolve('token'); + }); + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.reject() + }); + return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')) + .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); +}); + +test("authenticatedRequest error no token", () => { + c.recoverLogin = jest.fn(() => { + return Promise.reject(false); + }); jest.spyOn(global, 'fetch').mockImplementationOnce(() => { return Promise.resolve({ json: () => { - return { - state: true, - message: 'Connexion confirmée', - token: '' - } + return {state: false, message: 'Le champ token sélectionné est invalide.'} }, }) }); - return expect(c.connect('email', 'password')) - .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); + return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')) + .rejects.toBe(ERROR_TYPE.NO_TOKEN); }); diff --git a/managers/ConnectionManager.js b/managers/ConnectionManager.js index 32e1ea4..7069ca9 100644 --- a/managers/ConnectionManager.js +++ b/managers/ConnectionManager.js @@ -6,6 +6,7 @@ export const ERROR_TYPE = { BAD_CREDENTIALS: 0, CONNECTION_ERROR: 1, SAVE_TOKEN: 2, + NO_TOKEN: 3, }; const AUTH_URL = "https://www.amicale-insat.fr/api/password"; @@ -16,10 +17,6 @@ export default class ConnectionManager { #email: string; #token: string; - constructor() { - - } - /** * Get this class instance or create one if none is found * @returns {ConnectionManager} @@ -30,12 +27,31 @@ export default class ConnectionManager { ConnectionManager.instance; } + async recoverLogin() { + return new Promise((resolve, reject) => { + console.log(this.#token); + if (this.#token !== undefined) + resolve(this.#token); + else { + SecureStore.getItemAsync('token') + .then((token) => { + console.log(token); + resolve(token); + }) + .catch(error => { + reject(false); + }); + } + }); + } + async saveLogin(email: string, token: string) { - this.#token = token; - this.#email = email; + console.log(token); return new Promise((resolve, reject) => { SecureStore.setItemAsync('token', token) .then(() => { + this.#token = token; + this.#email = email; resolve(true); }) .catch(error => { @@ -59,7 +75,7 @@ export default class ConnectionManager { body: JSON.stringify(data) }).then(async (response) => response.json()) .then((data) => { - if (this.isResponseValid(data)) { + if (this.isConnectionResponseValid(data)) { if (data.state) { this.saveLogin(email, data.token) .then(() => { @@ -79,11 +95,60 @@ export default class ConnectionManager { }); } - isResponseValid(response: Object) { - let valid = response !== undefined && response.state !== undefined; + isRequestResponseValid(response: Object) { + let valid = response !== undefined + && response.state !== undefined + && typeof response.state === "boolean"; + if (valid && response.state) - valid = valid && response.token !== undefined && response.token !== ''; + valid = valid + && response.data !== undefined + && typeof response.data === "object"; return valid; } + isConnectionResponseValid(response: Object) { + let valid = response !== undefined + && response.state !== undefined + && typeof response.state === "boolean"; + + if (valid && response.state) + valid = valid + && response.token !== undefined + && response.token !== '' + && typeof response.token === "string"; + return valid; + } + + async authenticatedRequest(url: string) { + return new Promise((resolve, reject) => { + this.recoverLogin() + .then(token => { + fetch(url, { + method: 'POST', + headers: new Headers({ + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }), + body: JSON.stringify({token: token}) + }).then(async (response) => response.json()) + .then((data) => { + console.log(data); + if (this.isRequestResponseValid(data)) { + if (data.state) + resolve(data.data); + else + reject(ERROR_TYPE.BAD_CREDENTIALS); + } else + reject(ERROR_TYPE.CONNECTION_ERROR); + }) + .catch(() => { + reject(ERROR_TYPE.CONNECTION_ERROR); + }); + }) + .catch(() => { + reject(ERROR_TYPE.NO_TOKEN); + }); + }); + } }