public void EncodeStructuredModeMessage_AllAttributeTypes()
        {
            var cloudEvent = new CloudEvent(AllTypesExtensions)
            {
                ["binary"]       = SampleBinaryData,
                ["boolean"]      = true,
                ["integer"]      = 10,
                ["string"]       = "text",
                ["timestamp"]    = SampleTimestamp,
                ["uri"]          = SampleUri,
                ["urireference"] = SampleUriReference
            };

            // We're not going to check these.
            cloudEvent.PopulateRequiredAttributes();

            JObject obj      = EncodeAndParseStructured(cloudEvent);
            var     asserter = new JTokenAsserter
            {
                { "binary", JTokenType.String, SampleBinaryDataBase64 },
                { "boolean", JTokenType.Boolean, true },
                { "integer", JTokenType.Integer, 10 },
                { "string", JTokenType.String, "text" },
                { "timestamp", JTokenType.String, SampleTimestampText },
                { "uri", JTokenType.String, SampleUriText },
                { "urireference", JTokenType.String, SampleUriReferenceText },
            };

            asserter.AssertProperties(obj, assertCount: false);
        }
        public void EncodeStructuredModeMessage_V1Attributes()
        {
            var cloudEvent = new CloudEvent(CloudEventsSpecVersion.V1_0)
            {
                Data            = "text", // Just so that it's reasonable to have a DataContentType
                DataContentType = "text/plain",
                DataSchema      = new Uri("https://data-schema"),
                Id      = "event-id",
                Source  = new Uri("https://event-source"),
                Subject = "event-subject",
                Time    = new DateTimeOffset(2021, 2, 19, 12, 34, 56, 789, TimeSpan.FromHours(1)),
                Type    = "event-type"
            };

            byte[] encoded = new JsonEventFormatter().EncodeStructuredModeMessage(cloudEvent, out var contentType);
            Assert.Equal("application/cloudevents+json; charset=utf-8", contentType.ToString());
            JObject obj      = ParseJson(encoded);
            var     asserter = new JTokenAsserter
            {
                { "data", JTokenType.String, "text" },
                { "datacontenttype", JTokenType.String, "text/plain" },
                { "dataschema", JTokenType.String, "https://data-schema" },
                { "id", JTokenType.String, "event-id" },
                { "source", JTokenType.String, "https://event-source" },
                { "specversion", JTokenType.String, "1.0" },
                { "subject", JTokenType.String, "event-subject" },
                { "time", JTokenType.String, "2021-02-19T12:34:56.789+01:00" },
                { "type", JTokenType.String, "event-type" },
            };

            asserter.AssertProperties(obj, assertCount: true);
        }
        public void EncodeStructured_BinaryData_DefaultContentTypeIsNotImplied()
        {
            var cloudEvent = new CloudEvent
            {
                Data = SampleBinaryData
            }.PopulateRequiredAttributes();

            // If a CloudEvent to have binary data but no data content type,
            // the spec says the data should be placed in data_base64, but the content type
            // should *not* be defaulted to application/json, as clarified in https://github.com/cloudevents/spec/issues/933
            var encoded = new JsonEventFormatter().EncodeStructuredModeMessage(cloudEvent, out var contentType);

            Assert.Equal("application/cloudevents+json; charset=utf-8", contentType.ToString());
            JObject obj      = ParseJson(encoded);
            var     asserter = new JTokenAsserter
            {
                { "data_base64", JTokenType.String, SampleBinaryDataBase64 },
                { "id", JTokenType.String, "test-id" },
                { "source", JTokenType.String, "//test" },
                { "specversion", JTokenType.String, "1.0" },
                { "type", JTokenType.String, "test-type" },
            };

            asserter.AssertProperties(obj, assertCount: true);
        }
        public void EncodeStructuredModeMessage_JsonDataType_NumberSerialization()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data            = 10;
            cloudEvent.DataContentType = "application/json";
            JObject obj      = EncodeAndParseStructured(cloudEvent);
            var     asserter = new JTokenAsserter
            {
                { "data", JTokenType.Integer, 10 }
            };

            asserter.AssertProperties(obj, assertCount: false);
        }
        public void EncodeStructuredModeMessage_JsonDataType_ObjectSerialization()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data            = new { Text = "simple text" };
            cloudEvent.DataContentType = "application/json";
            JObject obj          = EncodeAndParseStructured(cloudEvent);
            JObject dataProperty = (JObject)obj["data"];
            var     asserter     = new JTokenAsserter
            {
                { "Text", JTokenType.String, "simple text" }
            };

            asserter.AssertProperties(dataProperty, assertCount: true);
        }
        public void DecodeBinaryModeEventData_Json(string charset)
        {
            var encoding = Encoding.GetEncoding(charset);
            var bytes    = encoding.GetBytes(new JObject {
                ["test"] = NonAsciiValue
            }.ToString());
            var data     = DecodeBinaryModeEventData(bytes, $"application/json; charset={charset}");
            var obj      = Assert.IsType <JObject>(data);
            var asserter = new JTokenAsserter
            {
                { "test", JTokenType.String, NonAsciiValue }
            };

            asserter.AssertProperties(obj, assertCount: true);
        }
        public void EncodeBinaryModeEventData_JsonDataType_ObjectSerialization()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data            = new { Text = "simple text" };
            cloudEvent.DataContentType = "application/json";
            byte[]  bytes    = new JsonEventFormatter().EncodeBinaryModeEventData(cloudEvent);
            JObject data     = ParseJson(bytes);
            var     asserter = new JTokenAsserter
            {
                { "Text", JTokenType.String, "simple text" }
            };

            asserter.AssertProperties(data, assertCount: true);
        }
        public void EncodeStructuredModeMessage_JsonDataType_JTokenObject()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data = new JObject {
                ["Key"] = "value"
            };
            cloudEvent.DataContentType = "application/json";
            JObject obj          = EncodeAndParseStructured(cloudEvent);
            JObject dataProperty = (JObject)obj["data"] !;
            var     asserter     = new JTokenAsserter
            {
                { "Key", JTokenType.String, "value" }
            };

            asserter.AssertProperties(dataProperty, assertCount: true);
        }
        public void EncodeBatchModeMessage_TwoEvents()
        {
            var event1 = new CloudEvent().PopulateRequiredAttributes();

            event1.Id              = "event1";
            event1.Data            = "simple text";
            event1.DataContentType = "text/plain";

            var event2 = new CloudEvent().PopulateRequiredAttributes();

            event2.Id = "event2";

            var cloudEvents = new[] { event1, event2 };
            var formatter   = new JsonEventFormatter();

            byte[] bytes = formatter.EncodeBatchModeMessage(cloudEvents, out var contentType);
            Assert.Equal("application/cloudevents-batch+json; charset=utf-8", contentType.ToString());
            var array = ParseJsonArray(bytes);

            Assert.Equal(2, array.Count);

            var asserter1 = new JTokenAsserter
            {
                { "specversion", JTokenType.String, "1.0" },
                { "id", JTokenType.String, event1.Id },
                { "type", JTokenType.String, event1.Type },
                { "source", JTokenType.String, "//test" },
                { "data", JTokenType.String, "simple text" },
                { "datacontenttype", JTokenType.String, event1.DataContentType }
            };

            asserter1.AssertProperties((JObject)array[0], assertCount: true);

            var asserter2 = new JTokenAsserter
            {
                { "specversion", JTokenType.String, "1.0" },
                { "id", JTokenType.String, event2.Id },
                { "type", JTokenType.String, event2.Type },
                { "source", JTokenType.String, "//test" },
            };

            asserter2.AssertProperties((JObject)array[1], assertCount: true);
        }
        public void EncodeBinaryModeEventData_JsonDataType_CustomSerializer()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data            = new { DateValue = new DateTime(2021, 2, 19, 12, 49, 34, DateTimeKind.Utc) };
            cloudEvent.DataContentType = "application/json";

            var serializer = new JsonSerializer
            {
                DateFormatString = "yyyy-MM-dd"
            };
            var     formatter = new JsonEventFormatter(serializer);
            var     bytes     = formatter.EncodeBinaryModeEventData(cloudEvent);
            JObject data      = ParseJson(bytes);
            var     asserter  = new JTokenAsserter
            {
                { "DateValue", JTokenType.String, "2021-02-19" }
            };

            asserter.AssertProperties(data, assertCount: true);
        }
        public void EncodeStructuredModeMessage_JsonDataType_CustomSerializer()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data            = new { DateValue = new DateTime(2021, 2, 19, 12, 49, 34, DateTimeKind.Utc) };
            cloudEvent.DataContentType = "application/json";

            var serializer = new JsonSerializer
            {
                DateFormatString = "yyyy-MM-dd"
            };
            var     formatter    = new JsonEventFormatter(serializer);
            var     encoded      = formatter.EncodeStructuredModeMessage(cloudEvent, out _);
            JObject obj          = ParseJson(encoded);
            JObject dataProperty = (JObject)obj["data"] !;
            var     asserter     = new JTokenAsserter
            {
                { "DateValue", JTokenType.String, "2021-02-19" }
            };

            asserter.AssertProperties(dataProperty, assertCount: true);
        }
        public void EncodeStructured_DefaultContentTypeToApplicationJson()
        {
            var cloudEvent = new CloudEvent
            {
                Data = new { Key = "value" }
            }.PopulateRequiredAttributes();

            var encoded = new JsonEventFormatter().EncodeStructuredModeMessage(cloudEvent, out var contentType);

            Assert.Equal("application/cloudevents+json; charset=utf-8", contentType.ToString());
            JObject obj      = ParseJson(encoded);
            var     asserter = new JTokenAsserter
            {
                { "data", JTokenType.Object, cloudEvent.Data },
                { "datacontenttype", JTokenType.String, "application/json" },
                { "id", JTokenType.String, "test-id" },
                { "source", JTokenType.String, "//test" },
                { "specversion", JTokenType.String, "1.0" },
                { "type", JTokenType.String, "test-type" },
            };

            asserter.AssertProperties(obj, assertCount: true);
        }