<commit_before>require 'spec_helper'
require 'billy'
require 'resolv'

shared_examples_for 'a proxy server' do
  it 'should proxy GET requests' do
    http.get('/echo').body.should == 'GET /echo'
  end

  it 'should proxy POST requests' do
    http.post('/echo', :foo => 'bar').body.should == "POST /echo\nfoo=bar"
  end

  it 'should proxy PUT requests' do
    http.post('/echo', :foo => 'bar').body.should == "POST /echo\nfoo=bar"
  end

  it 'should proxy HEAD requests' do
    http.head('/echo').headers['HTTP-X-EchoServer'].should == 'HEAD /echo'
  end

  it 'should proxy DELETE requests' do
    http.delete('/echo').body.should == 'DELETE /echo'
  end
end

shared_examples_for 'a request stub' do
  it 'should stub GET requests' do
    proxy.stub("#{url}/foo").
      and_return(:text => 'hello, GET!')
    http.get('/foo').body.should == 'hello, GET!'
  end

  it 'should stub GET response statuses' do
    proxy.stub("#{url}/foo").
      and_return(:code => 200)
    http.get('/foo').status.should == 200
  end

  it 'should stub POST requests' do
    proxy.stub("#{url}/bar", :method => :post).
      and_return(:text => 'hello, POST!')
    http.post('/bar', :foo => :bar).body.should == 'hello, POST!'
  end

  it 'should stub PUT requests' do
    proxy.stub("#{url}/baz", :method => :put).
      and_return(:text => 'hello, PUT!')
    http.put('/baz', :foo => :bar).body.should == 'hello, PUT!'
  end

  it 'should stub HEAD requests' do
    proxy.stub("#{url}/bap", :method => :head).
      and_return(:headers => {'HTTP-X-Hello' => 'hello, HEAD!'})
    http.head('/bap').headers['http-x-hello'].should == 'hello, HEAD!'
  end

  it 'should stub DELETE requests' do
    proxy.stub("#{url}/bam", :method => :delete).
      and_return(:text => 'hello, DELETE!')
    http.delete('/bam').body.should == 'hello, DELETE!'
  end
end

