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 '/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 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