From 5aa3afd38351f9daf5ea12b3729c593a1ec372c3 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Mon, 30 Mar 2020 23:44:06 +0200 Subject: [PATCH] Improved connection manager and added new tests --- __tests__/managers/ConnectionManager.test.js | 136 ++++++++++++++++++- managers/ConnectionManager.js | 46 +++++-- package.json | 3 + 3 files changed, 170 insertions(+), 15 deletions(-) diff --git a/__tests__/managers/ConnectionManager.test.js b/__tests__/managers/ConnectionManager.test.js index 246983b..ace2273 100644 --- a/__tests__/managers/ConnectionManager.test.js +++ b/__tests__/managers/ConnectionManager.test.js @@ -1,15 +1,143 @@ import React from 'react'; import ConnectionManager, {ERROR_TYPE} from "../../managers/ConnectionManager"; +import * as SecureStore from 'expo-secure-store'; + +let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native -const fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native const c = ConnectionManager.getInstance(); test("connect bad credentials", () => { - return expect(c.connect('truc', 'chose')) + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + state: false, + message: 'Adresse mail ou mot de passe incorrect', + token: '' + } + }, + }) + }); + return expect(c.connect('email', 'password')) .rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS); }); test("connect good credentials", () => { - return expect(c.connect('vergnet@etud.insa-toulouse.fr', 'Coucoù512')) - .resolves.toBe('test'); + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + state: true, + message: 'Connexion confirmée', + token: 'token' + } + }, + }) + }); + jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { + return Promise.resolve(true); + }); + return expect(c.connect('email', 'password')).resolves.toBeTruthy(); +}); + +test("connect good credentials, fail save token", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + state: true, + message: 'Connexion confirmée', + token: 'token' + } + }, + }) + }); + jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { + return Promise.reject(false); + }); + return expect(c.connect('email', 'password')).rejects.toBe(ERROR_TYPE.SAVE_TOKEN); +}); + +test("connect connection error", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.reject(); + }); + return expect(c.connect('email', 'password')) + .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); +}); + +test("connect bogus response 1", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + thing: true, + wrong: '', + } + }, + }) + }); + return expect(c.connect('email', 'password')) + .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); +}); + +test("connect bogus response 2", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + state: true, + message: '', + } + }, + }) + }); + return expect(c.connect('email', 'password')) + .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); +}); + +test("connect bogus response 3", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + state: false, + message: '', + } + }, + }) + }); + return expect(c.connect('email', 'password')) + .rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS); +}); + +test("connect bogus response 4", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + message: '', + token: '', + } + }, + }) + }); + return expect(c.connect('email', 'password')) + .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); +}); + +test("connect bogus response 5", () => { + jest.spyOn(global, 'fetch').mockImplementationOnce(() => { + return Promise.resolve({ + json: () => { + return { + state: true, + message: 'Connexion confirmée', + token: '' + } + }, + }) + }); + return expect(c.connect('email', 'password')) + .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR); }); diff --git a/managers/ConnectionManager.js b/managers/ConnectionManager.js index 64fab55..32e1ea4 100644 --- a/managers/ConnectionManager.js +++ b/managers/ConnectionManager.js @@ -1,8 +1,11 @@ // @flow +import * as SecureStore from 'expo-secure-store'; + export const ERROR_TYPE = { BAD_CREDENTIALS: 0, - CONNECTION_ERROR: 1 + CONNECTION_ERROR: 1, + SAVE_TOKEN: 2, }; const AUTH_URL = "https://www.amicale-insat.fr/api/password"; @@ -27,6 +30,20 @@ export default class ConnectionManager { ConnectionManager.instance; } + async saveLogin(email: string, token: string) { + this.#token = token; + this.#email = email; + return new Promise((resolve, reject) => { + SecureStore.setItemAsync('token', token) + .then(() => { + resolve(true); + }) + .catch(error => { + reject(false); + }); + }); + } + async connect(email: string, password: string) { let data = { email: email, @@ -42,24 +59,31 @@ export default class ConnectionManager { body: JSON.stringify(data) }).then(async (response) => response.json()) .then((data) => { - console.log(data); - if (this.isResponseValid(data)) - resolve({success: data.success, token: data.token}); - else - reject(ERROR_TYPE.BAD_CREDENTIALS); + if (this.isResponseValid(data)) { + if (data.state) { + this.saveLogin(email, data.token) + .then(() => { + resolve(true); + }) + .catch(() => { + reject(ERROR_TYPE.SAVE_TOKEN); + }); + } else + reject(ERROR_TYPE.BAD_CREDENTIALS); + } else + reject(ERROR_TYPE.CONNECTION_ERROR); }) .catch((error) => { - console.log(error); reject(ERROR_TYPE.CONNECTION_ERROR); }); }); } isResponseValid(response: Object) { - return response !== undefined - && response.success !== undefined - && response.success - && response.token !== undefined; + let valid = response !== undefined && response.state !== undefined; + if (valid && response.state) + valid = valid && response.token !== undefined && response.token !== ''; + return valid; } } diff --git a/package.json b/package.json index 23bc6b6..5c45062 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,9 @@ }, "jest": { "preset": "react-native", + "transformIgnorePatterns": [ + "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base)" + ], "setupFilesAfterEnv": [ "jest-extended" ]