houdini/spec/lib/export/export_recurring_donations_spec.rb

197 lines
8.9 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
require 'rails_helper'
require 'support/test_upload_service'
describe ExportRecurringDonations do
before(:each) do
stub_const('CHUNKED_UPLOAD_SERVICE', TestUploadService.new)
@email = 'example@example.com'
@user = force_create(:user, email: @email)
@nonprofit = force_create(:nm_justice)
@supporters = [force_create(:supporter, name: 'supporter-0', nonprofit: @nonprofit),
force_create(:supporter, name: 'supporter-1', nonprofit: @nonprofit)]
@donations = [force_create(:donation, nonprofit: @nonprofit, supporter: @supporters[0]),
force_create(:donation, nonprofit: @nonprofit, supporter: @supporters[1])]
@recurring_donations = [force_create(:recurring_donation, donation: @donations[0], nonprofit: @nonprofit, edit_token: 'edit_token_1', active: true),
force_create(:recurring_donation, donation: @donations[1], supporter: @supporters[1], nonprofit: @nonprofit, edit_token: 'edit_token_2', active: true)]
CHUNKED_UPLOAD_SERVICE.clear
end
let(:export_url_regex) { /http:\/\/fake\.url\/tmp\/csv-exports\/recurring_donations-04-06-2020--01-02-03-#{UUID::Regex}\.csv/}
context '.initiate_export' do
context 'param verification' do
it 'performs initial verification' do
expect { ExportRecurringDonations.initiate_export(nil, nil, nil) }.to(raise_error do |error|
expect(error).to be_a(ParamValidation::ValidationError)
expect(error.data.length).to eq(6)
expect_validation_errors(error.data, [{ key: 'npo_id', name: :required },
{ key: 'npo_id', name: :is_integer },
{ key: 'user_id', name: :required },
{ key: 'user_id', name: :is_integer },
{ key: 'params', name: :required },
{ key: 'params', name: :is_hash }])
end)
end
it 'nonprofit doesnt exist' do
fake_npo = 8_888_881
expect { ExportRecurringDonations.initiate_export(fake_npo, {}, 8_888_883) }.to(raise_error do |error|
expect(error).to be_a(ParamValidation::ValidationError)
expect(error.message).to eq "Nonprofit #{fake_npo} doesn't exist!"
end)
end
it 'user doesnt exist' do
fake_user = 8_888_883
expect { ExportRecurringDonations.initiate_export(@nonprofit.id, {}, fake_user) }.to(raise_error do |error|
expect(error).to be_a(ParamValidation::ValidationError)
expect(error.message).to eq "User #{fake_user} doesn't exist!"
end)
end
end
it 'creates an export object and schedules job' do
Timecop.freeze(2020, 4, 5) do
params = { param1: 'pp', root_url: 'https://localhost:8080' }.with_indifferent_access
2019-11-07 23:24:09 +00:00
expect {
ExportRecurringDonations.initiate_export(@nonprofit.id, params, @user.id)
2019-11-08 19:12:55 +00:00
}.to have_enqueued_job(RecurringDonationsExportCreateJob)
export = Export.first
expected_export = { id: export.id,
user_id: @user.id,
nonprofit_id: @nonprofit.id,
status: 'queued',
export_type: 'ExportRecurringDonations',
parameters: params.to_json,
updated_at: Time.now,
created_at: Time.now,
url: nil,
ended: nil,
exception: nil }.with_indifferent_access
expect(export.attributes).to eq(expected_export)
end
end
end
context '.run_export' do
context 'param validation' do
it 'rejects basic invalid data' do
expect { ExportRecurringDonations.run_export(nil, nil, nil, nil) }.to(raise_error do |error|
expect(error).to be_a(ParamValidation::ValidationError)
expect_validation_errors(error, [{ key: 'npo_id', name: :required },
{ key: 'npo_id', name: :is_integer },
{ key: 'user_id', name: :required },
{ key: 'user_id', name: :is_integer },
{ key: 'params', name: :required },
{ key: 'params', name: :is_json },
{ key: 'export_id', name: :required },
{ key: 'export_id', name: :is_integer }])
end)
end
it 'rejects json which isnt a hash' do
expect { ExportRecurringDonations.run_export(1, [{ item: '' }, { item: '' }].to_json, 1, 1) }.to(raise_error do |error|
expect(error).to be_a(ParamValidation::ValidationError)
expect_validation_errors(error, [
{ key: :params, name: :is_hash }
])
end)
end
it 'no export throw an exception' do
expect { ExportRecurringDonations.run_export(0, { x: 1 }.to_json, 0, 11_111) }.to(raise_error do |error|
expect(error).to be_a ParamValidation::ValidationError
expect(error.data[:key]).to eq :export_id
expect(error.message).to start_with('Export')
end)
end
it 'no nonprofit' do
Timecop.freeze(2020, 4, 5) do
@export = force_create(:export, user: @user)
Timecop.freeze(2020, 4, 6) do
expect { ExportRecurringDonations.run_export(0, { x: 1 }.to_json, @user.id, @export.id) }.to(raise_error do |error|
expect(error).to be_a ParamValidation::ValidationError
expect(error.data[:key]).to eq :npo_id
expect(error.message).to start_with('Nonprofit')
@export.reload
expect(@export.status).to eq 'failed'
expect(@export.exception).to eq error.to_s
expect(@export.ended).to eq Time.now
expect(@export.updated_at).to eq Time.now
end)
end
end
end
it 'no user' do
Timecop.freeze(2020, 4, 5) do
@export = force_create(:export, user: @user)
Timecop.freeze(2020, 4, 6) do
expect { ExportRecurringDonations.run_export(@nonprofit.id, { x: 1 }.to_json, 0, @export.id) }.to(raise_error do |error|
expect(error).to be_a ParamValidation::ValidationError
expect(error.data[:key]).to eq :user_id
expect(error.message).to start_with('User')
@export.reload
expect(@export.status).to eq 'failed'
expect(@export.exception).to eq error.to_s
expect(@export.ended).to eq Time.now
expect(@export.updated_at).to eq Time.now
end)
end
end
end
end
it 'handles exception in upload properly' do
Timecop.freeze(2020, 4, 5) do
@export = force_create(:export, user: @user)
CHUNKED_UPLOAD_SERVICE.raise_error
Timecop.freeze(2020, 4, 6) do
expect { ExportRecurringDonations.run_export(@nonprofit.id, {}.to_json, @user.id, @export.id) }.to(raise_error do |error|
expect(error).to be_a StandardError
expect(error.message).to eq TestUploadService::TEST_ERROR_MESSAGE
@export.reload
expect(@export.status).to eq 'failed'
expect(@export.exception).to eq error.to_s
expect(@export.ended).to eq Time.now
expect(@export.updated_at).to eq Time.now
end)
2019-11-08 19:12:55 +00:00
expect(ExportRecurringDonationsFailedJob).to have_been_enqueued.with(@export)
end
end
end
it 'uploads as expected' do
Timecop.freeze(2020, 4, 5) do
@export = create(:export, user: @user, created_at: Time.now, updated_at: Time.now)
Timecop.freeze(2020, 4, 6, 1, 2, 3) do
ExportRecurringDonations.run_export(@nonprofit.id, { root_url: 'https://localhost:8080/' }.to_json, @user.id, @export.id)
2019-11-08 19:12:55 +00:00
expect(ExportRecurringDonationsCompletedJob).to have_been_enqueued.with(@export)
@export.reload
expect(@export.url).to match export_url_regex
expect(@export.status).to eq 'completed'
expect(@export.exception).to be_nil
expect(@export.ended).to eq Time.now
expect(@export.updated_at).to eq Time.now
csv = CSV.parse(CHUNKED_UPLOAD_SERVICE.output)
expect(csv.length).to eq 3
expect(csv[0]).to eq MockHelpers.recurring_donation_export_headers
expect(CHUNKED_UPLOAD_SERVICE.options[:content_type]).to eq 'text/csv'
expect(CHUNKED_UPLOAD_SERVICE.options[:content_disposition]).to eq 'attachment'
end
end
end
end
end