How to mock Pusher with RSpec in Ruby? - ruby

Currently using Pusher and RSpec.
Pusher.should_receive( :trigger ).with( 'message', { :data => '12345' })
This would work, except the call is Pusher[ 'channel-id' ].trigger...
How to mock this with RSpec?

Well [] is a function name so it can be stubbed. In the Pusher source you see: def_delegators :default_client, :webhook, :channel, :[] So all of these methods are forwarded to default_client. So this is actually a chain of methods.
I would do what you want to do like this.
mock_client = mock('client')
Pusher.stub(:[]).with('channel-id').and_return(mock_client)
mock_client.should_receive( :trigger ).with( 'message', { :data => '12345' })
I do not have rspec handy right now, but see no reason why it would not work.

Newer versions of Pusher support a shallower API that is easier to stub:
expect(Pusher).to receive(:trigger).with("channel-id", "message", { data: "12345" })
Pusher.trigger("channel-id", "message", { data: "12345" })

There is also pusher-fake which starts up a fake server for your tests, so you don't have to stub – it lets your app both send and receive via that fake server.

Michael Papile's answer is essentially correct. Here's the code I used:
Pusher.stub_chain( :[] , :trigger )
Pusher[ channel_id ].should_receive( :trigger ).with( 'message', { :data => '12345' })
Actually, it turns out this code does not work because it does not match channel_id.

Related

Sending dynamic content sms with twilio

I am using Twilio SMS service for one of my projects it is in Ruby. In this, I want to send SMS with dynamic values like for example Hi, {{name}} in this name attributes will be dynamic. I have gone through the documentation but I am not able to figure it out how can I achieve this. I am using the ruby Twilio client library. However, I can send normal plan text SMS with it but not SMS having dynamic contents.
My current code is
#connection = Twilio::REST::Client.new(#account_sid, #auth_token)
#connection.messages.create({
:from => options.fetch(:from),
:to => options.fetch(:to),
:body => options.fetch(:body)
})
def welcome_message(name)
"Hi, #{name}! welcome to our website."
end
And when you're passing the options:
options = {
from: someone,
to: someone,
body: welcome_message(some_name),
}
Then the same snippet you shared:
#connection = Twilio::REST::Client.new(#account_sid, #auth_token)
#connection.messages.create({
:from => options.fetch(:from),
:to => options.fetch(:to),
:body => options.fetch(:body)
})

How to send MKCOL in Faraday?

In ruby built-in library Net::HTTP it's possible. In the code of Faraday there's no mention of MKCOL anywhere.
How to send MKCOL in Faraday?
There seems to be a filter on the allowed http methods:
https://github.com/lostisland/faraday/blob/v0.15.3/lib/faraday/connection.rb#L15
You can make a call by doing:
Faraday::Connection::METHODS << :mkcol
f = Faraday.new('http://localhost:3000')
f.run_request(:mkcol, '/mypath', { 'param-foo' => 'test' }, { 'X-fake-header' => 'test' })

FIWARE keyrock oauth callback - ruby

I am trying to implement/use Fiware Keyrock for authentization. Is there any tutorial/webinar on how to do it. Anyone does this ? It requires callbackurl and url of application of oauth, how to implement this in my rails application that it would communicate with keyrock (IDM). Any help is greatly appreciated, Thank you.
I have done this using the omniauth gem and using oauth2. There are several tutorials for using omniauth. You can first try another provider, like twitter.
I have created a "strategy" like this and placed it into /lib/omni_auth/strategies/filab_strategy.rb
require 'omniauth-oauth2'
module OmniAuth
module Strategies
class FilabStrategy < OmniAuth::Strategies::OAuth2
option :name, "filab"
option :client_options, {
:site => 'https://account.lab.fiware.org',
:authorize_url => 'https://account.lab.fiware.org/oauth2/authorize',
:token_url => 'https://account.lab.fiware.org/oauth2/token'
}
uid { raw_info['id'].to_s }
info do
{
'nickname' => raw_info['nickName'],
'displayName' => raw_info['displayName'],
'email' => raw_info['email'],
'name' => raw_info['displayName'],
}
end
extra do
{:raw_info => raw_info}
end
def raw_info
access_token.options[:mode] = :query
#raw_info ||= access_token.get('user.json', params: { access_token: access_token.token }).parsed
end
end
end
end
Then I configured and it the same way other more mainstream strategies are configured.

Mocking methods in Puppet rspec tests

