Skip to content

Commit

Permalink
Extend test and don't close form file.
Browse files Browse the repository at this point in the history
  • Loading branch information
hantonelli committed Apr 15, 2019
1 parent 2cf7f45 commit da52e81
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
51 changes: 51 additions & 0 deletions example/fileupload/fileupload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,57 @@ func TestFileUpload(t *testing.T) {
require.Nil(t, err)
require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1"},{"id":2,"name":"b.txt","content":"test2"}]}}`, string(responseBody))
})

t.Run("valid file list upload with payload and file reuse", func(t *testing.T) {
resolver := &Resolver{
MultipleUploadWithPayloadFunc: func(ctx context.Context, req []model.UploadFile) ([]model.File, error) {
require.Len(t, req, 2)
var ids []int
var contents []string
var resp []model.File
for i := range req {
require.NotNil(t, req[i].File)
require.NotNil(t, req[i].File.File)
ids = append(ids, req[i].ID)
req[i].File.File.Seek(0, 0)
content, err := ioutil.ReadAll(req[i].File.File)
require.Nil(t, err)
contents = append(contents, string(content))
resp = append(resp, model.File{
ID: i + 1,
Name: req[i].File.Filename,
Content: string(content),
})
}
require.ElementsMatch(t, []int{1, 2}, ids)
require.ElementsMatch(t, []string{"test1", "test1"}, contents)
return resp, nil
},
}
srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(Config{Resolvers: resolver}), handler.UploadMaxMemory(2)))
defer srv.Close()

operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }`
mapData := `{ "0": ["variables.req.0.file", "variables.req.1.file"] }`
files := []file{
{
mapKey: "0",
name: "a.txt",
content: "test1",
},
}
req := createUploadRequest(t, srv.URL, operations, mapData, files)

resp, err := client.Do(req)
require.Nil(t, err)
defer func() {
_ = resp.Body.Close()
}()
require.Equal(t, http.StatusOK, resp.StatusCode)
responseBody, err := ioutil.ReadAll(resp.Body)
require.Nil(t, err)
require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1"},{"id":2,"name":"a.txt","content":"test1"}]}}`, string(responseBody))
})
}

type file struct {
Expand Down
1 change: 0 additions & 1 deletion handler/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,6 @@ func processMultipart(w http.ResponseWriter, r *http.Request, request *params, u
if err != nil {
return fmt.Errorf("failed to get key %s from form", key)
}
defer file.Close()
if len(paths) == 0 {
return fmt.Errorf("invalid empty operations paths list for key %s", key)
}
Expand Down
65 changes: 65 additions & 0 deletions handler/graphql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package handler
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"mime/multipart"
"net/http"
Expand Down Expand Up @@ -301,6 +302,33 @@ func TestFileUpload(t *testing.T) {
require.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1},{"id":2}]}}`, resp.Body.String())
})

t.Run("valid file list upload with payload and file reuse", func(t *testing.T) {
mock := &executableSchemaMock{
MutationFunc: func(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
require.Equal(t, len(op.VariableDefinitions), 1)
require.Equal(t, op.VariableDefinitions[0].Variable, "req")
return &graphql.Response{Data: []byte(`{"multipleUploadWithPayload":[{"id":1},{"id":2}]}`)}
},
}
handler := GraphQL(mock)

operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }`
mapData := `{ "0": ["variables.req.0.file", "variables.req.1.file"] }`
files := []file{
{
mapKey: "0",
name: "a.txt",
content: "test1",
},
}
req := createUploadRequest(t, operations, mapData, files)

resp := httptest.NewRecorder()
handler.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1},{"id":2}]}}`, resp.Body.String())
})
}

func TestProcessMultipart(t *testing.T) {
Expand Down Expand Up @@ -401,6 +429,43 @@ func TestProcessMultipart(t *testing.T) {
require.Nil(t, err)
require.Equal(t, "test1", string(content))
})

t.Run("valid request with two values", func(t *testing.T) {
operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }`
mapData := `{ "0": ["variables.req.0.file", "variables.req.1.file"] }`
files := []file{
{
mapKey: "0",
name: "a.txt",
content: "test1",
},
}
req := createUploadRequest(t, operations, mapData, files)

var reqParams params
w := httptest.NewRecorder()
err := processMultipart(w, req, &reqParams, DefaultUploadMaxSize, 2)
require.Nil(t, err)
require.Equal(t, "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id } }", reqParams.Query)
require.Equal(t, "", reqParams.OperationName)
require.Equal(t, 1, len(reqParams.Variables))
require.NotNil(t, reqParams.Variables["req"])
reqParamsFile, ok := reqParams.Variables["req"].([]interface{})
require.True(t, ok)
require.Equal(t, 2, len(reqParamsFile))
for i, item := range reqParamsFile {
itemMap := item.(map[string]interface{})
require.Equal(t, fmt.Sprint(itemMap["id"]), fmt.Sprint(i+1))
file := itemMap["file"].(graphql.Upload)
require.Equal(t, "a.txt", file.Filename)
require.Equal(t, int64(len("test1")), file.Size)
_, err = file.File.Seek(0, 0)
require.Nil(t, err)
content, err := ioutil.ReadAll(file.File)
require.Nil(t, err)
require.Equal(t, "test1", string(content))
}
})
}

func TestAddUploadToOperations(t *testing.T) {
Expand Down

0 comments on commit da52e81

Please sign in to comment.