Feature/subject in contact form (#1926)

* #1915 Add a subject to contact form and add it to email sent

* #1915 Add subject to contact form tests

* #1915 Contact form test corrected && tslint correction
pull/1934/head
Nassim Bounouas 2019-06-21 08:49:35 +02:00 committed by Chocobozzz
parent d1ea2a988d
commit 4e9fa5b7e9
10 changed files with 42 additions and 8 deletions

View File

@ -25,6 +25,15 @@
<div *ngIf="formErrors.fromEmail" class="form-error">{{ formErrors.fromEmail }}</div> <div *ngIf="formErrors.fromEmail" class="form-error">{{ formErrors.fromEmail }}</div>
</div> </div>
<div class="form-group">
<label i18n for="subject">Subject</label>
<input
type="text" id="subject"
formControlName="subject" [ngClass]="{ 'input-error': formErrors['subject'] }"
>
<div *ngIf="formErrors.subject" class="form-error">{{ formErrors.subject }}</div>
</div>
<div class="form-group"> <div class="form-group">
<label i18n for="body">Your message</label> <label i18n for="body">Your message</label>
<textarea id="body" formControlName="body" [ngClass]="{ 'input-error': formErrors['body'] }"> <textarea id="body" formControlName="body" [ngClass]="{ 'input-error': formErrors['body'] }">

View File

@ -39,6 +39,7 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit {
this.buildForm({ this.buildForm({
fromName: this.instanceValidatorsService.FROM_NAME, fromName: this.instanceValidatorsService.FROM_NAME,
fromEmail: this.instanceValidatorsService.FROM_EMAIL, fromEmail: this.instanceValidatorsService.FROM_EMAIL,
subject: this.instanceValidatorsService.SUBJECT,
body: this.instanceValidatorsService.BODY body: this.instanceValidatorsService.BODY
}) })
} }
@ -58,9 +59,10 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit {
sendForm () { sendForm () {
const fromName = this.form.value['fromName'] const fromName = this.form.value['fromName']
const fromEmail = this.form.value[ 'fromEmail' ] const fromEmail = this.form.value[ 'fromEmail' ]
const subject = this.form.value[ 'subject' ]
const body = this.form.value[ 'body' ] const body = this.form.value[ 'body' ]
this.instanceService.contactAdministrator(fromEmail, fromName, body) this.instanceService.contactAdministrator(fromEmail, fromName, subject, body)
.subscribe( .subscribe(
() => { () => {
this.notifier.success(this.i18n('Your message has been sent.')) this.notifier.success(this.i18n('Your message has been sent.'))

View File

@ -7,6 +7,7 @@ import { Injectable } from '@angular/core'
export class InstanceValidatorsService { export class InstanceValidatorsService {
readonly FROM_EMAIL: BuildFormValidator readonly FROM_EMAIL: BuildFormValidator
readonly FROM_NAME: BuildFormValidator readonly FROM_NAME: BuildFormValidator
readonly SUBJECT: BuildFormValidator
readonly BODY: BuildFormValidator readonly BODY: BuildFormValidator
constructor (private i18n: I18n) { constructor (private i18n: I18n) {
@ -32,6 +33,19 @@ export class InstanceValidatorsService {
} }
} }
this.SUBJECT = {
VALIDATORS: [
Validators.required,
Validators.minLength(1),
Validators.maxLength(120)
],
MESSAGES: {
'required': this.i18n('A subject is required.'),
'minlength': this.i18n('The subject must be at least 1 character long.'),
'maxlength': this.i18n('The subject cannot be more than 120 characters long.')
}
}
this.BODY = { this.BODY = {
VALIDATORS: [ VALIDATORS: [
Validators.required, Validators.required,

View File

@ -22,10 +22,11 @@ export class InstanceService {
.pipe(catchError(res => this.restExtractor.handleError(res))) .pipe(catchError(res => this.restExtractor.handleError(res)))
} }
contactAdministrator (fromEmail: string, fromName: string, message: string) { contactAdministrator (fromEmail: string, fromName: string, subject: string, message: string) {
const body = { const body = {
fromEmail, fromEmail,
fromName, fromName,
subject,
body: message body: message
} }

View File

@ -14,7 +14,7 @@ contactRouter.post('/contact',
async function contactAdministrator (req: express.Request, res: express.Response) { async function contactAdministrator (req: express.Request, res: express.Response) {
const data = req.body as ContactForm const data = req.body as ContactForm
await Emailer.Instance.addContactFormJob(data.fromEmail, data.fromName, data.body) await Emailer.Instance.addContactFormJob(data.fromEmail, data.fromName, data.subject, data.body)
await Redis.Instance.setContactFormIp(req.ip) await Redis.Instance.setContactFormIp(req.ip)

View File

@ -402,7 +402,7 @@ class Emailer {
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
} }
addContactFormJob (fromEmail: string, fromName: string, body: string) { addContactFormJob (fromEmail: string, fromName: string, subject: string, body: string) {
const text = 'Hello dear admin,\n\n' + const text = 'Hello dear admin,\n\n' +
fromName + ' sent you a message' + fromName + ' sent you a message' +
'\n\n---------------------------------------\n\n' + '\n\n---------------------------------------\n\n' +
@ -415,7 +415,7 @@ class Emailer {
fromDisplayName: fromEmail, fromDisplayName: fromEmail,
replyTo: fromEmail, replyTo: fromEmail,
to: [ CONFIG.ADMIN.EMAIL ], to: [ CONFIG.ADMIN.EMAIL ],
subject: CONFIG.EMAIL.OBJECT.PREFIX + 'Contact form submitted', subject: CONFIG.EMAIL.OBJECT.PREFIX + subject,
text text
} }

View File

@ -26,6 +26,7 @@ describe('Test contact form API validators', function () {
const defaultBody = { const defaultBody = {
fromName: 'super name', fromName: 'super name',
fromEmail: 'toto@example.com', fromEmail: 'toto@example.com',
subject: 'my subject',
body: 'Hello, how are you?' body: 'Hello, how are you?'
} }
let emailPort: number let emailPort: number

View File

@ -43,6 +43,7 @@ describe('Test contact form', function () {
url: server.url, url: server.url,
fromEmail: 'toto@example.com', fromEmail: 'toto@example.com',
body: 'my super message', body: 'my super message',
subject: 'my subject',
fromName: 'Super toto' fromName: 'Super toto'
}) })
@ -55,7 +56,7 @@ describe('Test contact form', function () {
expect(email['from'][0]['address']).equal('test-admin@localhost') expect(email['from'][0]['address']).equal('test-admin@localhost')
expect(email['from'][0]['name']).equal('toto@example.com') expect(email['from'][0]['name']).equal('toto@example.com')
expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com') expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com')
expect(email['subject']).contains('Contact form') expect(email['subject']).contains('my subject')
expect(email['text']).contains('my super message') expect(email['text']).contains('my super message')
}) })
@ -64,6 +65,7 @@ describe('Test contact form', function () {
url: server.url, url: server.url,
fromEmail: 'toto@example.com', fromEmail: 'toto@example.com',
body: 'my super message', body: 'my super message',
subject: 'my subject',
fromName: 'Super toto' fromName: 'Super toto'
}) })
@ -72,6 +74,7 @@ describe('Test contact form', function () {
fromEmail: 'toto@example.com', fromEmail: 'toto@example.com',
body: 'my super message', body: 'my super message',
fromName: 'Super toto', fromName: 'Super toto',
subject: 'my subject',
expectedStatus: 403 expectedStatus: 403
}) })
}) })
@ -82,8 +85,9 @@ describe('Test contact form', function () {
await sendContactForm({ await sendContactForm({
url: server.url, url: server.url,
fromEmail: 'toto@example.com', fromEmail: 'toto@example.com',
body: 'my super message', fromName: 'Super toto',
fromName: 'Super toto' subject: 'my subject',
body: 'my super message'
}) })
}) })

View File

@ -5,6 +5,7 @@ function sendContactForm (options: {
url: string, url: string,
fromEmail: string, fromEmail: string,
fromName: string, fromName: string,
subject: string,
body: string, body: string,
expectedStatus?: number expectedStatus?: number
}) { }) {
@ -13,6 +14,7 @@ function sendContactForm (options: {
const body: ContactForm = { const body: ContactForm = {
fromEmail: options.fromEmail, fromEmail: options.fromEmail,
fromName: options.fromName, fromName: options.fromName,
subject: options.subject,
body: options.body body: options.body
} }
return request(options.url) return request(options.url)

View File

@ -1,5 +1,6 @@
export interface ContactForm { export interface ContactForm {
fromEmail: string fromEmail: string
fromName: string fromName: string
subject: string
body: string body: string
} }