express-generator-typescript 2.4.6 → 2.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/express-generator-typescript.js +1 -1
- package/lib/project-files/package.json +4 -3
- package/lib/project-files/spec/support/apiCb.ts +76 -0
- package/lib/project-files/spec/tests/users.spec.ts +102 -127
- package/lib/project-files/spec/types/misc.ts +18 -0
- package/lib/project-files/src/models/User.ts +13 -27
- package/lib/project-files/src/public/scripts/http.js +3 -1
- package/lib/project-files/src/public/scripts/users.js +31 -65
- package/lib/project-files/src/public/stylesheets/users.css +4 -6
- package/lib/project-files/src/repos/UserRepo.ts +6 -1
- package/lib/project-files/src/repos/database.json +22 -1
- package/lib/project-files/src/routes/types/express/misc.ts +1 -5
- package/lib/project-files/src/routes/types/types.ts +0 -8
- package/lib/project-files/src/views/users.html +100 -5
- package/lib/project-files-auth/package.json +4 -3
- package/lib/project-files-auth/spec/support/apiCb.ts +76 -0
- package/lib/project-files-auth/spec/support/login.ts +6 -8
- package/lib/project-files-auth/spec/tests/auth.spec.ts +52 -59
- package/lib/project-files-auth/spec/tests/users.spec.ts +101 -133
- package/lib/project-files-auth/spec/types/misc.ts +18 -0
- package/lib/project-files-auth/src/models/User.ts +17 -12
- package/lib/project-files-auth/src/public/scripts/http.js +3 -1
- package/lib/project-files-auth/src/public/scripts/login.js +1 -3
- package/lib/project-files-auth/src/public/scripts/users.js +31 -63
- package/lib/project-files-auth/src/public/stylesheets/users.css +4 -11
- package/lib/project-files-auth/src/repos/UserRepo.ts +6 -1
- package/lib/project-files-auth/src/repos/database.json +1 -1
- package/lib/project-files-auth/src/services/UserService.ts +2 -8
- package/lib/project-files-auth/src/views/login.html +26 -3
- package/lib/project-files-auth/src/views/users.html +106 -8
- package/package.json +1 -1
- package/lib/project-files/spec/support/types.ts +0 -1
- package/lib/project-files-auth/spec/support/types.ts +0 -1
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
//
|
|
1
|
+
// **** Variables **** //
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const DateFormatter = new Intl.DateTimeFormat('en-US', {
|
|
4
|
+
year: 'numeric',
|
|
5
|
+
month: '2-digit',
|
|
6
|
+
day: '2-digit',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const formatDate = (date) => DateFormatter.format(new Date(date));
|
|
4
10
|
|
|
5
11
|
|
|
6
|
-
//
|
|
12
|
+
// **** Run **** //
|
|
13
|
+
|
|
14
|
+
// Start
|
|
15
|
+
displayUsers();
|
|
7
16
|
|
|
8
17
|
/**
|
|
9
18
|
* Call api
|
|
@@ -12,59 +21,22 @@ function displayUsers() {
|
|
|
12
21
|
Http
|
|
13
22
|
.get('/api/users/all')
|
|
14
23
|
.then(resp => resp.json())
|
|
15
|
-
.then(
|
|
16
|
-
var
|
|
17
|
-
|
|
24
|
+
.then(resp => {
|
|
25
|
+
var allUsersTemplate = document.getElementById('all-users-template'),
|
|
26
|
+
allUsersTemplateHtml = allUsersTemplate.innerHTML,
|
|
27
|
+
template = Handlebars.compile(allUsersTemplateHtml);
|
|
18
28
|
var allUsersAnchor = document.getElementById('all-users-anchor');
|
|
19
|
-
allUsersAnchor.innerHTML =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
allUsersAnchor.innerHTML = template({
|
|
30
|
+
users: resp.users.map(user => ({
|
|
31
|
+
...user,
|
|
32
|
+
createdFormatted: formatDate(user.created),
|
|
33
|
+
})),
|
|
23
34
|
});
|
|
24
35
|
});
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
/**
|
|
28
|
-
* Get user display element
|
|
29
|
-
*/
|
|
30
|
-
function getUserDisplayEle(user) {
|
|
31
|
-
return (
|
|
32
|
-
`<div class="user-display-ele">
|
|
33
|
-
|
|
34
|
-
<div class="normal-view">
|
|
35
|
-
<div>Name: ${user.name}</div>
|
|
36
|
-
<div>Email: ${user.email}</div>
|
|
37
|
-
<button class="edit-user-btn" data-user-id="${user.id}" data-user-role="${user.role}">
|
|
38
|
-
Edit
|
|
39
|
-
</button>
|
|
40
|
-
<button class="delete-user-btn" data-user-id="${user.id}">
|
|
41
|
-
Delete
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<div class="edit-view">
|
|
46
|
-
<div>
|
|
47
|
-
Name: <input class="name-edit-input" value="${user.name}">
|
|
48
|
-
</div>
|
|
49
|
-
<div>
|
|
50
|
-
Email: <input class="email-edit-input" value="${user.email}">
|
|
51
|
-
</div>
|
|
52
|
-
<button class="submit-edit-btn" data-user-id="${user.id}">
|
|
53
|
-
Submit
|
|
54
|
-
</button>
|
|
55
|
-
<button class="cancel-edit-btn" data-user-id="${user.id}">
|
|
56
|
-
Cancel
|
|
57
|
-
</button>
|
|
58
|
-
</div>
|
|
59
|
-
</div>`
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// **** Add, Edit, and Delete Users **** //
|
|
65
|
-
|
|
66
38
|
// Setup event listener for button click
|
|
67
|
-
document.addEventListener('click',
|
|
39
|
+
document.addEventListener('click', event => {
|
|
68
40
|
event.preventDefault();
|
|
69
41
|
var ele = event.target;
|
|
70
42
|
if (ele.matches('#add-user-btn')) {
|
|
@@ -77,8 +49,6 @@ document.addEventListener('click', function (event) {
|
|
|
77
49
|
submitEdit(ele);
|
|
78
50
|
} else if (ele.matches('.delete-user-btn')) {
|
|
79
51
|
deleteUser(ele);
|
|
80
|
-
} else if (ele.matches('#logout-btn')) {
|
|
81
|
-
logoutUser();
|
|
82
52
|
}
|
|
83
53
|
}, false);
|
|
84
54
|
|
|
@@ -93,13 +63,17 @@ function addUser() {
|
|
|
93
63
|
id: -1,
|
|
94
64
|
name: nameInput.value,
|
|
95
65
|
email: emailInput.value,
|
|
96
|
-
|
|
66
|
+
created: new Date(),
|
|
97
67
|
},
|
|
98
68
|
};
|
|
99
69
|
// Call api
|
|
100
70
|
Http
|
|
101
71
|
.post('/api/users/add', data)
|
|
102
|
-
.then(() =>
|
|
72
|
+
.then(() => {
|
|
73
|
+
nameInput.value = '';
|
|
74
|
+
emailInput.value = '';
|
|
75
|
+
displayUsers();
|
|
76
|
+
});
|
|
103
77
|
}
|
|
104
78
|
|
|
105
79
|
/**
|
|
@@ -130,13 +104,14 @@ function submitEdit(ele) {
|
|
|
130
104
|
var nameInput = userEle.getElementsByClassName('name-edit-input')[0];
|
|
131
105
|
var emailInput = userEle.getElementsByClassName('email-edit-input')[0];
|
|
132
106
|
var id = ele.getAttribute('data-user-id');
|
|
133
|
-
var
|
|
107
|
+
var created = ele.getAttribute('data-user-created');
|
|
108
|
+
console.log(ele, created)
|
|
134
109
|
var data = {
|
|
135
110
|
user: {
|
|
136
111
|
id: Number(id),
|
|
137
112
|
name: nameInput.value,
|
|
138
113
|
email: emailInput.value,
|
|
139
|
-
|
|
114
|
+
created: new Date(created),
|
|
140
115
|
},
|
|
141
116
|
};
|
|
142
117
|
Http
|
|
@@ -153,12 +128,3 @@ function deleteUser(ele) {
|
|
|
153
128
|
.delete('/api/users/delete/' + id)
|
|
154
129
|
.then(() => displayUsers());
|
|
155
130
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// **** Logout **** //
|
|
159
|
-
|
|
160
|
-
function logoutUser() {
|
|
161
|
-
Http
|
|
162
|
-
.get('/api/auth/logout')
|
|
163
|
-
.then(() => window.location.href = '/');
|
|
164
|
-
}
|
|
@@ -27,15 +27,13 @@ body .add-user-col #add-user-btn {
|
|
|
27
27
|
margin-bottom: 10px;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
body .add-user-col #logout-btn {
|
|
31
|
-
margin-top: 25px;
|
|
32
|
-
margin-bottom: 10px;
|
|
33
|
-
font-size: 15px;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
30
|
|
|
37
31
|
/** Users Display Column **/
|
|
38
32
|
|
|
33
|
+
.email-edit {
|
|
34
|
+
padding-bottom: 8px;
|
|
35
|
+
}
|
|
36
|
+
|
|
39
37
|
body .users-column .user-display-ele {
|
|
40
38
|
padding-bottom: 10px;
|
|
41
39
|
}
|
|
@@ -56,7 +56,12 @@ async function update(user: IUser): Promise<void> {
|
|
|
56
56
|
const db = await orm.openDb();
|
|
57
57
|
for (let i = 0; i < db.users.length; i++) {
|
|
58
58
|
if (db.users[i].id === user.id) {
|
|
59
|
-
db.users[i]
|
|
59
|
+
const dbUser = db.users[i];
|
|
60
|
+
db.users[i] = {
|
|
61
|
+
...dbUser,
|
|
62
|
+
name: user.name,
|
|
63
|
+
email: user.email,
|
|
64
|
+
};
|
|
60
65
|
return orm.saveDb(db);
|
|
61
66
|
}
|
|
62
67
|
}
|
|
@@ -1 +1,22 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"users": [
|
|
3
|
+
{
|
|
4
|
+
"id": 366115170645,
|
|
5
|
+
"name": "Sean Maxwell",
|
|
6
|
+
"email": "smaxwell@example.com",
|
|
7
|
+
"created": "2024-03-22T05:14:36.252Z"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": 310946254456,
|
|
11
|
+
"name": "John Smith",
|
|
12
|
+
"email": "john.smith@example.com",
|
|
13
|
+
"created": "2024-03-22T05:20:55.079Z"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": 143027113460,
|
|
17
|
+
"name": "Gordan Freeman",
|
|
18
|
+
"email": "nova@prospect.com",
|
|
19
|
+
"created": "2024-03-22T05:42:18.895Z"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import * as e from 'express';
|
|
2
2
|
|
|
3
|
-
import { ISessionUser } from '@src/models/User';
|
|
4
|
-
|
|
5
3
|
|
|
6
4
|
// **** Express **** //
|
|
7
5
|
|
|
@@ -10,7 +8,5 @@ export interface IReq<T = void> extends e.Request {
|
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
export interface IRes extends e.Response {
|
|
13
|
-
locals:
|
|
14
|
-
sessionUser?: ISessionUser;
|
|
15
|
-
};
|
|
11
|
+
locals: Record<string, unknown>;
|
|
16
12
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as e from 'express';
|
|
2
2
|
import { Query } from 'express-serve-static-core';
|
|
3
3
|
|
|
4
|
-
import { ISessionUser } from '@src/models/User';
|
|
5
|
-
|
|
6
4
|
|
|
7
5
|
// **** Express **** //
|
|
8
6
|
|
|
@@ -14,9 +12,3 @@ export interface IReqQuery<T extends Query, U = void> extends e.Request {
|
|
|
14
12
|
query: T;
|
|
15
13
|
body: U;
|
|
16
14
|
}
|
|
17
|
-
|
|
18
|
-
export interface IRes extends e.Response {
|
|
19
|
-
locals: {
|
|
20
|
-
sessionUser: ISessionUser;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<!-- Head -->
|
|
3
5
|
<head>
|
|
4
6
|
<meta charset="UTF-8">
|
|
5
7
|
<title>Users</title>
|
|
6
8
|
<link rel="stylesheet" type="text/css" href="/stylesheets/users.css" />
|
|
9
|
+
|
|
10
|
+
<!-- Handlebars -->
|
|
11
|
+
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>
|
|
12
|
+
|
|
13
|
+
<!-- Bootstrap -->
|
|
14
|
+
<link
|
|
15
|
+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
|
16
|
+
rel="stylesheet"
|
|
17
|
+
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
|
18
|
+
crossorigin="anonymous"
|
|
19
|
+
/>
|
|
20
|
+
<script
|
|
21
|
+
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
|
22
|
+
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
|
23
|
+
crossorigin="anonymous"
|
|
24
|
+
></script>
|
|
7
25
|
</head>
|
|
26
|
+
|
|
27
|
+
<!-- Body -->
|
|
8
28
|
<body>
|
|
9
29
|
|
|
10
30
|
<!-- Add Users -->
|
|
@@ -13,13 +33,26 @@
|
|
|
13
33
|
Add User:
|
|
14
34
|
</div>
|
|
15
35
|
<div>
|
|
16
|
-
<input
|
|
36
|
+
<input
|
|
37
|
+
id="name-input"
|
|
38
|
+
type="text"
|
|
39
|
+
class="form-control"
|
|
40
|
+
placeholder="Name"
|
|
41
|
+
/>
|
|
17
42
|
</div>
|
|
18
43
|
<div>
|
|
19
|
-
<input
|
|
44
|
+
<input
|
|
45
|
+
id="email-input"
|
|
46
|
+
type="email"
|
|
47
|
+
class="form-control"
|
|
48
|
+
placeholder="Email"
|
|
49
|
+
/>
|
|
20
50
|
</div>
|
|
21
51
|
<div>
|
|
22
|
-
<button
|
|
52
|
+
<button
|
|
53
|
+
id="add-user-btn"
|
|
54
|
+
class="btn btn-success"
|
|
55
|
+
>
|
|
23
56
|
Add
|
|
24
57
|
</button>
|
|
25
58
|
</div>
|
|
@@ -27,11 +60,73 @@
|
|
|
27
60
|
|
|
28
61
|
<!-- Display Users -->
|
|
29
62
|
<div class="users-column">
|
|
30
|
-
<div class="column-header">
|
|
63
|
+
<div class="column-header">
|
|
64
|
+
Users:
|
|
65
|
+
</div>
|
|
66
|
+
|
|
31
67
|
<div id="all-users-anchor"></div>
|
|
32
|
-
|
|
68
|
+
<script
|
|
69
|
+
id="all-users-template"
|
|
70
|
+
type="text/x-handlebars-template"
|
|
71
|
+
>
|
|
72
|
+
{{#each users}}
|
|
73
|
+
<div class="user-display-ele">
|
|
74
|
+
<div class="normal-view">
|
|
75
|
+
<div><b>Name:</b> {{name}}</div>
|
|
76
|
+
<div><b>Email:</b> {{email}}</div>
|
|
77
|
+
<div><b>Created:</b> {{createdFormatted}}</div>
|
|
78
|
+
<button
|
|
79
|
+
type="button"
|
|
80
|
+
class="btn btn-primary edit-user-btn"
|
|
81
|
+
data-user-id="{{id}}"
|
|
82
|
+
>
|
|
83
|
+
Edit
|
|
84
|
+
</button>
|
|
85
|
+
<button
|
|
86
|
+
class="btn btn-danger delete-user-btn"
|
|
87
|
+
data-user-id="{{id}}"
|
|
88
|
+
>
|
|
89
|
+
Delete
|
|
90
|
+
</button>
|
|
91
|
+
</div>
|
|
33
92
|
|
|
93
|
+
<div class="edit-view">
|
|
94
|
+
<div>
|
|
95
|
+
Name:
|
|
96
|
+
<input
|
|
97
|
+
type="text"
|
|
98
|
+
class="form-control name-edit-input"
|
|
99
|
+
value="{{name}}"
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="email-edit">
|
|
103
|
+
Email:
|
|
104
|
+
<input
|
|
105
|
+
type="email"
|
|
106
|
+
class="form-control email-edit-input"
|
|
107
|
+
value="{{email}}"
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
<button
|
|
111
|
+
class="btn btn-primary submit-edit-btn"
|
|
112
|
+
data-user-id="{{id}}"
|
|
113
|
+
data-user-created="{{created}}"
|
|
114
|
+
>
|
|
115
|
+
Submit
|
|
116
|
+
</button>
|
|
117
|
+
<button
|
|
118
|
+
class="btn btn-secondary cancel-edit-btn"
|
|
119
|
+
data-user-id="{{id}}"
|
|
120
|
+
>
|
|
121
|
+
Cancel
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
{{/each}}
|
|
126
|
+
</script>
|
|
127
|
+
</div>
|
|
34
128
|
</body>
|
|
129
|
+
|
|
35
130
|
<script src="scripts/http.js"></script>
|
|
36
131
|
<script src="scripts/users.js"></script>
|
|
37
132
|
</html>
|
|
@@ -35,11 +35,12 @@
|
|
|
35
35
|
"helmet": "^6.0.0",
|
|
36
36
|
"inserturlparams": "^1.0.1",
|
|
37
37
|
"jet-logger": "^1.3.1",
|
|
38
|
-
"jet-validator": "^1.0.3",
|
|
39
38
|
"jet-paths": "^1.0.5",
|
|
39
|
+
"jet-validator": "^1.0.3",
|
|
40
40
|
"jsonfile": "^6.1.0",
|
|
41
41
|
"jsonwebtoken": "^8.5.1",
|
|
42
42
|
"module-alias": "^2.2.2",
|
|
43
|
+
"moment": "^2.30.1",
|
|
43
44
|
"morgan": "^1.10.0",
|
|
44
45
|
"ts-command-line-args": "^2.4.2"
|
|
45
46
|
},
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
"@types/jsonwebtoken": "^8.5.9",
|
|
55
56
|
"@types/morgan": "^1.9.3",
|
|
56
57
|
"@types/node": "^18.7.14",
|
|
57
|
-
"@types/supertest": "^
|
|
58
|
+
"@types/supertest": "^6.0.2",
|
|
58
59
|
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
|
59
60
|
"@typescript-eslint/parser": "^5.36.1",
|
|
60
61
|
"eslint": "^8.23.0",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"fs-extra": "^10.1.0",
|
|
64
65
|
"jasmine": "^4.3.0",
|
|
65
66
|
"nodemon": "^2.0.19",
|
|
66
|
-
"supertest": "^6.
|
|
67
|
+
"supertest": "^6.3.4",
|
|
67
68
|
"ts-node": "^10.9.1",
|
|
68
69
|
"tsconfig-paths": "^4.1.0",
|
|
69
70
|
"typescript": "^4.8.2"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CallbackHandler } from 'supertest';
|
|
2
|
+
import moment from 'moment';
|
|
3
|
+
import logger from 'jet-logger';
|
|
4
|
+
|
|
5
|
+
import { TApiCb, TRes } from 'spec/types/misc';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* API callback function.
|
|
10
|
+
*/
|
|
11
|
+
function apiCb(
|
|
12
|
+
cb: TApiCb,
|
|
13
|
+
dateParam = 'created',
|
|
14
|
+
printErr?: boolean,
|
|
15
|
+
): CallbackHandler {
|
|
16
|
+
return (err: Error, res: TRes) => {
|
|
17
|
+
if (printErr) {
|
|
18
|
+
logger.err(err);
|
|
19
|
+
}
|
|
20
|
+
_strToDate(res.body, dateParam);
|
|
21
|
+
return cb(res);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* When date objects get sent through supertest they are converted to
|
|
27
|
+
* iso-strings. This will cause "toEqual()"" tests to fail, so we need to
|
|
28
|
+
* convert them back to Date objects.
|
|
29
|
+
*/
|
|
30
|
+
function _strToDate(
|
|
31
|
+
param: unknown,
|
|
32
|
+
prop: string,
|
|
33
|
+
): void {
|
|
34
|
+
return _iterate(param, prop);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Interate object recursively and convert string-dates to "Date" objects.
|
|
39
|
+
*/
|
|
40
|
+
function _iterate(param: unknown, prop: string): void {
|
|
41
|
+
if (!param || typeof param !== 'object') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const paramF = param as Record<string, unknown>;
|
|
45
|
+
// For Arrays
|
|
46
|
+
if (Array.isArray(paramF)) {
|
|
47
|
+
for (const item of paramF) {
|
|
48
|
+
_iterate(item, prop);
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Check valid string or Date object. If undefined just skip
|
|
53
|
+
const val = paramF[prop];
|
|
54
|
+
if (
|
|
55
|
+
(typeof val !== 'undefined') &&
|
|
56
|
+
!((typeof val === 'string') || (val instanceof Date)) &&
|
|
57
|
+
!moment(val as string | Date).isValid()
|
|
58
|
+
) {
|
|
59
|
+
throw new Error('Property must be a valid date-string or Date() object');
|
|
60
|
+
}
|
|
61
|
+
// Convert and iterate
|
|
62
|
+
if (typeof val !== 'undefined') {
|
|
63
|
+
paramF[prop] = new Date(val as string | Date);
|
|
64
|
+
}
|
|
65
|
+
for (const key in paramF) {
|
|
66
|
+
const oval = paramF[key];
|
|
67
|
+
if (typeof oval === 'object' && key !== prop) {
|
|
68
|
+
_iterate(oval, prop);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
// **** Export default **** //
|
|
75
|
+
|
|
76
|
+
export default apiCb;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Test, Response } from 'supertest';
|
|
2
|
+
import TestAgent from 'supertest/lib/agent';
|
|
2
3
|
|
|
3
4
|
import User, { UserRoles } from '@src/models/User';
|
|
4
5
|
import UserRepo from '@src/repos/UserRepo';
|
|
@@ -7,24 +8,21 @@ import PwdUtil from '@src/util/PwdUtil';
|
|
|
7
8
|
import Paths from './Paths';
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
//
|
|
11
|
-
|
|
11
|
+
// Login Credentials
|
|
12
12
|
const LoginCreds = {
|
|
13
13
|
email: 'jsmith@gmail.com',
|
|
14
14
|
password: 'Password@1',
|
|
15
15
|
} as const;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
// **** Functions **** //
|
|
19
|
-
|
|
20
17
|
/**
|
|
21
18
|
* Login a user.
|
|
22
19
|
*/
|
|
23
|
-
function login(beforeAgent:
|
|
20
|
+
function login(beforeAgent: TestAgent<Test>, done: (arg: string) => void) {
|
|
24
21
|
// Setup dummy data
|
|
25
22
|
const role = UserRoles.Admin,
|
|
26
23
|
pwdHash = PwdUtil.hashSync(LoginCreds.password),
|
|
27
|
-
loginUser = User.new('john smith', LoginCreds.email, role,
|
|
24
|
+
loginUser = User.new('john smith', LoginCreds.email, new Date(), role,
|
|
25
|
+
pwdHash);
|
|
28
26
|
// Add spy
|
|
29
27
|
spyOn(UserRepo, 'getOne').and.resolveTo(loginUser);
|
|
30
28
|
// Call Login API
|