<commit_before># frozen_string_literal: true

RSpec.describe HTTP::Redirector do
  def simple_response(status, body = "", headers = {})
    HTTP::Response.new(
      :status  => status,
      :version => "1.1",
      :headers => headers,
      :body    => body,
      :request => HTTP::Request.new(:verb => :get, :uri => "http://example.com")
    )
  end

  def redirect_response(status, location, set_cookie = {})
    res = simple_response status, "", "Location" => location
    set_cookie.each do |name, value|
      res.headers.add("Set-Cookie", "#{name}=#{value}; path=/; httponly; secure; SameSite=none; Secure")
    end
    res
  end

  describe "#strict" do
    subject { redirector.strict }

    context "by default" do
      let(:redirector) { described_class.new }
      it { is_expected.to be true }
    end
  end

  describe "#max_hops" do
    subject { redirector.max_hops }

    context "by default" do
      let(:redirector) { described_class.new }
      it { is_expected.to eq 5 }
    end
  end

  describe "#perform" do
    let(:options)    { {} }
    let(:redirector) { described_class.new options }

    it "fails with TooManyRedirectsError if max hops reached" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      res = proc { |prev_req| redirect_response(301, "#{prev_req.uri}/1") }

      expect { redirector.perform(req, res.call(req), &res) }.
        to raise_error HTTP::Redirector::TooManyRedirectsError
    end

    it "fails with EndlessRedirectError if endless loop detected" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      res = redirect_response(301, req.uri)

      expect { redirector.perform(req, res) { res } }.
        to raise_error HTTP::Redirector::EndlessRedirectError
    end

    it "fails with StateError if there were no Location header" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      res = simple_response(301)

      expect { |b| redirector.perform(req, res, &b) }.
        to raise_error HTTP::StateError
    end

    it "returns first non-redirect response" do
      req  = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      hops = [
        redirect_response(301, "http://example.com/1"),
        redirect_response(301, "http://example.com/2"),
        redirect_response(301, "http://example.com/3"),
        simple_response(200, "foo"),
        redirect_response(301, "http://example.com/4"),
        simple_response(200, "bar")
      ]

      res = redirector.perform(req, hops.shift) { hops.shift }
      expect(res.to_s).to eq "foo"
    end

    it "concatenates multiple Location headers" do
      req     = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      headers = HTTP::Headers.new

      %w[http://example.com /123].each { |loc| headers.add("Location", loc) }

      res = redirector.perform(req, simple_response(301, "", headers)) do |redirect|
        simple_response(200, redirect.uri.to_s)
      end

      expect(res.to_s).to eq "http://example.com/123"
    end

    it "returns cookies in response" do
      req  = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      hops = [
        redirect_response(301, "http://example.com/1", {"foo" => "42"}),
        redirect_response(301, "http://example.com/2", {"bar" => "53", "deleted" => "foo"}),
        redirect_response(301, "http://example.com/3", {"baz" => "64", "deleted" => ""}),
        redirect_response(301, "http://example.com/4", {"baz" => "65"}),
        simple_response(200, "bar")
      ]

      request_cookies = [
        {"foo" => "42"},
        {"foo" => "42", "bar" => "53", "deleted" => "foo"},
        {"foo" => "42", "bar" => "53", "baz" => "64"},
        {"foo" => "42", "bar" => "53", "baz" => "65"}
      ]

      res = redirector.perform(req, hops.shift) do |request|
        req_cookie = HTTP::Cookie.cookie_value_to_hash(request.headers["Cookie"] || "")
        expect(req_cookie).to eq request_cookies.shift
        hops.shift
      end
      expect(res.to_s).to eq "bar"
      cookies = res.cookies.cookies.map { |c| [c.name, c.value] }.to_h
      expect(cookies["foo"]).to eq "42"
      expect(cookies["bar"]).to eq "53"
      expect(cookies["baz"]).to eq "65"
      expect(cookies["deleted"]).to eq nil
    end

    it "returns original cookies in response" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      req.headers.set("Cookie", "foo=42; deleted=baz")
      hops = [
        redirect_response(301, "http://example.com/1", {"bar" => "64", "deleted" => ""}),
        simple_response(200, "bar")
      ]

      request_cookies = [
        {"foo" => "42", "bar" => "64"},
        {"foo" => "42", "bar" => "64"}
      ]

      res = redirector.perform(req, hops.shift) do |request|
        req_cookie = HTTP::Cookie.cookie_value_to_hash(request.headers["Cookie"] || "")
        expect(req_cookie).to eq request_cookies.shift
        hops.shift
      end
      expect(res.to_s).to eq "bar"
      cookies = res.cookies.cookies.map { |c| [c.name, c.value] }.to_h
      expect(cookies["foo"]).to eq "42"
      expect(cookies["bar"]).to eq "64"
      expect(cookies["deleted"]).to eq nil
    end<commit_msg>Fix rubocop (#718)<commit_after># frozen_string_literal: true

RSpec.describe HTTP::Redirector do
  def simple_response(status, body = "", headers = {})
    HTTP::Response.new(
      :status  => status,
      :version => "1.1",
      :headers => headers,
      :body    => body,
      :request => HTTP::Request.new(:verb => :get, :uri => "http://example.com")
    )
  end

  def redirect_response(status, location, set_cookie = {})
    res = simple_response status, "", "Location" => location
    set_cookie.each do |name, value|
      res.headers.add("Set-Cookie", "#{name}=#{value}; path=/; httponly; secure; SameSite=none; Secure")
    end
    res
  end

  describe "#strict" do
    subject { redirector.strict }

    context "by default" do
      let(:redirector) { described_class.new }
      it { is_expected.to be true }
    end
  end

  describe "#max_hops" do
    subject { redirector.max_hops }

    context "by default" do
      let(:redirector) { described_class.new }
      it { is_expected.to eq 5 }
    end
  end

  describe "#perform" do
    let(:options)    { {} }
    let(:redirector) { described_class.new options }

    it "fails with TooManyRedirectsError if max hops reached" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      res = proc { |prev_req| redirect_response(301, "#{prev_req.uri}/1") }

      expect { redirector.perform(req, res.call(req), &res) }.
        to raise_error HTTP::Redirector::TooManyRedirectsError
    end

    it "fails with EndlessRedirectError if endless loop detected" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      res = redirect_response(301, req.uri)

      expect { redirector.perform(req, res) { res } }.
        to raise_error HTTP::Redirector::EndlessRedirectError
    end

    it "fails with StateError if there were no Location header" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      res = simple_response(301)

      expect { |b| redirector.perform(req, res, &b) }.
        to raise_error HTTP::StateError
    end

    it "returns first non-redirect response" do
      req  = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      hops = [
        redirect_response(301, "http://example.com/1"),
        redirect_response(301, "http://example.com/2"),
        redirect_response(301, "http://example.com/3"),
        simple_response(200, "foo"),
        redirect_response(301, "http://example.com/4"),
        simple_response(200, "bar")
      ]

      res = redirector.perform(req, hops.shift) { hops.shift }
      expect(res.to_s).to eq "foo"
    end

    it "concatenates multiple Location headers" do
      req     = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      headers = HTTP::Headers.new

      %w[http://example.com /123].each { |loc| headers.add("Location", loc) }

      res = redirector.perform(req, simple_response(301, "", headers)) do |redirect|
        simple_response(200, redirect.uri.to_s)
      end

      expect(res.to_s).to eq "http://example.com/123"
    end

    it "returns cookies in response" do
      req  = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      hops = [
        redirect_response(301, "http://example.com/1", {"foo" => "42"}),
        redirect_response(301, "http://example.com/2", {"bar" => "53", "deleted" => "foo"}),
        redirect_response(301, "http://example.com/3", {"baz" => "64", "deleted" => ""}),
        redirect_response(301, "http://example.com/4", {"baz" => "65"}),
        simple_response(200, "bar")
      ]

      request_cookies = [
        {"foo" => "42"},
        {"foo" => "42", "bar" => "53", "deleted" => "foo"},
        {"foo" => "42", "bar" => "53", "baz" => "64"},
        {"foo" => "42", "bar" => "53", "baz" => "65"}
      ]

      res = redirector.perform(req, hops.shift) do |request|
        req_cookie = HTTP::Cookie.cookie_value_to_hash(request.headers["Cookie"] || "")
        expect(req_cookie).to eq request_cookies.shift
        hops.shift
      end
      expect(res.to_s).to eq "bar"
      cookies = res.cookies.cookies.to_h { |c| [c.name, c.value] }
      expect(cookies["foo"]).to eq "42"
      expect(cookies["bar"]).to eq "53"
      expect(cookies["baz"]).to eq "65"
      expect(cookies["deleted"]).to eq nil
    end

    it "returns original cookies in response" do
      req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
      req.headers.set("Cookie", "foo=42; deleted=baz")
      hops = [
        redirect_response(301, "http://example.com/1", {"bar" => "64", "deleted" => ""}),
        simple_response(200, "bar")
      ]

      request_cookies = [
        {"foo" => "42", "bar" => "64"},
        {"foo" => "42", "bar" => "64"}
      ]

      res = redirector.perform(req, hops.shift) do |request|
        req_cookie = HTTP::Cookie.cookie_value_to_hash(request.headers["Cookie"] || "")
        expect(req_cookie).to eq request_cookies.shift
        hops.shift
      end
      expect(res.to_s).to eq "bar"
      cookies = res.cookies.cookies.to_h { |c| [c.name, c.value] }
      expect(cookies["foo"]).to eq "42"
      expect(cookies["bar"]).to eq "64"
      expect(cookies["deleted"]).to eq nil
    end
{'fraction_non_alphanumeric': 0.17349374582259142, 'fraction_numerical': 0.023393488016805117, 'mean_word_length': 2.7260761294912843, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2469146', 'n_tokens_mistral': 3618, 'n_tokens_neox': 3407, 'n_words': 777}