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