WIP
This commit is contained in:
parent
25c7cd7c6a
commit
30b2df23e2
22 changed files with 459 additions and 33 deletions
38
Gemfile.lock
38
Gemfile.lock
|
@ -116,7 +116,7 @@ GEM
|
|||
debug_inspector (>= 0.0.1)
|
||||
bootsnap (1.4.4)
|
||||
msgpack (~> 1.0)
|
||||
builder (3.2.4)
|
||||
builder (3.2.3)
|
||||
bunny (2.14.2)
|
||||
amq-protocol (~> 2.3, >= 2.3.0)
|
||||
byebug (11.0.1)
|
||||
|
@ -132,7 +132,7 @@ GEM
|
|||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
colorize (0.8.1)
|
||||
concurrent-ruby (1.1.6)
|
||||
concurrent-ruby (1.1.5)
|
||||
config (1.7.2)
|
||||
activesupport (>= 3.0)
|
||||
deep_merge (~> 1.2, >= 1.2.1)
|
||||
|
@ -143,7 +143,7 @@ GEM
|
|||
unicode_utils (~> 1.4)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
crass (1.0.6)
|
||||
crass (1.0.4)
|
||||
css_parser (1.7.0)
|
||||
addressable
|
||||
dante (0.2.0)
|
||||
|
@ -155,10 +155,10 @@ GEM
|
|||
deep_merge (1.2.1)
|
||||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
devise (4.7.1)
|
||||
devise (4.6.2)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-async (1.0.0)
|
||||
|
@ -201,7 +201,7 @@ GEM
|
|||
dry-logic (~> 0.5, >= 0.5.0)
|
||||
dry-types (~> 0.14.0)
|
||||
equalizer (0.0.11)
|
||||
erubi (1.9.0)
|
||||
erubi (1.8.0)
|
||||
execjs (2.7.0)
|
||||
factory_bot (5.0.2)
|
||||
activesupport (>= 4.2.0)
|
||||
|
@ -260,7 +260,7 @@ GEM
|
|||
httparty (0.17.0)
|
||||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.8.2)
|
||||
i18n (1.6.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.3.0)
|
||||
i18n (>= 0.6.6)
|
||||
|
@ -276,7 +276,7 @@ GEM
|
|||
activesupport (>= 4)
|
||||
railties (>= 4)
|
||||
request_store (~> 1.0)
|
||||
loofah (2.5.0)
|
||||
loofah (2.2.3)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
|
@ -293,7 +293,7 @@ GEM
|
|||
mini_magick (4.9.5)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.14.0)
|
||||
minitest (5.11.3)
|
||||
msgpack (1.3.1)
|
||||
multi_json (1.13.1)
|
||||
multi_xml (0.6.0)
|
||||
|
@ -307,7 +307,7 @@ GEM
|
|||
require_all
|
||||
netrc (0.11.0)
|
||||
nio4r (2.4.0)
|
||||
nokogiri (1.10.9)
|
||||
nokogiri (1.10.3)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
orm_adapter (0.5.0)
|
||||
parallel (1.17.0)
|
||||
|
@ -331,11 +331,7 @@ GEM
|
|||
puma (>= 2.7, < 5)
|
||||
rabl (0.14.1)
|
||||
activesupport (>= 2.3.14)
|
||||
<<<<<<< HEAD
|
||||
rack (2.0.9)
|
||||
=======
|
||||
rack (2.2.2)
|
||||
>>>>>>> Update to Rack
|
||||
rack-accept (0.4.5)
|
||||
rack (>= 0.4)
|
||||
rack-attack (5.4.2)
|
||||
|
@ -361,8 +357,8 @@ GEM
|
|||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.3.0)
|
||||
loofah (~> 2.3)
|
||||
rails-html-sanitizer (1.2.0)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
rails-i18n (5.1.3)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 5.0, < 6)
|
||||
|
@ -398,13 +394,13 @@ GEM
|
|||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.2)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.6)
|
||||
rspec-expectations (3.8.4)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.2)
|
||||
rspec-mocks (3.8.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.3)
|
||||
rspec-rails (3.8.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
|
@ -412,7 +408,7 @@ GEM
|
|||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.3)
|
||||
rspec-support (3.8.2)
|
||||
rubocop (0.72.0)
|
||||
jaro_winkler (~> 1.5.1)
|
||||
parallel (~> 1.10)
|
||||
|
@ -475,7 +471,7 @@ GEM
|
|||
timecop (0.9.1)
|
||||
traceroute (0.8.0)
|
||||
rails (>= 3.0.0)
|
||||
tzinfo (1.2.7)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (4.1.20)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
|
|
81
app/controllers/api/nonprofits_controller.rb
Normal file
81
app/controllers/api/nonprofits_controller.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
class Api::NonprofitsController < ApplicationController
|
||||
|
||||
# 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' }
|
||||
# requires :state_code, type: String, allow_blank: false, desc: 'Organization Address State Code', documentation: { param_type: 'body' }
|
||||
# requires :city, type: String, allow_blank: false, desc: 'Organization Address City', documentation: { param_type: 'body' }
|
||||
# end
|
||||
|
||||
# requires :user, type: Hash do
|
||||
# requires :name, type: String, desc: 'Full name', allow_blank: false, documentation: { param_type: 'body' }
|
||||
# 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
|
||||
Qx.transaction do
|
||||
raise Errors::MessageInvalid.new(model) unless model.valid?
|
||||
model.save!
|
||||
end
|
||||
# Qx.transaction do
|
||||
# byebug
|
||||
# np = ::Nonprofit.new(OnboardAccounts.set_nonprofit_defaults(clean_params[:nonprofit]))
|
||||
|
||||
# begin
|
||||
# np.save!
|
||||
# rescue ActiveRecord::RecordInvalid => e
|
||||
# if e.record.errors[:slug]
|
||||
# begin
|
||||
# slug = SlugNonprofitNamingAlgorithm.new(np.state_code_slug, np.city_slug).create_copy_name(np.slug)
|
||||
# np.slug = slug
|
||||
# np.save!
|
||||
# rescue UnableToCreateNameCopyError
|
||||
# raise Grape::Exceptions::ValidationErrors.new(errors: [Grape::Exceptions::Validation.new(
|
||||
# params: ['nonprofit[name]'],
|
||||
# message: 'has an invalid slug. Contact support for help.'
|
||||
# )])
|
||||
# end
|
||||
# else
|
||||
# raise e
|
||||
# end
|
||||
# end
|
||||
|
||||
# u = User.new(clean_params[:user])
|
||||
# u.save!
|
||||
|
||||
# role = u.roles.build(host: np, name: 'nonprofit_admin')
|
||||
# role.save!
|
||||
|
||||
# billing_plan = BillingPlan.find(Settings.default_bp.id)
|
||||
# b_sub = np.build_billing_subscription(billing_plan: billing_plan, status: 'active')
|
||||
# b_sub.save!
|
||||
# rescue ActiveRecord::RecordInvalid => e
|
||||
# class_to_name = { Nonprofit => 'nonprofit', User => 'user' }
|
||||
# if class_to_name[e.record.class]
|
||||
# errors = e.record.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
|
||||
|
||||
# raise Grape::Exceptions::ValidationErrors.new(errors: errors.flatten)
|
||||
# else
|
||||
# raise e
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def clean_params
|
||||
params.permit(nonprofit: [:name, :zip_code, :state_code, :city], user: [:name, :email, :password])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
41
app/models/base.rb
Normal file
41
app/models/base.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
|
||||
class Base
|
||||
include ActiveModel::Model
|
||||
include ActiveModel::Validations
|
||||
include ActiveModel::Validations::Callbacks
|
||||
|
||||
|
||||
def self.validate_nested_attribute(*attributes)
|
||||
validates_with NestedAttributesValidator, _merge_attributes(attributes)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def _merge_attributes(attr_names)
|
||||
options = attr_names.extract_options!.symbolize_keys
|
||||
attr_names.flatten!
|
||||
options[:attributes] = attr_names
|
||||
options
|
||||
end
|
||||
|
||||
class NestedAttributesValidator < ActiveModel::EachValidator
|
||||
def initialize(options)
|
||||
@model_class = options[:model_class]
|
||||
super
|
||||
end
|
||||
|
||||
def validate_each(record, attribute, value)
|
||||
inner_validator = @model_class.new(value) unless value.is_a? @model_class
|
||||
return if inner_validator.valid?
|
||||
add_nested_errors_for(record, attribute, inner_validator)
|
||||
end
|
||||
|
||||
def add_nested_errors_for(record, attribute, other_validator)
|
||||
record.errors.messages[attribute] = other_validator.errors.messages
|
||||
record.errors.details[attribute] = other_validator.errors.details
|
||||
end
|
||||
end
|
||||
end
|
||||
|
48
app/models/create_model.rb
Normal file
48
app/models/create_model.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
class CreateModel < Base
|
||||
attr_accessor :nonprofit, :user
|
||||
validates_presence_of :user
|
||||
validates_presence_of :nonprofit
|
||||
validate_nested_attribute :user, model_class: User
|
||||
validate_nested_attribute :nonprofit, model_class: Nonprofit
|
||||
|
||||
before_validation do
|
||||
nonprofit = Nonprofit.create(nonprofit) if !nonprofit.is_a? Nonprofit
|
||||
user = User.create(user) if !nonprofit.is_a? Nonprofit
|
||||
end
|
||||
|
||||
def save
|
||||
if valid?
|
||||
if nonprofit.save!
|
||||
if user.save!
|
||||
role = user.roles.build(host: nonprofit, name: 'nonprofit_admin')
|
||||
role.save!
|
||||
|
||||
billing_plan = BillingPlan.find(Settings.default_bp.id)
|
||||
b_sub = nonprofit.build_billing_subscription(billing_plan: billing_plan, status: 'active')
|
||||
b_sub.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
# rescue ActiveRecord::RecordInvalid => e
|
||||
# class_to_name = { Nonprofit => 'nonprofit', User => 'user' }
|
||||
# if class_to_name[e.record.class]
|
||||
# errors = e.record.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}]"],
|
||||
# value message: error
|
||||
# )
|
||||
# end
|
||||
# end
|
||||
# raise Grape::Exceptions::ValidationErrors.new(errors: errors.flatten)
|
||||
# else
|
||||
# raise e
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def save!
|
||||
raise 'runtime' unless save
|
||||
end
|
||||
end
|
5
app/models/errors/active_model_error.rb
Normal file
5
app/models/errors/active_model_error.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
|
||||
class Errors::ActiveModelError < StandardError
|
||||
|
||||
end
|
17
app/models/errors/message_invalid.rb
Normal file
17
app/models/errors/message_invalid.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
class Errors::MessageInvalid < Errors::ActiveModelError
|
||||
|
||||
attr_reader :record
|
||||
def initialize(record=nil)
|
||||
if record
|
||||
@record = record
|
||||
errors = @record.errors.full_messages.join(", ")
|
||||
message = I18n.t(:"#{@record.class.i18n_scope}.errors.messages.record_invalid", errors: errors, default: :"errors.messages.record_invalid")
|
||||
else
|
||||
message = "Record invalid"
|
||||
end
|
||||
|
||||
super(message)
|
||||
|
||||
end
|
||||
end
|
|
@ -106,6 +106,10 @@ class Nonprofit < ApplicationRecord
|
|||
self
|
||||
end
|
||||
|
||||
after_validation(on: :create) do
|
||||
correct_nonunique_slug
|
||||
end
|
||||
|
||||
# Register (create) a nonprofit with an initial admin
|
||||
def self.register(user, params)
|
||||
np = create ConstructNonprofit.construct(user, params)
|
||||
|
@ -148,6 +152,16 @@ class Nonprofit < ApplicationRecord
|
|||
end
|
||||
self
|
||||
end
|
||||
|
||||
def correct_nonunique_slug
|
||||
if errors[:slug]
|
||||
begin
|
||||
slug = SlugNonprofitNamingAlgorithm.new(self.state_code_slug, self.city_slug).create_copy_name(self.slug)
|
||||
self.slug = slug
|
||||
rescue UnableToCreateNameCopyError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def full_address
|
||||
Format::Address.full_address(address, city, state_code)
|
||||
|
|
|
@ -14,7 +14,7 @@ require "action_mailer/railtie"
|
|||
require "action_view/railtie"
|
||||
# require "action_cable/engine"
|
||||
# require "sprockets/railtie"
|
||||
# require "rails/test_unit/railtie"
|
||||
require "rails/test_unit/railtie"
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
|
@ -24,6 +24,7 @@ Bundler.require(*Rails.groups)
|
|||
|
||||
module Commitchange
|
||||
class Application < Rails::Application
|
||||
config.load_defaults '5.0'
|
||||
# Settings in config/environments/* take precedence over those specified here.
|
||||
# Application configuration should go into files in config/initializers
|
||||
# -- all .rb files in that directory are automatically loaded.
|
||||
|
@ -32,9 +33,9 @@ module Commitchange
|
|||
# config.autoload_paths += %W(#{config.root}/extras)
|
||||
config.eager_load_paths += Dir["#{config.root}/lib/**/", ""]
|
||||
|
||||
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
|
||||
# config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
|
||||
config.paths.add File.join('app', 'listeners'), glob: File.join('**', '*.rb')
|
||||
config.eager_load_paths += Dir[Rails.root.join('app', 'api', '*'), Rails.root.join('app', 'listeners', '*')]
|
||||
# config.eager_load_paths += Dir[Rails.root.join('app', 'api', '*'), Rails.root.join('app', 'listeners', '*')]
|
||||
|
||||
# Only load the plugins named here, in the order given (default is alphabetical).
|
||||
# :all can be used as a placeholder for all plugins not explicitly named.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||
Rails.application.routes.draw do
|
||||
mount Houdini::API => '/api'
|
||||
|
||||
if Rails.env == 'development'
|
||||
get '/button_debug/embedded' => 'button_debug#embedded'
|
||||
|
@ -12,6 +11,10 @@ Rails.application.routes.draw do
|
|||
end
|
||||
get 'onboard' => 'onboard#index'
|
||||
|
||||
namespace(:api) do
|
||||
resources(:nonprofits)
|
||||
end
|
||||
|
||||
resources(:emails, only: [:create])
|
||||
resources(:settings, only: [:index])
|
||||
resources(:campaign_gifts, only: [:create])
|
||||
|
@ -254,5 +257,7 @@ Rails.application.routes.draw do
|
|||
get '/static/terms_and_privacy' => 'static#terms_and_privacy'
|
||||
get '/static/ccs' => 'static#ccs'
|
||||
|
||||
|
||||
|
||||
root to: 'front#index'
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||
require 'rails_helper'
|
||||
|
||||
describe Houdini::V1::Nonprofit, type: :request do
|
||||
describe 'HOUDINI NOnprofit_spec', type: :request do
|
||||
describe 'get' do
|
||||
end
|
||||
|
||||
|
@ -53,14 +53,14 @@ describe Houdini::V1::Nonprofit, type: :request do
|
|||
end
|
||||
|
||||
it 'rejects csrf' do
|
||||
post '/api/v1/nonprofit', params: {}, xhr: true
|
||||
post '/api/nonprofits', params: {}, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
end
|
||||
end
|
||||
|
||||
it 'validates nothing' do
|
||||
input = {}
|
||||
post '/api/v1/nonprofit', params: input, xhr: true
|
||||
post '/api/nonprofits', params: input, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
expect_validation_errors(JSON.parse(response.body), create_errors('nonprofit', 'user'))
|
||||
end
|
||||
|
@ -73,7 +73,7 @@ describe Houdini::V1::Nonprofit, type: :request do
|
|||
url: ''
|
||||
}
|
||||
}
|
||||
post '/api/v1/nonprofit', params: input, xhr: true
|
||||
post '/api/nonprofits', params: input, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
expected = create_errors('user')
|
||||
expected[:errors].push(h(params: ['nonprofit[email]'], messages: gr_e('regexp')))
|
||||
|
@ -93,7 +93,7 @@ describe Houdini::V1::Nonprofit, type: :request do
|
|||
password_confirmation: 'doesn\'t match'
|
||||
}
|
||||
}
|
||||
post '/api/v1/nonprofit', params: input, xhr: true
|
||||
post '/api/nonprofits', 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
|
||||
|
@ -107,7 +107,7 @@ describe Houdini::V1::Nonprofit, type: :request do
|
|||
|
||||
expect_any_instance_of(SlugNonprofitNamingAlgorithm).to receive(:create_copy_name).and_raise(UnableToCreateNameCopyError.new)
|
||||
|
||||
post '/api/v1/nonprofit', params: input, xhr: true
|
||||
post '/api/nonprofits', params: input, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
|
||||
expect_validation_errors(JSON.parse(response.body),
|
||||
|
@ -127,7 +127,7 @@ describe Houdini::V1::Nonprofit, type: :request do
|
|||
user: { name: 'Name', email: 'em@em.com', password: '12345678', password_confirmation: '12345678' }
|
||||
}
|
||||
|
||||
post '/api/v1/nonprofit', params: input, xhr: true
|
||||
post '/api/nonprofits', params: input, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
|
||||
expect_validation_errors(JSON.parse(response.body),
|
||||
|
@ -151,7 +151,7 @@ describe Houdini::V1::Nonprofit, type: :request do
|
|||
|
||||
# expect(Houdini::V1::Nonprofit).to receive(:sign_in)
|
||||
|
||||
post '/api/v1/nonprofit', params: input, xhr: true
|
||||
post '/api/nonprofits', params: input, xhr: true
|
||||
expect(response.code).to eq '201'
|
||||
|
||||
our_np = Nonprofit.all[1]
|
||||
|
|
218
spec/controllers/api/nonprofits_controller_spec.rb
Normal file
218
spec/controllers/api/nonprofits_controller_spec.rb
Normal file
|
@ -0,0 +1,218 @@
|
|||
require 'rails_helper'
|
||||
|
||||
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
|
||||
|
||||
|
||||
describe 'get' do
|
||||
end
|
||||
|
||||
describe 'post' do
|
||||
around(:each) do |example|
|
||||
@old_bp = Settings.default_bp
|
||||
example.run
|
||||
Settings.default_bp = @old_bp
|
||||
end
|
||||
def expect_validation_errors(actual, input)
|
||||
expected_errors = input.with_indifferent_access[:errors]
|
||||
expect(actual['errors']).to match_array expected_errors
|
||||
end
|
||||
|
||||
def create_errors(*wrapper_params)
|
||||
output = totally_empty_errors
|
||||
wrapper_params.each { |i| output[:errors].push(h(params: [i], messages: gr_e('presence'))) }
|
||||
output
|
||||
end
|
||||
|
||||
def h(h = {})
|
||||
h.with_indifferent_access
|
||||
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
|
||||
around(:each) do |e|
|
||||
Rails.configuration.action_controller.allow_forgery_protection = true
|
||||
e.run
|
||||
Rails.configuration.action_controller.allow_forgery_protection = false
|
||||
end
|
||||
|
||||
it 'rejects csrf' do
|
||||
post :create, params: {}, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
end
|
||||
end
|
||||
|
||||
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'))
|
||||
end
|
||||
|
||||
it 'validates url, email, phone ' do
|
||||
input = {
|
||||
nonprofit: {
|
||||
email: 'noemeila',
|
||||
phone: 'notphone',
|
||||
url: ''
|
||||
}
|
||||
}
|
||||
post :create, params: input, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
expected = create_errors('user')
|
||||
expected[:errors].push(h(params: ['nonprofit[email]'], messages: gr_e('regexp')))
|
||||
# expected[:errors].push(h(params:["nonprofit[phone]"], messages: gr_e("regexp")))
|
||||
# expected[:errors].push(h(params:["nonprofit[url]"], messages: gr_e("regexp")))
|
||||
|
||||
expect_validation_errors(JSON.parse(response.body), expected)
|
||||
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
|
||||
force_create(:nonprofit, slug: 'n', state_code_slug: 'wi', city_slug: 'appleton')
|
||||
input = {
|
||||
nonprofit: { name: 'n', state_code: 'WI', city: 'appleton', zip_code: 54_915 },
|
||||
user: { name: 'Name', email: 'em@em.com', password: '12345678', password_confirmation: '12345678' }
|
||||
}
|
||||
|
||||
expect_any_instance_of(SlugNonprofitNamingAlgorithm).to receive(:create_copy_name).and_raise(UnableToCreateNameCopyError.new)
|
||||
|
||||
post :create, params: input, xhr: true
|
||||
expect(response.code).to eq '400'
|
||||
|
||||
expect_validation_errors(JSON.parse(response.body),
|
||||
errors: [
|
||||
h(
|
||||
params: ['nonprofit[name]'],
|
||||
messages: ['has an invalid slug. Contact support for help.']
|
||||
)
|
||||
])
|
||||
end
|
||||
|
||||
it 'errors on attempt to add user with email that already exists' do
|
||||
force_create(:user, email: 'em@em.com')
|
||||
|
||||
input = {
|
||||
nonprofit: { name: 'n', state_code: 'WI', city: 'appleton', zip_code: 54_915 },
|
||||
user: { name: 'Name', email: 'em@em.com', password: '12345678', password_confirmation: '12345678' }
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
it 'succeeds' do
|
||||
force_create(:nonprofit, slug: 'n', state_code_slug: 'wi', city_slug: 'appleton')
|
||||
input = {
|
||||
nonprofit: { name: 'n', state_code: 'WI', city: 'appleton', zip_code: 54_915, url: 'www.cs.c', website: 'www.cs.c' },
|
||||
user: { name: 'Name', email: 'em@em.com', password: '12345678', password_confirmation: '12345678' }
|
||||
}
|
||||
|
||||
bp = force_create(:billing_plan)
|
||||
Settings.default_bp.id = bp.id
|
||||
|
||||
# expect(Houdini::V1::Nonprofit).to receive(:sign_in)
|
||||
|
||||
post :create, params: input, xhr: true
|
||||
expect(response.code).to eq '201'
|
||||
|
||||
our_np = Nonprofit.all[1]
|
||||
expected_np = {
|
||||
name: 'n',
|
||||
state_code: 'WI',
|
||||
city: 'appleton',
|
||||
zip_code: '54915',
|
||||
state_code_slug: 'wi',
|
||||
city_slug: 'appleton',
|
||||
slug: 'n-00',
|
||||
website: 'http://www.cs.c'
|
||||
}.with_indifferent_access
|
||||
|
||||
expected_np = our_np.attributes.with_indifferent_access.merge(expected_np)
|
||||
expect(our_np.attributes).to eq expected_np
|
||||
|
||||
expect(our_np.billing_subscription.billing_plan).to eq bp
|
||||
|
||||
response_body = {
|
||||
id: our_np.id
|
||||
}.with_indifferent_access
|
||||
|
||||
expect(JSON.parse(response.body)).to eq response_body
|
||||
|
||||
user = User.first
|
||||
expected_user = {
|
||||
email: 'em@em.com',
|
||||
name: 'Name'
|
||||
}
|
||||
|
||||
expected_user = user.attributes.with_indifferent_access.merge(expected_user)
|
||||
expect(our_np.roles.nonprofit_admins.count).to eq 1
|
||||
expect(our_np.roles.nonprofit_admins.first.user.attributes).to eq expected_user
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def find_error_message(json, field_name)
|
||||
errors = json['errors']
|
||||
|
||||
error = errors.select { |i| i['params'].any? { |j| j == field_name } }.first
|
||||
return error unless error
|
||||
|
||||
error['messages']
|
||||
end
|
||||
|
||||
def gr_e(*keys)
|
||||
keys.map { |i| I18n.translate('grape.errors.messages.' + i, locale: 'en') }
|
||||
end
|
||||
|
||||
|
Loading…
Reference in a new issue