Files
timeoverflow/spec/controllers/offers_controller_spec.rb
2025-03-23 16:49:27 +01:00

284 lines
7.8 KiB
Ruby

RSpec.describe OffersController, type: :controller do
let(:organization) { Fabricate(:organization) }
let(:member) { Fabricate(:member, organization: organization) }
let(:another_member) { Fabricate(:member, organization: organization) }
let(:yet_another_member) { Fabricate(:member) }
let(:test_category) { Fabricate(:category) }
let!(:offer) do
Fabricate(:offer,
user: member.user,
organization: organization,
category: test_category)
end
let!(:other_offer) do
Fabricate(:offer,
user: another_member.user,
organization: organization,
category: test_category)
end
describe "GET #index" do
context "with a logged user" do
before { login(another_member.user) }
it "populates an array of offers" do
get :index
expect(assigns(:offers)).to eq([other_offer, offer])
end
context "when one offer is not active" do
before do
other_offer.active = false
other_offer.save!
end
it "only returns active offers" do
get :index
expect(assigns(:offers)).to eq([offer])
end
end
context "when one offer's user is not active" do
before do
member.active = false
member.save!
end
it "only returns offers from active users" do
get :index
expect(assigns(:offers)).to eq([other_offer])
end
end
end
context "with another organization" do
it "skips the original org's offers" do
login(yet_another_member.user)
get :index
expect(assigns(:offers)).to eq([])
end
end
end
describe "GET #index (search)" do
before do
login(another_member.user)
offer.title = "Queridos compañeros"
offer.save!
end
it "populates an array of offers" do
get :index, params: { q: 'compañeros' }
expect(assigns(:offers)).to eq([offer])
end
it "allows to search by partial word" do
get :index, params: { q: 'compañ' }
expect(assigns(:offers)).to eq([offer])
end
it "applies organization filter if passed" do
get :index, params: { q: offer.title, org: 2 }
expect(assigns(:offers)).to eq([])
end
context "when one offer is not active" do
before do
other_offer.active = false
other_offer.save!
end
it "only returns active offers" do
login(another_member.user)
get :index
expect(assigns(:offers)).to eq([offer])
end
end
context "when one offer's user is not active" do
before do
member.active = false
member.save!
end
it "only returns offers from active users" do
login(another_member.user)
get :index
expect(assigns(:offers)).to eq([other_offer])
end
end
end
describe 'GET #show' do
context 'when the user is logged in' do
before { login(another_member.user) }
context 'when the requested offer' do
context 'is not active' do
before do
offer.active = false
offer.save!
end
it 'renders the 404 page' do
get :show, params: { id: offer.id }
expect(response.status).to eq(404)
end
end
context 'is active' do
context 'and the user that created the offer is not active anymore' do
before do
member.active = false
member.save!
end
it 'renders the 404 page' do
get :show, params: { id: offer.id }
expect(response.status).to eq(404)
end
end
context 'and the user that created the offer is active' do
it 'renders a successful response' do
get :show, params: { id: offer.id }
expect(response.status).to eq(200)
end
it 'assigns the requested offer to @offer' do
get :show, params: { id: offer.id }
expect(assigns(:offer)).to eq(offer)
end
it 'assigns the account destination of the transfer' do
get :show, params: { id: offer.id }
expect(assigns(:destination_account)).to eq(member.account)
end
end
end
end
context 'when the user pertains to multiple organizations' do
context 'and user\'s current organization is different than offer\'s organization' do
let(:another_organization) { Fabricate(:organization) }
before do
Fabricate(:member, user: another_member.user, organization: another_organization)
allow(controller).to receive(:@current_organization).and_return(another_organization)
end
it 'sets the offer\'s organization as user\'s current organization' do
get :show, params: { id: offer.id }
expect(session[:current_organization_id]).to eq(offer.organization_id)
expect(assigns(:current_organization)).to eq(offer.organization)
end
end
end
end
context 'when the user is not a member of the organization where the offer is published' do
let(:another_user) { Fabricate(:user) }
before { login(another_user) }
end
context 'when the user is not logged in' do
it 'assigns the requested offer to @offer' do
get :show, params: { id: offer.id }
expect(assigns(:offer)).to eq(offer)
end
end
end
describe "POST #create" do
context "with valid params" do
context "with a logged user" do
it "creates a new offer" do
login(another_member.user)
expect do
post "create", params: { offer: { user: another_member.user,
category_id: test_category,
title: "New title" } }
end.to change(Offer, :count).by(1)
end
end
end
end
describe "PUT #update" do
context "with valid params" do
context "with a logged user" do
it "located the requested @offer" do
login(member.user)
put "update", params: { id: offer.id, offer: Fabricate.to_params(:offer) }
expect(assigns(:offer)).to eq(offer)
end
it "changes @offer's attributes" do
login(member.user)
put "update", params: { id: offer.id, offer: Fabricate.to_params(:offer,
user: member,
title: "New title",
description: "New description",
tag_list: ["foo"]) }
offer.reload
expect(offer.title).to eq("New title")
expect(offer.description).to eq("New description")
expect(offer.tags).to include("foo")
end
end
end
context "with invalid params" do
context "with a logged user" do
it "does not change @offer's attributes" do
login(member.user)
put :update, params: { id: offer.id, offer: Fabricate.to_params(:offer,
user: nil,
title: "New title",
description: "New description") }
expect(offer.title).not_to eq("New title")
expect(offer.description).not_to eq("New description")
end
end
end
end
describe "DELETE destroy" do
it "toggle active field" do
login(member.user)
delete :destroy, params: { id: offer.id }
offer.reload
expect(offer.active).to be false
end
it "redirects to offers#index" do
login(member.user)
delete :destroy, params: { id: offer.id }
expect(response).to redirect_to offers_url
end
end
end