234 lines
8.5 KiB
Ruby
234 lines
8.5 KiB
Ruby
require 'rails_helper'
|
|
require 'webmock/rspec'
|
|
|
|
RSpec.describe "Donations", type: :request do
|
|
let(:user) { create :user, cn: 'jimmy', ou: 'kosmos.org' }
|
|
|
|
before do
|
|
Warden.test_mode!
|
|
login_as user, scope: :user
|
|
end
|
|
|
|
after { Warden.test_reset! }
|
|
|
|
describe "#create" do
|
|
describe "with disabled methods" do
|
|
before do
|
|
Setting.btcpay_enabled = false
|
|
end
|
|
|
|
it "returns a 403" do
|
|
post "/contributions/donations", params: { donation_method: "btcpay" }
|
|
expect(response).to have_http_status(:forbidden)
|
|
end
|
|
end
|
|
|
|
describe "with fake methods" do
|
|
it "returns a 403" do
|
|
post "/contributions/donations", params: { donation_method: "remotestorage" }
|
|
expect(response).to have_http_status(:forbidden)
|
|
end
|
|
end
|
|
|
|
describe "with invalid fiat currency" do
|
|
it "returns a 422" do
|
|
post "/contributions/donations", params: {
|
|
donation_method: "btcpay", amount: "10", currency: "GBP"
|
|
}
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
end
|
|
end
|
|
|
|
describe "with bad amount" do
|
|
it "returns a 422" do
|
|
post "/contributions/donations", params: {
|
|
donation_method: "btcpay", amount: ""
|
|
}
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
end
|
|
end
|
|
|
|
describe "with BTCPay" do
|
|
before { Setting.btcpay_enabled = true }
|
|
|
|
describe "amount in EUR" do
|
|
before do
|
|
expect(BtcpayManager::CreateInvoice).to receive(:call)
|
|
.with(amount: 25, currency: "EUR", redirect_url: "http://www.example.com/contributions/donations/1/confirm_btcpay")
|
|
.and_return({
|
|
"id" => "Q9GBe143HJIkdpZeH4Ftx5",
|
|
"amount" => "25",
|
|
"currency" => "EUR",
|
|
"checkoutLink" => "#{Setting.btcpay_api_url}/i/Q9GBe143HJIkdpZeH4Ftx5",
|
|
"expirationTime" => 1707908626,
|
|
"checkout" => { "redirectURL" => "http://www.example.com/contributions/donations/1/confirm_btcpay" }
|
|
})
|
|
|
|
post "/contributions/donations", params: {
|
|
donation_method: "btcpay", amount: "25", currency: "EUR",
|
|
public_name: "Mickey"
|
|
}
|
|
end
|
|
|
|
it "creates a new donation record" do
|
|
expect(user.donations.count).to eq(1)
|
|
donation = user.donations.first
|
|
expect(donation.donation_method).to eq("btcpay")
|
|
expect(donation.payment_method).to be_nil
|
|
expect(donation.paid_at).to be_nil
|
|
expect(donation.public_name).to eq("Mickey")
|
|
expect(donation.amount_sats).to be_nil
|
|
expect(donation.fiat_amount).to eq(2500)
|
|
expect(donation.fiat_currency).to eq("EUR")
|
|
expect(donation.btcpay_invoice_id).to eq("Q9GBe143HJIkdpZeH4Ftx5")
|
|
end
|
|
|
|
it "redirects to the BTCPay checkout page" do
|
|
expect(response).to redirect_to("https://btcpay.example.com/i/Q9GBe143HJIkdpZeH4Ftx5")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#confirm_btcpay" do
|
|
before { Setting.btcpay_enabled = true }
|
|
|
|
describe "with donation of another user" do
|
|
let(:other_user) { create :user, id: 3, cn: "carl", ou: 'kosmos.org', email: "carl@example.com" }
|
|
|
|
before do
|
|
@donation = other_user.donations.create!(
|
|
donation_method: "btcpay", btcpay_invoice_id: "123abc",
|
|
fiat_amount: 25, fiat_currency: "EUR", paid_at: nil
|
|
)
|
|
get confirm_btcpay_contributions_donation_path(@donation.id)
|
|
end
|
|
|
|
it "returns a 404" do
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
|
|
describe "with confirmed donation" do
|
|
before do
|
|
@donation = user.donations.create!(
|
|
donation_method: "btcpay", btcpay_invoice_id: "123abc",
|
|
fiat_amount: 25, fiat_currency: "EUR",
|
|
paid_at: "2024-02-16", payment_status: "settled"
|
|
)
|
|
get confirm_btcpay_contributions_donation_path(@donation.id)
|
|
end
|
|
|
|
it "redirects to the donations index" do
|
|
expect(response).to redirect_to(contributions_donations_url)
|
|
end
|
|
end
|
|
|
|
describe "settled via Lightning" do
|
|
describe "amount in EUR" do
|
|
subject do
|
|
user.donations.create!(
|
|
donation_method: "btcpay", btcpay_invoice_id: "MCkDbf2cUgBuuisUCgnRnb",
|
|
fiat_amount: 25, fiat_currency: "EUR", paid_at: nil
|
|
)
|
|
end
|
|
|
|
before do
|
|
invoice = File.read("#{Rails.root}/spec/fixtures/btcpay/lightning_eur_settled_invoice.json")
|
|
payments = File.read("#{Rails.root}/spec/fixtures/btcpay/lightning_eur_settled_payments.json")
|
|
stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/invoices/MCkDbf2cUgBuuisUCgnRnb")
|
|
.to_return(status: 200, headers: {}, body: invoice)
|
|
stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/invoices/MCkDbf2cUgBuuisUCgnRnb/payment-methods")
|
|
.to_return(status: 200, headers: {}, body: payments)
|
|
|
|
get confirm_btcpay_contributions_donation_path(subject)
|
|
end
|
|
|
|
it "updates the donation record" do
|
|
subject.reload
|
|
expect(subject.paid_at).not_to be_nil
|
|
expect(subject.amount_sats).to eq(2061)
|
|
end
|
|
|
|
it "redirects to the donations index" do
|
|
expect(response).to redirect_to(contributions_donations_url)
|
|
end
|
|
end
|
|
|
|
describe "amount in sats" do
|
|
subject do
|
|
user.donations.create!(
|
|
donation_method: "btcpay", btcpay_invoice_id: "JxjfeJi1TtX8FcWSjEvGxg",
|
|
amount_sats: 10000, fiat_amount: nil, fiat_currency: nil, paid_at: nil
|
|
)
|
|
end
|
|
|
|
before do
|
|
invoice = File.read("#{Rails.root}/spec/fixtures/btcpay/lightning_sats_settled_invoice.json")
|
|
payments = File.read("#{Rails.root}/spec/fixtures/btcpay/lightning_sats_settled_payments.json")
|
|
stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/invoices/JxjfeJi1TtX8FcWSjEvGxg")
|
|
.to_return(status: 200, headers: {}, body: invoice)
|
|
stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/invoices/JxjfeJi1TtX8FcWSjEvGxg/payment-methods")
|
|
.to_return(status: 200, headers: {}, body: payments)
|
|
|
|
expect(BtcpayManager::FetchExchangeRate).to receive(:call)
|
|
.with(fiat_currency: "EUR").and_return(48532.00)
|
|
|
|
get confirm_btcpay_contributions_donation_path(subject)
|
|
end
|
|
|
|
it "updates the donation record" do
|
|
subject.reload
|
|
expect(subject.paid_at).not_to be_nil
|
|
expect(subject.amount_sats).to eq(10000)
|
|
expect(subject.fiat_amount).to eq(485)
|
|
expect(subject.fiat_currency).to eq("EUR")
|
|
end
|
|
|
|
it "redirects to the donations index" do
|
|
expect(response).to redirect_to(contributions_donations_url)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "on-chain" do
|
|
describe "waiting for confirmations" do
|
|
subject do
|
|
user.donations.create!(
|
|
donation_method: "btcpay", btcpay_invoice_id: "K4e31MhbLKmr3D7qoNYRd3",
|
|
fiat_amount: 120, fiat_currency: "USD", paid_at: nil
|
|
)
|
|
end
|
|
|
|
before do
|
|
invoice = File.read("#{Rails.root}/spec/fixtures/btcpay/onchain_eur_processing_invoice.json")
|
|
payments = File.read("#{Rails.root}/spec/fixtures/btcpay/onchain_eur_processing_payments.json")
|
|
stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/invoices/K4e31MhbLKmr3D7qoNYRd3")
|
|
.to_return(status: 200, headers: {}, body: invoice)
|
|
stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/invoices/K4e31MhbLKmr3D7qoNYRd3/payment-methods")
|
|
.to_return(status: 200, headers: {}, body: payments)
|
|
|
|
get confirm_btcpay_contributions_donation_path(subject)
|
|
end
|
|
|
|
it "updates the donation record" do
|
|
subject.reload
|
|
expect(subject.paid_at).to be_nil
|
|
expect(subject.amount_sats).to eq(191354)
|
|
expect(subject.payment_status).to eq("processing")
|
|
end
|
|
|
|
it "enqueues a job to periodically check the invoice status" do
|
|
expect(enqueued_jobs.size).to eq(1)
|
|
expect(enqueued_jobs.first["job_class"]).to eq("BtcpayCheckDonationJob")
|
|
expect(enqueued_jobs.first['arguments'][0]["_aj_globalid"]).to eq("gid://akkounts/Donation/#{subject.id}")
|
|
end
|
|
|
|
it "redirects to the donations index" do
|
|
expect(response).to redirect_to(contributions_donations_url)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|