Skip to content

Commit

Permalink
Add InitializeResponder to improve testing (palantir#34)
Browse files Browse the repository at this point in the history
Allow code other than the default dispatcher to initialize a request
context for use with Set/GetResponder.
  • Loading branch information
bluekeyes authored Apr 7, 2020
1 parent da539ea commit a2a34ed
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions githubapp/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,7 @@ func (d *eventDispatcher) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

// initialize context for SetResponder/GetResponder
// we store a pointer in the context so that functions deeper in the call
// tree can modify the value without creating a new context
var responder func(http.ResponseWriter, *http.Request)
ctx = context.WithValue(ctx, responderKey{}, &responder)
ctx = InitializeResponder(ctx)
r = r.WithContext(ctx)

eventType := r.Header.Get("X-GitHub-Event")
Expand Down Expand Up @@ -216,17 +213,25 @@ func DefaultResponseCallback(w http.ResponseWriter, r *http.Request, event strin

type responderKey struct{}

// InitializeResponder prepares the context to work with SetResponder and
// GetResponder. It is used to test handlers that call SetResponder or to
// implement custom event dispatchers that support responders.
func InitializeResponder(ctx context.Context) context.Context {
var responder func(http.ResponseWriter, *http.Request)
return context.WithValue(ctx, responderKey{}, &responder)
}

// SetResponder sets a function that sends a response to GitHub after event
// processing completes. This function may only be called from event handler
// functions invoked by the event dispatcher.
// processing completes. The context must be initialized by InitializeResponder.
// The event dispatcher does this automatically before calling a handler.
//
// Customizing individual handler responses should be rare. Applications that
// want to modify the standard responses should consider registering a response
// callback before using this function.
func SetResponder(ctx context.Context, responder func(http.ResponseWriter, *http.Request)) {
r, ok := ctx.Value(responderKey{}).(*func(http.ResponseWriter, *http.Request))
if !ok || r == nil {
panic("SetResponder() must be called from an event handler invoked by the go-githubapp event dispatcher")
panic("SetResponder() must be called with an initialized context, such as one from the event dispatcher")
}
*r = responder
}
Expand Down

0 comments on commit a2a34ed

Please sign in to comment.