@tellescope/sdk 0.0.24 → 0.0.28
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/cjs/enduser.d.ts +6 -7
- package/lib/cjs/enduser.d.ts.map +1 -1
- package/lib/cjs/enduser.js +21 -6
- package/lib/cjs/enduser.js.map +1 -1
- package/lib/cjs/sdk.d.ts +6 -7
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +16 -1
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/session.d.ts +2 -2
- package/lib/cjs/session.d.ts.map +1 -1
- package/lib/cjs/session.js +13 -21
- package/lib/cjs/session.js.map +1 -1
- package/lib/cjs/tests/tests.js +111 -47
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/enduser.d.ts +7 -7
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/enduser.js +21 -6
- package/lib/esm/enduser.js.map +1 -1
- package/lib/esm/sdk.d.ts +7 -7
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +16 -1
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/session.d.ts +3 -2
- package/lib/esm/session.d.ts.map +1 -1
- package/lib/esm/session.js +13 -21
- package/lib/esm/session.js.map +1 -1
- package/lib/esm/tests/tests.js +111 -47
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/enduser.ts +13 -7
- package/src/sdk.ts +10 -6
- package/src/session.ts +12 -17
- package/src/tests/tests.ts +66 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellescope/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"description": "Code for interacting with the Tellescope API",
|
|
5
5
|
"main": "./lib/cjs/sdk.js",
|
|
6
6
|
"module": "./lib/esm/sdk.js",
|
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://github.com/tellescope-os/tellescope#readme",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@tellescope/constants": "^0.0.
|
|
36
|
-
"@tellescope/schema": "^0.0.
|
|
37
|
-
"@tellescope/testing": "^0.0.
|
|
38
|
-
"@tellescope/types-client": "^0.0.
|
|
39
|
-
"@tellescope/types-models": "^0.0.
|
|
40
|
-
"@tellescope/types-utilities": "^0.0.
|
|
41
|
-
"@tellescope/utilities": "^0.0.
|
|
42
|
-
"@tellescope/validation": "^0.0.
|
|
35
|
+
"@tellescope/constants": "^0.0.28",
|
|
36
|
+
"@tellescope/schema": "^0.0.28",
|
|
37
|
+
"@tellescope/testing": "^0.0.28",
|
|
38
|
+
"@tellescope/types-client": "^0.0.28",
|
|
39
|
+
"@tellescope/types-models": "^0.0.28",
|
|
40
|
+
"@tellescope/types-utilities": "^0.0.28",
|
|
41
|
+
"@tellescope/utilities": "^0.0.28",
|
|
42
|
+
"@tellescope/validation": "^0.0.28",
|
|
43
43
|
"axios": "^0.21.1",
|
|
44
44
|
"express": "^4.17.1",
|
|
45
45
|
"form-data": "^4.0.0",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "90f22163cadb40fbba2c44561a56fd4ea6530c16"
|
|
60
60
|
}
|
package/src/enduser.ts
CHANGED
|
@@ -4,10 +4,9 @@ import { Session, SessionOptions } from "./session"
|
|
|
4
4
|
import { APIQuery } from "./sdk"
|
|
5
5
|
import { url_safe_path } from "@tellescope/utilities"
|
|
6
6
|
|
|
7
|
-
import { S3PresignedPost, UserIdentity } from "@tellescope/types-utilities"
|
|
7
|
+
import { FileBlob, FileBuffer, FileDetails, ReactNativeFile, S3PresignedPost, UserIdentity } from "@tellescope/types-utilities"
|
|
8
8
|
import {
|
|
9
9
|
Attendee,
|
|
10
|
-
AttendeeInfo,
|
|
11
10
|
} from "@tellescope/types-models"
|
|
12
11
|
import {
|
|
13
12
|
ClientModelForName,
|
|
@@ -20,7 +19,7 @@ import {
|
|
|
20
19
|
|
|
21
20
|
export interface EnduserSessionOptions extends SessionOptions {}
|
|
22
21
|
|
|
23
|
-
type EnduserAccessibleModels = "chat_rooms" | 'chats' | 'files' | 'tickets'
|
|
22
|
+
type EnduserAccessibleModels = 'endusers' | "chat_rooms" | 'chats' | 'files' | 'tickets'
|
|
24
23
|
|
|
25
24
|
export const defaultQueries = <N extends keyof ClientModelForName>(
|
|
26
25
|
s: EnduserSession, n: keyof ClientModelForName_required
|
|
@@ -48,7 +47,7 @@ type EnduserQueries = { [K in EnduserAccessibleModels]: APIQuery<K> } & {
|
|
|
48
47
|
display_info: () => Promise<UserDisplayInfo[]>
|
|
49
48
|
},
|
|
50
49
|
files: {
|
|
51
|
-
prepare_file_upload: (args:
|
|
50
|
+
prepare_file_upload: (args: FileDetails) => Promise<{ presignedUpload: S3PresignedPost, file: File }>,
|
|
52
51
|
file_download_URL: (args: { secureName: string }) => Promise<{ downloadURL: string }>,
|
|
53
52
|
},
|
|
54
53
|
meetings: {
|
|
@@ -61,6 +60,7 @@ type EnduserQueries = { [K in EnduserAccessibleModels]: APIQuery<K> } & {
|
|
|
61
60
|
const loadDefaultQueries = (s: EnduserSession): { [K in EnduserAccessibleModels] : APIQuery<K> } => ({
|
|
62
61
|
chat_rooms: defaultQueries(s, 'chat_rooms'),
|
|
63
62
|
chats: defaultQueries(s, 'chats'),
|
|
63
|
+
endusers: defaultQueries(s, 'endusers'),
|
|
64
64
|
files: defaultQueries(s, 'files'),
|
|
65
65
|
tickets: defaultQueries(s, 'tickets'),
|
|
66
66
|
})
|
|
@@ -76,9 +76,8 @@ export class EnduserSession extends Session {
|
|
|
76
76
|
|
|
77
77
|
this.api = loadDefaultQueries(this) as EnduserQueries
|
|
78
78
|
|
|
79
|
-
this.api.endusers =
|
|
80
|
-
|
|
81
|
-
}
|
|
79
|
+
this.api.endusers.logout = () => this._POST('/v1/logout-enduser'),
|
|
80
|
+
|
|
82
81
|
this.api.users = {
|
|
83
82
|
display_info: () => this._GET<{}, UserDisplayInfo[] >(`/v1/user-display-info`),
|
|
84
83
|
}
|
|
@@ -114,6 +113,13 @@ export class EnduserSession extends Session {
|
|
|
114
113
|
return await this.DELETE<A,R>(endpoint, args, authenticated)
|
|
115
114
|
}
|
|
116
115
|
|
|
116
|
+
prepare_and_upload_file = async (details: FileDetails, file: Blob | Buffer | ReactNativeFile) => {
|
|
117
|
+
const { name, size, type } = details
|
|
118
|
+
const { presignedUpload, file: { secureName } } = await this.api.files.prepare_file_upload({ name, size, type })
|
|
119
|
+
await this.UPLOAD(presignedUpload, file)
|
|
120
|
+
return { secureName }
|
|
121
|
+
}
|
|
122
|
+
|
|
117
123
|
handle_new_session = async ({ authToken, enduser }: { authToken: string, enduser: Enduser }) => {
|
|
118
124
|
this.sessionStart = Date.now()
|
|
119
125
|
this.setAuthToken(authToken)
|
package/src/sdk.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AttendeeInfo,
|
|
3
2
|
JourneyState,
|
|
4
3
|
UserSession,
|
|
5
4
|
MeetingInfo,
|
|
@@ -18,7 +17,7 @@ import {
|
|
|
18
17
|
File,
|
|
19
18
|
Meeting,
|
|
20
19
|
} from "@tellescope/types-client"
|
|
21
|
-
import { CustomUpdateOptions, SortOption, S3PresignedPost, UserIdentity } from "@tellescope/types-utilities"
|
|
20
|
+
import { CustomUpdateOptions, SortOption, S3PresignedPost, UserIdentity, FileBlob, FileBuffer, FileDetails, ReactNativeFile } from "@tellescope/types-utilities"
|
|
22
21
|
import { url_safe_path } from "@tellescope/utilities"
|
|
23
22
|
|
|
24
23
|
import { Session as SessionManager, SessionOptions } from "./session"
|
|
@@ -93,14 +92,14 @@ type Queries = { [K in keyof ClientModelForName]: APIQuery<K> } & {
|
|
|
93
92
|
},
|
|
94
93
|
endusers: {
|
|
95
94
|
set_password: (args: { id: string, password: string }) => Promise<void>,
|
|
96
|
-
is_authenticated: (args: { id
|
|
95
|
+
is_authenticated: (args: { id?: string, authToken: string }) => Promise<{ isAuthenticated: boolean, enduser: Enduser }>
|
|
97
96
|
generate_auth_token: (args: { id?: string, phone?: string, email?: string, externalId?: string }) => Promise<{ authToken: string, enduser: Enduser }>
|
|
98
97
|
},
|
|
99
98
|
users: {
|
|
100
99
|
display_names: () => Promise<{ fname: string, lname: string, id: string }[]>,
|
|
101
100
|
},
|
|
102
101
|
files: {
|
|
103
|
-
prepare_file_upload: (args:
|
|
102
|
+
prepare_file_upload: (args: FileDetails) => Promise<{ presignedUpload: S3PresignedPost, file: File }>,
|
|
104
103
|
file_download_URL: (args: { secureName: string }) => Promise<{ downloadURL: string }>,
|
|
105
104
|
},
|
|
106
105
|
meetings: {
|
|
@@ -148,8 +147,6 @@ export class Session extends SessionManager {
|
|
|
148
147
|
queries.webhooks.update = a => this._PATCH('/v1/update-webhooks', a)
|
|
149
148
|
|
|
150
149
|
this.api = queries
|
|
151
|
-
|
|
152
|
-
// if (this.userInfo) this.refresh_session()
|
|
153
150
|
}
|
|
154
151
|
|
|
155
152
|
_POST = async <A,R=void>(endpoint: string, args?: A, authenticated=true) => {
|
|
@@ -205,6 +202,13 @@ export class Session extends SessionManager {
|
|
|
205
202
|
await this.POST('/logout-api').catch(console.error)
|
|
206
203
|
}
|
|
207
204
|
|
|
205
|
+
prepare_and_upload_file = async (details: FileDetails, file: Blob | Buffer | ReactNativeFile) => {
|
|
206
|
+
const { name, size, type } = details
|
|
207
|
+
const { presignedUpload, file: { secureName } } = await this.api.files.prepare_file_upload({ name, size, type })
|
|
208
|
+
await this.UPLOAD(presignedUpload, file)
|
|
209
|
+
return { secureName }
|
|
210
|
+
}
|
|
211
|
+
|
|
208
212
|
reset_db = () => this.POST('/reset-demo')
|
|
209
213
|
test_online = () => this.GET<{}, string>('/v1')
|
|
210
214
|
test_authenticated = () => this.GET<{}, string>('/v1/test-authenticated')
|
package/src/session.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Socket, io } from 'socket.io-client'
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
FileBlob,
|
|
7
|
+
ReactNativeFile,
|
|
7
8
|
S3PresignedPost,
|
|
8
9
|
} from "@tellescope/types-utilities"
|
|
9
10
|
import {
|
|
@@ -152,27 +153,17 @@ export class Session {
|
|
|
152
153
|
} catch(err) { throw await this.errorHandler(err) }
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
UPLOAD = async (presigned: S3PresignedPost, file
|
|
156
|
-
const formData =
|
|
156
|
+
UPLOAD = async (presigned: S3PresignedPost, file: Blob | Buffer | ReactNativeFile) => {
|
|
157
|
+
const formData = new NodeFormData();
|
|
157
158
|
Object.keys(presigned.fields).forEach(key => {
|
|
158
|
-
formData.append(key, presigned.fields[key]);
|
|
159
|
+
formData.append(key, presigned.fields[key as keyof S3PresignedPost['fields']]);
|
|
159
160
|
});
|
|
161
|
+
formData.append("file", file) // must be appended last
|
|
160
162
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
formData.append("file", file as Blob)
|
|
163
|
+
const headers = formData.getHeaders ? { ...formData.getHeaders(), 'Content-Length' : (formData as any).maxDataSize }
|
|
164
|
+
: { 'Content-Type': 'multipart/form-data' }
|
|
164
165
|
|
|
165
|
-
|
|
166
|
-
await axios.post(presigned.url, formData, {
|
|
167
|
-
headers: IN_BROWSER
|
|
168
|
-
? { 'Content-Type': 'multipart/form-data'}
|
|
169
|
-
: {
|
|
170
|
-
...(formData as NodeFormData).getHeaders(),
|
|
171
|
-
'Content-Length' : (formData as any).maxDataSize
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
catch(err) { console.error(err); throw err }
|
|
166
|
+
await axios.post(presigned.url, formData, { headers })
|
|
176
167
|
}
|
|
177
168
|
|
|
178
169
|
DOWNLOAD = async (downloadURL: string) => {
|
|
@@ -181,6 +172,9 @@ export class Session {
|
|
|
181
172
|
}
|
|
182
173
|
|
|
183
174
|
EMIT = async (route: string, args: object, authenticated=true, options={} as RequestOptions) => {
|
|
175
|
+
if (!this.socket) {
|
|
176
|
+
this.authenticate_socket() // sets namespace correctly
|
|
177
|
+
}
|
|
184
178
|
this.socket?.emit(route, { ...args, ...authenticated ? { authToken: this.authToken } : {} } )
|
|
185
179
|
}
|
|
186
180
|
|
|
@@ -199,6 +193,7 @@ export class Session {
|
|
|
199
193
|
removeAllSocketListeners = (s: string) => this.socket?.removeAllListeners(s)
|
|
200
194
|
|
|
201
195
|
authenticate_socket = () => {
|
|
196
|
+
if (!this.userInfo?.businessId) return
|
|
202
197
|
this.socket = io(`${this.host}/${this.userInfo.businessId}`, { transports: ['websocket'] }); // supporting polling requires sticky session at load balancer
|
|
203
198
|
this.socket.on('disconnect', () => { this.socketAuthenticated = false })
|
|
204
199
|
this.socket.on('authenticated', () => { this.socketAuthenticated = true })
|
package/src/tests/tests.ts
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
const host = process.env.TEST_URL || 'http://localhost:8080'
|
|
50
50
|
const [email, password] = [process.env.TEST_EMAIL, process.env.TEST_PASSWORD]
|
|
51
51
|
const [email2, password2] = [process.env.TEST_EMAIL_2, process.env.TEST_PASSWORD_2]
|
|
52
|
+
const [nonAdminEmail, nonAdminPassword] = [process.env.NON_ADMIN_EMAIL, process.env.NON_ADMIN_PASSWORD]
|
|
52
53
|
|
|
53
54
|
const userId = '60398b0231a295e64f084fd9'
|
|
54
55
|
|
|
@@ -73,10 +74,11 @@ const userId = '60398b0231a295e64f084fd9'
|
|
|
73
74
|
|
|
74
75
|
const sdk = new Session({ host })
|
|
75
76
|
const sdkOther = new Session({ host, apiKey: "ba745e25162bb95a795c5fa1af70df188d93c4d3aac9c48b34a5c8c9dd7b80f7" })
|
|
77
|
+
const sdkNonAdmin = new Session({ host })
|
|
76
78
|
const enduserSDK = new EnduserSession({ host })
|
|
77
79
|
// const sdkOtherEmail = "sebass@tellescope.com"
|
|
78
80
|
|
|
79
|
-
if (!(email && password && email2 && password2)) {
|
|
81
|
+
if (!(email && password && email2 && password2 && nonAdminEmail && nonAdminPassword)) {
|
|
80
82
|
console.error("Set TEST_EMAIL and TEST_PASSWORD")
|
|
81
83
|
process.exit()
|
|
82
84
|
}
|
|
@@ -293,8 +295,13 @@ const generateEnduserAuthTests = async () => {
|
|
|
293
295
|
|
|
294
296
|
const { authToken, enduser } = await sdk.api.endusers.generate_auth_token({ id: e.id })
|
|
295
297
|
assert(!!authToken && !!enduser, 'invalid returned values', 'Generate authToken and get enduser')
|
|
296
|
-
|
|
298
|
+
let { isAuthenticated } = await sdk.api.endusers.is_authenticated({ id: enduser.id, authToken })
|
|
297
299
|
assert(isAuthenticated, 'invalid authToken generated for enduser', 'Generate authToken for enduser is valid')
|
|
300
|
+
assert(
|
|
301
|
+
(await sdk.api.endusers.is_authenticated({ authToken })).isAuthenticated,
|
|
302
|
+
'id omitted results in failed authentication',
|
|
303
|
+
'id optional for is_authenticated'
|
|
304
|
+
)
|
|
298
305
|
|
|
299
306
|
const { authToken: authTokenUID, enduser: enduser2 } = await sdk.api.endusers.generate_auth_token({ externalId })
|
|
300
307
|
assert(!!authTokenUID && !!enduser2, 'invalid returned values eid', 'Generate authToken and get enduser eid')
|
|
@@ -967,6 +974,7 @@ const enduserAccessTests = async () => {
|
|
|
967
974
|
const password = 'testpassword'
|
|
968
975
|
|
|
969
976
|
const enduser = await sdk.api.endusers.createOne({ email })
|
|
977
|
+
const enduser2 = await sdk.api.endusers.createOne({ email: 'hi' + email })
|
|
970
978
|
await sdk.api.endusers.set_password({ id: enduser.id, password }).catch(console.error)
|
|
971
979
|
await enduserSDK.authenticate(email, password).catch(console.error)
|
|
972
980
|
|
|
@@ -1019,6 +1027,17 @@ const enduserAccessTests = async () => {
|
|
|
1019
1027
|
}
|
|
1020
1028
|
}
|
|
1021
1029
|
|
|
1030
|
+
await async_test(
|
|
1031
|
+
`enduser can update self`,
|
|
1032
|
+
() => enduserSDK.api.endusers.updateOne(enduser.id, { fname: "Sebastian", lname: "Coates" }),
|
|
1033
|
+
{ onResult: e => e.id === enduser.id && e.fname === 'Sebastian' && e.lname === "Coates" }
|
|
1034
|
+
)
|
|
1035
|
+
await async_test(
|
|
1036
|
+
`enduser can't update other enduser`,
|
|
1037
|
+
() => enduserSDK.api.endusers.updateOne(enduser2.id, { fname: "Shouldn't Work"}),
|
|
1038
|
+
{ shouldError: true, onError: e => e.message === "Could not find a record for the given id" }
|
|
1039
|
+
)
|
|
1040
|
+
|
|
1022
1041
|
const ticketAccessible = await sdk.api.tickets.createOne({ enduserId: enduser.id, title: "Accessible ticket" })
|
|
1023
1042
|
const ticketInaccessible = await sdk.api.tickets.createOne({ enduserId: PLACEHOLDER_ID, title: "Inaccessible ticket" })
|
|
1024
1043
|
await async_test(
|
|
@@ -1045,6 +1064,7 @@ const enduserAccessTests = async () => {
|
|
|
1045
1064
|
await sdk.api.tickets.deleteOne(ticketAccessible.id)
|
|
1046
1065
|
await sdk.api.tickets.deleteOne(ticketInaccessible.id)
|
|
1047
1066
|
await sdk.api.endusers.deleteOne(enduser.id)
|
|
1067
|
+
await sdk.api.endusers.deleteOne(enduser2.id)
|
|
1048
1068
|
}
|
|
1049
1069
|
|
|
1050
1070
|
const files_tests = async () => {
|
|
@@ -1053,7 +1073,7 @@ const files_tests = async () => {
|
|
|
1053
1073
|
const { presignedUpload, file } = await sdk.api.files.prepare_file_upload({
|
|
1054
1074
|
name: 'Test File', size: buff.byteLength, type: 'text/plain'
|
|
1055
1075
|
})
|
|
1056
|
-
await sdk.UPLOAD(presignedUpload,
|
|
1076
|
+
await sdk.UPLOAD(presignedUpload, buff)
|
|
1057
1077
|
|
|
1058
1078
|
const { downloadURL } = await sdk.api.files.file_download_URL({ secureName: file.secureName })
|
|
1059
1079
|
const downloaded: string = await sdk.DOWNLOAD(downloadURL)
|
|
@@ -1075,6 +1095,44 @@ const enduser_session_tests = async () => {
|
|
|
1075
1095
|
await sdk.api.endusers.deleteOne(enduser.id)
|
|
1076
1096
|
}
|
|
1077
1097
|
|
|
1098
|
+
const users_tests = async () => {
|
|
1099
|
+
log_header("Users Tests")
|
|
1100
|
+
/* Update user tests */
|
|
1101
|
+
await async_test(
|
|
1102
|
+
`update user (non-admin, other user)`,
|
|
1103
|
+
() => sdkNonAdmin.api.users.updateOne(sdk.userInfo.id, { fname: 'Failure' }),
|
|
1104
|
+
{ shouldError: true, onError: e => e.message === "Only admin users can update others' profiles" }
|
|
1105
|
+
)
|
|
1106
|
+
await async_test(
|
|
1107
|
+
`update user (non-admin, self)`,
|
|
1108
|
+
() => sdkNonAdmin.api.users.updateOne(sdkNonAdmin.userInfo.id, { fname: 'Updated' }),
|
|
1109
|
+
{ onResult: u => u.id === sdkNonAdmin.userInfo.id && u.fname === "Updated" }
|
|
1110
|
+
)
|
|
1111
|
+
await async_test(
|
|
1112
|
+
`verify user update with admin get`,
|
|
1113
|
+
() => sdk.api.users.getOne(sdkNonAdmin.userInfo.id),
|
|
1114
|
+
{ onResult: u => u.id === sdkNonAdmin.userInfo.id && u.fname === "Updated" }
|
|
1115
|
+
)
|
|
1116
|
+
|
|
1117
|
+
// reset fname to "Non" if this test throws, otherwise will falsely pass on next run
|
|
1118
|
+
// NOT Supported behavior any more
|
|
1119
|
+
// assert(sdkNonAdmin.userInfo.fname === 'Updated', 'refresh_session not called on self after update', 'sdk updated on user update')
|
|
1120
|
+
|
|
1121
|
+
await async_test(
|
|
1122
|
+
`update user (admin, other user)`,
|
|
1123
|
+
() => sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { fname: 'Non' }), // change back
|
|
1124
|
+
{ onResult: u => u.id === sdkNonAdmin.userInfo.id && u.fname === "Non" }
|
|
1125
|
+
)
|
|
1126
|
+
// sdkNonAdmin.userInfo.fname = 'Non' // update back in sdk instance as well
|
|
1127
|
+
|
|
1128
|
+
await async_test(
|
|
1129
|
+
`verify user update with admin get`,
|
|
1130
|
+
() => sdk.api.users.getOne(sdkNonAdmin.userInfo.id),
|
|
1131
|
+
{ onResult: u => u.id === sdkNonAdmin.userInfo.id && u.fname === "Non" }
|
|
1132
|
+
)
|
|
1133
|
+
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1078
1136
|
const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
1079
1137
|
chats: chat_tests,
|
|
1080
1138
|
endusers: enduser_tests,
|
|
@@ -1085,7 +1143,7 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
1085
1143
|
emails: email_tests,
|
|
1086
1144
|
sms_messages: sms_tests,
|
|
1087
1145
|
chat_rooms: chat_room_tests,
|
|
1088
|
-
users:
|
|
1146
|
+
users: users_tests,
|
|
1089
1147
|
templates: () => {},
|
|
1090
1148
|
files: files_tests,
|
|
1091
1149
|
tickets: () => {},
|
|
@@ -1098,7 +1156,10 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
|
|
|
1098
1156
|
log_header("API")
|
|
1099
1157
|
|
|
1100
1158
|
try {
|
|
1101
|
-
await
|
|
1159
|
+
await Promise.all([
|
|
1160
|
+
sdk.authenticate(email, password),
|
|
1161
|
+
sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword),
|
|
1162
|
+
])
|
|
1102
1163
|
await setup_tests()
|
|
1103
1164
|
await multi_tenant_tests() // should come right after setup tests
|
|
1104
1165
|
await badInputTests()
|