@webresto/graphql 1.3.7 → 1.3.8
Sign up to get free protection for your applications and to get access to all the features.
- package/.gitattributes +2 -0
- package/.gitlab-ci.yml +18 -0
- package/.vscode/extensions.json +5 -0
- package/docs/actions.md +25 -0
- package/docs/authorization.md +215 -0
- package/docs/captcha.md +71 -0
- package/docs/device-id.md +30 -0
- package/docs/messages.md +10 -0
- package/docs/user.md +54 -0
- package/index.d.ts +0 -1
- package/index.js +6 -2
- package/index.ts +2 -2
- package/lib/afterHook.js +8 -0
- package/lib/afterHook.ts +9 -0
- package/lib/bindTranslations.d.ts +1 -0
- package/lib/bindTranslations.js +40 -0
- package/lib/bindTranslations.ts +39 -0
- package/lib/defaults.d.ts +1 -0
- package/lib/defaults.js +49 -10
- package/lib/defaults.ts +55 -0
- package/lib/eventHelper.d.ts +14 -5
- package/lib/eventHelper.js +28 -9
- package/lib/eventHelper.ts +41 -8
- package/lib/getRecomended.d.ts +1 -0
- package/lib/getRecomended.js +29 -0
- package/lib/getRecomended.ts +31 -0
- package/lib/graphqlHelper.d.ts +3 -4
- package/lib/graphqlHelper.js +184 -72
- package/lib/graphqlHelper.ts +329 -185
- package/lib/jwt.d.ts +10 -0
- package/lib/jwt.js +43 -0
- package/lib/jwt.ts +61 -0
- package/package.json +13 -6
- package/src/additionalResolvers.d.ts +72 -9
- package/src/additionalResolvers.js +93 -24
- package/src/additionalResolvers.ts +105 -34
- package/src/graphql.d.ts +5 -3
- package/src/graphql.js +170 -37
- package/src/graphql.ts +210 -60
- package/src/resolvers/bonusProgram.d.ts +32 -0
- package/src/resolvers/bonusProgram.js +65 -0
- package/src/resolvers/bonusProgram.ts +79 -0
- package/src/resolvers/captcha.d.ts +11 -0
- package/src/resolvers/captcha.js +19 -0
- package/src/resolvers/captcha.ts +16 -0
- package/src/resolvers/checkout.d.ts +35 -16
- package/src/resolvers/checkout.js +171 -94
- package/src/resolvers/checkout.ts +214 -104
- package/src/resolvers/dishAndModifier.js +8 -4
- package/src/resolvers/dishAndModifier.ts +4 -0
- package/src/resolvers/error.d.ts +9 -0
- package/src/resolvers/error.js +21 -0
- package/src/resolvers/error.ts +21 -0
- package/src/resolvers/menu.d.ts +9 -0
- package/src/resolvers/menu.js +12 -0
- package/src/resolvers/menu.ts +10 -0
- package/src/resolvers/order.d.ts +527 -0
- package/src/resolvers/order.js +349 -0
- package/src/resolvers/order.ts +435 -0
- package/src/resolvers/paymentMethod.js +7 -3
- package/src/resolvers/paymentMethod.ts +9 -5
- package/src/resolvers/pickupPoint.d.ts +1 -0
- package/src/resolvers/pickupPoint.js +24 -0
- package/src/resolvers/pickupPoint.ts +23 -0
- package/src/resolvers/recomended.d.ts +13 -0
- package/src/resolvers/recomended.js +80 -0
- package/src/resolvers/recomended.ts +86 -0
- package/src/resolvers/restrictions.d.ts +37 -1
- package/src/resolvers/restrictions.js +100 -15
- package/src/resolvers/restrictions.ts +106 -14
- package/src/resolvers/streets.d.ts +1 -1
- package/src/resolvers/streets.js +1 -4
- package/src/resolvers/streets.ts +1 -3
- package/src/resolvers/subscriptions.d.ts +4 -4
- package/src/resolvers/subscriptions.js +49 -12
- package/src/resolvers/subscriptions.ts +59 -14
- package/src/resolvers/telemetry.d.ts +14 -0
- package/src/resolvers/telemetry.js +25 -0
- package/src/resolvers/telemetry.ts +24 -0
- package/src/resolvers/user.d.ts +82 -0
- package/src/resolvers/user.js +416 -0
- package/src/resolvers/user.ts +621 -0
- package/src/resolvers/userLocation.d.ts +53 -0
- package/src/resolvers/userLocation.js +74 -0
- package/src/resolvers/userLocation.ts +125 -0
- package/src/resolvers/userOTPrequest.d.ts +21 -0
- package/src/resolvers/userOTPrequest.js +57 -0
- package/src/resolvers/userOTPrequest.ts +75 -0
- package/test/e2e_helper.js +157 -0
- package/test/e2e_helper.ts +212 -0
- package/test/fixture/config/i18n.js +7 -20
- package/test/fixture/config/locales/de.json +1 -0
- package/test/fixture/config/locales/en.json +10 -0
- package/test/fixture/config/locales/es.json +3 -0
- package/test/fixture/config/locales/fr.json +1 -0
- package/test/fixture/config/log.js +1 -1
- package/test/fixture/package.json +5 -6
- package/test/fixture/patches/rttc+10.0.1.patch +17 -0
- package/test/integration/captcha.test.js +20 -0
- package/test/integration/captcha.test.ts +25 -0
- package/test/integration/dish.test.js +35 -0
- package/test/integration/dish.test.ts +43 -0
- package/test/integration/graphql.test.js +5 -2
- package/test/integration/graphql.test.ts +2 -4
- package/test/integration/images.test.js +35 -0
- package/test/integration/images.test.ts +40 -0
- package/test/integration/locale.test.js +26 -0
- package/test/integration/locale.test.ts +32 -0
- package/test/integration/order.test.js +56 -43
- package/test/integration/order.test.ts +59 -59
- package/test/integration/subscriptions.test.js +136 -0
- package/test/integration/subscriptions.test.ts +162 -0
- package/test/integration/user.test.js +249 -0
- package/test/integration/user.test.ts +299 -0
- package/test/unit/first.test.js +4 -2
- package/test/unit/first.test.ts +1 -1
- package/test/unit/get-recomended.test.js +56 -0
- package/test/unit/get-recomended.test.ts +63 -0
- package/translations/de.json +2 -0
- package/translations/en.json +3 -0
- package/translations/es.json +3 -0
- package/translations/fr.json +2 -0
- package/translations/ru.json +36 -0
- package/tsconfig.json +20 -5
- package/types/global.d.ts +30 -0
- package/types/global.js +2 -0
- package/types/global.ts +31 -0
- package/types/primitives.d.ts +19 -0
- package/types/references.d.ts +1 -0
- package/types/restoGraphQLConfig.d.ts +13 -0
- package/lib/afterHook.ts___graphql-transport-ws +0 -138
- package/lib/afterHook.ts___graphql-ws +0 -133
- package/lib/errorWrapper.d.ts +0 -4
- package/lib/errorWrapper.js +0 -13
- package/lib/errorWrapper.ts +0 -12
- package/notes.md +0 -1976
- package/src/resolvers/cart.d.ts +0 -343
- package/src/resolvers/cart.js +0 -196
- package/src/resolvers/cart.ts +0 -278
- package/test/fixture/config/connections.js +0 -9
- package/test/integration/sails_not_crash.test.js +0 -3
- package/test/integration/sails_not_crash.test.ts +0 -3
@@ -0,0 +1,249 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
process.env.CAPTCHA_POW_DIFFICUTLY = "5000";
|
4
|
+
let Puzzle = require("fix-esm").require("crypto-puzzle").default;
|
5
|
+
let graphql;
|
6
|
+
let serverInfo;
|
7
|
+
describe("User", function () {
|
8
|
+
let token;
|
9
|
+
this.timeout(50000);
|
10
|
+
// it("Login new user and setting password", async () => {
|
11
|
+
// await sleep(3000);
|
12
|
+
// graphql =
|
13
|
+
// require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
14
|
+
// let OTP = await getOTP(`1123`);
|
15
|
+
// let captcha = await resolveCaptcha(`registration:1123`);
|
16
|
+
// let phone = { code: "+1", number: "123" };
|
17
|
+
// const result = await graphql.getServer().executeOperation({
|
18
|
+
// query: `#graphql
|
19
|
+
// mutation{login(
|
20
|
+
// login: "1123",
|
21
|
+
// phone: { code: "${phone.code}", number: "${phone.number}"},
|
22
|
+
// otp: "${OTP.password}",
|
23
|
+
// password: "test123"
|
24
|
+
// captcha: {id: "${captcha.id}", solution: ${captcha.solution}}
|
25
|
+
// ){
|
26
|
+
// user {
|
27
|
+
// id
|
28
|
+
// phone {
|
29
|
+
// number
|
30
|
+
// code
|
31
|
+
// }
|
32
|
+
// lastName
|
33
|
+
// }
|
34
|
+
// message {
|
35
|
+
// message
|
36
|
+
// }
|
37
|
+
// action {
|
38
|
+
// type
|
39
|
+
// data
|
40
|
+
// }
|
41
|
+
// }}`,
|
42
|
+
// });
|
43
|
+
// if (result.errors) throw new Error(result.errors);
|
44
|
+
// const response = result.data.registration;
|
45
|
+
// expect(response.message.message).to.equal("New user created");
|
46
|
+
// assert.deepEqual(response.action, {
|
47
|
+
// type: "GoTo",
|
48
|
+
// data: {
|
49
|
+
// section: "login",
|
50
|
+
// delaySeconds: 5,
|
51
|
+
// },
|
52
|
+
// });
|
53
|
+
// expect(response.user.id).to.not.be.null;
|
54
|
+
// assert.deepEqual(response.user.phone, phone);
|
55
|
+
// });
|
56
|
+
it("Login new user passwordPolicy = from_otp, LoginOTPrequired = false", async () => {
|
57
|
+
graphql = require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
58
|
+
let captcha = await resolveCaptcha(`login:1123`);
|
59
|
+
let OTP = await getOTP(`1123`);
|
60
|
+
let query = `#graphql
|
61
|
+
mutation{login(
|
62
|
+
login: "1123",
|
63
|
+
otp: "${OTP.password}",
|
64
|
+
phone: {
|
65
|
+
code: "1",
|
66
|
+
number: "123"
|
67
|
+
},
|
68
|
+
captcha: {id: "${captcha.id}", solution: ${captcha.solution}}
|
69
|
+
){
|
70
|
+
message {
|
71
|
+
message
|
72
|
+
}
|
73
|
+
action {
|
74
|
+
type
|
75
|
+
data
|
76
|
+
}
|
77
|
+
}}`;
|
78
|
+
const loginMutation = await graphql.getServer().executeOperation({
|
79
|
+
query: query,
|
80
|
+
}, { req: { rawHeaders: ["X-Device-Id", "test001"] } });
|
81
|
+
if (loginMutation.errors)
|
82
|
+
throw new Error(loginMutation.errors);
|
83
|
+
// token = loginMutation.data?.login?.action?.data?.token;
|
84
|
+
// if (!token) throw `TOKEN JWT is not defined`;
|
85
|
+
// const auth = await JWTAuth.verify(token);
|
86
|
+
// let ud = await UserDevice.findOne({ sessionId: auth.sessionId });
|
87
|
+
// if (!ud) throw `Device not found by session`;
|
88
|
+
// if (!ud.isLogined) throw `Session is not logined`;
|
89
|
+
});
|
90
|
+
// it("Login user by password", async () => {
|
91
|
+
// await Settings.set("LOGIN_OTP_REQUIRED", false);
|
92
|
+
// token = await loginTestUserByPassword("Login user by password");
|
93
|
+
// if (!token) throw `TOKEN JWT is not defined`;
|
94
|
+
// const auth = await JWTAuth.verify(token);
|
95
|
+
// let ud = await UserDevice.findOne({ sessionId: auth.sessionId });
|
96
|
+
// if (!ud) throw `Device not found by session`;
|
97
|
+
// if (!ud.isLogined) throw `Session is not logined`;
|
98
|
+
// });
|
99
|
+
// /////////////////////////////////////////////////////////////////////
|
100
|
+
// describe("logout mutation", () => {
|
101
|
+
// it("Logout user from current device", async () => {
|
102
|
+
// let token = await loginTestUserByPassword("Test000");
|
103
|
+
// if (!token) throw `TOKEN JWT is not defined`;
|
104
|
+
// const auth = await JWTAuth.verify(token);
|
105
|
+
// let query = `#graphql
|
106
|
+
// mutation {
|
107
|
+
// logout {
|
108
|
+
// message {
|
109
|
+
// message
|
110
|
+
// }
|
111
|
+
// action {
|
112
|
+
// type
|
113
|
+
// data
|
114
|
+
// }
|
115
|
+
// }
|
116
|
+
// }`
|
117
|
+
// const logoutMutation: any = await runGQL(query, token);
|
118
|
+
// if (logoutMutation.errors) throw new Error(logoutMutation.errors);
|
119
|
+
// let ud = await UserDevice.findOne({ id: auth.deviceId });
|
120
|
+
// if (!ud) throw `Device not found by deviceName`;
|
121
|
+
// if (ud.isLogined) throw `Session is still logined`;
|
122
|
+
// });
|
123
|
+
// it("Logout user from specific device", async () => {
|
124
|
+
// // 1st device
|
125
|
+
// let token1 = await loginTestUserByPassword("Test001");
|
126
|
+
// if (!token1) throw `TOKEN2 JWT is not defined`;
|
127
|
+
// // 2th device
|
128
|
+
// let token2 = await loginTestUserByPassword("Test002");
|
129
|
+
// if (!token2) throw `TOKEN2 JWT is not defined`;
|
130
|
+
// // logout from 2th device only
|
131
|
+
// let query = `#graphql
|
132
|
+
// mutation {
|
133
|
+
// logout(deviceName: "Test002") {
|
134
|
+
// message {
|
135
|
+
// message
|
136
|
+
// }
|
137
|
+
// action {
|
138
|
+
// type
|
139
|
+
// data
|
140
|
+
// }
|
141
|
+
// }
|
142
|
+
// }`
|
143
|
+
// const logoutMutation: any = await runGQL(query, token);
|
144
|
+
// if (logoutMutation.errors) throw new Error(logoutMutation.errors);
|
145
|
+
// // 1th device should be logined
|
146
|
+
// const auth0 = await JWTAuth.verify(token1);
|
147
|
+
// let ud0 = await UserDevice.findOne({
|
148
|
+
// user: auth0.userId,
|
149
|
+
// sessionId: auth0.sessionId,
|
150
|
+
// });
|
151
|
+
// if (!ud0) throw `Device not found by deviceName`;
|
152
|
+
// if (!ud0.isLogined) throw `Session 1 was logouted`;
|
153
|
+
// // 2th device should not be logined
|
154
|
+
// try {
|
155
|
+
// await JWTAuth.verify(token2);
|
156
|
+
// assert.fail('Should have thrown an error');
|
157
|
+
// } catch (error) {
|
158
|
+
// assert.equal(error, 'Logined device not found');
|
159
|
+
// }
|
160
|
+
// });
|
161
|
+
// });
|
162
|
+
// it('User query filter', async () => true); // // @webresto/graphql/lib/graphqlHelper.ts#390
|
163
|
+
// it('User subscription filter', async () => true); // @webresto/graphql/lib/graphqlHelper.ts#559
|
164
|
+
// it('Update user info', async () => true);
|
165
|
+
// it('Update user custom fields', async () => true);
|
166
|
+
// it('Update user password', async () => true);
|
167
|
+
// it('Reset user password', async () => true);
|
168
|
+
// it('Mutation RequestLogin & RequestRegistration just exist', async () => true);
|
169
|
+
// it('Logout from current device', async () => true);
|
170
|
+
// it('Logout from all device', async () => true);
|
171
|
+
});
|
172
|
+
async function getOTP(login) {
|
173
|
+
let captcha = await resolveCaptcha(`OTPRequest:1123`);
|
174
|
+
const _graphql = require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
175
|
+
const gqlReq = await _graphql.getServer().executeOperation({
|
176
|
+
query: `#graphql
|
177
|
+
mutation{OTPRequest(login: "${login}", captcha: {id: "${captcha.id}", solution: ${captcha.solution}}) {
|
178
|
+
id
|
179
|
+
nextOTPAfterSeconds
|
180
|
+
}
|
181
|
+
}
|
182
|
+
`,
|
183
|
+
});
|
184
|
+
if (gqlReq.errors)
|
185
|
+
throw gqlReq.errors;
|
186
|
+
let OTP = await OneTimePassword.findOne({ id: gqlReq.data.OTPRequest.id });
|
187
|
+
return OTP;
|
188
|
+
}
|
189
|
+
async function resolveCaptcha(label) {
|
190
|
+
const _graphql = require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
191
|
+
const captcha = await _graphql.getServer().executeOperation({
|
192
|
+
query: `#graphql
|
193
|
+
{
|
194
|
+
captchaGetJob(label: "${label}") {
|
195
|
+
id
|
196
|
+
task
|
197
|
+
}
|
198
|
+
}
|
199
|
+
`,
|
200
|
+
});
|
201
|
+
if (captcha.errors)
|
202
|
+
throw captcha.errors;
|
203
|
+
let id = captcha.data.captchaGetJob.id;
|
204
|
+
let task = JSON.parse(captcha.data.captchaGetJob.task);
|
205
|
+
let parsedTask = {
|
206
|
+
difficulty: parseInt(task.difficulty),
|
207
|
+
salt: task.salt,
|
208
|
+
hash: task.hash,
|
209
|
+
};
|
210
|
+
let resolvedTask = await Puzzle.solve(parsedTask);
|
211
|
+
let resolvedCaptcha = {
|
212
|
+
id: id,
|
213
|
+
solution: JSON.stringify(resolvedTask, (key, value) => typeof value === "bigint" ? value.toString() : value),
|
214
|
+
};
|
215
|
+
return resolvedCaptcha;
|
216
|
+
}
|
217
|
+
async function loginTestUserByPassword(deviceName) {
|
218
|
+
await Settings.set("PASSWORD_REQUIRED", true);
|
219
|
+
await Settings.set("LOGIN_OTP_REQUIRED", false);
|
220
|
+
const _graphql = require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
221
|
+
let captcha = await resolveCaptcha(`login:1123`);
|
222
|
+
let query = `#graphql
|
223
|
+
mutation {
|
224
|
+
login(
|
225
|
+
login: "1123",
|
226
|
+
password: "test123",
|
227
|
+
deviceName: "${deviceName}",
|
228
|
+
captcha: {id: "${captcha.id}", solution: ${captcha.solution}}
|
229
|
+
) {
|
230
|
+
message {
|
231
|
+
message
|
232
|
+
}
|
233
|
+
action {
|
234
|
+
type
|
235
|
+
data
|
236
|
+
}
|
237
|
+
}
|
238
|
+
}`;
|
239
|
+
const loginMutation = await _graphql.getServer().executeOperation({
|
240
|
+
query: query,
|
241
|
+
});
|
242
|
+
if (loginMutation.errors)
|
243
|
+
throw new Error(loginMutation.errors);
|
244
|
+
return loginMutation.data?.login?.action?.data?.token;
|
245
|
+
}
|
246
|
+
function e2eMutation(query, token) { }
|
247
|
+
function sleep(ms) {
|
248
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
249
|
+
}
|
@@ -0,0 +1,299 @@
|
|
1
|
+
process.env.CAPTCHA_POW_DIFFICUTLY = "5000";
|
2
|
+
import { ResolvedCaptcha } from "@webresto/core/adapters/captcha/CaptchaAdapter";
|
3
|
+
import { Captcha } from "@webresto/core/adapters/index";
|
4
|
+
let Puzzle = require("fix-esm").require("crypto-puzzle").default;
|
5
|
+
import OneTimePassword from "@webresto/core/models/OneTimePassword";
|
6
|
+
import { expect, assert } from "chai";
|
7
|
+
import { JWTAuth } from "../../lib/jwt";
|
8
|
+
|
9
|
+
// E2E
|
10
|
+
import { runGQL } from "../e2e_helper";
|
11
|
+
|
12
|
+
let graphql;
|
13
|
+
let serverInfo;
|
14
|
+
describe("User", function () {
|
15
|
+
let token;
|
16
|
+
this.timeout(50000);
|
17
|
+
|
18
|
+
// it("Login new user and setting password", async () => {
|
19
|
+
// await sleep(3000);
|
20
|
+
// graphql =
|
21
|
+
// require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
22
|
+
|
23
|
+
// let OTP = await getOTP(`1123`);
|
24
|
+
// let captcha = await resolveCaptcha(`registration:1123`);
|
25
|
+
// let phone = { code: "+1", number: "123" };
|
26
|
+
|
27
|
+
// const result = await graphql.getServer().executeOperation({
|
28
|
+
// query: `#graphql
|
29
|
+
// mutation{login(
|
30
|
+
// login: "1123",
|
31
|
+
// phone: { code: "${phone.code}", number: "${phone.number}"},
|
32
|
+
// otp: "${OTP.password}",
|
33
|
+
// password: "test123"
|
34
|
+
// captcha: {id: "${captcha.id}", solution: ${captcha.solution}}
|
35
|
+
// ){
|
36
|
+
// user {
|
37
|
+
// id
|
38
|
+
// phone {
|
39
|
+
// number
|
40
|
+
// code
|
41
|
+
// }
|
42
|
+
// lastName
|
43
|
+
// }
|
44
|
+
// message {
|
45
|
+
// message
|
46
|
+
// }
|
47
|
+
// action {
|
48
|
+
// type
|
49
|
+
// data
|
50
|
+
// }
|
51
|
+
// }}`,
|
52
|
+
// });
|
53
|
+
|
54
|
+
// if (result.errors) throw new Error(result.errors);
|
55
|
+
// const response = result.data.registration;
|
56
|
+
// expect(response.message.message).to.equal("New user created");
|
57
|
+
|
58
|
+
// assert.deepEqual(response.action, {
|
59
|
+
// type: "GoTo",
|
60
|
+
// data: {
|
61
|
+
// section: "login",
|
62
|
+
// delaySeconds: 5,
|
63
|
+
// },
|
64
|
+
// });
|
65
|
+
|
66
|
+
// expect(response.user.id).to.not.be.null;
|
67
|
+
// assert.deepEqual(response.user.phone, phone);
|
68
|
+
// });
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
it("Login new user passwordPolicy = from_otp, LoginOTPrequired = false", async () => {
|
73
|
+
|
74
|
+
graphql = require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
75
|
+
|
76
|
+
let captcha = await resolveCaptcha(`login:1123`);
|
77
|
+
let OTP = await getOTP(`1123`);
|
78
|
+
|
79
|
+
let query = `#graphql
|
80
|
+
mutation{login(
|
81
|
+
login: "1123",
|
82
|
+
otp: "${OTP.password}",
|
83
|
+
phone: {
|
84
|
+
code: "1",
|
85
|
+
number: "123"
|
86
|
+
},
|
87
|
+
captcha: {id: "${captcha.id}", solution: ${captcha.solution}}
|
88
|
+
){
|
89
|
+
message {
|
90
|
+
message
|
91
|
+
}
|
92
|
+
action {
|
93
|
+
type
|
94
|
+
data
|
95
|
+
}
|
96
|
+
}}`;
|
97
|
+
const loginMutation = await graphql.getServer().executeOperation({
|
98
|
+
query: query,
|
99
|
+
},
|
100
|
+
{req: {rawHeaders: [ "X-Device-Id", "test001"]}}
|
101
|
+
);
|
102
|
+
if (loginMutation.errors) throw new Error(loginMutation.errors);
|
103
|
+
|
104
|
+
// token = loginMutation.data?.login?.action?.data?.token;
|
105
|
+
// if (!token) throw `TOKEN JWT is not defined`;
|
106
|
+
|
107
|
+
// const auth = await JWTAuth.verify(token);
|
108
|
+
// let ud = await UserDevice.findOne({ sessionId: auth.sessionId });
|
109
|
+
// if (!ud) throw `Device not found by session`;
|
110
|
+
// if (!ud.isLogined) throw `Session is not logined`;
|
111
|
+
});
|
112
|
+
|
113
|
+
// it("Login user by password", async () => {
|
114
|
+
// await Settings.set("LOGIN_OTP_REQUIRED", false);
|
115
|
+
|
116
|
+
// token = await loginTestUserByPassword("Login user by password");
|
117
|
+
// if (!token) throw `TOKEN JWT is not defined`;
|
118
|
+
|
119
|
+
// const auth = await JWTAuth.verify(token);
|
120
|
+
// let ud = await UserDevice.findOne({ sessionId: auth.sessionId });
|
121
|
+
// if (!ud) throw `Device not found by session`;
|
122
|
+
// if (!ud.isLogined) throw `Session is not logined`;
|
123
|
+
// });
|
124
|
+
|
125
|
+
// /////////////////////////////////////////////////////////////////////
|
126
|
+
|
127
|
+
// describe("logout mutation", () => {
|
128
|
+
// it("Logout user from current device", async () => {
|
129
|
+
// let token = await loginTestUserByPassword("Test000");
|
130
|
+
// if (!token) throw `TOKEN JWT is not defined`;
|
131
|
+
// const auth = await JWTAuth.verify(token);
|
132
|
+
// let query = `#graphql
|
133
|
+
// mutation {
|
134
|
+
// logout {
|
135
|
+
// message {
|
136
|
+
// message
|
137
|
+
// }
|
138
|
+
// action {
|
139
|
+
// type
|
140
|
+
// data
|
141
|
+
// }
|
142
|
+
// }
|
143
|
+
// }`
|
144
|
+
// const logoutMutation: any = await runGQL(query, token);
|
145
|
+
// if (logoutMutation.errors) throw new Error(logoutMutation.errors);
|
146
|
+
// let ud = await UserDevice.findOne({ id: auth.deviceId });
|
147
|
+
// if (!ud) throw `Device not found by deviceName`;
|
148
|
+
// if (ud.isLogined) throw `Session is still logined`;
|
149
|
+
// });
|
150
|
+
|
151
|
+
// it("Logout user from specific device", async () => {
|
152
|
+
// // 1st device
|
153
|
+
// let token1 = await loginTestUserByPassword("Test001");
|
154
|
+
// if (!token1) throw `TOKEN2 JWT is not defined`;
|
155
|
+
|
156
|
+
// // 2th device
|
157
|
+
// let token2 = await loginTestUserByPassword("Test002");
|
158
|
+
// if (!token2) throw `TOKEN2 JWT is not defined`;
|
159
|
+
|
160
|
+
// // logout from 2th device only
|
161
|
+
// let query = `#graphql
|
162
|
+
// mutation {
|
163
|
+
// logout(deviceName: "Test002") {
|
164
|
+
// message {
|
165
|
+
// message
|
166
|
+
// }
|
167
|
+
// action {
|
168
|
+
// type
|
169
|
+
// data
|
170
|
+
// }
|
171
|
+
// }
|
172
|
+
// }`
|
173
|
+
// const logoutMutation: any = await runGQL(query, token);
|
174
|
+
// if (logoutMutation.errors) throw new Error(logoutMutation.errors);
|
175
|
+
// // 1th device should be logined
|
176
|
+
// const auth0 = await JWTAuth.verify(token1);
|
177
|
+
// let ud0 = await UserDevice.findOne({
|
178
|
+
// user: auth0.userId,
|
179
|
+
// sessionId: auth0.sessionId,
|
180
|
+
// });
|
181
|
+
// if (!ud0) throw `Device not found by deviceName`;
|
182
|
+
// if (!ud0.isLogined) throw `Session 1 was logouted`;
|
183
|
+
|
184
|
+
// // 2th device should not be logined
|
185
|
+
|
186
|
+
// try {
|
187
|
+
// await JWTAuth.verify(token2);
|
188
|
+
// assert.fail('Should have thrown an error');
|
189
|
+
// } catch (error) {
|
190
|
+
// assert.equal(error, 'Logined device not found');
|
191
|
+
// }
|
192
|
+
// });
|
193
|
+
// });
|
194
|
+
|
195
|
+
// it('User query filter', async () => true); // // @webresto/graphql/lib/graphqlHelper.ts#390
|
196
|
+
// it('User subscription filter', async () => true); // @webresto/graphql/lib/graphqlHelper.ts#559
|
197
|
+
// it('Update user info', async () => true);
|
198
|
+
// it('Update user custom fields', async () => true);
|
199
|
+
// it('Update user password', async () => true);
|
200
|
+
// it('Reset user password', async () => true);
|
201
|
+
// it('Mutation RequestLogin & RequestRegistration just exist', async () => true);
|
202
|
+
// it('Logout from current device', async () => true);
|
203
|
+
// it('Logout from all device', async () => true);
|
204
|
+
});
|
205
|
+
|
206
|
+
async function getOTP(login: string): Promise<OneTimePassword> {
|
207
|
+
let captcha = await resolveCaptcha(`OTPRequest:1123`);
|
208
|
+
const _graphql =
|
209
|
+
require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
210
|
+
|
211
|
+
const gqlReq = await _graphql.getServer().executeOperation({
|
212
|
+
query: `#graphql
|
213
|
+
mutation{OTPRequest(login: "${login}", captcha: {id: "${captcha.id}", solution: ${captcha.solution}}) {
|
214
|
+
id
|
215
|
+
nextOTPAfterSeconds
|
216
|
+
}
|
217
|
+
}
|
218
|
+
`,
|
219
|
+
});
|
220
|
+
|
221
|
+
if (gqlReq.errors) throw gqlReq.errors;
|
222
|
+
let OTP = await OneTimePassword.findOne({ id: gqlReq.data.OTPRequest.id });
|
223
|
+
return OTP;
|
224
|
+
}
|
225
|
+
|
226
|
+
async function resolveCaptcha(label: string): Promise<ResolvedCaptcha> {
|
227
|
+
const _graphql =
|
228
|
+
require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
229
|
+
const captcha = await _graphql.getServer().executeOperation({
|
230
|
+
query: `#graphql
|
231
|
+
{
|
232
|
+
captchaGetJob(label: "${label}") {
|
233
|
+
id
|
234
|
+
task
|
235
|
+
}
|
236
|
+
}
|
237
|
+
`,
|
238
|
+
});
|
239
|
+
if (captcha.errors) throw captcha.errors;
|
240
|
+
let id = captcha.data.captchaGetJob.id;
|
241
|
+
let task = JSON.parse(captcha.data.captchaGetJob.task);
|
242
|
+
|
243
|
+
let parsedTask = {
|
244
|
+
difficulty: parseInt(task.difficulty),
|
245
|
+
salt: task.salt,
|
246
|
+
hash: task.hash,
|
247
|
+
};
|
248
|
+
|
249
|
+
let resolvedTask = await Puzzle.solve(parsedTask);
|
250
|
+
let resolvedCaptcha = {
|
251
|
+
id: id,
|
252
|
+
solution: JSON.stringify(resolvedTask, (key, value) =>
|
253
|
+
typeof value === "bigint" ? value.toString() : value
|
254
|
+
),
|
255
|
+
};
|
256
|
+
return resolvedCaptcha;
|
257
|
+
}
|
258
|
+
|
259
|
+
async function loginTestUserByPassword(
|
260
|
+
deviceName: string
|
261
|
+
): Promise<string> {
|
262
|
+
await Settings.set("PASSWORD_REQUIRED", true);
|
263
|
+
await Settings.set("LOGIN_OTP_REQUIRED", false);
|
264
|
+
const _graphql =
|
265
|
+
require("./../fixture/node_modules/@webresto/graphql/src/graphql").default;
|
266
|
+
|
267
|
+
let captcha = await resolveCaptcha(`login:1123`);
|
268
|
+
let query = `#graphql
|
269
|
+
mutation {
|
270
|
+
login(
|
271
|
+
login: "1123",
|
272
|
+
password: "test123",
|
273
|
+
deviceName: "${deviceName}",
|
274
|
+
captcha: {id: "${captcha.id}", solution: ${captcha.solution}}
|
275
|
+
) {
|
276
|
+
message {
|
277
|
+
message
|
278
|
+
}
|
279
|
+
action {
|
280
|
+
type
|
281
|
+
data
|
282
|
+
}
|
283
|
+
}
|
284
|
+
}`;
|
285
|
+
|
286
|
+
const loginMutation = await _graphql.getServer().executeOperation({
|
287
|
+
query: query,
|
288
|
+
});
|
289
|
+
|
290
|
+
if (loginMutation.errors) throw new Error(loginMutation.errors);
|
291
|
+
|
292
|
+
return loginMutation.data?.login?.action?.data?.token;
|
293
|
+
}
|
294
|
+
|
295
|
+
function e2eMutation(query, token) {}
|
296
|
+
|
297
|
+
function sleep(ms) {
|
298
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
299
|
+
}
|
package/test/unit/first.test.js
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const chai_1 = require("chai");
|
2
4
|
describe('GraphQl', function () {
|
3
5
|
it('schema exist', async () => {
|
4
6
|
// const data = await TestModel.find({});
|
5
7
|
// console.log(data);
|
6
8
|
const graphql = require('./../fixture/node_modules/@webresto/graphql/src/graphql').default;
|
7
|
-
expect(graphql.getServer().schema._typeMap.Dish != undefined);
|
9
|
+
(0, chai_1.expect)(graphql.getServer().schema._typeMap.Dish != undefined);
|
8
10
|
});
|
9
11
|
});
|
package/test/unit/first.test.ts
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const chai_1 = require("chai");
|
4
|
+
const getRecomended_1 = require("../../lib/getRecomended");
|
5
|
+
describe('getRecomendElements', function () {
|
6
|
+
it('should return an empty array when the input array is empty', function () {
|
7
|
+
const result = (0, getRecomended_1.getRecomendElements)([], 3);
|
8
|
+
(0, chai_1.expect)(result).to.be.an('array');
|
9
|
+
(0, chai_1.expect)(result.length).to.be.equal(0);
|
10
|
+
});
|
11
|
+
it('should throw an error when the input array is of incorrect type', function () {
|
12
|
+
(0, chai_1.expect)(() => (0, getRecomended_1.getRecomendElements)('not_an_array', 3)).to.have.length(0);
|
13
|
+
});
|
14
|
+
it('should return an empty array if there are no items with prices within the range of 20 to max price', function () {
|
15
|
+
const inputArray = [
|
16
|
+
{ name: 'item1', price: 10 },
|
17
|
+
{ name: 'item2', price: 15 },
|
18
|
+
];
|
19
|
+
const result = (0, getRecomended_1.getRecomendElements)(inputArray, 3);
|
20
|
+
(0, chai_1.expect)(result).to.be.an('array');
|
21
|
+
(0, chai_1.expect)(result.length).to.be.equal(2);
|
22
|
+
});
|
23
|
+
it('should return the correct number of elements if not found in range 20/80% of max price', function () {
|
24
|
+
const inputArray = [
|
25
|
+
{ name: 'item1', price: 10 },
|
26
|
+
{ name: 'item2', price: 25 },
|
27
|
+
{ name: 'item3', price: 30 },
|
28
|
+
{ name: 'item4', price: 15 },
|
29
|
+
{ name: 'item4', price: 151 },
|
30
|
+
{ name: 'item4', price: 103 },
|
31
|
+
{ name: 'item4', price: 406 },
|
32
|
+
{ name: 'item4', price: 9909 },
|
33
|
+
{ name: 'item4', price: 10002 },
|
34
|
+
];
|
35
|
+
const result = (0, getRecomended_1.getRecomendElements)(inputArray, 3);
|
36
|
+
(0, chai_1.expect)(result).to.be.an('array');
|
37
|
+
(0, chai_1.expect)(result).to.have.length(3);
|
38
|
+
});
|
39
|
+
it('should return the correct number of elements with a total price not exceeding the max price', function () {
|
40
|
+
const inputArray = [
|
41
|
+
{ name: 'item1', price: 10 },
|
42
|
+
{ name: 'item2', price: 25 },
|
43
|
+
{ name: 'item3', price: 5530 },
|
44
|
+
{ name: 'item4', price: 15 },
|
45
|
+
{ name: 'item4', price: 3151 },
|
46
|
+
{ name: 'item4', price: 103 },
|
47
|
+
{ name: 'item4', price: 2406 },
|
48
|
+
{ name: 'item4', price: 9909 },
|
49
|
+
{ name: 'item4', price: 10002 },
|
50
|
+
];
|
51
|
+
const result = (0, getRecomended_1.getRecomendElements)(inputArray, 3);
|
52
|
+
(0, chai_1.expect)(result).to.be.an('array');
|
53
|
+
(0, chai_1.expect)(result).to.have.length(3);
|
54
|
+
});
|
55
|
+
// Add additional tests as needed
|
56
|
+
});
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import {expect} from "chai"
|
2
|
+
|
3
|
+
import { getRecomendElements } from "../../lib/getRecomended";
|
4
|
+
|
5
|
+
describe('getRecomendElements', function() {
|
6
|
+
it('should return an empty array when the input array is empty', function() {
|
7
|
+
const result = getRecomendElements([], 3);
|
8
|
+
expect(result).to.be.an('array');
|
9
|
+
expect(result.length).to.be.equal(0);
|
10
|
+
});
|
11
|
+
|
12
|
+
it('should throw an error when the input array is of incorrect type', function() {
|
13
|
+
expect(() => getRecomendElements('not_an_array', 3)).to.have.length(0);
|
14
|
+
});
|
15
|
+
|
16
|
+
it('should return an empty array if there are no items with prices within the range of 20 to max price', function() {
|
17
|
+
const inputArray = [
|
18
|
+
{ name: 'item1', price: 10 },
|
19
|
+
{ name: 'item2', price: 15 },
|
20
|
+
];
|
21
|
+
const result = getRecomendElements(inputArray, 3);
|
22
|
+
expect(result).to.be.an('array');
|
23
|
+
expect(result.length).to.be.equal(2);
|
24
|
+
});
|
25
|
+
|
26
|
+
it('should return the correct number of elements if not found in range 20/80% of max price', function() {
|
27
|
+
const inputArray = [
|
28
|
+
{ name: 'item1', price: 10 },
|
29
|
+
{ name: 'item2', price: 25 },
|
30
|
+
{ name: 'item3', price: 30 },
|
31
|
+
{ name: 'item4', price: 15 },
|
32
|
+
{ name: 'item4', price: 151 },
|
33
|
+
{ name: 'item4', price: 103 },
|
34
|
+
{ name: 'item4', price: 406 },
|
35
|
+
{ name: 'item4', price: 9909 },
|
36
|
+
{ name: 'item4', price: 10002 },
|
37
|
+
];
|
38
|
+
const result = getRecomendElements(inputArray, 3);
|
39
|
+
expect(result).to.be.an('array');
|
40
|
+
expect(result).to.have.length(3);
|
41
|
+
});
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
it('should return the correct number of elements with a total price not exceeding the max price', function() {
|
46
|
+
const inputArray = [
|
47
|
+
{ name: 'item1', price: 10 },
|
48
|
+
{ name: 'item2', price: 25 },
|
49
|
+
{ name: 'item3', price: 5530 },
|
50
|
+
{ name: 'item4', price: 15 },
|
51
|
+
{ name: 'item4', price: 3151 },
|
52
|
+
{ name: 'item4', price: 103 },
|
53
|
+
{ name: 'item4', price: 2406 },
|
54
|
+
{ name: 'item4', price: 9909 },
|
55
|
+
{ name: 'item4', price: 10002 },
|
56
|
+
];
|
57
|
+
const result = getRecomendElements(inputArray, 3);
|
58
|
+
expect(result).to.be.an('array');
|
59
|
+
expect(result).to.have.length(3);
|
60
|
+
});
|
61
|
+
|
62
|
+
// Add additional tests as needed
|
63
|
+
});
|