Skip to content

Instantly share code, notes, and snippets.

@rasmar
Last active February 23, 2018 15:52
Show Gist options
  • Save rasmar/9bef73d5aae964b3769efbd1e619f40e to your computer and use it in GitHub Desktop.
Save rasmar/9bef73d5aae964b3769efbd1e619f40e to your computer and use it in GitHub Desktop.
Juniorship - specs
# frozen_string_literal: true
require "rails_helper"
describe OAuthServices::Create::CreateUserViaFacebook do
describe "#call" do
let(:id) { rand(100000..999999).to_s }
let(:email) { "john.doe@example.com" }
let(:languages) { [{ id: "106059522759137", name: "English" }] }
let(:photo_url) { "#{provider_api_url}#{id}/#{provider_api_silhouette_suffix}" }
let(:photo_check_url) { "#{provider_api_url}#{id}/#{provider_api_silhouette_check_suffix}" }
let(:provider_api_url) { Rails.application.secrets.facebook_api_url }
let(:provider_api_silhouette_check_suffix) do
Rails.application.secrets.facebook_api_silhouette_check_suffix
end
let(:provider_api_silhouette_suffix) do
Rails.application.secrets.facebook_api_silhouette_suffix
end
let(:params) do
{
id: id,
email: email,
first_name: "John",
last_name: "Doe",
gender: "male",
birthday: "08/01/1990",
languages: languages,
}
end
let(:stub_photo_check_request) do
stub_request(:get, photo_check_url)
.with(
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"Host" => "graph.facebook.com",
"User-Agent" => "Ruby",
},
)
.to_return(
status: 200,
body: returned_body,
headers: {},
)
end
let(:stub_photo_request) do
stub_request(:get, photo_url)
.with(
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"User-Agent" => "Ruby",
},
)
.to_return(
status: 200,
body: File.new("spec/fixtures/files/stubbed_silhouette.jpg"),
headers: {
"content-type" => "image/jpeg",
},
)
end
subject { described_class.call(params) }
before do
stub_photo_check_request
stub_photo_request
end
context "when user_data with silhouette photo is passed" do
let!(:returned_body) { { "data" => { "is_silhouette" => true } }.to_json }
it "creates user without photo" do
expect { subject }.to change(User, :count).by(1)
expect(User.last.photos.length).to be 0
end
end
context "when user_data with real photo is passed" do
let!(:returned_body) { { "data" => { "is_silhouette" => false } }.to_json }
it "creates user with photo" do
expect { subject }.to change(User, :count).by(1)
expect(User.last.photos.length).to be 1
end
end
context "when valid user_data is passed" do
let!(:returned_body) { { "data" => { "is_silhouette" => true } }.to_json }
let(:user) { User.find_by(email: email) }
it "returns new, created user" do
expect { subject.data[:user] }.to change(User, :count).by(1)
result = subject.data[:user]
expect(result).to eq(user)
expect(result.languages).to eq ["EN"]
expect(result.date_of_birth).to eq Date.new(1990, 8, 1)
expect(result.gender).to eq "male"
end
end
end
end
# frozen_string_literal: true
require "rails_helper"
describe OAuth::ExternalAuthorize::Facebook do
describe "#get_user!" do
let(:auth_code) { SecureRandom.hex(20) }
let(:provider_api_url) do
Rails.application.secrets.facebook_api_url +
Rails.application.secrets.facebook_api_user_suffix
end
let(:request_url) { "#{provider_api_url}access_token=#{auth_code}" }
let(:request_params) { "&fields=id,email,first_name,last_name,gender,birthday,languages" }
let(:stub_user_data_request) do
stub_request(:get, request_url + request_params)
.with(
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"Host" => "graph.facebook.com",
"User-Agent" => "Ruby",
},
)
.to_return(
status: 200,
body: response_body.to_json,
headers: {},
)
end
before do
stub_user_data_request
end
subject { described_class.new(auth_code) }
context "when invalid auth_code passed" do
let(:response_body) do
{
error: {
message: "Unauthorized",
},
}
end
it "raises ProviderError" do
expect(OAuthServices::Authorize::AuthorizeViaFacebook).to_not receive(:call)
expect { subject.get_user! }.to raise_error(OAuth::CustomErrors::ProviderError)
end
end
context "when valid auth_code passed" do
let(:id) { rand(100000..999999).to_s }
let(:email) { "john.doe@example.com" }
let(:response_body) do
{
id: id,
email: email,
first_name: "John",
last_name: "Doe",
gender: "male",
birthday: "08/01/1990",
languages: [{ id: "106059522759137", name: "English" }],
}
end
let(:user) do
build(
:user,
email: response_body[:email],
first_name: response_body[:first_name],
last_name: response_body[:last_name],
)
end
let(:success) do
Result::Success.new(data: { user: user })
end
before do
allow(OAuthServices::Authorize::AuthorizeViaFacebook).to receive(:call).and_return(success)
end
context "when not enough data in response" do
let(:response_body) do
{
id: id,
email: email,
}
end
it "raises MissingProviderDataError" do
expect { subject.get_user! }.to raise_error(OAuth::CustomErrors::MissingProviderDataError)
end
end
it "returns user" do
expect(OAuthServices::Authorize::AuthorizeViaFacebook).to receive(:call)
expect(subject.get_user!).to eq user
end
end
end
end
# frozen_string_literal: true
require "rails_helper"
describe DeviseOverrides::PasswordsController, type: :request do
describe "POST /admin/password" do
let(:valid_email) { "valid@example.com" }
let!(:user) { create(:user, email: valid_email) }
let(:front_url) { Rails.application.secrets.frontend_host }
subject do
post "/admin/password", params: params, headers: headers
end
context "invalid email" do
let(:invalid_email) { "invalid@example.com" }
let(:params) { { user: { email: invalid_email } } }
let(:recover_url) { front_url + "/recover-password" }
let(:recover_regexp) { Regexp.new(recover_url + ".*") }
it_behaves_like "303"
it_behaves_like "redirect with error"
it "redirects to front::/recover-password" do
subject
expect(response.location).to match(recover_regexp)
end
end
context "valid email" do
let(:params) { { user: { email: valid_email } } }
let(:front_root_regexp) { Regexp.new(front_url + ".*") }
it_behaves_like "303"
it_behaves_like "redirect with notice"
it "redirects to front::/root" do
subject
expect(response.location).to match(front_root_regexp)
end
end
end
describe "PUT /admin/password" do
let(:valid_passwords) { { password: "password", password_confirmation: "password" } }
let(:invalid_passwords) { { password: "password", password_confirmation: "password123" } }
let!(:reset_tokens) { Devise.token_generator.generate(User, :reset_password_token) }
let!(:original_token) { reset_tokens.first }
let!(:encrypted_token) { reset_tokens.last }
let(:front_url) { Rails.application.secrets.frontend_host }
let!(:user) do
create(:user, reset_password_token: encrypted_token, reset_password_sent_at: Time.now.utc)
end
let(:params) do
{
user: {
reset_password_token: token,
password: password,
password_confirmation: password_confirmation,
},
}
end
subject do
put "/admin/password", params: params, headers: headers
end
context "invalid params reset_password_token or passwords" do
let(:recover_url) { front_url + "/recover-password" }
let(:recover_regexp) { Regexp.new(recover_url + ".*") }
context "invalid reset_password_token" do
let(:token) { SecureRandom.hex(8) }
let(:password) { valid_passwords[:password] }
let(:password_confirmation) { valid_passwords[:password_confirmation] }
it_behaves_like "303"
it_behaves_like "redirect with error"
it "redirects to front::/recover-password" do
subject
expect(response.location).to match(recover_regexp)
end
end
context "invalid passwords" do
let(:token) { original_token }
let(:password) { invalid_passwords[:password] }
let(:password_confirmation) { invalid_passwords[:password_confirmation] }
it_behaves_like "303"
it_behaves_like "redirect with error"
it "redirects to front::/recover-password" do
subject
expect(response.location).to match(recover_regexp)
end
end
end
context "valid password and reset_password_token" do
let(:token) { original_token }
let(:password) { valid_passwords[:password] }
let(:password_confirmation) { valid_passwords[:password_confirmation] }
let(:login_url) { front_url + "/login" }
let(:login_regexp) { Regexp.new(login_url + ".*") }
it_behaves_like "303"
it_behaves_like "redirect with notice"
it "redirects to front::/login" do
subject
expect(response.location).to match(login_regexp)
end
it "changes user's password" do
subject
expect(user.reload.valid_password?(password)).to be true
end
end
end
end
# frozen_string_literal: true
require "rails_helper"
describe RemoveIncompleteOpportunitiesJob, type: :job do
include ActiveJob::TestHelper
subject { described_class }
it "enqueues the job" do
ActiveJob::Base.queue_adapter = :test
expect { subject.perform_later }.to have_enqueued_job(described_class)
end
describe "destroys opportunities" do
let!(:opportunity) { create(:opportunity, step_trait, updated_at: updated_at)}
shared_examples "destroys opportunity" do
it "destroys opportunity" do
subject.perform_now
expect(Opportunity.exists?(opportunity.id)).to eq false
end
end
shared_examples "doesn't destroy opportunity" do
it "doesn't destroy opportunity" do
subject.perform_now
expect(Opportunity.exists?(opportunity.id)).to eq true
end
end
context "opportunity updated more that 25 hours ago" do
let(:updated_at) { 25.hours.ago }
context "on information step" do
let(:step_trait) { :on_information_step }
it_behaves_like "destroys opportunity"
end
context "on location step" do
let(:step_trait) { :on_location_step }
it_behaves_like "destroys opportunity"
end
context "on schedule step" do
let(:step_trait) { :on_schedule_step }
it_behaves_like "destroys opportunity"
end
context "on completed step" do
let(:step_trait) { :completed }
end
end
context "opportunity updated in 24 hours" do
let(:updated_at) { 23.hours.ago }
context "on information step" do
let(:step_trait) { :on_information_step }
it_behaves_like "doesn't destroy opportunity"
end
context "on location step" do
let(:step_trait) { :on_location_step }
it_behaves_like "doesn't destroy opportunity"
end
context "on schedule step" do
let(:step_trait) { :on_schedule_step }
it_behaves_like "doesn't destroy opportunity"
end
context "on completed step" do
let(:step_trait) { :completed }
it_behaves_like "doesn't destroy opportunity"
end
end
context "multiple opportunities to destroy" do
let!(:opportunity2) { create(:opportunity, step_trait, updated_at: updated_at)}
let(:step_trait) { :on_information_step }
let(:updated_at) { 25.hours.ago }
it_behaves_like "destroys opportunity"
it "destroys second opportunity" do
subject.perform_now
expect(Opportunity.exists?(opportunity2.id)).to eq false
end
end
end
after do
clear_enqueued_jobs
clear_performed_jobs
end
end
shared_examples "303" do
it "responds with redirection status" do
subject
expect(response).to have_http_status(:see_other)
end
it "responds with proper body" do
subject
expect(response.body).to include("redirected")
end
end
shared_examples "redirect with error" do
let(:redirect_uri) { Addressable::URI.parse(response.location) }
it "redirects with error in params" do
subject
expect(redirect_uri.query_values).to include("error")
end
end
shared_examples "redirect with notice" do
let(:redirect_uri) { Addressable::URI.parse(response.location) }
it "redirects with notice in params" do
subject
expect(redirect_uri.query_values).to include("notice")
end
end
@tomajask
Copy link

  1. If you use multiple expects in one it block then use also :aggregate_failures -> https://relishapp.com/rspec/rspec-core/docs/expectation-framework-integration/aggregating-failures
  2. When you're testing Sidekiq jobs you can use inline option: https://github.com/mperham/sidekiq/wiki/Testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment