From ba28eaa181de7f654fafffd0927a9c987ef4c90b Mon Sep 17 00:00:00 2001 From: Casey Helbling Date: Wed, 18 Jun 2025 12:42:04 -0500 Subject: [PATCH 1/2] Extract query spec --- spec/factories/events.rb | 6 +- spec/factories/import.rb | 6 ++ spec/factories/nonprofits.rb | 6 +- spec/factories/ticket_levels.rb | 3 + spec/factories/tickets.rb | 10 ++ spec/lib/insert/insert_source_token_spec.rb | 3 + spec/lib/query/query_event_metrics_spec.rb | 112 ++++++++++++++++++++ spec/lib/update/update_tickets_spec.rb | 11 +- 8 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 spec/factories/import.rb create mode 100644 spec/lib/query/query_event_metrics_spec.rb diff --git a/spec/factories/events.rb b/spec/factories/events.rb index 0f116618ce..82d7ef5e2c 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -7,9 +7,13 @@ address { "100 N Appleton St" } city { "Appleton" } state_code { "WI" } - slug { "event-of-wonders" } + slug { SecureRandom.uuid } nonprofit profile + + before(:create) do |event, context| + Event.any_instance.stub(:geocode).and_return([1, 1]) + end end factory :event_base, class: "Event" do diff --git a/spec/factories/import.rb b/spec/factories/import.rb new file mode 100644 index 0000000000..b08c736b63 --- /dev/null +++ b/spec/factories/import.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :import do + nonprofit + user + end +end diff --git a/spec/factories/nonprofits.rb b/spec/factories/nonprofits.rb index c2c709b419..7e278ebdb6 100644 --- a/spec/factories/nonprofits.rb +++ b/spec/factories/nonprofits.rb @@ -6,10 +6,14 @@ state_code { "NM" } zip_code { 55555 } email { "example@email.com" } - slug { "sluggy-sluggo" } + slug { SecureRandom.uuid } billing_subscription { build(:billing_subscription, billing_plan: build(:billing_plan_percentage_fee_of_2_5_percent_and_5_cents_flat)) } vetted { true } + before(:create) do |np, context| + Nonprofit.any_instance.stub(:geocode).and_return([1, 1]) + end + factory :nonprofit_with_cards do after(:create) { |nonprofit, evaluator| create(:active_card_1, holder: nonprofit) diff --git a/spec/factories/ticket_levels.rb b/spec/factories/ticket_levels.rb index 6727564dbb..bc7bb4318c 100644 --- a/spec/factories/ticket_levels.rb +++ b/spec/factories/ticket_levels.rb @@ -1,6 +1,9 @@ # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later FactoryBot.define do factory :ticket_level do + name { Faker::Lorem.words(number: 3) } + event + trait :has_tickets do end end diff --git a/spec/factories/tickets.rb b/spec/factories/tickets.rb index 99e045e114..16a7ce0114 100644 --- a/spec/factories/tickets.rb +++ b/spec/factories/tickets.rb @@ -1,6 +1,16 @@ # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later FactoryBot.define do factory :ticket do + event_discount + supporter + profile + ticket_level + charge + payment + source_token + ticket_purchase + note { Faker::Lorem.sentence } + trait :has_event do event end diff --git a/spec/lib/insert/insert_source_token_spec.rb b/spec/lib/insert/insert_source_token_spec.rb index 3791d8aece..08c6148381 100644 --- a/spec/lib/insert/insert_source_token_spec.rb +++ b/spec/lib/insert/insert_source_token_spec.rb @@ -58,9 +58,11 @@ end it "with event" do + Timecop.freeze(2020, 4, 5) do ouruuid = nil + event # to make sure SecureRandom.uuid from slug doesnt interfere with InsertSourceToken tokenizable = Card.create! expect(SecureRandom).to receive(:uuid).and_wrap_original { |m| ouruuid = m.call @@ -119,6 +121,7 @@ Timecop.freeze(2020, 4, 5) do ouruuid = nil + event # to make sure SecureRandom.uuid from slug doesnt interfere with InsertSourceToken tokenizable = Card.create! expect(SecureRandom).to receive(:uuid).and_wrap_original { |m| ouruuid = m.call diff --git a/spec/lib/query/query_event_metrics_spec.rb b/spec/lib/query/query_event_metrics_spec.rb new file mode 100644 index 0000000000..301797df9f --- /dev/null +++ b/spec/lib/query/query_event_metrics_spec.rb @@ -0,0 +1,112 @@ +# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later +require "rails_helper" + +describe QueryEventMetrics do + let(:nonprofit) { create(:nonprofit, slug: SecureRandom.uuid) } + let(:user) { create(:user) } + let(:profile) { create(:profile, user:) } + let(:supporter) { create(:supporter, nonprofit:, profile:, import: create(:import, user:, nonprofit:)) } + let(:supporter2) { create(:supporter, nonprofit:, import: create(:import, nonprofit:)) } + + let!(:event_active1) do + create(:event, nonprofit:, + name: Faker::FunnyName.four_word_name, + organizer_email: Faker::Internet.email, + end_datetime: 10.days.since.at_beginning_of_day, start_datetime: 10.days.ago.at_beginning_of_day, published: true, slug: SecureRandom.uuid, + address: Faker::Address.street_address, city: Faker::Address.city, state_code: Faker::Address.state_abbr, zip_code: Faker::Address.zip) + end + + let!(:event_active2) do + create(:event, nonprofit:, + name: Faker::FunnyName.four_word_name, + organizer_email: Faker::Internet.email, + end_datetime: 20.days.since.at_beginning_of_day, start_datetime: 10.days.ago.at_beginning_of_day, published: true, slug: SecureRandom.uuid, + address: Faker::Address.street_address, city: Faker::Address.city, state_code: Faker::Address.state_abbr, zip_code: Faker::Address.zip) + end + + let!(:tl1) { create(:ticket_level, event: event_active2) } + let!(:payment1) { create(:payment, supporter:, nonprofit:, gross_amount: 2137, fee_total: -159, net_amount: 1978) } + let!(:ticket1) { create(:ticket, event: event_active2, supporter:, profile:, payment: payment1, ticket_level: tl1, checked_in: true, quantity: 4) } + + let!(:payment2) { create(:payment, supporter:, nonprofit:, gross_amount: 1085, fee_total: -85, net_amount: 1000) } + let!(:ticket2) { create(:ticket, event: event_active2, supporter: supporter2, payment: payment2, ticket_level: tl1, checked_in: nil, quantity: 3) } + # Two tickets, two payments (21.37 + 10.85 = $32.22) + + let!(:donation_payment1) { create(:payment, supporter:, nonprofit:, gross_amount: 2664, fee_total: -164, net_amount: 2500) } + let!(:donation1) { create(:donation, supporter:, nonprofit:, event: event_active2, card: create(:card), amount: 2664, payment: donation_payment1) } + + let!(:donation_payment2) { create(:payment, supporter:, nonprofit:, gross_amount: 5295, fee_total: -295, net_amount: 5000) } + let!(:donation2) { create(:donation, supporter:, nonprofit:, event: event_active2, card: create(:card), amount: 5295, payment: donation_payment2) } + # Two donations 2664 + 5295 = $79.59 + + let!(:event_past) { create(:event, nonprofit:, end_datetime: 20.days.ago.at_beginning_of_day, published: true, slug: SecureRandom.uuid) } + let!(:event_deleted) { create(:event, nonprofit:, deleted: true, slug: SecureRandom.uuid) } + let!(:event_unpublished) { create(:event, nonprofit:, slug: SecureRandom.uuid) } + + let!(:nonprofit2) { create(:nonprofit, slug: SecureRandom.uuid) } + let!(:other_event_active2) { create(:event, nonprofit: nonprofit2, end_datetime: 10.days.since, published: true, slug: SecureRandom.uuid) } + let!(:other_event_active3) { create(:event, nonprofit: nonprofit2, end_datetime: 20.days.since, published: true, slug: SecureRandom.uuid) } + + describe ".for_listings" do + describe "for nonprofit" do + describe "active" do + subject(:results) { QueryEventMetrics.for_listings("nonprofit", nonprofit.id, {"active" => true}) } + + it "query result has correct attributes" do + expect(results.count).to eq 2 + + # first element is event_active2 because of order desc + expect(results.first["id"]).to eq event_active2.id + expect(results.first["name"]).to eq event_active2.name + expect(results.first["venue_name"]).to eq event_active2.venue_name + expect(results.first["address"]).to eq event_active2.address + expect(results.first["city"]).to eq event_active2.city + expect(results.first["state_code"]).to eq event_active2.state_code + expect(results.first["zip_code"]).to eq event_active2.zip_code + expect(results.first["start_datetime"]).to eq 10.days.ago.at_beginning_of_day + expect(results.first["end_datetime"]).to eq 20.days.since.at_beginning_of_day + expect(results.first["organizer_email"]).to eq event_active2.organizer_email + expect(results.first["checked_in_count"]).to eq 1 + expect(results.first["total_attendees"]).to eq 7 + expect(results.first["tickets_total_paid"]).to eq 3_222 + expect(results.first["donations_total_paid"]).to eq 7_959 + expect(results.first["total_paid"]).to eq(3_222 + 7_959) + + expect(results.last["id"]).to eq event_active1.id + end + end + + describe "active" do + subject(:results) { QueryEventMetrics.for_listings("nonprofit", nonprofit.id, {"past" => true}) } + it "query result has correct element" do + expect(results.count).to eq 1 + expect(results.first["id"]).to eq event_past.id + end + end + + describe "unpublished" do + subject(:results) { QueryEventMetrics.for_listings("nonprofit", nonprofit.id, {"unpublished" => true}) } + it "query result has correct element" do + expect(results.count).to eq 1 + expect(results.first["id"]).to eq event_unpublished.id + end + end + + describe "deleted" do + subject(:results) { QueryEventMetrics.for_listings("nonprofit", nonprofit.id, {"deleted" => true}) } + it "query result has correct element" do + expect(results.count).to eq 1 + expect(results.first["id"]).to eq event_deleted.id + end + end + end + + describe "for profile" do + skip "TODO" + end + end + + describe ".with_event_ids" do + skip "TODO" + end +end diff --git a/spec/lib/update/update_tickets_spec.rb b/spec/lib/update/update_tickets_spec.rb index 7abf3ca81b..b77675f001 100644 --- a/spec/lib/update/update_tickets_spec.rb +++ b/spec/lib/update/update_tickets_spec.rb @@ -36,8 +36,9 @@ profile_id: nil, note: nil, deleted: false, - source_token_id: nil, - ticket_level_id: nil + source_token: nil, + ticket_level: nil, + ticket_purchase: nil } } @@ -68,13 +69,11 @@ let(:charge) { force_create(:charge) } let(:ticket) { - force_create(:ticket, - general_ticket.merge(event: event)) + force_create(:ticket, general_ticket.merge(event: event)) } let(:other_ticket) { - force_create(:ticket, - general_ticket.merge(event: other_event)) + force_create(:ticket, general_ticket.merge(event: other_event)) } it "basic validation" do From dc3ac5a3358c453ed26d19358493fcc12bad96e9 Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Wed, 18 Jun 2025 16:06:40 -0500 Subject: [PATCH 2/2] Adjust to use the `_base` versions of factories --- spec/factories/tickets.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/factories/tickets.rb b/spec/factories/tickets.rb index 16a7ce0114..5966254f75 100644 --- a/spec/factories/tickets.rb +++ b/spec/factories/tickets.rb @@ -1,12 +1,12 @@ # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later FactoryBot.define do factory :ticket do - event_discount - supporter + event_discount { association :event_discount_base } + supporter { association :supporter_base } profile - ticket_level - charge - payment + ticket_level { association :source_token_base } + charge { association :charge_base } + payment { association :payment_base } source_token ticket_purchase note { Faker::Lorem.sentence }