Browse Source

Added authenticated post request support and added more tests

Arnaud Vergnet 4 years ago
parent
commit
4259dd779d
2 changed files with 241 additions and 42 deletions
  1. 166
    32
      __tests__/managers/ConnectionManager.test.js
  2. 75
    10
      managers/ConnectionManager.js

+ 166
- 32
__tests__/managers/ConnectionManager.test.js View File

@@ -6,6 +6,129 @@ let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS b
6 6
 
7 7
 const c = ConnectionManager.getInstance();
8 8
 
9
+afterEach(() => {
10
+    jest.restoreAllMocks();
11
+});
12
+
13
+test('recoverLogin error crypto', () => {
14
+    jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
15
+        return Promise.reject();
16
+    });
17
+    return expect(c.recoverLogin()).rejects.toBe(false);
18
+});
19
+
20
+test('recoverLogin success crypto', () => {
21
+    jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
22
+        return Promise.resolve('token1');
23
+    });
24
+    return expect(c.recoverLogin()).resolves.toBe('token1');
25
+});
26
+
27
+test('saveLogin success', () => {
28
+    jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
29
+        return Promise.resolve();
30
+    });
31
+    return expect(c.saveLogin('email', 'token2')).resolves.toBeTruthy();
32
+});
33
+
34
+test('saveLogin error', () => {
35
+    jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
36
+        return Promise.reject();
37
+    });
38
+    return expect(c.saveLogin('email', 'token3')).rejects.toBeFalsy();
39
+});
40
+
41
+test('recoverLogin error crypto with saved token', () => {
42
+    jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
43
+        return Promise.reject();
44
+    });
45
+    return expect(c.recoverLogin()).resolves.toBe('token2');
46
+});
47
+
48
+test('recoverLogin success saved', () => {
49
+    return expect(c.recoverLogin()).resolves.toBe('token2');
50
+});
51
+
52
+test('isRequestResponseValid', () => {
53
+    let json = {
54
+        state: true,
55
+        data: {}
56
+    };
57
+    expect(c.isRequestResponseValid(json)).toBeTrue();
58
+    json = {
59
+        state: false,
60
+        data: {}
61
+    };
62
+    expect(c.isRequestResponseValid(json)).toBeTrue();
63
+    json = {
64
+        state: false,
65
+        message: 'coucou',
66
+        data: {truc: 'machin'}
67
+    };
68
+    expect(c.isRequestResponseValid(json)).toBeTrue();
69
+    json = {
70
+        message: 'coucou'
71
+    };
72
+    expect(c.isRequestResponseValid(json)).toBeFalse();
73
+    json = {
74
+        state: 'coucou'
75
+    };
76
+    expect(c.isRequestResponseValid(json)).toBeFalse();
77
+    json = {
78
+        state: true,
79
+    };
80
+    expect(c.isRequestResponseValid(json)).toBeFalse();
81
+});
82
+
83
+test("isConnectionResponseValid", () => {
84
+    let json = {
85
+        state: true,
86
+        message: 'Connexion confirmée',
87
+        token: 'token'
88
+    };
89
+    expect(c.isConnectionResponseValid(json)).toBeTrue();
90
+    json = {
91
+        state: true,
92
+        token: 'token'
93
+    };
94
+    expect(c.isConnectionResponseValid(json)).toBeTrue();
95
+    json = {
96
+        state: false,
97
+    };
98
+    expect(c.isConnectionResponseValid(json)).toBeTrue();
99
+
100
+    json = {
101
+        state: true,
102
+        message: 'Connexion confirmée',
103
+        token: ''
104
+    };
105
+    expect(c.isConnectionResponseValid(json)).toBeFalse();
106
+    json = {
107
+        state: true,
108
+        message: 'Connexion confirmée',
109
+    };
110
+    expect(c.isConnectionResponseValid(json)).toBeFalse();
111
+    json = {
112
+        state: 'coucou',
113
+        message: 'Connexion confirmée',
114
+        token: 'token'
115
+    };
116
+    expect(c.isConnectionResponseValid(json)).toBeFalse();
117
+    json = {
118
+        state: true,
119
+        message: 'Connexion confirmée',
120
+        token: 2
121
+    };
122
+    expect(c.isConnectionResponseValid(json)).toBeFalse();
123
+    json = {
124
+        coucou: 'coucou',
125
+        message: 'Connexion confirmée',
126
+        token: 'token'
127
+    };
128
+    expect(c.isConnectionResponseValid(json)).toBeFalse();
129
+});
130
+
131
+
9 132
 test("connect bad credentials", () => {
10 133
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
11 134
         return Promise.resolve({
@@ -26,7 +149,7 @@ test("connect good credentials", () => {
26 149
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
27 150
         return Promise.resolve({
28 151
             json: () => {
29
-                return     {
152
+                return {
30 153
                     state: true,
31 154
                     message: 'Connexion confirmée',
32 155
                     token: 'token'
@@ -34,7 +157,7 @@ test("connect good credentials", () => {
34 157
             },
35 158
         })
36 159
     });
37
-    jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
160
+    c.saveLogin = jest.fn(() => {
38 161
         return Promise.resolve(true);
39 162
     });
40 163
     return expect(c.connect('email', 'password')).resolves.toBeTruthy();
@@ -44,7 +167,7 @@ test("connect good credentials, fail save token", () => {
44 167
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
45 168
         return Promise.resolve({
46 169
             json: () => {
47
-                return     {
170
+                return {
48 171
                     state: true,
49 172
                     message: 'Connexion confirmée',
50 173
                     token: 'token'
@@ -52,7 +175,7 @@ test("connect good credentials, fail save token", () => {
52 175
             },
53 176
         })
54 177
     });
55
-    jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
178
+    c.saveLogin = jest.fn(() => {
56 179
         return Promise.reject(false);
57 180
     });
58 181
     return expect(c.connect('email', 'password')).rejects.toBe(ERROR_TYPE.SAVE_TOKEN);
@@ -70,7 +193,7 @@ test("connect bogus response 1", () => {
70 193
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
71 194
         return Promise.resolve({
72 195
             json: () => {
73
-                return     {
196
+                return {
74 197
                     thing: true,
75 198
                     wrong: '',
76 199
                 }
@@ -81,63 +204,74 @@ test("connect bogus response 1", () => {
81 204
         .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
82 205
 });
83 206
 
84
-test("connect bogus response 2", () => {
207
+
208
+test("authenticatedRequest success", () => {
209
+    c.recoverLogin = jest.fn(() => {
210
+        return Promise.resolve('token');
211
+    });
85 212
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
86 213
         return Promise.resolve({
87 214
             json: () => {
88
-                return     {
89
-                    state: true,
90
-                    message: '',
91
-                }
215
+                return {state: true, message: 'Connexion vérifiée', data: {coucou: 'toi'}}
92 216
             },
93 217
         })
94 218
     });
95
-    return expect(c.connect('email', 'password'))
96
-        .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
219
+    return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
220
+        .resolves.toStrictEqual({coucou: 'toi'});
97 221
 });
98 222
 
99
-test("connect bogus response 3", () => {
223
+test("authenticatedRequest error wrong token", () => {
224
+    c.recoverLogin = jest.fn(() => {
225
+        return Promise.resolve('token');
226
+    });
100 227
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
101 228
         return Promise.resolve({
102 229
             json: () => {
103
-                return     {
104
-                    state: false,
105
-                    message: '',
106
-                }
230
+                return {state: false, message: 'Le champ token sélectionné est invalide.'}
107 231
             },
108 232
         })
109 233
     });
110
-    return expect(c.connect('email', 'password'))
234
+    return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
111 235
         .rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS);
112 236
 });
113 237
 
114
-test("connect bogus response 4", () => {
238
+test("authenticatedRequest error bogus response", () => {
239
+    c.recoverLogin = jest.fn(() => {
240
+        return Promise.resolve('token');
241
+    });
115 242
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
116 243
         return Promise.resolve({
117 244
             json: () => {
118
-                return     {
119
-                    message: '',
120
-                    token: '',
121
-                }
245
+                return {state: true, message: 'Connexion vérifiée'}
122 246
             },
123 247
         })
124 248
     });
125
-    return expect(c.connect('email', 'password'))
249
+    return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
126 250
         .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
127 251
 });
128 252
 
129
-test("connect bogus response 5", () => {
253
+test("authenticatedRequest connection error", () => {
254
+    c.recoverLogin = jest.fn(() => {
255
+        return Promise.resolve('token');
256
+    });
257
+    jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
258
+        return Promise.reject()
259
+    });
260
+    return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
261
+        .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
262
+});
263
+
264
+test("authenticatedRequest error no token", () => {
265
+    c.recoverLogin = jest.fn(() => {
266
+        return Promise.reject(false);
267
+    });
130 268
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
131 269
         return Promise.resolve({
132 270
             json: () => {
133
-                return     {
134
-                    state: true,
135
-                    message: 'Connexion confirmée',
136
-                    token: ''
137
-                }
271
+                return {state: false, message: 'Le champ token sélectionné est invalide.'}
138 272
             },
139 273
         })
140 274
     });
141
-    return expect(c.connect('email', 'password'))
142
-        .rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
275
+    return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
276
+        .rejects.toBe(ERROR_TYPE.NO_TOKEN);
143 277
 });

+ 75
- 10
managers/ConnectionManager.js View File

@@ -6,6 +6,7 @@ export const ERROR_TYPE = {
6 6
     BAD_CREDENTIALS: 0,
7 7
     CONNECTION_ERROR: 1,
8 8
     SAVE_TOKEN: 2,
9
+    NO_TOKEN: 3,
9 10
 };
10 11
 
11 12
 const AUTH_URL = "https://www.amicale-insat.fr/api/password";
@@ -16,10 +17,6 @@ export default class ConnectionManager {
16 17
     #email: string;
17 18
     #token: string;
18 19
 
19
-    constructor() {
20
-
21
-    }
22
-
23 20
     /**
24 21
      * Get this class instance or create one if none is found
25 22
      * @returns {ConnectionManager}
@@ -30,12 +27,31 @@ export default class ConnectionManager {
30 27
             ConnectionManager.instance;
31 28
     }
32 29
 
30
+    async recoverLogin() {
31
+        return new Promise((resolve, reject) => {
32
+            console.log(this.#token);
33
+            if (this.#token !== undefined)
34
+                resolve(this.#token);
35
+            else {
36
+                SecureStore.getItemAsync('token')
37
+                    .then((token) => {
38
+                        console.log(token);
39
+                        resolve(token);
40
+                    })
41
+                    .catch(error => {
42
+                        reject(false);
43
+                    });
44
+            }
45
+        });
46
+    }
47
+
33 48
     async saveLogin(email: string, token: string) {
34
-        this.#token = token;
35
-        this.#email = email;
49
+        console.log(token);
36 50
         return new Promise((resolve, reject) => {
37 51
             SecureStore.setItemAsync('token', token)
38 52
                 .then(() => {
53
+                    this.#token = token;
54
+                    this.#email = email;
39 55
                     resolve(true);
40 56
                 })
41 57
                 .catch(error => {
@@ -59,7 +75,7 @@ export default class ConnectionManager {
59 75
                 body: JSON.stringify(data)
60 76
             }).then(async (response) => response.json())
61 77
                 .then((data) => {
62
-                    if (this.isResponseValid(data)) {
78
+                    if (this.isConnectionResponseValid(data)) {
63 79
                         if (data.state) {
64 80
                             this.saveLogin(email, data.token)
65 81
                                 .then(() => {
@@ -79,11 +95,60 @@ export default class ConnectionManager {
79 95
         });
80 96
     }
81 97
 
82
-    isResponseValid(response: Object) {
83
-        let valid = response !== undefined && response.state !== undefined;
98
+    isRequestResponseValid(response: Object) {
99
+        let valid = response !== undefined
100
+            && response.state !== undefined
101
+            && typeof response.state === "boolean";
102
+
103
+        if (valid && response.state)
104
+            valid = valid
105
+                && response.data !== undefined
106
+                && typeof response.data === "object";
107
+        return valid;
108
+    }
109
+
110
+    isConnectionResponseValid(response: Object) {
111
+        let valid = response !== undefined
112
+            && response.state !== undefined
113
+            && typeof response.state === "boolean";
114
+
84 115
         if (valid && response.state)
85
-            valid = valid && response.token !== undefined && response.token !== '';
116
+            valid = valid
117
+                && response.token !== undefined
118
+                && response.token !== ''
119
+                && typeof response.token === "string";
86 120
         return valid;
87 121
     }
88 122
 
123
+    async authenticatedRequest(url: string) {
124
+        return new Promise((resolve, reject) => {
125
+            this.recoverLogin()
126
+                .then(token => {
127
+                    fetch(url, {
128
+                        method: 'POST',
129
+                        headers: new Headers({
130
+                            'Accept': 'application/json',
131
+                            'Content-Type': 'application/json',
132
+                        }),
133
+                        body: JSON.stringify({token: token})
134
+                    }).then(async (response) => response.json())
135
+                        .then((data) => {
136
+                            console.log(data);
137
+                            if (this.isRequestResponseValid(data)) {
138
+                                if (data.state)
139
+                                    resolve(data.data);
140
+                                else
141
+                                    reject(ERROR_TYPE.BAD_CREDENTIALS);
142
+                            } else
143
+                                reject(ERROR_TYPE.CONNECTION_ERROR);
144
+                        })
145
+                        .catch(() => {
146
+                            reject(ERROR_TYPE.CONNECTION_ERROR);
147
+                        });
148
+                })
149
+                .catch(() => {
150
+                    reject(ERROR_TYPE.NO_TOKEN);
151
+                });
152
+        });
153
+    }
89 154
 }

Loading…
Cancel
Save