diff --git a/app/models/wire.rb b/app/models/wire.rb index 54adc52b0a..1d211f284f 100644 --- a/app/models/wire.rb +++ b/app/models/wire.rb @@ -178,7 +178,11 @@ def usd_amount_cents return -1 * local_hcb_code.amount_cents unless local_hcb_code.nil? || local_hcb_code.no_transactions? eu_bank = EuCentralBank.new - eu_bank.update_rates + if Rails.env.test? + eu_bank.update_rates(Rails.root.join("spec/fixtures/files/eurofxref-daily.xml")) + else + eu_bank.update_rates + end eu_bank.exchange(amount_cents, currency, "USD").cents end diff --git a/config/application.rb b/config/application.rb index 0b19635b0d..518f7247a5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -94,6 +94,24 @@ class Application < Rails::Application config.active_record.encryption.deterministic_key = Credentials.fetch(:ACTIVE_RECORD, :ENCRYPTION, :DETERMINISTIC_KEY) config.active_record.encryption.key_derivation_salt = Credentials.fetch(:ACTIVE_RECORD, :ENCRYPTION, :KEY_DERIVATION_SALT) + if Rails.env.test? && config.active_record.encryption.values_at(:primary_key, :deterministic_key, :key_derivation_salt).none? + # https://github.com/rails/rails/blob/8174a486bc3d2a720aaa4adb95028f5d03857d1e/activerecord/lib/active_record/railties/databases.rake#L527-L531 + primary_key = SecureRandom.alphanumeric(32) + deterministic_key = SecureRandom.alphanumeric(32) + key_derivation_salt = SecureRandom.alphanumeric(32) + + warn(<<~LOG) + ⚠️ Using temporary ActiveRecord::Encryption credentials + \tprimary_key: #{primary_key.inspect} + \tdeterministic_key: #{deterministic_key.inspect} + \tkey_derivation_salt: #{key_derivation_salt.inspect} + LOG + + config.active_record.encryption.primary_key = primary_key + config.active_record.encryption.deterministic_key = deterministic_key + config.active_record.encryption.key_derivation_salt = key_derivation_salt + end + # CSV previews config.active_storage.previewers << ActiveStorage::Previewer::DocumentPreviewer diff --git a/config/environments/test.rb b/config/environments/test.rb index 2dc1986ece..6934b5ff6c 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -57,14 +57,13 @@ config.active_support.disallowed_deprecation_warnings = [] config.action_mailer.default_url_options = { - host: Credentials.fetch(:TEST_URL_HOST) + host: Credentials.fetch(:TEST_URL_HOST, fallback: "localhost:3000"), } - Rails.application.routes.default_url_options[:host] = Credentials.fetch(:TEST_URL_HOST) + Rails.application.routes.default_url_options[:host] = Credentials.fetch(:TEST_URL_HOST, fallback: "localhost:3000") # Raises error for missing translations. # config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true - end diff --git a/config/initializers/lockbox.rb b/config/initializers/lockbox.rb index 7456a76cfe..9c3a644c4a 100644 --- a/config/initializers/lockbox.rb +++ b/config/initializers/lockbox.rb @@ -2,4 +2,11 @@ # https://github.com/ankane/lockbox -Lockbox.master_key = Credentials.fetch(:LOCKBOX) +master_key = Credentials.fetch(:LOCKBOX) + +if master_key.blank? && Rails.env.test? + master_key = Lockbox.generate_key + warn("⚠️ Using temporary Lockbox master key: #{master_key.inspect}") +end + +Lockbox.master_key = master_key diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb index 87edf9b229..a16de74617 100644 --- a/config/initializers/stripe.rb +++ b/config/initializers/stripe.rb @@ -4,4 +4,12 @@ # update as needed, we specify explicitly in code to avoid inter-branch API version conflicts Stripe.api_version = "2024-06-20" -Stripe.api_key = Credentials.fetch(:STRIPE, stripe_environment, :SECRET_KEY) + +api_key = Credentials.fetch(:STRIPE, stripe_environment, :SECRET_KEY) + +if api_key.blank? && Rails.env.test? + api_key = "sk_fake_#{SecureRandom.alphanumeric(32)}" + warn("⚠️ Using fake Stripe API key: #{api_key.inspect}") +end + +Stripe.api_key = api_key diff --git a/spec/controllers/ach_transfers_controller_spec.rb b/spec/controllers/ach_transfers_controller_spec.rb index 5f9c82a8ae..0438935b75 100644 --- a/spec/controllers/ach_transfers_controller_spec.rb +++ b/spec/controllers/ach_transfers_controller_spec.rb @@ -28,15 +28,28 @@ end it "handles unknown routing numbers" do + stub_request(:get, "https://api.column.com/institutions/123456789") + .to_return(status: 400) + get :validate_routing_number, params: { value: "123456789" } - expect(response.body).to match(/"valid":false/) + expect(response.parsed_body).to eq({ "valid" => false, "hint" => "Bank not found for this routing number." }) end it "returns bank name" do + stub_request(:get, "https://api.column.com/institutions/083000137") + .to_return_json( + status: 200, + body: { + routing_number_type: "aba", + ach_eligible: true, + full_name: "JPMORGAN CHASE BANK, NA", + } + ) + get :validate_routing_number, params: { value: "083000137" } - expect(response.body).to eq({ valid: true, hint: "Jpmorgan Chase Bank, Na" }.to_json) + expect(response.parsed_body).to eq({ "valid" => true, "hint" => "Jpmorgan Chase Bank, Na" }) end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index dde961e886..bc0e0ab4eb 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -4,6 +4,7 @@ RSpec.describe UsersController do include SessionSupport + include TwilioSupport describe "#impersonate" do it "allows admins to switch to an impersonated session" do @@ -56,6 +57,7 @@ ) user.update!(phone_number_verified: true) Flipper.enable(:sudo_mode_2015_07_21, user) + stub_twilio_sms_verification(phone_number: user.phone_number, code: "123456") sign_in(user) travel_to(3.hours.from_now) @@ -78,8 +80,8 @@ id: user.id, user: { use_two_factor_authentication: false }, _sudo: { - submit_method: "email", - login_code: user.login_codes.last.code, + submit_method: "sms", + login_code: "123456", login_id: user.logins.last.hashid, } } diff --git a/spec/controllers/wires_controller_spec.rb b/spec/controllers/wires_controller_spec.rb index 77c981c9ae..61e9815ecf 100644 --- a/spec/controllers/wires_controller_spec.rb +++ b/spec/controllers/wires_controller_spec.rb @@ -33,6 +33,12 @@ def wire_params sign_in(user) + stub_request(:get, "https://api.column.com/institutions/NOSCCATT") + .to_return_json( + status: 200, + body: { country_code: "CA" } + ) + post( :create, params: { @@ -84,6 +90,12 @@ def wire_params expect(response).to have_http_status(:unprocessable_entity) expect(response.body).to include("Confirm Access") + stub_request(:get, "https://api.column.com/institutions/NOSCCATT") + .to_return_json( + status: 200, + body: { country_code: "CA" } + ) + post( :create, params: { diff --git a/spec/fixtures/files/eurofxref-daily.xml b/spec/fixtures/files/eurofxref-daily.xml new file mode 100644 index 0000000000..2c4699a18c --- /dev/null +++ b/spec/fixtures/files/eurofxref-daily.xml @@ -0,0 +1,41 @@ + + + Reference rates + + European Central Bank + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spec/mailboxes/receipt_bin_mailbox_spec.rb b/spec/mailboxes/receipt_bin_mailbox_spec.rb index 7be6e8d746..2948a4769e 100644 --- a/spec/mailboxes/receipt_bin_mailbox_spec.rb +++ b/spec/mailboxes/receipt_bin_mailbox_spec.rb @@ -5,6 +5,9 @@ RSpec.describe ReceiptBinMailbox do include ActionMailbox::TestHelper include ActionMailer::TestHelper + # The helpers above expect a tagged_logger method to be present + # See https://github.com/rspec/rspec-rails/issues/2545 + attr_reader(:tagged_logger) def receive_email(to:, from:, cc: nil) receive_inbound_email_from_mail( @@ -21,6 +24,12 @@ def receive_email(to:, from:, cc: nil) ) end + before do + extract_service = instance_double(ReceiptService::Extract) + expect(extract_service).to receive(:run!).and_return(nil) + expect(ReceiptService::Extract).to receive(:new).and_return(extract_service) + end + context "with generic addresses" do it "finds the user based on the from address" do user = create(:user, email: "test@example.com") diff --git a/spec/models/donation_spec.rb b/spec/models/donation_spec.rb index a803c5fd9f..ab9d854725 100644 --- a/spec/models/donation_spec.rb +++ b/spec/models/donation_spec.rb @@ -2,8 +2,13 @@ require "rails_helper" -RSpec.describe Donation, type: :modal do +RSpec.describe Donation, type: :model do include ActiveJob::TestHelper + include DonationSupport + + before do + stub_donation_payment_intent_creation + end it "is valid" do donation = create(:donation) diff --git a/spec/models/invoice_spec.rb b/spec/models/invoice_spec.rb index 3c0554ea87..9884723418 100644 --- a/spec/models/invoice_spec.rb +++ b/spec/models/invoice_spec.rb @@ -3,9 +3,12 @@ require "rails_helper" RSpec.describe Invoice, type: :model do - let(:invoice) { create(:invoice) } + before do + expect_any_instance_of(Sponsor).to receive(:create_stripe_customer).and_return(true) + end it "is valid" do + invoice = create(:invoice) expect(invoice).to be_valid end end diff --git a/spec/models/sponsor_spec.rb b/spec/models/sponsor_spec.rb index 86e6dc459c..1d22bb911d 100644 --- a/spec/models/sponsor_spec.rb +++ b/spec/models/sponsor_spec.rb @@ -3,9 +3,38 @@ require "rails_helper" RSpec.describe Sponsor, type: :model do - let(:sponsor) { create(:sponsor) } - it "is valid" do + sponsor = build(:sponsor) expect(sponsor).to be_valid end + + it "creates a stripe customer" do + sponsor = build(:sponsor) + + expect(StripeService::Customer).to( + receive(:create) + .with( + { + description: sponsor.name, + email: sponsor.contact_email, + shipping: { + name: sponsor.name, + address: { + line1: sponsor.address_line1, + line2: sponsor.address_line2, + city: sponsor.address_city, + state: sponsor.address_state, + postal_code: sponsor.address_postal_code, + country: sponsor.address_country + } + } + } + ) + .and_return(Stripe::Customer.construct_from(id: "cu_1234")) + ) + + sponsor.save! + + expect(sponsor.stripe_customer_id).to eq("cu_1234") + end end diff --git a/spec/models/stripe_cardholder_spec.rb b/spec/models/stripe_cardholder_spec.rb index b1c0825377..4cab997831 100644 --- a/spec/models/stripe_cardholder_spec.rb +++ b/spec/models/stripe_cardholder_spec.rb @@ -3,9 +3,33 @@ require "rails_helper" RSpec.describe StripeCardholder, type: :model do - let(:stripe_cardholder) { create(:stripe_cardholder) } - it "is valid" do + stripe_cardholder = build(:stripe_cardholder) expect(stripe_cardholder).to be_valid end + + it "syncs Stripe on update" do + stripe_cardholder = create(:stripe_cardholder) + + expect(StripeService::Issuing::Cardholder).to( + receive(:update) + .with( + stripe_cardholder.stripe_id, + { + phone_number: "+18556254225", + billing: { + address: { + line1: stripe_cardholder.address_line1, + city: stripe_cardholder.address_city, + state: stripe_cardholder.address_state, + postal_code: stripe_cardholder.address_postal_code, + country: stripe_cardholder.address_country + } + } + } + ) + ) + + stripe_cardholder.update!(stripe_phone_number: "+18556254225") + end end diff --git a/spec/services/invoice_service/create_spec.rb b/spec/services/invoice_service/create_spec.rb index b4a562c845..6ec8eb96ab 100644 --- a/spec/services/invoice_service/create_spec.rb +++ b/spec/services/invoice_service/create_spec.rb @@ -3,86 +3,136 @@ require "rails_helper" RSpec.describe InvoiceService::Create, type: :model do - let(:user) { create(:user) } - let(:event) { create(:event) } + before do + expect_any_instance_of(Sponsor).to receive(:create_stripe_customer).and_return(true) + end - let(:event_id) { event.id } - let(:due_date) { (Date.current + 14).to_s } - let(:item_description) { "Invoice Description" } - let(:item_amount) { "100.00" } - let(:current_user) { user } - let(:sponsor_id) { nil } - let(:sponsor_name) { "Sponsor Name" } - let(:sponsor_email) { "sponsor@email.com" } - let(:sponsor_address_line1) { "123 Main St" } - let(:sponsor_address_line2) { nil } - let(:sponsor_address_city) { "Santa Monica" } - let(:sponsor_address_state) { "CA" } - let(:sponsor_address_postal_code) { "90401" } - let(:sponsor_address_country) { "US" } + it "creates a Stripe invoice and invoice item" do + freeze_time do + user = create(:user) + event = create(:event, name: "Scrapyard") + due_date = (Date.current + 14).to_s + due_date_unix = Time.find_zone("UTC").parse(due_date).to_i - let(:service) do - InvoiceService::Create.new( - event_id:, - due_date:, - item_description:, - item_amount:, - current_user:, - sponsor_id:, - sponsor_name:, - sponsor_email:, - sponsor_address_line1:, - sponsor_address_line2:, - sponsor_address_city:, - sponsor_address_state:, - sponsor_address_postal_code:, - sponsor_address_country: - ) - end + service = + InvoiceService::Create.new( + event_id: event.id, + due_date:, + item_description: "Item description", + item_amount: "100.00", + current_user: user, + sponsor_id: nil, + sponsor_name: "Sponsor Name", + sponsor_email: "sponsor@email.com", + sponsor_address_line1: "123 Main St", + sponsor_address_line2: nil, + sponsor_address_city: "Santa Monica", + sponsor_address_state: "CA", + sponsor_address_postal_code: "90401", + sponsor_address_country: "US" + ) - let(:stripe_invoice_item) { double("StripeInvoice", id: 1) } - let(:stripe_invoice_values) do - { - send_invoice: true, - id: 1, - amount_due: 100_00, - amount_paid: 100_00, - amount_remaining: 100_00, - attempt_count: 1, - attempted: true, - auto_advance: false, - due_date: 12345689, - ending_balance: 100_00, - finalized_at: "2021-12-12", - hosted_invoice_url: "http://example.com", - invoice_pdf: "http://example.com", - livemode: false, - description: "Invoice Memo", - number: 1234, - starting_balance: 0, - statement_descriptor: "Statement Descriptor", - status: "paid", - charge: double("charge", id: 1, payment_method_details: double("payment_method_detail", type: nil)), - subtotal: 100_00, - tax: 0, - tax_percent: 0, - total: 100_00, - } - end - let(:stripe_invoice) { double("StripeInvoice", stripe_invoice_values) } + stripe_invoice = Stripe::Invoice.construct_from( + id: "in_1234", + send_invoice: true, + amount_due: 100_00, + amount_paid: 0, + amount_remaining: 100_00, + attempt_count: 1, + attempted: true, + auto_advance: true, + due_date: due_date_unix, + ending_balance: 100_00, + finalized_at: Time.now.to_i, + hosted_invoice_url: "https://example.com", + invoice_pdf: "https://example.com/invoice.pdf", + livemode: false, + description: "Invoice Memo", + number: 1234, + starting_balance: 0, + statement_descriptor: "Statement Descriptor", + status: "paid", + charge: { id: "ch_1234", payment_method_details: { type: nil } }, + subtotal: 100_00, + tax: 0, + tax_percent: 0, + total: 100_00, + ) - it "creates an invoice" do - expect do - service.run - end.to change(Invoice, :count).by(1) - end + expect(stripe_invoice).to receive(:send_invoice) + + expect(StripeService::Invoice).to( + receive(:create) + .with( + { + auto_advance: true, + collection_method: "send_invoice", + customer: nil, + description: "To support Scrapyard. Scrapyard is fiscally sponsored by The Hack Foundation (d.b.a. Hack Club), a 501(c)(3) nonprofit with the EIN 81-2908499.", + due_date: due_date_unix, + footer: "\n\n\n\n\nNeed to pay by mailed paper check?\n\nPlease pay the amount to the order of The Hack Foundation, and include 'Scrapyard (##{event.id})' in the memo. Checks can be mailed to:\n\nScrapyard (##{event.id}) c/o The Hack Foundation\n8605 Santa Monica Blvd #86294\nWest Hollywood, CA 90069", + metadata: { event_id: event.id }, + payment_settings: {}, + statement_descriptor: "HCB* Scrapyard", + status: nil + } + ) + .and_return(stripe_invoice) + ) + + expect(StripeService::InvoiceItem).to( + receive(:create) + .with( + { + amount: 100_00, + currency: "usd", + customer: nil, + description: "Item description", + invoice: stripe_invoice.id, + } + ) + .and_return(Stripe::InvoiceItem.construct_from(id: "ii_1234")) + ) + + expect(StripeService::Invoice).to( + receive(:retrieve) + .with( + { + id: stripe_invoice.id, + expand: ["charge", "charge.payment_method_details", "charge.balance_transaction"], + } + ) + .and_return(stripe_invoice) + ) - it "creates a stripe invoice item" do - expect(::StripeService::InvoiceItem).to receive(:create).and_return(stripe_invoice_item) - expect(::StripeService::Invoice).to receive(:create).and_return(stripe_invoice) - expect(::StripeService::Invoice).to receive(:retrieve).and_return(stripe_invoice) + expect do + service.run + end.to change(Invoice, :count).by(1) - service.run + invoice = Invoice.last + expect(invoice.item_stripe_id).to eq("ii_1234") + expect(invoice.stripe_invoice_id).to eq("in_1234") + expect(invoice.amount_due).to eq(100_00) + expect(invoice.amount_paid).to eq(0) + expect(invoice.amount_remaining).to eq(100_00) + expect(invoice.starting_balance).to eq(0) + expect(invoice.ending_balance).to eq(100_00) + expect(invoice.subtotal).to eq(100_00) + expect(invoice.tax).to eq(0) + expect(invoice.total).to eq(100_00) + expect(invoice.attempt_count).to eq(1) + expect(invoice.attempted).to eq(true) + expect(invoice.auto_advance).to eq(true) + expect(invoice.due_date.to_i).to eq(due_date_unix) + expect(invoice.hosted_invoice_url).to eq("https://example.com") + expect(invoice.invoice_pdf).to eq("https://example.com/invoice.pdf") + expect(invoice.livemode).to eq(false) + expect(invoice.memo).to eq("Invoice Memo") + expect(invoice.number).to eq("1234") + expect(invoice.statement_descriptor).to eq("Statement Descriptor") + expect(invoice.status).to eq("paid") + expect(invoice.stripe_charge_id).to eq("ch_1234") + end end end diff --git a/spec/services/payout_service/donation/create_spec.rb b/spec/services/payout_service/donation/create_spec.rb index 84fabf5e98..5672a3c934 100644 --- a/spec/services/payout_service/donation/create_spec.rb +++ b/spec/services/payout_service/donation/create_spec.rb @@ -3,28 +3,40 @@ require "rails_helper" RSpec.describe PayoutService::Donation::Create do - let(:donation) { create(:donation, aasm_state: :in_transit) } - - let(:service) { PayoutService::Donation::Create.new(donation_id: donation.id) } + include DonationSupport before do - allow(service).to receive(:funds_available?).and_return(true) allow_any_instance_of(DonationPayout).to receive(:create_stripe_payout).and_return(true) + stub_donation_payment_intent_creation + end + + def setup_context + donation = create(:donation, aasm_state: :in_transit) + + service = described_class.new(donation_id: donation.id) + allow(service).to receive(:funds_available?).and_return(true) + + { donation:, service: } end it "creates a payout" do + setup_context => { service: } + expect do service.run end.to change(DonationPayout, :count).by(1) end it "creates a fee_reimbursement" do + setup_context => { service: } + expect do service.run end.to change(FeeReimbursement, :count).by(1) end it "updates donation with relationships" do + setup_context => { donation:, service: } expect(donation.payout_id).to be_nil expect(donation.fee_reimbursement_id).to be_nil diff --git a/spec/services/payout_service/invoice/create_spec.rb b/spec/services/payout_service/invoice/create_spec.rb index c809621cd6..c90295b26d 100644 --- a/spec/services/payout_service/invoice/create_spec.rb +++ b/spec/services/payout_service/invoice/create_spec.rb @@ -3,31 +3,40 @@ require "rails_helper" RSpec.describe PayoutService::Invoice::Create do - let(:invoice) { create(:invoice) } + before do + expect_any_instance_of(InvoicePayout).to receive(:create_stripe_payout).and_return(true) + expect_any_instance_of(Sponsor).to receive(:create_stripe_customer).and_return(true) + end - let(:service) { PayoutService::Invoice::Create.new(invoice_id: invoice.id) } + def setup_context + invoice = create(:invoice) - before do + service = described_class.new(invoice_id: invoice.id) allow(service).to receive(:funds_available?).and_return(true) allow(service).to receive(:charge).and_return(true) - allow_any_instance_of(InvoicePayout).to receive(:create_stripe_payout).and_return(true) - allow_any_instance_of(Sponsor).to receive(:create_stripe_customer).and_return(true) - allow_any_instance_of(Sponsor).to receive(:update_stripe_customer).and_return(true) + + { invoice:, service: } end it "creates a payout" do + setup_context => { service: } + expect do service.run end.to change(InvoicePayout, :count).by(1) end it "creates a fee_reimbursement" do + setup_context => { service: } + expect do service.run end.to change(FeeReimbursement, :count).by(1) end it "updates invoice with relationships" do + setup_context => { service:, invoice: } + expect(invoice.payout_id).to be_nil expect(invoice.fee_reimbursement_id).to be_nil diff --git a/spec/services/transaction_engine/nightly_spec.rb b/spec/services/transaction_engine/nightly_spec.rb index 391f03bd7d..8086e0bae5 100644 --- a/spec/services/transaction_engine/nightly_spec.rb +++ b/spec/services/transaction_engine/nightly_spec.rb @@ -6,20 +6,33 @@ let(:service) { TransactionEngine::Nightly.new } it "succeeds" do - expect(service).to receive(:import_raw_plaid_transactions!).and_return(true) - expect(service).to receive(:import_raw_stripe_transactions!).and_return(true) - expect(service).to receive(:import_raw_csv_transactions!).and_return(true) - - expect(service).to receive(:hash_raw_plaid_transactions!).and_return(true) - expect(service).to receive(:hash_raw_stripe_transactions!).and_return(true) - expect(service).to receive(:hash_raw_csv_transactions!).and_return(true) - - expect(service).to receive(:canonize_hashed_transactions!).and_return(true) - - expect(service).to receive(:fix_plaid_mistakes!).and_return(true) - - expect(service).to receive(:fix_memo_mistakes!).and_return(true) - - service.run + freeze_time do + stub_request(:get, "https://api.column.com/reporting") + .with( + query: { + from_date: 1.week.ago.to_date, + to_date: Date.today, + limit: 100, + type: "bank_account_transaction" + } + ) + .to_return_json(status: 200, body: { reports: [], has_more: false }) + + expect(service).to receive(:import_raw_plaid_transactions!).and_return(true) + expect(service).to receive(:import_raw_stripe_transactions!).and_return(true) + expect(service).to receive(:import_raw_csv_transactions!).and_return(true) + + expect(service).to receive(:hash_raw_plaid_transactions!).and_return(true) + expect(service).to receive(:hash_raw_stripe_transactions!).and_return(true) + expect(service).to receive(:hash_raw_csv_transactions!).and_return(true) + + expect(service).to receive(:canonize_hashed_transactions!).and_return(true) + + expect(service).to receive(:fix_plaid_mistakes!).and_return(true) + + expect(service).to receive(:fix_memo_mistakes!).and_return(true) + + service.run + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e82afdb0eb..ee43993759 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -100,6 +100,6 @@ # # as the one that triggered the failure. # Kernel.srand config.seed - # Allow the test suite to make external web requests - WebMock.allow_net_connect! + # Uncomment to allow the test suite to make network calls + # WebMock.allow_net_connect! end diff --git a/spec/support/donation_support.rb b/spec/support/donation_support.rb new file mode 100644 index 0000000000..a8ec3da94b --- /dev/null +++ b/spec/support/donation_support.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module DonationSupport + def stub_donation_payment_intent_creation + expect(StripeService::Customer).to( + receive(:create) + .and_return( + Stripe::Customer.construct_from( + id: "cus_#{SecureRandom.alphanumeric(10)}" + ) + ) + .at_least(:once) + ) + + payment_intent_id = "pi_#{SecureRandom.alphanumeric(10)}" + + expect(StripeService::PaymentIntent).to( + receive(:create) + .and_return( + Stripe::PaymentIntent.construct_from( + id: payment_intent_id, + amount: 12_34, + amount_received: 0, + status: "processing", + client_secret: "#{payment_intent_id}_secret_#{SecureRandom.alphanumeric(10)}" + ) + ) + .at_least(:once) + ) + end +end diff --git a/spec/support/twilio_support.rb b/spec/support/twilio_support.rb new file mode 100644 index 0000000000..50e83c11d6 --- /dev/null +++ b/spec/support/twilio_support.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module TwilioSupport + def stub_twilio_sms_verification(phone_number:, code:) + verification_service = instance_double(TwilioVerificationService) + + allow(verification_service).to( + receive(:send_verification_request) + .with(phone_number) + ) + + allow(verification_service).to( + receive(:check_verification_token) + .with(phone_number, code) + .and_return(true) + ) + + allow(TwilioVerificationService).to receive(:new).and_return(verification_service) + end +end