@budibase/server 1.0.199 → 1.0.200-alpha.2

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.
Files changed (281) hide show
  1. package/Dockerfile +2 -0
  2. package/builder/assets/index.359da19e.js +1315 -0
  3. package/builder/index.html +1 -1
  4. package/coverage/clover.xml +2089 -2001
  5. package/coverage/coverage-final.json +121 -122
  6. package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
  7. package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
  8. package/coverage/lcov-report/api/controllers/automation.js.html +174 -72
  9. package/coverage/lcov-report/api/controllers/backup.js.html +30 -6
  10. package/coverage/lcov-report/api/controllers/cloud.js.html +11 -11
  11. package/coverage/lcov-report/api/controllers/component.js.html +5 -5
  12. package/coverage/lcov-report/api/controllers/datasource.js.html +53 -41
  13. package/coverage/lcov-report/api/controllers/dev.js.html +94 -70
  14. package/coverage/lcov-report/api/controllers/index.html +57 -72
  15. package/coverage/lcov-report/api/controllers/integration.js.html +8 -8
  16. package/coverage/lcov-report/api/controllers/layout.js.html +28 -19
  17. package/coverage/lcov-report/api/controllers/metadata.js.html +9 -9
  18. package/coverage/lcov-report/api/controllers/migrations.js.html +4 -4
  19. package/coverage/lcov-report/api/controllers/permission.js.html +15 -15
  20. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  21. package/coverage/lcov-report/api/controllers/query/validation.js.html +10 -10
  22. package/coverage/lcov-report/api/controllers/role.js.html +78 -48
  23. package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
  24. package/coverage/lcov-report/api/controllers/row/external.js.html +19 -19
  25. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/internal.js.html +54 -54
  27. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +9 -9
  28. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +24 -24
  29. package/coverage/lcov-report/api/controllers/row/utils.js.html +24 -24
  30. package/coverage/lcov-report/api/controllers/screen.js.html +56 -20
  31. package/coverage/lcov-report/api/controllers/script.js.html +4 -4
  32. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +49 -49
  33. package/coverage/lcov-report/api/controllers/table/external.js.html +23 -17
  34. package/coverage/lcov-report/api/controllers/table/index.html +26 -26
  35. package/coverage/lcov-report/api/controllers/table/index.js.html +85 -49
  36. package/coverage/lcov-report/api/controllers/templates.js.html +6 -6
  37. package/coverage/lcov-report/api/controllers/user.js.html +19 -19
  38. package/coverage/lcov-report/api/controllers/view/exporters.js.html +11 -11
  39. package/coverage/lcov-report/api/controllers/view/index.html +21 -21
  40. package/coverage/lcov-report/api/controllers/view/index.js.html +275 -65
  41. package/coverage/lcov-report/api/controllers/view/utils.js.html +23 -23
  42. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +40 -40
  43. package/coverage/lcov-report/api/controllers/webhook.js.html +17 -17
  44. package/coverage/lcov-report/api/index.html +15 -15
  45. package/coverage/lcov-report/api/index.js.html +39 -45
  46. package/coverage/lcov-report/api/routes/analytics.js.html +7 -13
  47. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
  48. package/coverage/lcov-report/api/routes/auth.js.html +6 -6
  49. package/coverage/lcov-report/api/routes/automation.js.html +11 -11
  50. package/coverage/lcov-report/api/routes/backup.js.html +8 -8
  51. package/coverage/lcov-report/api/routes/cloud.js.html +8 -8
  52. package/coverage/lcov-report/api/routes/component.js.html +8 -8
  53. package/coverage/lcov-report/api/routes/datasource.js.html +9 -9
  54. package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
  55. package/coverage/lcov-report/api/routes/dev.js.html +13 -13
  56. package/coverage/lcov-report/api/routes/index.html +1 -1
  57. package/coverage/lcov-report/api/routes/integration.js.html +8 -8
  58. package/coverage/lcov-report/api/routes/layout.js.html +8 -8
  59. package/coverage/lcov-report/api/routes/metadata.js.html +9 -9
  60. package/coverage/lcov-report/api/routes/migrations.js.html +7 -7
  61. package/coverage/lcov-report/api/routes/permission.js.html +9 -9
  62. package/coverage/lcov-report/api/routes/query.js.html +10 -10
  63. package/coverage/lcov-report/api/routes/role.js.html +9 -9
  64. package/coverage/lcov-report/api/routes/routing.js.html +8 -8
  65. package/coverage/lcov-report/api/routes/screen.js.html +9 -9
  66. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/table.js.html +10 -10
  68. package/coverage/lcov-report/api/routes/templates.js.html +8 -8
  69. package/coverage/lcov-report/api/routes/user.js.html +8 -8
  70. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  71. package/coverage/lcov-report/api/routes/utils/validators.js.html +36 -36
  72. package/coverage/lcov-report/api/routes/view.js.html +10 -10
  73. package/coverage/lcov-report/api/routes/webhook.js.html +9 -9
  74. package/coverage/lcov-report/automations/actions.js.html +25 -25
  75. package/coverage/lcov-report/automations/automationUtils.js.html +8 -8
  76. package/coverage/lcov-report/automations/bullboard.js.html +35 -35
  77. package/coverage/lcov-report/automations/index.html +29 -29
  78. package/coverage/lcov-report/automations/index.js.html +29 -17
  79. package/coverage/lcov-report/automations/steps/bash.js.html +7 -7
  80. package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
  81. package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
  82. package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
  83. package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
  84. package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
  85. package/coverage/lcov-report/automations/steps/index.html +1 -1
  86. package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
  87. package/coverage/lcov-report/automations/steps/loop.js.html +2 -2
  88. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
  89. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
  90. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
  91. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
  92. package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
  93. package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
  94. package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
  95. package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
  96. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  97. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  98. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  100. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  101. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  102. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  103. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  104. package/coverage/lcov-report/automations/triggers.js.html +18 -18
  105. package/coverage/lcov-report/constants/index.html +1 -1
  106. package/coverage/lcov-report/constants/index.js.html +30 -30
  107. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  108. package/coverage/lcov-report/constants/screens.js.html +4 -4
  109. package/coverage/lcov-report/db/inMemoryView.js.html +5 -5
  110. package/coverage/lcov-report/db/index.html +1 -1
  111. package/coverage/lcov-report/db/index.js.html +9 -9
  112. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +17 -17
  113. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  114. package/coverage/lcov-report/db/linkedRows/index.js.html +36 -36
  115. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +19 -19
  116. package/coverage/lcov-report/db/newid.js.html +4 -4
  117. package/coverage/lcov-report/db/utils.js.html +81 -81
  118. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  119. package/coverage/lcov-report/events/index.html +1 -1
  120. package/coverage/lcov-report/events/index.js.html +7 -7
  121. package/coverage/lcov-report/events/utils.js.html +10 -10
  122. package/coverage/lcov-report/index.html +74 -74
  123. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  124. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  125. package/coverage/lcov-report/middleware/appInfo.js.html +5 -5
  126. package/coverage/lcov-report/middleware/builder.js.html +20 -20
  127. package/coverage/lcov-report/middleware/currentapp.js.html +49 -49
  128. package/coverage/lcov-report/middleware/index.html +1 -1
  129. package/coverage/lcov-report/middleware/joi-validator.js.html +14 -14
  130. package/coverage/lcov-report/middleware/publicApi.js.html +5 -5
  131. package/coverage/lcov-report/middleware/resourceId.js.html +29 -29
  132. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  133. package/coverage/lcov-report/middleware/utils.js.html +4 -4
  134. package/coverage/lcov-report/threads/automation.js.html +1 -1
  135. package/coverage/lcov-report/threads/index.html +1 -1
  136. package/coverage/lcov-report/threads/query.js.html +1 -1
  137. package/coverage/lcov-report/threads/utils.js.html +13 -13
  138. package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -3
  139. package/coverage/lcov-report/utilities/centralPath.js.html +14 -14
  140. package/coverage/lcov-report/utilities/csvParser.js.html +34 -34
  141. package/coverage/lcov-report/utilities/global.js.html +28 -28
  142. package/coverage/lcov-report/utilities/index.html +25 -25
  143. package/coverage/lcov-report/utilities/index.js.html +41 -41
  144. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +18 -18
  145. package/coverage/lcov-report/utilities/queue/index.html +15 -15
  146. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  147. package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
  148. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  149. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +59 -59
  150. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +15 -15
  151. package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
  152. package/coverage/lcov-report/utilities/security.js.html +8 -8
  153. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  154. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  155. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +30 -30
  156. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  157. package/coverage/lcov-report/utilities/users.js.html +7 -7
  158. package/coverage/lcov-report/utilities/workerRequests.js.html +29 -29
  159. package/coverage/lcov.info +2903 -2762
  160. package/dist/api/controllers/analytics.js +7 -30
  161. package/dist/api/controllers/application.js +56 -16
  162. package/dist/api/controllers/automation.js +31 -2
  163. package/dist/api/controllers/backup.js +7 -0
  164. package/dist/api/controllers/datasource.js +8 -2
  165. package/dist/api/controllers/deploy/index.js +6 -2
  166. package/dist/api/controllers/dev.js +9 -2
  167. package/dist/api/controllers/layout.js +3 -0
  168. package/dist/api/controllers/query/import/index.js +12 -2
  169. package/dist/api/controllers/query/import/sources/curl.js +3 -0
  170. package/dist/api/controllers/query/import/sources/openapi2.js +3 -0
  171. package/dist/api/controllers/query/import/sources/openapi3.js +3 -0
  172. package/dist/api/controllers/query/index.js +16 -2
  173. package/dist/api/controllers/role.js +11 -0
  174. package/dist/api/controllers/screen.js +10 -1
  175. package/dist/api/controllers/static/index.js +29 -15
  176. package/dist/api/controllers/table/external.js +2 -0
  177. package/dist/api/controllers/table/index.js +12 -0
  178. package/dist/api/controllers/table/utils.js +3 -3
  179. package/dist/api/controllers/view/index.js +62 -6
  180. package/dist/api/index.js +2 -4
  181. package/dist/api/routes/analytics.js +1 -3
  182. package/dist/app.js +16 -8
  183. package/dist/automations/index.js +4 -0
  184. package/dist/environment.js +4 -2
  185. package/dist/migrations/functions/backfill/app/automations.js +31 -0
  186. package/dist/migrations/functions/backfill/app/datasources.js +28 -0
  187. package/dist/migrations/functions/backfill/app/layouts.js +33 -0
  188. package/dist/migrations/functions/backfill/app/queries.js +32 -0
  189. package/dist/migrations/functions/backfill/app/roles.js +28 -0
  190. package/dist/migrations/functions/backfill/app/screens.js +28 -0
  191. package/dist/migrations/functions/backfill/app/tables.js +40 -0
  192. package/dist/migrations/functions/backfill/app.js +175 -0
  193. package/dist/migrations/functions/backfill/global/configs.js +61 -0
  194. package/dist/migrations/functions/backfill/global/quotas.js +60 -0
  195. package/dist/migrations/functions/backfill/global/users.js +50 -0
  196. package/dist/migrations/functions/backfill/global.js +189 -0
  197. package/dist/migrations/functions/backfill/index.js +32 -0
  198. package/dist/migrations/functions/backfill/installation.js +81 -0
  199. package/dist/migrations/index.js +95 -31
  200. package/dist/migrations/tests/helpers.js +72 -0
  201. package/dist/migrations/tests/structures.js +37 -0
  202. package/dist/package.json +79 -69
  203. package/dist/tests/utilities/TestConfiguration.js +121 -93
  204. package/dist/tests/utilities/structures.js +45 -0
  205. package/dist/tsconfig.build.tsbuildinfo +1 -1
  206. package/nodemon.json +1 -1
  207. package/package.json +80 -70
  208. package/scripts/dev/manage.js +2 -0
  209. package/scripts/jestSetup.js +7 -0
  210. package/scripts/likeCypress.ts +1 -1
  211. package/src/api/controllers/analytics.ts +8 -0
  212. package/src/api/controllers/application.ts +60 -18
  213. package/src/api/controllers/automation.js +36 -2
  214. package/src/api/controllers/backup.js +8 -0
  215. package/src/api/controllers/datasource.js +8 -4
  216. package/src/api/controllers/deploy/index.ts +6 -2
  217. package/src/api/controllers/dev.js +10 -2
  218. package/src/api/controllers/layout.js +3 -0
  219. package/src/api/controllers/query/import/index.ts +16 -3
  220. package/src/api/controllers/query/import/sources/base/index.ts +2 -1
  221. package/src/api/controllers/query/import/sources/curl.ts +4 -0
  222. package/src/api/controllers/query/import/sources/openapi2.ts +4 -0
  223. package/src/api/controllers/query/import/sources/openapi3.ts +4 -0
  224. package/src/api/controllers/query/import/tests/index.spec.js +20 -7
  225. package/src/api/controllers/query/index.ts +16 -3
  226. package/src/api/controllers/role.js +10 -0
  227. package/src/api/controllers/screen.js +13 -1
  228. package/src/api/controllers/static/index.js +28 -15
  229. package/src/api/controllers/table/external.js +2 -0
  230. package/src/api/controllers/table/index.js +12 -0
  231. package/src/api/controllers/table/utils.ts +4 -4
  232. package/src/api/controllers/view/index.js +76 -6
  233. package/src/api/index.js +2 -4
  234. package/src/api/routes/analytics.js +1 -3
  235. package/src/api/routes/public/utils/Endpoint.ts +1 -1
  236. package/src/api/routes/tests/__snapshots__/datasource.spec.js.snap +5 -1
  237. package/src/api/routes/tests/application.spec.js +64 -4
  238. package/src/api/routes/tests/automation.spec.js +168 -60
  239. package/src/api/routes/tests/backup.spec.js +2 -0
  240. package/src/api/routes/tests/data/export.txt +1 -0
  241. package/src/api/routes/tests/datasource.spec.js +5 -0
  242. package/src/api/routes/tests/deployment.spec.js +25 -0
  243. package/src/api/routes/tests/dev.spec.js +40 -0
  244. package/src/api/routes/tests/layout.spec.js +4 -0
  245. package/src/api/routes/tests/query.spec.js +56 -13
  246. package/src/api/routes/tests/role.spec.js +40 -7
  247. package/src/api/routes/tests/row.spec.js +2 -3
  248. package/src/api/routes/tests/screen.spec.js +30 -4
  249. package/src/api/routes/tests/static.spec.js +120 -54
  250. package/src/api/routes/tests/table.spec.js +102 -38
  251. package/src/api/routes/tests/view.spec.js +222 -43
  252. package/src/app.ts +18 -9
  253. package/src/automations/index.js +4 -0
  254. package/src/automations/tests/delay.spec.js +4 -0
  255. package/src/environment.js +5 -2
  256. package/src/migrations/functions/backfill/app/automations.ts +26 -0
  257. package/src/migrations/functions/backfill/app/datasources.ts +22 -0
  258. package/src/migrations/functions/backfill/app/layouts.ts +29 -0
  259. package/src/migrations/functions/backfill/app/queries.ts +33 -0
  260. package/src/migrations/functions/backfill/app/roles.ts +22 -0
  261. package/src/migrations/functions/backfill/app/screens.ts +22 -0
  262. package/src/migrations/functions/backfill/app/tables.ts +36 -0
  263. package/src/migrations/functions/backfill/app.ts +148 -0
  264. package/src/migrations/functions/backfill/global/configs.ts +66 -0
  265. package/src/migrations/functions/backfill/global/quotas.ts +60 -0
  266. package/src/migrations/functions/backfill/global/users.ts +49 -0
  267. package/src/migrations/functions/backfill/global.ts +194 -0
  268. package/src/migrations/functions/backfill/index.ts +7 -0
  269. package/src/migrations/functions/backfill/installation.ts +51 -0
  270. package/src/migrations/index.ts +120 -51
  271. package/src/migrations/tests/helpers.ts +40 -0
  272. package/src/migrations/tests/index.spec.ts +132 -0
  273. package/src/migrations/tests/structures.ts +66 -0
  274. package/src/module.d.ts +0 -1
  275. package/src/tests/utilities/TestConfiguration.js +138 -90
  276. package/src/tests/utilities/structures.js +71 -0
  277. package/tsconfig.build.json +20 -5
  278. package/tsconfig.json +22 -17
  279. package/builder/assets/index.107ba2e5.js +0 -1315
  280. package/coverage/lcov-report/api/controllers/analytics.js.html +0 -202
  281. package/src/api/controllers/analytics.js +0 -39
