github.com/abolfazlbeh/zhycan@v0.0.0-20230819144214-24cf38237387/internal/http/fiber_wrapper_test.go (about)

     1  package http
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"github.com/gofiber/fiber/v2"
     7  	"github.com/gofiber/fiber/v2/utils"
     8  	"io"
     9  	"net/http/httptest"
    10  	"reflect"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func TestFiberWrapper_startServer(t *testing.T) {
    16  	// create a new fiber wrapper and start it
    17  
    18  	serverConfig := ServerConfig{ListenAddress: ":3000"}
    19  	server, err := NewServer("http", serverConfig)
    20  	if err != nil {
    21  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
    22  		return
    23  	}
    24  
    25  	err = server.Start()
    26  	if err != nil {
    27  		t.Errorf("Starting HTTP Server --> Expected: %v, but got %v", nil, err)
    28  		return
    29  	}
    30  }
    31  
    32  func TestFiberWrapper_AddRoute(t *testing.T) {
    33  	serverConfig := ServerConfig{ListenAddress: ":3000"}
    34  	server, err := NewServer("http", serverConfig)
    35  	if err != nil {
    36  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
    37  		return
    38  	}
    39  
    40  	server.AddRoute(fiber.MethodGet, "/", func(c *fiber.Ctx) error {
    41  		return nil
    42  	}, "TestGet", []string{}, []string{})
    43  
    44  	routes := server.app.GetRoutes()
    45  	if len(routes) == 0 {
    46  		t.Errorf("Expected 1 routes added to server, but got %v", len(routes))
    47  		return
    48  	}
    49  
    50  	// check the name of the route
    51  	r := server.app.GetRoute("TestGet")
    52  	if r.Method != fiber.MethodGet {
    53  		t.Errorf("Expected to get method %v, but got %v", fiber.MethodGet, r.Method)
    54  		return
    55  	}
    56  	if r.Path != "/" {
    57  		t.Errorf("Expected to get route '%v', but got '%v'", "/", r.Path)
    58  		return
    59  	}
    60  }
    61  
    62  func TestFiberWrapper_AddMultipleRoute(t *testing.T) {
    63  	serverConfig := ServerConfig{ListenAddress: ":3000"}
    64  	server, err := NewServer("http", serverConfig)
    65  	if err != nil {
    66  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
    67  		return
    68  	}
    69  
    70  	for i := range []int{1, 2, 3} {
    71  		server.AddRoute(fiber.MethodGet, fmt.Sprintf("/%v", i), func(c *fiber.Ctx) error {
    72  			return nil
    73  		}, fmt.Sprintf("Test%v", i), []string{}, []string{})
    74  	}
    75  
    76  	routes := server.app.GetRoutes()
    77  	if len(routes) == 0 {
    78  		t.Errorf("Expected 1 routes added to server, but got %v", len(routes))
    79  		return
    80  	} else if len(routes) != 3 {
    81  		t.Errorf("Expected 1 routes added to server, but got %v", len(routes))
    82  		return
    83  	}
    84  
    85  	// check the name of the route
    86  	r := server.app.GetRoute("Test2")
    87  	if r.Method != fiber.MethodGet {
    88  		t.Errorf("Expected to get method %v, but got %v", fiber.MethodGet, r.Method)
    89  		return
    90  	}
    91  	if r.Path != "/2" {
    92  		t.Errorf("Expected to get route '%v', but got '%v'", "/2", r.Path)
    93  		return
    94  	}
    95  }
    96  
    97  func TestFiberWrapper_AddBlockRouteMethod(t *testing.T) {
    98  	serverConfig := ServerConfig{ListenAddress: ":3000"}
    99  	server, err := NewServer("http", serverConfig)
   100  	if err != nil {
   101  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   102  		return
   103  	}
   104  
   105  	server.AddRoute("TTT", "/", func(c *fiber.Ctx) error {
   106  		return nil
   107  	}, "TestGet", []string{}, []string{})
   108  
   109  	routes := server.app.GetRoutes()
   110  	if len(routes) > 0 {
   111  		t.Errorf("Expected the route not to be added, but added")
   112  		return
   113  	}
   114  }
   115  
   116  func TestFiberWrapper_GetRouteByName(t *testing.T) {
   117  	serverConfig := ServerConfig{ListenAddress: ":3000"}
   118  	server, err := NewServer("http", serverConfig)
   119  	if err != nil {
   120  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   121  		return
   122  	}
   123  
   124  	routeName := "TestGet"
   125  	server.AddRoute(fiber.MethodGet, "/", func(c *fiber.Ctx) error {
   126  		return nil
   127  	}, routeName, []string{}, []string{})
   128  
   129  	routes := server.app.GetRoutes()
   130  	if len(routes) == 0 {
   131  		t.Errorf("Expected that %v route(s) exist, but got %v", 1, len(routes))
   132  		return
   133  	}
   134  
   135  	route, err := server.GetRouteByName(routeName)
   136  	routes = server.app.GetRoutes()
   137  	if err != nil {
   138  		t.Errorf("Get route by name --> Expected no err:  but got %v", err)
   139  		return
   140  	}
   141  
   142  	if route.Name != routeName {
   143  		t.Errorf("Expected to get route by name: %v, but got %v", routeName, route)
   144  	}
   145  }
   146  
   147  func TestFiberWrapper_AddRouteToOneSupportedVersion(t *testing.T) {
   148  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1"}}
   149  	server, err := NewServer("http", serverConfig)
   150  	if err != nil {
   151  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   152  		return
   153  	}
   154  
   155  	routeName := "TestGet"
   156  	server.AddRoute(fiber.MethodGet, "/", func(c *fiber.Ctx) error {
   157  		return nil
   158  	}, routeName, []string{"v1"}, []string{})
   159  
   160  	routes := server.app.GetRoutes()
   161  	if len(routes) == 0 {
   162  		t.Errorf("Expected that %v route(s) exist, but got %v", 1, len(routes))
   163  		return
   164  	}
   165  
   166  	expectedPath := "/v1"
   167  	if routes[0].Path != expectedPath {
   168  		t.Errorf("Expected that get route '%v', but got %v", expectedPath, routes[0].Path)
   169  		return
   170  	}
   171  }
   172  
   173  func TestFiberWrapper_AddRouteToTwoSupportedVersions(t *testing.T) {
   174  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1", "v2"}}
   175  	server, err := NewServer("http", serverConfig)
   176  	if err != nil {
   177  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   178  		return
   179  	}
   180  
   181  	routeName := "TestGet"
   182  	server.AddRoute(fiber.MethodGet, "/", func(c *fiber.Ctx) error {
   183  		return nil
   184  	}, routeName, []string{"v1", "v2"}, []string{})
   185  
   186  	routes := server.app.GetRoutes()
   187  	if len(routes) != 2 {
   188  		t.Errorf("Expected that %v route(s) exist, but got %v", 2, len(routes))
   189  		return
   190  	}
   191  
   192  	expectedPath := []string{"/v1/", "/v2/"}
   193  	var actualPath []string
   194  	for _, r := range routes {
   195  		actualPath = append(actualPath, r.Path)
   196  	}
   197  	if !reflect.DeepEqual(actualPath, expectedPath) {
   198  		t.Errorf("Expected that get route '%v', but got %v", expectedPath, actualPath)
   199  		return
   200  	}
   201  }
   202  
   203  func TestFiberWrapper_AddRouteToAllVersions(t *testing.T) {
   204  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1", "v2"}}
   205  	server, err := NewServer("http", serverConfig)
   206  	if err != nil {
   207  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   208  		return
   209  	}
   210  
   211  	routeName := "TestGet"
   212  	server.AddRoute(fiber.MethodGet, "/", func(c *fiber.Ctx) error {
   213  		return nil
   214  	}, routeName, []string{"all"}, []string{})
   215  
   216  	routes := server.app.GetRoutes()
   217  	if len(routes) != 2 {
   218  		t.Errorf("Expected that %v route(s) exist, but got %v", 2, len(routes))
   219  		return
   220  	}
   221  
   222  	expectedPath := []string{"/v1/", "/v2/"}
   223  	var actualPath []string
   224  	for _, r := range routes {
   225  		actualPath = append(actualPath, r.Path)
   226  	}
   227  	if !reflect.DeepEqual(actualPath, expectedPath) {
   228  		t.Errorf("Expected that get route '%v', but got %v", expectedPath, actualPath)
   229  		return
   230  	}
   231  }
   232  
   233  func TestFiberWrapper_AddRouteToNoVersions(t *testing.T) {
   234  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1", "v2"}}
   235  	server, err := NewServer("http", serverConfig)
   236  	if err != nil {
   237  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   238  		return
   239  	}
   240  
   241  	routeName := "TestGet"
   242  	server.AddRoute(fiber.MethodGet, "/", func(c *fiber.Ctx) error {
   243  		return nil
   244  	}, routeName, []string{""}, []string{})
   245  
   246  	routes := server.app.GetRoutes()
   247  	if len(routes) != 1 {
   248  		t.Errorf("Expected that %v route(s) exist, but got %v", 1, len(routes))
   249  		return
   250  	}
   251  
   252  	expectedPath := []string{"/"}
   253  	var actualPath []string
   254  	for _, r := range routes {
   255  		actualPath = append(actualPath, r.Path)
   256  	}
   257  	if !reflect.DeepEqual(actualPath, expectedPath) {
   258  		t.Errorf("Expected that get route '%v', but got %v", expectedPath, actualPath)
   259  		return
   260  	}
   261  }
   262  
   263  func TestFiberWrapper_AddGroup(t *testing.T) {
   264  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1", "v2"}}
   265  	server, err := NewServer("http", serverConfig)
   266  	if err != nil {
   267  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   268  		return
   269  	}
   270  
   271  	groupName := "p"
   272  	server.AddGroup(groupName, func(c *fiber.Ctx) error {
   273  		return nil
   274  	})
   275  
   276  	expectedGroups := []string{"v1.p", "v2.p", "p"}
   277  	var actualGroups []string
   278  	for key, _ := range server.groups {
   279  		actualGroups = append(actualGroups, key)
   280  	}
   281  
   282  	if !reflect.DeepEqual(expectedGroups, actualGroups) {
   283  		t.Errorf("Expected that get group list '%v', but got %v", expectedGroups, actualGroups)
   284  		return
   285  	}
   286  }
   287  
   288  func TestFiberWrapper_AddGroupToGroup(t *testing.T) {
   289  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1", "v2"}}
   290  	server, err := NewServer("http", serverConfig)
   291  	if err != nil {
   292  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   293  		return
   294  	}
   295  
   296  	groupName := "p2"
   297  	server.AddGroup(groupName, func(c *fiber.Ctx) error {
   298  		return nil
   299  	})
   300  
   301  	groupName = "p"
   302  	server.AddGroup(groupName, func(c *fiber.Ctx) error {
   303  		return nil
   304  	}, "p2")
   305  
   306  	expectedGroups := []string{"p2.p", "v1.p2", "v2.p2", "p2", "v1.p2.p", "v2.p2.p"}
   307  	var actualGroups []string
   308  	for key, _ := range server.groups {
   309  		actualGroups = append(actualGroups, key)
   310  	}
   311  
   312  	if !reflect.DeepEqual(expectedGroups, actualGroups) {
   313  		t.Errorf("Expected that get group list '%v', but got %v", expectedGroups, actualGroups)
   314  		return
   315  	}
   316  }
   317  
   318  func TestFiberWrapper_AddRouteToSpecificGroup(t *testing.T) {
   319  	serverConfig := ServerConfig{ListenAddress: ":3000", Versions: []string{"v1", "v2"}}
   320  	server, err := NewServer("http", serverConfig)
   321  	if err != nil {
   322  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   323  		return
   324  	}
   325  
   326  	groupName := "p2"
   327  	server.AddGroup(groupName, nil)
   328  
   329  	routeName := "TestGet"
   330  	server.AddRoute(fiber.MethodGet, "/ttt", func(c *fiber.Ctx) error {
   331  		return nil
   332  	}, routeName, []string{"v1"}, []string{groupName})
   333  
   334  	routes := server.app.GetRoutes()
   335  	if len(routes) != 1 {
   336  		t.Errorf("Expected that %v route(s) exist, but got %v", 1, len(routes))
   337  		return
   338  	}
   339  	expectedRoute := "/v1/p2/ttt"
   340  	actualRoute := routes[0].Path
   341  	if !reflect.DeepEqual(actualRoute, expectedRoute) {
   342  		t.Errorf("Expected that the first route be %v, but got %v", expectedRoute, actualRoute)
   343  		return
   344  	}
   345  }
   346  
   347  func TestFiberWrapper_RequestMethodsNotAllowed(t *testing.T) {
   348  	serverConfig := ServerConfig{
   349  		ListenAddress: ":3000",
   350  		Config: struct {
   351  			ServerHeader         string   `json:"server_header"`
   352  			StrictRouting        bool     `json:"strict_routing"`
   353  			CaseSensitive        bool     `json:"case_sensitive"`
   354  			UnescapePath         bool     `json:"unescape_path"`
   355  			Etag                 bool     `json:"etag"`
   356  			BodyLimit            int      `json:"body_limit"`
   357  			Concurrency          int      `json:"concurrency"`
   358  			ReadTimeout          int      `json:"read_timeout"`
   359  			WriteTimeout         int      `json:"write_timeout"`
   360  			IdleTimeout          int      `json:"idle_timeout"`
   361  			ReadBufferSize       int      `json:"read_buffer_size"`
   362  			WriteBufferSize      int      `json:"write_buffer_size"`
   363  			CompressedFileSuffix string   `json:"compressed_file_suffix"`
   364  			GetOnly              bool     `json:"get_only"`
   365  			DisableKeepalive     bool     `json:"disable_keepalive"`
   366  			Network              string   `json:"network"`
   367  			EnablePrintRoutes    bool     `json:"enable_print_routes"`
   368  			AttachErrorHandler   bool     `json:"attach_error_handler"`
   369  			RequestMethods       []string `json:"request_methods"`
   370  		}{
   371  			ServerHeader:         "",
   372  			StrictRouting:        false,
   373  			CaseSensitive:        false,
   374  			UnescapePath:         false,
   375  			Etag:                 false,
   376  			BodyLimit:            4194304,
   377  			Concurrency:          262144,
   378  			ReadTimeout:          -1,
   379  			WriteTimeout:         -1,
   380  			IdleTimeout:          -1,
   381  			ReadBufferSize:       4096,
   382  			WriteBufferSize:      4096,
   383  			CompressedFileSuffix: ".gz",
   384  			GetOnly:              false,
   385  			DisableKeepalive:     false,
   386  			Network:              "tcp",
   387  			EnablePrintRoutes:    true,
   388  			AttachErrorHandler:   true,
   389  			RequestMethods:       []string{"GET"},
   390  		},
   391  	}
   392  	server, err := NewServer("http", serverConfig)
   393  	if err != nil {
   394  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   395  		return
   396  	}
   397  
   398  	err = server.AddRoute(fiber.MethodPost, "/p", func(c *fiber.Ctx) error {
   399  		return nil
   400  	}, "TestPOST", []string{}, []string{})
   401  	if err == nil {
   402  		t.Errorf("Expected to not add POST method, but it's added")
   403  	}
   404  }
   405  
   406  func TestFiberWrapper_RequestMethodsFilter(t *testing.T) {
   407  	serverConfig := ServerConfig{
   408  		ListenAddress: ":3000",
   409  		Config: struct {
   410  			ServerHeader         string   `json:"server_header"`
   411  			StrictRouting        bool     `json:"strict_routing"`
   412  			CaseSensitive        bool     `json:"case_sensitive"`
   413  			UnescapePath         bool     `json:"unescape_path"`
   414  			Etag                 bool     `json:"etag"`
   415  			BodyLimit            int      `json:"body_limit"`
   416  			Concurrency          int      `json:"concurrency"`
   417  			ReadTimeout          int      `json:"read_timeout"`
   418  			WriteTimeout         int      `json:"write_timeout"`
   419  			IdleTimeout          int      `json:"idle_timeout"`
   420  			ReadBufferSize       int      `json:"read_buffer_size"`
   421  			WriteBufferSize      int      `json:"write_buffer_size"`
   422  			CompressedFileSuffix string   `json:"compressed_file_suffix"`
   423  			GetOnly              bool     `json:"get_only"`
   424  			DisableKeepalive     bool     `json:"disable_keepalive"`
   425  			Network              string   `json:"network"`
   426  			EnablePrintRoutes    bool     `json:"enable_print_routes"`
   427  			AttachErrorHandler   bool     `json:"attach_error_handler"`
   428  			RequestMethods       []string `json:"request_methods"`
   429  		}{
   430  			ServerHeader:         "",
   431  			StrictRouting:        false,
   432  			CaseSensitive:        false,
   433  			UnescapePath:         false,
   434  			Etag:                 false,
   435  			BodyLimit:            4194304,
   436  			Concurrency:          262144,
   437  			ReadTimeout:          -1,
   438  			WriteTimeout:         -1,
   439  			IdleTimeout:          -1,
   440  			ReadBufferSize:       4096,
   441  			WriteBufferSize:      4096,
   442  			CompressedFileSuffix: ".gz",
   443  			GetOnly:              false,
   444  			DisableKeepalive:     false,
   445  			Network:              "tcp",
   446  			EnablePrintRoutes:    true,
   447  			AttachErrorHandler:   true,
   448  			RequestMethods:       []string{"GET"},
   449  		},
   450  	}
   451  	server, err := NewServer("http", serverConfig)
   452  	if err != nil {
   453  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   454  		return
   455  	}
   456  
   457  	server.AddRoute(fiber.MethodPost, "/p", func(c *fiber.Ctx) error {
   458  		return nil
   459  	}, "TestPOST", []string{}, []string{})
   460  
   461  	server.AddRoute(fiber.MethodGet, "/g", func(c *fiber.Ctx) error {
   462  		return nil
   463  	}, "TestGET", []string{}, []string{})
   464  
   465  	routes := server.app.GetRoutes()
   466  	if len(routes) != 1 {
   467  		t.Errorf("Expected 1 route added to server, but got %v", len(routes))
   468  		return
   469  	}
   470  
   471  	// check the name of the route
   472  	r := server.app.GetRoute("TestPOST")
   473  	if r.Path == "/p" {
   474  		t.Errorf("Expected to get route '%v', but got '%v'", "/", r.Path)
   475  		return
   476  	}
   477  }
   478  
   479  func TestFiberWrapper_StaticHandling(t *testing.T) {
   480  	serverConfig := ServerConfig{
   481  		ListenAddress: ":3000",
   482  		SupportStatic: true,
   483  		Static: struct {
   484  			Prefix string       `json:"prefix"`
   485  			Root   string       `json:"root"`
   486  			Config fiber.Static `json:"config"`
   487  		}{
   488  			Prefix: "/public",
   489  			Root:   "../../data/static/",
   490  			Config: fiber.Static{Compress: false, ByteRange: false, Browse: false, Download: false, Index: "index.html", CacheDuration: 10 * time.Second, MaxAge: 0, ModifyResponse: nil, Next: nil},
   491  		},
   492  	}
   493  
   494  	server, err := NewServer("http", serverConfig)
   495  	if err != nil {
   496  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   497  		return
   498  	}
   499  	go server.Start()
   500  	defer server.Stop()
   501  
   502  	req := httptest.NewRequest(fiber.MethodGet, "http://127.0.0.1:3000/public/index.html", nil)
   503  	resp, err := server.app.Test(req)
   504  	utils.AssertEqual(t, nil, err, "Expected to not get error")
   505  	utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
   506  
   507  	body, err := io.ReadAll(resp.Body)
   508  	utils.AssertEqual(t, nil, err, "Response Body Result")
   509  
   510  	expectedText := `<!DOCTYPE html>
   511  <html lang="en">
   512  <body>
   513      Hi
   514  </body>
   515  </html>`
   516  	utils.AssertEqual(t, expectedText, string(body), "Unmatched content")
   517  }
   518  
   519  func TestFiberWrapper_AddRouteWithMultipleHandler(t *testing.T) {
   520  	serverConfig := ServerConfig{ListenAddress: ":3000"}
   521  	server, err := NewServer("http", serverConfig)
   522  	if err != nil {
   523  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   524  		return
   525  	}
   526  
   527  	server.AddRouteWithMultiHandlers(fiber.MethodGet, "/", []func(c *fiber.Ctx) error{
   528  		func(c *fiber.Ctx) error { return nil },
   529  		func(c *fiber.Ctx) error { return errors.New("error") },
   530  	}, "TestGet", []string{}, []string{})
   531  
   532  	routes := server.app.GetRoutes()
   533  	if len(routes) == 0 {
   534  		t.Errorf("Expected 1 routes added to server, but got %v", len(routes))
   535  		return
   536  	}
   537  
   538  	// check the name of the route
   539  	r := server.app.GetRoute("TestGet")
   540  	if r.Method != fiber.MethodGet {
   541  		t.Errorf("Expected to get method %v, but got %v", fiber.MethodGet, r.Method)
   542  		return
   543  	}
   544  	if r.Path != "/" {
   545  		t.Errorf("Expected to get route '%v', but got '%v'", "/", r.Path)
   546  		return
   547  	}
   548  }
   549  
   550  func TestFiberWrapper_CustomErrorHandler(t *testing.T) {
   551  	serverConfig := ServerConfig{ListenAddress: ":3000"}
   552  	server, err := NewServer("http", serverConfig)
   553  	if err != nil {
   554  		t.Errorf("Creating HTTP Server --> Expected: %v, but got %v", nil, err)
   555  		return
   556  	}
   557  
   558  	server.AttachErrorHandler(func(ctx *fiber.Ctx, err error) error {
   559  		// Status code defaults to 500
   560  		code := fiber.StatusInternalServerError
   561  
   562  		// Retrieve the custom status code if it's a *fiber.Error
   563  		var e *fiber.Error
   564  		if errors.As(err, &e) {
   565  			code = e.Code
   566  		}
   567  
   568  		utils.AssertEqual(t, fiber.StatusNotFound, code, "Status code")
   569  		ctx.Status(code).SendString(e.Error())
   570  		return nil
   571  	})
   572  
   573  	go server.Start()
   574  	defer server.Stop()
   575  
   576  	req := httptest.NewRequest(fiber.MethodGet, "http://127.0.0.1:3000/t", nil)
   577  	resp, err := server.app.Test(req)
   578  	utils.AssertEqual(t, nil, err, "Expected to not get error")
   579  	utils.AssertEqual(t, 404, resp.StatusCode, "Status code")
   580  }