require "rails_helper"

RSpec.describe NotificationsController, type: :controller do
  describe "#create" do
    context "for a subscription confirmation" do
      it "responds ok" do
        post :create, body: subscription_confirmation_body_json

        expect(response).to be_ok
      end

      it "log the subscribe url" do
        allow(Rails.logger).to receive(:info)

        post :create, body: subscription_confirmation_body_json

        expect(Rails.logger).to have_received(:info).with("http://example.com")
      end
    end

    context "for a notification" do
      context "for video analysis" do
        let!(:video) { create(:video, analysis_uid: "job_id") }

        context "when successful" do
          it "responds ok" do
            post :create, body: successful_notification_body_json

            expect(response).to be_ok
          end

          it "updates video analysis status" do
            post :create, body: successful_notification_body_json

            expect(video.reload).to be_analysis_success
          end

          it "broadcasts analysis update" do
            allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)

            post :create, body: successful_notification_body_json

            expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
          end
        end

        context "when failed" do
          it "responds ok" do
            post :create, body: failure_notification_body_json

            expect(response).to be_ok
          end

          it "updates video analysis status" do
            post :create, body: failure_notification_body_json

            expect(video.reload).to be_analysis_failure
          end

          it "broadcasts analysis update" do
            allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)

            post :create, body: successful_notification_body_json

            expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
          end
        end
      end

      context "for audio analysis" do
        let!(:video) { create(:video, audio_analysis_uid: "job_id") }

        context "when successful" do
          it "responds ok" do
            post :create, body: successful_notification_body_json("audio")

            expect(response).to be_ok
          end

          it "updates video analysis status" do
            post :create, body: successful_notification_body_json("audio")

            expect(video.reload).to be_audio_analysis_success
          end

          it "broadcasts analysis update" do
            allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)

            post :create, body: successful_notification_body_json("audio")

            expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
          end
        end

        context "when failed" do
          it "responds ok" do
            post :create, body: failure_notification_body_json("audio")

            expect(response).to be_ok
          end

          it "updates video analysis status" do
            post :create, body: failure_notification_body_json("audio")

            expect(video.reload).to be_audio_analysis_failure
          end

          it "broadcasts analysis update" do
            allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)

            post :create, body: successful_notification_body_json("audio")

            expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
          end
        end
      end
    end
  end

  private

  def subscription_confirmation_body_json
    { "Type" => "SubscriptionConfirmation", "SubscribeURL" => "http://example.com" }.to_json
  end

  def successful_notification_body_json(analysis_type = "video")
    { 
      "Type" => "Notification", 
      "Message" => {
        "JobId" => "job_id",
        "Status" => "SUCCEEDED",
        "AnalysisType" => analysis_type,
      }.to_json
    }.to_json
  end

  def failure_notification_body_json(analysis_type = "video")
    { 
      "Type" => "Notification", 
      "Message" => {
        "JobId" => "job_id",
        "Status" => "FAILED",
        "AnalysisType" => analysis_type,
      }.to_json
    }.to_json
  end
end
