require 'rails_helper'

RSpec.describe "Webhooks", type: :request do
  describe "Allowed IP addresses" do
    context "IP not allowed" do
      it "returns a 403 status" do
        post "/webhooks/lndhub"
        expect(response).to have_http_status(:forbidden)
      end
    end

    context "IP allowed" do
      before do
        ENV['WEBHOOKS_ALLOWED_IPS'] = '127.0.0.1'
      end

      it "does not return a 403 status" do
        post "/webhooks/lndhub"
        expect(response).not_to have_http_status(:forbidden)
      end
    end
  end

  # Webhooks from lndhub.go
  describe "/webhooks/lndhub" do
    before do
      ENV['WEBHOOKS_ALLOWED_IPS'] = '127.0.0.1'
    end

    describe "Payload cannot be processed as JSON" do
      before do
        post "/webhooks/lndhub", params: "Foo"
      end

      it "returns a 422 status" do
        expect(response).to have_http_status(:unprocessable_entity)
      end
    end

    describe "Valid payload for outgoing payment" do
      let(:payload) { JSON.parse(File.read(File.expand_path("../fixtures/lndhub/outgoing.json", File.dirname(__FILE__)))) }

      before do
        post "/webhooks/lndhub", params: payload.to_json
      end

      it "returns a 204 status" do
        expect(response).to have_http_status(:no_content)
      end
    end

    describe "Valid payload for incoming payment" do
      let(:user) { create :user, ln_account: "123456abcdef" }
      let(:payload) { JSON.parse(File.read(File.expand_path("../fixtures/lndhub/incoming.json", File.dirname(__FILE__)))) }

      before do
        user.save! #FIXME this should not be necessary
      end

      it "returns a 200 status" do
        post "/webhooks/lndhub", params: payload.to_json
        expect(response).to have_http_status(:ok)
      end

      it "does not send notifications by default" do
        expect(enqueued_jobs.size).to eq(0)
      end

      context "notification preference set to 'xmpp'" do
        before do
          Setting.xmpp_notifications_from_address = "botka@kosmos.org"
          user.update! preferences: { lightning_notify_sats_received: "xmpp" }
          post "/webhooks/lndhub", params: payload.to_json
        end

        it "sends an XMPP message to the account owner's JID" do
          expect(enqueued_jobs.size).to eq(1)
          expect(enqueued_jobs.first["job_class"]).to eq("XmppSendMessageJob")

          msg = enqueued_jobs.first["arguments"].first
          expect(msg["type"]).to eq("normal")
          expect(msg["from"]).to eq("botka@kosmos.org")
          expect(msg["to"]).to eq(user.address)
          expect(msg["subject"]).to eq("Sats received!")
          expect(msg["body"]).to match(/^12,300 sats received/)
        end
      end

      context "notification preference set to 'email'" do
        before do
          user.update! preferences: { lightning_notify_sats_received: "email" }
          post "/webhooks/lndhub", params: payload.to_json
        end

        it "sends an email notification to the account owner" do
          expect(enqueued_jobs.size).to eq(1)
          expect(enqueued_jobs.first["job_class"]).to eq("ActionMailer::MailDeliveryJob")
          args = enqueued_jobs.first['arguments']
          expect(args[0]).to eq("NotificationMailer")
          expect(args[1]).to eq("lightning_sats_received")
          expect(args[3]["params"]["user"]["_aj_globalid"]).to eq("gid://akkounts/User/1")
          expect(args[3]["params"]["amount_sats"]).to eq(12300)
        end
      end
    end
  end
end