@@ -13,6 +13,7 @@ const setup = require("./utilities")
13
13
  const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
14
14
  const { checkCacheForDynamicVariable } = require("../../../threads/utils")
15
15
  const { basicQuery, basicDatasource } = setup.structures
16
+ const { events } = require("@budibase/backend-core")
16
17
 
17
18
  describe("/queries", () => {
18
19
  let request = setup.getRequest()
@@ -38,16 +39,46 @@ describe("/queries", () => {
38
39
  return { datasource, query }
39
40
  }
40
41
 
42
+ const createQuery = async (query) => {
43
+ return request
44
+ .post(`/api/queries`)
45
+ .send(query)
46
+ .set(config.defaultHeaders())
47
+ .expect("Content-Type", /json/)
48
+ .expect(200)
49
+ }
50
+
41
51
  describe("create", () => {
42
52
  it("should create a new query", async () => {
43
53
  const { _id } = await config.createDatasource()
44
54
  const query = basicQuery(_id)
45
- const res = await request
46
- .post(`/api/queries`)
47
- .send(query)
48
- .set(config.defaultHeaders())
49
- .expect("Content-Type", /json/)
50
- .expect(200)
55
+ jest.clearAllMocks()
56
+ const res = await createQuery(query)
57
+
58
+ expect(res.res.statusMessage).toEqual(
59
+ `Query ${query.name} saved successfully.`
60
+ )
61
+ expect(res.body).toEqual({
62
+ _rev: res.body._rev,
63
+ _id: res.body._id,
64
+ ...query,
65
+ createdAt: new Date().toISOString(),
66
+ updatedAt: new Date().toISOString()
67
+ })
68
+ expect(events.query.created).toBeCalledTimes(1)
69
+ expect(events.query.updated).not.toBeCalled()
70
+ })
71
+ })
72
+
73
+ describe("update", () => {
74
+ it("should update query", async () => {
75
+ const { _id } = await config.createDatasource()
76
+ const query = basicQuery(_id)
77
+ const res = await createQuery(query)
78
+ jest.clearAllMocks()
79
+ query._id = res.body._id
80
+ query._rev = res.body._rev
81
+ await createQuery(query)
51
82
 
52
83
  expect(res.res.statusMessage).toEqual(
53
84
  `Query ${query.name} saved successfully.`
@@ -56,7 +87,11 @@ describe("/queries", () => {
56
87
  _rev: res.body._rev,
57
88
  _id: res.body._id,
58
89
  ...query,
90
+ createdAt: new Date().toISOString(),
91
+ updatedAt: new Date().toISOString()
59
92
  })
93
+ expect(events.query.created).not.toBeCalled()
94
+ expect(events.query.updated).toBeCalledTimes(1)
60
95
  })
61
96
  })
62
97
 
@@ -73,7 +108,9 @@ describe("/queries", () => {
73
108
  {
74
109
  _rev: query._rev,
75
110
  _id: query._id,
111
+ createdAt: new Date().toISOString(),
76
112
  ...basicQuery(datasource._id),
113
+ updatedAt: new Date().toISOString(),
77
114
  readable: true,
78
115
  },
79
116
  ])
@@ -149,6 +186,8 @@ describe("/queries", () => {
149
186
  .expect(200)
150
187
 
151
188
  expect(res.body).toEqual([])
189
+ expect(events.query.deleted).toBeCalledTimes(1)
190
+ expect(events.query.deleted).toBeCalledWith(datasource, query)
152
191
  })
153
192
 
154
193
  it("should apply authorization to endpoint", async () => {
@@ -162,21 +201,25 @@ describe("/queries", () => {
162
201
 
163
202
  describe("preview", () => {
164
203
  it("should be able to preview the query", async () => {
204
+ const query = {
205
+ datasourceId: datasource._id,
206
+ parameters: {},
207
+ fields: {},
208
+ queryVerb: "read",
209
+ name: datasource.name,
210
+ }
165
211
  const res = await request
166
212
  .post(`/api/queries/preview`)
167
- .send({
168
- datasourceId: datasource._id,
169
- parameters: {},
170
- fields: {},
171
- queryVerb: "read",
172
- name: datasource.name,
173
- })
213
+ .send(query)
174
214
  .set(config.defaultHeaders())
175
215
  .expect("Content-Type", /json/)
176
216
  .expect(200)
177
217
  // these responses come from the mock
178
218
  expect(res.body.schemaFields).toEqual(["a", "b"])
179
219
  expect(res.body.rows.length).toEqual(1)
220
+ expect(events.query.previewed).toBeCalledTimes(1)
221
+ datasource.config = { schema: "public" }
222
+ expect(events.query.previewed).toBeCalledWith(datasource, query)
180
223
  })
181
224
 
182
225
  it("should apply authorization to endpoint", async () => {
@@ -4,6 +4,7 @@ const {
4
4
  } = require("@budibase/backend-core/permissions")
5
5
  const setup = require("./utilities")
6
6
  const { basicRole } = setup.structures
7
+ const { events } = require("@budibase/backend-core")
7
8
 
8
9
  describe("/roles", () => {
9
10
  let request = setup.getRequest()
@@ -15,20 +16,48 @@ describe("/roles", () => {
15
16
  await config.init()
16
17
  })
17
18
 
19
+ const createRole = async (role) => {
20
+ if (!role) {
21
+ role = basicRole()
22
+ }
23
+
24
+ return request
25
+ .post(`/api/roles`)
26
+ .send(role)
27
+ .set(config.defaultHeaders())
28
+ .expect("Content-Type", /json/)
29
+ .expect(200)
30
+ }
31
+
18
32
  describe("create", () => {
19
33
  it("returns a success message when role is successfully created", async () => {
20
- const res = await request
21
- .post(`/api/roles`)
22
- .send(basicRole())
23
- .set(config.defaultHeaders())
24
- .expect("Content-Type", /json/)
25
- .expect(200)
34
+ const res = await createRole()
35
+
36
+ expect(res.res.statusMessage).toEqual(
37
+ "Role 'NewRole' created successfully."
38
+ )
39
+ expect(res.body._id).toBeDefined()
40
+ expect(res.body._rev).toBeDefined()
41
+ expect(events.role.updated).not.toBeCalled()
42
+ expect(events.role.created).toBeCalledTimes(1)
43
+ expect(events.role.created).toBeCalledWith(res.body)
44
+ })
45
+ })
46
+
47
+ describe("update", () => {
48
+ it("updates a role", async () => {
49
+ let res = await createRole()
50
+ jest.clearAllMocks()
51
+ res = await createRole(res.body)
26
52
 
27
53
  expect(res.res.statusMessage).toEqual(
28
54
  "Role 'NewRole' created successfully."
29
55
  )
30
56
  expect(res.body._id).toBeDefined()
31
57
  expect(res.body._rev).toBeDefined()
58
+ expect(events.role.created).not.toBeCalled()
59
+ expect(events.role.updated).toBeCalledTimes(1)
60
+ expect(events.role.updated).toBeCalledWith(res.body)
32
61
  })
33
62
  })
34
63
 
@@ -80,8 +109,10 @@ describe("/roles", () => {
80
109
  it("should delete custom roles", async () => {
81
110
  const customRole = await config.createRole({
82
111
  name: "user",
83
- permissionId: BUILTIN_PERMISSION_IDS.READ_ONLY
112
+ permissionId: BUILTIN_PERMISSION_IDS.READ_ONLY,
113
+ inherits: BUILTIN_ROLE_IDS.BASIC,
84
114
  })
115
+ delete customRole._rev_tree
85
116
  await request
86
117
  .delete(`/api/roles/${customRole._id}/${customRole._rev}`)
87
118
  .set(config.defaultHeaders())
@@ -90,6 +121,8 @@ describe("/roles", () => {
90
121
  .get(`/api/roles/${customRole._id}`)
91
122
  .set(config.defaultHeaders())
92
123
  .expect(404)
124
+ expect(events.role.deleted).toBeCalledTimes(1)
125
+ expect(events.role.deleted).toBeCalledWith(customRole)
93
126
  })
94
127
  })
95
128
  })
@@ -5,9 +5,6 @@ const { doInAppContext } = require("@budibase/backend-core/context")
5
5
  const { doInTenant } = require("@budibase/backend-core/tenancy")
6
6
  const { quotas, QuotaUsageType, StaticQuotaName, MonthlyQuotaName } = require("@budibase/pro")
7
7
 
8
- // mock the fetch for the search system
9
- jest.mock("node-fetch")
10
-
11
8
  describe("/rows", () => {
12
9
  let request = setup.getRequest()
13
10
  let config = setup.getConfig()
@@ -103,6 +100,8 @@ describe("/rows", () => {
103
100
  _id: existing._id,
104
101
  _rev: existing._rev,
105
102
  type: "row",
103
+ createdAt: "2020-01-01T00:00:00.000Z",
104
+ updatedAt: "2020-01-01T00:00:00.000Z",
106
105
  })
107
106
  await assertQueryUsage(queryUsage + 1)
108
107
  })
@@ -1,6 +1,7 @@
1
1
  const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
2
2
  const setup = require("./utilities")
3
3
  const { basicScreen } = setup.structures
4
+ const { events } = require("@budibase/backend-core")
4
5
 
5
6
  describe("/screens", () => {
6
7
  let request = setup.getRequest()
@@ -35,16 +36,40 @@ describe("/screens", () => {
35
36
  })
36
37
 
37
38
  describe("save", () => {
38
- it("should be able to save a screen", async () => {
39
- const screenCfg = basicScreen()
39
+ const saveScreen = async (screen) => {
40
40
  const res = await request
41
41
  .post(`/api/screens`)
42
- .send(screenCfg)
42
+ .send(screen)
43
43
  .set(config.defaultHeaders())
44
44
  .expect("Content-Type", /json/)
45
45
  .expect(200)
46
+ return res
47
+ }
48
+
49
+ it("should be able to create a screen", async () => {
50
+ jest.clearAllMocks()
51
+
52
+ const screen = basicScreen()
53
+ const res = await saveScreen(screen)
54
+
55
+ expect(res.body._rev).toBeDefined()
56
+ expect(res.body.name).toEqual(screen.name)
57
+ expect(events.screen.created).toBeCalledTimes(1)
58
+ })
59
+
60
+ it("should be able to update a screen", async () => {
61
+ const screen = basicScreen()
62
+ let res = await saveScreen(screen)
63
+ screen._id = res.body._id
64
+ screen._rev = res.body._rev
65
+ screen.name = "edit"
66
+ jest.clearAllMocks()
67
+
68
+ res = await saveScreen(screen)
69
+
46
70
  expect(res.body._rev).toBeDefined()
47
- expect(res.body.name).toEqual(screenCfg.name)
71
+ expect(res.body.name).toEqual(screen.name)
72
+ expect(events.screen.created).not.toBeCalled()
48
73
  })
49
74
 
50
75
  it("should apply authorization to endpoint", async () => {
@@ -64,6 +89,7 @@ describe("/screens", () => {
64
89
  .expect("Content-Type", /json/)
65
90
  .expect(200)
66
91
  expect(res.body.message).toBeDefined()
92
+ expect(events.screen.deleted).toBeCalledTimes(1)
67
93
  })
68
94
 
69
95
  it("should apply authorization to endpoint", async () => {
@@ -14,8 +14,9 @@ jest.mock("aws-sdk", () => ({
14
14
  }))
15
15
 
16
16
  const setup = require("./utilities")
17
+ const { events, constants } = require("@budibase/backend-core")
17
18
 
18
- describe("/attachments", () => {
19
+ describe("/static", () => {
19
20
  let request = setup.getRequest()
20
21
  let config = setup.getConfig()
21
22
  let app
@@ -26,73 +27,138 @@ describe("/attachments", () => {
26
27
  app = await config.init()
27
28
  })
28
29
 
29
- describe("generateSignedUrls", () => {
30
- let datasource
31
-
32
- beforeEach(async () => {
33
- datasource = await config.createDatasource({
34
- datasource: {
35
- type: "datasource",
36
- name: "Test",
37
- source: "S3",
38
- config: {},
39
- },
40
- })
30
+ describe("/builder", () => {
31
+ it("should serve the builder", async () => {
32
+ const res = await request
33
+ .get("/builder/portal")
34
+ .set(config.defaultHeaders())
35
+ .expect("Content-Type", /text\/html/)
36
+ .expect(200)
37
+
38
+ expect(res.text).toContain("<title>Budibase</title>")
39
+ expect(events.serve.servedBuilder).toBeCalledTimes(1)
40
+ })
41
+ })
42
+
43
+ describe("/app", () => {
44
+
45
+ beforeEach(() => {
46
+ jest.clearAllMocks()
41
47
  })
42
48
 
43
- it("should be able to generate a signed upload URL", async () => {
44
- const bucket = "foo"
45
- const key = "bar"
49
+ it("should serve the app by id", async () => {
50
+ const headers = config.defaultHeaders()
51
+ delete headers[constants.Headers.APP_ID]
52
+
46
53
  const res = await request
47
- .post(`/api/attachments/${datasource._id}/url`)
48
- .send({ bucket, key })
49
- .set(config.defaultHeaders())
50
- .expect("Content-Type", /json/)
54
+ .get(`/${config.prodAppId}`)
55
+ .set(headers)
51
56
  .expect(200)
52
- expect(res.body.signedUrl).toEqual("my-url")
53
- expect(res.body.publicUrl).toEqual(
54
- `https://${bucket}.s3.eu-west-1.amazonaws.com/${key}`
55
- )
57
+
58
+ expect(res.body.appId).toBe(config.prodAppId)
59
+ expect(events.serve.servedApp).toBeCalledTimes(1)
60
+ expect(events.serve.servedApp).toBeCalledWith(res.body)
61
+ expect(events.serve.servedAppPreview).not.toBeCalled()
56
62
  })
57
63
 
58
- it("should handle an invalid datasource ID", async () => {
64
+ it("should serve the app by url", async () => {
65
+ const headers = config.defaultHeaders()
66
+ delete headers[constants.Headers.APP_ID]
67
+
59
68
  const res = await request
60
- .post(`/api/attachments/foo/url`)
61
- .send({
62
- bucket: "foo",
63
- key: "bar",
64
- })
65
- .set(config.defaultHeaders())
66
- .expect("Content-Type", /json/)
67
- .expect(400)
68
- expect(res.body.message).toEqual(
69
- "The specified datasource could not be found"
70
- )
69
+ .get(`/app${config.prodApp.url}`)
70
+ .set(headers)
71
+ .expect(200)
72
+
73
+ expect(res.body.appId).toBe(config.prodAppId)
74
+ expect(events.serve.servedApp).toBeCalledTimes(1)
75
+ expect(events.serve.servedApp).toBeCalledWith(res.body)
76
+ expect(events.serve.servedAppPreview).not.toBeCalled()
71
77
  })
72
78
 
73
- it("should require a bucket parameter", async () => {
79
+ it("should serve the app preview by id", async () => {
74
80
  const res = await request
75
- .post(`/api/attachments/${datasource._id}/url`)
76
- .send({
77
- bucket: undefined,
78
- key: "bar",
79
- })
81
+ .get(`/${config.appId}`)
80
82
  .set(config.defaultHeaders())
81
- .expect("Content-Type", /json/)
82
- .expect(400)
83
- expect(res.body.message).toEqual("bucket and key values are required")
83
+ .expect(200)
84
+
85
+ expect(res.body.appId).toBe(config.appId)
86
+ expect(events.serve.servedAppPreview).toBeCalledTimes(1)
87
+ expect(events.serve.servedAppPreview).toBeCalledWith(res.body)
88
+ expect(events.serve.servedApp).not.toBeCalled()
84
89
  })
90
+ })
85
91
 
86
- it("should require a key parameter", async () => {
87
- const res = await request
88
- .post(`/api/attachments/${datasource._id}/url`)
89
- .send({
90
- bucket: "foo",
92
+ describe("/attachments", () => {
93
+ describe("generateSignedUrls", () => {
94
+ let datasource
95
+
96
+ beforeEach(async () => {
97
+ datasource = await config.createDatasource({
98
+ datasource: {
99
+ type: "datasource",
100
+ name: "Test",
101
+ source: "S3",
102
+ config: {},
103
+ },
91
104
  })
92
- .set(config.defaultHeaders())
93
- .expect("Content-Type", /json/)
94
- .expect(400)
95
- expect(res.body.message).toEqual("bucket and key values are required")
105
+ })
106
+
107
+ it("should be able to generate a signed upload URL", async () => {
108
+ const bucket = "foo"
109
+ const key = "bar"
110
+ const res = await request
111
+ .post(`/api/attachments/${datasource._id}/url`)
112
+ .send({ bucket, key })
113
+ .set(config.defaultHeaders())
114
+ .expect("Content-Type", /json/)
115
+ .expect(200)
116
+ expect(res.body.signedUrl).toEqual("my-url")
117
+ expect(res.body.publicUrl).toEqual(
118
+ `https://${bucket}.s3.eu-west-1.amazonaws.com/${key}`
119
+ )
120
+ })
121
+
122
+ it("should handle an invalid datasource ID", async () => {
123
+ const res = await request
124
+ .post(`/api/attachments/foo/url`)
125
+ .send({
126
+ bucket: "foo",
127
+ key: "bar",
128
+ })
129
+ .set(config.defaultHeaders())
130
+ .expect("Content-Type", /json/)
131
+ .expect(400)
132
+ expect(res.body.message).toEqual(
133
+ "The specified datasource could not be found"
134
+ )
135
+ })
136
+
137
+ it("should require a bucket parameter", async () => {
138
+ const res = await request
139
+ .post(`/api/attachments/${datasource._id}/url`)
140
+ .send({
141
+ bucket: undefined,
142
+ key: "bar",
143
+ })
144
+ .set(config.defaultHeaders())
145
+ .expect("Content-Type", /json/)
146
+ .expect(400)
147
+ expect(res.body.message).toEqual("bucket and key values are required")
148
+ })
149
+
150
+ it("should require a key parameter", async () => {
151
+ const res = await request
152
+ .post(`/api/attachments/${datasource._id}/url`)
153
+ .send({
154
+ bucket: "foo",
155
+ })
156
+ .set(config.defaultHeaders())
157
+ .expect("Content-Type", /json/)
158
+ .expect(400)
159
+ expect(res.body.message).toEqual("bucket and key values are required")
160
+ })
96
161
  })
97
162
  })
163
+
98
164
  })
@@ -2,6 +2,7 @@ const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
2
2
  const { getAppDB } = require("@budibase/backend-core/context")
3
3
  const setup = require("./utilities")
4
4
  const { basicTable } = setup.structures
5
+ const { events } = require("@budibase/backend-core")
5
6
 
6
7
  describe("/tables", () => {
7
8
  let request = setup.getRequest()
@@ -14,24 +15,76 @@ describe("/tables", () => {
14
15
  })
15
16
 
16
17
  describe("create", () => {
17
- it("returns a success message when the table is successfully created", async () => {
18
- const res = await request
18
+
19
+ beforeEach(() => {
20
+ jest.clearAllMocks()
21
+ })
22
+
23
+ const createTable = (table) => {
24
+ if (!table) {
25
+ table = basicTable()
26
+ }
27
+ return request
19
28
  .post(`/api/tables`)
20
- .send({
21
- name: "TestTable",
22
- key: "name",
23
- schema: {
24
- name: {type: "string"}
25
- }
26
- })
29
+ .send(table)
27
30
  .set(config.defaultHeaders())
28
31
  .expect('Content-Type', /json/)
29
32
  .expect(200)
33
+
34
+ }
35
+
36
+ it("returns a success message when the table is successfully created", async () => {
37
+ const res = await createTable()
38
+
30
39
  expect(res.res.statusMessage).toEqual("Table TestTable saved successfully.")
31
40
  expect(res.body.name).toEqual("TestTable")
41
+ expect(events.table.created).toBeCalledTimes(1)
42
+ expect(events.table.created).toBeCalledWith(res.body)
32
43
  })
33
44
 
34
- it("renames all the row fields for a table when a schema key is renamed", async () => {
45
+ it("creates a table via data import CSV", async () => {
46
+ const table = basicTable()
47
+ table.dataImport = {
48
+ csvString: "\"name\",\"description\"\n\"test-name\",\"test-desc\"",
49
+ }
50
+ table.dataImport.schema = table.schema
51
+
52
+ const res = await createTable(table)
53
+
54
+ expect(events.table.created).toBeCalledTimes(1)
55
+ expect(events.table.created).toBeCalledWith(res.body)
56
+ expect(events.table.imported).toBeCalledTimes(1)
57
+ expect(events.table.imported).toBeCalledWith(res.body, "csv")
58
+ expect(events.rows.imported).toBeCalledTimes(1)
59
+ expect(events.rows.imported).toBeCalledWith(res.body, "csv", 1)
60
+ })
61
+
62
+ it("should apply authorization to endpoint", async () => {
63
+ await checkBuilderEndpoint({
64
+ config,
65
+ method: "POST",
66
+ url: `/api/tables`,
67
+ body: basicTable()
68
+ })
69
+ })
70
+ })
71
+
72
+ describe("update", () => {
73
+ it("updates a table", async () => {
74
+ const testTable = await config.createTable()
75
+
76
+ const res = await request
77
+ .post(`/api/tables`)
78
+ .send(testTable)
79
+ .set(config.defaultHeaders())
80
+ .expect('Content-Type', /json/)
81
+ .expect(200)
82
+
83
+ expect(events.table.updated).toBeCalledTimes(1)
84
+ expect(events.table.updated).toBeCalledWith(res.body)
85
+ })
86
+
87
+ it("updates all the row fields for a table when a schema key is renamed", async () => {
35
88
  const testTable = await config.createTable()
36
89
 
37
90
  const testRow = await request
@@ -74,22 +127,47 @@ describe("/tables", () => {
74
127
  expect(res.body.name).toBeUndefined()
75
128
  })
76
129
 
77
- it("should apply authorization to endpoint", async () => {
78
- await checkBuilderEndpoint({
79
- config,
80
- method: "POST",
81
- url: `/api/tables`,
82
- body: {
83
- name: "TestTable",
84
- key: "name",
85
- schema: {
86
- name: {type: "string"}
87
- }
88
- }
130
+ describe("user table", () => {
131
+ it("should add roleId and email field when adjusting user table schema", async () => {
132
+ const res = await request
133
+ .post(`/api/tables`)
134
+ .send({
135
+ ...basicTable(),
136
+ _id: "ta_users",
137
+ })
138
+ .set(config.defaultHeaders())
139
+ .expect('Content-Type', /json/)
140
+ .expect(200)
141
+ expect(res.body.schema.email).toBeDefined()
142
+ expect(res.body.schema.roleId).toBeDefined()
89
143
  })
90
144
  })
91
145
  })
92
146
 
147
+ describe("import", () => {
148
+ it("imports rows successfully", async () => {
149
+ const table = await config.createTable()
150
+ const importRequest = {
151
+ dataImport: {
152
+ csvString: "\"name\",\"description\"\n\"test-name\",\"test-desc\"",
153
+ schema: table.schema
154
+ }
155
+ }
156
+ jest.clearAllMocks()
157
+
158
+ await request
159
+ .post(`/api/tables/${table._id}/import`)
160
+ .send(importRequest)
161
+ .set(config.defaultHeaders())
162
+ .expect('Content-Type', /json/)
163
+ .expect(200)
164
+
165
+ expect(events.table.created).not.toHaveBeenCalled()
166
+ expect(events.rows.imported).toBeCalledTimes(1)
167
+ expect(events.rows.imported).toBeCalledWith(table, "csv", 1)
168
+ })
169
+ })
170
+
93
171
  describe("fetch", () => {
94
172
  let testTable
95
173
 
@@ -153,22 +231,6 @@ describe("/tables", () => {
153
231
  })
154
232
  })
155
233
 
156
- describe("updating user table", () => {
157
- it("should add roleId and email field when adjusting user table schema", async () => {
158
- const res = await request
159
- .post(`/api/tables`)
160
- .send({
161
- ...basicTable(),
162
- _id: "ta_users",
163
- })
164
- .set(config.defaultHeaders())
165
- .expect('Content-Type', /json/)
166
- .expect(200)
167
- expect(res.body.schema.email).toBeDefined()
168
- expect(res.body.schema.roleId).toBeDefined()
169
- })
170
- })
171
-
172
234
  describe("validate csv", () => {
173
235
  it("should be able to validate a CSV layout", async () => {
174
236
  const res = await request
@@ -205,6 +267,8 @@ describe("/tables", () => {
205
267
  .expect('Content-Type', /json/)
206
268
  .expect(200)
207
269
  expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`)
270
+ expect(events.table.deleted).toBeCalledTimes(1)
271
+ expect(events.table.deleted).toBeCalledWith(testTable)
208
272
  })
209
273
 
210
274
  it("deletes linked references to the table after deletion", async () => {