Skip to content

Commit

Permalink
Merge pull request #11 from hmrc/referrer
Browse files Browse the repository at this point in the history
Capture campaign referrer at signup
  • Loading branch information
Henri Cook authored Jan 4, 2017
2 parents 4c5753d + 23d2bc6 commit 6dc0680
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 84 deletions.
41 changes: 20 additions & 21 deletions app/connectors/ApplicationClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,55 +42,56 @@ trait ApplicationClient {
import ExchangeObjects.Implicits._
import config.FrontendAppConfig.fasttrackConfig._

def createApplication(userId: UniqueIdentifier, frameworkId: String)(implicit hc: HeaderCarrier) = {
def createApplication(userId: UniqueIdentifier, frameworkId: String)
(implicit hc: HeaderCarrier): Future[ApplicationResponse] = {

http.PUT(s"${url.host}${url.base}/application/create", CreateApplicationRequest(userId, frameworkId)).map { response =>
response.json.as[ApplicationResponse]
}
}

def submitApplication(userId: UniqueIdentifier, applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier) = {
def submitApplication(userId: UniqueIdentifier, applicationId: UniqueIdentifier)
(implicit hc: HeaderCarrier): Future[Unit] = {
http.PUT(s"${url.host}${url.base}/application/submit/$userId/$applicationId", Json.toJson("")).map {
case x: HttpResponse if x.status == OK => ()
}.recover {
case _: BadRequestException => throw new CannotSubmit()
}
}

def withdrawApplication(applicationId: UniqueIdentifier, reason: WithdrawApplicationRequest)(implicit hc: HeaderCarrier) = {
def withdrawApplication(applicationId: UniqueIdentifier, reason: WithdrawApplicationRequest)
(implicit hc: HeaderCarrier): Future[Unit] = {
http.PUT(s"${url.host}${url.base}/application/withdraw/$applicationId", Json.toJson(reason)).map {
case x: HttpResponse if x.status == OK => ()
}.recover {
case _: NotFoundException => throw new CannotWithdraw()
}
}

def addMedia(userId: UniqueIdentifier, media: String)(implicit hc: HeaderCarrier) = {
def addMedia(userId: UniqueIdentifier, media: String)(implicit hc: HeaderCarrier): Future[Unit] = {
http.PUT(s"${url.host}${url.base}/media/create", AddMedia(userId, media)).map {
case x: HttpResponse if x.status == CREATED => ()
} recover {
case _: BadRequestException => throw new CannotAddMedia()
}
}

def getApplicationProgress(applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier) = {
def getApplicationProgress(applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier): Future[ProgressResponse] = {
http.GET(s"${url.host}${url.base}/application/progress/$applicationId").map { response =>
response.json.as[ProgressResponse]
}
}

def findApplication(userId: UniqueIdentifier, frameworkId: String)(implicit hc: HeaderCarrier) = {
def findApplication(userId: UniqueIdentifier, frameworkId: String)(implicit hc: HeaderCarrier): Future[ApplicationResponse] = {
http.GET(s"${url.host}${url.base}/application/find/user/$userId/framework/$frameworkId").map { response =>
response.json.as[ApplicationResponse]
} recover {
case _: NotFoundException => throw new ApplicationNotFound()
}
}

def updateGeneralDetails(applicationId: UniqueIdentifier, userId: UniqueIdentifier, data: GeneralDetailsForm.Data, email: String)(
implicit
hc: HeaderCarrier
) = {
def updateGeneralDetails(applicationId: UniqueIdentifier, userId: UniqueIdentifier, data: GeneralDetailsForm.Data,
email: String)(implicit hc: HeaderCarrier): Future[Unit] = {

http.POST(
s"${url.host}${url.base}/personal-details/$userId/$applicationId",
Expand All @@ -113,18 +114,17 @@ trait ApplicationClient {
}
}

def findPersonalDetails(userId: UniqueIdentifier, applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier) = {
def findPersonalDetails(userId: UniqueIdentifier, applicationId: UniqueIdentifier)
(implicit hc: HeaderCarrier): Future[GeneralDetailsExchange] = {
http.GET(s"${url.host}${url.base}/personal-details/$userId/$applicationId").map { response =>
response.json.as[GeneralDetailsExchange]
} recover {
case e: NotFoundException => throw new PersonalDetailsNotFound()
}
}

def updateAssistanceDetails(applicationId: UniqueIdentifier, userId: UniqueIdentifier, data: AssistanceForm.Data)(
implicit
hc: HeaderCarrier
) = {
def updateAssistanceDetails(applicationId: UniqueIdentifier, userId: UniqueIdentifier, data: AssistanceForm.Data)
(implicit hc: HeaderCarrier): Future[Unit] = {
http.PUT(
s"${url.host}${url.base}/assistance-details/$userId/$applicationId",
data.exchange
Expand All @@ -135,18 +135,17 @@ trait ApplicationClient {
}
}

def findAssistanceDetails(userId: UniqueIdentifier, applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier) = {
def findAssistanceDetails(userId: UniqueIdentifier, applicationId: UniqueIdentifier)
(implicit hc: HeaderCarrier): Future[AssistanceDetailsExchange] = {
http.GET(s"${url.host}${url.base}/assistance-details/$userId/$applicationId").map { response =>
response.json.as[AssistanceDetailsExchange]
} recover {
case _: NotFoundException => throw new AssistanceDetailsNotFound()
}
}

def updateQuestionnaire(applicationId: UniqueIdentifier, sectionId: String, questionnaire: Questionnaire)(
implicit
hc: HeaderCarrier
) = {
def updateQuestionnaire(applicationId: UniqueIdentifier, sectionId: String, questionnaire: Questionnaire)
(implicit hc: HeaderCarrier): Future[Unit] = {
http.PUT(
s"${url.host}${url.base}/questionnaire/$applicationId/$sectionId",
questionnaire
Expand All @@ -157,7 +156,7 @@ trait ApplicationClient {
}
}

def updateReview(applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier) = {
def updateReview(applicationId: UniqueIdentifier)(implicit hc: HeaderCarrier): Future[Unit] = {
http.PUT(
s"${url.host}${url.base}/application/review/$applicationId",
ReviewRequest(true)
Expand Down
8 changes: 2 additions & 6 deletions app/connectors/ExchangeObjects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ object ExchangeObjects {
guaranteedInterview: Option[String],
needsAdjustment: Option[String],
typeOfAdjustments: Option[List[String]],
otherAdjustments: Option[String],
campaignReferrer: Option[String],
campaignOther: Option[String]
otherAdjustments: Option[String]
)

case class AddMedia(userId: UniqueIdentifier, media: String)
Expand Down Expand Up @@ -219,9 +217,7 @@ object ExchangeObjects {
if (needsAssistance) { None } else data.guaranteedInterview,
Some(data.needsAdjustment),
if (data.needsAdjustment == "No") { None } else data.typeOfAdjustments,
adjustmentValid(data, data.otherAdjustments),
data.campaignReferrer,
data.campaignOther
adjustmentValid(data, data.otherAdjustments)
)
}

Expand Down
24 changes: 7 additions & 17 deletions app/controllers/AssistanceController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ trait AssistanceController extends BaseController with ApplicationClient {
ad.guaranteedInterview,
ad.needsAdjustment.getOrElse(""),
ad.typeOfAdjustments,
ad.otherAdjustments,
ad.campaignReferrer,
ad.campaignOther
ad.otherAdjustments
))
Ok(views.html.application.assistance(form))
}.recover {
Expand All @@ -59,24 +57,16 @@ trait AssistanceController extends BaseController with ApplicationClient {
invalidForm =>
Future.successful(Ok(views.html.application.assistance(invalidForm))),
data => {
addMedia(user.user.userID, extractMediaReferrer(data)).flatMap { _ =>
updateAssistanceDetails(user.application.applicationId, user.user.userID, data).flatMap { _ =>
updateProgress()(_ => Redirect(routes.ReviewApplicationController.present()))
}.recover {
case e: AssistanceDetailsNotFound =>
Redirect(routes.HomeController.present()).flashing(danger("account.error"))
}
updateAssistanceDetails(user.application.applicationId, user.user.userID, data).flatMap { _ =>
updateProgress()(_ => Redirect(routes.ReviewApplicationController.present()))
}.recover {
case e: AssistanceDetailsNotFound =>
Redirect(routes.HomeController.present()).flashing(danger("account.error"))
}
}
)
}

private def extractMediaReferrer(data: AssistanceForm.Data): String = {
if (data.campaignReferrer.contains("Other") || data.campaignReferrer.contains("Careers fair")) {
data.campaignOther.getOrElse("")
} else {
data.campaignReferrer.getOrElse("")
}
}


}
18 changes: 14 additions & 4 deletions app/controllers/SignUpController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,28 @@ trait SignUpController extends BaseController with SignInUtils with ApplicationC
invalidForm => Future.successful(Ok(views.html.registration.signup(invalidForm))),
data => {
env.register(data.email.toLowerCase, data.password, data.firstName, data.lastName).flatMap { u =>
signInUser(
u.toCached,
redirect = Redirect(routes.ActivationController.present()).flashing(success("account.successful"))
).map { r =>
addMedia(u.userId, extractMediaReferrer(data)).flatMap { _ =>
signInUser(
u.toCached,
redirect = Redirect(routes.ActivationController.present()).flashing(success("account.successful"))
).map { r =>
env.eventBus.publish(SignUpEvent(SecurityUser(u.userId.toString), request, request2lang))
r
}
}
}.recover {
case e: EmailTakenException =>
Ok(views.html.registration.signup(SignUpForm.form.fill(data), Some(danger("user.exists"))))
}
}
)
}

private def extractMediaReferrer(data: SignUpForm.Data): String = {
if (data.campaignReferrer.contains("Other") || data.campaignReferrer.contains("Careers fair")) {
data.campaignOther.getOrElse("")
} else {
data.campaignReferrer.getOrElse("")
}
}
}
8 changes: 2 additions & 6 deletions app/forms/AssistanceForm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@ object AssistanceForm {
"guaranteedInterview" -> of(requiredFormatter("needsAssistance", "guaranteedInterview")),
"needsAdjustment" -> Mappings.nonEmptyTrimmedText("needsAdjustment.chooseone", 3),
"typeOfAdjustments" -> of(requiredListFormatter("needsAdjustment", "typeOfAdjustments")),
"otherAdjustments" -> optional(Mappings.nonEmptyTrimmedText("otherAdjustments.chooseone", 4000)),
"campaignReferrer" -> Mappings.optionalTrimmedText(64),
"campaignOther" -> Mappings.optionalTrimmedText(256)
"otherAdjustments" -> optional(Mappings.nonEmptyTrimmedText("otherAdjustments.chooseone", 4000))
)(Data.apply)(Data.unapply)
)

Expand All @@ -111,9 +109,7 @@ object AssistanceForm {
guaranteedInterview: Option[String],
needsAdjustment: String,
typeOfAdjustments: Option[List[String]],
otherAdjustments: Option[String],
campaignReferrer: Option[String],
campaignOther: Option[String]
otherAdjustments: Option[String]
)

}
8 changes: 6 additions & 2 deletions app/forms/SignUpForm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ object SignUpForm {
passwordField -> of(passwordFormatter),
confirmPasswordField -> nonEmptyTrimmedText("error.confirmpwd", passwordMaxLength),
"agree" -> checked(Messages("agree.accept")),
"agreeEligibleToApply" -> checked(Messages("agree.eligible"))
"agreeEligibleToApply" -> checked(Messages("agree.eligible")),
"campaignReferrer" -> optionalTrimmedText(64),
"campaignOther" -> optionalTrimmedText(256)
)(Data.apply)(Data.unapply)
)

Expand All @@ -94,6 +96,8 @@ object SignUpForm {
password: String,
confirmpwd: String,
agree: Boolean,
agreeEligibleToApply: Boolean
agreeEligibleToApply: Boolean,
campaignReferrer: Option[String],
campaignOther: Option[String]
)
}
18 changes: 0 additions & 18 deletions app/views/application/assistance.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,6 @@ <h2 class="heading-large">Guaranteed interview scheme</h2>
}
</section>

<section>
<h2 class="heading-large">How did you hear about us?</h2>
<div data-optional>
@select_guard(assistanceForm("campaignReferrer"), models.CampaignReferrers.list,
"hearAboutUsDetail", "-- Select one --") {
Select how you heard about us (optional)
}
</div>

<div class="form-group toggle-content" id="hearAboutUsDetail" data-requiredifshown data-optional>
@helper.inputText(assistanceForm("campaignOther"),
'_label -> "Provide more information (optional)",
'class -> "form-control",
'_showConstraints -> false)
</div>
</section>


<div class="form-group">
<div>
<button id="submit" type="submit" value="submit" class="button">Save and continue</button>
Expand Down
18 changes: 17 additions & 1 deletion app/views/registration/signup.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
implicit request: Request[_], flash: Flash, user: Option[CachedData], feedbackUrl: String, fasttrackConfig: FasttrackConfig)

@import helpers.CSRFieldConstructor._
@import views.html.widgets.checkbox
@import views.html.widgets.{ checkbox, select_guard }

@main_template(title = "Create your account", pageForms = Seq(signUpForm), notification = notification) {
<h1 class="heading-xlarge">Create your account</h1>
Expand Down Expand Up @@ -77,6 +77,22 @@ <h3 class="heading-medium">Confirm the following statements are true:</h3>

</section>

<section class="section-border">
<h2 class="heading-large">How did you hear about us?</h2>
<div data-optional>
@select_guard(signUpForm("campaignReferrer"), models.CampaignReferrers.list,
"hearAboutUsDetail", "-- Select one --") {
Select how you heard about us (optional)
}
</div>
<div class="form-group toggle-content" id="hearAboutUsDetail" data-requiredifshown data-optional>
@helper.inputText(signUpForm("campaignOther"),
'_label -> "Provide more information (optional)",
'class -> "form-control",
'_showConstraints -> false)
</div>
</section>

<section>
<h2 class="heading-large">Terms and conditions</h2>
@checkbox(signUpForm("agree")) {
Expand Down
8 changes: 4 additions & 4 deletions test/controllers/forms/AssistanceFormSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@ class AssistanceFormSpec extends BaseSpec {
trait Fixture {

val noDisabilities = {
val data = Data("No", Some(List("")), None, Some("No"), "No", None, None, None, None)
val data = Data("No", Some(List("")), None, Some("No"), "No", None, None)

(data, AssistanceForm.form.fill(data))
}

val noAdjustments = {
val data = Data("Yes", Some(List("One of the disabilities")), None, None, "No", None, None, None, None)
val data = Data("Yes", Some(List("One of the disabilities")), None, None, "No", None, None)

(data, AssistanceForm.form.fill(data))
}

val fullForm: (Data, Form[Data]) = {
val data = Data("Yes", Some(List("One of the disabilities")), Some("some details"), None, "Yes", Some(List("other")), None, None, None)
val data = Data("Yes", Some(List("One of the disabilities")), Some("some details"), None, "Yes", Some(List("other")), None)

(data, AssistanceForm.form.fill(data))
}
Expand All @@ -79,7 +79,7 @@ class AssistanceFormSpec extends BaseSpec {
) = {

val data = Data(needsAssistance, typeOfdisability, detailsOfdisability, guaranteedInterview, needsAdjustment,
typeOfAdjustments, otherAdjustments, None, None)
typeOfAdjustments, otherAdjustments)

(data, AssistanceForm.form.fill(data))
}
Expand Down
17 changes: 12 additions & 5 deletions test/controllers/forms/SignUpFormSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ class SignUpFormSpec extends BaseSpec {
signUpForm.errors("password").head.messages must be(Seq(Messages("error.password")))
}

"throw an error if I haven't click on the I am eligible" in {
"throw an error if I haven't clicked on the I am eligible" in {
val (_, signUpForm) = SignupFormGenerator(agreeEligibleToApply = false).get
signUpForm.hasErrors must be(true)
signUpForm.errors.length must be(1)
signUpForm.errors("agreeEligibleToApply").head.messages must be(Seq(Messages("agree.eligible")))
}

"throw an error if I haven't click on the I agree" in {
"throw an error if I haven't clicked on the I agree" in {
val (_, signUpForm) = SignupFormGenerator(agree = false).get
signUpForm.hasErrors must be(true)
signUpForm.errors.length must be(1)
Expand All @@ -105,10 +105,14 @@ case class SignupFormGenerator(
password: String = "aA1234567",
confirm: String = "aA1234567",
agree: Boolean = true,
agreeEligibleToApply: Boolean = true
agreeEligibleToApply: Boolean = true,
campaignReferrer: Option[String] = Some("Google"),
campaignOther: Option[String] = Some("More Google")
) {

private val data = Data(firstName, lastName, email, confirmEmail, password, confirm, agree, agreeEligibleToApply)
private val data = Data(firstName, lastName, email, confirmEmail, password, confirm, agree, agreeEligibleToApply,
campaignReferrer, campaignOther
)

private val validFormData = Map(
"firstName" -> data.firstName,
Expand All @@ -118,7 +122,10 @@ case class SignupFormGenerator(
"password" -> data.password,
"confirmpwd" -> data.confirmpwd,
"agree" -> data.agree.toString,
"agreeEligibleToApply" -> data.agreeEligibleToApply.toString
"agreeEligibleToApply" -> data.agreeEligibleToApply.toString,
"campaignReferrer" -> data.campaignReferrer.getOrElse(""),
"campaignOther" -> data.campaignOther.getOrElse("")

)

private def signUpForm = Form(SignUpForm.form.mapping).bind(validFormData)
Expand Down

0 comments on commit 6dc0680

Please sign in to comment.