ngauthier / tubesock

Websocket interface on Rack Hijack w/ Rails support
MIT License
622 stars 46 forks source link

[rails] testing tubesock endpoints? #49

Open depili opened 8 years ago

depili commented 8 years ago

I was wondering if there is any known way to write tests for the websocket endpoints? Mainly would like to check that incoming messages trigger proper actions and send responses back on the socket.

If someone can point me towards the right direction I'm willing to then submit some examples to the tubesock readme when I get my tests up.

ngauthier commented 8 years ago

Hm, that would be tricky. Perhaps in an integration test (a.k.a. request spec or acceptance spec) it's possible to access the rack test driver's socket from capybara?

Or perhaps we could look at rails controller tests to see if we can inject our own rack env?

Or maybe we need to go all the way and run the app on a hijack compatible server and send it actual requests. On Nov 18, 2015 7:29 AM, "depili" notifications@github.com wrote:

I was wondering if there is any known way to write tests for the websocket endpoints? Mainly would like to check that incoming messages trigger proper actions and send responses back on the socket.

If someone can point me towards the right direction I'm willing to then submit some examples to the tubesock readme when I get my tests up.

— Reply to this email directly or view it on GitHub https://github.com/ngauthier/tubesock/issues/49.

depili commented 8 years ago

Figured one way that might work fine; modify the Tubesock.hijack in the test environment so that it yields a object that in turn first yields the wanted test message with .onmessage, stores the response sent out by .send_data and then runs the .onclose block. This should give a nice entrypoint for injecting the wanted test messages.

depili commented 8 years ago

https://gist.github.com/depili/0404aa8bd2e65255c91a This looks promising, as I'm now able to successfully inject a message from the test case.

It still lacks taking care of the missing response template: TubesockControllerTest#test_hello?: ActionView::MissingTemplate: Missing template tubesock/general

And also lacks capturing any outgoing trafic etc. but this seems really promising.

What I'm doing is adding the hijack method from the TestTubesock module in test_helper to the controller under test and thus getting the hijack call to yield TestSocket object that will just emit the single message.

One thing that this approach relies on is that the action defines its onmessage hook before its onclose hook, as they are just executed when defined.

depili commented 8 years ago

Refined the approach quite much, results are in https://github.com/iskcrew/isk/blob/tubesock/test/test_tubesock.rb and usage can be seen in https://github.com/iskcrew/isk/blob/tubesock/test/controllers/tubesock_controller_test.rb

Still need to make a mechanism of catching redis.publish events in the tests to check that appropriate events trigger notifications on websocket clients. I will leave the redis.subscribe -> send_data portition of the controller actions untested for now, since testing that would require running the controller action in a thread and there is no complex logic there anyway to test.

I can make a pull request on the chat demo app to add tests to it after I tackle the redis messages if you like, to give an example on how to write tests for tubesocks.