diff --git a/v2/extensions/dataref_extension.go b/v2/extensions/dataref_extension.go new file mode 100644 index 000000000..fc70789e2 --- /dev/null +++ b/v2/extensions/dataref_extension.go @@ -0,0 +1,41 @@ +/* + Copyright 2024 The CloudEvents Authors + SPDX-License-Identifier: Apache-2.0 +*/ + +package extensions + +import ( + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/types" + "net/url" +) + +const DataRefExtensionKey = "dataref" + +type DataRefExtension struct { + DataRef *url.URL `json:"dataref"` +} + +func AddDataRefExtension(e *event.Event, dataRef string) error { + parsedURL, err := url.Parse(dataRef) + if err != nil { + return err + } + + e.SetExtension(DataRefExtensionKey, parsedURL.String()) + return nil +} + +func GetDataRefExtension(e event.Event) (DataRefExtension, bool) { + if dataRefValue, ok := e.Extensions()[DataRefExtensionKey]; ok { + if dataRefStr, err := types.ToString(dataRefValue); err == nil { + parsedURL, err := url.Parse(dataRefStr) + if err != nil { + return DataRefExtension{}, false + } + return DataRefExtension{DataRef: parsedURL}, true + } + } + return DataRefExtension{}, false +} diff --git a/v2/extensions/dataref_extension_test.go b/v2/extensions/dataref_extension_test.go new file mode 100644 index 000000000..63532cecf --- /dev/null +++ b/v2/extensions/dataref_extension_test.go @@ -0,0 +1,77 @@ +/* + Copyright 2024 The CloudEvents Authors + SPDX-License-Identifier: Apache-2.0 +*/ + +package extensions + +import ( + "net/url" + "testing" + + "github.com/cloudevents/sdk-go/v2/event" +) + +func TestAddDataRefExtensionValidURL(t *testing.T) { + e := event.New() + expectedDataRef := "https://example.com/data" + + err := AddDataRefExtension(&e, expectedDataRef) + if err != nil { + t.Fatalf("Failed to add DataRefExtension with valid URL: %s", err) + } +} + +func TestAddDataRefExtensionInvalidURL(t *testing.T) { + e := event.New() + invalidDataRef := "://invalid-url" + + err := AddDataRefExtension(&e, invalidDataRef) + if err == nil { + t.Fatal("Expected error when adding DataRefExtension with invalid URL, but got none") + } +} + +func TestGetDataRefExtensionNotFound(t *testing.T) { + e := event.New() + + _, ok := GetDataRefExtension(e) + if ok { + t.Fatal("Expected not to find DataRefExtension, but did") + } +} + +func TestSerializationAndDeserialization(t *testing.T) { + e := event.New() + dataRef := "https://example.com/data" + + err := AddDataRefExtension(&e, dataRef) + if err != nil { + t.Fatalf("Failed to add DataRefExtension: %s", err) + } + + bytes, err := e.MarshalJSON() + if err != nil { + t.Fatalf("Failed to marshal event with DataRefExtension: %s", err) + } + + var deserializedEvent event.Event + err = deserializedEvent.UnmarshalJSON(bytes) + if err != nil { + t.Fatalf("Failed to unmarshal event with DataRefExtension: %s", err) + } + + dataRefExtension, ok := GetDataRefExtension(deserializedEvent) + if !ok { + t.Fatal("Expected to find DataRefExtension after deserialization, but did not") + } + + expectedURL, err := url.Parse(dataRef) + if err != nil { + t.Fatalf("Failed to parse expected DataRef URL: %s", err) + } + + if dataRefExtension.DataRef.String() != expectedURL.String() { + t.Errorf("Expected DataRefExtension.DataRef to be '%s', but got '%s' after deserialization", expectedURL, dataRefExtension.DataRef) + } +}