190 lines
6.1 KiB
Go
190 lines
6.1 KiB
Go
package mail
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDeliveryCommandsAsyncAPISpecLoads(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
doc := loadAsyncAPISpec(t)
|
|
require.Equal(t, "3.1.0", getStringValue(t, doc, "asyncapi"))
|
|
}
|
|
|
|
func TestDeliveryCommandsAsyncAPISpecFreezesChannelAndOperation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
doc := loadAsyncAPISpec(t)
|
|
|
|
channel := getMapValue(t, doc, "channels", "deliveryCommands")
|
|
require.Equal(t, "mail:delivery_commands", getStringValue(t, channel, "address"))
|
|
|
|
channelMessages := getMapValue(t, channel, "messages")
|
|
require.Equal(t, "#/components/messages/RenderedDeliveryCommand", getStringValue(t, getMapValue(t, channelMessages, "renderedDeliveryCommand"), "$ref"))
|
|
require.Equal(t, "#/components/messages/TemplateDeliveryCommand", getStringValue(t, getMapValue(t, channelMessages, "templateDeliveryCommand"), "$ref"))
|
|
|
|
operation := getMapValue(t, doc, "operations", "publishDeliveryCommand")
|
|
require.Equal(t, "send", getStringValue(t, operation, "action"))
|
|
require.Equal(t, "#/channels/deliveryCommands", getStringValue(t, getMapValue(t, operation, "channel"), "$ref"))
|
|
|
|
messageRefs := getSliceValue(t, operation, "messages")
|
|
require.Len(t, messageRefs, 2)
|
|
require.Equal(t, "#/channels/deliveryCommands/messages/renderedDeliveryCommand", getStringValue(t, messageRefs[0].(map[string]any), "$ref"))
|
|
require.Equal(t, "#/channels/deliveryCommands/messages/templateDeliveryCommand", getStringValue(t, messageRefs[1].(map[string]any), "$ref"))
|
|
}
|
|
|
|
func TestDeliveryCommandsAsyncAPISpecFreezesEnvelopeSchemas(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
doc := loadAsyncAPISpec(t)
|
|
schemas := getMapValue(t, getMapValue(t, doc, "components"), "schemas")
|
|
|
|
renderedEnvelope := getMapValue(t, schemas, "RenderedDeliveryCommandEnvelope")
|
|
require.ElementsMatch(
|
|
t,
|
|
[]any{"delivery_id", "source", "payload_mode", "idempotency_key", "requested_at_ms", "payload_json"},
|
|
getSliceValue(t, renderedEnvelope, "required"),
|
|
)
|
|
require.Equal(t, "notification", getScalarValue(t, getMapValue(t, getMapValue(t, renderedEnvelope, "properties"), "source"), "const"))
|
|
require.Equal(t, "rendered", getScalarValue(t, getMapValue(t, getMapValue(t, renderedEnvelope, "properties"), "payload_mode"), "const"))
|
|
require.Equal(
|
|
t,
|
|
"#/components/schemas/RenderedPayloadJSON",
|
|
getStringValue(t, getMapValue(t, getMapValue(t, getMapValue(t, renderedEnvelope, "properties"), "payload_json"), "contentSchema"), "$ref"),
|
|
)
|
|
|
|
templateEnvelope := getMapValue(t, schemas, "TemplateDeliveryCommandEnvelope")
|
|
require.Equal(t, "notification", getScalarValue(t, getMapValue(t, getMapValue(t, templateEnvelope, "properties"), "source"), "const"))
|
|
require.Equal(t, "template", getScalarValue(t, getMapValue(t, getMapValue(t, templateEnvelope, "properties"), "payload_mode"), "const"))
|
|
require.Equal(
|
|
t,
|
|
"#/components/schemas/TemplatePayloadJSON",
|
|
getStringValue(t, getMapValue(t, getMapValue(t, getMapValue(t, templateEnvelope, "properties"), "payload_json"), "contentSchema"), "$ref"),
|
|
)
|
|
}
|
|
|
|
func TestDeliveryCommandsAsyncAPISpecFreezesPayloadSchemasAndExamples(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
doc := loadAsyncAPISpec(t)
|
|
components := getMapValue(t, doc, "components")
|
|
schemas := getMapValue(t, components, "schemas")
|
|
messages := getMapValue(t, components, "messages")
|
|
|
|
renderedPayload := getMapValue(t, schemas, "RenderedPayloadJSON")
|
|
require.ElementsMatch(
|
|
t,
|
|
[]any{"to", "cc", "bcc", "reply_to", "subject", "text_body", "attachments"},
|
|
getSliceValue(t, renderedPayload, "required"),
|
|
)
|
|
|
|
templatePayload := getMapValue(t, schemas, "TemplatePayloadJSON")
|
|
require.ElementsMatch(
|
|
t,
|
|
[]any{"to", "cc", "bcc", "reply_to", "template_id", "locale", "variables", "attachments"},
|
|
getSliceValue(t, templatePayload, "required"),
|
|
)
|
|
|
|
attachment := getMapValue(t, schemas, "Attachment")
|
|
require.ElementsMatch(
|
|
t,
|
|
[]any{"filename", "content_type", "content_base64"},
|
|
getSliceValue(t, attachment, "required"),
|
|
)
|
|
|
|
renderedExamples := getSliceValue(t, getMapValue(t, messages, "RenderedDeliveryCommand"), "examples")
|
|
require.NotEmpty(t, getStringValue(t, getMapValue(t, renderedExamples[0].(map[string]any), "payload"), "payload_json"))
|
|
|
|
templateExamples := getSliceValue(t, getMapValue(t, messages, "TemplateDeliveryCommand"), "examples")
|
|
require.NotEmpty(t, getStringValue(t, getMapValue(t, templateExamples[0].(map[string]any), "payload"), "payload_json"))
|
|
}
|
|
|
|
func loadAsyncAPISpec(t *testing.T) map[string]any {
|
|
t.Helper()
|
|
|
|
_, thisFile, _, ok := runtime.Caller(0)
|
|
if !ok {
|
|
require.FailNow(t, "runtime.Caller failed")
|
|
}
|
|
|
|
specPath := filepath.Join(filepath.Dir(thisFile), "api", "delivery-commands-asyncapi.yaml")
|
|
payload, err := os.ReadFile(specPath)
|
|
if err != nil {
|
|
require.Failf(t, "test failed", "read spec %s: %v", specPath, err)
|
|
}
|
|
|
|
var doc map[string]any
|
|
if err := yaml.Unmarshal(payload, &doc); err != nil {
|
|
require.Failf(t, "test failed", "decode spec %s: %v", specPath, err)
|
|
}
|
|
|
|
return doc
|
|
}
|
|
|
|
func getMapValue(t *testing.T, value map[string]any, path ...string) map[string]any {
|
|
t.Helper()
|
|
|
|
current := value
|
|
for _, segment := range path {
|
|
raw, ok := current[segment]
|
|
if !ok {
|
|
require.Failf(t, "test failed", "missing map key %s", segment)
|
|
}
|
|
next, ok := raw.(map[string]any)
|
|
if !ok {
|
|
require.Failf(t, "test failed", "value at %s is not a map", segment)
|
|
}
|
|
current = next
|
|
}
|
|
|
|
return current
|
|
}
|
|
|
|
func getStringValue(t *testing.T, value map[string]any, key string) string {
|
|
t.Helper()
|
|
|
|
raw, ok := value[key]
|
|
if !ok {
|
|
require.Failf(t, "test failed", "missing key %s", key)
|
|
}
|
|
result, ok := raw.(string)
|
|
if !ok {
|
|
require.Failf(t, "test failed", "value at %s is not a string", key)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func getScalarValue(t *testing.T, value map[string]any, key string) any {
|
|
t.Helper()
|
|
|
|
raw, ok := value[key]
|
|
if !ok {
|
|
require.Failf(t, "test failed", "missing key %s", key)
|
|
}
|
|
|
|
return raw
|
|
}
|
|
|
|
func getSliceValue(t *testing.T, value map[string]any, key string) []any {
|
|
t.Helper()
|
|
|
|
raw, ok := value[key]
|
|
if !ok {
|
|
require.Failf(t, "test failed", "missing key %s", key)
|
|
}
|
|
result, ok := raw.([]any)
|
|
if !ok {
|
|
require.Failf(t, "test failed", "value at %s is not a slice", key)
|
|
}
|
|
|
|
return result
|
|
}
|