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 InsertDuplicate do
|
2019-07-30 21:29:24 +00:00
|
|
|
before(:all) do
|
2018-03-25 17:30:42 +00:00
|
|
|
Timecop.freeze(2020, 5, 5)
|
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
|
|
|
after(:all) do
|
2018-03-25 17:30:42 +00:00
|
|
|
Timecop.return
|
2019-07-30 21:29:24 +00:00
|
|
|
end
|
2020-04-16 20:50:03 +00:00
|
|
|
let(:nonprofit) { force_create(:nm_justice) }
|
2019-07-30 21:29:24 +00:00
|
|
|
let(:profile) { force_create(:profile) }
|
|
|
|
let(:dates) do
|
|
|
|
{
|
|
|
|
ten_days_from_now: DateTime.new(2020, 5, 15),
|
|
|
|
ten_days_from_now_plus_4_hours: DateTime.new(2020, 5, 15, 4),
|
|
|
|
two_days_from_now: DateTime.new(2020, 5, 7),
|
|
|
|
two_days_from_now_plus_4_hours: DateTime.new(2020, 5, 7, 4),
|
|
|
|
two_days_ago: DateTime.new(2020, 5, 3),
|
|
|
|
two_days_ago_plus_4_hours: DateTime.new(2020, 5, 3, 4)
|
|
|
|
}
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
describe '.campaign' do
|
|
|
|
def set_campaign_date(end_date)
|
|
|
|
@end_date = end_date
|
|
|
|
end
|
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
before(:each) do
|
2018-03-25 17:30:42 +00:00
|
|
|
set_campaign_date(dates[:ten_days_from_now])
|
2019-07-30 21:29:24 +00:00
|
|
|
end
|
|
|
|
let(:campaign) { force_create(:campaign, name: campaign_name, nonprofit: nonprofit, end_datetime: @end_date, slug: campaign_slug, goal_amount: 20_000, published: true, profile: profile) }
|
|
|
|
|
|
|
|
let(:campaign_gift_option) { force_create(:campaign_gift_option, name: cgo_name, campaign: campaign) }
|
|
|
|
let(:cgo_name) { 'cgo name' }
|
|
|
|
let(:campaign_name) { 'campaign_name is so long that it must be shortened down' }
|
|
|
|
let(:copy_name) { 'campaign_name is so long that it must b (2020-05-05 copy) 00' }
|
|
|
|
let(:campaign_slug) { 'campaign_slug' }
|
|
|
|
let(:copy_slug) { 'campaign_slug_copy_00' }
|
|
|
|
let(:common_result_attributes) do
|
2018-03-25 17:30:42 +00:00
|
|
|
{
|
2019-07-30 21:29:24 +00:00
|
|
|
nonprofit_id: nonprofit.id,
|
|
|
|
parent_campaign_id: nil,
|
|
|
|
reason_for_supporting: nil,
|
|
|
|
profile_id: profile.id,
|
|
|
|
background_image: nil,
|
|
|
|
body: nil,
|
|
|
|
created_at: Time.now,
|
|
|
|
deleted: nil,
|
|
|
|
goal_amount: 20_000,
|
|
|
|
hide_activity_feed: nil,
|
|
|
|
hide_custom_amounts: nil,
|
|
|
|
hide_goal: nil,
|
|
|
|
hide_thermometer: nil,
|
|
|
|
hide_title: nil,
|
|
|
|
main_image: nil,
|
|
|
|
published: false,
|
|
|
|
receipt_message: nil,
|
|
|
|
recurring_fund: nil,
|
|
|
|
show_recurring_amount: false,
|
|
|
|
show_total_count: true,
|
|
|
|
show_total_raised: true,
|
|
|
|
summary: nil,
|
|
|
|
tagline: nil,
|
|
|
|
total_raised: nil,
|
|
|
|
total_supporters: 1,
|
|
|
|
updated_at: Time.now,
|
|
|
|
url: nil,
|
|
|
|
video_url: nil,
|
|
|
|
vimeo_video_id: nil,
|
|
|
|
youtube_video_id: nil,
|
|
|
|
banner_image: nil,
|
|
|
|
default_reason_for_supporting: nil,
|
|
|
|
name: copy_name,
|
|
|
|
|
|
|
|
slug: copy_slug,
|
|
|
|
external_identifier: nil
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
}.with_indifferent_access
|
2019-07-30 21:29:24 +00:00
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
describe 'param validation' do
|
|
|
|
it 'does basic validation' do
|
2019-07-30 21:29:24 +00:00
|
|
|
expect { InsertDuplicate.campaign(nil, nil) }.to(raise_error do |error|
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
2019-07-30 21:29:24 +00:00
|
|
|
expect_validation_errors(error.data, [{ key: :campaign_id, name: :required },
|
|
|
|
{ key: :campaign_id, name: :is_integer },
|
|
|
|
{ key: :profile_id, name: :required },
|
|
|
|
{ key: :profile_id, name: :is_integer }])
|
|
|
|
end)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does campaign existence validation' do
|
2019-07-30 21:29:24 +00:00
|
|
|
expect { InsertDuplicate.campaign(999, 999) }.to(raise_error do |error|
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
2019-07-30 21:29:24 +00:00
|
|
|
expect_validation_errors(error.data, [{ key: :campaign_id }])
|
|
|
|
end)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does profile existence validation' do
|
2019-07-30 21:29:24 +00:00
|
|
|
expect { InsertDuplicate.campaign(campaign.id, 999) }.to(raise_error do |error|
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
2019-07-30 21:29:24 +00:00
|
|
|
expect_validation_errors(error.data, [{ key: :profile_id }])
|
|
|
|
end)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
end
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a nonending campaign properly' do
|
|
|
|
set_campaign_date(nil)
|
|
|
|
campaign_gift_option
|
|
|
|
result = InsertDuplicate.campaign(campaign.id, profile.id)
|
|
|
|
expect(Campaign.count).to eq 2
|
|
|
|
|
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
|
|
|
end_datetime: nil,
|
|
|
|
banner_image: nil
|
|
|
|
).with_indifferent_access)
|
|
|
|
validate_cgo(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a soon to finish campaign properly' do
|
|
|
|
set_campaign_date(dates[:two_days_from_now])
|
|
|
|
campaign_gift_option
|
|
|
|
result = InsertDuplicate.campaign(campaign.id, profile.id)
|
|
|
|
expect(Campaign.count).to eq 2
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
end_datetime: Time.utc(2020, 5, 12)
|
|
|
|
).with_indifferent_access)
|
|
|
|
validate_cgo(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a finished campaign properly' do
|
|
|
|
set_campaign_date(dates[:two_days_ago])
|
|
|
|
campaign_gift_option
|
|
|
|
result = InsertDuplicate.campaign(campaign.id, profile.id)
|
|
|
|
expect(Campaign.count).to eq 2
|
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
end_datetime: Time.utc(2020, 5, 12)
|
|
|
|
).with_indifferent_access)
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
validate_cgo(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a future campaign properly' do
|
|
|
|
campaign_gift_option
|
|
|
|
result = InsertDuplicate.campaign(campaign.id, profile.id)
|
|
|
|
expect(Campaign.count).to eq 2
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
|
|
|
end_datetime: campaign.end_datetime.to_time
|
|
|
|
).with_indifferent_access)
|
|
|
|
validate_cgo(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
def validate_cgo(new_campaign)
|
|
|
|
old_campaign = campaign
|
|
|
|
expect(CampaignGiftOption.count).to eq 2
|
|
|
|
old_cgo = old_campaign.campaign_gift_options.first
|
|
|
|
new_cgo = new_campaign.campaign_gift_options.first
|
|
|
|
expect(old_cgo.id).to_not eq new_cgo.id
|
|
|
|
expect(old_cgo.campaign_id).to_not eq new_cgo.campaign_id
|
2019-07-30 21:29:24 +00:00
|
|
|
expect(old_cgo.attributes.except('id', 'campaign_id')).to eq new_cgo.attributes.except('id', 'campaign_id')
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.event' do
|
|
|
|
def set_event_start_time(start_time, end_time)
|
|
|
|
@start_time = start_time
|
|
|
|
@end_time = end_time
|
|
|
|
end
|
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
before(:each) do
|
2018-03-25 17:30:42 +00:00
|
|
|
set_event_start_time(dates[:ten_days_from_now], dates[:ten_days_from_now_plus_4_hours])
|
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
|
|
|
let(:event) do
|
|
|
|
force_create(:event, name: event_name, nonprofit: nonprofit, start_datetime: @start_time, end_datetime: @end_time, slug: event_slug, published: true, profile: profile)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
let(:ticket_level) { force_create(:ticket_level, name: ticket_level_name, amount_dollars: 500, event: event) }
|
|
|
|
let(:event_discount) { force_create(:event_discount, code: 'code', event: event) }
|
|
|
|
let(:cgo_name) { 'cgo name' }
|
|
|
|
let(:ticket_level_name) { 'cgo name' }
|
|
|
|
let(:event_name) { 'campaign_name is so long that it must be shortened down' }
|
|
|
|
let(:copy_name) { 'campaign_name is so long that it must b (2020-05-05 copy) 00' }
|
|
|
|
let(:event_slug) { 'campaign_slug' }
|
|
|
|
let(:copy_slug) { 'campaign_slug_copy_00' }
|
|
|
|
let(:common_result_attributes) do
|
2018-03-25 17:30:42 +00:00
|
|
|
{
|
2019-07-30 21:29:24 +00:00
|
|
|
nonprofit_id: nonprofit.id,
|
|
|
|
profile_id: profile.id,
|
|
|
|
background_image: nil,
|
|
|
|
body: nil,
|
|
|
|
created_at: Time.now,
|
|
|
|
deleted: nil,
|
|
|
|
hide_activity_feed: nil,
|
|
|
|
hide_title: nil,
|
|
|
|
main_image: nil,
|
|
|
|
published: false,
|
|
|
|
receipt_message: nil,
|
|
|
|
summary: nil,
|
|
|
|
tagline: nil,
|
|
|
|
total_raised: 0,
|
|
|
|
updated_at: Time.now,
|
|
|
|
name: copy_name,
|
|
|
|
slug: copy_slug,
|
|
|
|
address: '100 N Appleton St',
|
|
|
|
city: 'Appleton',
|
|
|
|
directions: nil,
|
|
|
|
location: nil,
|
|
|
|
organizer_email: nil,
|
|
|
|
state_code: 'WI',
|
|
|
|
venue_name: nil,
|
|
|
|
zip_code: nil,
|
|
|
|
show_total_count: false,
|
|
|
|
|
|
|
|
show_total_raised: false
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
}.with_indifferent_access
|
2019-07-30 21:29:24 +00:00
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
describe 'param validation' do
|
|
|
|
it 'does basic validation' do
|
2019-07-30 21:29:24 +00:00
|
|
|
expect { InsertDuplicate.event(nil, nil) }.to(raise_error do |error|
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
2019-07-30 21:29:24 +00:00
|
|
|
expect_validation_errors(error.data, [{ key: :event_id, name: :required },
|
|
|
|
{ key: :event_id, name: :is_integer },
|
|
|
|
{ key: :profile_id, name: :required },
|
|
|
|
{ key: :profile_id, name: :is_integer }])
|
|
|
|
end)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does event existence validation' do
|
2019-07-30 21:29:24 +00:00
|
|
|
expect { InsertDuplicate.event(999, 999) }.to(raise_error do |error|
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
2019-07-30 21:29:24 +00:00
|
|
|
expect_validation_errors(error.data, [{ key: :event_id }])
|
|
|
|
end)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does profile existence validation' do
|
2019-07-30 21:29:24 +00:00
|
|
|
expect { InsertDuplicate.event(event.id, 999) }.to(raise_error do |error|
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(error).to be_a ParamValidation::ValidationError
|
2019-07-30 21:29:24 +00:00
|
|
|
expect_validation_errors(error.data, [{ key: :profile_id }])
|
|
|
|
end)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a soon to start event properly' do
|
|
|
|
set_event_start_time(dates[:two_days_from_now], dates[:two_days_from_now_plus_4_hours])
|
|
|
|
ticket_level
|
|
|
|
event_discount
|
|
|
|
|
|
|
|
result = InsertDuplicate.event(event.id, profile.id)
|
|
|
|
expect(Event.count).to eq 2
|
|
|
|
result.attributes['start_datetime'] = result.attributes['start_datetime'].to_datetime
|
|
|
|
result.attributes['end_datetime'] = result.attributes['end_datetime'].to_datetime
|
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
|
|
|
start_datetime: DateTime.new(2020, 5, 12),
|
|
|
|
end_datetime: DateTime.new(2020, 5, 12, 4)
|
|
|
|
).with_indifferent_access)
|
|
|
|
validate_tls(result)
|
|
|
|
validate_eds(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a finished event properly' do
|
|
|
|
set_event_start_time(dates[:two_days_ago], dates[:two_days_ago_plus_4_hours])
|
|
|
|
ticket_level
|
|
|
|
event_discount
|
|
|
|
result = InsertDuplicate.event(event.id, profile.id)
|
|
|
|
expect(Event.count).to eq 2
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
result.attributes['start_datetime'] = result.attributes['start_datetime']
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
result.attributes['end_datetime'] = result.attributes['end_datetime'].to_datetime
|
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
start_datetime: Time.utc(2020, 5, 12),
|
|
|
|
end_datetime: Time.utc(2020, 5, 12, 4)
|
|
|
|
).with_indifferent_access)
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
validate_tls(result)
|
|
|
|
validate_eds(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
2019-07-30 21:29:24 +00:00
|
|
|
it 'copies a future event properly' do
|
|
|
|
ticket_level
|
|
|
|
event_discount
|
|
|
|
result = InsertDuplicate.event(event.id, profile.id)
|
|
|
|
expect(Event.count).to eq 2
|
|
|
|
result.attributes['start_datetime'] = result.attributes['start_datetime'].to_datetime
|
|
|
|
result.attributes['end_datetime'] = result.attributes['end_datetime'].to_datetime
|
|
|
|
expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge(
|
|
|
|
id: result.id,
|
|
|
|
start_datetime: event.start_datetime.to_time,
|
|
|
|
end_datetime: event.end_datetime.to_time
|
|
|
|
).with_indifferent_access)
|
|
|
|
validate_tls(result)
|
|
|
|
validate_eds(result)
|
|
|
|
end
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
def validate_tls(new_event)
|
|
|
|
old_event = event
|
|
|
|
expect(TicketLevel.count).to eq 2
|
|
|
|
old_tl = old_event.ticket_levels.first
|
|
|
|
new_tl = new_event.ticket_levels.first
|
|
|
|
expect(old_tl.id).to_not eq new_tl.id
|
|
|
|
expect(old_tl.event_id).to_not eq new_tl.event_id
|
2019-07-30 21:29:24 +00:00
|
|
|
expect(old_tl.attributes.except('id', 'event_id')).to eq new_tl.attributes.except('id', 'event_id')
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def validate_eds(new_event)
|
|
|
|
old_event = event
|
2021-01-13 22:59:34 +00:00
|
|
|
old_event.reload
|
2018-03-25 17:30:42 +00:00
|
|
|
expect(EventDiscount.count).to eq 2
|
2021-01-13 22:59:34 +00:00
|
|
|
old_ed = old_event.event_discounts.first
|
|
|
|
new_ed = new_event.event_discounts.first
|
|
|
|
expect(old_ed.id).to_not eq new_ed.id
|
|
|
|
expect(old_ed.event_id).to_not eq new_ed.event_id
|
|
|
|
expect(old_ed.attributes.except('id', 'event_id')).to eq new_ed.attributes.except('id', 'event_id')
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|