2019-07-30 21:29:24 +00:00
# frozen_string_literal: true
2020-06-12 20:03:43 +00:00
# License: AGPL-3.0-or-later WITH WTO-AP-3.0-or-later
# Full license explanation at https://github.com/houdiniproject/houdini/blob/master/LICENSE
2018-03-25 17:30:42 +00:00
require 'rails_helper'
describe InsertCustomFieldJoins do
describe '.find_or_create' do
2020-04-16 20:50:03 +00:00
let ( :nonprofit ) { force_create ( :nm_justice ) }
let ( :other_nonprofit ) { force_create ( :fv_poverty ) }
2019-07-30 21:29:24 +00:00
let ( :supporter ) { force_create ( :supporter , nonprofit : nonprofit ) }
let ( :other_supporter ) { force_create ( :supporter , nonprofit : other_nonprofit ) }
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
let ( :initial_custom_field_master ) { force_create ( :custom_field_master , nonprofit : nonprofit , name : 'CFM Name' ) }
2018-03-25 17:30:42 +00:00
describe 'param validation' do
it 'basic validation' do
2019-07-30 21:29:24 +00:00
expect { InsertCustomFieldJoins . find_or_create ( nil , nil , nil ) } . to ( raise_error do | error |
2018-03-25 17:30:42 +00:00
expect ( error ) . to be_a ParamValidation :: ValidationError
expect_validation_errors ( error . data , [
2019-07-30 21:29:24 +00:00
{ 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 )
2018-03-25 17:30:42 +00:00
end
it 'validate nonprofit existence' do
2019-07-30 21:29:24 +00:00
expect { InsertCustomFieldJoins . find_or_create ( 5 , [ 555 ] , [ [ 1 , 1 ] ] ) } . to ( raise_error do | error |
2018-03-25 17:30:42 +00:00
expect ( error ) . to be_a ParamValidation :: ValidationError
expect_validation_errors ( error . data , [
2019-07-30 21:29:24 +00:00
{ key : :np_id }
] )
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( error . message ) . to eq '5 is not a valid non-profit'
end )
2018-03-25 17:30:42 +00:00
end
it 'validate supporter in nonprofit' do
2019-07-30 21:29:24 +00:00
expect { InsertCustomFieldJoins . find_or_create ( nonprofit . id , [ other_supporter . id ] , [ [ 1 , 1 ] ] ) } . to ( raise_error do | error |
2018-03-25 17:30:42 +00:00
expect ( error ) . to be_a ParamValidation :: ValidationError
expect_validation_errors ( error . data , [
2019-07-30 21:29:24 +00:00
{ key : :supporter_ids }
] )
2018-03-25 17:30:42 +00:00
expect ( error . message ) . to eq " #{ other_supporter . id } is not a valid supporter for nonprofit #{ nonprofit . id } "
2019-07-30 21:29:24 +00:00
end )
2018-03-25 17:30:42 +00:00
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
2019-07-30 21:29:24 +00:00
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 )
2018-03-25 17:30:42 +00:00
end
result = InsertCustomFieldJoins . find_or_create ( nonprofit . id , [ supporter . id ] , [
2019-07-30 21:29:24 +00:00
[
initial_custom_field_master . name ,
old_cf_value
] ,
[
new_cf_name ,
new_cf_value
]
] )
2018-03-25 17:30:42 +00:00
expect ( CustomFieldMaster . count ) . to eq 2
end
end
describe '.in_bulk' do
context 'parameter validation' do
it 'should validate parameters' do
2019-07-30 21:29:24 +00:00
response = InsertCustomFieldJoins . in_bulk ( nil , nil , nil )
2018-03-25 17:30:42 +00:00
errors = response [ :json ] [ :errors ]
expect ( errors . length ) . to eq ( 6 )
2019-07-30 21:29:24 +00:00
expect ( response [ :status ] ) . to eq :unprocessable_entity
2018-03-25 17:30:42 +00:00
expect_validation_errors ( errors , [
2019-07-30 21:29:24 +00:00
{ 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 }
] )
2018-03-25 17:30:42 +00:00
end
context 'requiring db' do
2019-07-30 21:29:24 +00:00
before ( :each ) do
2020-04-16 20:50:03 +00:00
@nonprofit = force_create ( :nm_justice )
@bad_nonprofit = force_create ( :fv_poverty , id : 50 )
2019-07-30 21:29:24 +00:00
end
2018-03-25 17:30:42 +00:00
it 'nonprofit must be valid' do
2019-07-30 21:29:24 +00:00
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 " )
2018-03-25 17:30:42 +00:00
end
it 'supporters if empty should do nothing' do
2019-07-30 21:29:24 +00:00
response = InsertCustomFieldJoins . in_bulk ( @nonprofit . id , [ ] , [ ] )
2018-03-25 17:30:42 +00:00
expect ( response ) . to eq ( successful_json ( 0 , 0 ) )
end
it 'supporters if empty should do nothing' do
2019-07-30 21:29:24 +00:00
response = InsertCustomFieldJoins . in_bulk ( @nonprofit . id , [ 50 ] , [ ] )
2018-03-25 17:30:42 +00:00
expect ( response ) . to eq ( successful_json ( 0 , 0 ) )
end
end
end
context 'main testing' do
2019-07-30 21:29:24 +00:00
before ( :each ) do
2020-04-16 20:50:03 +00:00
@nonprofit = force_create ( :nm_justice )
@other_nonprofit = force_create ( :fv_poverty )
@random_supporter = create ( :supporter , nonprofit : @other_nonprofit )
2018-03-25 17:30:42 +00:00
2020-04-16 20:50:03 +00:00
2019-07-30 21:29:24 +00:00
@delete_cfm = [ 20 , 40 , 60 ]
2018-03-25 17:30:42 +00:00
@add_cfm = [ 25 , 35 ]
@supporters = {
2019-07-30 21:29:24 +00:00
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
}
2018-03-25 17:30:42 +00:00
}
2019-07-30 21:29:24 +00:00
@supporters . each_key do | k |
2018-03-25 17:30:42 +00:00
i = @supporters [ k ]
2019-07-30 21:29:24 +00:00
nonprofit_for_supporter = i [ :other_np ] ? @other_nonprofit : @nonprofit
i [ :entity ] = create ( :supporter , nonprofit : nonprofit_for_supporter )
i [ :cfm_ids ] . each do | j |
2018-03-25 17:30:42 +00:00
cfm = CustomFieldMaster . exists? ( id : j ) ? CustomFieldMaster . find ( j ) : create ( :custom_field_master , id : j , nonprofit : nonprofit_for_supporter , name : " CFM #{ j } " )
2019-07-30 21:29:24 +00:00
create ( :custom_field_join , :value_from_id , supporter_id : i [ :entity ] . id , custom_field_master : cfm )
end
end
end
2018-03-25 17:30:42 +00:00
it 'invalid nonprofit-supporter combo returns okay' do
2019-07-30 21:29:24 +00:00
results = InsertCustomFieldJoins . in_bulk ( @nonprofit . id , [ @supporters [ :supporter_from_other_np ] [ :entity ] . id ] , [ ] )
2018-03-25 17:30:42 +00:00
expect ( results ) . to eq ( successful_json ( 0 , 0 ) )
end
it 'strips cfms which dont belong to nonprofit' do
2019-07-30 21:29:24 +00:00
results = InsertCustomFieldJoins . in_bulk ( @nonprofit . id , [ @supporters [ :np_supporter_with_add ] [ :entity ] . id ] ,
create_cfm_data ( [ 100 ] , [ 150 ] ) )
2018-03-25 17:30:42 +00:00
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
2019-07-30 21:29:24 +00:00
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 ) )
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ? ' , @supporters [ :np_supporter_with_some_of_both ] [ :entity ] . id ) . count ) . to eq 2
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ?' , @supporters [ :np_supporter_with_add ] [ :entity ] . id ) . count ) . to eq 5
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ?' , @supporters [ :np_supporter_with_cfms_to_delete ] [ :entity ] . id ) . count ) . to eq 4
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ?' , @supporters [ :supporter_from_other_np ] [ :entity ] . id ) . count ) . to eq 3
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ?' , @supporters [ :np_supporter_with_no_changes ] [ :entity ] . id ) . count ) . to eq 2
2018-03-25 17:30:42 +00:00
expect ( CustomFieldJoin . count ) . to eq 16
end
it 'id, updated_at, created_at changes are stripped' do
2019-07-30 21:29:24 +00:00
invalid_id = 10_000_000
Timecop . freeze ( 2020 , 9 , 1 , 12 , 0 , 0 ) do
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
2018-03-25 17:30:42 +00:00
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
2019-07-30 21:29:24 +00:00
expect ( result_tag . attributes . with_indifferent_access . reject { | k , _ | k == 'id' } ) . to eq ( expected )
2018-03-25 17:30:42 +00:00
expect ( result_tag . attributes [ :id ] ) . to_not eq invalid_id
2019-07-30 21:29:24 +00:00
end
2018-03-25 17:30:42 +00:00
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
2019-07-30 21:29:24 +00:00
Timecop . travel ( 20 ) do
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 ) )
2018-03-25 17:30:42 +00:00
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 )
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ? ' , @supporters [ :np_supporter_with_add ] [ :entity ] . id ) . count ) . to eq 5
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
original_db_pairs = get_original_and_db ( np_supporter_with_add_cfms , CustomFieldJoin . where ( 'supporter_id = ? and custom_field_master_id in (?)' ,
2018-03-25 17:30:42 +00:00
@supporters [ :np_supporter_with_add ] [ :entity ] . id ,
@supporters [ :np_supporter_with_add ] [ :cfm_ids ] ) . pluck ( :id ) )
2019-07-30 21:29:24 +00:00
original_db_pairs . each do | orig , db |
2018-03-25 17:30:42 +00:00
expect ( db . attributes . length ) . to eq ( orig . attributes . length )
expect ( db . attributes ) . to eq ( orig . attributes )
2019-07-30 21:29:24 +00:00
end
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
expect ( CustomFieldJoin . where ( 'supporter_id = ?' , @supporters [ :np_supporter_with_some_of_both ] [ :entity ] . id ) . count ) . to eq 2
2018-03-25 17:30:42 +00:00
2019-07-30 21:29:24 +00:00
original_db_pairs = get_original_and_db ( np_supporter_with_some_of_both_cfms , CustomFieldJoin . where ( 'supporter_id = ? and custom_field_master_id in (?)' ,
2018-03-25 17:30:42 +00:00
@supporters [ :np_supporter_with_some_of_both ] [ :entity ] . id ,
[ 35 ] ) . pluck ( :id ) )
2019-07-30 21:29:24 +00:00
skip_attribs = %w[ updated_at value ]
original_db_pairs . each do | orig , db |
2018-03-25 17:30:42 +00:00
expect ( db . attributes . length ) . to eq ( orig . attributes . length )
2019-07-30 21:29:24 +00:00
expect ( db . attributes . reject { | key , _value | skip_attribs . include? ( key ) } ) . to eq ( orig . attributes . reject { | key , _value | skip_attribs . include? ( key ) } )
2018-03-25 17:30:42 +00:00
expect ( db . attributes [ 'updated_at' ] ) . to be > orig . attributes [ 'updated_at' ]
2019-07-30 21:29:24 +00:00
expect ( db . attributes [ 'value' ] ) . to eq 'CFM value 35'
end
2018-03-25 17:30:42 +00:00
expect ( CustomFieldJoin . count ) . to eq 15
2019-07-30 21:29:24 +00:00
end
2018-03-25 17:30:42 +00:00
end
end
end
def successful_json ( inserted , deleted )
2019-07-30 21:29:24 +00:00
{ json : { inserted_count : inserted , removed_count : deleted } , status : :ok }
2018-03-25 17:30:42 +00:00
end
2019-07-30 21:29:24 +00:00
def create_cfm_data ( cfm_to_add = [ ] , cfm_to_delete = [ ] )
2018-03-25 17:30:42 +00:00
use_nil = true
2019-07-30 21:29:24 +00:00
cfm_to_add . map { | cfm | { custom_field_master_id : cfm , value : " CFM value #{ cfm } " } } + cfm_to_delete . map do | cfm |
value = use_nil ? nil : ''
use_nil = ! use_nil
{ custom_field_master_id : cfm , value : value }
end
2018-03-25 17:30:42 +00:00
end
def get_original_and_db ( original_items , ids_to_verify )
2019-07-30 21:29:24 +00:00
ids_to_verify . map do | i |
original_item = original_items . find { | oi | oi [ :id ] == i }
2018-03-25 17:30:42 +00:00
db_item = CustomFieldJoin . find ( i )
[ original_item , db_item ]
2019-07-30 21:29:24 +00:00
end
2018-03-25 17:30:42 +00:00
end
end