6772312ea7
The primary license of the project is changing to: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later with some specific files to be licensed under the one of two licenses: CC0-1.0 LGPL-3.0-or-later This commit is one of the many steps to relicense the entire codebase. Documentation granting permission for this relicensing (from all past contributors who hold copyrights) is on file with Software Freedom Conservancy, Inc.
311 lines
13 KiB
Ruby
311 lines
13 KiB
Ruby
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
|
require 'rails_helper'
|
|
|
|
|
|
describe InsertCustomFieldJoins do
|
|
describe '.find_or_create' do
|
|
let(:nonprofit) { force_create(:nonprofit)}
|
|
let(:other_nonprofit) { force_create(:nonprofit)}
|
|
let(:supporter) {force_create(:supporter, :nonprofit => nonprofit)}
|
|
let(:other_supporter){force_create(:supporter, :nonprofit => other_nonprofit)}
|
|
|
|
let(:initial_custom_field_master){ force_create(:custom_field_master, :nonprofit => nonprofit, :name => "CFM Name")}
|
|
|
|
describe 'param validation' do
|
|
it 'basic validation' do
|
|
expect {InsertCustomFieldJoins.find_or_create(nil, nil, nil)}.to(raise_error {|error|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
|
expect_validation_errors(error.data, [
|
|
{:key => :np_id, :name => :required},
|
|
{:key => :np_id, :name => :is_integer},
|
|
{:key => :supporter_ids, :name => :required},
|
|
{:key => :supporter_ids, :name => :is_array},
|
|
{:key => :supporter_ids, :name => :min_length},
|
|
{:key => :field_data, :name => :required},
|
|
{:key => :field_data, :name => :is_array},
|
|
{:key => :field_data, :name => :min_length}
|
|
])
|
|
|
|
})
|
|
end
|
|
|
|
it 'validate nonprofit existence' do
|
|
expect {InsertCustomFieldJoins.find_or_create(5, [555], [[1, 1]])}.to(raise_error {|error|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
|
expect_validation_errors(error.data, [
|
|
{:key => :np_id}
|
|
])
|
|
|
|
expect(error.message).to eq "5 is not a valid non-profit"
|
|
})
|
|
end
|
|
|
|
it 'validate supporter in nonprofit' do
|
|
expect {InsertCustomFieldJoins.find_or_create(nonprofit.id, [other_supporter.id], [[1, 1]])}.to(raise_error {|error|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
|
expect_validation_errors(error.data, [
|
|
{:key => :supporter_ids}
|
|
])
|
|
|
|
expect(error.message).to eq "#{other_supporter.id} is not a valid supporter for nonprofit #{nonprofit.id}"
|
|
})
|
|
end
|
|
end
|
|
|
|
it 'run insert' do
|
|
|
|
new_cf_name = 'new cf name'
|
|
new_cf_value = 'value'
|
|
old_cf_value = 'old_cf_value'
|
|
expect(InsertCustomFieldJoins).to receive(:in_bulk) do |np_id, supporters_id, field_data|
|
|
expect(np_id).to eq nonprofit.id
|
|
expect(supporters_id).to eq [supporter.id]
|
|
expect(field_data.length).to eq 2
|
|
expect(field_data).to include( { :custom_field_master_id => initial_custom_field_master.id, :value => old_cf_value})
|
|
expect(field_data).to include( { :custom_field_master_id => CustomFieldMaster.where(:name => new_cf_name).first.id, :value => new_cf_value})
|
|
end
|
|
result = InsertCustomFieldJoins.find_or_create(nonprofit.id, [supporter.id], [
|
|
[
|
|
initial_custom_field_master.name,
|
|
old_cf_value
|
|
],
|
|
[
|
|
new_cf_name,
|
|
new_cf_value
|
|
]])
|
|
expect(CustomFieldMaster.count).to eq 2
|
|
end
|
|
|
|
end
|
|
|
|
|
|
describe '.in_bulk' do
|
|
context 'parameter validation' do
|
|
it 'should validate parameters' do
|
|
|
|
response = InsertCustomFieldJoins::in_bulk(nil, nil, nil)
|
|
errors = response[:json][:errors]
|
|
expect(errors.length).to eq(6)
|
|
expect(response[:status]).to eq (:unprocessable_entity)
|
|
expect_validation_errors(errors, [
|
|
{key: :np_id, name: :required},
|
|
{key: :np_id, name: :is_integer},
|
|
{key: :supporter_ids, name: :required},
|
|
{key: :supporter_ids, name: :is_array},
|
|
{key: :field_data, name: :is_array},
|
|
{key: :field_data, name: :required}
|
|
])
|
|
|
|
end
|
|
context 'requiring db' do
|
|
|
|
before(:each) {
|
|
@nonprofit = force_create(:nonprofit)
|
|
@bad_nonprofit = force_create(:nonprofit, :id => 50)
|
|
}
|
|
it 'nonprofit must be valid' do
|
|
response = InsertCustomFieldJoins::in_bulk(@nonprofit.id+1, [], [])
|
|
expect(response[:status]).to eq (:unprocessable_entity)
|
|
expect(response[:json][:error]).to include("Nonprofit #{@nonprofit.id+1} is not valid")
|
|
end
|
|
|
|
it 'supporters if empty should do nothing' do
|
|
response = InsertCustomFieldJoins::in_bulk(@nonprofit.id, [], [])
|
|
expect(response).to eq(successful_json(0, 0))
|
|
end
|
|
|
|
it 'supporters if empty should do nothing' do
|
|
response = InsertCustomFieldJoins::in_bulk(@nonprofit.id, [50], [])
|
|
expect(response).to eq(successful_json(0, 0))
|
|
end
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
context 'main testing' do
|
|
before(:each) {
|
|
@nonprofit = force_create(:nonprofit)
|
|
|
|
@random_supporter = create(:supporter)
|
|
|
|
@other_nonprofit = force_create(:nonprofit)
|
|
@delete_cfm= [20, 40, 60]
|
|
@add_cfm = [25, 35]
|
|
|
|
|
|
@supporters = {
|
|
:np_supporter_with_add => {
|
|
:cfm_ids => [65, 75, 85]
|
|
},
|
|
:np_supporter_with_cfms_to_delete => {
|
|
:cfm_ids => [40, 75, 85]
|
|
},
|
|
|
|
:np_supporter_with_no_changes => {
|
|
:cfm_ids => @add_cfm
|
|
},
|
|
:np_supporter_with_some_of_both => {
|
|
|
|
:cfm_ids => [20, 35]
|
|
},
|
|
:supporter_from_other_np => {
|
|
:cfm_ids => [100, 150, 200],
|
|
:other_np => true
|
|
}
|
|
|
|
}
|
|
|
|
@supporters.each_key {|k|
|
|
i = @supporters[k]
|
|
nonprofit_for_supporter =i[:other_np] ? @other_nonprofit : @nonprofit
|
|
i[:entity] = create(:supporter, :nonprofit => nonprofit_for_supporter)
|
|
i[:cfm_ids].each {|j|
|
|
|
|
cfm = CustomFieldMaster.exists?(id: j) ? CustomFieldMaster.find(j) : create(:custom_field_master, id: j, nonprofit: nonprofit_for_supporter, name: "CFM #{j}")
|
|
|
|
create(:custom_field_join, :value_from_id, :supporter_id => i[:entity].id, :custom_field_master => cfm)
|
|
}
|
|
}
|
|
}
|
|
|
|
it 'invalid nonprofit-supporter combo returns okay' do
|
|
results = InsertCustomFieldJoins::in_bulk(@nonprofit.id, [@supporters[:supporter_from_other_np][:entity].id], [])
|
|
expect(results).to eq(successful_json(0, 0))
|
|
end
|
|
|
|
|
|
it 'strips cfms which dont belong to nonprofit' do
|
|
results = InsertCustomFieldJoins::in_bulk(@nonprofit.id, [@supporters[:np_supporter_with_add][:entity].id],
|
|
create_cfm_data([100], [150]))
|
|
expect(results).to eq(successful_json(0, 0))
|
|
|
|
expect(CustomFieldJoin.where('supporter_id = ? and custom_field_master_id = ?', @supporters[:np_supporter_with_add][:entity].id, 100).count).to eq 0
|
|
|
|
end
|
|
|
|
it 'delete' do
|
|
|
|
expect(CustomFieldJoin.count).to eq 13
|
|
@supporters[:np_supporter_with_some_of_both][:entity].id
|
|
|
|
results = InsertCustomFieldJoins::in_bulk(@nonprofit.id,
|
|
[@supporters[:np_supporter_with_some_of_both][:entity].id, @supporters[:np_supporter_with_cfms_to_delete][:entity].id, @supporters[:np_supporter_with_add][:entity].id, @supporters[:supporter_from_other_np][:entity].id, @supporters[:np_supporter_with_no_changes][:entity].id],
|
|
create_cfm_data(@add_cfm, @delete_cfm))
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ? ", @supporters[:np_supporter_with_some_of_both][:entity].id).count).to eq 2
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ?", @supporters[:np_supporter_with_add][:entity].id).count).to eq 5
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ?", @supporters[:np_supporter_with_cfms_to_delete][:entity].id).count).to eq 4
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ?", @supporters[:supporter_from_other_np][:entity].id).count).to eq 3
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ?", @supporters[:np_supporter_with_no_changes][:entity].id).count).to eq 2
|
|
|
|
expect(CustomFieldJoin.count).to eq 16
|
|
|
|
|
|
end
|
|
|
|
it 'id, updated_at, created_at changes are stripped' do
|
|
|
|
invalid_id = 10000000
|
|
Timecop.freeze(2020, 9, 1, 12, 0, 0) {
|
|
results = InsertCustomFieldJoins::in_bulk(@nonprofit.id,
|
|
[@supporters[:np_supporter_with_add][:entity].id],
|
|
[{custom_field_master_id: 25, value: "CFM value 25", id: invalid_id, created_at: Time.now.ago(3000), updated_at: Time.now.ago(2999)}])
|
|
expected = {custom_field_master_id: 25, value: "CFM value 25", created_at: Time.now, updated_at: Time.now, supporter_id: @supporters[:np_supporter_with_add][:entity].id}.with_indifferent_access
|
|
|
|
expect(results).to eq(successful_json(1, 0))
|
|
|
|
result_tag = @supporters[:np_supporter_with_add][:entity].custom_field_joins.where('custom_field_master_id = ?', 25).first
|
|
|
|
expect(result_tag.attributes.with_indifferent_access.reject {|k, _| k == 'id'}).to eq(expected)
|
|
|
|
expect(result_tag.attributes[:id]).to_not eq invalid_id
|
|
}
|
|
end
|
|
|
|
it 'add_to_one' do
|
|
|
|
expect(CustomFieldJoin.count).to eq 13
|
|
|
|
np_supporter_with_add_cfms = @supporters[:np_supporter_with_add][:entity].custom_field_joins.to_a
|
|
np_supporter_with_some_of_both_cfms = @supporters[:np_supporter_with_some_of_both][:entity].custom_field_joins.to_a
|
|
np_supporter_with_no_changes_cfms = @supporters[:np_supporter_with_no_changes][:entity].custom_field_joins.to_a
|
|
|
|
Timecop.travel(20) {
|
|
|
|
|
|
results = InsertCustomFieldJoins::in_bulk(@nonprofit.id,
|
|
[
|
|
@supporters[:np_supporter_with_add][:entity].id, #add 2
|
|
@supporters[:np_supporter_with_no_changes][:entity], # update 2
|
|
@supporters[:np_supporter_with_some_of_both][:entity].id], #add 2, delete 1
|
|
create_cfm_data(@add_cfm, @delete_cfm))
|
|
|
|
expect(results).to eq(successful_json(6, 1))
|
|
|
|
|
|
expect(@supporters[:np_supporter_with_no_changes][:entity].custom_field_joins).to match_array(np_supporter_with_no_changes_cfms)
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ? ", @supporters[:np_supporter_with_add][:entity].id).count).to eq 5
|
|
|
|
original_db_pairs = get_original_and_db(np_supporter_with_add_cfms, CustomFieldJoin.where("supporter_id = ? and custom_field_master_id in (?)",
|
|
@supporters[:np_supporter_with_add][:entity].id,
|
|
@supporters[:np_supporter_with_add][:cfm_ids]).pluck(:id))
|
|
|
|
original_db_pairs.each {|orig, db|
|
|
expect(db.attributes.length).to eq(orig.attributes.length)
|
|
expect(db.attributes).to eq(orig.attributes)
|
|
}
|
|
|
|
expect(CustomFieldJoin.where("supporter_id = ?", @supporters[:np_supporter_with_some_of_both][:entity].id).count).to eq 2
|
|
|
|
|
|
original_db_pairs = get_original_and_db(np_supporter_with_some_of_both_cfms, CustomFieldJoin.where("supporter_id = ? and custom_field_master_id in (?)",
|
|
@supporters[:np_supporter_with_some_of_both][:entity].id,
|
|
[35]).pluck(:id))
|
|
skip_attribs = ['updated_at', 'value']
|
|
original_db_pairs.each {|orig, db|
|
|
expect(db.attributes.length).to eq(orig.attributes.length)
|
|
expect(db.attributes.select {|key, value| !skip_attribs.include?(key)}).to eq(orig.attributes.select {|key, value| !skip_attribs.include?(key)})
|
|
expect(db.attributes['updated_at']).to be > orig.attributes['updated_at']
|
|
expect(db.attributes['value']).to eq "CFM value 35"
|
|
|
|
|
|
}
|
|
|
|
expect(CustomFieldJoin.count).to eq 15
|
|
|
|
}
|
|
|
|
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
def successful_json(inserted, deleted)
|
|
{:json => {:inserted_count => inserted, :removed_count => deleted}, :status => :ok}
|
|
end
|
|
|
|
def create_cfm_data(cfm_to_add =[], cfm_to_delete=[])
|
|
use_nil = true
|
|
cfm_to_add.map {|cfm| {custom_field_master_id: cfm, value: "CFM value #{cfm}"}} + cfm_to_delete.map {|cfm|
|
|
value = use_nil ? nil : ''
|
|
use_nil = !use_nil
|
|
|
|
{custom_field_master_id: cfm, value: value}}
|
|
end
|
|
|
|
def get_original_and_db(original_items, ids_to_verify)
|
|
ids_to_verify.map {|i|
|
|
original_item = original_items.find {|oi| oi[:id] == i}
|
|
db_item = CustomFieldJoin.find(i)
|
|
[original_item, db_item]
|
|
}
|
|
end
|
|
end
|