How to implement token authorization using Ruby Rspec Please? - ruby

Friends, in my project below how do I get the authentication that is generated in the swagger apis?
If I have an api in swagger with the post method where I pass the username and password to generate this authentication and from the generated key I pass it as an argument in the api.
how I create this architecture. In my tests directory I have the apis, as you usually do?
require 'httparty'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.color_mode = true
config.before(:all) do
class HttParty
include HTTParty
base_uri 'https://testtesttestxxxxx/'
end
end
end
require 'httparty'
RSpec.describe 'Validar a api de usuários' do
it 'Deve retornar 200 para API Fichas - Corporativo' do
response = HttParty.get('/index.html')
expect(response.code).to eql(200)
p response.code
end
it 'O retorno não deve ser vazio' do
response = HttParty.get('/index.html')
expect(response.parsed_response).not_to be_empty
end
end

Related

How to test HTTParty API call with Ruby and RSpec

I am using the HTTParty gem to make a call to the GitHub API to access a list of user's repos.
It is a very simple application using Sinatra that displays a user's favourite programming language based on the most common language that appears in their repos.
I am a bit stuck on how I can write an RSpec expectation that mocks out the actual API call and instead just checks that json data is being returned.
I have a mock .json file but not sure how to use it in my test.
Any ideas?
github_api.rb
require 'httparty'
class GithubApi
attr_reader :username, :data, :languages
def initialize(username)
#username = username
#response = HTTParty.get("https://api.github.com/users/#{#username}/repos")
#data = JSON.parse(#response.body)
end
end
github_api_spec.rb
require './app/models/github_api'
require 'spec_helper'
describe GithubApi do
let(:github_api) { GithubApi.new('mock_user') }
it "receives a json response" do
end
end
Rest of the files for clarity:
results.rb
require 'httparty'
require_relative 'github_api'
class Results
def initialize(github_api = Github.new(username))
#github_api = github_api
#languages = []
end
def get_languages
#github_api.data.each do |repo|
#languages << repo["language"]
end
end
def favourite_language
get_languages
#languages.group_by(&:itself).values.max_by(&:size).first
end
end
application_controller.rb
require './config/environment'
require 'sinatra/base'
require './app/models/github_api'
class ApplicationController < Sinatra::Base
configure do
enable :sessions
set :session_secret, "#3x!ilt£"
set :views, 'app/views'
end
get "/" do
erb :index
end
post "/user" do
#github = GithubApi.new(params[:username])
#results = Results.new(#github)
#language = #results.favourite_language
session[:language] = #language
session[:username] = params[:username]
redirect '/results'
end
get "/results" do
#language = session[:language]
#username = session[:username]
erb :results
end
run! if app_file == $0
end
There are multiple ways you could approach this problem.
You could, as #anil suggested, use a library like webmock to mock the underlying HTTP call. You could also do something similar with VCR (https://github.com/vcr/vcr) which records the results of an actual call to the HTTP endpoint and plays back that response on subsequent requests.
But, given your question, I don't see why you couldn't just use an Rspec double. I'll show you how below. But, first, it would be a bit easier to test the code if it were not all in the constructor.
github_api.rb
require 'httparty'
class GithubApi
attr_reader :username
def initialize(username)
#username = username
end
def favorite_language
# method to calculate which language is used most by username
end
def languages
# method to grab languages from repos
end
def repos
repos ||= do
response = HTTParty.get("https://api.github.com/users/#{username}/repos")
JSON.parse(response.body)
end
end
end
Note that you do not need to reference the #username variable in the url because you have an attr_reader.
github_api_spec.rb
require './app/models/github_api'
require 'spec_helper'
describe GithubApi do
subject(:api) { described_class.new(username) }
let(:username) { 'username' }
describe '#repos' do
let(:github_url) { "https://api.github.com/users/#{username}/repos" }
let(:github_response) { instance_double(HTTParty::Response, body: github_response_body) }
let(:github_response_body) { 'response_body' }
before do
allow(HTTParty).to receive(:get).and_return(github_response)
allow(JSON).to receive(:parse)
api.repos
end
it 'fetches the repos from Github api' do
expect(HTTParty).to have_received(:get).with(github_url)
end
it 'parses the Github response' do
expect(JSON).to have_received(:parse).with(github_response_body)
end
end
end
Note that there is no need to actually load or parse any real JSON. What we're testing here is that we made the correct HTTP call and that we called JSON.parse on the response. Once you start testing the languages method you'd need to actually load and parse your test file, like this:
let(:parsed_response) { JSON.parse(File.read('path/to/test/file.json')) }
You can mock those API calls using https://github.com/bblimke/webmock and send back mock.json using webmock. This post, https://robots.thoughtbot.com/how-to-stub-external-services-in-tests walks you through the setup of webmock with RSpec (the tests in the post mock GitHub API call too)

testing padrino post methods are stopped by csrf

