github.com/blend/go-sdk@v1.20220411.3/web/mock.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package web 9 10 import ( 11 "bytes" 12 "context" 13 "encoding/json" 14 "io" 15 "net/http" 16 "net/http/httptest" 17 "net/url" 18 19 "github.com/blend/go-sdk/r2" 20 "github.com/blend/go-sdk/webutil" 21 ) 22 23 // Mock sends a mock request to an app. 24 // It will reset the app Server, Listener, and will set the request host to the listener address 25 // for a randomized local listener. 26 func Mock(app *App, req *http.Request, options ...r2.Option) *MockResult { 27 var err error 28 result := &MockResult{ 29 App: app, 30 Request: &r2.Request{ 31 Request: req, 32 }, 33 } 34 for _, option := range options { 35 if err = option(result.Request); err != nil { 36 result.Err = err 37 return result 38 } 39 } 40 41 if err := app.StartupTasks(); err != nil { 42 result.Err = err 43 return result 44 } 45 46 if result.Request.Request.URL == nil { 47 result.Request.Request.URL = &url.URL{} 48 } 49 50 result.Server = httptest.NewUnstartedServer(app) 51 result.Server.Config.BaseContext = app.BaseContext 52 result.Server.Start() 53 result.Request.Closer = result.Close 54 55 parsedServerURL := webutil.MustParseURL(result.Server.URL) 56 result.Request.Request.URL.Scheme = parsedServerURL.Scheme 57 result.Request.Request.URL.Host = parsedServerURL.Host 58 59 return result 60 } 61 62 // MockMethod sends a mock request with a given method to an app. 63 // You should use request options to set the body of the request if it's a post or put etc. 64 func MockMethod(app *App, method, path string, options ...r2.Option) *MockResult { 65 req := &http.Request{ 66 Method: method, 67 URL: &url.URL{ 68 Path: path, 69 }, 70 } 71 return Mock(app, req, options...) 72 } 73 74 // MockGet sends a mock get request to an app. 75 func MockGet(app *App, path string, options ...r2.Option) *MockResult { 76 req := &http.Request{ 77 Method: "GET", 78 URL: &url.URL{ 79 Path: path, 80 }, 81 } 82 return Mock(app, req, options...) 83 } 84 85 // MockPost sends a mock post request to an app. 86 func MockPost(app *App, path string, body io.ReadCloser, options ...r2.Option) *MockResult { 87 req := &http.Request{ 88 Method: "POST", 89 Body: body, 90 URL: &url.URL{ 91 Path: path, 92 }, 93 } 94 return Mock(app, req, options...) 95 } 96 97 // MockPostJSON sends a mock post request with a json body to an app. 98 func MockPostJSON(app *App, path string, body interface{}, options ...r2.Option) *MockResult { 99 contents, _ := json.Marshal(body) 100 req := &http.Request{ 101 Method: "POST", 102 Body: io.NopCloser(bytes.NewReader(contents)), 103 URL: &url.URL{ 104 Path: path, 105 }, 106 } 107 return Mock(app, req, options...) 108 } 109 110 // MockResult is a result of a mocked request. 111 type MockResult struct { 112 *r2.Request 113 App *App 114 Server *httptest.Server 115 } 116 117 // Close stops the app. 118 func (mr *MockResult) Close() error { 119 mr.Server.Close() 120 return nil 121 } 122 123 // MockCtx returns a new mock ctx. 124 // It is intended to be used in testing. 125 func MockCtx(method, path string, options ...CtxOption) *Ctx { 126 return MockCtxWithBuffer(method, path, new(bytes.Buffer), options...) 127 } 128 129 // MockCtxWithBuffer returns a new mock ctx. 130 // It is intended to be used in testing. 131 func MockCtxWithBuffer(method, path string, buf io.Writer, options ...CtxOption) *Ctx { 132 return NewCtx( 133 webutil.NewMockResponse(buf), 134 webutil.NewMockRequest(method, path), 135 append( 136 []CtxOption{ 137 OptCtxApp(new(App)), 138 OptCtxDefaultProvider(Text), 139 }, 140 options..., 141 )..., 142 ) 143 } 144 145 // MockSimulateLogin simulates a user login for a given app as mocked request params (i.e. r2 options). 146 // 147 // This requires an auth manager to be set on the app. 148 func MockSimulateLogin(ctx context.Context, app *App, userID string, opts ...r2.Option) []r2.Option { 149 sessionID := NewSessionID() 150 session := NewSession(userID, sessionID) 151 if app.Auth.PersistHandler != nil { 152 _ = app.Auth.PersistHandler(ctx, session) 153 } 154 return append([]r2.Option{ 155 r2.OptCookieValue(app.Auth.CookieDefaults.Name, sessionID), 156 }, opts...) 157 }