Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: refactors company controller policies and tests to include … #45

Merged
merged 2 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/controllers/api/v1/companies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ class CompaniesController < ApplicationController
before_action :authenticate_user

def index
companies = @current_user.companies

companies = policy_scope(@current_user.companies)
authorize companies
if companies.empty?
render json: { data: [], message: "No companies found" }
else
Expand All @@ -14,6 +14,7 @@ def index
end

def create
authorize Company
company = @current_user.companies.build(company_params)
if company.save
render json: CompanySerializer.new(company), status: :created
Expand All @@ -27,6 +28,8 @@ def create
def company_params
params.permit(:name, :website, :street_address, :city, :state, :zip_code, :notes)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not relevant for this PR, but I wanted to make note of this so we have it on the record. There is a discrepancy in how different controllers are handling params, I know that Contacts and JobApplications handle this private method as follow

def contact_params
  params.require(:contact).permit(:first_name, :last_name, :company_id, :email, :phone_number, :notes)
end
def job_application_params
  params.require(:job_application).permit(
      :position_title, 
      :date_applied, 
      :status, 
      :notes, 
      :job_description, 
      :application_url, 
      :contact_information, 
      :company_id
  )
end

Note the require(:model) in the case above. The Companies controller is only using params.permit.
I don't think its inherently wrong, and like I said it isn't explicitly related to this ticket but we should be aware of the inconsistency moving forward.

end


end
end
end
1 change: 1 addition & 0 deletions app/models/company.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Company < ApplicationRecord
rolify strict: true
belongs_to :user
validates :name, presence: true
validates :website, presence: true
Expand Down
27 changes: 18 additions & 9 deletions app/policies/company_policy.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
class CompanyPolicy < ApplicationPolicy
# NOTE: Up to Pundit v2.3.1, the inheritance was declared as
# `Scope < Scope` rather than `Scope < ApplicationPolicy::Scope`.
# In most cases the behavior will be identical, but if updating existing
# code, beware of possible changes to the ancestors:
# https://gist.github.com/Burgestrand/4b4bc22f31c8a95c425fc0e30d7ef1f5
def create?
user.present?
end

def index?
user.present?
end

stefanjbloom marked this conversation as resolved.
Show resolved Hide resolved
# record.user == user

class Scope < ApplicationPolicy::Scope
# NOTE: Be explicit about which records you allow access to!
# def resolve
# scope.all
# end
def resolve
return scope.none unless user

if admin?
scope.all
else
scope.where(user_id: user.id)
end
end
end
end
25 changes: 10 additions & 15 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 75 additions & 12 deletions spec/policies/company_policy_spec.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,90 @@
require 'rails_helper'

RSpec.describe CompanyPolicy, type: :policy do
let(:user) { User.new }

subject { described_class }

permissions ".scope" do
pending "add some examples to (or delete) #{__FILE__}"
let(:user) { User.create!(name: "user", email: "[email protected]", password: "123") }
let(:other_user) { User.create!(name: "other_user", email: "[email protected]", password: "234") }
let(:admin) { User.create!(name: "admin", email: "[email protected]", password: "456") }

let(:company) do
Company.create!(
name: "Test Company",
website: "https://testcompany.com",
street_address: "123 Main St",
city: "Testville",
state: "TS",
zip_code: "12345",
notes: "A test company",
user: user
)
end

let(:other_company) do
Company.create!(
name: "Other Company",
website: "https://othercompany.com",
street_address: "456 Elm St",
city: "Othertown",
state: "OT",
zip_code: "67890",
notes: "Another test company",
user: other_user
)
end

permissions :show? do
pending "add some examples to (or delete) #{__FILE__}"
before(:each) do
admin.set_role(:admin)
end

permissions :create? do
pending "add some examples to (or delete) #{__FILE__}"
end
it "allows any logged-in user to create a company" do
expect(subject).to permit(user, Company.new)
expect(subject).to permit(admin, Company.new)
end

permissions :update? do
pending "add some examples to (or delete) #{__FILE__}"
it "does not allow guests to create a company" do
expect(subject).not_to permit(nil, Company.new)
end
end

permissions :destroy? do
pending "add some examples to (or delete) #{__FILE__}"
permissions ".scope" do
let(:scope) { Pundit.policy_scope!(current_user, Company) }

context "when the user is an admin" do
let(:current_user) { admin }

it "returns all companies" do
company
other_company
expect(scope).to match_array(Company.all)
end
end

context "when the user is a regular user" do
let(:current_user) { user }

it "returns only the user's companies" do
company
other_company
expect(scope).to match_array([company])
end

it "does not return other users' companies" do
company
other_company
expect(scope).not_to include(other_company)
end
end

context "when no user is logged in" do
let(:current_user) { nil }

it "returns an empty relation" do
company
other_company
expect(scope).to match_array([])
end
end
end
end