Skip to content

Commit

Permalink
Merge branch 'master' of github.com:rubyforgood/partner
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmarcia committed Nov 21, 2018
2 parents 396ffb2 + f2e9a78 commit c8658a8
Show file tree
Hide file tree
Showing 20 changed files with 239 additions and 25 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ gem "rails", "~> 5.2.1"
gem "sass-rails", "~> 5.0"
gem "turbolinks", "~> 5"
gem "uglifier", ">= 1.3.0"
gem "pundit", "~> 2.0.0"
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ GEM
pry (>= 0.10.4)
public_suffix (3.0.2)
puma (3.12.0)
pundit (2.0.0)
activesupport (>= 3.0.0)
rack (2.0.5)
rack-test (1.1.0)
rack (>= 1.0, < 3)
Expand Down Expand Up @@ -365,6 +367,7 @@ DEPENDENCIES
pry
pry-rails
puma (~> 3.11)
pundit (~> 2.0.0)
rails (~> 5.2.1)
rspec-rails (~> 3.5)
rubocop
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,14 @@ If you're getting the error `PG::ConnectionBad: fe_sendauth: no password supplie
## Seed the database
From the root of the app, run `bundle exec rails db:seed`. This will create some initial data to use while testing the app and developing new features, including setting up the default user.

To login, use these default credentials provided in the seeds:

Verified Organization
Email: [email protected]
Password: password

Pending Organization
Email: [email protected]
Password: password


10 changes: 10 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
class ApplicationController < ActionController::Base
include Pundit

rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

rescue_from ActiveRecord::RecordInvalid do |exception|
Rails.logger.error(exception.message)

Expand All @@ -15,4 +19,10 @@ class ApplicationController < ActionController::Base
def after_sign_out_path_for(*)
new_partner_session_path
end

private

def user_not_authorized
redirect_to(request.referrer || root_path, notice: "You are not authorized to perform this action.")
end
end
6 changes: 6 additions & 0 deletions app/controllers/partner_requests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ def create

def show
@partner_request = PartnerRequest.find(params[:id])
authorize @partner_request
end

private

def partner_request_params
params.require(:partner_request).permit(:comments, items_attributes: Item.attribute_names.map(&:to_sym).push(:_destroy))
end

# NOTE(chaserx): the is required for pundit since our auth'd user is named `partner`
def pundit_user
current_partner
end
end
10 changes: 9 additions & 1 deletion app/controllers/partners_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class PartnersController < ApplicationController
# GET /partners.json
def index
@partners = Partner.all
authorize @partners
end

# GET /partners/1
Expand Down Expand Up @@ -69,8 +70,10 @@ def destroy
private

# Use callbacks to share common setup or constraints between actions.
# NOTE(chaserx): pundit let's us authorize partner specific actions here as a
# convenience rather than in each of the partner specific methods
def set_partner
@partner = Partner.find(params[:id])
@partner = authorize Partner.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
Expand Down Expand Up @@ -154,4 +157,9 @@ def partner_params
documents: []
)
end

# NOTE(chaserx): the is required for pundit since our auth'd user is named `partner`
def pundit_user
current_partner
end
end
4 changes: 1 addition & 3 deletions app/models/partner_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ def export_json
end

def formatted_items_hash(items)
hsh = {}
items.each { |item| hsh[item.name] = item.quantity }
hsh
items.each_with_object({}) { |item, hsh| hsh[item.name] = item.quantity }
end
end
49 changes: 49 additions & 0 deletions app/policies/application_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class ApplicationPolicy
attr_reader :user, :record

def initialize(user, record)
@user = user
@record = record
end

def index?
false
end

def show?
false
end

def create?
false
end

def new?
create?
end

def update?
false
end

def edit?
update?
end

def destroy?
false
end

class Scope
attr_reader :user, :scope

def initialize(user, scope)
@user = user
@scope = scope
end

def resolve
scope.all
end
end
end
25 changes: 25 additions & 0 deletions app/policies/partner_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Authorization for CRUD actions on Partner using Pundit
#
# Pundit relies on current_user
# see `pundit_user` method in partners_controller
#
# Partners can only affect their own records.
# Later may want to admins authorization.
class PartnerPolicy < ApplicationPolicy
def create?
true
end

def show?
record == user
end

def update?
record == user
end

# TODO(chaserx): I think we should prevent deletion until we add a soft delete
def destroy?
false
end
end
19 changes: 19 additions & 0 deletions app/policies/partner_request_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Authorization for limited CRUD actions on Partner Requests using Pundit
#
# Pundit relies on current_user
# see `pundit_user` method in partner_requests_controller
#
# Partners can only view and create their own records.
class PartnerRequestPolicy < ApplicationPolicy
def index?
true
end

def create?
record.partner == user
end

def show?
record.partner == user
end
end
23 changes: 12 additions & 11 deletions app/services/diaper_bank_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,20 @@ def self.post(partner_id)
{ diaper_partner_id: partner_id } }

uri = URI(ENV["DIAPERBANK_APPROVAL_URL"])
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
req.body = partner.to_json
req["Content-Type"] = "application/json"
req["X-Api-Key"] = ENV["DIAPERBANK_KEY"]