shared_examples_for 'a cache' do

  context 'whitelisted GET requests' do
    it 'should not be cached' do
      assert_noncached_url
    end

    context 'with ports' do
      before do
        rack_app_url = URI(http.url_prefix)
        Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port}"]
      end

      it 'should not be cached ' do
        assert_noncached_url
      end
    end
  end

  context 'non-whitelisted GET requests' do
    before do
      Billy.config.whitelist = []
    end

    it 'should be cached' do
      assert_cached_url
    end

    context 'with ports' do
      before do
        rack_app_url = URI(http.url_prefix)
        Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port+1}"]
      end

      it 'should be cached' do
        assert_cached_url
      end
    end
  end

  context 'ignore_params GET requests' do
    before do
      Billy.config.ignore_params = ['/analytics']
    end

    it 'should be cached' do
      r = http.get('/analytics?some_param=5')
      r.body.should == 'GET /analytics'
      expect {
        expect {
          r = http.get('/analytics?some_param=20')
        }.to change { r.headers['HTTP-X-EchoCount'].to_i }.by(1)
      }.to_not change { r.body }
    end
  end

  context 'path_blacklist GET requests' do
    before do
      Billy.config.path_blacklist = ['/api']
    end

    it 'should be cached' do
      assert_cached_url('/api')
    end
  end

  context "cache persistence" do
    let(:cached_key) { proxy.cache.key('get',"#{url}/foo","") }
    let(:cached_file) do
      f = cached_key + ".yml"
      File.join(Billy.config.cache_path, f)
    end

    before { Billy.config.whitelist = [] }

    after do
      File.delete(cached_file) if File.exists?(cached_file)
    end

    context "enabled" do
      before { Billy.config.persist_cache = true }

      it 'should persist' do
        r = http.get('/foo')
        File.exists?(cached_file).should be_true
      end

      it 'should be read initially from persistent cache' do
        File.open(cached_file, 'w') do |f|
          cached = {
            :headers => {},
            :content => "GET /foo cached"
          }
          f.write(cached.to_yaml(:Encoding => :Utf8))
        end

        r = http.get('/foo')
        r.body.should == 'GET /foo cached'
      end

      context 'ignore_cache_port requests' do
        it 'should be cached without port' do
          r   = http.get('/foo')
          url = URI(r.env[:url])
          saved_cache = Billy.proxy.cache.fetch_from_persistence(cached_key)

          expect(saved_cache[:url]).to_not eql(url.to_s)
          expect(saved_cache[:url]).to eql(url.to_s.gsub(":#{url.port}", ''))
        end
      end

      context 'disable_nonwhitelisted_requests requests' do
        before { Billy.config.disable_nonwhitelisted_requests = true }

        it 'should raise error when disabled' do
          #TODO: Suppress stderr output: https://gist.github.com/adamstegman/926858
          expect{http.get('/foo')}.to raise_error(Faraday::Error::ConnectionFailed)
        end
      end

      context 'non_successful_cache_disabled requests' do
        before { Billy.config.non_successful_cache_disabled = true }

        it 'should not cache non-successful response when enabled' do
          # The test server in spec/support/test_server.rb is hard-coded to return a 200
          # Need a way to simulate a non-successful response for this testyy

          # Using this method never creates a file
          # proxy.stub("#{url}/foo").and_return(:text => 'GET /foo', :code => 500)
          # http.get('/foo')

          # File.exists?(cached_file).should be_false
        end

        it 'should cache successful response when enabled' do
          assert_cached_url
        end
      end

      context 'non_successful_error_level requests' do<commit_msg>More explicit error checking<commit_after>require 'spec_helper'
require 'billy'
require 'resolv'

shared_examples_for 'a proxy server' do
  it 'should proxy GET requests' do
    http.get('/echo').body.should == 'GET /echo'
  end

  it 'should proxy POST requests' do
    http.post('/echo', :foo => 'bar').body.should == "POST /echo\nfoo=bar"
  end

  it 'should proxy PUT requests' do
    http.post('/echo', :foo => 'bar').body.should == "POST /echo\nfoo=bar"
  end

  it 'should proxy HEAD requests' do
    http.head('/echo').headers['HTTP-X-EchoServer'].should == 'HEAD /echo'
  end

  it 'should proxy DELETE requests' do
    http.delete('/echo').body.should == 'DELETE /echo'
  end
end

shared_examples_for 'a request stub' do
  it 'should stub GET requests' do
    proxy.stub("#{url}/foo").
      and_return(:text => 'hello, GET!')
    http.get('/foo').body.should == 'hello, GET!'
  end

  it 'should stub GET response statuses' do
    proxy.stub("#{url}/foo").
      and_return(:code => 200)
    http.get('/foo').status.should == 200
  end

  it 'should stub POST requests' do
    proxy.stub("#{url}/bar", :method => :post).
      and_return(:text => 'hello, POST!')
    http.post('/bar', :foo => :bar).body.should == 'hello, POST!'
  end

  it 'should stub PUT requests' do
    proxy.stub("#{url}/baz", :method => :put).
      and_return(:text => 'hello, PUT!')
    http.put('/baz', :foo => :bar).body.should == 'hello, PUT!'
  end

  it 'should stub HEAD requests' do
    proxy.stub("#{url}/bap", :method => :head).
      and_return(:headers => {'HTTP-X-Hello' => 'hello, HEAD!'})
    http.head('/bap').headers['http-x-hello'].should == 'hello, HEAD!'
  end

  it 'should stub DELETE requests' do
    proxy.stub("#{url}/bam", :method => :delete).
      and_return(:text => 'hello, DELETE!')
    http.delete('/bam').body.should == 'hello, DELETE!'
  end
