require "test_helper"

module Agent
  class ServiceRequestsControllerTest < ActionDispatch::IntegrationTest
    include Devise::Test::IntegrationHelpers
    include ActionCable::TestHelper

    test "renders new" do
      sign_in users(:agent)

      client = users(:client)
      service_request = service_requests(:one)

      get new_agent_service_request_path, params: {
        service_request_id: service_request.id,
        client_id: client.id
      }

      assert_response :ok
    end

    test "create returns an error" do
      sign_in users(:agent)

      client = users(:client)
      service_request = service_requests(:one)

      post agent_service_requests_path, params: {
        service_request_id: service_request.id,
        service_request: {
          client_id: client.id,
          title: "test"
        }
      }

      assert_response :unprocessable_entity
    end

    test "create success" do
      sign_in users(:agent)

      client = users(:client)
      service_request = service_requests(:one)

      post agent_service_requests_path, params: {
        service_request_id: service_request.id,
        service_request: {
          client_id: client.id,
          category_id: 1,
          title: "test",
          description: "test description"
        }
      }

      assert_broadcasts "agent:todays_service_requests", 1
      assert_broadcasts "agent:all_service_requests", 1

      assert_response :ok
    end

    test "renders index" do
      sign_in users(:agent)

      get agent_service_requests_path

      assert_response :ok
    end

    test "renders show" do
      sign_in users(:agent)

      service_request = service_requests(:one)

      get agent_service_request_path(service_request)

      assert_response :ok
    end

    test "updates" do
      sign_in users(:agent)

      service_request = service_requests(:one)

      put agent_service_request_path(service_request), params: {
        id: service_request.id,
        service_request: {
          title: "updated"
        }
      }

      assert_equal "updated", service_request.reload.title

      assert_broadcasts "agent:todays_service_requests", 1
      assert_broadcasts "agent:all_service_requests", 1

      assert_response :ok
    end

    test "call" do
      sign_in agent = users(:agent)

      service_request = service_requests(:waiting)

      get call_agent_service_request_path(service_request)

      assert_equal agent.id, service_request.reload.agent_id
      assert_equal "waiting_for_answer", service_request.status

      assert_broadcasts "agent:todays_service_requests", agent.agent_service_requests.count
      assert_broadcasts "agent:all_service_requests", agent.agent_service_requests.count

      assert_response :ok
    end

    test "finish does not switch status for waiting requests" do
      sign_in users(:agent)

      service_request = service_requests(:waiting)

      put finish_agent_service_request_path(service_request)

      assert_not_equal "finished", service_request.reload.status
      assert_nil service_request.call_ended_at
      assert_nil service_request.call_duration

      assert_equal 0, service_request.logs.count

      assert_redirected_to agent_home_path
    end

    test "finish switches status of in progress requests" do
      service_request = service_requests(:in_progress)
      test_switch_status(service_request)
    end

    test "finish switches status of waiting for answer requests" do
      service_request = service_requests(:waiting_for_answer)
      test_switch_status(service_request)
    end

    test "switch" do
      sign_in users(:agent)

      service_request = service_requests(:waiting)
      previous_service_request = service_requests(:one)

      get switch_agent_service_request_path(service_request, service_request_id: previous_service_request)

      assert_equal "finished", previous_service_request.reload.status
      assert_equal "in_progress", service_request.reload.status
      assert previous_service_request.call_duration
      assert_equal 1, previous_service_request.logs.count

      assert_response :ok
    end

    private

    def test_switch_status(service_request)
      sign_in agent = users(:agent)

      put finish_agent_service_request_path(service_request)

      assert_equal "finished", service_request.reload.status
      assert service_request.call_ended_at
      assert service_request.call_duration

      assert_equal 1, service_request.logs.count

      assert_broadcasts "agent:todays_service_requests", agent.agent_service_requests.count
      assert_broadcasts "agent:all_service_requests", agent.agent_service_requests.count

      assert_redirected_to agent_home_path
    end
  end
end
