Using WebSpec to test result of a POST request

149 views
Skip to first unread message

Mads Hartmann Jensen

unread,
Aug 4, 2012, 4:55:45 PM8/4/12
to lif...@googlegroups.com
Hi, 

I can't seem to figure out how to use WebSpec to test the result of a POST request. I currently have 

"When submitting the form it invokes the function with the input" withReqFor(testUrl) withPost(jobj) in {
  req => {
    Result.is must_== Person("Mads","Hartmann")
  }
}

But this doesn't seem to actually invoke the POST request, is that correct? I want to test the effect a POST request has 

Thanks,
Mads Hartmann

Mads Hartmann Jensen

unread,
Aug 4, 2012, 4:56:44 PM8/4/12
to lif...@googlegroups.com
Sorry, I accidentally hit the post button :) The sentence was going to be: 

I want to test the effect a POST request has on a SessionVar. 

Mads Hartmann Jensen

unread,
Aug 5, 2012, 5:52:10 AM8/5/12
to lif...@googlegroups.com
Here's a basic Lift project that has one snippet (Sample.scala) with a form that sets a SessionVar when a POST request is made. It also has a Spec (PostSpec.scala). 

In SBT run 

> container:start

and see that the form works. Stop the container again and run 

> test

to see that it doesn't seem to perform the POST request.. or at least the SessionVar isn't being set as expected. 

It might be important to note that I'm using WebSpec2 (found here https://gist.github.com/2235088) so I can write the spec using specs2. 

Thanks, 
Mads Hartmann Jensen
WebSpecPost.zip

Diego Medina

unread,
Aug 5, 2012, 2:12:38 PM8/5/12
to lif...@googlegroups.com
alright, I got it working, but not using withPost()

see
https://gist.github.com/3266477

But, this uses a plain parameter, which I try to avoid as much as
possible, because it then opens up the possibility to send your server
you don't really expect (replay attack, etc.
So far I only allow using S.param on search pages, where there is no
risk if anyone on the net gets those results.

P.S.1 It is easier when you post a git repo, than a zip file :)
P.S.2 Now I'll try to convert the example to use Lift plumbing (but
don't hold your breath for that one

Regards,

Diego
> --
> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you:
> https://www.assembla.com/wiki/show/liftweb/Posting_example_code
>
>
>



--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com

Mads Hartmann Jensen

unread,
Aug 5, 2012, 2:41:12 PM8/5/12
to lif...@googlegroups.com
Thanks!

I only used a plain parameter to make it easier to
show that the test was failing :) Otherwise I would need to
get the generated UUID every time to make the correct
POST request.

Diego Medina

unread,
Aug 5, 2012, 2:50:26 PM8/5/12
to lif...@googlegroups.com
On Sun, Aug 5, 2012 at 2:41 PM, Mads Hartmann Jensen <mad...@gmail.com> wrote:
> Thanks!
>
> I only used a plain parameter to make it easier to
> show that the test was failing :) Otherwise I would need to
> get the generated UUID every time to make the correct
> POST request.

So, I'm trying with the UUId now, and I remembered how Lift does not
change the UUID of fields during test mode, they are stable, as long
as you don;t add more fields to your snippet, but for a soimple
example, we can say they are always the same.

But, just replacing the names text for the UUID (in my case it is
f00000000100000000_75d55eb9b447d5eb17b5021ebceb8124ba1e0046

does not seem to work, I get the request posted, but the associated
function is not being called, so my snippet now is:

"#result *" #> Result.is.getOrElse("Nothing entered yet") &
"#text" #> SHtml.text("", s=> Result(Some(s))) &
"type=submit" #> SHtml.onSubmitUnit(process)


I'll keep trying a few different things to see what works, and I'll
post back if I get it to work.

Thanks for the question though, I have been meaning to look at this
for a while, and getting a question on the list is always a good
excuse to work on Lift :)

Diego

Mads Hartmann Jensen

unread,
Aug 5, 2012, 4:35:52 PM8/5/12
to lif...@googlegroups.com
The thing I'm trying to create a test for is actually my formlet implementation (https://github.com/mads379/scala-formlets)
where the names are available so the code you've given me is good enough for my use (trying it out now) :)

But creating an example that shows how to test a normal snippet that is using SHtml stuff seems like a pretty important thing so keep up the work :)

Thanks,
Mads

Mads Hartmann Jensen

