Customizing the error messages for the standard validators - scala

I have a simple form:
val addForm = Form(
tuple("email" -> email, "password" -> nonEmptyText)
verifying("Invalid email or password", result => User.authenticate(result._1, result._2).isRight)
)
The general error message above is ok. But how do I customize the specific error messages for the email and password. For now in case of empty password I've got this kind of error:
password error.required
How do I customize this error message?
UPDATE:
Even this doesn't work because the validation message is still the same as it was:
val addForm = Form(
tuple("email" -> email, "password" -> nonEmptyTextWithMessage("My message"))
verifying("Invalid email or password", result => User.authenticate(result._1, result._2).isRight)
)
def nonEmptyTextWithMessage(errorMessage: String): Mapping[String] = nonEmptyText.verifying(errorMessage, { _ => true })

The nonEmptyText constraint defaults to using error.required as message key. You could change that in your conf/messages file, but I suppose this is not what you want.
If you want to re-use a pre-defined Constraint (note that nonEmptyText is not a Constraint but a Mapping), you could do the following:
val addForm = Form(
tuple(
"email" -> email,
"password" -> text.verifying(Constraints.nonEmpty.copy(name = Some("My message"))())
).verifying("Invalid email or password", result => User.authenticate(result._1, result._2).isRight)
)
It does not look very nice, but I'm not aware of any helper function that would achieve the same.

My colleague suggest, If you are using scala template, you could customize error message as follows
just add
'_error ->addForm("password").error.map(_.withMessage("Please provide password"))
like
#helper.inputPassword(addForm("password"), 'class->"col-md-12", '_label ->"Password",'style->"margin-bottom:20px", '_showConstraints->false, 'placeholder->"Enter Password", '_error ->addForm("password").error.map(_.withMessage("Please provide password")))

Related

Get token id from Login request in Gatling

