Major update, fixing email test case.
This commit is contained in:
parent
0dd46d12fa
commit
48c1b4b1fe
|
@ -28,6 +28,12 @@ async function buildEmail(purpose, email, user) {
|
|||
getTemplateByPurpose(TYPE, EmailTemplatePurpose.STYLES),
|
||||
getTemplateByPurpose(TYPE, purpose),
|
||||
])
|
||||
if (!base || !styles || !body) {
|
||||
throw "Unable to build email, missing base components"
|
||||
}
|
||||
base = base.contents
|
||||
styles = styles.contents
|
||||
body = body.contents
|
||||
|
||||
// TODO: need to extend the context as much as possible
|
||||
const context = {
|
||||
|
@ -59,6 +65,9 @@ exports.sendEmail = async ctx => {
|
|||
user = db.get(userId)
|
||||
}
|
||||
const config = await determineScopedConfig(db, params)
|
||||
if (!config) {
|
||||
ctx.throw(400, "Unable to find SMTP configuration")
|
||||
}
|
||||
const transport = createSMTPTransport(config)
|
||||
const message = {
|
||||
from: config.from,
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
const { generateTemplateID, StaticDatabases } = require("@budibase/auth").db
|
||||
const { CouchDB } = require("../../../db")
|
||||
const { TemplateMetadata, TemplateBindings } = require("../../../constants")
|
||||
const {
|
||||
TemplateMetadata,
|
||||
TemplateBindings,
|
||||
GLOBAL_OWNER,
|
||||
} = require("../../../constants")
|
||||
const { getTemplates } = require("../../../constants/templates")
|
||||
|
||||
const GLOBAL_DB = StaticDatabases.GLOBAL.name
|
||||
const GLOBAL_OWNER = "global"
|
||||
|
||||
exports.save = async ctx => {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
|
|
|
@ -11,7 +11,7 @@ const FIRST_USER_EMAIL = "test@test.com"
|
|||
const FIRST_USER_PASSWORD = "test"
|
||||
const GLOBAL_DB = StaticDatabases.GLOBAL.name
|
||||
|
||||
exports.userSave = async ctx => {
|
||||
exports.save = async ctx => {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
const { email, password, _id } = ctx.request.body
|
||||
|
||||
|
@ -69,10 +69,10 @@ exports.firstUser = async ctx => {
|
|||
global: true,
|
||||
},
|
||||
}
|
||||
await exports.userSave(ctx)
|
||||
await exports.save(ctx)
|
||||
}
|
||||
|
||||
exports.userDelete = async ctx => {
|
||||
exports.destroy = async ctx => {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
const dbUser = await db.get(ctx.params.id)
|
||||
await db.remove(dbUser._id, dbUser._rev)
|
||||
|
@ -82,7 +82,7 @@ exports.userDelete = async ctx => {
|
|||
}
|
||||
|
||||
// called internally by app server user fetch
|
||||
exports.userFetch = async ctx => {
|
||||
exports.fetch = async ctx => {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
const response = await db.allDocs(
|
||||
getGlobalUserParams(null, {
|
||||
|
@ -100,7 +100,7 @@ exports.userFetch = async ctx => {
|
|||
}
|
||||
|
||||
// called internally by app server user find
|
||||
exports.userFind = async ctx => {
|
||||
exports.find = async ctx => {
|
||||
const db = new CouchDB(GLOBAL_DB)
|
||||
let user
|
||||
try {
|
||||
|
|
|
@ -25,7 +25,7 @@ function smtpValidation() {
|
|||
function settingValidation() {
|
||||
// prettier-ignore
|
||||
return Joi.object({
|
||||
url: Joi.string().valid("", null),
|
||||
platformUrl: Joi.string().valid("", null),
|
||||
logoUrl: Joi.string().valid("", null),
|
||||
company: Joi.string().required(),
|
||||
}).unknown(true)
|
||||
|
|
|
@ -25,10 +25,10 @@ function buildUserSaveValidation() {
|
|||
}
|
||||
|
||||
router
|
||||
.post("/api/admin/users", buildUserSaveValidation(), controller.userSave)
|
||||
.get("/api/admin/users", controller.userFetch)
|
||||
.post("/api/admin/users", buildUserSaveValidation(), controller.save)
|
||||
.get("/api/admin/users", controller.fetch)
|
||||
.post("/api/admin/users/first", controller.firstUser)
|
||||
.delete("/api/admin/users/:id", controller.userDelete)
|
||||
.get("/api/admin/users/:id", controller.userFind)
|
||||
.delete("/api/admin/users/:id", controller.destroy)
|
||||
.get("/api/admin/users/:id", controller.find)
|
||||
|
||||
module.exports = router
|
||||
|
|
|
@ -5,12 +5,19 @@ const { EmailTemplatePurpose } = require("../../../constants")
|
|||
const sendMailMock = jest.fn()
|
||||
jest.mock("nodemailer")
|
||||
const nodemailer = require("nodemailer")
|
||||
nodemailer.createTransport.mockReturnValue({"sendMail": sendMailMock});
|
||||
nodemailer.createTransport.mockReturnValue({
|
||||
sendMail: sendMailMock,
|
||||
verify: jest.fn()
|
||||
})
|
||||
|
||||
describe("/api/admin/email", () => {
|
||||
let request = setup.getRequest()
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeAll(async () => {
|
||||
await config.init()
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to send an email (with mocking)", async () => {
|
||||
|
@ -26,5 +33,10 @@ describe("/api/admin/email", () => {
|
|||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
expect(res.body.message).toBeDefined()
|
||||
expect(sendMailMock).toHaveBeenCalled()
|
||||
const emailCall = sendMailMock.mock.calls[0][0]
|
||||
expect(emailCall.subject).toBe("Hello!")
|
||||
expect(emailCall.html).not.toContain("Invalid Binding")
|
||||
})
|
||||
})
|
|
@ -39,6 +39,8 @@ class TestConfiguration {
|
|||
async init() {
|
||||
// create a test user
|
||||
await this._req({
|
||||
email: "test@test.com",
|
||||
password: "test",
|
||||
_id: "us_uuid1",
|
||||
builder: {
|
||||
global: true,
|
||||
|
@ -64,7 +66,7 @@ class TestConfiguration {
|
|||
await this._req({
|
||||
type: Configs.SETTINGS,
|
||||
config: {
|
||||
url: "http://localhost:10000",
|
||||
platformUrl: "http://localhost:10000",
|
||||
logoUrl: "http://localhost:10000/logo",
|
||||
company: "TestCompany",
|
||||
}
|
||||
|
@ -78,7 +80,7 @@ class TestConfiguration {
|
|||
port: 12345,
|
||||
host: "smtptesthost.com",
|
||||
from: "testfrom@test.com",
|
||||
|
||||
subject: "Hello!",
|
||||
}
|
||||
}, null, controllers.config.save)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module.exports = {
|
||||
email: require("../../../controllers/admin/email"),
|
||||
groups: require("../../../controllers/admin/groups"),
|
||||
config: require("../../../controllers/admin/groups"),
|
||||
templates: require("../../../controllers/admin/groups"),
|
||||
users: require("../../../controllers/admin/groups"),
|
||||
config: require("../../../controllers/admin/configs"),
|
||||
templates: require("../../../controllers/admin/templates"),
|
||||
users: require("../../../controllers/admin/users"),
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ const EmailTemplatePurpose = {
|
|||
}
|
||||
|
||||
const TemplateBindings = {
|
||||
URL: "url",
|
||||
PLATFORM_URL: "platformUrl",
|
||||
COMPANY: "company",
|
||||
LOGO_URL: "logoUrl",
|
||||
STYLES: "styles",
|
||||
|
@ -76,3 +76,4 @@ exports.TemplateTypes = TemplateTypes
|
|||
exports.EmailTemplatePurpose = EmailTemplatePurpose
|
||||
exports.TemplateMetadata = TemplateMetadata
|
||||
exports.TemplateBindings = TemplateBindings
|
||||
exports.GLOBAL_OWNER = "global"
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align: left; padding-left: 10px;">
|
||||
<h3 class="heading"><a href="{{ url }}">Budibase Platform</a></h3>
|
||||
<h3 class="heading"><a href="{{ platformUrl }}">Budibase Platform</a></h3>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
@ -64,7 +64,7 @@
|
|||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align: left; padding-right: 10px;">
|
||||
<p>© 2021 Restobar. All Rights Reserved</p>
|
||||
<p>© 2021 {{ company }}. All Rights Reserved</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
@ -80,3 +80,4 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -3,6 +3,7 @@ const {
|
|||
EmailTemplatePurpose,
|
||||
TemplateTypes,
|
||||
TemplatePurpose,
|
||||
GLOBAL_OWNER,
|
||||
} = require("../index")
|
||||
const { join } = require("path")
|
||||
const CouchDB = require("../../db")
|
||||
|
@ -10,14 +11,14 @@ const { getTemplateParams, StaticDatabases } = require("@budibase/auth").db
|
|||
|
||||
exports.EmailTemplates = {
|
||||
[EmailTemplatePurpose.PASSWORD_RECOVERY]: readStaticFile(
|
||||
join(__dirname, "passwordRecovery.html")
|
||||
join(__dirname, "passwordRecovery.hbs")
|
||||
),
|
||||
[EmailTemplatePurpose.INVITATION]: readStaticFile(
|
||||
join(__dirname, "invitation.html")
|
||||
join(__dirname, "invitation.hbs")
|
||||
),
|
||||
[EmailTemplatePurpose.BASE]: readStaticFile(join(__dirname, "base.html")),
|
||||
[EmailTemplatePurpose.BASE]: readStaticFile(join(__dirname, "base.hbs")),
|
||||
[EmailTemplatePurpose.STYLES]: readStaticFile(
|
||||
join(__dirname, "style.css")
|
||||
join(__dirname, "style.hbs")
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -37,7 +38,11 @@ exports.addBaseTemplates = (templates, type = null) => {
|
|||
continue
|
||||
}
|
||||
if (exports.EmailTemplates[purpose]) {
|
||||
templates.push(exports.EmailTemplates[purpose])
|
||||
templates.push({
|
||||
contents: exports.EmailTemplates[purpose],
|
||||
purpose,
|
||||
type,
|
||||
})
|
||||
}
|
||||
}
|
||||
return templates
|
||||
|
@ -46,7 +51,7 @@ exports.addBaseTemplates = (templates, type = null) => {
|
|||
exports.getTemplates = async ({ ownerId, type, id } = {}) => {
|
||||
const db = new CouchDB(StaticDatabases.GLOBAL.name)
|
||||
const response = await db.allDocs(
|
||||
getTemplateParams(ownerId, id, {
|
||||
getTemplateParams(ownerId || GLOBAL_OWNER, id, {
|
||||
include_docs: true,
|
||||
})
|
||||
)
|
||||
|
|
|
@ -15,17 +15,18 @@ exports.getSettingsTemplateContext = async () => {
|
|||
})
|
||||
)
|
||||
let settings = response.rows.map(row => row.doc)[0] || {}
|
||||
if (!settings.url) {
|
||||
settings.url = LOCAL_URL
|
||||
if (!settings.platformUrl) {
|
||||
settings.platformUrl = LOCAL_URL
|
||||
}
|
||||
// TODO: need to fully spec out the context
|
||||
const URL = settings.platformUrl
|
||||
return {
|
||||
[TemplateBindings.LOGO_URL]: settings.logoUrl || LOGO_URL,
|
||||
[TemplateBindings.URL]: settings.url,
|
||||
[TemplateBindings.PLATFORM_URL]: URL,
|
||||
[TemplateBindings.REGISTRATION_URL]: checkSlashesInUrl(
|
||||
`${settings.url}/registration`
|
||||
`${URL}/registration`
|
||||
),
|
||||
[TemplateBindings.RESET_URL]: checkSlashesInUrl(`${settings.url}/reset`),
|
||||
[TemplateBindings.RESET_URL]: checkSlashesInUrl(`${URL}/reset`),
|
||||
[TemplateBindings.COMPANY]: settings.company || BASE_COMPANY,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue