2018-03-25 16:15:39 +00:00
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
2018-03-25 17:30:42 +00:00
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