Skip to content

Commit

Permalink
Add object events for Ticket Purchase (#664)
Browse files Browse the repository at this point in the history
  • Loading branch information
wwahammy authored May 4, 2023
1 parent 1851d49 commit 47753ac
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 67 deletions.
43 changes: 41 additions & 2 deletions app/legacy_lib/insert_tickets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def self.create(data, skip_notifications=false)


result = {}

trx = entities[:supporter_id].transactions.build(amount:0, created:Time.current)
tktpur = trx.ticket_purchases.build
if gross_amount > 0
# Create offsite payment for tickets
if data[:kind] == 'offsite'
Expand All @@ -68,7 +69,20 @@ def self.create(data, skip_notifications=false)
# create payment and offsite payment
result['payment'] = create_payment(entities, gross_amount)
result['offsite_payment'] = create_offsite_payment(entities, gross_amount, data, result['payment'])


trx.assign_attributes(amount: result['payment'].gross_amount, created: result['payment'].date)


trx_charge = SubtransactionPayment.new(
legacy_payment: Payment.find(result['payment']['id']),
paymentable: OfflineTransactionCharge.new
)

subtrx = trx.build_subtransaction(
subtransactable: OfflineTransaction.new(amount: result['payment'].gross_amount),
subtransaction_payments:[
trx_charge
])
# Create charge for tickets
elsif data['kind'] == 'charge' || !data['kind']
source_token = QuerySourceToken.get_and_increment_source_token(data[:token],nil)
Expand Down Expand Up @@ -98,6 +112,19 @@ def self.create(data, skip_notifications=false)
if result['charge']['status'] == 'failed'
raise ChargeError.new(result['charge']['failure_message'])
end

trx.assign_attributes(amount: result['payment'].gross_amount, created: result['payment'].date)

trx_charge = SubtransactionPayment.new(
legacy_payment: Payment.find(result['payment']['id']),
paymentable: StripeTransactionCharge.new
)

subtrx = trx.build_subtransaction(
subtransactable: StripeTransaction.new(amount: result['payment'].gross_amount),
subtransaction_payments:[
trx_charge
])
else
raise ParamValidation::ValidationError.new("Ticket costs money but you didn't pay.", {key: :kind})
end
Expand All @@ -108,6 +135,18 @@ def self.create(data, skip_notifications=false)

result['tickets'] = generated_ticket_entities(data['tickets'], result, entities)

tktpur.tickets = result['tickets']

trx.save!
tktpur.save!
if subtrx
subtrx.save!
subtrx.subtransaction_payments.each(&:publish_created)
end

#tktpur.publish_created
trx.publish_created

# Create the activity rows for the tickets
InsertActivities.for_tickets(result['tickets'].map{|t| t.id})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# License: AGPL-3.0-or-later WITH WTO-AP-3.0-or-later
# Full license explanation at https://github.com/houdiniproject/houdini/blob/main/LICENSE

json.object 'ticket_purchase'

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

# License: AGPL-3.0-or-later WITH WTO-AP-3.0-or-later
# Full license explanation at https://github.com/houdiniproject/houdini/blob/main/LICENSE

json.partial! 'api_new/transaction_assignments/transaction_assignment',
transaction_assignment: event_entity.transaction_assignment,
__expand: build_json_expansion_path_tree(
'transaction',
'transaction.transaction_assignments',
'transaction.subtransaction.payments'
)
163 changes: 111 additions & 52 deletions spec/lib/insert/insert_tickets_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def generate_expected_tickets(data = {})
id: item[:id],
quantity: item[:quantity],
ticket_level_id: item[:ticket_level_id],
ticket_purchase_id: nil,
ticket_purchase_id: item[:ticket_purchase_id],
event_id: data[:event].id,
supporter_id: data[:supporter].id,
payment_id: data[:payment_id],
Expand Down Expand Up @@ -142,7 +142,7 @@ def success_expectations
{key: :amount, name: :is_integer},
{key: :amount, name: :required},
])
}
}.and not_change {ObjectEvent.count}

# test that the quantity ticket_level validation works (it really doesn't very well)
expect {InsertTickets.create(event_discount_id: 'etheht',
Expand All @@ -162,7 +162,7 @@ def success_expectations
{key: :token, name: :format},
{key: :offsite_payment, name: :is_hash}
])
}
}.and not_change {ObjectEvent.count}


end
Expand All @@ -180,7 +180,7 @@ def success_expectations
{key: :ticket_level_id, name: :is_reference},
{key: :ticket_level_id, name: :required}
])
}
}.and not_change {ObjectEvent.count}
end

