@webresto/graphql 1.3.6 → 1.3.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/.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 -73
- package/lib/graphqlHelper.ts +329 -186
- 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 +43 -14
- package/src/resolvers/checkout.js +172 -122
- package/src/resolvers/checkout.ts +218 -142
- 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 -277
- 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
|
+
});
|