Major update, fixing email test case.

This commit is contained in:
mike12345567 2021-04-23 18:54:12 +01:00
parent d985d338ec
commit 73ad093a50
15 changed files with 67 additions and 33 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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")
})
})

View File

@ -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)
}

View File

@ -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"),
}

View File

@ -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"

View File

@ -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>
@ -79,4 +79,5 @@
</tr>
</tbody>
</table>
</body>
</body>
</html>

View File

@ -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,
})
)

View File

@ -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,
}
}