github.com/newrelic/go-agent@v3.26.0+incompatible/_integrations/nrhttprouter/nrhttprouter_test.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package nrhttprouter
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"testing"
    11  
    12  	"github.com/julienschmidt/httprouter"
    13  	newrelic "github.com/newrelic/go-agent"
    14  	"github.com/newrelic/go-agent/internal"
    15  	"github.com/newrelic/go-agent/internal/integrationsupport"
    16  )
    17  
    18  func TestMethodFunctions(t *testing.T) {
    19  
    20  	methodFuncs := []struct {
    21  		Method string
    22  		Fn     func(*Router) func(string, httprouter.Handle)
    23  	}{
    24  		{Method: "DELETE", Fn: func(r *Router) func(string, httprouter.Handle) { return r.DELETE }},
    25  		{Method: "GET", Fn: func(r *Router) func(string, httprouter.Handle) { return r.GET }},
    26  		{Method: "HEAD", Fn: func(r *Router) func(string, httprouter.Handle) { return r.HEAD }},
    27  		{Method: "OPTIONS", Fn: func(r *Router) func(string, httprouter.Handle) { return r.OPTIONS }},
    28  		{Method: "PATCH", Fn: func(r *Router) func(string, httprouter.Handle) { return r.PATCH }},
    29  		{Method: "POST", Fn: func(r *Router) func(string, httprouter.Handle) { return r.POST }},
    30  		{Method: "PUT", Fn: func(r *Router) func(string, httprouter.Handle) { return r.PUT }},
    31  	}
    32  
    33  	for _, md := range methodFuncs {
    34  		app := integrationsupport.NewBasicTestApp()
    35  		router := New(app)
    36  		md.Fn(router)("/hello/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    37  			// Test that the Transaction is used as the response writer.
    38  			w.WriteHeader(500)
    39  			w.Write([]byte(fmt.Sprintf("hi %s", ps.ByName("name"))))
    40  		})
    41  		response := httptest.NewRecorder()
    42  		req, err := http.NewRequest(md.Method, "/hello/person", nil)
    43  		if err != nil {
    44  			t.Fatal(err)
    45  		}
    46  		router.ServeHTTP(response, req)
    47  		if respBody := response.Body.String(); respBody != "hi person" {
    48  			t.Error("wrong response body", respBody)
    49  		}
    50  		app.ExpectTxnMetrics(t, internal.WantTxn{
    51  			Name:      md.Method + " /hello/:name",
    52  			IsWeb:     true,
    53  			NumErrors: 1,
    54  		})
    55  	}
    56  }
    57  
    58  func TestGetNoApplication(t *testing.T) {
    59  	router := New(nil)
    60  
    61  	router.GET("/hello/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    62  		w.Write([]byte(fmt.Sprintf("hi %s", ps.ByName("name"))))
    63  	})
    64  	response := httptest.NewRecorder()
    65  	req, err := http.NewRequest("GET", "/hello/person", nil)
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  	router.ServeHTTP(response, req)
    70  	if respBody := response.Body.String(); respBody != "hi person" {
    71  		t.Error("wrong response body", respBody)
    72  	}
    73  }
    74  
    75  func TestHandle(t *testing.T) {
    76  	app := integrationsupport.NewBasicTestApp()
    77  	router := New(app)
    78  
    79  	router.Handle("GET", "/hello/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    80  		// Test that the Transaction is used as the response writer.
    81  		w.WriteHeader(500)
    82  		w.Write([]byte(fmt.Sprintf("hi %s", ps.ByName("name"))))
    83  		if txn := newrelic.FromContext(r.Context()); txn != nil {
    84  			txn.AddAttribute("color", "purple")
    85  		}
    86  	})
    87  	response := httptest.NewRecorder()
    88  	req, err := http.NewRequest("GET", "/hello/person", nil)
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  	router.ServeHTTP(response, req)
    93  	if respBody := response.Body.String(); respBody != "hi person" {
    94  		t.Error("wrong response body", respBody)
    95  	}
    96  	app.ExpectTxnMetrics(t, internal.WantTxn{
    97  		Name:      "GET /hello/:name",
    98  		IsWeb:     true,
    99  		NumErrors: 1,
   100  	})
   101  	app.(internal.Expect).ExpectTxnEvents(t, []internal.WantEvent{
   102  		{
   103  			Intrinsics: map[string]interface{}{
   104  				"name":             "WebTransaction/Go/GET /hello/:name",
   105  				"nr.apdexPerfZone": internal.MatchAnything,
   106  			},
   107  			UserAttributes: map[string]interface{}{
   108  				"color": "purple",
   109  			},
   110  			AgentAttributes: map[string]interface{}{
   111  				"httpResponseCode": 500,
   112  				"request.method":   "GET",
   113  				"request.uri":      "/hello/person",
   114  			},
   115  		},
   116  	})
   117  }
   118  
   119  func TestHandler(t *testing.T) {
   120  	app := integrationsupport.NewBasicTestApp()
   121  	router := New(app)
   122  
   123  	router.Handler("GET", "/hello/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   124  		// Test that the Transaction is used as the response writer.
   125  		w.WriteHeader(500)
   126  		w.Write([]byte("hi there"))
   127  		if txn := newrelic.FromContext(r.Context()); txn != nil {
   128  			txn.AddAttribute("color", "purple")
   129  		}
   130  	}))
   131  	response := httptest.NewRecorder()
   132  	req, err := http.NewRequest("GET", "/hello/", nil)
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	router.ServeHTTP(response, req)
   137  	if respBody := response.Body.String(); respBody != "hi there" {
   138  		t.Error("wrong response body", respBody)
   139  	}
   140  	app.ExpectTxnMetrics(t, internal.WantTxn{
   141  		Name:      "GET /hello/",
   142  		IsWeb:     true,
   143  		NumErrors: 1,
   144  	})
   145  	app.(internal.Expect).ExpectTxnEvents(t, []internal.WantEvent{
   146  		{
   147  			Intrinsics: map[string]interface{}{
   148  				"name":             "WebTransaction/Go/GET /hello/",
   149  				"nr.apdexPerfZone": internal.MatchAnything,
   150  			},
   151  			UserAttributes: map[string]interface{}{
   152  				"color": "purple",
   153  			},
   154  			AgentAttributes: map[string]interface{}{
   155  				"httpResponseCode": 500,
   156  				"request.method":   "GET",
   157  				"request.uri":      "/hello/",
   158  			},
   159  		},
   160  	})
   161  }
   162  
   163  func TestHandlerMissingApplication(t *testing.T) {
   164  	router := New(nil)
   165  
   166  	router.Handler("GET", "/hello/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   167  		w.WriteHeader(500)
   168  		w.Write([]byte("hi there"))
   169  	}))
   170  	response := httptest.NewRecorder()
   171  	req, err := http.NewRequest("GET", "/hello/", nil)
   172  	if err != nil {
   173  		t.Fatal(err)
   174  	}
   175  	router.ServeHTTP(response, req)
   176  	if respBody := response.Body.String(); respBody != "hi there" {
   177  		t.Error("wrong response body", respBody)
   178  	}
   179  }
   180  
   181  func TestHandlerFunc(t *testing.T) {
   182  	app := integrationsupport.NewBasicTestApp()
   183  	router := New(app)
   184  
   185  	router.HandlerFunc("GET", "/hello/", func(w http.ResponseWriter, r *http.Request) {
   186  		// Test that the Transaction is used as the response writer.
   187  		w.WriteHeader(500)
   188  		w.Write([]byte("hi there"))
   189  	})
   190  	response := httptest.NewRecorder()
   191  	req, err := http.NewRequest("GET", "/hello/", nil)
   192  	if err != nil {
   193  		t.Fatal(err)
   194  	}
   195  	router.ServeHTTP(response, req)
   196  	if respBody := response.Body.String(); respBody != "hi there" {
   197  		t.Error("wrong response body", respBody)
   198  	}
   199  	app.ExpectTxnMetrics(t, internal.WantTxn{
   200  		Name:      "GET /hello/",
   201  		IsWeb:     true,
   202  		NumErrors: 1,
   203  	})
   204  }
   205  
   206  func TestNotFound(t *testing.T) {
   207  	app := integrationsupport.NewBasicTestApp()
   208  	router := New(app)
   209  
   210  	router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   211  		// Test that the Transaction is used as the response writer.
   212  		w.WriteHeader(500)
   213  		w.Write([]byte("not found!"))
   214  		if txn := newrelic.FromContext(r.Context()); txn != nil {
   215  			txn.AddAttribute("color", "purple")
   216  		}
   217  	})
   218  	response := httptest.NewRecorder()
   219  	req, err := http.NewRequest("GET", "/hello/", nil)
   220  	if err != nil {
   221  		t.Fatal(err)
   222  	}
   223  	router.ServeHTTP(response, req)
   224  	if respBody := response.Body.String(); respBody != "not found!" {
   225  		t.Error("wrong response body", respBody)
   226  	}
   227  	app.ExpectTxnMetrics(t, internal.WantTxn{
   228  		Name:      "NotFound",
   229  		IsWeb:     true,
   230  		NumErrors: 1,
   231  	})
   232  	app.(internal.Expect).ExpectTxnEvents(t, []internal.WantEvent{
   233  		{
   234  			Intrinsics: map[string]interface{}{
   235  				"name":             "WebTransaction/Go/NotFound",
   236  				"nr.apdexPerfZone": internal.MatchAnything,
   237  			},
   238  			UserAttributes: map[string]interface{}{
   239  				"color": "purple",
   240  			},
   241  			AgentAttributes: map[string]interface{}{
   242  				"httpResponseCode": 500,
   243  				"request.method":   "GET",
   244  				"request.uri":      "/hello/",
   245  			},
   246  		},
   247  	})
   248  }
   249  
   250  func TestNotFoundMissingApplication(t *testing.T) {
   251  	router := New(nil)
   252  
   253  	router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   254  		// Test that the Transaction is used as the response writer.
   255  		w.WriteHeader(500)
   256  		w.Write([]byte("not found!"))
   257  	})
   258  	response := httptest.NewRecorder()
   259  	req, err := http.NewRequest("GET", "/hello/", nil)
   260  	if err != nil {
   261  		t.Fatal(err)
   262  	}
   263  	router.ServeHTTP(response, req)
   264  	if respBody := response.Body.String(); respBody != "not found!" {
   265  		t.Error("wrong response body", respBody)
   266  	}
   267  }
   268  
   269  func TestNotFoundNotSet(t *testing.T) {
   270  	app := integrationsupport.NewBasicTestApp()
   271  	router := New(app)
   272  
   273  	response := httptest.NewRecorder()
   274  	req, err := http.NewRequest("GET", "/hello/", nil)
   275  	if err != nil {
   276  		t.Fatal(err)
   277  	}
   278  	router.ServeHTTP(response, req)
   279  	if response.Code != 404 {
   280  		t.Error(response.Code)
   281  	}
   282  	app.ExpectTxnMetrics(t, internal.WantTxn{
   283  		Name:  "NotFound",
   284  		IsWeb: true,
   285  	})
   286  }