github.com/orangenpresse/up@v0.6.0/http/redirects/redirects_test.go (about)

     1  package redirects
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"os"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/apex/up"
    12  	"github.com/tj/assert"
    13  
    14  	"github.com/apex/up/internal/redirect"
    15  )
    16  
    17  func TestRedirects(t *testing.T) {
    18  	t.Run("from config", func(t *testing.T) {
    19  		c := &up.Config{
    20  			Redirects: redirect.Rules{
    21  				"/blog": {
    22  					Location: "https://blog.apex.sh",
    23  					Status:   301,
    24  				},
    25  				"/enterprise": {
    26  					Location: "/docs/enterprise",
    27  					Status:   302,
    28  				},
    29  				"/api": {
    30  					Location: "/api/v1",
    31  					Status:   200,
    32  				},
    33  				"/products": {
    34  					Location: "/store",
    35  					Status:   301,
    36  				},
    37  				"/app/*": {
    38  					Location: "/",
    39  				},
    40  				"/app/login": {
    41  					Location: "https://app.apex.sh",
    42  					Status:   301,
    43  				},
    44  				"/documentation/:product/guides/:guide": {
    45  					Location: "/docs/:product/:guide",
    46  					Status:   200,
    47  				},
    48  				"/shop/:brand": {
    49  					Location: "/products/:brand",
    50  					Status:   301,
    51  				},
    52  				"/settings/*": {
    53  					Location: "/admin/:splat",
    54  					Status:   200,
    55  					Force:    true,
    56  				},
    57  			},
    58  		}
    59  
    60  		handle := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    61  			switch {
    62  			case r.URL.Path == "/":
    63  				fmt.Fprintln(w, "Index")
    64  			case r.URL.Path == "/api/v1":
    65  				fmt.Fprintln(w, "API V1")
    66  			case r.URL.Path == "/products":
    67  				fmt.Fprintln(w, "products")
    68  			case strings.Contains(r.URL.Path, "/docs"):
    69  				fmt.Fprintf(w, "docs %s", r.URL.Path)
    70  			case strings.HasPrefix(r.URL.Path, "/brand"):
    71  				fmt.Fprintf(w, "shop %s", r.URL.Path)
    72  			case strings.HasPrefix(r.URL.Path, "/setting"):
    73  				fmt.Fprintf(w, "settings %s", r.URL.Path)
    74  			case strings.HasPrefix(r.URL.Path, "/admin"):
    75  				fmt.Fprintf(w, "admin %s", r.URL.Path)
    76  			default:
    77  				http.NotFound(w, r)
    78  			}
    79  		})
    80  
    81  		h, err := New(c, handle)
    82  		assert.NoError(t, err, "init")
    83  
    84  		test(t, h)
    85  	})
    86  }
    87  
    88  func test(t *testing.T, h http.Handler) {
    89  	os.Chdir("testdata")
    90  	defer os.Chdir("..")
    91  
    92  	t.Run("mismatch", func(t *testing.T) {
    93  		res := httptest.NewRecorder()
    94  		req := httptest.NewRequest("GET", "/", nil)
    95  
    96  		h.ServeHTTP(res, req)
    97  
    98  		assert.Equal(t, 200, res.Code)
    99  		assert.Equal(t, "Index\n", res.Body.String())
   100  	})
   101  
   102  	t.Run("exact match", func(t *testing.T) {
   103  		res := httptest.NewRecorder()
   104  		req := httptest.NewRequest("GET", "/blog", nil)
   105  
   106  		h.ServeHTTP(res, req)
   107  
   108  		assert.Equal(t, 301, res.Code)
   109  		assert.Equal(t, "text/plain; charset=utf-8", res.Header().Get("Content-Type"))
   110  		assert.Equal(t, "Moved Permanently\n", res.Body.String())
   111  	})
   112  
   113  	t.Run("exact match status", func(t *testing.T) {
   114  		res := httptest.NewRecorder()
   115  		req := httptest.NewRequest("GET", "/enterprise", nil)
   116  
   117  		h.ServeHTTP(res, req)
   118  
   119  		assert.Equal(t, 302, res.Code)
   120  		assert.Equal(t, "/docs/enterprise", res.Header().Get("Location"))
   121  		assert.Equal(t, "text/plain; charset=utf-8", res.Header().Get("Content-Type"))
   122  		assert.Equal(t, "Found\n", res.Body.String())
   123  	})
   124  
   125  	t.Run("exact match rewrite", func(t *testing.T) {
   126  		res := httptest.NewRecorder()
   127  		req := httptest.NewRequest("GET", "/api", nil)
   128  
   129  		h.ServeHTTP(res, req)
   130  
   131  		assert.Equal(t, 200, res.Code)
   132  		assert.Equal(t, "/api", req.Header.Get("X-Original-Path"))
   133  		assert.Empty(t, res.Header().Get("Location"), "location")
   134  		assert.Equal(t, "API V1\n", res.Body.String())
   135  	})
   136  
   137  	t.Run("shadowed exact", func(t *testing.T) {
   138  		res := httptest.NewRecorder()
   139  		req := httptest.NewRequest("GET", "/products", nil)
   140  
   141  		h.ServeHTTP(res, req)
   142  
   143  		assert.Equal(t, 301, res.Code)
   144  		assert.Equal(t, "/store", res.Header().Get("Location"))
   145  		assert.Equal(t, "Moved Permanently\n", res.Body.String())
   146  	})
   147  
   148  	t.Run("shadowed dynamic", func(t *testing.T) {
   149  		res := httptest.NewRecorder()
   150  		req := httptest.NewRequest("GET", "/app/contact", nil)
   151  
   152  		h.ServeHTTP(res, req)
   153  
   154  		assert.Equal(t, 200, res.Code)
   155  		assert.Equal(t, "text/html; charset=utf-8", res.Header().Get("Content-Type"))
   156  		assert.Equal(t, "Index\n", res.Body.String())
   157  	})
   158  
   159  	t.Run("match precedence", func(t *testing.T) {
   160  		res := httptest.NewRecorder()
   161  		req := httptest.NewRequest("GET", "/app/login", nil)
   162  
   163  		h.ServeHTTP(res, req)
   164  
   165  		assert.Equal(t, 301, res.Code)
   166  		assert.Equal(t, "https://app.apex.sh", res.Header().Get("Location"))
   167  		assert.Equal(t, "Moved Permanently\n", res.Body.String())
   168  	})
   169  
   170  	t.Run("rewrite with placeholders", func(t *testing.T) {
   171  		res := httptest.NewRecorder()
   172  		req := httptest.NewRequest("GET", "/documentation/ping/guides/alerting", nil)
   173  
   174  		h.ServeHTTP(res, req)
   175  
   176  		assert.Equal(t, 200, res.Code)
   177  		assert.Equal(t, "docs /docs/ping/alerting", res.Body.String())
   178  	})
   179  
   180  	t.Run("redirect with placeholders", func(t *testing.T) {
   181  		res := httptest.NewRecorder()
   182  		req := httptest.NewRequest("GET", "/shop/apple", nil)
   183  
   184  		h.ServeHTTP(res, req)
   185  
   186  		assert.Equal(t, 301, res.Code)
   187  		assert.Equal(t, "Moved Permanently\n", res.Body.String())
   188  	})
   189  
   190  	t.Run("forced rewrite", func(t *testing.T) {
   191  		res := httptest.NewRecorder()
   192  		req := httptest.NewRequest("GET", "/settings/login", nil)
   193  
   194  		h.ServeHTTP(res, req)
   195  
   196  		assert.Equal(t, 200, res.Code)
   197  		assert.Equal(t, "admin /admin/login", res.Body.String())
   198  	})
   199  }