<commit_before>package rye

import (
	"strconv"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"context"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"time"

	"github.com/InVisionApp/rye/fakes/statsdfakes"
	"github.com/onsi/gomega/types"
)

const (
	RYE_TEST_HANDLER_ENV_VAR   = "RYE_TEST_HANDLER_PASS"
	RYE_TEST_HANDLER_2_ENV_VAR = "RYE_TEST_HANDLER_2_PASS"
	RYE_TEST_BEFORE_ENV_VAR    = "RYE_TEST_HANDLER_BEFORE_PASS"
)

type statsInc struct {
	Name     string
	Time     int64
	StatRate float32
}

type statsTiming struct {
	Name     string
	Time     time.Duration
	StatRate float32
}

var _ = Describe("Rye", func() {

	var (
		request     *http.Request
		response    *httptest.ResponseRecorder
		mwHandler   *MWHandler
		ryeConfig   Config
		fakeStatter *statsdfakes.FakeStatter
		inc         chan statsInc
		timing      chan statsTiming
	)

	const (
		STATRATE float32 = 1
	)

	BeforeEach(func() {
		fakeStatter = &statsdfakes.FakeStatter{}
		ryeConfig = Config{
			Statter:  fakeStatter,
			StatRate: STATRATE,
		}
		mwHandler = NewMWHandler(ryeConfig)

		response = httptest.NewRecorder()
		request = &http.Request{
			Header: make(map[string][]string, 0),
		}

		os.Unsetenv(RYE_TEST_HANDLER_ENV_VAR)
		os.Unsetenv(RYE_TEST_BEFORE_ENV_VAR)
		os.Unsetenv(RYE_TEST_HANDLER_2_ENV_VAR)

		inc = make(chan statsInc, 2)
		timing = make(chan statsTiming)

		fakeStatter.IncStub = func(name string, time int64, statrate float32) error {
			inc <- statsInc{name, time, statrate}
			return nil
		}

		fakeStatter.TimingDurationStub = func(name string, time time.Duration, statrate float32) error {
			timing <- statsTiming{name, time, statrate}
			return nil
		}

	})

	AfterEach(func() {
		os.Unsetenv(RYE_TEST_HANDLER_ENV_VAR)
	})

	Describe("NewMWHandler", func() {
		Context("when instantiating a mwhandler", func() {
			It("should have correct attributes", func() {
				ryeConfig := Config{
					Statter:  fakeStatter,
					StatRate: STATRATE,
				}
				handler := NewMWHandler(ryeConfig)
				Expect(handler).NotTo(BeNil())
				Expect(handler.Config.Statter).To(Equal(fakeStatter))
				Expect(handler.Config.StatRate).To(Equal(STATRATE))
			})

			It("should have attributes with default values when passed an empty config", func() {
				handler := NewMWHandler(Config{})
				Expect(handler).NotTo(BeNil())
				Expect(handler.Config.Statter).To(BeNil())
				Expect(handler.Config.StatRate).To(Equal(float32(0.0)))
			})
		})
	})

	Describe("Handle", func() {
		Context("when adding a valid handler", func() {
			It("should return valid HandlerFunc", func() {

				h := mwHandler.Handle([]Handler{successHandler})
				h.ServeHTTP(response, request)

				Expect(h).ToNot(BeNil())
				Expect(h).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))
				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).To(Equal("1"))

				Eventually(inc).Should(Receive(&statsInc{"handlers.successHandler.2xx", 1, float32(STATRATE)}))
				Eventually(timing).Should(Receive(HaveTiming("handlers.successHandler.runtime", float32(STATRATE))))
			})
		})

		Context("when adding a global handler it should get called for multiple handler chains", func() {

			It("should execute before handlers and end in success", func() {

				handlerWithGlobals := NewMWHandler(ryeConfig)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)

				h := handlerWithGlobals.Handle([]Handler{successHandler})
				h.ServeHTTP(response, request)

				Expect(h).ToNot(BeNil())
				Expect(h).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))
				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).To(Equal("1"))
				Expect(os.Getenv(RYE_TEST_BEFORE_ENV_VAR)).To(Equal("3"))
			})

			It("should execute before handlers and multiple Handles should manage their closure correctly", func() {

				handlerWithGlobals := NewMWHandler(ryeConfig)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)

				h := handlerWithGlobals.Handle([]Handler{successHandler})

				h2 := handlerWithGlobals.Handle([]Handler{success2Handler})

				h.ServeHTTP(response, request)
				h2.ServeHTTP(response, request)

				Expect(h).ToNot(BeNil())
				Expect(h).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))

				Expect(h2).ToNot(BeNil())
				Expect(h2).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))

				before := os.Getenv(RYE_TEST_BEFORE_ENV_VAR)
				handler1 := os.Getenv(RYE_TEST_HANDLER_ENV_VAR)
				handler2 := os.Getenv(RYE_TEST_HANDLER_2_ENV_VAR)

				Expect(before).To(Equal("6"))
				Expect(handler1).To(Equal("1"))
				Expect(handler2).To(Equal("1"))
			})
		})

		Context("when a handler returns a response with StopExecution", func() {
			It("should not execute any further handlers", func() {
				request.Method = "OPTIONS"

				h := mwHandler.Handle([]Handler{stopExecutionHandler, successHandler})
				h.ServeHTTP(response, request)

				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).ToNot(Equal("1"))
			})
		})

		Context("when a handler returns a response with StopExecution and StatusCode", func() {
			It("should not execute any further handlers", func() {
				h := mwHandler.Handle([]Handler{stopExecutionWithStatusHandler, successHandler})
				h.ServeHTTP(response, request)

				Eventually(inc).Should(Receive(&statsInc{"handlers.stopExecutionWithStatusHandler.404", 1, float32(STATRATE)}))
				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).ToNot(Equal("1"))
			})
		})

		Context("when a before handler returns a response with StopExecution", func() {
			It("should not execute any further handlers", func() {<commit_msg>Add Equality assertion to test so that it actually tests stuff<commit_after>package rye

import (
	"strconv"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"context"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"time"

	"github.com/InVisionApp/rye/fakes/statsdfakes"
	"github.com/onsi/gomega/types"
)

const (
	RYE_TEST_HANDLER_ENV_VAR   = "RYE_TEST_HANDLER_PASS"
	RYE_TEST_HANDLER_2_ENV_VAR = "RYE_TEST_HANDLER_2_PASS"
	RYE_TEST_BEFORE_ENV_VAR    = "RYE_TEST_HANDLER_BEFORE_PASS"
)

type statsInc struct {
	Name     string
	Time     int64
	StatRate float32
}

type statsTiming struct {
	Name     string
	Time     time.Duration
	StatRate float32
}

var _ = Describe("Rye", func() {

	var (
		request     *http.Request
		response    *httptest.ResponseRecorder
		mwHandler   *MWHandler
		ryeConfig   Config
		fakeStatter *statsdfakes.FakeStatter
		inc         chan statsInc
		timing      chan statsTiming
	)

	const (
		STATRATE float32 = 1
	)

	BeforeEach(func() {
		fakeStatter = &statsdfakes.FakeStatter{}
		ryeConfig = Config{
			Statter:  fakeStatter,
			StatRate: STATRATE,
		}
		mwHandler = NewMWHandler(ryeConfig)

		response = httptest.NewRecorder()
		request = &http.Request{
			Header: make(map[string][]string, 0),
		}

		os.Unsetenv(RYE_TEST_HANDLER_ENV_VAR)
		os.Unsetenv(RYE_TEST_BEFORE_ENV_VAR)
		os.Unsetenv(RYE_TEST_HANDLER_2_ENV_VAR)

		inc = make(chan statsInc, 2)
		timing = make(chan statsTiming)

		fakeStatter.IncStub = func(name string, time int64, statrate float32) error {
			inc <- statsInc{name, time, statrate}
			return nil
		}

		fakeStatter.TimingDurationStub = func(name string, time time.Duration, statrate float32) error {
			timing <- statsTiming{name, time, statrate}
			return nil
		}

	})

	AfterEach(func() {
		os.Unsetenv(RYE_TEST_HANDLER_ENV_VAR)
	})

	Describe("NewMWHandler", func() {
		Context("when instantiating a mwhandler", func() {
			It("should have correct attributes", func() {
				ryeConfig := Config{
					Statter:  fakeStatter,
					StatRate: STATRATE,
				}
				handler := NewMWHandler(ryeConfig)
				Expect(handler).NotTo(BeNil())
				Expect(handler.Config.Statter).To(Equal(fakeStatter))
				Expect(handler.Config.StatRate).To(Equal(STATRATE))
			})

			It("should have attributes with default values when passed an empty config", func() {
				handler := NewMWHandler(Config{})
				Expect(handler).NotTo(BeNil())
				Expect(handler.Config.Statter).To(BeNil())
				Expect(handler.Config.StatRate).To(Equal(float32(0.0)))
			})
		})
	})

	Describe("Handle", func() {
		Context("when adding a valid handler", func() {
			It("should return valid HandlerFunc", func() {

				h := mwHandler.Handle([]Handler{successHandler})
				h.ServeHTTP(response, request)

				Expect(h).ToNot(BeNil())
				Expect(h).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))
				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).To(Equal("1"))

				Eventually(inc).Should(Receive(&statsInc{"handlers.successHandler.2xx", 1, float32(STATRATE)}))
				Eventually(timing).Should(Receive(HaveTiming("handlers.successHandler.runtime", float32(STATRATE))))
			})
		})

		Context("when adding a global handler it should get called for multiple handler chains", func() {

			It("should execute before handlers and end in success", func() {

				handlerWithGlobals := NewMWHandler(ryeConfig)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)

				h := handlerWithGlobals.Handle([]Handler{successHandler})
				h.ServeHTTP(response, request)

				Expect(h).ToNot(BeNil())
				Expect(h).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))
				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).To(Equal("1"))
				Expect(os.Getenv(RYE_TEST_BEFORE_ENV_VAR)).To(Equal("3"))
			})

			It("should execute before handlers and multiple Handles should manage their closure correctly", func() {

				handlerWithGlobals := NewMWHandler(ryeConfig)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)
				handlerWithGlobals.Use(beforeHandler)

				h := handlerWithGlobals.Handle([]Handler{successHandler})

				h2 := handlerWithGlobals.Handle([]Handler{success2Handler})

				h.ServeHTTP(response, request)
				h2.ServeHTTP(response, request)

				Expect(h).ToNot(BeNil())
				Expect(h).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))

				Expect(h2).ToNot(BeNil())
				Expect(h2).To(BeAssignableToTypeOf(func(http.ResponseWriter, *http.Request) {}))

				before := os.Getenv(RYE_TEST_BEFORE_ENV_VAR)
				handler1 := os.Getenv(RYE_TEST_HANDLER_ENV_VAR)
				handler2 := os.Getenv(RYE_TEST_HANDLER_2_ENV_VAR)

				Expect(before).To(Equal("6"))
				Expect(handler1).To(Equal("1"))
				Expect(handler2).To(Equal("1"))
			})
		})

		Context("when a handler returns a response with StopExecution", func() {
			It("should not execute any further handlers", func() {
				request.Method = "OPTIONS"

				h := mwHandler.Handle([]Handler{stopExecutionHandler, successHandler})
				h.ServeHTTP(response, request)

				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).ToNot(Equal("1"))
			})
		})

		Context("when a handler returns a response with StopExecution and StatusCode", func() {
			It("should not execute any further handlers", func() {
				h := mwHandler.Handle([]Handler{stopExecutionWithStatusHandler, successHandler})
				h.ServeHTTP(response, request)

				Eventually(inc).Should(Receive(Equal(statsInc{"handlers.stopExecutionWithStatusHandler.404", 1, float32(STATRATE)})))
				Expect(os.Getenv(RYE_TEST_HANDLER_ENV_VAR)).ToNot(Equal("1"))
			})
		})

		Context("when a before handler returns a response with StopExecution", func() {
			It("should not execute any further handlers", func() {
{'fraction_non_alphanumeric': 0.12870942476720912, 'fraction_numerical': 0.009398659820729266, 'mean_word_length': 4.614069369809477, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, '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': '7406608', 'n_tokens_mistral': 4623, 'n_tokens_neox': 3921, 'n_words': 678}