@budibase/server 2.4.42 → 2.4.43

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.
@@ -37,10 +37,6 @@ const init = () => {
37
37
  }
38
38
  }
39
39
  }
40
- const clientLibPath = (0, path_1.join)((0, budibaseDir_1.budibaseTempDir)(), "budibase-client.js");
41
- if (environment_1.default.isTest() && !fs_1.default.existsSync(clientLibPath)) {
42
- fs_1.default.copyFileSync(require.resolve("@budibase/client"), clientLibPath);
43
- }
44
40
  };
45
41
  exports.init = init;
46
42
  /**
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/tests/**/*.{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.42",
4
+ "version": "2.4.43",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -43,12 +43,12 @@
43
43
  "license": "GPL-3.0",
44
44
  "dependencies": {
45
45
  "@apidevtools/swagger-parser": "10.0.3",
46
- "@budibase/backend-core": "^2.4.42",
47
- "@budibase/client": "^2.4.42",
48
- "@budibase/pro": "2.4.41",
49
- "@budibase/shared-core": "^2.4.42",
50
- "@budibase/string-templates": "^2.4.42",
51
- "@budibase/types": "^2.4.42",
46
+ "@budibase/backend-core": "^2.4.43",
47
+ "@budibase/client": "^2.4.43",
48
+ "@budibase/pro": "2.4.42",
49
+ "@budibase/shared-core": "^2.4.43",
50
+ "@budibase/string-templates": "^2.4.43",
51
+ "@budibase/types": "^2.4.43",
52
52
  "@bull-board/api": "3.7.0",
53
53
  "@bull-board/koa": "3.9.4",
54
54
  "@elastic/elasticsearch": "7.10.0",
@@ -175,5 +175,5 @@
175
175
  "optionalDependencies": {
176
176
  "oracledb": "5.3.0"
177
177
  },
178
- "gitHead": "6cff785e5ac488eafb8b9a4c3ccd7558f2f332cf"
178
+ "gitHead": "0648b19ecff921f3444e1677904846a5b470c329"
179
179
  }
package/scripts/test.sh CHANGED
@@ -1,12 +1,14 @@
1
1
  #!/bin/bash
2
+ set -e
2
3
 
3
4
  if [[ -n $CI ]]
4
5
  then
5
6
  # --runInBand performs better in ci where resources are limited
6
- echo "jest --coverage --runInBand"
7
- jest --coverage --runInBand
7
+ export NODE_OPTIONS="--max-old-space-size=4096"
8
+ echo "jest --coverage --runInBand --forceExit"
9
+ jest --coverage --runInBand --forceExit
8
10
  else
9
11
  # --maxWorkers performs better in development
10
- echo "jest --coverage --maxWorkers=2"
11
- jest --coverage --maxWorkers=2
12
+ echo "jest --coverage --maxWorkers=2 --forceExit"
13
+ jest --coverage --maxWorkers=2 --forceExit
12
14
  fi
@@ -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 constraints = cloneDeep(fetchedTable.schema[fieldName].constraints)
66
- const type = fetchedTable.schema[fieldName].type
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)
@@ -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 its empty initially", async () => {
28
+ const rows = await getUserMetadata()
29
+ expect(rows.length).toBe(1)
30
+ })
31
+ })
@@ -1,6 +1,7 @@
1
+ const fetch = require("node-fetch")
2
+ fetch.mockSearch()
1
3
  const search = require("../../controllers/row/internalSearch")
2
4
  // this will be mocked out for _search endpoint