response = https(uri).request(req)
response = https(uri).request(post_request(uri: uri, body: partner.to_json))

response.body
end

def self.request_submission_post(partner_request_id)
return if Rails.env != "production"
return unless Rails.env.production?
return unless PartnerRequest.exists?(partner_request_id)

uri = URI(ENV["DIAPERBANK_PARTNER_REQUEST_URL"])
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
req.body = PartnerRequest.find(partner_request_id).export_json
req["Content-Type"] = "application/json"
req["X-Api-Key"] = ENV["DIAPERBANK_KEY"]
body = PartnerRequest.find(partner_request_id).export_json

response = https(uri).request(req)
response = https(uri).request(post_request(uri: uri, body: body))

response.body
end
Expand All @@ -37,4 +30,12 @@ def self.https(uri)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
end

def self.post_request(uri:, body:, content_type: "application/json")
req = Net::HTTP::Post.new(uri)
req.body = body
req["Content-Type"] = content_type
req["X-Api-Key"] = ENV["DIAPERBANK_KEY"]
req
end
end
2 changes: 1 addition & 1 deletion app/views/partner_requests/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ul class="nav justify-content-end">
<%= link_to 'Organization', partner_path(@partner), class: 'btn btn-primary' %>
<%= link_to 'Organization', partner_path(current_partner), class: 'btn btn-primary' %>
&nbsp
<%= link_to 'Sign Out', destroy_partner_session_path, class: 'btn btn-warning', method: :delete %>
</ul>
Expand Down
9 changes: 9 additions & 0 deletions app/views/partner_requests/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
<ul class="nav justify-content-end">
<li class="nav-item">
<%= link_to 'Account', edit_partner_path(current_partner), class: 'nav-link' %>
</li>
<li class="nav-item">
<%= link_to 'Sign Out', destroy_partner_session_path, class: 'nav-link', method: :delete %>
</li>
</ul>

<h1>Thanks</h1>

<% if @partner_request.errors.any? %>
Expand Down
3 changes: 1 addition & 2 deletions app/views/partners/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
</li>
</ul>

<p id="notice"><%= notice %></p>

<div class="container">
<p id="notice"><%= notice %></p>
<div class="actions">
<% if @partner.verified? %>
<%= link_to 'Request Diapers', partner_requests_path, class: 'btn btn-success' %>
Expand Down
22 changes: 19 additions & 3 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
require 'faker'

# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
# Character.create(name: 'Luke', movie: movies.first)

puts "Creating partners..."
puts "Adding an 'approved' partner."
Partner.create(
Expand All @@ -18,14 +21,27 @@
zip_code: 62558,
website: "http://pawneeindiana.com",
zips_served: 62558,
executive_director_email: "leslie@example.com",
email: "leslie@example.com",
executive_director_email: "org_admin1@example.com",
email: "org_admin1@example.com",
password: "password",
partner_status: "Verified"
)

puts "Adding a generic 'pending' partner."
pending_user_name = Faker::Name.name
Partner.create(
email: "[email protected]",
executive_director_name: pending_user_name,
program_contact_name: pending_user_name,
name: "County Diaper Bank",
address1: Faker::Address.street_address,
address2: "",
city: Faker::Address.city,
state: Faker::Address.state_abbr,
zip_code: Faker::Address.zip,
website: Faker::Internet.domain_name,
zips_served: Faker::Address.zip,
executive_director_email: "[email protected]",
email: "[email protected]",
password: "password"
)
puts "Done creating partners."
8 changes: 5 additions & 3 deletions spec/controllers/partner_requests_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
end
end

describe "GET #show" do
it "returns http success" do
@partner_request = create(:partner_request_with_items)
describe 'GET #show' do
it 'returns http success' do
@partner = create(:partner)
sign_in @partner
@partner_request = create(:partner_request_with_items, partner: @partner)
get :show, params: { id: @partner_request.id }
expect(response).to have_http_status(200)
end
Expand Down
30 changes: 30 additions & 0 deletions spec/controllers/partners_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require "rails_helper"

RSpec.describe PartnersController, type: :controller do
login_partner

describe "GET #new" do
it "returns http success" do
get :new
expect(response).to have_http_status(200)
end
end

describe "Get #approve" do
it "should redirect to partner" do
@partner = create(:partner)
get :approve, params: { partner_id: @partner.id }
expect(response).to redirect_to(@partner)
end
end

describe "Post #create" do
it "creates a new partner" do
expect do
print(FactoryBot.attributes_for(:partner))
post :create, params: { partner: FactoryBot.attributes_for(:partner) }
end.to change(Partner, :count).by(0)
end
end
end

8 changes: 8 additions & 0 deletions spec/models/item_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,13 @@
it "requires a quantity greater than or equal to 1" do
expect(build(:item, quantity: 0)).not_to be_valid
end

it "requires a quantity with integer value only" do
expect(build(:item, quantity: 1.2)).not_to be_valid
end

it "requires a name" do
expect(build(:item, name: nil)).not_to be_valid
end
end
end
Loading

0 comments on commit c8658a8

Please sign in to comment.