it 'validates the offsite_payment hash' do
Expand All @@ -193,7 +193,7 @@ def success_expectations
expect_validation_errors(error.data, [
{key: :kind, name: :included_in}
])
}
}.and not_change {ObjectEvent.count}
end

# it 'errors out if token is invalid' do
Expand Down Expand Up @@ -243,7 +243,7 @@ def success_expectations
expect_validation_errors(error.data, [{key: :tickets}])
expect(error.message).to include 'deleted'
expect(error.message).to include "Ticket level #{ticket_level.id}"
}
}.and not_change {ObjectEvent.count}
end

it 'event is deleted' do
Expand All @@ -265,14 +265,14 @@ def success_expectations
expect_validation_errors(e.data, [{key: :event_discount_id}])
expect(e.message).to include "Event discount #{other_event_discount.id}"
expect(e.message).to include "event #{event.id}"
}
}.and not_change {ObjectEvent.count}
end
end

it 'verify ticket not available raises properly' do
expected_error = NotEnoughQuantityError.new(TicketLevel, nil, nil, nil)
expect(QueryTicketLevels).to receive(:verify_tickets_available).and_raise(expected_error)
expect {InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, amount: 1400)}.to raise_error(expected_error)
expect {InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, amount: 1400)}.to raise_error(expected_error).and not_change {ObjectEvent.count}
end

describe 'gross_amount > 0' do
Expand All @@ -288,37 +288,75 @@ def success_expectations
}

describe 'and kind == offsite' do
it 'errors without current_user' do
expect {InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, 'kind' => 'offsite', amount:1600)}.to raise_error {|e|
expect(e).to be_a AuthenticationError
}

describe 'errors without current_user' do
let(:result) {InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, 'kind' => 'offsite', amount:1600)}
it 'to raise error' do
expect { result }.to raise_error {|e|
expect(e).to be_a AuthenticationError
}.and not_change {ObjectEvent.count}
end
end

it 'errors with unauthorized current_user' do
expect(QueryRoles).to receive(:is_authorized_for_nonprofit?).with(user.id, nonprofit.id).and_return(false)
expect {InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, kind: 'offsite', current_user: user, amount:1600)}.to raise_error {|e|
expect(e).to be_a AuthenticationError
}
describe 'errors with unauthorized current_user' do
let(:result) { InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, kind: 'offsite', current_user: user, amount:1600) }
it 'raises error' do
expect(QueryRoles).to receive(:is_authorized_for_nonprofit?).with(user.id, nonprofit.id).and_return(false)
expect { result }.to raise_error {|e|
expect(e).to be_a AuthenticationError
}.and not_change {ObjectEvent.count}
end
end

it 'succeeds' do
success_expectations
expect(QueryRoles).to receive(:is_authorized_for_nonprofit?).with(user.id, nonprofit.id).and_return true
result = InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, kind: 'offsite', offsite_payment: {kind: 'check', check_number: 'fake_checknumber'}, current_user: user, amount: 1600)
expected = generate_expected_tickets(payment_id: result['payment'].id,
nonprofit: nonprofit,
supporter: supporter,
event: event,
gross_amount: 1600,
kind: 'OffsitePayment',
offsite_payment: {id: result['offsite_payment'].id, kind: 'check', check_number:'fake_checknumber'},
tickets: [{
id: result['tickets'][0]['id'],
quantity: 1,
ticket_level_id: ticket_level.id}])
expect(result['payment'].attributes).to eq expected[:payment]
expect(result['offsite_payment'].attributes).to eq expected[:offsite_payment]
expect(result['tickets'].map{|i| i.attributes}[0]).to eq expected[:tickets][0]
describe 'succeeds' do

let(:result ) {
expect(QueryRoles).to receive(:is_authorized_for_nonprofit?).with(user.id, nonprofit.id).and_return true
InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, kind: 'offsite', offsite_payment: {kind: 'check', check_number: 'fake_checknumber'}, current_user: user, amount: 1600)
}
it 'has normal results' do
success_expectations
ticket_purchase = result['tickets'][0].ticket_purchase
expected = generate_expected_tickets(payment_id: result['payment'].id,
nonprofit: nonprofit,
supporter: supporter,
event: event,
gross_amount: 1600,
kind: 'OffsitePayment',
offsite_payment: {id: result['offsite_payment'].id, kind: 'check', check_number:'fake_checknumber'},
tickets: [{
id: result['tickets'][0]['id'],
quantity: 1,
ticket_level_id: ticket_level.id,
ticket_purchase_id: ticket_purchase.id
}])
expect(result['payment'].attributes).to eq expected[:payment]
expect(result['offsite_payment'].attributes).to eq expected[:offsite_payment]
expect(result['tickets'].map{|i| i.attributes}[0]).to eq expected[:tickets][0]

