github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/api/parse_request_test.go (about)

     1  package api
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"mime/multipart"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	"github.com/google/go-cmp/cmp/cmpopts"
    13  	"github.com/gorilla/mux"
    14  	"github.com/qri-io/dataset"
    15  	"github.com/qri-io/qri/base/params"
    16  	"github.com/qri-io/qri/lib"
    17  )
    18  
    19  func TestParseGetParamsFromRequest(t *testing.T) {
    20  	cases := []struct {
    21  		description  string
    22  		url          string
    23  		expectParams *lib.GetParams
    24  		muxVars      map[string]string
    25  	}{
    26  		{
    27  			"basic get",
    28  			"/get/peer/my_ds",
    29  			&lib.GetParams{
    30  				Ref: "peer/my_ds",
    31  				All: true,
    32  			},
    33  			map[string]string{"username": "peer", "name": "my_ds"},
    34  		},
    35  		{
    36  			"get request with ref",
    37  			"/get/peer/my_ds",
    38  			&lib.GetParams{
    39  				Ref: "peer/my_ds",
    40  				All: true,
    41  			},
    42  			map[string]string{"ref": "peer/my_ds"},
    43  		},
    44  		{
    45  			"meta component",
    46  			"/get/peer/my_ds/meta",
    47  			&lib.GetParams{
    48  				Ref:      "peer/my_ds",
    49  				Selector: "meta",
    50  				All:      true,
    51  			},
    52  			map[string]string{"username": "peer", "name": "my_ds", "selector": "meta"},
    53  		},
    54  		{
    55  			"get request with limit and offset",
    56  			"/get/peer/my_ds/body",
    57  			&lib.GetParams{
    58  				Ref:      "peer/my_ds",
    59  				Selector: "body",
    60  				List: params.List{
    61  					Offset: 10,
    62  					Limit:  0,
    63  				},
    64  			},
    65  			map[string]string{"ref": "peer/my_ds", "selector": "body", "limit": "0", "offset": "10"},
    66  		},
    67  		{
    68  			"get request with 'all'",
    69  			"/get/peer/my_ds/body",
    70  			&lib.GetParams{
    71  				Ref:      "peer/my_ds",
    72  				Selector: "body",
    73  				All:      true,
    74  			},
    75  			map[string]string{"ref": "peer/my_ds", "selector": "body", "all": "true"},
    76  		},
    77  	}
    78  	for _, c := range cases {
    79  		t.Run(c.description, func(t *testing.T) {
    80  			r, _ := http.NewRequest("GET", c.url, nil)
    81  			if c.muxVars != nil {
    82  				r = mux.SetURLVars(r, c.muxVars)
    83  			}
    84  			r = mustSetMuxVarsOnRequest(t, r, c.muxVars)
    85  			gotParams := &lib.GetParams{}
    86  			if err := parseGetParamsFromRequest(r, gotParams); err != nil {
    87  				t.Error(err)
    88  				return
    89  			}
    90  			if diff := cmp.Diff(c.expectParams, gotParams); diff != "" {
    91  				t.Errorf("output mismatch (-want +got):\n%s", diff)
    92  			}
    93  		})
    94  	}
    95  
    96  	badCases := []struct {
    97  		description string
    98  		url         string
    99  		expectErr   string
   100  		muxVars     map[string]string
   101  	}{
   102  		{
   103  			"get me",
   104  			"/get/me/my_ds",
   105  			`username "me" not allowed`,
   106  			map[string]string{"ref": "me/my_ds"},
   107  		},
   108  		{
   109  			"bad parse",
   110  			"/get/peer/my+ds",
   111  			`unexpected character at position 7: '+'`,
   112  			map[string]string{"ref": "peer/my+ds"},
   113  		},
   114  	}
   115  	for i, c := range badCases {
   116  		t.Run(c.description, func(t *testing.T) {
   117  			r := httptest.NewRequest("GET", c.url, nil)
   118  			r = mustSetMuxVarsOnRequest(t, r, c.muxVars)
   119  			gotParams := &lib.GetParams{}
   120  			err := parseGetParamsFromRequest(r, gotParams)
   121  			if err == nil {
   122  				t.Errorf("case %d: expected error, but did not get one", i)
   123  				return
   124  			}
   125  			if diff := cmp.Diff(c.expectErr, err.Error()); diff != "" {
   126  				t.Errorf("output mismatch (-want +got):\n%s", diff)
   127  			}
   128  		})
   129  	}
   130  }
   131  
   132  func TestParseSaveParamsFromRequest(t *testing.T) {
   133  	expect := &lib.SaveParams{
   134  		Ref:                 "test/ref",
   135  		Title:               "test title",
   136  		Message:             "test message",
   137  		Apply:               true,
   138  		Replace:             true,
   139  		ConvertFormatToPrev: true,
   140  		Drop:                "drop",
   141  		Force:               true,
   142  		NewName:             true,
   143  		Dataset: &dataset.Dataset{
   144  			Name:     "dataset name",
   145  			Peername: "test peername",
   146  			Meta: &dataset.Meta{
   147  				Title: "test meta title",
   148  				Qri:   "md:0",
   149  			},
   150  		},
   151  	}
   152  
   153  	dsBytes, err := json.Marshal(expect.Dataset)
   154  	if err != nil {
   155  		t.Fatalf("error marshaling dataset: %s", err)
   156  	}
   157  
   158  	body := new(bytes.Buffer)
   159  	writer := multipart.NewWriter(body)
   160  	writer.WriteField("ref", expect.Ref)
   161  	writer.WriteField("title", expect.Title)
   162  	writer.WriteField("message", expect.Message)
   163  	writer.WriteField("apply", "true")
   164  	writer.WriteField("replace", "true")
   165  	writer.WriteField("convertFormatToPrev", "true")
   166  	writer.WriteField("drop", "drop")
   167  	writer.WriteField("force", "true")
   168  	writer.WriteField("newName", "true")
   169  	writer.WriteField("dataset", string(dsBytes))
   170  	writer.Close()
   171  
   172  	r, err := http.NewRequest(http.MethodPost, "save", body)
   173  	if err != nil {
   174  		t.Fatalf("error creating new request: %s", err)
   175  	}
   176  	r.Header.Add("Content-Type", writer.FormDataContentType())
   177  	got := &lib.SaveParams{}
   178  	err = parseSaveParamsFromRequest(r, got)
   179  	if err != nil {
   180  		t.Fatalf("error saving params from request: %s", err)
   181  	}
   182  	if diff := cmp.Diff(expect, got, cmpopts.IgnoreUnexported(dataset.Dataset{}), cmpopts.IgnoreUnexported(dataset.Meta{})); diff != "" {
   183  		t.Errorf("SaveParams mismatch (-want +got):%s\n", diff)
   184  	}
   185  }
   186  
   187  func TestParseDatasetFromRequest(t *testing.T) {
   188  	r := newFormFileRequest(t, "/", nil, nil)
   189  	dsp := &dataset.Dataset{}
   190  	if err := parseDatasetFromRequest(r, dsp); err != nil {
   191  		t.Error("expected 'empty' request to be ok")
   192  	}
   193  
   194  	r = newFormFileRequest(t, "/", map[string]string{
   195  		"file":      dstestTestdataFile("cities/init_dataset.json"),
   196  		"viz":       dstestTestdataFile("cities/template.html"),
   197  		"transform": dstestTestdataFile("cities/transform.star"),
   198  		"readme":    dstestTestdataFile("cities/readme.md"),
   199  		"body":      dstestTestdataFile("cities/data.csv"),
   200  	}, nil)
   201  	if err := parseDatasetFromRequest(r, dsp); err != nil {
   202  		t.Error(err)
   203  	}
   204  
   205  	r = newFormFileRequest(t, "/", map[string]string{
   206  		"file": "testdata/cities/dataset.yml",
   207  		"body": dstestTestdataFile("cities/data.csv"),
   208  	}, nil)
   209  	if err := parseDatasetFromRequest(r, dsp); err != nil {
   210  		t.Error(err)
   211  	}
   212  }