github.com/bketelsen/buffalo@v0.9.5/default_context_test.go (about)

     1  package buffalo
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/url"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"golang.org/x/net/websocket"
    15  
    16  	"github.com/gobuffalo/buffalo/render"
    17  	"github.com/markbates/willie"
    18  	"github.com/pkg/errors"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func basicContext() DefaultContext {
    23  	return DefaultContext{
    24  		Context: context.Background(),
    25  		logger:  NewLogger("debug"),
    26  		data:    make(map[string]interface{}),
    27  		flash:   &Flash{data: make(map[string][]string)},
    28  	}
    29  }
    30  
    31  func Test_DefaultContext_Redirect(t *testing.T) {
    32  	r := require.New(t)
    33  	a := New(Options{})
    34  	u := "/foo?bar=http%3A%2F%2Flocalhost%3A3000%2Flogin%2Fcallback%2Ffacebook"
    35  	a.GET("/", func(c Context) error {
    36  		return c.Redirect(302, u)
    37  	})
    38  
    39  	w := willie.New(a)
    40  	res := w.Request("/").Get()
    41  	r.Equal(u, res.Location())
    42  }
    43  
    44  func Test_DefaultContext_Param(t *testing.T) {
    45  	r := require.New(t)
    46  	c := DefaultContext{
    47  		params: url.Values{
    48  			"name": []string{"Mark"},
    49  		},
    50  	}
    51  
    52  	r.Equal("Mark", c.Param("name"))
    53  }
    54  
    55  func Test_DefaultContext_GetSet(t *testing.T) {
    56  	r := require.New(t)
    57  	c := basicContext()
    58  	r.Nil(c.Value("name"))
    59  
    60  	c.Set("name", "Mark")
    61  	r.NotNil(c.Value("name"))
    62  	r.Equal("Mark", c.Value("name").(string))
    63  }
    64  
    65  func Test_DefaultContext_Value(t *testing.T) {
    66  	r := require.New(t)
    67  	c := basicContext()
    68  	r.Nil(c.Value("name"))
    69  
    70  	c.Set("name", "Mark")
    71  	r.NotNil(c.Value("name"))
    72  	r.Equal("Mark", c.Value("name").(string))
    73  	r.Equal("Mark", c.Value("name").(string))
    74  }
    75  
    76  func Test_DefaultContext_Render(t *testing.T) {
    77  	r := require.New(t)
    78  
    79  	c := basicContext()
    80  	res := httptest.NewRecorder()
    81  	c.response = res
    82  	c.params = url.Values{"name": []string{"Mark"}}
    83  	c.Set("greet", "Hello")
    84  
    85  	err := c.Render(123, render.String(`<%= greet %> <%= params["name"] %>!`))
    86  	r.NoError(err)
    87  
    88  	r.Equal(123, res.Code)
    89  	r.Equal("Hello Mark!", res.Body.String())
    90  }
    91  
    92  func Test_DefaultContext_Bind_Default(t *testing.T) {
    93  	r := require.New(t)
    94  
    95  	user := struct {
    96  		FirstName string `form:"first_name"`
    97  	}{}
    98  
    99  	a := New(Options{})
   100  	a.POST("/", func(c Context) error {
   101  		err := c.Bind(&user)
   102  		if err != nil {
   103  			return errors.WithStack(err)
   104  		}
   105  		return c.Render(201, nil)
   106  	})
   107  
   108  	w := willie.New(a)
   109  	uv := url.Values{"first_name": []string{"Mark"}}
   110  	res := w.Request("/").Post(uv)
   111  	r.Equal(201, res.Code)
   112  
   113  	r.Equal("Mark", user.FirstName)
   114  }
   115  
   116  func Test_DefaultContext_Bind_No_ContentType(t *testing.T) {
   117  	r := require.New(t)
   118  
   119  	user := struct {
   120  		FirstName string `form:"first_name"`
   121  	}{
   122  		FirstName: "Mark",
   123  	}
   124  
   125  	a := New(Options{})
   126  	a.POST("/", func(c Context) error {
   127  		err := c.Bind(&user)
   128  		if err != nil {
   129  			return c.Error(422, err)
   130  		}
   131  		return c.Render(201, nil)
   132  	})
   133  
   134  	bb := &bytes.Buffer{}
   135  	req, err := http.NewRequest("POST", "/", bb)
   136  	r.NoError(err)
   137  	req.Header.Del("Content-Type")
   138  	res := httptest.NewRecorder()
   139  	a.ServeHTTP(res, req)
   140  	r.Equal(422, res.Code)
   141  	r.Contains(res.Body.String(), "blank content type")
   142  }
   143  
   144  func Test_DefaultContext_Bind_Empty_ContentType(t *testing.T) {
   145  	r := require.New(t)
   146  
   147  	user := struct {
   148  		FirstName string `form:"first_name"`
   149  	}{
   150  		FirstName: "Mark",
   151  	}
   152  
   153  	a := New(Options{})
   154  	a.POST("/", func(c Context) error {
   155  		err := c.Bind(&user)
   156  		if err != nil {
   157  			return c.Error(422, err)
   158  		}
   159  		return c.Render(201, nil)
   160  	})
   161  
   162  	bb := &bytes.Buffer{}
   163  	req, err := http.NewRequest("POST", "/", bb)
   164  	r.NoError(err)
   165  	// Want to make sure that an empty string value does not cause an error on `split`
   166  	req.Header.Set("Content-Type", "")
   167  	res := httptest.NewRecorder()
   168  	a.ServeHTTP(res, req)
   169  	r.Equal(422, res.Code)
   170  	r.Contains(res.Body.String(), "blank content type")
   171  }
   172  
   173  func Test_DefaultContext_Bind_Default_BlankFields(t *testing.T) {
   174  	r := require.New(t)
   175  
   176  	user := struct {
   177  		FirstName string `form:"first_name"`
   178  	}{
   179  		FirstName: "Mark",
   180  	}
   181  
   182  	a := New(Options{})
   183  	a.POST("/", func(c Context) error {
   184  		err := c.Bind(&user)
   185  		if err != nil {
   186  			return errors.WithStack(err)
   187  		}
   188  		return c.Render(201, nil)
   189  	})
   190  
   191  	w := willie.New(a)
   192  	uv := url.Values{"first_name": []string{""}}
   193  	res := w.Request("/").Post(uv)
   194  	r.Equal(201, res.Code)
   195  
   196  	r.Equal("", user.FirstName)
   197  }
   198  
   199  func Test_DefaultContext_Bind_JSON(t *testing.T) {
   200  	r := require.New(t)
   201  
   202  	user := struct {
   203  		FirstName string `json:"first_name"`
   204  	}{}
   205  
   206  	a := New(Options{})
   207  	a.POST("/", func(c Context) error {
   208  		err := c.Bind(&user)
   209  		if err != nil {
   210  			return errors.WithStack(err)
   211  		}
   212  		return c.Render(201, nil)
   213  	})
   214  
   215  	w := willie.New(a)
   216  	res := w.JSON("/").Post(map[string]string{
   217  		"first_name": "Mark",
   218  	})
   219  	r.Equal(201, res.Code)
   220  
   221  	r.Equal("Mark", user.FirstName)
   222  }
   223  
   224  func Test_DefaultContext_Websocket(t *testing.T) {
   225  	r := require.New(t)
   226  
   227  	type Message struct {
   228  		Original  string    `json:"original"`
   229  		Formatted string    `json:"formatted"`
   230  		Received  time.Time `json:"received"`
   231  	}
   232  
   233  	a := New(Options{})
   234  	a.GET("/socket", func(c Context) error {
   235  		conn, err := c.Websocket()
   236  		if err != nil {
   237  			return err
   238  		}
   239  		for {
   240  
   241  			_, m, err := conn.ReadMessage()
   242  			if err != nil {
   243  				return err
   244  			}
   245  
   246  			data := string(m)
   247  
   248  			msg := Message{
   249  				Original:  data,
   250  				Formatted: strings.ToUpper(data),
   251  				Received:  time.Now(),
   252  			}
   253  
   254  			if err := conn.WriteJSON(msg); err != nil {
   255  				return err
   256  			}
   257  		}
   258  	})
   259  
   260  	ts := httptest.NewServer(a)
   261  	defer ts.Close()
   262  
   263  	wsURL := strings.Replace(ts.URL, "http", "ws", 1) + "/socket"
   264  
   265  	ws, err := websocket.Dial(wsURL, "", "http://127.0.0.1")
   266  	r.NoError(err)
   267  
   268  	_, err = ws.Write([]byte("hello, world!"))
   269  	r.NoError(err)
   270  
   271  	msg := make([]byte, 512)
   272  	read, err := ws.Read(msg)
   273  	r.NoError(err)
   274  
   275  	var message Message
   276  	err = json.NewDecoder(bytes.NewReader(msg[:read])).Decode(&message)
   277  	r.NoError(err)
   278  
   279  	// Create a table of what we expect.
   280  	tests := []struct {
   281  		Got  string
   282  		Want string
   283  	}{
   284  		{message.Formatted, "HELLO, WORLD!"},
   285  		{message.Original, "hello, world!"},
   286  	}
   287  
   288  	// Check the different fields.
   289  	for _, tt := range tests {
   290  		r.Equal(tt.Want, tt.Got)
   291  	}
   292  }