Files
upstream-watermill/message/message_test.go
2026-09-15 21:27:46 +05:00

191 lines
4.4 KiB
Go

package message_test
import (
"context"
"testing"
"github.com/ThreeDotsLabs/watermill/message"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMessage_Equals(t *testing.T) {
withMetadata := func(msg *message.Message, metadata message.Metadata) *message.Message {
msg.Metadata = metadata
return msg
}
testCases := []struct {
Name string
Msg1 *message.Message
Msg2 *message.Message
Equals bool
}{
{
Name: "equal",
Msg1: message.NewMessage("1", []byte("foo")),
Msg2: message.NewMessage("1", []byte("foo")),
Equals: true,
},
{
Name: "different_uuid",
Msg1: message.NewMessage("1", []byte("foo")),
Msg2: message.NewMessage("2", []byte("foo")),
Equals: false,
},
{
Name: "different_payload",
Msg1: message.NewMessage("1", []byte("foo")),
Msg2: message.NewMessage("1", []byte("bar")),
Equals: false,
},
{
Name: "different_metadata",
Msg1: withMetadata(message.NewMessage("1", []byte("foo")), map[string]string{"foo": "1"}),
Msg2: withMetadata(message.NewMessage("1", []byte("foo")), map[string]string{"foo": "2"}),
Equals: false,
},
}
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
assert.Equal(t, tc.Equals, tc.Msg1.Equals(tc.Msg2))
assert.Equal(t, tc.Equals, tc.Msg2.Equals(tc.Msg1))
})
}
}
func TestMessage_Ack(t *testing.T) {
msg := &message.Message{}
require.True(t, msg.Ack())
assertAcked(t, msg)
assertNoNack(t, msg)
}
func TestMessage_Ack_idempotent(t *testing.T) {
msg := &message.Message{}
require.True(t, msg.Ack())
require.True(t, msg.Ack())
assertAcked(t, msg)
}
func TestMessage_Ack_already_Nack(t *testing.T) {
msg := &message.Message{}
require.True(t, msg.Nack())
assert.False(t, msg.Ack())
}
func TestMessage_Nack(t *testing.T) {
msg := &message.Message{}
require.True(t, msg.Nack())
assertNoAck(t, msg)
assertNacked(t, msg)
}
func TestMessage_Nack_idempotent(t *testing.T) {
msg := &message.Message{}
require.True(t, msg.Nack())
require.True(t, msg.Nack())
assertNacked(t, msg)
}
func TestMessage_Nack_already_Ack(t *testing.T) {
msg := &message.Message{}
require.True(t, msg.Ack())
assert.False(t, msg.Nack())
}
func TestMessage_Copy(t *testing.T) {
msg := message.NewMessage("1", []byte("foo"))
msgCopy := msg.Copy()
require.True(t, msg.Ack())
assertAcked(t, msg)
assertNoAck(t, msgCopy)
assert.True(t, msg.Equals(msgCopy))
}
type ctxKey string
func TestMessage_CopyWithContext(t *testing.T) {
msg := message.NewMessage("1", []byte("foo"))
testCtx := context.Background()
testCtx = context.WithValue(testCtx, ctxKey("foo"), "bar")
msg.SetContext(testCtx)
msgCopy := msg.CopyWithContext()
copyMsgCtx := msgCopy.Context()
assert.True(t, copyMsgCtx.Value(ctxKey("foo")) == "bar", "expected context not being copied")
assert.False(t, copyMsgCtx.Value(ctxKey("abc")) == "def", "non-expected context being copied")
assert.True(t, msg.Equals(msgCopy))
}
func TestMessage_CopyWithContextAndMetadata(t *testing.T) {
msg := message.NewMessage("1", []byte("foo"))
testCtx := context.Background()
testCtx = context.WithValue(testCtx, ctxKey("foo"), "bar")
msg.SetContext(testCtx)
msg.Metadata.Set("foo", "bar")
msgCopy := msg.CopyWithContext()
msg.Metadata.Set("foo", "baz")
copyMsgCtx := msgCopy.Context()
assert.True(t, copyMsgCtx.Value(ctxKey("foo")) == "bar", "expected context not being copied")
assert.Equal(t, msgCopy.Metadata.Get("foo"), "bar", "did not expect changing source message's metadata to alter copy's metadata")
}
func TestMessage_CopyMetadata(t *testing.T) {
msg := message.NewMessage("1", []byte("foo"))
msg.Metadata.Set("foo", "bar")
msgCopy := msg.Copy()
msg.Metadata.Set("foo", "baz")
assert.Equal(t, msgCopy.Metadata.Get("foo"), "bar", "did not expect changing source message's metadata to alter copy's metadata")
}
func assertAcked(t *testing.T, msg *message.Message) {
select {
case <-msg.Acked():
// ok
default:
t.Fatal("no ack received")
}
}
func assertNacked(t *testing.T, msg *message.Message) {
select {
case <-msg.Nacked():
// ok
default:
t.Fatal("no ack received")
}
}
func assertNoAck(t *testing.T, msg *message.Message) {
select {
case <-msg.Acked():
t.Fatal("nack should be not sent")
default:
// ok
}
}
func assertNoNack(t *testing.T, msg *message.Message) {
select {
case <-msg.Nacked():
t.Fatal("nack should be not sent")
default:
// ok
}
}