unread,
Aug 5, 2012, 6:04:09 PM8/5/12
to lif...@googlegroups.com
I think I know what we need to do this. In my case (and in yours as well I reckon) we need to
first submit a GET request to the url. This will invoke the snippet which sets up the handlers
etc. for the session. Then we need to perform the POST request with the UUID of the handler
as part of the parameters so the function will be invoked.

The first part can be done using `withTemplateFor`. It seems to correctly invoke the snippet.
It's the second part I can't quite get to work.

I've checked that both my request are running sequentially and sharing the same session
so I'm not sure why I can't get it to work ;)

/Mads

Mads Hartmann Jensen

unread,
Aug 5, 2012, 6:33:48 PM8/5/12
to lif...@googlegroups.com
Okay so in my case the session is the same but they don't seem to share S.functionMap.

Mads Hartmann Jensen

unread,
Aug 5, 2012, 6:55:49 PM8/5/12
to lif...@googlegroups.com
I think if we figure out how to preserve S.functionMap between the tests then
we've nailed it.

See example here that shows it doesn't currently do so
https://github.com/mads379/scala-formlets/blob/master/src/test/scala/com/sidewayscoding/formlets/LiftBackendSpec.scala


Diego Medina

unread,
Aug 5, 2012, 7:55:07 PM8/5/12
to lif...@googlegroups.com

I'll try a few things later tonight.

Thanks

Diego
Sent from my android cell

Derek Chen-Becker

unread,
Aug 6, 2012, 2:06:58 PM8/6/12
to lif...@googlegroups.com
Right now setting your own S isn't supported (see MockWeb.realTestS), but it wouldn't be hard to expose something that allows you to pass in your own S and share it across tests.

Derek

Diego Medina

unread,
Aug 6, 2012, 2:27:28 PM8/6/12
to lif...@googlegroups.com
On Mon, Aug 6, 2012 at 2:06 PM, Derek Chen-Becker <dchen...@gmail.com> wrote:
> Right now setting your own S isn't supported (see MockWeb.realTestS), but it
> wouldn't be hard to expose something that allows you to pass in your own S
> and share it across tests.

It's great to see you on the list again (even if for a short time).

Do you mean that instead of having

private def realTestS [T](newSession : Box[LiftSession])(f : () =>
T)(req : Req) : T = {
val session = newSession openOr LiftSession(req)
S.init(req, session) {
f()
}
}


we would run

S.init(req, session) {
f()
}

in our tests and pass that around from test to test? (I may be totally
off, because I still don;t know how S is an object, but we somehow can
init it per session.)

Thanks

Diego


>
> Derek
>
>
> On Sunday, August 5, 2012 4:55:49 PM UTC-6, Mads Hartmann Jensen wrote:
>>
>> I think if we figure out how to preserve S.functionMap between the tests
>> then
>> we've nailed it.
>>
>> See example here that shows it doesn't currently do so
>>
>> https://github.com/mads379/scala-formlets/blob/master/src/test/scala/com/sidewayscoding/formlets/LiftBackendSpec.scala
>>
>>

Mads Hartmann Jensen

unread,
Aug 6, 2012, 2:56:06 PM8/6/12
to lif...@googlegroups.com
That would be wonderful. Would you have time to do so? :) 

Derek Chen-Becker

unread,
Aug 6, 2012, 3:23:59 PM8/6/12
to lif...@googlegroups.com
Actually, your question reminded me of some things. IIRC, S is an object with a ThreadLocal storage, and I think that the functionMap is with the session, not S per se. If that's the case, you could just use withSFor with the appropriate args (using one of the overloads that can pass in a LiftSession), and have it use the same function map.

Derek

Derek Chen-Becker

unread,
Aug 6, 2012, 3:30:19 PM8/6/12
to lif...@googlegroups.com
Yeah, just had a quick look at LiftSession:

https://github.com/lift/framework/blob/master/web/webkit/src/main/scala/net/liftweb/http/LiftSession.scala

Line 1044. Can you try creating a session outside of your Spec's examples and using withSFor(testUrl, <shared session>) instead of withReqFor(testUrl) and see if that works?

Thanks,

Derek

Mads Hartmann Jensen

unread,
Aug 8, 2012, 11:14:03 AM8/8/12
to lif...@googlegroups.com

Derek Chen-Becker

unread,
Aug 8, 2012, 1:26:52 PM8/8/12
to lif...@googlegroups.com
I would have thought so, but honestly I've need away from this long enough that I may be missing something obvious here. I don't have any time to look into this right now, but I think the first step would be to determine whether or not that function map init is actually occurring.

Derek
Reply all
Reply to author
Forward
0 new messages