I am using Gatling for performance testing, so I want know that how we extract token id from the login request here is code
val scn = scenario("Navigation")
.exec(http("request_6")
.post("/WEBAUTO03/aurora/login/security_check")
.headers(headers_6)
.formParam("j_username", "TONY")
.formParam("j_password", "1234")
.formParam("doLogin", "")
Above request provide token and I need apply the token in following request
val headers_9 = Map(
"Content-type" -> "text/plain",
"Origin" -> "https://resource.com",
"X-XSRF-TOKEN" -> ""4c81ed9c-e509-4830-b724-62e489c918e2"") -----here i need to replace token
.exec(http("request_9")
.post("/WEBAUTO03/aurora/JSON-RPC")
.headers(headers_9)
.body(RawFileBody("webview/navigation/0009_request.txt")))
anyone have any idea
Without seeing the response from the "above request" we cannot suggest the exact steps, approximate would be something like:
http("request_6")
.post("/WEBAUTO03/aurora/login/security_check")
.check(css("input[name='csrf_token']", "value").saveAs("Correlation1"))
val headers_9 = Map(
"Content-type" -> "text/plain",
"Origin" -> "https://resource.com",
"X-CSRF-Token" -> "${Correlation1}")
More information:
Gatling HTTP Checks
How to Run a Simple Load Test with Gatling

Pass specific value from feeder to script in gatling

I am working on performance test, for that I have below Gatling script -
val getUserById: ChainBuilder = feed(userEmailFeeder).exec(http("User By Id")
.get("url")
.headers(getHeaders)
.check(status is 200)
)
private val getHeaders = Map.apply(
"Content-Type" -> "application/json",
"Accept" -> "application/json",
"token" -> {tokenValue}
)
object BearerToken {
//Generating token here
}
In userEmailFeeder I have user emails and passwords. I have to generate a token for every email present in feeder and add to header in getHeader.
Can someone guide me how I can pass same email & associated password to BearerToken for which getUserById is referring from feeder so it will genearte token and add into header?
You can create method which will get your email and password from session, generate token and then write this values to session.
val generateTokenByEmailAndPassword: Expression[Session] = (session: Session) => {
val email = session("email").as[String]
val password = session("password").as[String]
// your logic for generate token
val token = email + password
session.set("tokenValue", token)
}
And then add to scenarion
...
.feed(userEmailFeeder)
.exec(generateTokenByEmailAndPassword)
.exec(http("User By Id")
...
A little remark - for get session value need add $
Wrong: {tokenValue}
Right way: ${tokenValue}

How to save a header from an http response

i'm trying to build a scenario where the user log in first, then do something before logging out.
The problem is that i want to save the header response from the log in request to use it in my next request.
When a user log in, he gets an header response containing the Authorization header, with the token.
Here is my code, but it's not working :
val LoggingTest = scenario("Basic Scenario")
.exec(http("Logging")
.post("/login")
.body(
StringBody("""{"name" : "test",
"password" : "test"}""")
)
.check(header("Authorization").saveAs("token"),status.is(200))
).pause(15)
.exec(http("check")
.get("/sayhi")
.header("Authorization",s"${token}")
.check(status.is(200))
).pause(15)
How can i fix it please ?
This is how you can do it:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
val LoggingTest: ScenarioBuilder = scenario("Basic Scenario")
.exec(http("Logging")
.post("/login")
.body(
StringBody("""{"name" : "test",
"password" : "test"}""")
)
.check(header("Authorization").saveAs("token"),status.is(200))
).pause(15)
.exec(
http("check")
.get("/sayhi")
.header("Authorization", session => session("token").validate[String])
.check(status.is(200))
).pause(15)
It's not s"${token}" but "${token}" without the s.
Sadly, IntelliJ automatically adds this s because it thinks you want to use Scala's String interpolation while you want to use Gatling Expression Language.

Load testing basic authentication with parameters with Gatling - Scala

I have a problem when trying to use the basicAuth method with parameter retrived from a csv files.
Here is my code:
class spiSimulation extends Simulation {
val httpProtocol = http
.baseURL("http://spi.test.com")
.inferHtmlResources()
val headers_0 = Map(
"Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Cache-Control" -> "no-cache",
"Pragma" -> "no-cache",
"Proxy-Connection" -> "keep-alive")
val users = csv("users.csv")
val scn = scenario("LosspiSimulation_request")
.feed(users)
.exec(
http("request")
.get("/SPI/Basic").headers(headers_0)
.basicAuth("${login}", "${password}")
.headers(headers_0).check(
header("Set-Cookie").saveAs("Cookie")))
.exec(
http("validate")
.get("/SPI-back/Validation?cookie=${Cookie}")
.headers(headers_0))
setUp(scn.inject(rampUsers(10) over (2 seconds))).protocols(httpProtocol)
}
When I use only one user and hard code my login and password it works. But with param login and password, I have two errors when running the Gatling script, one is "No attribute named Cookie" is defined and "No attribute named login is defined".
Here is a sample of my csv file:
login, password
test01, password01
test02, password02
I would be pleased if you can find a solution.
Thank you very much for your help!
Please try without whitespaces in the CSV file :)
The Feeders documentation of Gatling explicitly states that they honor only The RFC. They do not automatically trim whitespaces.
Should be:
login,password
test01,password01
test02,password02
Last line
setUp(scn.inject(rampUsers(10) over (2 seconds))).protocols(httpProtocol)
You declare 10 user and program must have 10 user in csv file.

Play Scala activator compile command shows value userid is not a member of play.api.data.Form[models.Changepas sword]

I am new to play framework(Scala),In my project I need to update new Password for this I need to get user id which is Primary key for that user table. Based on this unique user id value i will update Password.
What I need
need to get user table's user id value and pass this value into Controller's Action
What I tried
controllers/users.scala
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import views._
import models._
val changepasswordForm = Form(
mapping(
"userid" -> ignored(None:Option[Int]),
"password" -> tuple(
"main" -> text,
"confirm" -> text
).verifying(
// Add an additional constraint: both passwords must match
"Passwords don't match", passwords => passwords._1 == passwords._2
)
)(models.Changepassword.apply)(models.Changepassword.unapply)
)
def changePassword = Action {
Ok(html.changePassword(changepasswordForm))
}
def updatePassword(userid: Int) = Action { implicit request =>
changepasswordForm.bindFromRequest.fold(
formWithErrors => BadRequest(html.changePassword(formWithErrors)),
user => {
Changepassword.update(userid, user)
Ok("password Updated")
}
)
}
models/User.scala
case class Changepassword(
userid: Option[Int] = None,
password:(String,String)
)
object Changepassword{
val simple = {
get[Option[Int]]("user.USER_ID") ~
get[String]("user.PASSWORD") map {
case userid~password => Changepassword(userid, (password,password))
}
}
def update(userid: Int,changepassword:Changepassword) = {
DB.withConnection { implicit connection =>
SQL("update user set PASSWORD = {changepassword} where USER_ID = {userid}").
on('userid -> userid,
'changepassword -> changepassword.password._1)
.executeUpdate()
}
}
}
views/changePassword.scala.html
#(userForm: Form[Changepassword])
#import helper._
#implicitFieldConstructor = #{ FieldConstructor(twitterBootstrapInput.f) }
#main("") {
<h1>Change Password</h1>
#form(routes.Users.updatePassword(userForm.userid.get)) {
<fieldset>
#inputPassword(userForm("password.main"), '_label -> "New Password", '_help -> "",'placeholder -> "New Password")
#inputPassword(userForm("password.confirm"), '_label -> "Confirm Password", '_help -> "",'placeholder -> "Repeat Password")
</fieldset>
<div class="actions">
<input type="submit" value="Change password" class="btn primary"> or
Cancel
</div>
}
}
If I run activator compile command it shows below exception
D:\Jamal\test>activator compile
[info] Loading project definition from D:\Jamal\test\p
roject
[info] Set current project to scala-crud (in build file:/D:\Jamal\test/)
[info] Compiling 1 Scala source to D:\Jamal\test\targe
t\scala-2.11\classes...
[error] D:\Jamal\test\app\views\changePassword.sc
ala.html:11: value userid is not a member of play.api.data.Form[models.Changepas
sword]
[error] #form(routes.Users.updatePassword(userForm.userid.get)) {
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 13 s, completed Jun 11, 2015 3:52:19 PM
D:\Jamal\test>
You can't use the value of the form as a parameter for the route:
#form(routes.Users.updatePassword(userForm.userid.get))
The userid depends on the form and could therefore change. In any case, you would access the userid of the form using userForm("userid") and not userForm.userid (although it might not be what you want/need).
A better approach for your problem would be to pass a second parameter like this:
controllers/users.scala
def changePassword = Action {
val userId = ... get the current id ...
Ok(html.changePassword(changepasswordForm,userId))
}
views/changePassword.scala.html
#(userForm: Form[Changepassword], userId:Int)
...
...
#form(routes.Users.updatePassword(userId)) {
...
...
}
...
This way, you ensure the userId is known when the page is displayed and that a "evil" user can't change the passwords of other users by manipulating the userId.