I've implemented a custom Puppet function that queries a Keystone server for information. The module that defines this function includes some helper methods that perform the actual work of querying keystone. Broadly, the structure looks like this:
def authenticate(auth_url, username, password)
...
end
def list_tenants(auth_url, token)
...
end
module Puppet::Parser::Functions
newfunction(:lookup_tenant, :type => :rvalue) do |args|
...
end
end
I would like to mock out the authenticate and list_tenants methods
during testing so that I can test the rest of the Puppet module in the
absence of an actual Keystone server.
I haven't previously worked with either Ruby or Rpsec before, and I'm
having a hard time finding examples of how to provide stubs for these
internal methods.
So far I have a stub rspec file that simply verified the existence of
the function:
require 'spec_helper'
describe 'lookup_tenant' do
it "should exist" do
Puppet::Parser::Functions.function("lookup_tenant").should == "function_lookup_tenant"
end
# This will fail because there is no keystone server.
it "should fail" do
should run.with_params(
'http://127.0.0.1:35357/v2.0',
'admin_user',
'admin_password',
'admin_tenant_name',
'target_tenant_name'
).and_raise_error(KeystoneError)
end
end
I would like to be able to provide custom returns from the
authenticate and list_tenants methods (or even raise exceptions
from inside these methods) so that I can test the behavior of the
lookup_tenant function in different failure scenarios.
WebMock could be used for simulating the http requests as stubs. Here is the link to the github repo: https://github.com/bblimke/webmock
For folks who haven't seen webmock before, I wanted to leave some information here about why it's particularly awesome.
So, I have in my module some code that makes an http request:
url = URI.parse("#{auth_url}/tokens")
req = Net::HTTP::Post.new url.path
req['content-type'] = 'application/json'
req.body = JSON.generate(post_args)
begin
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
if res.code != '200'
raise KeystoneError, "Failed to authenticate to Keystone server at #{auth_url} as user #{username}."
end
rescue Errno::ECONNREFUSED
raise KeystoneError, "Failed to connect to Keystone server at #{auth_url}."
end
By simply adding a require to the start of the spec file:
require `webmock`
Attempts to open a connection will result in:
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: POST http://127.0.0.1:35357/v2.0/tokens with body '{"auth":{"passwordCredentials":{"username":"admin_user","password":"admin_password"},"tenantName":"admin_tenant"}}' with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
You can stub this request with the following snippet:
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
with(:body => "{\"auth\":{\"passwordCredentials\":{\"username\":\"admin_user\",\"password\":\"admin_password\"},\"tenantName\":\"admin_tenant\"}}",
:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => "", :headers => {})
And that's just about all the information you need to stub out the
call. You can make the stubs as granular as necessary; I ended up
using something like:
good_auth_request = {
'auth' => {
'passwordCredentials' => {
'username' => 'admin_user',
'password' => 'admin_password',
},
'tenantName' => 'admin_tenant',
}
}
auth_response = {
'access' => {
'token' => {
'id' => 'TOKEN',
}
}
}
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
with(:body => good_auth_request.to_json).
to_return(:status => 200, :body => auth_response.to_json, :headers => {})
And now I can test my module when there is no Keystone server
available.

Specify token options for OmniAuth OAuth2 based strategy

I'm creating custom strategy for Nimble.com API. As they're using OAuth, it's pretty simple.
require 'omniauth-oauth2'
module OmniAuth
module Strategies
class Nimble < OmniAuth::Strategies::OAuth2
option :name, "nimble"
option :client_options, {
:site => "https://api.nimble.com",
:authorize_url => '/oauth/authorize',
:token_url => '/oauth/token'
}
# option :access_token_options, {
# :mode => :query,
# :param_name => :access_token
# }
option :provider_ignores_state, true
uid { raw_info['email'] }
info do
{
'uid' => raw_info['email'],
'name' => raw_info['name'],
'email' => raw_info['email']
}
end
extra do
{ 'raw_info' => raw_info }
end
def raw_info
access_token.options[:mode] = :query
access_token.options[:param_name] = :access_token
#raw_info ||= access_token.get('/api/users/myself/', {:parse => :json}).parsed
end
end
end
end
For passing tokens, they need to use access_token parameter in URL. When I specify options in raw_info function directly, as in sample — it's OK.
When I'm trying to specify this options in access_token_options hash (like in commented section) — parameters aren't passing to token. I'm not very good in Ruby, so I didn't figure out from libraries sources — how correctly pass parameters to access_token in OmniAuth OAuth2 descendants.
I'd like to make it "right way", so access_token initialised with correct options, plese someone point me the right way.
Thank you!
I've explored several existing strategies (GitHub, 4SQ), and looks like it's normal practice to directly modify access token options.
So I'll stay with it :)

Resources