end

shared_examples_for 'a cache' do

  context 'whitelisted GET requests' do
    it 'should not be cached' do
      assert_noncached_url
    end

    context 'with ports' do
      before do
        rack_app_url = URI(http.url_prefix)
        Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port}"]
      end

      it 'should not be cached ' do
        assert_noncached_url
      end
    end
  end

  context 'non-whitelisted GET requests' do
    before do
      Billy.config.whitelist = []
    end

    it 'should be cached' do
      assert_cached_url
    end

    context 'with ports' do
      before do
        rack_app_url = URI(http.url_prefix)
        Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port+1}"]
      end

      it 'should be cached' do
        assert_cached_url
      end
    end
  end

  context 'ignore_params GET requests' do
    before do
      Billy.config.ignore_params = ['/analytics']
    end

    it 'should be cached' do
      r = http.get('/analytics?some_param=5')
      r.body.should == 'GET /analytics'
      expect {
        expect {
          r = http.get('/analytics?some_param=20')
        }.to change { r.headers['HTTP-X-EchoCount'].to_i }.by(1)
      }.to_not change { r.body }
    end
  end

  context 'path_blacklist GET requests' do
    before do
      Billy.config.path_blacklist = ['/api']
    end

    it 'should be cached' do
      assert_cached_url('/api')
    end
  end

  context "cache persistence" do
    let(:cached_key) { proxy.cache.key('get',"#{url}/foo","") }
    let(:cached_file) do
      f = cached_key + ".yml"
      File.join(Billy.config.cache_path, f)
    end

    before { Billy.config.whitelist = [] }

    after do
      File.delete(cached_file) if File.exists?(cached_file)
    end

    context "enabled" do
      before { Billy.config.persist_cache = true }

      it 'should persist' do
        r = http.get('/foo')
        File.exists?(cached_file).should be_true
      end

      it 'should be read initially from persistent cache' do
        File.open(cached_file, 'w') do |f|
          cached = {
            :headers => {},
            :content => "GET /foo cached"
          }
          f.write(cached.to_yaml(:Encoding => :Utf8))
        end

        r = http.get('/foo')
        r.body.should == 'GET /foo cached'
      end

      context 'ignore_cache_port requests' do
        it 'should be cached without port' do
          r   = http.get('/foo')
          url = URI(r.env[:url])
          saved_cache = Billy.proxy.cache.fetch_from_persistence(cached_key)

          expect(saved_cache[:url]).to_not eql(url.to_s)
          expect(saved_cache[:url]).to eql(url.to_s.gsub(":#{url.port}", ''))
        end
      end

      context 'disable_nonwhitelisted_requests requests' do
        before { Billy.config.disable_nonwhitelisted_requests = true }

        it 'should raise error when disabled' do
          #TODO: Suppress stderr output: https://gist.github.com/adamstegman/926858
          expect{http.get('/foo')}.to raise_error(Faraday::Error::ConnectionFailed, "end of file reached")
        end
      end

      context 'non_successful_cache_disabled requests' do
        before { Billy.config.non_successful_cache_disabled = true }

        it 'should not cache non-successful response when enabled' do
          # The test server in spec/support/test_server.rb is hard-coded to return a 200
          # Need a way to simulate a non-successful response for this testyy

          # Using this method never creates a file
          # proxy.stub("#{url}/foo").and_return(:text => 'GET /foo', :code => 500)
          # http.get('/foo')

          # File.exists?(cached_file).should be_false
        end

        it 'should cache successful response when enabled' do
          assert_cached_url
        end
      end

      context 'non_successful_error_level requests' do
{'fraction_non_alphanumeric': 0.13372295882763433, 'fraction_numerical': 0.00418702023726448, 'mean_word_length': 2.5039731051344742, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 43, 'https://': 2, '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': '1035636', 'n_tokens_mistral': 3752, 'n_tokens_neox': 3649, 'n_words': 954}