diff --git a/client.go b/client.go index 372c42bb..349c1539 100644 --- a/client.go +++ b/client.go @@ -4,58 +4,40 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" + "log/slog" "net/http" + "net/url" "os" -) -var ( - // DefaultClient represents the default, mutable, global client used - // within the `Send` function provided by this package. - // - // You should initialize this within an init() function using `NewClient` - // if you plan to use the `Send` function: - // - // func init() { - // inngestgo.DefaultClient = inngestgo.NewClient( - // "key", - // inngestgo.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}), - // ) - // } - // - // If this client is not set, Send will return an error. - DefaultClient Client + "github.com/inngest/inngestgo/connect" ) const ( defaultEndpoint = "https://inn.gs" ) -// Send uses the DefaultClient to send the given event. -func Send(ctx context.Context, e any) (string, error) { - if DefaultClient == nil { - return "", fmt.Errorf("no default client initialized for inngest") - } - return DefaultClient.Send(ctx, e) -} - -// SendMany uses the DefaultClient to send the given event batch. -func SendMany(ctx context.Context, e []any) ([]string, error) { - if DefaultClient == nil { - return nil, fmt.Errorf("no default client initialized for inngest") - } - return DefaultClient.SendMany(ctx, e) -} - // Client represents a client used to send events to Inngest. type Client interface { + AppID() string + Connect( + ctx context.Context, + opts ConnectOpts, + ) (connect.WorkerConnection, error) + // Send sends the specific event to the ingest API. Send(ctx context.Context, evt any) (string, error) // Send sends a batch of events to the ingest API. SendMany(ctx context.Context, evt []any) ([]string, error) + + Serve() http.Handler + ServeWithOpts(opts ServeOpts) http.Handler } type ClientOpts struct { + AppID string + // HTTPClient is the HTTP client used to send events. HTTPClient *http.Client // EventKey is your Inngest event key for sending events. This defaults to the @@ -68,26 +50,105 @@ type ClientOpts struct { // os.Getenv("INNGEST_ENV"). This only deploys to branches if the // signing key is a branch signing key. Env *string + + // Logger is the structured logger to use from Go's builtin structured + // logging package. + Logger *slog.Logger + + // SigningKey is the signing key for your app. If nil, this defaults + // to os.Getenv("INNGEST_SIGNING_KEY"). + SigningKey *string + + // SigningKeyFallback is the fallback signing key for your app. If nil, this + // defaults to os.Getenv("INNGEST_SIGNING_KEY_FALLBACK"). + SigningKeyFallback *string + + // APIOrigin is the specified host to be used to make API calls + APIBaseURL *string + + // EventAPIOrigin is the specified host to be used to send events to + EventAPIBaseURL *string + + // RegisterURL is the URL to use when registering functions. If nil + // this defaults to Inngest's API. + // + // This only needs to be set when self hosting. + RegisterURL *string + + // AppVersion supplies an application version identifier. This should change + // whenever code within one of your Inngest function or any dependency thereof changes. + AppVersion *string + + // MaxBodySize is the max body size to read for incoming invoke requests + MaxBodySize int + + // URL that the function is served at. If not supplied this is taken from + // the incoming request's data. + URL *url.URL + + // UseStreaming enables streaming - continued writes to the HTTP writer. This + // differs from true streaming in that we don't support server-sent events. + UseStreaming bool + + // AllowInBandSync allows in-band syncs to occur. If nil, in-band syncs are + // disallowed. + AllowInBandSync *bool + + // Dev is whether to use the Dev Server. + Dev *bool +} + +func (c ClientOpts) validate() error { + if c.AppID == "" { + return errors.New("app id is required") + } + return nil } // NewClient returns a concrete client initialized with the given ingest key, // which can immediately send events to the ingest API. -func NewClient(opts ClientOpts) Client { +func NewClient(opts ClientOpts) (Client, error) { + err := opts.validate() + if err != nil { + return nil, err + } + c := &apiClient{ ClientOpts: opts, } + h := newHandler(c, handlerOpts{ + Logger: opts.Logger, + SigningKey: opts.SigningKey, + SigningKeyFallback: opts.SigningKeyFallback, + APIBaseURL: opts.APIBaseURL, + EventAPIBaseURL: opts.EventAPIBaseURL, + Env: opts.Env, + RegisterURL: opts.RegisterURL, + AppVersion: opts.AppVersion, + MaxBodySize: opts.MaxBodySize, + URL: opts.URL, + UseStreaming: opts.UseStreaming, + AllowInBandSync: opts.AllowInBandSync, + Dev: opts.Dev, + }) + c.h = h if c.ClientOpts.HTTPClient == nil { c.ClientOpts.HTTPClient = http.DefaultClient } - return c + return c, nil } // apiClient is a concrete implementation of Client that uses the given HTTP client // to send events to the ingest API type apiClient struct { ClientOpts + h *handler +} + +func (a apiClient) AppID() string { + return a.ClientOpts.AppID } func (a apiClient) GetEnv() string { @@ -114,6 +175,35 @@ func (a apiClient) GetEventKey() string { return "" } +type ServeOpts struct { + // ServeOrigin is the host to used for HTTP base function invoking. + // It's used to specify the host were the functions are hosted on sync. + // e.g. https://example.com + ServeOrigin *string + + // ServePath is the path to use for HTTP base function invoking + // It's used to specify the path were the functions are hosted on sync. + // e.g. /api/inngest + ServePath *string +} + +func (a apiClient) Connect( + ctx context.Context, + opts ConnectOpts, +) (connect.WorkerConnection, error) { + return a.h.Connect(ctx, opts) +} + +func (a apiClient) Serve() http.Handler { + return a.ServeWithOpts(ServeOpts{}) +} + +func (a apiClient) ServeWithOpts(opts ServeOpts) http.Handler { + a.h.handlerOpts.ServeOrigin = opts.ServeOrigin + a.h.handlerOpts.ServePath = opts.ServePath + return a.h +} + type validatable interface { Validate() error } diff --git a/connect.go b/connect.go index 4163449e..5b5d3bc4 100644 --- a/connect.go +++ b/connect.go @@ -3,11 +3,12 @@ package inngestgo import ( "context" "fmt" + "net/url" + "github.com/inngest/inngest/pkg/execution/state" "github.com/inngest/inngest/pkg/publicerr" "github.com/inngest/inngestgo/connect" "github.com/inngest/inngestgo/internal/sdkrequest" - "net/url" ) const ( @@ -93,7 +94,7 @@ func (h *handler) getServableFunctionBySlug(slug string) ServableFunction { h.l.RLock() var fn ServableFunction for _, f := range h.funcs { - if f.Slug(h.appName) == slug { + if f.FullyQualifiedID() == slug { fn = f break } diff --git a/examples/connect/main.go b/examples/connect/main.go index d2f89cb6..5f3bff78 100644 --- a/examples/connect/main.go +++ b/examples/connect/main.go @@ -3,13 +3,14 @@ package main import ( "context" "fmt" - "github.com/inngest/inngest/pkg/logger" - "github.com/inngest/inngestgo" - "github.com/inngest/inngestgo/connect" "os" "os/signal" "syscall" "time" + + "github.com/inngest/inngest/pkg/logger" + "github.com/inngest/inngestgo" + "github.com/inngest/inngestgo/connect" ) func main() { @@ -17,22 +18,28 @@ func main() { defer cancel() key := "signkey-test-12345678" - h := inngestgo.NewHandler("connect-test", inngestgo.HandlerOpts{ - Logger: logger.StdlibLogger(ctx), - SigningKey: &key, + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: "connect-test", AppVersion: nil, Dev: inngestgo.BoolPtr(true), + Logger: logger.StdlibLogger(ctx), + SigningKey: &key, }) + if err != nil { + panic(err) + } - f := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ID: "conntest", Name: "connect test"}, inngestgo.EventTrigger("test/connect.run", nil), testRun, ) + if err != nil { + panic(err) + } - h.Register(f) - - conn, err := h.Connect(ctx, inngestgo.ConnectOpts{ + conn, err := c.Connect(ctx, inngestgo.ConnectOpts{ InstanceID: inngestgo.Ptr("example-worker"), }) defer func(conn connect.WorkerConnection) { diff --git a/examples/http/main.go b/examples/http/main.go index 2140ba13..207fe562 100644 --- a/examples/http/main.go +++ b/examples/http/main.go @@ -14,11 +14,17 @@ import ( ) func main() { - h := inngestgo.NewHandler("billing", inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: "billing", + }) + if err != nil { + panic(err) + } // CreateFunction is a factory method which creates new Inngest functions (step functions, // or workflows) with a specific configuration. - f := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "account-created", Name: "Account creation flow", @@ -29,12 +35,12 @@ func main() { // The function to run. AccountCreated, ) - - // Register the functions with your app/service. - h.Register(f) + if err != nil { + panic(err) + } // And serve the functions from an HTTP handler. - _ = http.ListenAndServe(":8080", h) + _ = http.ListenAndServe(":8080", c.Serve()) } // AccountCreated is a durable function which runs any time the "api/account.created" diff --git a/funcs.go b/funcs.go index e2f6b3ad..4a76a637 100644 --- a/funcs.go +++ b/funcs.go @@ -2,6 +2,8 @@ package inngestgo import ( "context" + "errors" + "fmt" "reflect" "time" @@ -9,6 +11,13 @@ import ( "github.com/inngest/inngest/pkg/inngest" ) +// Slugify converts a string to a slug. This is only useful for replicating the +// legacy slugification logic for function IDs, aiding in migration to a newer +// SDK version. +func Slugify(s string) string { + return slug.Make(s) +} + // Ptr converts the given type to a pointer. Nil pointers are sometimes // used for optional arguments within configuration, meaning we need pointers // within struct values. This util helps. @@ -47,6 +56,14 @@ type FunctionOpts struct { BatchEvents *inngest.EventBatchConfig } +func (f FunctionOpts) validate() error { + var err error + if f.ID == "" { + err = errors.Join(err, errors.New("id is required")) + } + return err +} + // GetRateLimit returns the inngest.RateLimit for function configuration. The // SDK's RateLimit type is incompatible with the inngest.RateLimit type signature // for ease of definition. @@ -181,16 +198,23 @@ func (t Timeouts) Convert() *inngest.Timeouts { // }, // ) func CreateFunction[T any]( + c Client, fc FunctionOpts, trigger inngest.Trigger, f SDKFunction[T], -) ServableFunction { +) (ServableFunction, error) { // Validate that the input type is a concrete type, and not an interface. // // The only exception is `any`, when users don't care about the input event // eg. for cron based functions. + err := fc.validate() + if err != nil { + return nil, err + } + sf := servableFunc{ + appID: c.AppID(), fc: fc, trigger: trigger, f: f, @@ -198,9 +222,16 @@ func CreateFunction[T any]( zt := sf.ZeroType() if zt.Interface() == nil && zt.NumMethod() > 0 { - panic("You cannot use an interface type as the input within an Inngest function.") + return nil, errors.New("You cannot use an interface type as the input within an Inngest function.") + } + + // TODO: This feels wrong but is necessary since there isn't a + // function-adding method on the client interface. + if v, ok := c.(*apiClient); ok { + v.h.Register(sf) } - return sf + + return sf, nil } func EventTrigger(name string, expression *string) inngest.Trigger { @@ -237,8 +268,9 @@ type SDKFunction[T any] func(ctx context.Context, input Input[T]) (any, error) // // This is created via CreateFunction in this package. type ServableFunction interface { - // Slug returns the function's human-readable ID, such as "sign-up-flow". - Slug(appName string) string + FullyQualifiedID() string + + ID() string // Name returns the function name. Name() string @@ -275,6 +307,7 @@ type InputCtx struct { } type servableFunc struct { + appID string fc FunctionOpts trigger inngest.Trigger f any @@ -284,22 +317,18 @@ func (s servableFunc) Config() FunctionOpts { return s.fc } -func (s servableFunc) Slug(appName string) string { - fnSlug := s.fc.ID - if fnSlug == "" { - fnSlug = slug.Make(s.fc.Name) - } - - // Old format which only includes the fn slug - // This should no longer be used. - if appName == "" { - return fnSlug - } +func (s servableFunc) ID() string { + return s.fc.ID +} - return appName + "-" + fnSlug +func (s servableFunc) FullyQualifiedID() string { + return fmt.Sprintf("%s-%s", s.appID, s.ID()) } func (s servableFunc) Name() string { + if s.fc.Name == "" { + return s.ID() + } return s.fc.Name } diff --git a/handler.go b/handler.go index 2cbb07f9..0975e5cd 100644 --- a/handler.go +++ b/handler.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/inngest/inngestgo/connect" "io" "log/slog" "net/http" @@ -29,15 +28,9 @@ import ( "github.com/inngest/inngestgo/step" ) -var ( - // DefaultHandler provides a default handler for registering and serving functions - // globally. - // - // It's recommended to call SetOptions() to set configuration before serving - // this in production environments; this is set up for development and will - // attempt to connect to the dev server. - DefaultHandler Handler = NewHandler("Go app", HandlerOpts{}) +type clientCtxKeyType struct{} +var ( ErrTypeMismatch = fmt.Errorf("cannot invoke function with mismatched types") errBadRequest = fmt.Errorf("bad request") @@ -53,24 +46,11 @@ var ( TrustProbe: sdk.TrustProbeV1, Connect: sdk.ConnectV1, } -) - -// Register adds the given functions to the default handler for serving. You must register all -// functions with a handler prior to serving the handler for them to be enabled. -func Register(funcs ...ServableFunction) { - DefaultHandler.Register(funcs...) -} -// Serve serves all registered functions within the default handler. -func Serve(w http.ResponseWriter, r *http.Request) { - DefaultHandler.ServeHTTP(w, r) -} - -func Connect(ctx context.Context, opts ConnectOpts) (connect.WorkerConnection, error) { - return DefaultHandler.Connect(ctx, opts) -} + clientCtxKey = clientCtxKeyType{} +) -type HandlerOpts struct { +type handlerOpts struct { // Logger is the structured logger to use from Go's builtin structured // logging package. Logger *slog.Logger @@ -132,12 +112,12 @@ type HandlerOpts struct { Dev *bool } -// GetSigningKey returns the signing key defined within HandlerOpts, or the default +// GetSigningKey returns the signing key defined within handlerOpts, or the default // defined within INNGEST_SIGNING_KEY. // // This is the private key used to register functions and communicate with the private // API. -func (h HandlerOpts) GetSigningKey() string { +func (h handlerOpts) GetSigningKey() string { if h.SigningKey == nil { return os.Getenv("INNGEST_SIGNING_KEY") } @@ -145,12 +125,12 @@ func (h HandlerOpts) GetSigningKey() string { } // GetSigningKeyFallback returns the signing key fallback defined within -// HandlerOpts, or the default defined within INNGEST_SIGNING_KEY_FALLBACK. +// handlerOpts, or the default defined within INNGEST_SIGNING_KEY_FALLBACK. // // This is the fallback private key used to register functions and communicate // with the private API. If a request fails auth with the signing key then we'll // try again with the fallback -func (h HandlerOpts) GetSigningKeyFallback() string { +func (h handlerOpts) GetSigningKeyFallback() string { if h.SigningKeyFallback == nil { return os.Getenv("INNGEST_SIGNING_KEY_FALLBACK") } @@ -158,7 +138,7 @@ func (h HandlerOpts) GetSigningKeyFallback() string { } // GetAPIOrigin returns the host to use for sending API requests -func (h HandlerOpts) GetAPIBaseURL() string { +func (h handlerOpts) GetAPIBaseURL() string { if h.isDev() { return DevServerURL() } @@ -176,7 +156,7 @@ func (h HandlerOpts) GetAPIBaseURL() string { } // GetEventAPIOrigin returns the host to use for sending events -func (h HandlerOpts) GetEventAPIBaseURL() string { +func (h handlerOpts) GetEventAPIBaseURL() string { if h.isDev() { return DevServerURL() } @@ -193,7 +173,7 @@ func (h HandlerOpts) GetEventAPIBaseURL() string { } // GetServeOrigin returns the host used for HTTP based executions -func (h HandlerOpts) GetServeOrigin() string { +func (h handlerOpts) GetServeOrigin() string { if h.ServeOrigin != nil { return *h.ServeOrigin } @@ -201,34 +181,34 @@ func (h HandlerOpts) GetServeOrigin() string { } // GetServePath returns the path used for HTTP based executions -func (h HandlerOpts) GetServePath() string { +func (h handlerOpts) GetServePath() string { if h.ServePath != nil { return *h.ServePath } return "" } -// GetEnv returns the env defined within HandlerOpts, or the default +// GetEnv returns the env defined within handlerOpts, or the default // defined within INNGEST_ENV. // // This is the environment name used for preview/branch environments within Inngest. -func (h HandlerOpts) GetEnv() string { +func (h handlerOpts) GetEnv() string { if h.Env == nil { return os.Getenv("INNGEST_ENV") } return *h.Env } -// GetRegisterURL returns the registration URL defined wtihin HandlerOpts, +// GetRegisterURL returns the registration URL defined wtihin handlerOpts, // defaulting to the production Inngest URL if nil. -func (h HandlerOpts) GetRegisterURL() string { +func (h handlerOpts) GetRegisterURL() string { if h.RegisterURL == nil { return "https://www.inngest.com/fn/register" } return *h.RegisterURL } -func (h HandlerOpts) IsInBandSyncAllowed() bool { +func (h handlerOpts) IsInBandSyncAllowed() bool { if h.AllowInBandSync != nil { return *h.AllowInBandSync } @@ -241,7 +221,7 @@ func (h HandlerOpts) IsInBandSyncAllowed() bool { return false } -func (h HandlerOpts) isDev() bool { +func (h handlerOpts) isDev() bool { if h.Dev != nil { return *h.Dev } @@ -252,26 +232,26 @@ func (h HandlerOpts) isDev() bool { // Handler represents a handler which serves the Inngest API via HTTP. This provides // function registration to Inngest, plus the invocation of registered functions via // an HTTP POST. -type Handler interface { - http.Handler +// type Handler interface { +// http.Handler - // SetAppName updates the handler's app name. This is used to group functions - // and track deploys within the UI. - SetAppName(name string) Handler +// // SetAppName updates the handler's app name. This is used to group functions +// // and track deploys within the UI. +// SetAppName(name string) Handler - // SetOptions sets the handler's options used to register functions. - SetOptions(h HandlerOpts) Handler +// // SetOptions sets the handler's options used to register functions. +// SetOptions(h handlerOpts) Handler - // Register registers the given functions with the handler, allowing them to - // be invoked by Inngest. - Register(...ServableFunction) +// // Register registers the given functions with the handler, allowing them to +// // be invoked by Inngest. +// Register(...ServableFunction) - // Connect establishes an outbound connection to Inngest - Connect(ctx context.Context, opts ConnectOpts) (connect.WorkerConnection, error) -} +// // Connect establishes an outbound connection to Inngest +// Connect(ctx context.Context, opts ConnectOpts) (connect.WorkerConnection, error) +// } -// NewHandler returns a new Handler for serving Inngest functions. -func NewHandler(appName string, opts HandlerOpts) Handler { +// newHandler returns a new Handler for serving Inngest functions. +func newHandler(c Client, opts handlerOpts) *handler { if opts.Logger == nil { opts.Logger = slog.Default() } @@ -281,23 +261,25 @@ func NewHandler(appName string, opts HandlerOpts) Handler { } return &handler{ - HandlerOpts: opts, - appName: appName, + handlerOpts: opts, + appName: c.AppID(), + client: c, funcs: []ServableFunction{}, } } type handler struct { - HandlerOpts + handlerOpts appName string + client Client funcs []ServableFunction // lock prevents reading the function maps while serving l sync.RWMutex } -func (h *handler) SetOptions(opts HandlerOpts) Handler { - h.HandlerOpts = opts +func (h *handler) SetOptions(opts handlerOpts) *handler { + h.handlerOpts = opts if opts.MaxBodySize == 0 { opts.MaxBodySize = DefaultMaxBodySize @@ -309,7 +291,7 @@ func (h *handler) SetOptions(opts HandlerOpts) Handler { return h } -func (h *handler) SetAppName(name string) Handler { +func (h *handler) SetAppName(name string) *handler { h.appName = name return h } @@ -322,11 +304,11 @@ func (h *handler) Register(funcs ...ServableFunction) { // that already exists, clear it. slugs := map[string]ServableFunction{} for _, f := range h.funcs { - slugs[f.Slug(h.appName)] = f + slugs[f.FullyQualifiedID()] = f } for _, f := range funcs { - slugs[f.Slug(h.appName)] = f + slugs[f.FullyQualifiedID()] = f } newFuncs := make([]ServableFunction, len(slugs)) @@ -484,7 +466,7 @@ func (h *handler) inBandSync( } } - max := h.HandlerOpts.MaxBodySize + max := h.handlerOpts.MaxBodySize if max == 0 { max = DefaultMaxBodySize } @@ -752,13 +734,13 @@ func createFunctionConfigs( // Modify URL to contain fn ID, step params values := appURL.Query() - values.Set("fnId", fn.Slug(appName)) // This should match the Slug below + values.Set("fnId", fn.FullyQualifiedID()) // This should match the Slug below values.Set("step", "step") appURL.RawQuery = values.Encode() f := sdk.SDKFunction{ Name: fn.Name(), - Slug: fn.Slug(appName), + Slug: fn.FullyQualifiedID(), Idempotency: c.Idempotency, Priority: fn.Config().Priority, Triggers: inngest.MultipleTriggers{}, @@ -838,7 +820,7 @@ func (h *handler) invoke(w http.ResponseWriter, r *http.Request) error { } } - max := h.HandlerOpts.MaxBodySize + max := h.handlerOpts.MaxBodySize if max == 0 { max = DefaultMaxBodySize } @@ -879,8 +861,8 @@ func (h *handler) invoke(w http.ResponseWriter, r *http.Request) error { h.l.RLock() var fn ServableFunction for _, f := range h.funcs { - isOldFormat := f.Slug("") == fnID // Only include function slug - if f.Slug(h.appName) == fnID || isOldFormat { + isOldFormat := f.ID() == fnID // Only include function slug + if f.FullyQualifiedID() == fnID || isOldFormat { fn = f break } @@ -913,8 +895,10 @@ func (h *handler) invoke(w http.ResponseWriter, r *http.Request) error { stepID = &rawStepID } + ctx := context.WithValue(r.Context(), clientCtxKey, h.client) + // Invoke the function, then immediately stop the streaming buffer. - resp, ops, err := invoke(r.Context(), fn, request, stepID) + resp, ops, err := invoke(ctx, fn, request, stepID) streamCancel() // NOTE: When triggering step errors, we should have an OpcodeStepError @@ -1174,7 +1158,7 @@ func (h *handler) trust( } } - max := h.HandlerOpts.MaxBodySize + max := h.handlerOpts.MaxBodySize if max == 0 { max = DefaultMaxBodySize } diff --git a/handler_test.go b/handler_test.go index eb506b20..3eab8f45 100644 --- a/handler_test.go +++ b/handler_test.go @@ -42,41 +42,53 @@ type EventB struct{} type EventC struct{} func TestRegister(t *testing.T) { + r := require.New(t) setEnvVars(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) - a := CreateFunction( + _, err = CreateFunction( + c, FunctionOpts{ - Name: "my func name", + ID: "my-func-name", }, EventTrigger("test/event.a", nil), func(ctx context.Context, input Input[EventA]) (any, error) { return nil, nil }, ) - b := CreateFunction( - FunctionOpts{Name: "another func"}, + r.NoError(err) + + _, err = CreateFunction( + c, + FunctionOpts{ID: "another-func"}, EventTrigger("test/event.b", nil), func(ctx context.Context, input Input[EventB]) (any, error) { return nil, nil }, ) - c := CreateFunction( - FunctionOpts{Name: "batch func", BatchEvents: &inngest.EventBatchConfig{MaxSize: 20, Timeout: "10s"}}, + r.NoError(err) + + _, err = CreateFunction( + c, + FunctionOpts{ID: "batch-func", BatchEvents: &inngest.EventBatchConfig{MaxSize: 20, Timeout: "10s"}}, EventTrigger("test/batch.a", nil), func(ctx context.Context, input Input[EventC]) (any, error) { return nil, nil }, ) - - Register(a, b, c) + r.NoError(err) } // TestInvoke asserts that invoking a function with both the correct and incorrect type // works as expected. func TestInvoke(t *testing.T) { - t.Run("With a struct value event type", func(t *testing.T) { ctx := context.Background() + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) + input := EventA{ Name: "test/event.a", Data: struct { @@ -90,15 +102,16 @@ func TestInvoke(t *testing.T) { resp := map[string]any{ "test": true, } - a := CreateFunction( - FunctionOpts{Name: "my func name"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-func-name"}, EventTrigger("test/event.a", nil), func(ctx context.Context, event Input[EventA]) (any, error) { require.EqualValues(t, event.Event, input) return resp, nil }, ) - Register(a) + r.NoError(err) t.Run("it invokes the function with correct types", func(t *testing.T) { actual, op, err := invoke(ctx, a, createRequest(t, input), nil) @@ -110,6 +123,9 @@ func TestInvoke(t *testing.T) { t.Run("With a struct value event type batch", func(t *testing.T) { ctx := context.Background() + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) input := EventA{ Name: "test/event.a", Data: struct { @@ -123,8 +139,9 @@ func TestInvoke(t *testing.T) { resp := map[string]any{ "test": true, } - a := CreateFunction( - FunctionOpts{Name: "my func name", BatchEvents: &inngest.EventBatchConfig{MaxSize: 5, Timeout: "10s"}}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-func-name", BatchEvents: &inngest.EventBatchConfig{MaxSize: 5, Timeout: "10s"}}, EventTrigger("test/event.a", nil), func(ctx context.Context, event Input[EventA]) (any, error) { require.EqualValues(t, event.Event, input) @@ -132,7 +149,7 @@ func TestInvoke(t *testing.T) { return resp, nil }, ) - Register(a) + r.NoError(err) t.Run("it invokes the function with correct types", func(t *testing.T) { actual, op, err := invoke(ctx, a, createBatchRequest(t, input, 5), nil) @@ -143,6 +160,9 @@ func TestInvoke(t *testing.T) { }) t.Run("With a struct ptr event type", func(t *testing.T) { + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) input := EventA{ Name: "test/event.a", Data: struct { @@ -156,8 +176,9 @@ func TestInvoke(t *testing.T) { resp := map[string]any{ "test": true, } - a := CreateFunction( - FunctionOpts{Name: "my func name"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-func-name"}, EventTrigger("test/event.a", nil), func(ctx context.Context, event Input[*EventA]) (any, error) { require.NotNil(t, event.Event) @@ -165,7 +186,7 @@ func TestInvoke(t *testing.T) { return resp, nil }, ) - Register(a) + r.NoError(err) ctx := context.Background() @@ -178,6 +199,9 @@ func TestInvoke(t *testing.T) { }) t.Run("With Input[any] as a function type", func(t *testing.T) { + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) resp := map[string]any{"test": true} input := EventA{ Name: "test/event.a", @@ -189,8 +213,9 @@ func TestInvoke(t *testing.T) { Bar: "squished", }, } - a := CreateFunction( - FunctionOpts{Name: "my func name"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-func-name"}, EventTrigger("test/event.a", nil), func(ctx context.Context, event Input[any]) (any, error) { require.NotNil(t, event.Event) @@ -204,7 +229,7 @@ func TestInvoke(t *testing.T) { return resp, nil }, ) - Register(a) + r.NoError(err) ctx := context.Background() t.Run("it invokes the function with correct types", func(t *testing.T) { @@ -216,6 +241,9 @@ func TestInvoke(t *testing.T) { }) t.Run("With Input[map[string]any] as a function type", func(t *testing.T) { + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) resp := map[string]any{"test": true} input := EventA{ Name: "test/event.a", @@ -227,8 +255,9 @@ func TestInvoke(t *testing.T) { Bar: "squished", }, } - a := CreateFunction( - FunctionOpts{Name: "my func name"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-func-name"}, EventTrigger("test/event.a", nil), func(ctx context.Context, event Input[map[string]any]) (any, error) { require.NotNil(t, event.Event) @@ -241,7 +270,7 @@ func TestInvoke(t *testing.T) { return resp, nil }, ) - Register(a) + r.NoError(err) ctx := context.Background() t.Run("it invokes the function with correct types", func(t *testing.T) { @@ -255,32 +284,39 @@ func TestInvoke(t *testing.T) { // This is silly and no one should ever do this. The tests are here // so that we ensure the code panics on creation. t.Run("With an io.Reader as a function type", func(t *testing.T) { - require.Panics(t, func() { - // Creating a function with an interface is impossible. This can - // never go into production, and you should always be testing this - // before deploying to Inngest. - CreateFunction( - FunctionOpts{Name: "my func name"}, - EventTrigger("test/event.a", nil), - func(ctx context.Context, event Input[io.Reader]) (any, error) { - return nil, nil - }, - ) - }) + // Creating a function with an interface is impossible. This can + // never go into production, and you should always be testing this + // before deploying to Inngest. + + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) + _, err = CreateFunction( + c, + FunctionOpts{ID: "my-func-name"}, + EventTrigger("test/event.a", nil), + func(ctx context.Context, event Input[io.Reader]) (any, error) { + return nil, nil + }, + ) + r.Error(err) }) t.Run("captures panic stack", func(t *testing.T) { ctx := context.Background() r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "inspection"}) + r.NoError(err) - a := CreateFunction( - FunctionOpts{Name: "my-fn"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-fn"}, EventTrigger("my-event", nil), func(ctx context.Context, event Input[any]) (any, error) { panic("oh no!") }, ) - Register(a) + r.NoError(err) actual, op, err := invoke( ctx, a, @@ -301,6 +337,9 @@ func TestInvoke(t *testing.T) { func TestServe(t *testing.T) { setEnvVars(t) + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "my-app"}) + r.NoError(err) event := EventA{ Name: "test/event.a", @@ -316,8 +355,9 @@ func TestServe(t *testing.T) { result := map[string]any{"result": true} var called int32 - a := CreateFunction( - FunctionOpts{Name: "My servable function!"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "my-servable-function"}, EventTrigger("test/event.a", nil), func(ctx context.Context, input Input[EventA]) (any, error) { atomic.AddInt32(&called, 1) @@ -325,8 +365,8 @@ func TestServe(t *testing.T) { return result, nil }, ) - Register(a) - server := httptest.NewServer(DefaultHandler) + r.NoError(err) + server := httptest.NewServer(c.Serve()) byt, err := json.Marshal(map[string]any{ "event": event, "ctx": map[string]any{ @@ -338,10 +378,8 @@ func TestServe(t *testing.T) { t.Run("It calls the correct function with the correct data", func(t *testing.T) { queryParams := url.Values{} - appName := "Go app" - DefaultHandler.SetAppName(appName) - queryParams.Add("fnId", a.Slug(appName)) + queryParams.Add("fnId", a.FullyQualifiedID()) url := fmt.Sprintf("%s?%s", server.URL, queryParams.Encode()) resp := handlerPost(t, url, createRequest(t, event)) @@ -372,6 +410,9 @@ func TestServe(t *testing.T) { func TestSteps(t *testing.T) { setEnvVars(t) + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "my-app"}) + r.NoError(err) event := EventA{ Name: "test/event.a", @@ -386,8 +427,9 @@ func TestSteps(t *testing.T) { var fnCt, aCt, bCt int32 - a := CreateFunction( - FunctionOpts{Name: "step function"}, + a, err := CreateFunction( + c, + FunctionOpts{ID: "step-function"}, EventTrigger("test/event.a", nil), func(ctx context.Context, input Input[EventA]) (any, error) { atomic.AddInt32(&fnCt, 1) @@ -408,14 +450,12 @@ func TestSteps(t *testing.T) { return stepB, nil }, ) + r.NoError(err) - Register(a) - server := httptest.NewServer(DefaultHandler) - appName := "Go app" - DefaultHandler.SetAppName(appName) + server := httptest.NewServer(c.Serve()) queryParams := url.Values{} - queryParams.Add("fnId", a.Slug(appName)) + queryParams.Add("fnId", a.FullyQualifiedID()) url := fmt.Sprintf("%s?%s", server.URL, queryParams.Encode()) t.Run("It invokes the first step and returns an opcode", func(t *testing.T) { @@ -496,16 +536,23 @@ func TestInspection(t *testing.T) { setEnvVars(t) t.Run("dev mode", func(t *testing.T) { - fn := CreateFunction( - FunctionOpts{Name: "My servable function!"}, + r := require.New(t) + c, err := NewClient(ClientOpts{ + AppID: "inspection", + Dev: BoolPtr(false), + }) + r.NoError(err) + _, err = CreateFunction( + c, + FunctionOpts{ID: "my-servable-function"}, EventTrigger("test/event.a", nil), func(ctx context.Context, input Input[any]) (any, error) { return nil, nil }, ) - h := NewHandler("inspection", HandlerOpts{Dev: BoolPtr(false)}) - h.Register(fn) - server := httptest.NewServer(h) + r.NoError(err) + + server := httptest.NewServer(c.Serve()) defer server.Close() t.Run("no signature", func(t *testing.T) { @@ -620,16 +667,22 @@ func TestInspection(t *testing.T) { }) t.Run("cloud mode", func(t *testing.T) { - fn := CreateFunction( - FunctionOpts{Name: "My servable function!"}, + r := require.New(t) + c, err := NewClient(ClientOpts{ + AppID: "inspection", + Dev: BoolPtr(false), + }) + r.NoError(err) + _, err = CreateFunction( + c, + FunctionOpts{ID: "my-servable-function"}, EventTrigger("test/event.a", nil), func(ctx context.Context, input Input[any]) (any, error) { return nil, nil }, ) - h := NewHandler("inspection", HandlerOpts{Dev: BoolPtr(false)}) - h.Register(fn) - server := httptest.NewServer(h) + r.NoError(err) + server := httptest.NewServer(c.Serve()) defer server.Close() t.Run("no signature", func(t *testing.T) { @@ -746,16 +799,20 @@ func TestInspection(t *testing.T) { func TestInBandSync(t *testing.T) { setEnvVars(t) - appID := "test-in-band-sync" + r := require.New(t) + c, err := NewClient(ClientOpts{AppID: "test-in-band-sync"}) + r.NoError(err) - fn := CreateFunction( - FunctionOpts{Name: "my-fn"}, + fn, err := CreateFunction( + c, + FunctionOpts{ID: "my-fn"}, EventTrigger("my-event", nil), func(ctx context.Context, input Input[any]) (any, error) { return nil, nil }, ) - h := NewHandler(appID, HandlerOpts{ + r.NoError(err) + h := newHandler(c, handlerOpts{ AllowInBandSync: toPtr(true), Env: toPtr("my-env"), }) @@ -794,17 +851,17 @@ func TestInBandSync(t *testing.T) { r.Equal( inBandSynchronizeResponse{ - AppID: appID, + AppID: c.AppID(), Env: toPtr("my-env"), Functions: []sdk.SDKFunction{{ Name: "my-fn", - Slug: fmt.Sprintf("%s-my-fn", appID), + Slug: fmt.Sprintf("%s-my-fn", c.AppID()), Steps: map[string]sdk.SDKStep{ "step": { ID: "step", Name: "my-fn", Runtime: map[string]any{ - "url": fmt.Sprintf("http://test.local?fnId=%s-my-fn&step=step", appID), + "url": fmt.Sprintf("http://test.local?fnId=%s-my-fn&step=step", c.AppID()), }, }, }, @@ -918,15 +975,16 @@ func TestInBandSync(t *testing.T) { })) defer mockCloud.Close() - appID := "test-in-band-sync-missing-header" - fn := CreateFunction( - FunctionOpts{Name: "my-fn"}, + fn, err := CreateFunction( + c, + FunctionOpts{ID: "my-fn"}, EventTrigger("my-event", nil), func(ctx context.Context, input Input[any]) (any, error) { return nil, nil }, ) - h := NewHandler(appID, HandlerOpts{ + r.NoError(err) + h := newHandler(c, handlerOpts{ Env: toPtr("my-env"), RegisterURL: &mockCloud.URL, }) diff --git a/tests/invoke_test.go b/tests/invoke_test.go index e6c2ea34..68e4d97c 100644 --- a/tests/invoke_test.go +++ b/tests/invoke_test.go @@ -24,14 +24,17 @@ func TestInvoke(t *testing.T) { r := require.New(t) appName := randomSuffix("my-app") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) + // h := inngestgo.newHandler(c, inngestgo.handlerOpts{}) type ChildEventData struct { Message string `json:"message"` } childFnName := "my-child-fn" - childFn := inngestgo.CreateFunction( + childFn, err := inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: childFnName, Name: childFnName, @@ -45,12 +48,14 @@ func TestInvoke(t *testing.T) { return input.Event.Data.Message, nil }, ) + r.NoError(err) var runID string var invokeResult any var invokeErr error eventName := randomSuffix("my-event") - parentFn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-parent-fn", Name: "my-parent-fn", @@ -63,20 +68,19 @@ func TestInvoke(t *testing.T) { "invoke", step.InvokeOpts{ Data: map[string]any{"message": "hello"}, - FunctionId: fmt.Sprintf("%s-%s", appName, childFnName), + FunctionId: childFn.FullyQualifiedID(), }, ) return invokeResult, invokeErr }, ) + r.NoError(err) - h.Register(childFn, parentFn) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) @@ -104,10 +108,12 @@ func TestInvoke(t *testing.T) { r := require.New(t) appName := randomSuffix("my-app") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) childFnName := "my-child-fn" - childFn := inngestgo.CreateFunction( + childFn, err := inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: childFnName, Name: childFnName, @@ -121,12 +127,13 @@ func TestInvoke(t *testing.T) { return nil, fmt.Errorf("oh no") }, ) - + r.NoError(err) var runID string var invokeResult any var invokeErr error eventName := randomSuffix("my-event") - parentFn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-parent-fn", Name: "my-parent-fn", @@ -138,20 +145,19 @@ func TestInvoke(t *testing.T) { invokeResult, invokeErr = step.Invoke[any](ctx, "invoke", step.InvokeOpts{ - FunctionId: fmt.Sprintf("%s-%s", appName, childFnName), + FunctionId: childFn.FullyQualifiedID(), }, ) return invokeResult, invokeErr }, ) + r.NoError(err) - h.Register(childFn, parentFn) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) @@ -184,13 +190,15 @@ func TestInvoke(t *testing.T) { r := require.New(t) appName := randomSuffix("my-app") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) var runID string var invokeResult any var invokeErr error eventName := randomSuffix("my-event") - fn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-fn", Name: "my-fn", @@ -206,14 +214,13 @@ func TestInvoke(t *testing.T) { return invokeResult, invokeErr }, ) + r.NoError(err) - h.Register(fn) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) @@ -249,11 +256,13 @@ func TestInvoke(t *testing.T) { ctx := context.Background() r := require.New(t) appName := randomSuffix("my-app") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) var childCounter int32 childFnName := "my-child-fn" - childFn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: childFnName, Name: childFnName, @@ -268,11 +277,13 @@ func TestInvoke(t *testing.T) { return nil, fmt.Errorf("oh no") }, ) + r.NoError(err) var runID string var invokeErr error eventName := randomSuffix("my-event") - parentFn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-parent-fn", Name: "my-parent-fn", @@ -295,14 +306,13 @@ func TestInvoke(t *testing.T) { return nil, nil }, ) + r.NoError(err) - h.Register(childFn, parentFn) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) @@ -329,11 +339,13 @@ func TestInvoke(t *testing.T) { ctx := context.Background() r := require.New(t) appName := randomSuffix("my-app") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) var childCounter int32 childFnName := "my-child-fn" - childFn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: childFnName, Name: childFnName, @@ -348,11 +360,12 @@ func TestInvoke(t *testing.T) { return nil, fmt.Errorf("oh no") }, ) - + r.NoError(err) var runID string var attempt int eventName := randomSuffix("my-event") - parentFn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-parent-fn", Name: "my-parent-fn", @@ -373,14 +386,13 @@ func TestInvoke(t *testing.T) { ) }, ) + r.NoError(err) - h.Register(childFn, parentFn) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) diff --git a/tests/main_test.go b/tests/main_test.go index 01f90018..6c310b71 100644 --- a/tests/main_test.go +++ b/tests/main_test.go @@ -8,8 +8,6 @@ import ( "syscall" "testing" "time" - - "github.com/inngest/inngestgo" ) func TestMain(m *testing.M) { @@ -33,12 +31,6 @@ func TestMain(m *testing.M) { func setup() (func() error, error) { os.Setenv("INNGEST_DEV", "1") - inngestgo.DefaultClient = inngestgo.NewClient( - inngestgo.ClientOpts{ - EventKey: inngestgo.StrPtr("dev"), - }, - ) - if os.Getenv("DEV_SERVER_ENABLED") == "0" { // Don't start the Dev Server. return func() error { return nil }, nil diff --git a/tests/parallel_test.go b/tests/parallel_test.go index e30614b9..ca91a78a 100644 --- a/tests/parallel_test.go +++ b/tests/parallel_test.go @@ -30,9 +30,11 @@ func TestParallel(t *testing.T) { }{} appName := randomSuffix("TestParallel") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) - fn1 := inngestgo.CreateFunction( + fn1, err := inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-fn-1", Name: "my-fn-1", @@ -43,9 +45,11 @@ func TestParallel(t *testing.T) { return "invoked output", nil }, ) + r.NoError(err) eventName := randomSuffix("my-event") - fn2 := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-fn-2", Name: "my-fn-2", @@ -94,14 +98,13 @@ func TestParallel(t *testing.T) { return nil, nil }, ) + r.NoError(err) - h.Register(fn1, fn2) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) @@ -127,11 +130,13 @@ func TestParallel(t *testing.T) { r := require.New(t) appName := randomSuffix("TestParallel") - h := inngestgo.NewHandler(appName, inngestgo.HandlerOpts{}) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{AppID: appName}) + r.NoError(err) var runID string eventName := randomSuffix("my-event") - fn := inngestgo.CreateFunction( + _, err = inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-fn", Name: "my-fn", @@ -158,14 +163,13 @@ func TestParallel(t *testing.T) { return nil, nil }, ) + r.NoError(err) - h.Register(fn) - - server, sync := serve(t, h) + server, sync := serve(t, c) defer server.Close() r.NoError(sync()) - _, err := inngestgo.Send(ctx, inngestgo.Event{ + _, err = c.Send(ctx, inngestgo.Event{ Name: eventName, Data: map[string]any{"foo": "bar"}}, ) diff --git a/tests/probe_test.go b/tests/probe_test.go index 1ed20265..ccf11dd6 100644 --- a/tests/probe_test.go +++ b/tests/probe_test.go @@ -24,7 +24,13 @@ func TestTrustProbe(t *testing.T) { ctx := context.Background() appName := randomSuffix("TestTrustProbe") - server := createApp(t, appName, isDev) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: appName, + Dev: inngestgo.BoolPtr(isDev), + SigningKey: inngestgo.StrPtr(sKey), + }) + r.NoError(err) + server := createApp(t, c) defer server.Close() appURL := fmt.Sprintf("%s?probe=trust", server.URL) @@ -44,7 +50,13 @@ func TestTrustProbe(t *testing.T) { r := require.New(t) appName := randomSuffix("TestTrustProbe") - server := createApp(t, appName, isDev) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: appName, + Dev: inngestgo.BoolPtr(isDev), + SigningKey: inngestgo.StrPtr(sKey), + }) + r.NoError(err) + server := createApp(t, c) defer server.Close() appURL := fmt.Sprintf("%s?probe=trust", server.URL) @@ -61,7 +73,13 @@ func TestTrustProbe(t *testing.T) { ctx := context.Background() appName := randomSuffix("TestTrustProbe") - server := createApp(t, appName, isDev) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: appName, + Dev: inngestgo.BoolPtr(isDev), + SigningKey: inngestgo.StrPtr(sKey), + }) + r.NoError(err) + server := createApp(t, c) defer server.Close() appURL := fmt.Sprintf("%s?probe=trust", server.URL) @@ -87,7 +105,13 @@ func TestTrustProbe(t *testing.T) { ctx := context.Background() appName := randomSuffix("TestTrustProbe") - server := createApp(t, appName, isDev) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: appName, + Dev: inngestgo.BoolPtr(isDev), + SigningKey: inngestgo.StrPtr(sKey), + }) + r.NoError(err) + server := createApp(t, c) defer server.Close() appURL := fmt.Sprintf("%s?probe=trust", server.URL) @@ -124,7 +148,13 @@ func TestTrustProbe(t *testing.T) { r := require.New(t) appName := randomSuffix("TestTrustProbe") - server := createApp(t, appName, isDev) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: appName, + Dev: inngestgo.BoolPtr(isDev), + SigningKey: inngestgo.StrPtr(sKey), + }) + r.NoError(err) + server := createApp(t, c) defer server.Close() appURL := fmt.Sprintf("%s?probe=trust", server.URL) @@ -141,7 +171,13 @@ func TestTrustProbe(t *testing.T) { ctx := context.Background() appName := randomSuffix("TestTrustProbe") - server := createApp(t, appName, isDev) + c, err := inngestgo.NewClient(inngestgo.ClientOpts{ + AppID: appName, + Dev: inngestgo.BoolPtr(isDev), + SigningKey: inngestgo.StrPtr(sKey), + }) + r.NoError(err) + server := createApp(t, c) defer server.Close() appURL := fmt.Sprintf("%s?probe=trust", server.URL) @@ -160,15 +196,10 @@ func TestTrustProbe(t *testing.T) { }) } -func createApp(t *testing.T, appName string, isDev bool) *httptest.Server { - h := inngestgo.NewHandler( - appName, - inngestgo.HandlerOpts{ - Dev: inngestgo.BoolPtr(isDev), - SigningKey: inngestgo.StrPtr(sKey), - }, - ) - h.Register(inngestgo.CreateFunction( +func createApp(t *testing.T, c inngestgo.Client) *httptest.Server { + r := require.New(t) + _, err := inngestgo.CreateFunction( + c, inngestgo.FunctionOpts{ ID: "my-fn", Name: "my-fn", @@ -177,8 +208,8 @@ func createApp(t *testing.T, appName string, isDev bool) *httptest.Server { func(ctx context.Context, input inngestgo.Input[any]) (any, error) { return nil, nil }, - )) - - server, _ := serve(t, h) + ) + r.NoError(err) + server, _ := serve(t, c) return server } diff --git a/tests/utils.go b/tests/utils.go index 44340442..c3647a1d 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -77,8 +77,8 @@ func randomSuffix(s string) string { return s + uuid.NewString() } -func serve(t *testing.T, h inngestgo.Handler) (*httptest.Server, func() error) { - server := httptest.NewServer(h) +func serve(t *testing.T, c inngestgo.Client) (*httptest.Server, func() error) { + server := httptest.NewServer(c.Serve()) sync := func() error { t.Helper()