3
- const fetch = require("node-fetch")
4
5
  const PARAMS = {
5
6
  tableId: "ta_12345679abcdef",
6
7
  version: "1",
@@ -1,3 +1,6 @@
1
+ import fetch from "node-fetch"
2
+ // @ts-ignore
3
+ fetch.mockSearch()
1
4
  import {
2
5
  generateMakeRequest,
3
6
  MakeRequestResponse,
@@ -16,6 +19,7 @@ import _ from "lodash"
16
19
  import { generator } from "@budibase/backend-core/tests"
17
20
  import { utils } from "@budibase/backend-core"
18
21
  import { GenericContainer } from "testcontainers"
22
+ import { generateRowIdField } from "../integrations/utils"
19
23
 
20
24
  const config = setup.getConfig()!
21
25
 
@@ -80,16 +84,10 @@ describe("row api - postgres", () => {
80
84
  name: "id",
81
85
  type: FieldType.AUTO,
82
86
  autocolumn: true,
83
- constraints: {
84
- presence: true,
85
- },
86
87
  },
87
88
  title: {
88
89
  name: "title",
89
90
  type: FieldType.STRING,
90
- constraints: {
91
- presence: true,
92
- },
93
91
  },
94
92
  },
95
93
  sourceId: postgresDatasource._id,
@@ -121,16 +119,10 @@ describe("row api - postgres", () => {
121
119
  name: "id",
122
120
  type: FieldType.AUTO,
123
121
  autocolumn: true,
124
- constraints: {
125
- presence: true,
126
- },
127
122
  },
128
123
  name: {
129
124
  name: "name",
130
125
  type: FieldType.STRING,
131
- constraints: {
132
- presence: true,
133
- },
134
126
  },
135
127
  description: {
136
128
  name: "description",
@@ -144,7 +136,6 @@ describe("row api - postgres", () => {
144
136
  type: FieldType.LINK,
145
137
  constraints: {
146
138
  type: "array",
147
- presence: false,
148
139
  },
149
140
  fieldName: oneToManyRelationshipInfo.fieldName,
150
141
  name: "oneToManyRelation",
@@ -156,7 +147,6 @@ describe("row api - postgres", () => {
156
147
  type: FieldType.LINK,
157
148
  constraints: {
158
149
  type: "array",
159
- presence: false,
160
150
  },
161
151
  fieldName: manyToOneRelationshipInfo.fieldName,
162
152
  name: "manyToOneRelation",
@@ -168,7 +158,6 @@ describe("row api - postgres", () => {
168
158
  type: FieldType.LINK,
169
159
  constraints: {
170
160
  type: "array",
171
- presence: false,
172
161
  },
173
162
  fieldName: manyToManyRelationshipInfo.fieldName,
174
163
  name: "manyToManyRelation",
@@ -309,9 +298,6 @@ describe("row api - postgres", () => {
309
298
  id: {
310
299
  name: "id",
311
300
  type: FieldType.AUTO,
312
- constraints: {
313
- presence: true,
314
- },
315
301
  },
316
302
  },
317
303
  sourceId: postgresDatasource._id,
@@ -921,47 +907,55 @@ describe("row api - postgres", () => {
921
907
  foreignRows,
922
908
  x => x.relationshipType
923
909
  )
924
- expect(res.body).toEqual({
925
- ...rowData,
926
- [`fk_${oneToManyRelationshipInfo.table.name}_${oneToManyRelationshipInfo.fieldName}`]:
927
- foreignRowsByType[RelationshipTypes.ONE_TO_MANY][0].row.id,
928
- [oneToManyRelationshipInfo.fieldName]: [
929
- {
930
- ...foreignRowsByType[RelationshipTypes.ONE_TO_MANY][0].row,
931
- _id: expect.any(String),
932
- _rev: expect.any(String),
933
- },
934
- ],
935
- [manyToOneRelationshipInfo.fieldName]: [
936
- {
937
- ...foreignRowsByType[RelationshipTypes.MANY_TO_ONE][0].row,
938
- [`fk_${manyToOneRelationshipInfo.table.name}_${manyToOneRelationshipInfo.fieldName}`]:
939
- row.id,
940
- },
941
- {
942
- ...foreignRowsByType[RelationshipTypes.MANY_TO_ONE][1].row,
943
- [`fk_${manyToOneRelationshipInfo.table.name}_${manyToOneRelationshipInfo.fieldName}`]:
944
- row.id,
945
- },
910
+ const m2mFieldName = manyToManyRelationshipInfo.fieldName,
911
+ o2mFieldName = oneToManyRelationshipInfo.fieldName,
912
+ m2oFieldName = manyToOneRelationshipInfo.fieldName
913
+ const m2mRow1 = res.body[m2mFieldName].find(
914
+ (row: Row) => row.id === 1
915
+ )
916
+ const m2mRow2 = res.body[m2mFieldName].find(
917
+ (row: Row) => row.id === 2
918
+ )
919
+ expect(m2mRow1).toEqual({
920
+ ...foreignRowsByType[RelationshipTypes.MANY_TO_MANY][0].row,
921
+ [m2mFieldName]: [
946
922
  {
947
- ...foreignRowsByType[RelationshipTypes.MANY_TO_ONE][2].row,
948
- [`fk_${manyToOneRelationshipInfo.table.name}_${manyToOneRelationshipInfo.fieldName}`]:
949
- row.id,
923
+ _id: row._id,
950
924
  },
951
925
  ],
952
- [manyToManyRelationshipInfo.fieldName]: [
953
- {
954
- ...foreignRowsByType[RelationshipTypes.MANY_TO_MANY][0].row,
955
- },
926
+ })
927
+ expect(m2mRow2).toEqual({
928
+ ...foreignRowsByType[RelationshipTypes.MANY_TO_MANY][1].row,
929
+ [m2mFieldName]: [
956
930
  {
957
- ...foreignRowsByType[RelationshipTypes.MANY_TO_MANY][1].row,
931
+ _id: row._id,
958
932
  },
959
933
  ],
960
- id: row.id,
961
- tableId: row.tableId,
962
- _id: expect.any(String),
963
- _rev: expect.any(String),
964
934
  })
935
+ expect(res.body[m2oFieldName]).toEqual([
936
+ {
937
+ ...foreignRowsByType[RelationshipTypes.MANY_TO_ONE][0].row,
938
+ [`fk_${manyToOneRelationshipInfo.table.name}_${manyToOneRelationshipInfo.fieldName}`]:
939
+ row.id,
940
+ },
941
+ {
942
+ ...foreignRowsByType[RelationshipTypes.MANY_TO_ONE][1].row,
943
+ [`fk_${manyToOneRelationshipInfo.table.name}_${manyToOneRelationshipInfo.fieldName}`]:
944
+ row.id,
945
+ },
946
+ {
947
+ ...foreignRowsByType[RelationshipTypes.MANY_TO_ONE][2].row,
948
+ [`fk_${manyToOneRelationshipInfo.table.name}_${manyToOneRelationshipInfo.fieldName}`]:
949
+ row.id,
950
+ },
951
+ ])
952
+ expect(res.body[o2mFieldName]).toEqual([
953
+ {
954
+ ...foreignRowsByType[RelationshipTypes.ONE_TO_MANY][0].row,
955
+ _id: expect.any(String),
956
+ _rev: expect.any(String),
957
+ },
958
+ ])
965
959
  })
966
960
  })
967
961
  })
@@ -99,8 +99,8 @@ describe("Google Sheets Integration", () => {
99
99
  })
100
100
  })
101
101
 
102
- test("removing an existing field will not remove the data from the spreadsheet", async () => {
103
- await config.doInContext(structures.uuid(), async () => {
102
+ test("removing an existing field will remove the header from the google sheet", async () => {
103
+ const sheet = await config.doInContext(structures.uuid(), async () => {
104
104
  const tableColumns = ["name"]
105
105
  const table = createBasicTable(structures.uuid(), tableColumns)
106
106
 
@@ -109,18 +109,14 @@ describe("Google Sheets Integration", () => {
109
109
  })
110
110
  sheetsByTitle[table.name] = sheet
111
111
  await integration.updateTable(table)
112
-
113
- expect(sheet.loadHeaderRow).toBeCalledTimes(1)
114
- expect(sheet.setHeaderRow).toBeCalledTimes(1)
115
- expect(sheet.setHeaderRow).toBeCalledWith([
116
- "name",
117
- "description",
118
- "location",
119
- ])
120
-
121
- // No undefineds are sent
122
- expect((sheet.setHeaderRow as any).mock.calls[0][0]).toHaveLength(3)
112
+ return sheet
123
113
  })
114
+ expect(sheet.loadHeaderRow).toBeCalledTimes(1)
115
+ expect(sheet.setHeaderRow).toBeCalledTimes(1)
116
+ expect(sheet.setHeaderRow).toBeCalledWith(["name"])
117
+
118
+ // No undefined are sent
119
+ expect((sheet.setHeaderRow as any).mock.calls[0][0]).toHaveLength(1)
124
120
  })
125
121
  })
126
122
  })
@@ -9,3 +9,4 @@ process.env.LOG_LEVEL = process.env.LOG_LEVEL || "error"
9
9
  process.env.ENABLE_4XX_HTTP_LOGGING = "0"
10
10
  process.env.MOCK_REDIS = "1"
11
11
  process.env.PLATFORM_URL = "http://localhost:10000"
12
+ process.env.REDIS_PASSWORD = "budibase"
@@ -46,6 +46,7 @@ import {
46
46
  Row,
47
47
  SourceName,
48
48
  Table,
49
+ SearchFilters,
49
50
  } from "@budibase/types"
50
51
 
51
52
  type DefaultUserValues = {
@@ -568,6 +569,16 @@ class TestConfiguration {
568
569
  return this._req(null, { tableId }, controllers.row.fetch)
569
570
  }
570
571
 
572
+ async searchRows(tableId: string, searchParams: SearchFilters = {}) {
573
+ if (!tableId && this.table) {
574
+ tableId = this.table._id
575
+ }
576
+ const body = {
577
+ query: searchParams,
578
+ }
579
+ return this._req(body, { tableId }, controllers.row.search)
580
+ }
581
+
571
582
  // ROLE
572
583
 
573
584
  async createRole(config?: any) {
@@ -24,10 +24,6 @@ export const init = () => {
24
24
  }
25
25
  }
26
26
  }
27
- const clientLibPath = join(budibaseTempDir(), "budibase-client.js")
28
- if (env.isTest() && !fs.existsSync(clientLibPath)) {
29
- fs.copyFileSync(require.resolve("@budibase/client"), clientLibPath)
30
- }
31
27
  }
32
28
 
33
29
  /**