builder / app / app preview served events

This commit is contained in:
Rory Powell 2022-04-08 14:07:11 +01:00
parent c316a27f26
commit d41037a859
8 changed files with 182 additions and 98 deletions

View File

@ -64,8 +64,10 @@ exports.Events = {
ROLE_ASSIGNED: "role:assigned",
ROLE_UNASSIGNED: "role:unassigned",
// APP / CLIENT
CLIENT_SERVED: "client:served",
// SERVE
SERVED_BUILDER: "served:builder",
SERVED_APP: "served:app",
SERVED_APP_PREVIEW: "served:app:preview",
// DATASOURCE
DATASOURCE_CREATED: "datasource:created",
@ -102,9 +104,6 @@ exports.Events = {
// ROW
// ROW_CREATED: "row:created",
// BUILDER
BUILDER_SERVED: "builder:served",
// COMPONENT
COMPONENT_CREATED: "component:created",
COMPONENT_DELETED: "component:deleted",

View File

@ -1,13 +1,11 @@
const events = require("../events")
const { Events } = require("../constants")
// TODO
exports.created = () => {
const properties = {}
events.processEvent(Events.SCREEN_CREATED, properties)
}
// TODO
exports.deleted = () => {
const properties = {}
events.processEvent(Events.SCREEN_DELETED, properties)

View File

@ -1,14 +1,19 @@
const events = require("../events")
const { Events } = require("../constants")
// TODO
exports.builderServed = () => {
/* eslint-disable */
exports.servedBuilder = version => {
const properties = {}
events.processEvent(Events.BUILDER_SERVED, properties)
events.processEvent(Events.SERVED_BUILDER, properties)
}
// TODO
exports.clientServed = () => {
exports.servedApp = appMetadata => {
const properties = {}
events.processEvent(Events.CLIENT_SERVED, properties)
events.processEvent(Events.SERVED_APP, properties)
}
exports.servedAppPreview = appMetadata => {
const properties = {}
events.processEvent(Events.SERVED_APP_PREVIEW, properties)
}

View File

@ -90,7 +90,11 @@ jest.mock("../../../events", () => {
passwordResetRequested: jest.fn(),
passwordReset: jest.fn(),
},
serve: {},
serve: {
servedBuilder: jest.fn(),
servedApp: jest.fn(),
servedAppPreview: jest.fn(),
},
table: {},
view: {},
}

View File

@ -15,10 +15,12 @@ const env = require("../../../environment")
const { clientLibraryPath } = require("../../../utilities")
const { upload } = require("../../../utilities/fileSystem")
const { attachmentsRelativeURL } = require("../../../utilities")
const { DocumentTypes } = require("../../../db/utils")
const { DocumentTypes, isDevAppID } = require("../../../db/utils")
const { getAppDB, updateAppId } = require("@budibase/backend-core/context")
const AWS = require("aws-sdk")
const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : "eu-west-1"
const { events } = require("@budibase/backend-core")
const version = require("../../../../package.json").version
async function prepareUpload({ s3Key, bucket, metadata, file }) {
const response = await upload({
@ -57,6 +59,7 @@ async function getAppIdFromUrl(ctx) {
exports.serveBuilder = async function (ctx) {
let builderPath = resolve(TOP_LEVEL_PATH, "builder")
await send(ctx, ctx.file, { root: builderPath })
events.serve.servedBuilder(version)
}
exports.uploadFile = async function (ctx) {
@ -82,24 +85,35 @@ exports.uploadFile = async function (ctx) {
exports.serveApp = async function (ctx) {
let appId = await getAppIdFromUrl(ctx)
const App = require("./templates/BudibaseApp.svelte").default
const db = getAppDB({ skip_setup: true })
const appInfo = await db.get(DocumentTypes.APP_METADATA)
const { head, html, css } = App.render({
title: appInfo.name,
production: env.isProd(),
appId,
clientLibPath: clientLibraryPath(appId, appInfo.version),
})
if (!env.isJest()) {
const App = require("./templates/BudibaseApp.svelte").default
const { head, html, css } = App.render({
title: appInfo.name,
production: env.isProd(),
appId,
clientLibPath: clientLibraryPath(appId, appInfo.version),
})
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
ctx.body = await processString(appHbs, {
head,
body: html,
style: css.code,
appId,
})
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
ctx.body = await processString(appHbs, {
head,
body: html,
style: css.code,
appId,
})
} else {
// just return the app info for jest to assert on
ctx.body = appInfo
}
if (isDevAppID(appInfo.appId)) {
events.serve.servedAppPreview(appInfo)
} else {
events.serve.servedApp(appInfo)
}
}
exports.serveClientLibrary = async function (ctx) {

View File

@ -72,10 +72,8 @@ router.use(async (ctx, next) => {
validationErrors: err.validation,
error,
}
if (env.NODE_ENV !== "jest") {
ctx.log.error(err)
console.trace(err)
}
ctx.log.error(err)
console.trace(err)
}
})

View File

@ -14,8 +14,10 @@ jest.mock("aws-sdk", () => ({
}))
const setup = require("./utilities")
const { events } = require("@budibase/backend-core")
const version = require("../../../../package.json").version
describe("/attachments", () => {
describe("/static", () => {
let request = setup.getRequest()
let config = setup.getConfig()
let app
@ -26,73 +28,133 @@ describe("/attachments", () => {
app = await config.init()
})
describe("generateSignedUrls", () => {
let datasource
beforeEach(async () => {
datasource = await config.createDatasource({
datasource: {
type: "datasource",
name: "Test",
source: "S3",
config: {},
},
})
})
it("should be able to generate a signed upload URL", async () => {
const bucket = "foo"
const key = "bar"
describe("/builder", () => {
it("should serve the builder", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
.send({ bucket, key })
.get("/builder/portal")
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect("Content-Type", /text\/html/)
.expect(200)
expect(res.body.signedUrl).toEqual("my-url")
expect(res.body.publicUrl).toEqual(
`https://${bucket}.s3.eu-west-1.amazonaws.com/${key}`
)
})
it("should handle an invalid datasource ID", async () => {
const res = await request
.post(`/api/attachments/foo/url`)
.send({
bucket: "foo",
key: "bar",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(400)
expect(res.body.message).toEqual(
"The specified datasource could not be found"
)
})
it("should require a bucket parameter", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
.send({
bucket: undefined,
key: "bar",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(400)
expect(res.body.message).toEqual("bucket and key values are required")
})
it("should require a key parameter", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
.send({
bucket: "foo",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(400)
expect(res.body.message).toEqual("bucket and key values are required")
expect(res.text).toContain("<title>Budibase</title>")
expect(events.serve.servedBuilder).toBeCalledTimes(1)
expect(events.serve.servedBuilder).toBeCalledWith(version)
})
})
describe("/app", () => {
beforeEach(() => {
jest.clearAllMocks()
})
it("should serve the app by id", async () => {
const res = await request
.get(`/${config.prodAppId}`)
.set(config.defaultHeaders())
.expect(200)
expect(res.body.appId).toBe(config.prodAppId)
expect(events.serve.servedApp).toBeCalledTimes(1)
expect(events.serve.servedApp).toBeCalledWith(res.body)
expect(events.serve.servedAppPreview).not.toBeCalled()
})
it("should serve the app by url", async () => {
const res = await request
.get(`${config.prodApp.url}`)
.set(config.defaultHeaders())
.expect(200)
expect(res.body.appId).toBe(config.prodAppId)
expect(events.serve.servedApp).toBeCalledTimes(1)
expect(events.serve.servedApp).toBeCalledWith(res.body)
expect(events.serve.servedAppPreview).not.toBeCalled()
})
it("should serve the app preview by id", async () => {
const res = await request
.get(`/${config.appId}`)
.set(config.defaultHeaders())
.expect(200)
expect(res.body.appId).toBe(config.appId)
expect(events.serve.servedAppPreview).toBeCalledTimes(1)
expect(events.serve.servedAppPreview).toBeCalledWith(res.body)
expect(events.serve.servedApp).not.toBeCalled()
})
})
describe("/attachments", () => {
describe("generateSignedUrls", () => {
let datasource
beforeEach(async () => {
datasource = await config.createDatasource({
datasource: {
type: "datasource",
name: "Test",
source: "S3",
config: {},
},
})
})
it("should be able to generate a signed upload URL", async () => {
const bucket = "foo"
const key = "bar"
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
.send({ bucket, key })
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(200)
expect(res.body.signedUrl).toEqual("my-url")
expect(res.body.publicUrl).toEqual(
`https://${bucket}.s3.eu-west-1.amazonaws.com/${key}`
)
})
it("should handle an invalid datasource ID", async () => {
const res = await request
.post(`/api/attachments/foo/url`)
.send({
bucket: "foo",
key: "bar",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(400)
expect(res.body.message).toEqual(
"The specified datasource could not be found"
)
})
it("should require a bucket parameter", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
.send({
bucket: undefined,
key: "bar",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(400)
expect(res.body.message).toEqual("bucket and key values are required")
})
it("should require a key parameter", async () => {
const res = await request
.post(`/api/attachments/${datasource._id}/url`)
.send({
bucket: "foo",
})
.set(config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(400)
expect(res.body.message).toEqual("bucket and key values are required")
})
})
})
})

View File

@ -1,7 +1,10 @@
function isTest() {
return isCypress() || isJest()
}
function isJest() {
return (
process.env.NODE_ENV === "jest" ||
process.env.NODE_ENV === "cypress" ||
(process.env.JEST_WORKER_ID != null &&
process.env.JEST_WORKER_ID !== "null")
)
@ -73,6 +76,7 @@ module.exports = {
module.exports[key] = value
},
isTest,
isJest,
isCypress,
isDev,
isProd: () => {