From 38a1afc0f17a36afa78286bb8aeb679e34153509 Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Fri, 17 Apr 2020 15:30:54 -0500 Subject: [PATCH] getting closer! --- app/controllers/api/nonprofits_controller.rb | 40 +++++++++++++++---- app/models/nonprofit.rb | 26 ++++++++++++ .../api/nonprofits_controller_spec.rb | 6 +-- spec/factories/nonprofits.rb | 2 + 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/nonprofits_controller.rb b/app/controllers/api/nonprofits_controller.rb index 2ff5782d..58a7a9d4 100644 --- a/app/controllers/api/nonprofits_controller.rb +++ b/app/controllers/api/nonprofits_controller.rb @@ -1,5 +1,5 @@ class Api::NonprofitsController < ApplicationController - + rescue_from ActiveRecord::RecordInvalid, with: :record_invalid_rescue # requires :nonprofit, type: Hash do # requires :name, type: String, desc: 'Organization Name', allow_blank: false, documentation: { param_type: 'body' } # requires :zip_code, type: String, allow_blank: false, desc: 'Organization Address ZIP Code', documentation: { param_type: 'body' } @@ -12,13 +12,11 @@ class Api::NonprofitsController < ApplicationController # requires :email, type: String, desc: 'Username', allow_blank: false, documentation: { param_type: 'body' } # requires :password, type: String, desc: 'Password', allow_blank: false, is_equal_to: :password_confirmation, documentation: { param_type: 'body' } def create - model = CreateModel.new(clean_params) - np = nil - u = nil - raise ActiveRecord::RecordInvalid + #model = CreateModel.new(clean_params) Qx.transaction do - raise Errors::MessageInvalid.new(model) unless model.valid? - model.save! + # raise Errors::MessageInvalid.new(model) unless model.valid? + nonprofit = Nonprofit.new(clean_params) + nonprofit.save! end # Qx.transaction do # byebug @@ -72,6 +70,34 @@ class Api::NonprofitsController < ApplicationController # end end + private + def record_invalid_rescue(error) + render json:{errors: error.record.errors.messages}, status: :unprocessable_entity + end + + def change_to_errors(message) + message.model.errors.keys.map do |k| + errors = e.record.errors[k].uniq + errors.map do |error| + Grape::Exceptions::Validation.new( + params: ["#{class_to_name[e.record.class]}[#{k}]"], + message: error + ) + end + end + end + + def flatten_errors(hash_or_array, parent=nil) + if hash_or_array.keys + result = hash_or_array.keys.map{|i| + param = !parent ? i : "#{parent}[#{i}]" + + } + else + return hash_or_array; + end + end + def clean_params params.permit(nonprofit: [:name, :zip_code, :state_code, :city], user: [:name, :email, :password]) end diff --git a/app/models/nonprofit.rb b/app/models/nonprofit.rb index 71eb47e3..d60cbc70 100755 --- a/app/models/nonprofit.rb +++ b/app/models/nonprofit.rb @@ -2,6 +2,7 @@ # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later class Nonprofit < ApplicationRecord + attr_accessor :register_np_only, :user Categories = ['Public Benefit', 'Human Services', 'Education', 'Civic Duty', 'Human Rights', 'Animals', 'Environment', 'Health', 'Arts, Culture, Humanities', 'International', 'Children', 'Religion', 'LGBTQ', "Women's Rights", 'Disaster Relief', 'Veterans'].freeze # :name, # str @@ -79,12 +80,18 @@ class Nonprofit < ApplicationRecord has_one :billing_plan, through: :billing_subscription has_one :miscellaneous_np_info + ##only meaningful on registration + has_one :user + validates :name, presence: true validates :city, presence: true validates :state_code, presence: true validates :email, format: { with: Email::Regex }, allow_blank: true validates_uniqueness_of :slug, scope: %i[city_slug state_code_slug] validates_presence_of :slug + + validates_presence_of :user, on: :create, unless: -> {register_np_only} + validate :user_registerable_as_admin, on: :create, unless: -> {register_np_only} scope :vetted, -> { where(vetted: true) } scope :identity_verified, -> { where(verification_status: 'verified') } @@ -110,6 +117,8 @@ class Nonprofit < ApplicationRecord correct_nonunique_slug end + after_create :build_admin_role, unless: -> {register_np_only} + # Register (create) a nonprofit with an initial admin def self.register(user, params) np = create ConstructNonprofit.construct(user, params) @@ -210,4 +219,21 @@ class Nonprofit < ApplicationRecord def currency_symbol Settings.intntl.all_currencies.find { |i| i.abbv.casecmp(currency).zero? }&.symbol end + + def user_registerable_as_admin + if user && user.roles.nonprofit_admins.any? + errors.add(:user, "cannot already be an admin for a nonprofit.") + end + end +private + def build_admin_role + role = user.roles.build(host: self, name: 'nonprofit_admin') + role.save! + end + + def add_billing_subscription + billing_plan = BillingPlan.find(Settings.default_bp.id) + b_sub = build_billing_subscription(billing_plan: billing_plan, status: 'active') + b_sub.save! + end end diff --git a/spec/controllers/api/nonprofits_controller_spec.rb b/spec/controllers/api/nonprofits_controller_spec.rb index 41a0cff3..739dc206 100644 --- a/spec/controllers/api/nonprofits_controller_spec.rb +++ b/spec/controllers/api/nonprofits_controller_spec.rb @@ -66,9 +66,9 @@ describe Api::NonprofitsController, type: :request do it 'validates nothing' do input = {} - post :create, params: input, xhr: true - expect(response.code).to eq '400' - expect_validation_errors(JSON.parse(response.body), create_errors('nonprofit', 'user')) + post '/api/nonprofits', params: input, xhr: true + expect(response).to have_http_status :unprocessable_entity + expect(response.parsed_body['errors'].keys).to match_array ['name', 'city', 'state_code', 'slug', 'user'] end it 'validates url, email, phone ' do diff --git a/spec/factories/nonprofits.rb b/spec/factories/nonprofits.rb index c31a44bd..7995f1ac 100644 --- a/spec/factories/nonprofits.rb +++ b/spec/factories/nonprofits.rb @@ -12,6 +12,7 @@ FactoryBot.define do slug { 'new_mexican_equality' } state_code_slug { 'nm'} city_slug { 'albuquerque'} + register_np_only { true } end factory :fv_poverty, class: Nonprofit do @@ -25,5 +26,6 @@ FactoryBot.define do slug { 'end_poverty_in_the_fox_valley_inc' } state_code_slug { 'wi'} city_slug { 'appleton'} + register_np_only { true } end end