Skip to content

Commit c096ccd

Browse files
committed
feat(subscriptions): Scripts for consuming events
1 parent 70c5cb4 commit c096ccd

6 files changed

Lines changed: 679 additions & 11 deletions

File tree

test/utils/dump.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import (
99

1010
// DumpJSON dumps the given value as JSON to the given writer.
1111
func DumpJSON(v any, w io.Writer) {
12+
if bytesData, ok := v.([]byte); ok {
13+
jsonData := make(map[string]any)
14+
if err := json.Unmarshal(bytesData, &jsonData); err == nil {
15+
v = jsonData
16+
}
17+
}
18+
1219
// Convert any error interfaces recursively before encoding.
1320
convertedValue := substituteErrorsToStrings(v)
1421

test/utils/testscenario/crud.go

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"os"
78
"strconv"
89
"time"
910

@@ -61,6 +62,10 @@ func (p Property) isZero() bool {
6162
return p.Key == "" && p.Value == ""
6263
}
6364

65+
func (p Property) String() string {
66+
return fmt.Sprintf("{ %v : %v }", p.Key, p.Value)
67+
}
68+
6469
// ValidateCreateUpdateDelete is a comprehensive test scenario utilizing Read/Write/Delete connector operations.
6570
//
6671
// Flow:
@@ -69,7 +74,8 @@ func (p Property) isZero() bool {
6974
// 3. Update the object using the "UP" payload.
7075
// 4. Read again and verify updates took effect.
7176
// 5. Delete the object at the end.
72-
func ValidateCreateUpdateDelete[CP, UP any](ctx context.Context, conn ConnectorCRUD, objectName string,
77+
func ValidateCreateUpdateDelete[CP, UP any](
78+
ctx context.Context, conn ConnectorCRUD, objectName string,
7379
createPayload CP, updatePayload UP, suite CRUDTestSuite,
7480
) {
7581
fmt.Println("> TEST Create/Update/Delete", objectName)
@@ -114,7 +120,7 @@ func ValidateCreateUpdateDelete[CP, UP any](ctx context.Context, conn ConnectorC
114120

115121
// UPDATE
116122
fmt.Println("Updating some object properties")
117-
err = updateObject(ctx, conn, objectName, objectID, &updatePayload)
123+
_, err = updateObject(ctx, conn, objectName, objectID, &updatePayload)
118124
failOnError(err)
119125
fmt.Println("Validate object has changed accordingly")
120126

@@ -181,7 +187,7 @@ func getRecordIdentifierValue(object map[string]any, key string) string {
181187
}
182188

183189
func createObject[CP any](
184-
ctx context.Context, conn ConnectorCRUD, objectName string, payload *CP,
190+
ctx context.Context, conn connectors.WriteConnector, objectName string, payload *CP,
185191
) (*common.WriteResult, error) {
186192
res, err := conn.Write(ctx, common.WriteParams{
187193
ObjectName: objectName,
@@ -199,8 +205,10 @@ func createObject[CP any](
199205
return res, nil
200206
}
201207

202-
func readObjects(ctx context.Context, conn ConnectorCRUD,
203-
objectName string, fields datautils.StringSet, since time.Time) (*common.ReadResult, error) {
208+
func readObjects(
209+
ctx context.Context, conn connectors.ReadConnector,
210+
objectName string, fields datautils.StringSet, since time.Time,
211+
) (*common.ReadResult, error) {
204212
res, err := conn.Read(ctx, common.ReadParams{
205213
ObjectName: objectName,
206214
Fields: fields,
@@ -247,22 +255,22 @@ func searchObjectRecord(res *common.ReadResult, key, value string) (*objectRecor
247255
}
248256

249257
func updateObject[UP any](
250-
ctx context.Context, conn ConnectorCRUD, objectName string, objectID string, payload *UP,
251-
) error {
258+
ctx context.Context, conn connectors.WriteConnector, objectName string, objectID string, payload *UP,
259+
) (*common.WriteResult, error) {
252260
res, err := conn.Write(ctx, common.WriteParams{
253261
ObjectName: objectName,
254262
RecordId: objectID,
255263
RecordData: payload,
256264
})
257265
if err != nil {
258-
return fmt.Errorf("error updating object: %w", err)
266+
return nil, fmt.Errorf("error updating object: %w", err)
259267
}
260268

261269
if !res.Success {
262-
return errors.New("failed to update an object")
270+
return nil, errors.New("failed to update an object")
263271
}
264272

265-
return nil
273+
return res, nil
266274
}
267275

268276
func removeObject(ctx context.Context, conn ConnectorCRUD, objectName string, objectID string) error {
@@ -283,6 +291,21 @@ func removeObject(ctx context.Context, conn ConnectorCRUD, objectName string, ob
283291

284292
func failOnError(err error) {
285293
if err != nil {
286-
utils.Fail("fatal", "error", err)
294+
utils.Fail("[test failed]", "error", err)
287295
}
288296
}
297+
298+
// printError prints error and returns true if error is not nil.
299+
func printError(err error) bool {
300+
if err == nil {
301+
return false
302+
}
303+
304+
fmt.Println("[test failed]", "error", err.Error())
305+
if httpError, ok := errors.AsType[*common.HTTPError](err); ok {
306+
utils.DumpJSON(httpError.Body, os.Stdout)
307+
return true
308+
}
309+
310+
return true
311+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package testscenario
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"os"
8+
9+
"github.com/amp-labs/connectors/common"
10+
"github.com/amp-labs/connectors/internal/components"
11+
"github.com/amp-labs/connectors/test/utils"
12+
)
13+
14+
type ConnectorSubscriptionManager interface {
15+
components.SubscriptionCreator
16+
components.SubscriptionUpdater
17+
components.SubscriptionRemover
18+
}
19+
20+
// SubscriptionCreateUpdateDelete is a test scenario utilizing
21+
// Subscribe/UpdateSubscription/DeleteSubscription connector operations.
22+
// Each step will be displayed on the screen and to be analyzed by developer.
23+
func SubscriptionCreateUpdateDelete(
24+
ctx context.Context, conn ConnectorSubscriptionManager,
25+
createParams, updateParams SubscribeParamBuilder,
26+
) {
27+
fmt.Println("> TEST Subscription Create/Update/Delete")
28+
publicURL, ok := getPublicWebhookURL(ctx)
29+
if !ok {
30+
failOnError(errors.New("webhook URL is needed"))
31+
}
32+
33+
fmt.Println("============= Create =============")
34+
result, err := conn.Subscribe(ctx, *createParams(publicURL))
35+
if err != nil {
36+
fmt.Println("conn.Subscribe() -> failed")
37+
failOnError(err)
38+
}
39+
validateSubscriptionResult(result)
40+
41+
fmt.Println("============= Update =============")
42+
result, err = conn.UpdateSubscription(ctx, *updateParams(publicURL), result)
43+
if err != nil {
44+
fmt.Println("conn.UpdateSubscription() -> failed")
45+
failOnError(err)
46+
}
47+
validateSubscriptionResult(result)
48+
49+
fmt.Println("============= Delete =============")
50+
err = conn.DeleteSubscription(ctx, *result)
51+
if err != nil {
52+
fmt.Println("conn.DeleteSubscription() -> failed")
53+
failOnError(err)
54+
}
55+
56+
fmt.Println("> Successful test completion")
57+
}
58+
59+
func validateSubscriptionResult(result *common.SubscriptionResult) {
60+
fmt.Println("(1) Result:")
61+
utils.DumpJSON(result.Result, os.Stdout)
62+
fmt.Println("(2) ObjectEvents:")
63+
utils.DumpJSON(result.ObjectEvents, os.Stdout)
64+
fmt.Printf("(3) Status: \"%v\"\n", result.Status)
65+
if result.Status != common.SubscriptionStatusSuccess {
66+
failOnError(errors.New("subscription has not succeeded"))
67+
}
68+
}

0 commit comments

Comments
 (0)