I have a padrino controller with a single post method and a single get method. I can use rack-test to test the get method but not the post method. When I am testing the request returns 403. I think this is because of padrino's built in csrf protection because when I comment out the line with set :protect_from_csrf, true I can test the post route. Obviously I don't want to comment out this line as csrf is useful. How can I get temporary access to test these routes for the purpose of testing?
Controller
SailPowerCourses::Admin.controllers :owners do
get :index do
puts 'hello'
end
post :index do
puts params
end
end
Test
class OwnersControllerTest < MiniTest::Test
def setup
app SailPowerCourses::Admin
end
def test_creates_an_owner
email = 'test#example.com'
assert_empty Owner
post '/owners', owner: {email: email}
puts last_response.status
refute_empty Owner
end
def test_other
email = 'test#example.com'
get '/owners', owner: {email: email}
end
end
```
When setting up an app in minitest you can use a block to access and change settings. such as csrf protection. I found the best solution to be the following. in test_config.rb I set up a version of the app with csrf protection off.
class OwnersControllerTest < MiniTest::Test
def setup
app SailPowerCourses::Admin do
set :protect_from_csrf, false
end
end
def test_creates_an_owner
email = 'test#example.com'
assert_empty Owner
post '/owners', owner: {email: email}
puts last_response.status
refute_empty Owner
end
def test_other
email = 'test#example.com'
get '/owners', owner: {email: email}
end
end

capybara +rspec: Post "/api/albums" not working

So I am trying to create an item using POST method. But it doesn't seem to post the item.
When I do get /api/albums seems to respond fine and my test passes.
/album_spec.rb:
describe AlbumController do
before :each do
#user =FactoryGirl.create(:person)
#album = FactoryGirl.create(:album)
end
it "creates first story on login", :js => true do
login(#user)
post "/api/albums/", :format => :api_v1,:album =>#album
response.should be_success
end
it "gets album", :js=> true do
get "api/albums/"
response.should be_success
end
end
spec_helper.rb:
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
require "capybara-screenshot"
require "factory_girl_rails"
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
#Capybara.defualt_wait_time = 10
if ENV['BROWSER_TEST']
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
else
Capybara.javascript_driver = :selenium
end
RSpec.configure do |config|
config.include Capybara::DSL
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
config.include RequestHelpers, :type => :request
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.infer_base_class_for_anonymous_controllers = false
end
end
Spork.each_run do
# This code will be run each time you run your specs.
FactoryGirl.reload
end
I found the solution for myself. In the album factory, I had to add more attributes to make sure that the #user and album.user match.
#album = FactoryGirl.create(:album,person_id=>#user.id)
And then my test case looked like this
it "creates first story on login"do
login_as #user
post "/api/albums/", :format =>":api_v1",:album =>#album.attributes
response.should be_success
a = Album.last
a.person_id.should == #user.id #verifying user_ids match end
end

Google API for Blogger 3.0 error

I am trying to run sample code in Ruby to fetch blog posts list using Google's APIs for Blogger 3.0. This is the code:
require 'rubygems'
require 'google/api_client'
require 'sinatra'
require 'google/api_client'
require 'logger'
enable :sessions
def logger; settings.logger end
def api_client; settings.api_client; end
def blogger_api; settings.blogger; end
def user_credentials
# Build a per-request oauth credential based on token stored in session
# which allows us to use a shared API client.
#authorization ||= (
auth = api_client.authorization.dup
auth.redirect_uri = to('/oauth2callback')
auth.update_token!(session)
auth
)
end
configure do
log_file = File.open('blogger.log', 'a+')
log_file.sync = true
logger = Logger.new(log_file)
logger.level = Logger::DEBUG
client = Google::APIClient.new
client.authorization.client_id = 'XXXXXXXXXXXXX'
client.authorization.client_secret = 'XXXXXXXXXXXXX'
client.authorization.scope = 'https://www.googleapis.com/auth/blogger'
blogger = client.discovered_api('blogger', 'v3')
set :logger, logger
set :api_client, client
set :blogger, blogger
end
before do
# Ensure user has authorized the app
unless user_credentials.access_token || request.path_info =~ /^\/oauth2/
redirect to('/oauth2authorize')
end
end
after do
# Serialize the access/refresh token to the session
session[:access_token] = user_credentials.access_token
session[:refresh_token] = user_credentials.refresh_token
session[:expires_in] = user_credentials.expires_in
session[:issued_at] = user_credentials.issued_at
end
get '/oauth2authorize' do
# Request authorization
redirect user_credentials.authorization_uri.to_s, 303
end
get '/oauth2callback' do
# Exchange token
user_credentials.code = params[:code] if params[:code]
user_credentials.fetch_access_token!
redirect to('/')
end
get '/' do
# Fetch list of posts
result = api_client.execute(:api_method => settings.blogger.posts.list, :parameters => {'blogId' => 'XXXXXXXXXXXXX'})
[result.status, {'Content-Type' => 'application/json'}, result.data.to_json]
end
When I connect to the running local application (after authorized it) I can see this "sinatra" error:
#<NameError: undefined local variable or method `blogger' for #<Sinatra::Application:0x92ac2dc>>
It is a bit obscure to me. Any idea?

Sinatra Mongoid String not valid UTF-8

I wrote this little application :
require 'rubygems'
require 'sinatra'
require 'bson'
require 'mongoid'
Mongoid.configure do |config|
name = "articles"
host = "localhost"
config.master = Mongo::Connection.new.db(name)
config.persist_in_safe_mode = false
end
class Article
include Mongoid::Document
field :title
field :content
end
get '/' do
#articles = Article.all
end
get '/show/:id' do
#article = Article.find(params[:id])
end
get '/new' do
haml :new
end
post '/create' do
#article = Article.new(params['article'])
if #article.save
redirect '/'
else
redirect '/new'
end
end
The following error occur when i post an article with a content "Test d'un article en français"
BSON::InvalidStringEncoding at /create String not valid UTF-8
How i can fix this error ?
Thanks
This is a known issue with Ruby 1.9 and Sinatra. Wait for Sinatra 1.1 to be released or use Sinatra edge version from github.

Resources