require 'test_helper'
require 'developer_portal'

class LogRequestsTest < ActionDispatch::IntegrationTest

  include TestHelpers::LogRequestsAssertions
  include TestHelpers::BackendClientStubs
  include DeveloperPortal::Engine.routes.url_helpers

  def setup
    @provider = Factory :provider_account
    @provider.settings.allow_log_requests!
    @provider.settings.show_log_requests!

    @plan1 = Factory :application_plan, :issuer => @provider.default_service

    @service1 = Factory :service, :account => @provider, :name => "API1"
    @service2 = Factory :service, :account => @provider, :name => "API2"

    @plan1 = Factory :application_plan, :issuer => @service1
    @plan2 = Factory :application_plan, :issuer => @service2

    @buyer = Factory :buyer_account, :provider_account => @provider

    @application1 = @plan1.create_contract_with(@buyer)
    @application2 = @plan2.create_contract_with(@buyer)
  end

  should 'a buyer that is not logged in cannot see log requests' do

    ## buyer side
    host! @provider.domain
    get(admin_application_log_requests_path(@application1))
    assert_redirected_to login_url
    delete(admin_application_purge_logs_path(@application1))
    assert_redirected_to login_url

    ## provider side, by application
    host! @provider.admin_domain
    get(admin_buyers_account_application_log_requests_path(@provider, @application1))
    assert_redirected_to provider_login_url
    delete(admin_buyers_account_application_purge_logs_path(@provider, @application1))
    assert_redirected_to provider_login_url

    ## provider side, by service
    host! @provider.admin_domain
    get(admin_service_log_requests_path(@service1))
    assert_redirected_to provider_login_url
    delete(admin_service_purge_logs_path(@service1))
    assert_redirected_to provider_login_url
  end

  context :provider_logged_in do

    setup do
      host! @provider.admin_domain
      provider_login_with @provider.admins.first.username, 'supersecret'
    end

    should 'index' do
      data = data_for_log_requests("service",@service1.id,@application1.application_id,10)
      stub_backend_get_service_log_requests(data)

      get(admin_service_log_requests_path(@service1))

      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_log_results_by_service(xml,data,@application1)
    end

    should 'index without log requests' do
      data = data_for_log_requests("service",@service1.id,@application1.application_id,0)
      stub_backend_get_service_log_requests(data)

      get(admin_service_log_requests_path(@service1))

      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_log_empty(xml,data)
    end

    should 'checking application log request' do
      data = data_for_log_requests("application",@service1.id,@application1.application_id,10)
      stub_backend_get_application_log_requests(data)

      get(admin_buyers_account_application_log_requests_path(@buyer, @application1))
      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_log_results_by_application(xml,data,@application1)
    end

    should 'application empty log request without' do
      data = data_for_log_requests("application",@service1.id,@application1.application_id,0)
      stub_backend_get_application_log_requests(data)

      get(admin_buyers_account_application_log_requests_path(@buyer, @application1))

      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_log_empty(xml,data)
    end

    should 'purge by service' do

      data = data_for_log_requests("service",@service1.id,@application1.application_id,10)
      stub_backend_get_service_log_requests(data)
      stub_backend_delete_all_service_log_requests(data)

      delete(admin_service_purge_logs_path(@service1))
      assert_redirected_to admin_service_log_requests_url(@service1)
    end

    should 'purge by application' do

      data = data_for_log_requests("application",@service1.id,@application1.application_id,10)
      stub_backend_get_application_log_requests(data)
      stub_backend_delete_all_application_log_requests(data)

      delete(admin_buyers_account_application_purge_logs_path(@buyer, @application1))
      assert_redirected_to admin_buyers_account_application_log_requests_url(@buyer, @application1)

    end

  end

  context :buyer_logged_in do

    setup do
      host! @provider.domain

      post '/session', :username => @buyer.admins.first.username, :password => 'supersecret'
      follow_redirect!

      @service1.buyer_can_see_log_requests = true
      @service2.buyer_can_see_log_requests = false

      @service1.save
      @service2.save
    end

    should 'get 403 when provider has log_requests disabled' do
      @provider.settings.deny_log_requests!

      get(admin_application_log_requests_path(@application1))
      assert_response :forbidden

      @service2.buyer_can_see_log_requests = true
      @service2.save!
      get(admin_application_log_requests_path(@application2))
      assert_response :forbidden

      @provider.settings.allow_log_requests!

      get(admin_application_log_requests_path(@application1))
      assert_response :forbidden

      get(admin_application_log_requests_path(@application2))
      assert_response :forbidden
    end

    should 'checking application log request buyer_can_see settings' do
      data = data_for_log_requests("application",@service1.id,@application1.application_id,10)
      stub_backend_get_application_log_requests(data)

      get(admin_application_log_requests_path(@application1))

      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_log_results_by_application(xml,data,@application1)
    end

    should 'checking empty application log request buyer_can_see settings' do
      get(admin_application_log_requests_path(@application2))
      assert_response :not_found
    end

    should 'link to log requests only appears if buyer_can_see' do

      data = data_for_log_requests("application",@service1.id,@application1.application_id,10)
      stub_backend_get_application_log_requests(data)
      stub_backend_get_keys

      get(admin_application_path(@application1))
      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_equal xml.xpath(".//a[@href='#{admin_application_log_requests_path(@application1)}']").size, 1
      assert_equal xml.xpath(".//a[@href='#{admin_application_log_requests_path(@application2)}']").size, 0

      get(admin_application_path(@application2))
      assert_response :success
      xml = Nokogiri::XML.parse(body)
      assert_equal xml.xpath(".//a[@href='#{admin_application_log_requests_path(@application1)}']").size, 0
      assert_equal xml.xpath(".//a[@href='#{admin_application_log_requests_path(@application2)}']").size, 0

    end

    should 'purge by application' do
      data = data_for_log_requests("application",@service1.id,@application1.application_id,10)
      stub_backend_get_application_log_requests(data)
      stub_backend_delete_all_application_log_requests(data)

      delete(admin_application_purge_logs_path(@application1))

      assert_redirected_to admin_application_log_requests_url(@application1)
    end

  end

  private

  def data_for_log_requests(type, service_id, app_id, size)
    Array.new(size) do |i|
      { code: "#{type}: code #{i}",
        request: "fake_request",
        response: "fake_response",
        app_id: app_id,
        service_id: service_id,
        usage: "fake_usage" }
    end
  end

end