expect(result['tickets'].map(&:ticket_purchase)).to contain_exactly TicketPurchase.last
end


it 'increases object events by 2' do
expect { result }.to change {ObjectEvent.count}.by(2)
end

it 'increases offline_transaction_charge.created by 1' do
expect { result }.to change {ObjectEvent.where(event_type: 'offline_transaction_charge.created').count}.by(1)
end

it 'increases transaction.created by 1' do
expect { result }.to change {ObjectEvent.where(event_type: 'transaction.created').count}.by(1)
end

it 'increases Transaction by 1' do
expect { result }.to change {Transaction.count}.by(1)
end

it 'increases TicketPurchase by 1' do
expect { result }.to change {TicketPurchase.count}.by(1)
end
end
end

Expand Down Expand Up @@ -458,6 +496,7 @@ def success(other_elements={})
stripe_charge_id = a['id']
a}
result = InsertTickets.create(include_valid_token.merge(event_discount_id:event_discount.id).merge(fee_covered: other_elements[:fee_covered], amount: other_elements[:amount]))
tp = result['tickets'][0].ticket_purchase
expected = generate_expected_tickets(
{gross_amount: other_elements[:amount],
payment_fee_total: other_elements[:fee],
Expand All @@ -472,11 +511,14 @@ def success(other_elements={})
tickets: [{
id: result['tickets'][0]['id'],
quantity: 1,
ticket_level_id: ticket_level.id},
ticket_level_id: ticket_level.id,
ticket_purchase_id: tp.id,
},
{
id: result['tickets'][0]['id'],
quantity: 2,
ticket_level_id: ticket_level2.id
ticket_level_id: ticket_level2.id,
ticket_purchase_id: tp.id,
}]}.merge(other_elements))

expect(result['payment'].attributes).to eq expected[:payment]
Expand All @@ -492,15 +534,15 @@ def success(other_elements={})
expect(e).to be_a ParamValidation::ValidationError
expect_validation_errors(e.data, [{key: :amount}])
expect(e.message).to eq "You authorized a payment of $3.99 but the total value of tickets requested was $16."
}
}.and not_change { ObjectEvent.count }
end

it 'errors where kind == free and positive gross_amount' do
expect {InsertTickets.create(tickets: [{quantity: 1, ticket_level_id: ticket_level.id}], nonprofit_id: nonprofit.id, supporter_id: supporter.id, token: source_token.token, event_id: event.id, 'kind' => 'free', amount: 1600)}.to raise_error {|e|
expect(e).to be_a ParamValidation::ValidationError
expect_validation_errors(e.data, [{key: :kind}])
expect(e.message).to eq "Ticket costs money but you didn't pay."
}
}.and not_change { ObjectEvent.count }
end

end
Expand All @@ -509,20 +551,24 @@ def success(other_elements={})
before do
ticket_level.update_attributes(amount: 0)
end
it 'creates the corresponding activity' do
ticket =

let(:ticket) do
InsertTickets.create(
tickets: [{
quantity: 1, ticket_level_id: ticket_level.id
}],
nonprofit_id: nonprofit.id,
supporter_id: supporter.id,
token: source_token.token,
event_id: event.id,
kind: 'free',
current_user: user,
amount: 0
)['tickets'].first
tickets: [{
quantity: 1, ticket_level_id: ticket_level.id
}],
nonprofit_id: nonprofit.id,
supporter_id: supporter.id,
token: source_token.token,
event_id: event.id,
kind: 'free',
current_user: user,
amount: 0
)['tickets'].first
end

it 'creates the corresponding activity' do


expect(Activity.where(attachment_id: ticket.id).last)
.to have_attributes({
Expand All @@ -537,6 +583,19 @@ def success(other_elements={})
}
})
end

it 'adds one ObjectEvent' do
expect { ticket }.to change { ObjectEvent.count }.by(1)
end

it 'adds one transaction.created event' do
expect { ticket }.to change { ObjectEvent.where(event_type: 'transaction.created').count }.by(1)
end

it 'adds one Transaction' do
expect { ticket }.to change { Transaction.count}.by(1)
end

end
end

Expand Down
Loading

0 comments on commit 47753ac

Please sign in to comment.