github.com/gofiber/fiber/v2@v2.47.0/middleware/redirect/redirect_test.go (about)

     1  //nolint:bodyclose // Much easier to just ignore memory leaks in tests
     2  package redirect
     3  
     4  import (
     5  	"context"
     6  	"net/http"
     7  	"testing"
     8  
     9  	"github.com/gofiber/fiber/v2"
    10  	"github.com/gofiber/fiber/v2/utils"
    11  )
    12  
    13  func Test_Redirect(t *testing.T) {
    14  	app := *fiber.New()
    15  
    16  	app.Use(New(Config{
    17  		Rules: map[string]string{
    18  			"/default": "google.com",
    19  		},
    20  		StatusCode: fiber.StatusMovedPermanently,
    21  	}))
    22  	app.Use(New(Config{
    23  		Rules: map[string]string{
    24  			"/default/*": "fiber.wiki",
    25  		},
    26  		StatusCode: fiber.StatusTemporaryRedirect,
    27  	}))
    28  	app.Use(New(Config{
    29  		Rules: map[string]string{
    30  			"/redirect/*": "$1",
    31  		},
    32  		StatusCode: fiber.StatusSeeOther,
    33  	}))
    34  	app.Use(New(Config{
    35  		Rules: map[string]string{
    36  			"/pattern/*": "golang.org",
    37  		},
    38  		StatusCode: fiber.StatusFound,
    39  	}))
    40  
    41  	app.Use(New(Config{
    42  		Rules: map[string]string{
    43  			"/": "/swagger",
    44  		},
    45  		StatusCode: fiber.StatusMovedPermanently,
    46  	}))
    47  
    48  	app.Get("/api/*", func(c *fiber.Ctx) error {
    49  		return c.SendString("API")
    50  	})
    51  
    52  	app.Get("/new", func(c *fiber.Ctx) error {
    53  		return c.SendString("Hello, World!")
    54  	})
    55  
    56  	tests := []struct {
    57  		name       string
    58  		url        string
    59  		redirectTo string
    60  		statusCode int
    61  	}{
    62  		{
    63  			name:       "should be returns status StatusFound without a wildcard",
    64  			url:        "/default",
    65  			redirectTo: "google.com",
    66  			statusCode: fiber.StatusMovedPermanently,
    67  		},
    68  		{
    69  			name:       "should be returns status StatusTemporaryRedirect  using wildcard",
    70  			url:        "/default/xyz",
    71  			redirectTo: "fiber.wiki",
    72  			statusCode: fiber.StatusTemporaryRedirect,
    73  		},
    74  		{
    75  			name:       "should be returns status StatusSeeOther without set redirectTo to use the default",
    76  			url:        "/redirect/github.com/gofiber/redirect",
    77  			redirectTo: "github.com/gofiber/redirect",
    78  			statusCode: fiber.StatusSeeOther,
    79  		},
    80  		{
    81  			name:       "should return the status code default",
    82  			url:        "/pattern/xyz",
    83  			redirectTo: "golang.org",
    84  			statusCode: fiber.StatusFound,
    85  		},
    86  		{
    87  			name:       "access URL without rule",
    88  			url:        "/new",
    89  			statusCode: fiber.StatusOK,
    90  		},
    91  		{
    92  			name:       "redirect to swagger route",
    93  			url:        "/",
    94  			redirectTo: "/swagger",
    95  			statusCode: fiber.StatusMovedPermanently,
    96  		},
    97  		{
    98  			name:       "no redirect to swagger route",
    99  			url:        "/api/",
   100  			statusCode: fiber.StatusOK,
   101  		},
   102  		{
   103  			name:       "no redirect to swagger route #2",
   104  			url:        "/api/test",
   105  			statusCode: fiber.StatusOK,
   106  		},
   107  	}
   108  	for _, tt := range tests {
   109  		t.Run(tt.name, func(t *testing.T) {
   110  			req, err := http.NewRequestWithContext(context.Background(), fiber.MethodGet, tt.url, nil)
   111  			utils.AssertEqual(t, err, nil)
   112  			req.Header.Set("Location", "github.com/gofiber/redirect")
   113  			resp, err := app.Test(req)
   114  
   115  			utils.AssertEqual(t, err, nil)
   116  			utils.AssertEqual(t, tt.statusCode, resp.StatusCode)
   117  			utils.AssertEqual(t, tt.redirectTo, resp.Header.Get("Location"))
   118  		})
   119  	}
   120  }
   121  
   122  func Test_Next(t *testing.T) {
   123  	// Case 1 : Next function always returns true
   124  	app := *fiber.New()
   125  	app.Use(New(Config{
   126  		Next: func(*fiber.Ctx) bool {
   127  			return true
   128  		},
   129  		Rules: map[string]string{
   130  			"/default": "google.com",
   131  		},
   132  		StatusCode: fiber.StatusMovedPermanently,
   133  	}))
   134  
   135  	app.Use(func(c *fiber.Ctx) error {
   136  		return c.SendStatus(fiber.StatusOK)
   137  	})
   138  
   139  	req, err := http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   140  	utils.AssertEqual(t, err, nil)
   141  	resp, err := app.Test(req)
   142  	utils.AssertEqual(t, err, nil)
   143  
   144  	utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
   145  
   146  	// Case 2 : Next function always returns false
   147  	app = *fiber.New()
   148  	app.Use(New(Config{
   149  		Next: func(*fiber.Ctx) bool {
   150  			return false
   151  		},
   152  		Rules: map[string]string{
   153  			"/default": "google.com",
   154  		},
   155  		StatusCode: fiber.StatusMovedPermanently,
   156  	}))
   157  
   158  	req, err = http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   159  	utils.AssertEqual(t, err, nil)
   160  	resp, err = app.Test(req)
   161  	utils.AssertEqual(t, err, nil)
   162  
   163  	utils.AssertEqual(t, fiber.StatusMovedPermanently, resp.StatusCode)
   164  	utils.AssertEqual(t, "google.com", resp.Header.Get("Location"))
   165  }
   166  
   167  func Test_NoRules(t *testing.T) {
   168  	// Case 1: No rules with default route defined
   169  	app := *fiber.New()
   170  
   171  	app.Use(New(Config{
   172  		StatusCode: fiber.StatusMovedPermanently,
   173  	}))
   174  
   175  	app.Use(func(c *fiber.Ctx) error {
   176  		return c.SendStatus(fiber.StatusOK)
   177  	})
   178  
   179  	req, err := http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   180  	utils.AssertEqual(t, err, nil)
   181  	resp, err := app.Test(req)
   182  	utils.AssertEqual(t, err, nil)
   183  	utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
   184  
   185  	// Case 2: No rules and no default route defined
   186  	app = *fiber.New()
   187  
   188  	app.Use(New(Config{
   189  		StatusCode: fiber.StatusMovedPermanently,
   190  	}))
   191  
   192  	req, err = http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   193  	utils.AssertEqual(t, err, nil)
   194  	resp, err = app.Test(req)
   195  	utils.AssertEqual(t, err, nil)
   196  	utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
   197  }
   198  
   199  func Test_DefaultConfig(t *testing.T) {
   200  	// Case 1: Default config and no default route
   201  	app := *fiber.New()
   202  
   203  	app.Use(New())
   204  
   205  	req, err := http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   206  	utils.AssertEqual(t, err, nil)
   207  	resp, err := app.Test(req)
   208  
   209  	utils.AssertEqual(t, err, nil)
   210  	utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
   211  
   212  	// Case 2: Default config and default route
   213  	app = *fiber.New()
   214  
   215  	app.Use(New())
   216  	app.Use(func(c *fiber.Ctx) error {
   217  		return c.SendStatus(fiber.StatusOK)
   218  	})
   219  
   220  	req, err = http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   221  	utils.AssertEqual(t, err, nil)
   222  	resp, err = app.Test(req)
   223  
   224  	utils.AssertEqual(t, err, nil)
   225  	utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
   226  }
   227  
   228  func Test_RegexRules(t *testing.T) {
   229  	// Case 1: Rules regex is empty
   230  	app := *fiber.New()
   231  	app.Use(New(Config{
   232  		Rules:      map[string]string{},
   233  		StatusCode: fiber.StatusMovedPermanently,
   234  	}))
   235  
   236  	app.Use(func(c *fiber.Ctx) error {
   237  		return c.SendStatus(fiber.StatusOK)
   238  	})
   239  
   240  	req, err := http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   241  	utils.AssertEqual(t, err, nil)
   242  	resp, err := app.Test(req)
   243  
   244  	utils.AssertEqual(t, err, nil)
   245  	utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
   246  
   247  	// Case 2: Rules regex map contains valid regex and well-formed replacement URLs
   248  	app = *fiber.New()
   249  	app.Use(New(Config{
   250  		Rules: map[string]string{
   251  			"/default": "google.com",
   252  		},
   253  		StatusCode: fiber.StatusMovedPermanently,
   254  	}))
   255  
   256  	app.Use(func(c *fiber.Ctx) error {
   257  		return c.SendStatus(fiber.StatusOK)
   258  	})
   259  
   260  	req, err = http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/default", nil)
   261  	utils.AssertEqual(t, err, nil)
   262  	resp, err = app.Test(req)
   263  
   264  	utils.AssertEqual(t, err, nil)
   265  	utils.AssertEqual(t, fiber.StatusMovedPermanently, resp.StatusCode)
   266  	utils.AssertEqual(t, "google.com", resp.Header.Get("Location"))
   267  
   268  	// Case 3: Test invalid regex throws panic
   269  	defer func() {
   270  		if r := recover(); r != nil {
   271  			t.Log("Recovered from invalid regex: ", r)
   272  		}
   273  	}()
   274  
   275  	app = *fiber.New()
   276  	app.Use(New(Config{
   277  		Rules: map[string]string{
   278  			"(": "google.com",
   279  		},
   280  		StatusCode: fiber.StatusMovedPermanently,
   281  	}))
   282  	t.Error("Expected panic, got nil")
   283  }