diff --git a/providers/livestorm/README.md b/providers/livestorm/README.md new file mode 100644 index 000000000..b0402f9f8 --- /dev/null +++ b/providers/livestorm/README.md @@ -0,0 +1,6 @@ +# Livestorm connector + +This directory contains the deep connector implementation for Livestorm. + +- `connector.go` wires the metadata provider. +- `metadata/schemas.json` contains static object metadata. \ No newline at end of file diff --git a/providers/livestorm/connector.go b/providers/livestorm/connector.go index 9469ddfa5..6e0a10861 100644 --- a/providers/livestorm/connector.go +++ b/providers/livestorm/connector.go @@ -3,9 +3,11 @@ package livestorm import ( "github.com/amp-labs/connectors/common" "github.com/amp-labs/connectors/internal/components" + "github.com/amp-labs/connectors/internal/components/deleter" "github.com/amp-labs/connectors/internal/components/operations" "github.com/amp-labs/connectors/internal/components/reader" "github.com/amp-labs/connectors/internal/components/schema" + "github.com/amp-labs/connectors/internal/components/writer" "github.com/amp-labs/connectors/providers" "github.com/amp-labs/connectors/providers/livestorm/metadata" ) @@ -16,6 +18,8 @@ type Connector struct { common.RequireAuthenticatedClient components.SchemaProvider components.Reader + components.Writer + components.Deleter } func NewConnector(params common.ConnectorParams) (*Connector, error) { @@ -41,5 +45,27 @@ func constructor(base *components.Connector) (*Connector, error) { }, ) + connector.Writer = writer.NewHTTPWriter( + connector.HTTPClient().Client, + components.NewEmptyEndpointRegistry(), + connector.ProviderContext.Module(), + operations.WriteHandlers{ + BuildRequest: connector.buildWriteRequest, + ParseResponse: connector.parseWriteResponse, + ErrorHandler: common.InterpretError, + }, + ) + + connector.Deleter = deleter.NewHTTPDeleter( + connector.HTTPClient().Client, + components.NewEmptyEndpointRegistry(), + connector.ProviderContext.Module(), + operations.DeleteHandlers{ + BuildRequest: connector.buildDeleteRequest, + ParseResponse: connector.parseDeleteResponse, + ErrorHandler: common.InterpretError, + }, + ) + return connector, nil } diff --git a/providers/livestorm/delete.go b/providers/livestorm/delete.go new file mode 100644 index 000000000..d95bb2f39 --- /dev/null +++ b/providers/livestorm/delete.go @@ -0,0 +1,49 @@ +package livestorm + +import ( + "context" + "fmt" + "net/http" + + "github.com/amp-labs/connectors/common" + "github.com/amp-labs/connectors/common/urlbuilder" + "github.com/amp-labs/connectors/internal/httpkit" +) + +// Delete an event: https://developers.livestorm.co/reference/delete_events-id +func (c *Connector) buildDeleteRequest(ctx context.Context, params common.DeleteParams) (*http.Request, error) { + if err := params.ValidateParams(); err != nil { + return nil, err + } + + if params.ObjectName != objectEvents { + return nil, common.ErrOperationNotSupportedForObject + } + + u, err := urlbuilder.New(c.ProviderInfo().BaseURL, apiVersion, objectEvents, params.RecordId) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, u.String(), nil) + if err != nil { + return nil, err + } + + req.Header.Set("Accept", jsonAPIContentType) + + return req, nil +} + +func (c *Connector) parseDeleteResponse( + _ context.Context, + _ common.DeleteParams, + _ *http.Request, + response *common.JSONHTTPResponse, +) (*common.DeleteResult, error) { + if !httpkit.Status2xx(response.Code) { + return nil, fmt.Errorf("%w: failed to delete record: %d", common.ErrRequestFailed, response.Code) + } + + return &common.DeleteResult{Success: true}, nil +} diff --git a/providers/livestorm/delete_test.go b/providers/livestorm/delete_test.go new file mode 100644 index 000000000..adedeaac3 --- /dev/null +++ b/providers/livestorm/delete_test.go @@ -0,0 +1,64 @@ +package livestorm + +import ( + "net/http" + "testing" + + "github.com/amp-labs/connectors" + "github.com/amp-labs/connectors/common" + "github.com/amp-labs/connectors/test/utils/mockutils/mockcond" + "github.com/amp-labs/connectors/test/utils/mockutils/mockserver" + "github.com/amp-labs/connectors/test/utils/testroutines" +) + +func TestDelete(t *testing.T) { + t.Parallel() + + tests := []testroutines.Delete{ + { + Name: "Object name is required", + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrMissingObjects}, + }, + { + Name: "Record id is required", + Input: common.DeleteParams{ObjectName: objectEvents}, + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrMissingRecordID}, + }, + { + Name: "Unsupported object", + Input: common.DeleteParams{ObjectName: "people", RecordId: "p1"}, + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrOperationNotSupportedForObject}, + }, + { + Name: "Delete event (204)", + Input: common.DeleteParams{ + ObjectName: objectEvents, + RecordId: "evt_del", + }, + Server: mockserver.Conditional{ + Setup: mockserver.ContentJSON(), + If: mockcond.And{ + mockcond.MethodDELETE(), + mockcond.Path("/v1/events/evt_del"), + }, + Then: mockserver.Response(http.StatusNoContent, nil), + }.Server(), + Expected: &common.DeleteResult{Success: true}, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.Name, func(t *testing.T) { + t.Parallel() + + tt.Run(t, func() (connectors.DeleteConnector, error) { + return constructTestConnector(tt.Server.URL) + }) + }) + } +} diff --git a/providers/livestorm/errors.go b/providers/livestorm/errors.go index e22e619b6..fe1203cd6 100644 --- a/providers/livestorm/errors.go +++ b/providers/livestorm/errors.go @@ -5,7 +5,4 @@ import "errors" var ( // ErrSessionIDRequired is returned when reading session_chat_messages without a session id in ReadParams.Filter. ErrSessionIDRequired = errors.New("read session_chat_messages requires a non-empty ReadParams.Filter (session id)") - - // ErrJobIDRequired is returned when reading jobs without a job id in ReadParams.Filter. - ErrJobIDRequired = errors.New("read jobs requires a non-empty ReadParams.Filter (job id)") ) diff --git a/providers/livestorm/jsonapi.go b/providers/livestorm/jsonapi.go index 31250358e..134bdc697 100644 --- a/providers/livestorm/jsonapi.go +++ b/providers/livestorm/jsonapi.go @@ -6,10 +6,8 @@ import ( ) // extractJSONAPIResourceNodes returns JSON:API primary `data` resource nodes only (no flattening). -// List endpoints use `data` as an array (the usual Read path). Livestorm also returns `data` as a -// single resource object for GET /v1/jobs/{id}; that yields one row. If Read is narrowed to -// collections-only later, drop jobs (or similar singleton reads) from read routing instead of -// changing this extractor. +// List read responses use `data` as an array of resource objects. JSON:API also allows `data` as a +// single resource object; that is normalized to a one-element slice so parsing stays spec-tolerant. func extractJSONAPIResourceNodes(root *ajson.Node) ([]*ajson.Node, error) { items, arrErr := jsonquery.New(root).ArrayOptional("data") if arrErr == nil { diff --git a/providers/livestorm/metadata/README.md b/providers/livestorm/metadata/README.md index 0ef686868..62091d67a 100644 --- a/providers/livestorm/metadata/README.md +++ b/providers/livestorm/metadata/README.md @@ -5,5 +5,6 @@ The static file `schemas.json` is embedded by `metadata.go` and defines metadata - [List events](https://developers.livestorm.co/reference/get_events) - [List people](https://developers.livestorm.co/reference/get_people) - [List people attributes](https://developers.livestorm.co/reference/get_people-attributes) -- [Get a job](https://developers.livestorm.co/reference/get_jobs-id) - [List chat messages from a session](https://developers.livestorm.co/reference/get_sessions-id-chat-messages) + +Bulk session registrants (`POST …/sessions/{id}/people/bulk`) are not exposed on Write; a future Bulk-style integration would live outside this deep connector’s write path (see Salesforce bulk-write in-repo). diff --git a/providers/livestorm/metadata/schemas.json b/providers/livestorm/metadata/schemas.json index 47fa3d51a..6b03db016 100644 --- a/providers/livestorm/metadata/schemas.json +++ b/providers/livestorm/metadata/schemas.json @@ -113,31 +113,21 @@ } } }, - "jobs": { - "displayName": "Jobs", - "path": "/jobs", + "users": { + "displayName": "Users", + "path": "/v1/users", "responseKey": "data", - "docs": "https://developers.livestorm.co/reference/get_jobs-id", + "docs": "https://developers.livestorm.co/reference/post_users", "fields": { "id": { - "displayName": "Job Id", + "displayName": "User Id", "valueType": "string", "providerType": "string" }, - "status": { - "displayName": "Status", + "email": { + "displayName": "Email", "valueType": "string", "providerType": "string" - }, - "created_at": { - "displayName": "Created At", - "valueType": "datetime", - "providerType": "datetime" - }, - "updated_at": { - "displayName": "Updated At", - "valueType": "datetime", - "providerType": "datetime" } } }, diff --git a/providers/livestorm/metadata_test.go b/providers/livestorm/metadata_test.go index 3b1fd619e..073024e4a 100644 --- a/providers/livestorm/metadata_test.go +++ b/providers/livestorm/metadata_test.go @@ -16,7 +16,7 @@ func TestListObjectMetadata(t *testing.T) { tests := []testroutines.Metadata{ { Name: "Successful metadata for events and people", - Input: []string{"events", "people", "people_attributes", "jobs", "session_chat_messages"}, + Input: []string{"events", "people", "people_attributes", "users", "session_chat_messages"}, Server: mockserver.Dummy(), Comparator: testroutines.ComparatorSubsetMetadata, Expected: &common.ListObjectMetadataResult{ @@ -66,16 +66,16 @@ func TestListObjectMetadata(t *testing.T) { }, }, }, - "jobs": { - DisplayName: "Jobs", + "users": { + DisplayName: "Users", Fields: map[string]common.FieldMetadata{ "id": { - DisplayName: "Job Id", + DisplayName: "User Id", ValueType: "string", ProviderType: "string", }, - "status": { - DisplayName: "Status", + "email": { + DisplayName: "Email", ValueType: "string", ProviderType: "string", }, diff --git a/providers/livestorm/read.go b/providers/livestorm/read.go index 6f942ff68..50ba22072 100644 --- a/providers/livestorm/read.go +++ b/providers/livestorm/read.go @@ -22,7 +22,6 @@ const ( apiVersion = "v1" objectEvents = "events" objectSessionChatMessages = "session_chat_messages" - objectJobs = "jobs" ) // nolint:gochecknoglobals @@ -31,7 +30,6 @@ var readSupportedObjects = datautils.NewStringSet( "people", "people_attributes", "session_chat_messages", - "jobs", ) func (c *Connector) buildReadRequest(ctx context.Context, params common.ReadParams) (*http.Request, error) { @@ -68,8 +66,6 @@ func (c *Connector) buildReadURL(params common.ReadParams) (*urlbuilder.URL, err return nil, common.ErrMissingObjects case objectSessionChatMessages: return c.buildSessionChatMessagesReadURL(params) - case objectJobs: - return c.buildJobReadURL(params) default: return c.buildGenericReadURL(params) } @@ -92,15 +88,6 @@ func (c *Connector) buildSessionChatMessagesReadURL(params common.ReadParams) (* return endpointURL, nil } -func (c *Connector) buildJobReadURL(params common.ReadParams) (*urlbuilder.URL, error) { - jobID := strings.TrimSpace(params.Filter) - if jobID == "" { - return nil, ErrJobIDRequired - } - - return urlbuilder.New(c.ProviderInfo().BaseURL, apiVersion, "jobs", jobID) -} - func (c *Connector) buildGenericReadURL(params common.ReadParams) (*urlbuilder.URL, error) { path, err := metadata.Schemas.FindURLPath(c.ProviderContext.Module(), params.ObjectName) if err != nil { diff --git a/providers/livestorm/read_test.go b/providers/livestorm/read_test.go index ef34d8f01..8fd4458f2 100644 --- a/providers/livestorm/read_test.go +++ b/providers/livestorm/read_test.go @@ -27,7 +27,6 @@ func TestRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx eventsMultipageBody := testutils.DataFromFile(t, "read-events-multipage.json") peopleFirstPageBody := testutils.DataFromFile(t, "read-people-first-page.json") chatMessagesBody := testutils.DataFromFile(t, "read-session-chat-messages.json") - jobBody := testutils.DataFromFile(t, "read-job.json") peopleAttributesBody := testutils.DataFromFile(t, "read-people-attributes.json") tests := []testroutines.Read{ @@ -55,12 +54,6 @@ func TestRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx Server: mockserver.Dummy(), ExpectedErrs: []error{ErrSessionIDRequired}, }, - { - Name: "Jobs require job id in filter", - Input: common.ReadParams{ObjectName: objectJobs, Fields: connectors.Fields("id")}, - Server: mockserver.Dummy(), - ExpectedErrs: []error{ErrJobIDRequired}, - }, { Name: "Read events applies v1 path and incremental time filters", Input: common.ReadParams{ @@ -260,41 +253,6 @@ func TestRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx }, }, }, - { - Name: "Read job by id", - Input: common.ReadParams{ - ObjectName: objectJobs, - Filter: "job_1", - Fields: connectors.Fields("status"), - }, - Server: mockserver.Conditional{ - Setup: mockserver.ContentJSON(), - If: mockcond.And{ - mockcond.MethodGET(), - mockcond.Path("/v1/jobs/job_1"), - }, - Then: mockserver.Response(http.StatusOK, jobBody), - }.Server(), - Comparator: testroutines.ComparatorSubsetRead, - Expected: &common.ReadResult{ - Rows: 1, - Done: true, - Data: []common.ReadResultRow{ - { - Fields: map[string]any{ - "status": "done", - }, - Raw: map[string]any{ - "id": "job_1", - "type": "jobs", - "attributes": map[string]any{ - "status": "done", - }, - }, - }, - }, - }, - }, { Name: "Read people attributes via generic object metadata path", Input: common.ReadParams{ diff --git a/providers/livestorm/test/read-job.json b/providers/livestorm/test/read-job.json deleted file mode 100644 index 2ae6ad166..000000000 --- a/providers/livestorm/test/read-job.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "data": { - "id": "job_1", - "type": "jobs", - "attributes": { - "status": "done" - } - } -} diff --git a/providers/livestorm/write.go b/providers/livestorm/write.go new file mode 100644 index 000000000..9abad54ea --- /dev/null +++ b/providers/livestorm/write.go @@ -0,0 +1,202 @@ +package livestorm + +import ( + "bytes" + "context" + "encoding/json" + "net/http" + + "github.com/amp-labs/connectors/common" + "github.com/amp-labs/connectors/common/urlbuilder" + "github.com/amp-labs/connectors/internal/jsonquery" + "github.com/spyzhov/ajson" +) + +// Livestorm write API references: +// - Create event: https://developers.livestorm.co/reference/post_events +// - Update event: https://developers.livestorm.co/reference/patch_events-id +// - Create user (team member): https://developers.livestorm.co/reference/post_users +// +// Session bulk registrants (POST …/sessions/{id}/people/bulk) are not implemented on Write; +// that flow belongs with a future Bulk API surface (see e.g. providers/salesforce/bulk-write.go). +const ( + objectUsers = "users" + jsonAPIContentType = "application/vnd.api+json" + jsonAPIResourceTypeEvents = "events" + jsonAPIResourceTypeUsers = "users" +) + +func (c *Connector) buildWriteRequest(ctx context.Context, params common.WriteParams) (*http.Request, error) { + if err := validateLivestormWrite(params); err != nil { + return nil, err + } + + record, err := common.RecordDataToMap(params.RecordData) + if err != nil { + return nil, err + } + + body, err := buildLivestormWriteBody(params, record) + if err != nil { + return nil, err + } + + u, method, err := c.buildWriteURL(params) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, method, u.String(), bytes.NewReader(body)) + if err != nil { + return nil, err + } + + req.Header.Set("Accept", jsonAPIContentType) + req.Header.Set("Content-Type", jsonAPIContentType) + + return req, nil +} + +func validateLivestormWrite(params common.WriteParams) error { + if err := params.ValidateParams(); err != nil { + return err + } + + switch params.ObjectName { + case objectEvents: + return nil + case objectUsers: + if params.IsUpdate() { + return common.ErrOperationNotSupportedForObject + } + + return nil + default: + return common.ErrOperationNotSupportedForObject + } +} + +func (c *Connector) buildWriteURL(params common.WriteParams) (*urlbuilder.URL, string, error) { + base := c.ProviderInfo().BaseURL + + switch params.ObjectName { + case objectEvents: + if params.IsCreate() { + u, err := urlbuilder.New(base, apiVersion, objectEvents) + + return u, http.MethodPost, err + } + + u, err := urlbuilder.New(base, apiVersion, objectEvents, params.RecordId) + + return u, http.MethodPatch, err + case objectUsers: + u, err := urlbuilder.New(base, apiVersion, objectUsers) + + return u, http.MethodPost, err + default: + return nil, "", common.ErrOperationNotSupportedForObject + } +} + +func buildLivestormWriteBody(params common.WriteParams, record map[string]any) ([]byte, error) { + switch params.ObjectName { + case objectEvents: + return marshalEventsWriteBody(params, record) + case objectUsers: + return marshalUsersWriteBody(record) + default: + return nil, common.ErrOperationNotSupportedForObject + } +} + +func marshalEventsWriteBody(params common.WriteParams, record map[string]any) ([]byte, error) { + if _, has := record["data"]; has { + return json.Marshal(record) + } + + delete(record, "id") + + payload := map[string]any{ + "data": map[string]any{ + "type": jsonAPIResourceTypeEvents, + "attributes": record, + }, + } + + if params.IsUpdate() { + data, ok := payload["data"].(map[string]any) + if !ok { + return nil, common.ErrBadRequest + } + + data["id"] = params.RecordId + } + + return json.Marshal(payload) +} + +func marshalUsersWriteBody(record map[string]any) ([]byte, error) { + if _, has := record["data"]; has { + return json.Marshal(record) + } + + return json.Marshal(map[string]any{ + "data": map[string]any{ + "type": jsonAPIResourceTypeUsers, + "attributes": record, + }, + }) +} + +func (c *Connector) parseWriteResponse( + _ context.Context, + params common.WriteParams, + _ *http.Request, + response *common.JSONHTTPResponse, +) (*common.WriteResult, error) { + body, ok := response.Body() + if !ok || body == nil { + return &common.WriteResult{ + Success: true, + RecordId: fallbackWriteRecordID(params), + }, nil + } + + recordID := extractJSONAPIResourceID(body) + if recordID == "" { + recordID = fallbackWriteRecordID(params) + } + + data, err := jsonquery.Convertor.ObjectToMap(body) + if err != nil { + return nil, err + } + + return &common.WriteResult{ + Success: true, + RecordId: recordID, + Data: data, + }, nil +} + +func fallbackWriteRecordID(params common.WriteParams) string { + if params.ObjectName == objectEvents && params.IsCreate() { + return "" + } + + return params.RecordId +} + +// extractJSONAPIResourceID reads id from JSON:API data.id or a root-level id (some job responses). +func extractJSONAPIResourceID(body *ajson.Node) string { + if id, err := jsonquery.New(body, "data").StringOptional("id"); err == nil && id != nil && *id != "" { + return *id + } + + if id, err := jsonquery.New(body).StringOptional("id"); err == nil && id != nil && *id != "" { + return *id + } + + return "" +} diff --git a/providers/livestorm/write_test.go b/providers/livestorm/write_test.go new file mode 100644 index 000000000..d9c942060 --- /dev/null +++ b/providers/livestorm/write_test.go @@ -0,0 +1,143 @@ +package livestorm + +import ( + "net/http" + "testing" + + "github.com/amp-labs/connectors" + "github.com/amp-labs/connectors/common" + "github.com/amp-labs/connectors/test/utils/mockutils/mockcond" + "github.com/amp-labs/connectors/test/utils/mockutils/mockserver" + "github.com/amp-labs/connectors/test/utils/testroutines" +) + +func TestWrite(t *testing.T) { //nolint:funlen + t.Parallel() + + eventCreateResp := []byte(`{"data":{"id":"evt_new","type":"events","attributes":{"title":"Webinar"}}}`) + eventUpdateResp := []byte(`{"data":{"id":"evt_1","type":"events","attributes":{"title":"Updated"}}}`) + userCreateResp := []byte(`{"data":{"id":"usr_1","type":"users","attributes":{"email":"new@example.com"}}}`) + + tests := []testroutines.Write{ + { + Name: "Write object must be included", + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrMissingObjects}, + }, + { + Name: "RecordData is required", + Input: common.WriteParams{ObjectName: objectEvents}, + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrMissingRecordData}, + }, + { + Name: "Unknown object is not supported", + Input: common.WriteParams{ObjectName: "people", RecordData: map[string]any{"email": "x@y.com"}}, + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrOperationNotSupportedForObject}, + }, + { + Name: "Users update is not supported", + Input: common.WriteParams{ObjectName: objectUsers, RecordId: "usr_1", RecordData: map[string]any{"email": "x@y.com"}}, + Server: mockserver.Dummy(), + ExpectedErrs: []error{common.ErrOperationNotSupportedForObject}, + }, + { + Name: "Create event", + Input: common.WriteParams{ + ObjectName: objectEvents, + RecordData: map[string]any{"title": "Webinar"}, + }, + Server: mockserver.Conditional{ + Setup: mockserver.ContentJSON(), + If: mockcond.And{ + mockcond.MethodPOST(), + mockcond.Path("/v1/events"), + mockcond.Body(`{"data":{"attributes":{"title":"Webinar"},"type":"events"}}`), + }, + Then: mockserver.Response(http.StatusCreated, eventCreateResp), + }.Server(), + Comparator: testroutines.ComparatorSubsetWrite, + Expected: &common.WriteResult{ + Success: true, + RecordId: "evt_new", + Data: map[string]any{ + "data": map[string]any{ + "id": "evt_new", + "type": "events", + "attributes": map[string]any{"title": "Webinar"}, + }, + }, + }, + }, + { + Name: "Update event", + Input: common.WriteParams{ + ObjectName: objectEvents, + RecordId: "evt_1", + RecordData: map[string]any{"title": "Updated"}, + }, + Server: mockserver.Conditional{ + Setup: mockserver.ContentJSON(), + If: mockcond.And{ + mockcond.MethodPATCH(), + mockcond.Path("/v1/events/evt_1"), + mockcond.Body(`{"data":{"attributes":{"title":"Updated"},"id":"evt_1","type":"events"}}`), + }, + Then: mockserver.Response(http.StatusOK, eventUpdateResp), + }.Server(), + Comparator: testroutines.ComparatorSubsetWrite, + Expected: &common.WriteResult{ + Success: true, + RecordId: "evt_1", + Data: map[string]any{ + "data": map[string]any{ + "id": "evt_1", + "type": "events", + "attributes": map[string]any{"title": "Updated"}, + }, + }, + }, + }, + { + Name: "Create user", + Input: common.WriteParams{ + ObjectName: objectUsers, + RecordData: map[string]any{"email": "new@example.com"}, + }, + Server: mockserver.Conditional{ + Setup: mockserver.ContentJSON(), + If: mockcond.And{ + mockcond.MethodPOST(), + mockcond.Path("/v1/users"), + mockcond.Body(`{"data":{"attributes":{"email":"new@example.com"},"type":"users"}}`), + }, + Then: mockserver.Response(http.StatusCreated, userCreateResp), + }.Server(), + Comparator: testroutines.ComparatorSubsetWrite, + Expected: &common.WriteResult{ + Success: true, + RecordId: "usr_1", + Data: map[string]any{ + "data": map[string]any{ + "id": "usr_1", + "type": "users", + "attributes": map[string]any{"email": "new@example.com"}, + }, + }, + }, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.Name, func(t *testing.T) { + t.Parallel() + + tt.Run(t, func() (connectors.WriteConnector, error) { + return constructTestConnector(tt.Server.URL) + }) + }) + } +} diff --git a/test/livestorm/metadata/main.go b/test/livestorm/metadata/main.go index a7dbe8b36..e7d8ab358 100644 --- a/test/livestorm/metadata/main.go +++ b/test/livestorm/metadata/main.go @@ -17,7 +17,6 @@ func main() { "events", "people", "people_attributes", - "jobs", "session_chat_messages", }) if err != nil { diff --git a/test/livestorm/read/main.go b/test/livestorm/read/main.go index 103671378..288cb8fbf 100644 --- a/test/livestorm/read/main.go +++ b/test/livestorm/read/main.go @@ -77,11 +77,6 @@ func main() { readSessionChatMessages(ctx, conn, sessionID) } - if jobID := os.Getenv("LIVESTORM_JOB_ID"); jobID != "" { - slog.Info("=== Read jobs by id (requires LIVESTORM_JOB_ID) ===") - readJob(ctx, conn, jobID) - } - slog.Info("Livestorm read tests completed successfully!") } @@ -100,19 +95,3 @@ func readSessionChatMessages(ctx context.Context, conn *livestormprovider.Connec utils.DumpJSON(res, os.Stdout) } - -func readJob(ctx context.Context, conn *livestormprovider.Connector, jobID string) { - res, err := conn.Read(ctx, common.ReadParams{ - ObjectName: "jobs", - Filter: jobID, - Fields: connectors.Fields( - "status", - "updated_at", - ), - }) - if err != nil { - utils.Fail("error reading jobs from Livestorm", "error", err) - } - - utils.DumpJSON(res, os.Stdout) -}