Add initial verification for Nonprofit registration through model
This commit is contained in:
parent
38a1afc0f1
commit
4d8e5207b9
4 changed files with 84 additions and 80 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||||
class Nonprofit < ApplicationRecord
|
class Nonprofit < ApplicationRecord
|
||||||
attr_accessor :register_np_only, :user
|
attr_accessor :register_np_only, :user_id, :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
|
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
|
# :name, # str
|
||||||
|
@ -80,9 +80,6 @@ class Nonprofit < ApplicationRecord
|
||||||
has_one :billing_plan, through: :billing_subscription
|
has_one :billing_plan, through: :billing_subscription
|
||||||
has_one :miscellaneous_np_info
|
has_one :miscellaneous_np_info
|
||||||
|
|
||||||
##only meaningful on registration
|
|
||||||
has_one :user
|
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :city, presence: true
|
validates :city, presence: true
|
||||||
validates :state_code, presence: true
|
validates :state_code, presence: true
|
||||||
|
@ -90,7 +87,8 @@ class Nonprofit < ApplicationRecord
|
||||||
validates_uniqueness_of :slug, scope: %i[city_slug state_code_slug]
|
validates_uniqueness_of :slug, scope: %i[city_slug state_code_slug]
|
||||||
validates_presence_of :slug
|
validates_presence_of :slug
|
||||||
|
|
||||||
validates_presence_of :user, on: :create, unless: -> {register_np_only}
|
validates_presence_of :user_id, on: :create, unless: -> {register_np_only}
|
||||||
|
validate :user_is_valid, on: :create, unless: -> {register_np_only}
|
||||||
validate :user_registerable_as_admin, on: :create, unless: -> {register_np_only}
|
validate :user_registerable_as_admin, on: :create, unless: -> {register_np_only}
|
||||||
|
|
||||||
scope :vetted, -> { where(vetted: true) }
|
scope :vetted, -> { where(vetted: true) }
|
||||||
|
@ -110,13 +108,10 @@ class Nonprofit < ApplicationRecord
|
||||||
|
|
||||||
before_validation(on: :create) do
|
before_validation(on: :create) do
|
||||||
set_slugs
|
set_slugs
|
||||||
|
set_user
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
after_validation(on: :create) do
|
|
||||||
correct_nonunique_slug
|
|
||||||
end
|
|
||||||
|
|
||||||
after_create :build_admin_role, unless: -> {register_np_only}
|
after_create :build_admin_role, unless: -> {register_np_only}
|
||||||
|
|
||||||
# Register (create) a nonprofit with an initial admin
|
# Register (create) a nonprofit with an initial admin
|
||||||
|
@ -159,19 +154,32 @@ class Nonprofit < ApplicationRecord
|
||||||
unless state_code_slug
|
unless state_code_slug
|
||||||
self.state_code_slug = Format::Url.convert_to_slug state_code
|
self.state_code_slug = Format::Url.convert_to_slug state_code
|
||||||
end
|
end
|
||||||
|
if Nonprofit.where(slug: slug, city_slug: city_slug, state_code_slug: state_code_slug).any?
|
||||||
|
correct_nonunique_slug
|
||||||
|
end
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def correct_nonunique_slug
|
def correct_nonunique_slug
|
||||||
if errors[:slug]
|
begin
|
||||||
begin
|
slug = SlugNonprofitNamingAlgorithm.new(self.state_code_slug, self.city_slug).create_copy_name(self.slug)
|
||||||
slug = SlugNonprofitNamingAlgorithm.new(self.state_code_slug, self.city_slug).create_copy_name(self.slug)
|
self.slug = slug
|
||||||
self.slug = slug
|
rescue UnableToCreateNameCopyError
|
||||||
rescue UnableToCreateNameCopyError
|
errors.add(:slug, "another nonprofit admin")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_user
|
||||||
|
if (user_id && User.where(id: user_id).any?)
|
||||||
|
@user = User.find(user_id)
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_is_valid
|
||||||
|
(user && user.is_a?(User)) || errors.add(:user_id, "is not a valid user")
|
||||||
|
end
|
||||||
|
|
||||||
def full_address
|
def full_address
|
||||||
Format::Address.full_address(address, city, state_code)
|
Format::Address.full_address(address, city, state_code)
|
||||||
end
|
end
|
||||||
|
@ -222,7 +230,7 @@ class Nonprofit < ApplicationRecord
|
||||||
|
|
||||||
def user_registerable_as_admin
|
def user_registerable_as_admin
|
||||||
if user && user.roles.nonprofit_admins.any?
|
if user && user.roles.nonprofit_admins.any?
|
||||||
errors.add(:user, "cannot already be an admin for a nonprofit.")
|
errors.add(:user_id, "cannot already be an admin for a nonprofit.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private
|
private
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe Api::NonprofitsController, type: :request do
|
describe Api::NonprofitsController, type: :request do
|
||||||
it 'do things' do
|
|
||||||
|
|
||||||
post '/api/nonprofits', params: {nonprofit: {name: 'hathatoh'}, user: {email: 'thoahtoa'}}
|
|
||||||
|
|
||||||
byebug
|
|
||||||
expect(response.code).to eq 400
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
let(:user) { create(:user)}
|
||||||
|
let(:nonprofit_admin_role) do
|
||||||
|
role = user.roles.build(host: nonprofit, name: 'nonprofit_admin')
|
||||||
|
role.save!
|
||||||
|
role
|
||||||
|
end
|
||||||
|
let(:nonprofit) {create(:nm_justice)}
|
||||||
describe 'get' do
|
describe 'get' do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -34,23 +33,6 @@ describe Api::NonprofitsController, type: :request do
|
||||||
h.with_indifferent_access
|
h.with_indifferent_access
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:totally_empty_errors) do
|
|
||||||
{
|
|
||||||
errors:
|
|
||||||
[
|
|
||||||
h(params: ['nonprofit[name]'], messages: gr_e('presence', 'blank')),
|
|
||||||
h(params: ['nonprofit[zip_code]'], messages: gr_e('presence', 'blank')),
|
|
||||||
h(params: ['nonprofit[state_code]'], messages: gr_e('presence', 'blank')),
|
|
||||||
h(params: ['nonprofit[city]'], messages: gr_e('presence', 'blank')),
|
|
||||||
|
|
||||||
h(params: ['user[name]'], messages: gr_e('presence', 'blank')),
|
|
||||||
h(params: ['user[email]'], messages: gr_e('presence', 'blank')),
|
|
||||||
h(params: ['user[password]'], messages: gr_e('presence', 'blank')),
|
|
||||||
h(params: ['user[password_confirmation]'], messages: gr_e('presence', 'blank'))
|
|
||||||
]
|
|
||||||
|
|
||||||
}.with_indifferent_access
|
|
||||||
end
|
|
||||||
describe 'authorization' do
|
describe 'authorization' do
|
||||||
around(:each) do |e|
|
around(:each) do |e|
|
||||||
Rails.configuration.action_controller.allow_forgery_protection = true
|
Rails.configuration.action_controller.allow_forgery_protection = true
|
||||||
|
@ -89,21 +71,6 @@ describe Api::NonprofitsController, type: :request do
|
||||||
expect_validation_errors(JSON.parse(response.body), expected)
|
expect_validation_errors(JSON.parse(response.body), expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should reject unmatching passwords ' do
|
|
||||||
input = {
|
|
||||||
|
|
||||||
user: {
|
|
||||||
email: 'wmeil@email.com',
|
|
||||||
name: 'name',
|
|
||||||
password: 'password',
|
|
||||||
password_confirmation: 'doesn\'t match'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
post :create, params: input, xhr: true
|
|
||||||
expect(response.code).to eq '400'
|
|
||||||
expect(JSON.parse(response.body)['errors']).to include(h(params: ['user[password]', 'user[password_confirmation]'], messages: gr_e('is_equal_to')))
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'attempts to make a slug copy and returns the proper errors' do
|
it 'attempts to make a slug copy and returns the proper errors' do
|
||||||
force_create(:nonprofit, slug: 'n', state_code_slug: 'wi', city_slug: 'appleton')
|
force_create(:nonprofit, slug: 'n', state_code_slug: 'wi', city_slug: 'appleton')
|
||||||
input = {
|
input = {
|
||||||
|
@ -125,30 +92,14 @@ describe Api::NonprofitsController, type: :request do
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'errors on attempt to add user with email that already exists' do
|
it 'errors on attempt to add the user to a second nonprofit' do
|
||||||
force_create(:user, email: 'em@em.com')
|
nonprofit_admin_role
|
||||||
|
input = { name: 'n', state_code: 'WI', city: 'appleton', zip_code: 54_915, user_id: user.id }
|
||||||
input = {
|
post '/api/nonprofits', params: input, xhr:true
|
||||||
nonprofit: { name: 'n', state_code: 'WI', city: 'appleton', zip_code: 54_915 },
|
expect(response).to have_http_status :unprocessable_entity
|
||||||
user: { name: 'Name', email: 'em@em.com', password: '12345678', password_confirmation: '12345678' }
|
expect(response.parsed_body['errors'].keys).to match_array 'user'
|
||||||
}
|
byebug
|
||||||
|
expect(response.parsed_body['errors']['user'].first).to has_include? 'nonprofit admin'
|
||||||
expect do
|
|
||||||
post :create, params: input, xhr: true
|
|
||||||
end.to raise_error {|error|
|
|
||||||
|
|
||||||
expect(error).to be_a Errors::MessageInvalid
|
|
||||||
}
|
|
||||||
byebug
|
|
||||||
expect(response.code).to eq '400'
|
|
||||||
|
|
||||||
expect_validation_errors(JSON.parse(response.body),
|
|
||||||
errors: [
|
|
||||||
h(
|
|
||||||
params: ['user[email]'],
|
|
||||||
messages: ['has already been taken']
|
|
||||||
)
|
|
||||||
])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'succeeds' do
|
it 'succeeds' do
|
||||||
|
|
|
@ -43,4 +43,45 @@ RSpec.describe Nonprofit, type: :model do
|
||||||
expect(nonprofit.currency_symbol).to eq euro
|
expect(nonprofit.currency_symbol).to eq euro
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'create' do
|
||||||
|
describe 'validates on parameters' do
|
||||||
|
let(:nonprofit) { Nonprofit.new()}
|
||||||
|
let(:nonprofit_with_invalid_user) { Nonprofit.new(user_id: 3333)}
|
||||||
|
let(:nonprofit_with_user_who_already_admin) {nonprofit_admin_role; Nonprofit.new(user_id: user.id)}
|
||||||
|
let(:user) { create(:user)}
|
||||||
|
let(:nonprofit_admin_role) do
|
||||||
|
role = user.roles.build(host: nonprofit, name: 'nonprofit_admin')
|
||||||
|
role.save!
|
||||||
|
role
|
||||||
|
end
|
||||||
|
let(:nm_justice) {create(:nm_justice)}
|
||||||
|
|
||||||
|
before(:each) { nonprofit.valid?; nonprofit_with_invalid_user.valid?; nonprofit_with_user_who_already_admin.valid?}
|
||||||
|
it 'has an error for no name' do
|
||||||
|
expect(nonprofit.errors['name'].first).to match /.*blank.*/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has an error for no user' do
|
||||||
|
expect(nonprofit.errors['user_id'].first).to match /.*blank.*/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has an error for no city' do
|
||||||
|
expect(nonprofit.errors['city'].first).to match /.*blank.*/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has an error for no state' do
|
||||||
|
expect(nonprofit.errors['state_code'].first).to match /.*blank.*/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'rejects an invalid user' do
|
||||||
|
expect(nonprofit_with_invalid_user.errors['user_id'].first).to match /.*not a valid user.*/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'rejects a user who is already an admin' do
|
||||||
|
byebug
|
||||||
|
expect(nonprofit_with_user_who_already_admin.errors['user_id'].first).to match /.*admin.*/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
4
spec/support/time_helpers.rb
Normal file
4
spec/support/time_helpers.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
require 'active_support/testing/time_helpers'
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include ActiveSupport::Testing::TimeHelpers
|
||||||
|
end
|
Loading…
Reference in a new issue