<commit_before># frozen_string_literal: true

require 'spec_helper'

module Bullet
  describe Rack do
    let(:middleware) { Bullet::Rack.new app }
    let(:app) { Support::AppDouble.new }

    context '#html_request?' do
      it 'should be true if Content-Type is text/html and http body contains html tag' do
        headers = { 'Content-Type' => 'text/html' }
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).to be_html_request(headers, response)
      end

      it 'should be true if Content-Type is text/html and http body contains html tag with attributes' do
        headers = { 'Content-Type' => 'text/html' }
        response = double(body: "<html attr='hello'><head></head><body></body></html>")
        expect(middleware).to be_html_request(headers, response)
      end

      it 'should be false if there is no Content-Type header' do
        headers = {}
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).not_to be_html_request(headers, response)
      end

      it 'should be false if Content-Type is javascript' do
        headers = { 'Content-Type' => 'text/javascript' }
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).not_to be_html_request(headers, response)
      end

      it "should be false if response body doesn't contain html tag" do
        headers = { 'Content-Type' => 'text/html' }
        response = double(body: '<div>Partial</div>')
        expect(middleware).not_to be_html_request(headers, response)
      end
    end

    context 'empty?' do
      it 'should be false if response is a string and not empty' do
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).not_to be_empty(response)
      end

      it 'should be false if response is not found' do
        response = ['Not Found']
        expect(middleware).not_to be_empty(response)
      end

      it 'should be true if response body is empty' do
        response = double(body: '')
        expect(middleware).to be_empty(response)
      end
    end

    context '#call' do
      context 'when Bullet is enabled' do
        it 'should return original response body' do
          expected_response = Support::ResponseDouble.new 'Actual body'
          app.response = expected_response
          _, _, response = middleware.call({})
          expect(response).to eq(expected_response)
        end

        it 'should change response body if notification is active' do
          expect(Bullet).to receive(:notification?).and_return(true)
          expect(Bullet).to receive(:console_enabled?).and_return(true)
          expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
          expect(Bullet).to receive(:perform_out_of_channel_notifications)
          _, headers, response = middleware.call('Content-Type' => 'text/html')
          expect(headers['Content-Length']).to eq('56')
          expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
        end

        it 'should set the right Content-Length if response body contains accents' do
          response = Support::ResponseDouble.new
          response.body = '<html><head></head><body>é</body></html>'
          app.response = response
          expect(Bullet).to receive(:notification?).and_return(true)
          allow(Bullet).to receive(:console_enabled?).and_return(true)
          expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
          _, headers, response = middleware.call('Content-Type' => 'text/html')
          expect(headers['Content-Length']).to eq('58')
        end

        context 'with injection notifiers' do
          before do
            expect(Bullet).to receive(:notification?).and_return(true)
            allow(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
            allow(middleware).to receive(:xhr_script).and_return('')
            allow(middleware).to receive(:footer_note).and_return('footer')
            expect(Bullet).to receive(:perform_out_of_channel_notifications)
          end

          it 'should change response body if add_footer is true' do
            expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
            _, headers, response = middleware.call('Content-Type' => 'text/html')

            expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
            expect(response.first).to start_with('<html><head></head><body>')
            expect(response.first).to include('<bullet></bullet><')
          end

          it 'should change response body for html safe string if add_footer is true' do
            expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
            app.response = Support::ResponseDouble.new.tap do |response|
              response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')
            end
            _, headers, response = middleware.call('Content-Type' => 'text/html')

            expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
            expect(response.first).to start_with('<html><head></head><body>')
            expect(response.first).to include('<bullet></bullet><')
          end

          it 'should change response body if console_enabled is true' do
            expect(Bullet).to receive(:console_enabled?).and_return(true)
            _, headers, response = middleware.call('Content-Type' => 'text/html')
            expect(headers['Content-Length']).to eq('56')
            expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
          end

          it 'should change response body for html safe string if console_enabled is true' do
            expect(Bullet).to receive(:console_enabled?).and_return(true)
            app.response = Support::ResponseDouble.new.tap do |response|
              response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')<commit_msg>Made specs check if/when the xhr script tag is added<commit_after># frozen_string_literal: true

require 'spec_helper'

module Bullet
  describe Rack do
    let(:middleware) { Bullet::Rack.new app }
    let(:app) { Support::AppDouble.new }

    context '#html_request?' do
      it 'should be true if Content-Type is text/html and http body contains html tag' do
        headers = { 'Content-Type' => 'text/html' }
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).to be_html_request(headers, response)
      end

      it 'should be true if Content-Type is text/html and http body contains html tag with attributes' do
        headers = { 'Content-Type' => 'text/html' }
        response = double(body: "<html attr='hello'><head></head><body></body></html>")
        expect(middleware).to be_html_request(headers, response)
      end

      it 'should be false if there is no Content-Type header' do
        headers = {}
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).not_to be_html_request(headers, response)
      end

      it 'should be false if Content-Type is javascript' do
        headers = { 'Content-Type' => 'text/javascript' }
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).not_to be_html_request(headers, response)
      end

      it "should be false if response body doesn't contain html tag" do
        headers = { 'Content-Type' => 'text/html' }
        response = double(body: '<div>Partial</div>')
        expect(middleware).not_to be_html_request(headers, response)
      end
    end

    context 'empty?' do
      it 'should be false if response is a string and not empty' do
        response = double(body: '<html><head></head><body></body></html>')
        expect(middleware).not_to be_empty(response)
      end

      it 'should be false if response is not found' do
        response = ['Not Found']
        expect(middleware).not_to be_empty(response)
      end

      it 'should be true if response body is empty' do
        response = double(body: '')
        expect(middleware).to be_empty(response)
      end
    end

    context '#call' do
      context 'when Bullet is enabled' do
        it 'should return original response body' do
          expected_response = Support::ResponseDouble.new 'Actual body'
          app.response = expected_response
          _, _, response = middleware.call({})
          expect(response).to eq(expected_response)
        end

        it 'should change response body if notification is active' do
          expect(Bullet).to receive(:notification?).and_return(true)
          expect(Bullet).to receive(:console_enabled?).and_return(true)
          expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
          expect(Bullet).to receive(:perform_out_of_channel_notifications)
          _, headers, response = middleware.call('Content-Type' => 'text/html')
          expect(headers['Content-Length']).to eq('56')
          expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
        end

        it 'should set the right Content-Length if response body contains accents' do
          response = Support::ResponseDouble.new
          response.body = '<html><head></head><body>é</body></html>'
          app.response = response
          expect(Bullet).to receive(:notification?).and_return(true)
          allow(Bullet).to receive(:console_enabled?).and_return(true)
          expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
          _, headers, response = middleware.call('Content-Type' => 'text/html')
          expect(headers['Content-Length']).to eq('58')
        end

        context 'with injection notifiers' do
          before do
            expect(Bullet).to receive(:notification?).and_return(true)
            allow(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
            allow(middleware).to receive(:xhr_script).and_return('<script></script>')
            allow(middleware).to receive(:footer_note).and_return('footer')
            expect(Bullet).to receive(:perform_out_of_channel_notifications)
          end

          it 'should change response body if add_footer is true' do
            expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
            _, headers, response = middleware.call('Content-Type' => 'text/html')

            expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
            expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet><script></script></body></html>])
          end

          it 'should change response body for html safe string if add_footer is true' do
            expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
            app.response = Support::ResponseDouble.new.tap do |response|
              response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')
            end
            _, headers, response = middleware.call('Content-Type' => 'text/html')

            expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
            expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet><script></script></body></html>])
          end

          it 'should change response body if console_enabled is true' do
            expect(Bullet).to receive(:console_enabled?).and_return(true)
            _, headers, response = middleware.call('Content-Type' => 'text/html')
            expect(headers['Content-Length']).to eq('56')
            expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
          end

          it 'should change response body for html safe string if console_enabled is true' do
            expect(Bullet).to receive(:console_enabled?).and_return(true)
            app.response = Support::ResponseDouble.new.tap do |response|
              response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')
{'fraction_non_alphanumeric': 0.13748588026464417, 'fraction_numerical': 0.0019364208487978054, 'mean_word_length': 2.9753046824887748, 'pattern_counts': {'":': 0, '<': 183, '<?xml version=': 0, '>': 199, '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': '5291288', 'n_tokens_mistral': 3413, 'n_tokens_neox': 3348, 'n_words': 786}