@budibase/server 2.4.27-alpha.6 → 2.4.27-alpha.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/__mocks__/node-fetch.ts +6 -1
- package/builder/assets/{index.bbeacf52.js → index.7f87e580.js} +2 -2
- package/builder/index.html +1 -1
- package/dist/api/controllers/application.js +27 -23
- package/dist/api/controllers/row/utils.js +4 -3
- package/dist/app.js +1 -0
- package/dist/integrations/redis.js +1 -1
- package/dist/package.json +13 -12
- package/dist/sdk/users/utils.js +2 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/global.js +17 -7
- package/jest.config.ts +1 -0
- package/package.json +14 -13
- package/scripts/test.sh +3 -3
- package/src/api/controllers/application.ts +18 -19
- package/src/api/controllers/row/utils.ts +4 -3
- package/src/api/controllers/view/tests/__snapshots__/viewBuilder.spec.js.snap +48 -48
- package/src/api/routes/tests/__snapshots__/datasource.spec.ts.snap +22 -22
- package/src/api/routes/tests/__snapshots__/view.spec.js.snap +5 -5
- package/src/api/routes/tests/appSync.spec.ts +31 -0
- package/src/api/routes/tests/internalSearch.spec.js +8 -7
- package/src/app.ts +2 -1
- package/src/automations/automationUtils.ts +1 -1
- package/src/automations/tests/automation.spec.ts +99 -0
- package/src/integration-test/postgres.spec.ts +46 -52
- package/src/integrations/redis.ts +1 -1
- package/src/integrations/tests/googlesheets.spec.ts +13 -13
- package/src/integrations/tests/redis.spec.ts +9 -5
- package/src/middleware/currentapp.ts +2 -2
- package/src/sdk/users/utils.ts +4 -1
- package/src/tests/jestEnv.ts +1 -0
- package/src/tests/jestSetup.ts +5 -1
- package/src/tests/utilities/TestConfiguration.ts +13 -0
- package/src/tests/utilities/structures.ts +13 -1
- package/src/utilities/global.ts +21 -9
- package/src/automations/tests/automation.spec.js +0 -84
package/dist/utilities/global.js
CHANGED
|
@@ -45,26 +45,33 @@ function updateAppRole(user, { appId } = {}) {
|
|
|
45
45
|
return user;
|
|
46
46
|
}
|
|
47
47
|
exports.updateAppRole = updateAppRole;
|
|
48
|
-
function checkGroupRoles(user,
|
|
48
|
+
function checkGroupRoles(user, opts = {}) {
|
|
49
49
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50
50
|
if (user.roleId && user.roleId !== backend_core_1.roles.BUILTIN_ROLE_IDS.PUBLIC) {
|
|
51
51
|
return user;
|
|
52
52
|
}
|
|
53
|
-
if (appId) {
|
|
54
|
-
user.roleId = yield pro_1.groups.getGroupRoleId(user, appId
|
|
53
|
+
if (opts.appId) {
|
|
54
|
+
user.roleId = yield pro_1.groups.getGroupRoleId(user, opts.appId, {
|
|
55
|
+
groups: opts.groups,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// final fallback, simply couldn't find a role - user must be public
|
|
59
|
+
if (!user.roleId) {
|
|
60
|
+
user.roleId = backend_core_1.roles.BUILTIN_ROLE_IDS.PUBLIC;
|
|
55
61
|
}
|
|
56
62
|
return user;
|
|
57
63
|
});
|
|
58
64
|
}
|
|
59
|
-
function processUser(user,
|
|
65
|
+
function processUser(user, opts = {}) {
|
|
60
66
|
var _a;
|
|
61
67
|
return __awaiter(this, void 0, void 0, function* () {
|
|
62
68
|
if (user) {
|
|
63
69
|
delete user.password;
|
|
64
70
|
}
|
|
65
|
-
|
|
71
|
+
const appId = opts.appId || backend_core_1.context.getAppId();
|
|
72
|
+
user = updateAppRole(user, { appId });
|
|
66
73
|
if (!user.roleId && ((_a = user === null || user === void 0 ? void 0 : user.userGroups) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
67
|
-
user = yield checkGroupRoles(user, { appId });
|
|
74
|
+
user = yield checkGroupRoles(user, { appId, groups: opts === null || opts === void 0 ? void 0 : opts.groups });
|
|
68
75
|
}
|
|
69
76
|
return user;
|
|
70
77
|
});
|
|
@@ -98,6 +105,7 @@ function getGlobalUsers(users) {
|
|
|
98
105
|
return __awaiter(this, void 0, void 0, function* () {
|
|
99
106
|
const appId = backend_core_1.context.getAppId();
|
|
100
107
|
const db = backend_core_1.tenancy.getGlobalDB();
|
|
108
|
+
const allGroups = yield pro_1.groups.fetch();
|
|
101
109
|
let globalUsers;
|
|
102
110
|
if (users) {
|
|
103
111
|
const globalIds = users.map(user => (0, utils_1.getGlobalIDFromUserMetadataID)(user._id));
|
|
@@ -118,7 +126,9 @@ function getGlobalUsers(users) {
|
|
|
118
126
|
if (!appId) {
|
|
119
127
|
return globalUsers;
|
|
120
128
|
}
|
|
121
|
-
|
|
129
|
+
// pass in the groups, meaning we don't actually need to retrieve them for
|
|
130
|
+
// each user individually
|
|
131
|
+
return Promise.all(globalUsers.map(user => processUser(user, { groups: allGroups })));
|
|
122
132
|
});
|
|
123
133
|
}
|
|
124
134
|
exports.getGlobalUsers = getGlobalUsers;
|
package/jest.config.ts
CHANGED
|
@@ -43,6 +43,7 @@ const config: Config.InitialOptions = {
|
|
|
43
43
|
"../backend-core/src/**/*.{js,ts}",
|
|
44
44
|
// The use of coverage with couchdb view functions breaks tests
|
|
45
45
|
"!src/db/views/staticViews.*",
|
|
46
|
+
"!src/**/*.spec.{js,ts}",
|
|
46
47
|
],
|
|
47
48
|
coverageReporters: ["lcov", "json", "clover"],
|
|
48
49
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.4.27-alpha.
|
|
4
|
+
"version": "2.4.27-alpha.8",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
|
15
15
|
"debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js",
|
|
16
16
|
"postbuild": "copyfiles -u 1 src/**/*.svelte dist/ && copyfiles -u 1 src/**/*.hbs dist/ && copyfiles -u 1 src/**/*.json dist/",
|
|
17
|
-
"test": "bash scripts/test.sh",
|
|
17
|
+
"test": "NODE_OPTIONS=\"--max-old-space-size=4096\" bash scripts/test.sh",
|
|
18
|
+
"test:memory": "jest --maxWorkers=2 --logHeapUsage --forceExit",
|
|
18
19
|
"test:watch": "jest --watch",
|
|
19
20
|
"predocker": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client",
|
|
20
21
|
"build:docker": "yarn run predocker && docker build . -t app-service --label version=$BUDIBASE_RELEASE_VERSION",
|
|
@@ -43,12 +44,12 @@
|
|
|
43
44
|
"license": "GPL-3.0",
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
46
|
-
"@budibase/backend-core": "2.4.27-alpha.
|
|
47
|
-
"@budibase/client": "2.4.27-alpha.
|
|
48
|
-
"@budibase/pro": "2.4.27-alpha.
|
|
49
|
-
"@budibase/shared-core": "2.4.27-alpha.
|
|
50
|
-
"@budibase/string-templates": "2.4.27-alpha.
|
|
51
|
-
"@budibase/types": "2.4.27-alpha.
|
|
47
|
+
"@budibase/backend-core": "2.4.27-alpha.8",
|
|
48
|
+
"@budibase/client": "2.4.27-alpha.8",
|
|
49
|
+
"@budibase/pro": "2.4.27-alpha.7",
|
|
50
|
+
"@budibase/shared-core": "2.4.27-alpha.8",
|
|
51
|
+
"@budibase/string-templates": "2.4.27-alpha.8",
|
|
52
|
+
"@budibase/types": "2.4.27-alpha.8",
|
|
52
53
|
"@bull-board/api": "3.7.0",
|
|
53
54
|
"@bull-board/koa": "3.9.4",
|
|
54
55
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -125,7 +126,7 @@
|
|
|
125
126
|
"@babel/core": "7.17.4",
|
|
126
127
|
"@babel/preset-env": "7.16.11",
|
|
127
128
|
"@budibase/standard-components": "^0.9.139",
|
|
128
|
-
"@jest/test-sequencer": "
|
|
129
|
+
"@jest/test-sequencer": "29.5.0",
|
|
129
130
|
"@swc/core": "^1.3.25",
|
|
130
131
|
"@swc/jest": "^0.2.24",
|
|
131
132
|
"@trendyol/jest-testcontainers": "^2.1.1",
|
|
@@ -134,7 +135,7 @@
|
|
|
134
135
|
"@types/global-agent": "2.1.1",
|
|
135
136
|
"@types/google-spreadsheet": "3.1.5",
|
|
136
137
|
"@types/ioredis": "4.28.10",
|
|
137
|
-
"@types/jest": "
|
|
138
|
+
"@types/jest": "29.5.0",
|
|
138
139
|
"@types/koa": "2.13.4",
|
|
139
140
|
"@types/koa__router": "8.0.8",
|
|
140
141
|
"@types/lodash": "4.14.180",
|
|
@@ -154,7 +155,7 @@
|
|
|
154
155
|
"eslint": "6.8.0",
|
|
155
156
|
"ioredis-mock": "7.2.0",
|
|
156
157
|
"is-wsl": "2.2.0",
|
|
157
|
-
"jest": "
|
|
158
|
+
"jest": "29.5.0",
|
|
158
159
|
"jest-openapi": "0.14.2",
|
|
159
160
|
"jest-serial-runner": "^1.2.1",
|
|
160
161
|
"nodemon": "2.0.15",
|
|
@@ -166,7 +167,7 @@
|
|
|
166
167
|
"supertest": "6.2.2",
|
|
167
168
|
"swagger-jsdoc": "6.1.0",
|
|
168
169
|
"timekeeper": "2.2.0",
|
|
169
|
-
"ts-jest": "
|
|
170
|
+
"ts-jest": "29.0.5",
|
|
170
171
|
"ts-node": "10.8.1",
|
|
171
172
|
"tsconfig-paths": "4.0.0",
|
|
172
173
|
"typescript": "4.7.3",
|
|
@@ -175,5 +176,5 @@
|
|
|
175
176
|
"optionalDependencies": {
|
|
176
177
|
"oracledb": "5.3.0"
|
|
177
178
|
},
|
|
178
|
-
"gitHead": "
|
|
179
|
+
"gitHead": "daeec6f5201291037b1ba89e7db3b587a09bd2e1"
|
|
179
180
|
}
|
package/scripts/test.sh
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
if [[ -n $CI ]]
|
|
4
4
|
then
|
|
5
5
|
# --runInBand performs better in ci where resources are limited
|
|
6
|
-
echo "jest --coverage --runInBand"
|
|
7
|
-
jest --coverage --runInBand
|
|
6
|
+
echo "jest --coverage --runInBand --forceExit"
|
|
7
|
+
jest --coverage --runInBand --forceExit
|
|
8
8
|
else
|
|
9
9
|
# --maxWorkers performs better in development
|
|
10
10
|
echo "jest --coverage --maxWorkers=2"
|
|
11
11
|
jest --coverage --maxWorkers=2
|
|
12
|
-
fi
|
|
12
|
+
fi
|
|
@@ -44,7 +44,6 @@ import {
|
|
|
44
44
|
Layout,
|
|
45
45
|
Screen,
|
|
46
46
|
MigrationType,
|
|
47
|
-
BBContext,
|
|
48
47
|
Database,
|
|
49
48
|
UserCtx,
|
|
50
49
|
} from "@budibase/types"
|
|
@@ -74,14 +73,14 @@ async function getScreens() {
|
|
|
74
73
|
).rows.map((row: any) => row.doc)
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
function getUserRoleId(ctx:
|
|
76
|
+
function getUserRoleId(ctx: UserCtx) {
|
|
78
77
|
return !ctx.user?.role || !ctx.user.role._id
|
|
79
78
|
? roles.BUILTIN_ROLE_IDS.PUBLIC
|
|
80
79
|
: ctx.user.role._id
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
function checkAppUrl(
|
|
84
|
-
ctx:
|
|
83
|
+
ctx: UserCtx,
|
|
85
84
|
apps: App[],
|
|
86
85
|
url: string,
|
|
87
86
|
currentAppId?: string
|
|
@@ -95,7 +94,7 @@ function checkAppUrl(
|
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
function checkAppName(
|
|
98
|
-
ctx:
|
|
97
|
+
ctx: UserCtx,
|
|
99
98
|
apps: App[],
|
|
100
99
|
name: string,
|
|
101
100
|
currentAppId?: string
|
|
@@ -160,7 +159,7 @@ async function addDefaultTables(db: Database) {
|
|
|
160
159
|
await db.bulkDocs([...defaultDbDocs])
|
|
161
160
|
}
|
|
162
161
|
|
|
163
|
-
export async function fetch(ctx:
|
|
162
|
+
export async function fetch(ctx: UserCtx) {
|
|
164
163
|
const dev = ctx.query && ctx.query.status === AppStatus.DEV
|
|
165
164
|
const all = ctx.query && ctx.query.status === AppStatus.ALL
|
|
166
165
|
const apps = (await dbCore.getAllApps({ dev, all })) as App[]
|
|
@@ -185,7 +184,7 @@ export async function fetch(ctx: BBContext) {
|
|
|
185
184
|
ctx.body = await checkAppMetadata(apps)
|
|
186
185
|
}
|
|
187
186
|
|
|
188
|
-
export async function fetchAppDefinition(ctx:
|
|
187
|
+
export async function fetchAppDefinition(ctx: UserCtx) {
|
|
189
188
|
const layouts = await getLayouts()
|
|
190
189
|
const userRoleId = getUserRoleId(ctx)
|
|
191
190
|
const accessController = new roles.AccessController()
|
|
@@ -231,7 +230,7 @@ export async function fetchAppPackage(ctx: UserCtx) {
|
|
|
231
230
|
}
|
|
232
231
|
}
|
|
233
232
|
|
|
234
|
-
async function performAppCreate(ctx:
|
|
233
|
+
async function performAppCreate(ctx: UserCtx) {
|
|
235
234
|
const apps = (await dbCore.getAllApps({ dev: true })) as App[]
|
|
236
235
|
const name = ctx.request.body.name,
|
|
237
236
|
possibleUrl = ctx.request.body.url
|
|
@@ -360,7 +359,7 @@ async function creationEvents(request: any, app: App) {
|
|
|
360
359
|
}
|
|
361
360
|
}
|
|
362
361
|
|
|
363
|
-
async function appPostCreate(ctx:
|
|
362
|
+
async function appPostCreate(ctx: UserCtx, app: App) {
|
|
364
363
|
const tenantId = tenancy.getTenantId()
|
|
365
364
|
await migrations.backPopulateMigrations({
|
|
366
365
|
type: MigrationType.APP,
|
|
@@ -391,7 +390,7 @@ async function appPostCreate(ctx: BBContext, app: App) {
|
|
|
391
390
|
}
|
|
392
391
|
}
|
|
393
392
|
|
|
394
|
-
export async function create(ctx:
|
|
393
|
+
export async function create(ctx: UserCtx) {
|
|
395
394
|
const newApplication = await quotas.addApp(() => performAppCreate(ctx))
|
|
396
395
|
await appPostCreate(ctx, newApplication)
|
|
397
396
|
await cache.bustCache(cache.CacheKey.CHECKLIST)
|
|
@@ -401,7 +400,7 @@ export async function create(ctx: BBContext) {
|
|
|
401
400
|
|
|
402
401
|
// This endpoint currently operates as a PATCH rather than a PUT
|
|
403
402
|
// Thus name and url fields are handled only if present
|
|
404
|
-
export async function update(ctx:
|
|
403
|
+
export async function update(ctx: UserCtx) {
|
|
405
404
|
const apps = (await dbCore.getAllApps({ dev: true })) as App[]
|
|
406
405
|
// validation
|
|
407
406
|
const name = ctx.request.body.name,
|
|
@@ -421,7 +420,7 @@ export async function update(ctx: BBContext) {
|
|
|
421
420
|
ctx.body = app
|
|
422
421
|
}
|
|
423
422
|
|
|
424
|
-
export async function updateClient(ctx:
|
|
423
|
+
export async function updateClient(ctx: UserCtx) {
|
|
425
424
|
// Get current app version
|
|
426
425
|
const db = context.getAppDB()
|
|
427
426
|
const application = await db.get(DocumentType.APP_METADATA)
|
|
@@ -445,7 +444,7 @@ export async function updateClient(ctx: BBContext) {
|
|
|
445
444
|
ctx.body = app
|
|
446
445
|
}
|
|
447
446
|
|
|
448
|
-
export async function revertClient(ctx:
|
|
447
|
+
export async function revertClient(ctx: UserCtx) {
|
|
449
448
|
// Check app can be reverted
|
|
450
449
|
const db = context.getAppDB()
|
|
451
450
|
const application = await db.get(DocumentType.APP_METADATA)
|
|
@@ -471,7 +470,7 @@ export async function revertClient(ctx: BBContext) {
|
|
|
471
470
|
ctx.body = app
|
|
472
471
|
}
|
|
473
472
|
|
|
474
|
-
|
|
473
|
+
async function unpublishApp(ctx: UserCtx) {
|
|
475
474
|
let appId = ctx.params.appId
|
|
476
475
|
appId = dbCore.getProdAppID(appId)
|
|
477
476
|
|
|
@@ -487,7 +486,7 @@ const unpublishApp = async (ctx: any) => {
|
|
|
487
486
|
return result
|
|
488
487
|
}
|
|
489
488
|
|
|
490
|
-
async function destroyApp(ctx:
|
|
489
|
+
async function destroyApp(ctx: UserCtx) {
|
|
491
490
|
let appId = ctx.params.appId
|
|
492
491
|
appId = dbCore.getProdAppID(appId)
|
|
493
492
|
const devAppId = dbCore.getDevAppID(appId)
|
|
@@ -515,12 +514,12 @@ async function destroyApp(ctx: BBContext) {
|
|
|
515
514
|
return result
|
|
516
515
|
}
|
|
517
516
|
|
|
518
|
-
async function preDestroyApp(ctx:
|
|
517
|
+
async function preDestroyApp(ctx: UserCtx) {
|
|
519
518
|
const { rows } = await getUniqueRows([ctx.params.appId])
|
|
520
519
|
ctx.rowCount = rows.length
|
|
521
520
|
}
|
|
522
521
|
|
|
523
|
-
async function postDestroyApp(ctx:
|
|
522
|
+
async function postDestroyApp(ctx: UserCtx) {
|
|
524
523
|
const rowCount = ctx.rowCount
|
|
525
524
|
await groups.cleanupApp(ctx.params.appId)
|
|
526
525
|
if (rowCount) {
|
|
@@ -528,7 +527,7 @@ async function postDestroyApp(ctx: BBContext) {
|
|
|
528
527
|
}
|
|
529
528
|
}
|
|
530
529
|
|
|
531
|
-
export async function destroy(ctx:
|
|
530
|
+
export async function destroy(ctx: UserCtx) {
|
|
532
531
|
await preDestroyApp(ctx)
|
|
533
532
|
const result = await destroyApp(ctx)
|
|
534
533
|
await postDestroyApp(ctx)
|
|
@@ -536,7 +535,7 @@ export async function destroy(ctx: BBContext) {
|
|
|
536
535
|
ctx.body = result
|
|
537
536
|
}
|
|
538
537
|
|
|
539
|
-
export
|
|
538
|
+
export async function unpublish(ctx: UserCtx) {
|
|
540
539
|
const prodAppId = dbCore.getProdAppID(ctx.params.appId)
|
|
541
540
|
const dbExists = await dbCore.dbExists(prodAppId)
|
|
542
541
|
|
|
@@ -551,7 +550,7 @@ export const unpublish = async (ctx: BBContext) => {
|
|
|
551
550
|
ctx.status = 204
|
|
552
551
|
}
|
|
553
552
|
|
|
554
|
-
export async function sync(ctx:
|
|
553
|
+
export async function sync(ctx: UserCtx) {
|
|
555
554
|
const appId = ctx.params.appId
|
|
556
555
|
try {
|
|
557
556
|
ctx.body = await sdk.applications.syncApp(appId)
|
|
@@ -62,10 +62,11 @@ export async function validate({
|
|
|
62
62
|
}
|
|
63
63
|
const errors: any = {}
|
|
64
64
|
for (let fieldName of Object.keys(fetchedTable.schema)) {
|
|
65
|
-
const
|
|
66
|
-
const
|
|
65
|
+
const column = fetchedTable.schema[fieldName]
|
|
66
|
+
const constraints = cloneDeep(column.constraints)
|
|
67
|
+
const type = column.type
|
|
67
68
|
// formulas shouldn't validated, data will be deleted anyway
|
|
68
|
-
if (type === FieldTypes.FORMULA) {
|
|
69
|
+
if (type === FieldTypes.FORMULA || column.autocolumn) {
|
|
69
70
|
continue
|
|
70
71
|
}
|
|
71
72
|
// special case for options, need to always allow unselected (null)
|
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`viewBuilder Calculate and filter creates a view with the calculation statistics and filter schema 1`] = `
|
|
4
|
-
|
|
4
|
+
{
|
|
5
5
|
"map": "function (doc) {
|
|
6
|
-
if ((doc.tableId ===
|
|
7
|
-
doc[
|
|
8
|
-
doc[
|
|
9
|
-
doc[
|
|
10
|
-
(Array.isArray(doc[
|
|
11
|
-
)) && (doc[
|
|
12
|
-
emit(doc[
|
|
6
|
+
if ((doc.tableId === "14f1c4e94d6a47b682ce89d35d4c78b0" && !(
|
|
7
|
+
doc["myField"] === undefined ||
|
|
8
|
+
doc["myField"] === null ||
|
|
9
|
+
doc["myField"] === "" ||
|
|
10
|
+
(Array.isArray(doc["myField"]) && doc["myField"].length === 0)
|
|
11
|
+
)) && (doc["age"] > 17)) {
|
|
12
|
+
emit(doc["_id"], doc["myField"]);
|
|
13
13
|
}
|
|
14
14
|
}",
|
|
15
|
-
"meta":
|
|
15
|
+
"meta": {
|
|
16
16
|
"calculation": "stats",
|
|
17
17
|
"field": "myField",
|
|
18
|
-
"filters":
|
|
19
|
-
|
|
18
|
+
"filters": [
|
|
19
|
+
{
|
|
20
20
|
"condition": "MT",
|
|
21
21
|
"key": "age",
|
|
22
22
|
"value": 17,
|
|
23
23
|
},
|
|
24
24
|
],
|
|
25
25
|
"groupBy": undefined,
|
|
26
|
-
"schema":
|
|
27
|
-
"avg":
|
|
26
|
+
"schema": {
|
|
27
|
+
"avg": {
|
|
28
28
|
"type": "number",
|
|
29
29
|
},
|
|
30
|
-
"count":
|
|
30
|
+
"count": {
|
|
31
31
|
"type": "number",
|
|
32
32
|
},
|
|
33
|
-
"field":
|
|
33
|
+
"field": {
|
|
34
34
|
"type": "string",
|
|
35
35
|
},
|
|
36
|
-
"max":
|
|
36
|
+
"max": {
|
|
37
37
|
"type": "number",
|
|
38
38
|
},
|
|
39
|
-
"min":
|
|
39
|
+
"min": {
|
|
40
40
|
"type": "number",
|
|
41
41
|
},
|
|
42
|
-
"sum":
|
|
42
|
+
"sum": {
|
|
43
43
|
"type": "number",
|
|
44
44
|
},
|
|
45
|
-
"sumsqr":
|
|
45
|
+
"sumsqr": {
|
|
46
46
|
"type": "number",
|
|
47
47
|
},
|
|
48
48
|
},
|
|
@@ -53,42 +53,42 @@ Object {
|
|
|
53
53
|
`;
|
|
54
54
|
|
|
55
55
|
exports[`viewBuilder Calculate creates a view with the calculation statistics schema 1`] = `
|
|
56
|
-
|
|
56
|
+
{
|
|
57
57
|
"map": "function (doc) {
|
|
58
|
-
if ((doc.tableId ===
|
|
59
|
-
doc[
|
|
60
|
-
doc[
|
|
61
|
-
doc[
|
|
62
|
-
(Array.isArray(doc[
|
|
58
|
+
if ((doc.tableId === "14f1c4e94d6a47b682ce89d35d4c78b0" && !(
|
|
59
|
+
doc["myField"] === undefined ||
|
|
60
|
+
doc["myField"] === null ||
|
|
61
|
+
doc["myField"] === "" ||
|
|
62
|
+
(Array.isArray(doc["myField"]) && doc["myField"].length === 0)
|
|
63
63
|
)) ) {
|
|
64
|
-
emit(doc[
|
|
64
|
+
emit(doc["_id"], doc["myField"]);
|
|
65
65
|
}
|
|
66
66
|
}",
|
|
67
|
-
"meta":
|
|
67
|
+
"meta": {
|
|
68
68
|
"calculation": "stats",
|
|
69
69
|
"field": "myField",
|
|
70
|
-
"filters":
|
|
70
|
+
"filters": [],
|
|
71
71
|
"groupBy": undefined,
|
|
72
|
-
"schema":
|
|
73
|
-
"avg":
|
|
72
|
+
"schema": {
|
|
73
|
+
"avg": {
|
|
74
74
|
"type": "number",
|
|
75
75
|
},
|
|
76
|
-
"count":
|
|
76
|
+
"count": {
|
|
77
77
|
"type": "number",
|
|
78
78
|
},
|
|
79
|
-
"field":
|
|
79
|
+
"field": {
|
|
80
80
|
"type": "string",
|
|
81
81
|
},
|
|
82
|
-
"max":
|
|
82
|
+
"max": {
|
|
83
83
|
"type": "number",
|
|
84
84
|
},
|
|
85
|
-
"min":
|
|
85
|
+
"min": {
|
|
86
86
|
"type": "number",
|
|
87
87
|
},
|
|
88
|
-
"sum":
|
|
88
|
+
"sum": {
|
|
89
89
|
"type": "number",
|
|
90
90
|
},
|
|
91
|
-
"sumsqr":
|
|
91
|
+
"sumsqr": {
|
|
92
92
|
"type": "number",
|
|
93
93
|
},
|
|
94
94
|
},
|
|
@@ -99,22 +99,22 @@ Object {
|
|
|
99
99
|
`;
|
|
100
100
|
|
|
101
101
|
exports[`viewBuilder Filter creates a view with multiple filters and conjunctions 1`] = `
|
|
102
|
-
|
|
102
|
+
{
|
|
103
103
|
"map": "function (doc) {
|
|
104
|
-
if (doc.tableId ===
|
|
105
|
-
emit(doc[
|
|
104
|
+
if (doc.tableId === "14f1c4e94d6a47b682ce89d35d4c78b0" && (doc["Name"] === "Test" || doc["Yes"] > "Value")) {
|
|
105
|
+
emit(doc["_id"], doc["undefined"]);
|
|
106
106
|
}
|
|
107
107
|
}",
|
|
108
|
-
"meta":
|
|
108
|
+
"meta": {
|
|
109
109
|
"calculation": undefined,
|
|
110
110
|
"field": undefined,
|
|
111
|
-
"filters":
|
|
112
|
-
|
|
111
|
+
"filters": [
|
|
112
|
+
{
|
|
113
113
|
"condition": "EQUALS",
|
|
114
114
|
"key": "Name",
|
|
115
115
|
"value": "Test",
|
|
116
116
|
},
|
|
117
|
-
|
|
117
|
+
{
|
|
118
118
|
"condition": "MT",
|
|
119
119
|
"conjunction": "OR",
|
|
120
120
|
"key": "Yes",
|
|
@@ -129,16 +129,16 @@ Object {
|
|
|
129
129
|
`;
|
|
130
130
|
|
|
131
131
|
exports[`viewBuilder Group By creates a view emitting the group by field 1`] = `
|
|
132
|
-
|
|
132
|
+
{
|
|
133
133
|
"map": "function (doc) {
|
|
134
|
-
if (doc.tableId ===
|
|
135
|
-
emit(doc[
|
|
134
|
+
if (doc.tableId === "14f1c4e94d6a47b682ce89d35d4c78b0" ) {
|
|
135
|
+
emit(doc["age"], doc["score"]);
|
|
136
136
|
}
|
|
137
137
|
}",
|
|
138
|
-
"meta":
|
|
138
|
+
"meta": {
|
|
139
139
|
"calculation": undefined,
|
|
140
140
|
"field": "score",
|
|
141
|
-
"filters":
|
|
141
|
+
"filters": [],
|
|
142
142
|
"groupBy": "age",
|
|
143
143
|
"schema": null,
|
|
144
144
|
"tableId": "14f1c4e94d6a47b682ce89d35d4c78b0",
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`/datasources fetch returns all the datasources from the server 1`] = `
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"config":
|
|
7
|
-
"entities":
|
|
8
|
-
|
|
4
|
+
[
|
|
5
|
+
{
|
|
6
|
+
"config": {},
|
|
7
|
+
"entities": [
|
|
8
|
+
{
|
|
9
9
|
"_id": "ta_users",
|
|
10
10
|
"_rev": "1-2375e1bc58aeec664dc1b1f04ad43e44",
|
|
11
11
|
"createdAt": "2020-01-01T00:00:00.000Z",
|
|
12
12
|
"name": "Users",
|
|
13
13
|
"primaryDisplay": "email",
|
|
14
|
-
"schema":
|
|
15
|
-
"email":
|
|
16
|
-
"constraints":
|
|
14
|
+
"schema": {
|
|
15
|
+
"email": {
|
|
16
|
+
"constraints": {
|
|
17
17
|
"email": true,
|
|
18
|
-
"length":
|
|
18
|
+
"length": {
|
|
19
19
|
"maximum": "",
|
|
20
20
|
},
|
|
21
21
|
"presence": true,
|
|
@@ -25,8 +25,8 @@ Array [
|
|
|
25
25
|
"name": "email",
|
|
26
26
|
"type": "string",
|
|
27
27
|
},
|
|
28
|
-
"firstName":
|
|
29
|
-
"constraints":
|
|
28
|
+
"firstName": {
|
|
29
|
+
"constraints": {
|
|
30
30
|
"presence": false,
|
|
31
31
|
"type": "string",
|
|
32
32
|
},
|
|
@@ -34,8 +34,8 @@ Array [
|
|
|
34
34
|
"name": "firstName",
|
|
35
35
|
"type": "string",
|
|
36
36
|
},
|
|
37
|
-
"lastName":
|
|
38
|
-
"constraints":
|
|
37
|
+
"lastName": {
|
|
38
|
+
"constraints": {
|
|
39
39
|
"presence": false,
|
|
40
40
|
"type": "string",
|
|
41
41
|
},
|
|
@@ -43,9 +43,9 @@ Array [
|
|
|
43
43
|
"name": "lastName",
|
|
44
44
|
"type": "string",
|
|
45
45
|
},
|
|
46
|
-
"roleId":
|
|
47
|
-
"constraints":
|
|
48
|
-
"inclusion":
|
|
46
|
+
"roleId": {
|
|
47
|
+
"constraints": {
|
|
48
|
+
"inclusion": [
|
|
49
49
|
"ADMIN",
|
|
50
50
|
"POWER",
|
|
51
51
|
"BASIC",
|
|
@@ -58,9 +58,9 @@ Array [
|
|
|
58
58
|
"name": "roleId",
|
|
59
59
|
"type": "options",
|
|
60
60
|
},
|
|
61
|
-
"status":
|
|
62
|
-
"constraints":
|
|
63
|
-
"inclusion":
|
|
61
|
+
"status": {
|
|
62
|
+
"constraints": {
|
|
63
|
+
"inclusion": [
|
|
64
64
|
"active",
|
|
65
65
|
"inactive",
|
|
66
66
|
],
|
|
@@ -74,15 +74,15 @@ Array [
|
|
|
74
74
|
},
|
|
75
75
|
"type": "table",
|
|
76
76
|
"updatedAt": "2020-01-01T00:00:00.000Z",
|
|
77
|
-
"views":
|
|
77
|
+
"views": {},
|
|
78
78
|
},
|
|
79
79
|
],
|
|
80
80
|
"name": "Budibase DB",
|
|
81
81
|
"source": "BUDIBASE",
|
|
82
82
|
"type": "budibase",
|
|
83
83
|
},
|
|
84
|
-
|
|
85
|
-
"config":
|
|
84
|
+
{
|
|
85
|
+
"config": {},
|
|
86
86
|
"createdAt": "2020-01-01T00:00:00.000Z",
|
|
87
87
|
"name": "Test",
|
|
88
88
|
"source": "POSTGRES",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`/views query returns data for the created view 1`] = `
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
[
|
|
5
|
+
{
|
|
6
6
|
"avg": 2333.3333333333335,
|
|
7
7
|
"count": 3,
|
|
8
8
|
"group": null,
|
|
@@ -15,8 +15,8 @@ Array [
|
|
|
15
15
|
`;
|
|
16
16
|
|
|
17
17
|
exports[`/views query returns data for the created view using a group by 1`] = `
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
[
|
|
19
|
+
{
|
|
20
20
|
"avg": 1500,
|
|
21
21
|
"count": 2,
|
|
22
22
|
"group": "One",
|
|
@@ -25,7 +25,7 @@ Array [
|
|
|
25
25
|
"sum": 3000,
|
|
26
26
|
"sumsqr": 5000000,
|
|
27
27
|
},
|
|
28
|
-
|
|
28
|
+
{
|
|
29
29
|
"avg": 4000,
|
|
30
30
|
"count": 1,
|
|
31
31
|
"group": "Two",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as setup from "./utilities"
|
|
2
|
+
import { roles, db as dbCore } from "@budibase/backend-core"
|
|
3
|
+
|
|
4
|
+
describe("/api/applications/:appId/sync", () => {
|
|
5
|
+
let request = setup.getRequest()
|
|
6
|
+
let config = setup.getConfig()
|
|
7
|
+
let app
|
|
8
|
+
|
|
9
|
+
afterAll(setup.afterAll)
|
|
10
|
+
|
|
11
|
+
beforeAll(async () => {
|
|
12
|
+
app = await config.init()
|
|
13
|
+
// create some users which we will use throughout the tests
|
|
14
|
+
await config.createUser({
|
|
15
|
+
email: "sync1@test.com",
|
|
16
|
+
roles: {
|
|
17
|
+
[app._id!]: roles.BUILTIN_ROLE_IDS.BASIC,
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
async function getUserMetadata() {
|
|
23
|
+
const { rows } = await config.searchRows(dbCore.InternalTable.USER_METADATA)
|
|
24
|
+
return rows
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
it("make sure that user metadata is correctly sync'd", async () => {
|
|
28
|
+
const rows = await getUserMetadata()
|
|
29
|
+
expect(rows.length).toBe(1)
|
|
30
|
+
})
|
|
31
|
+
})
|