From 1fd87211197b929da9f307d26c5969f2e94dd2f6 Mon Sep 17 00:00:00 2001 From: Benjamin Wenger <ben@elixxir.ioo> Date: Mon, 29 Aug 2022 16:38:16 -0700 Subject: [PATCH] finished tested the event model --- channels/eventModel.go | 2 +- channels/eventModel_test.go | 754 ++++++++++++++++++++++++++++++++++++ channels/messages.go | 23 +- channels/messages_test.go | 97 ++--- channels/userListener.go | 2 +- 5 files changed, 799 insertions(+), 79 deletions(-) create mode 100644 channels/eventModel_test.go diff --git a/channels/eventModel.go b/channels/eventModel.go index f3c805b08..332ab75ba 100644 --- a/channels/eventModel.go +++ b/channels/eventModel.go @@ -116,7 +116,7 @@ func (e *events) RegisterReceiveHandler(messageType MessageType, // triggerEvent is an internal function which is used to trigger message // reception on a message received from a user (symmetric encryption) // It will call the appropriate MessageTypeHandler assuming one exists. -func (e *events) triggerEvent(chID *id.ID, umi *UserMessageInternal, +func (e *events) triggerEvent(chID *id.ID, umi *userMessageInternal, receptionID receptionID.EphemeralIdentity, round rounds.Round) { um := umi.GetUserMessage() cm := umi.GetChannelMessage() diff --git a/channels/eventModel_test.go b/channels/eventModel_test.go new file mode 100644 index 000000000..e6d4cb579 --- /dev/null +++ b/channels/eventModel_test.go @@ -0,0 +1,754 @@ +package channels + +import ( + "bytes" + "github.com/golang/protobuf/proto" + "gitlab.com/elixxir/client/cmix/identity/receptionID" + "gitlab.com/elixxir/client/cmix/rounds" + cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" + cryptoChannel "gitlab.com/elixxir/crypto/channel" + "gitlab.com/elixxir/primitives/states" + "gitlab.com/xx_network/primitives/id" + "reflect" + "runtime" + "testing" + "time" +) + +type eventReceive struct { + channelID *id.ID + messageID cryptoChannel.MessageID + reactionTo cryptoChannel.MessageID + senderUsername string + content []byte + timestamp time.Time + lease time.Duration + round rounds.Round +} + +type MockEvent struct { + eventReceive +} + +func (*MockEvent) JoinChannel(channel cryptoBroadcast.Channel) {} +func (*MockEvent) LeaveChannel(channelID *id.ID) {} +func (m *MockEvent) ReceiveMessage(channelID *id.ID, messageID cryptoChannel.MessageID, + senderUsername string, text string, + timestamp time.Time, lease time.Duration, round rounds.Round) { + m.eventReceive = eventReceive{ + channelID: channelID, + messageID: messageID, + reactionTo: cryptoChannel.MessageID{}, + senderUsername: senderUsername, + content: []byte(text), + timestamp: timestamp, + lease: lease, + round: round, + } +} +func (m *MockEvent) ReceiveReply(channelID *id.ID, messageID cryptoChannel.MessageID, + replyTo cryptoChannel.MessageID, senderUsername string, + text string, timestamp time.Time, lease time.Duration, + round rounds.Round) { + m.eventReceive = eventReceive{ + channelID: channelID, + messageID: messageID, + reactionTo: replyTo, + senderUsername: senderUsername, + content: []byte(text), + timestamp: timestamp, + lease: lease, + round: round, + } +} +func (m *MockEvent) ReceiveReaction(channelID *id.ID, messageID cryptoChannel.MessageID, + reactionTo cryptoChannel.MessageID, senderUsername string, + reaction string, timestamp time.Time, lease time.Duration, + round rounds.Round) { + m.eventReceive = eventReceive{ + channelID: channelID, + messageID: messageID, + reactionTo: reactionTo, + senderUsername: senderUsername, + content: []byte(reaction), + timestamp: timestamp, + lease: lease, + round: round, + } +} + +func Test_initEvents(t *testing.T) { + + me := &MockEvent{} + + e := initEvents(me) + + // verify the model is registered + if e.model != me { + t.Errorf("Event model is not registered") + } + + // check registered channels was created + if e.registered == nil { + t.Fatalf("Registered handlers is not registered") + } + + // check that all the default callbacks are registered + if len(e.registered) != 3 { + t.Errorf("The correct number of default handlers are not "+ + "registered; %d vs %d", len(e.registered), 3) + //If this fails, is means the default handlers have changed. edit the + //number here and add tests below. be suspicious if it goes down. + } + + if getFuncName(e.registered[Text]) != getFuncName(e.receiveTextMessage) { + t.Errorf("Text does not have recieveTextMessageRegistred") + } + + if getFuncName(e.registered[AdminText]) != getFuncName(e.receiveTextMessage) { + t.Errorf("AdminText does not have recieveTextMessageRegistred") + } + + if getFuncName(e.registered[Reaction]) != getFuncName(e.receiveReaction) { + t.Errorf("Reaction does not have recieveReaction") + } +} + +func TestEvents_RegisterReceiveHandler(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + //test that a new receive handler can be registered. + mt := MessageType(42) + err := e.RegisterReceiveHandler(mt, e.receiveReaction) + if err != nil { + t.Fatalf("Failed to register '%s' when it should be "+ + "sucesfull: %+v", mt, err) + } + + //check that it is written + returnedHandler, exists := e.registered[mt] + if !exists { + t.Fatalf("Failed to get handler '%s' after registration", mt) + } + + //check that the correct function is written + if getFuncName(e.receiveReaction) != getFuncName(returnedHandler) { + t.Fatalf("Failed to get correct handler for '%s' after "+ + "registration, %s vs %s", mt, getFuncName(e.receiveReaction), + getFuncName(returnedHandler)) + } + + //test that writing to the same receive handler fails + err = e.RegisterReceiveHandler(mt, e.receiveTextMessage) + if err == nil { + t.Fatalf("Failed to register '%s' when it should be "+ + "sucesfull: %+v", mt, err) + } else if err != MessageTypeAlreadyRegistered { + t.Fatalf("Wrong error returned when reregierting message "+ + "tyle '%s': %+v", mt, err) + } + + //check that it is still written + returnedHandler, exists = e.registered[mt] + if !exists { + t.Fatalf("Failed to get handler '%s' after second "+ + "registration", mt) + } + + //check that the correct function is written + if getFuncName(e.receiveReaction) != getFuncName(returnedHandler) { + t.Fatalf("Failed to get correct handler for '%s' after "+ + "second registration, %s vs %s", mt, getFuncName(e.receiveReaction), + getFuncName(returnedHandler)) + } +} + +type dummyMessageTypeHandler struct { + channelID *id.ID + messageID cryptoChannel.MessageID + messageType MessageType + senderUsername string + content []byte + timestamp time.Time + lease time.Duration + round rounds.Round +} + +func (dmth *dummyMessageTypeHandler) dummyMessageTypeReceiveMessage( + channelID *id.ID, messageID cryptoChannel.MessageID, + messageType MessageType, senderUsername string, content []byte, + timestamp time.Time, lease time.Duration, round rounds.Round) { + dmth.channelID = channelID + dmth.messageID = messageID + dmth.messageType = messageType + dmth.senderUsername = senderUsername + dmth.content = content + dmth.timestamp = timestamp + dmth.lease = lease + dmth.round = round +} + +func TestEvents_triggerEvents(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + dummy := &dummyMessageTypeHandler{} + + //register the handler + mt := MessageType(42) + err := e.RegisterReceiveHandler(mt, dummy.dummyMessageTypeReceiveMessage) + if err != nil { + t.Fatalf("Error on registration, should not have happened: "+ + "%+v", err) + } + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + umi, _, _ := builtTestUMI(t, mt) + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + //call the trigger + e.triggerEvent(chID, umi, receptionID.EphemeralIdentity{}, r) + + //check the data is stored in the dummy + if !dummy.channelID.Cmp(chID) { + t.Errorf("The channel IDs do not match %s vs %s", + dummy.channelID, chID) + } + + if !dummy.messageID.Equals(umi.GetMessageID()) { + t.Errorf("The message IDs do not match %s vs %s", + dummy.messageID, umi.GetMessageID()) + } + + if dummy.messageType != mt { + t.Errorf("The message types do not match %s vs %s", + dummy.messageType, mt) + } + + if dummy.senderUsername != umi.GetUserMessage().Username { + t.Errorf("The usernames do not match %s vs %s", + dummy.senderUsername, umi.GetUserMessage().Username) + } + + if !bytes.Equal(dummy.content, umi.GetChannelMessage().Payload) { + t.Errorf("The payloads do not match %s vs %s", + dummy.content, umi.GetChannelMessage().Payload) + } + + if !dummy.timestamp.Equal(r.Timestamps[states.QUEUED]) { + t.Errorf("The timestamps do not match %s vs %s", + dummy.timestamp, r.Timestamps[states.QUEUED]) + } + + if dummy.lease != time.Duration(umi.GetChannelMessage().Lease) { + t.Errorf("The messge lease durations do not match %s vs %s", + dummy.lease, time.Duration(umi.GetChannelMessage().Lease)) + } + + if dummy.round.ID != r.ID { + t.Errorf("The messge round does not match %s vs %s", + dummy.round.ID, r.ID) + } +} + +func TestEvents_triggerAdminEvents(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + dummy := &dummyMessageTypeHandler{} + + //register the handler + mt := MessageType(42) + err := e.RegisterReceiveHandler(mt, dummy.dummyMessageTypeReceiveMessage) + if err != nil { + t.Fatalf("Error on registration, should not have happened: "+ + "%+v", err) + } + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + u, _, cm := builtTestUMI(t, mt) + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + msgID := cryptoChannel.MakeMessageID(u.userMessage.Message) + + //call the trigger + e.triggerAdminEvent(chID, cm, msgID, receptionID.EphemeralIdentity{}, r) + + //check the data is stored in the dummy + if !dummy.channelID.Cmp(chID) { + t.Errorf("The channel IDs do not match %s vs %s", + dummy.channelID, chID) + } + + if !dummy.messageID.Equals(msgID) { + t.Errorf("The message IDs do not match %s vs %s", + dummy.messageID, msgID) + } + + if dummy.messageType != mt { + t.Errorf("The message types do not match %s vs %s", + dummy.messageType, mt) + } + + if dummy.senderUsername != AdminUsername { + t.Errorf("The usernames do not match %s vs %s", + dummy.senderUsername, AdminUsername) + } + + if !bytes.Equal(dummy.content, cm.Payload) { + t.Errorf("The payloads do not match %s vs %s", + dummy.senderUsername, cm.Payload) + } + + if !dummy.timestamp.Equal(r.Timestamps[states.QUEUED]) { + t.Errorf("The timestamps do not match %s vs %s", + dummy.timestamp, r.Timestamps[states.QUEUED]) + } + + if dummy.lease != time.Duration(cm.Lease) { + t.Errorf("The messge lease durations do not match %s vs %s", + dummy.lease, time.Duration(cm.Lease)) + } + + if dummy.round.ID != r.ID { + t.Errorf("The messge round does not match %s vs %s", + dummy.round.ID, r.ID) + } +} + +func TestEvents_receiveTextMessage_Message(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + textPayload := &CMIXChannelText{ + Version: 0, + Text: "They Don't Think It Be Like It Is, But It Do", + ReplyMessageID: nil, + } + + textMarshaled, err := proto.Marshal(textPayload) + if err != nil { + t.Fatalf("failed to marshael the message proto: %+v", err) + } + + msgID := cryptoChannel.MakeMessageID(textMarshaled) + + senderUsername := "Alice" + ts := time.Now() + + lease := 69 * time.Minute + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + //call the handler + e.receiveTextMessage(chID, msgID, 0, senderUsername, + textMarshaled, ts, lease, r) + + //check the results on the model + if !me.eventReceive.channelID.Cmp(chID) { + t.Errorf("Channel ID did not propogate correctly, %s vs %s", + me.eventReceive.channelID, chID) + } + + if !me.eventReceive.messageID.Equals(msgID) { + t.Errorf("Message ID did not propogate correctly, %s vs %s", + me.eventReceive.messageID, msgID) + } + + if !me.eventReceive.reactionTo.Equals(cryptoChannel.MessageID{}) { + t.Errorf("Reaction ID is not blank, %s", + me.eventReceive.reactionTo) + } + + if me.eventReceive.senderUsername != senderUsername { + t.Errorf("SenderID propogate correctly, %s vs %s", + me.eventReceive.senderUsername, senderUsername) + } + + if me.eventReceive.timestamp != ts { + t.Errorf("Message timestamp did not propogate correctly, %s vs %s", + me.eventReceive.timestamp, ts) + } + + if me.eventReceive.lease != lease { + t.Errorf("Message lease did not propogate correctly, %s vs %s", + me.eventReceive.lease, lease) + } + + if me.eventReceive.round.ID != r.ID { + t.Errorf("Message round did not propogate correctly, %d vs %d", + me.eventReceive.round.ID, r.ID) + } +} + +func TestEvents_receiveTextMessage_Reply(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + replyMsgId := cryptoChannel.MakeMessageID([]byte("blarg")) + + textPayload := &CMIXChannelText{ + Version: 0, + Text: "They Don't Think It Be Like It Is, But It Do", + ReplyMessageID: replyMsgId[:], + } + + textMarshaled, err := proto.Marshal(textPayload) + if err != nil { + t.Fatalf("failed to marshael the message proto: %+v", err) + } + + msgID := cryptoChannel.MakeMessageID(textMarshaled) + + senderUsername := "Alice" + ts := time.Now() + + lease := 69 * time.Minute + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + //call the handler + e.receiveTextMessage(chID, msgID, 0, senderUsername, + textMarshaled, ts, lease, r) + + //check the results on the model + if !me.eventReceive.channelID.Cmp(chID) { + t.Errorf("Channel ID did not propogate correctly, %s vs %s", + me.eventReceive.channelID, chID) + } + + if !me.eventReceive.messageID.Equals(msgID) { + t.Errorf("Message ID did not propogate correctly, %s vs %s", + me.eventReceive.messageID, msgID) + } + + if !me.eventReceive.reactionTo.Equals(replyMsgId) { + t.Errorf("Reaction ID is not equal to what was passed in, "+ + "%s vs %s", me.eventReceive.reactionTo, replyMsgId) + } + + if me.eventReceive.senderUsername != senderUsername { + t.Errorf("SenderID propogate correctly, %s vs %s", + me.eventReceive.senderUsername, senderUsername) + } + + if me.eventReceive.timestamp != ts { + t.Errorf("Message timestamp did not propogate correctly, "+ + "%s vs %s", me.eventReceive.timestamp, ts) + } + + if me.eventReceive.lease != lease { + t.Errorf("Message lease did not propogate correctly, %s vs %s", + me.eventReceive.lease, lease) + } + + if me.eventReceive.round.ID != r.ID { + t.Errorf("Message round did not propogate correctly, %d vs %d", + me.eventReceive.round.ID, r.ID) + } +} + +func TestEvents_receiveTextMessage_Reply_BadReply(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + replyMsgId := []byte("blarg") + + textPayload := &CMIXChannelText{ + Version: 0, + Text: "They Don't Think It Be Like It Is, But It Do", + ReplyMessageID: replyMsgId[:], + } + + textMarshaled, err := proto.Marshal(textPayload) + if err != nil { + t.Fatalf("failed to marshael the message proto: %+v", err) + } + + msgID := cryptoChannel.MakeMessageID(textMarshaled) + + senderUsername := "Alice" + ts := time.Now() + + lease := 69 * time.Minute + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + //call the handler + e.receiveTextMessage(chID, msgID, 0, senderUsername, + textMarshaled, ts, lease, r) + + //check the results on the model + if !me.eventReceive.channelID.Cmp(chID) { + t.Errorf("Channel ID did not propogate correctly, %s vs %s", + me.eventReceive.channelID, chID) + } + + if !me.eventReceive.messageID.Equals(msgID) { + t.Errorf("Message ID did not propogate correctly, %s vs %s", + me.eventReceive.messageID, msgID) + } + + if !me.eventReceive.reactionTo.Equals(cryptoChannel.MessageID{}) { + t.Errorf("Reaction ID is not blank, %s", + me.eventReceive.reactionTo) + } + + if me.eventReceive.senderUsername != senderUsername { + t.Errorf("SenderID propogate correctly, %s vs %s", + me.eventReceive.senderUsername, senderUsername) + } + + if me.eventReceive.timestamp != ts { + t.Errorf("Message timestamp did not propogate correctly, "+ + "%s vs %s", me.eventReceive.timestamp, ts) + } + + if me.eventReceive.lease != lease { + t.Errorf("Message lease did not propogate correctly, %s vs %s", + me.eventReceive.lease, lease) + } + + if me.eventReceive.round.ID != r.ID { + t.Errorf("Message round did not propogate correctly, %d vs %d", + me.eventReceive.round.ID, r.ID) + } +} + +func TestEvents_receiveReaction(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + replyMsgId := cryptoChannel.MakeMessageID([]byte("blarg")) + + textPayload := &CMIXChannelReaction{ + Version: 0, + Reaction: "ðŸ†", + ReactionMessageID: replyMsgId[:], + } + + textMarshaled, err := proto.Marshal(textPayload) + if err != nil { + t.Fatalf("failed to marshael the message proto: %+v", err) + } + + msgID := cryptoChannel.MakeMessageID(textMarshaled) + + senderUsername := "Alice" + ts := time.Now() + + lease := 69 * time.Minute + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + //call the handler + e.receiveReaction(chID, msgID, 0, senderUsername, + textMarshaled, ts, lease, r) + + //check the results on the model + if !me.eventReceive.channelID.Cmp(chID) { + t.Errorf("Channel ID did not propogate correctly, %s vs %s", + me.eventReceive.channelID, chID) + } + + if !me.eventReceive.messageID.Equals(msgID) { + t.Errorf("Message ID did not propogate correctly, %s vs %s", + me.eventReceive.messageID, msgID) + } + + if !me.eventReceive.reactionTo.Equals(replyMsgId) { + t.Errorf("Reaction ID is not equal to what was passed in, "+ + "%s vs %s", me.eventReceive.reactionTo, replyMsgId) + } + + if me.eventReceive.senderUsername != senderUsername { + t.Errorf("SenderID propogate correctly, %s vs %s", + me.eventReceive.senderUsername, senderUsername) + } + + if me.eventReceive.timestamp != ts { + t.Errorf("Message timestamp did not propogate correctly, "+ + "%s vs %s", me.eventReceive.timestamp, ts) + } + + if me.eventReceive.lease != lease { + t.Errorf("Message lease did not propogate correctly, %s vs %s", + me.eventReceive.lease, lease) + } + + if me.eventReceive.round.ID != r.ID { + t.Errorf("Message round did not propogate correctly, %d vs %d", + me.eventReceive.round.ID, r.ID) + } +} + +func TestEvents_receiveReaction_InvalidReactionMessageID(t *testing.T) { + me := &MockEvent{} + + e := initEvents(me) + + //craft the input for the event + chID := &id.ID{} + chID[0] = 1 + + replyMsgId := []byte("blarg") + + textPayload := &CMIXChannelReaction{ + Version: 0, + Reaction: "ðŸ†", + ReactionMessageID: replyMsgId[:], + } + + textMarshaled, err := proto.Marshal(textPayload) + if err != nil { + t.Fatalf("failed to marshael the message proto: %+v", err) + } + + msgID := cryptoChannel.MakeMessageID(textMarshaled) + + senderUsername := "Alice" + ts := time.Now() + + lease := 69 * time.Minute + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED] = time.Now() + + //call the handler + e.receiveReaction(chID, msgID, 0, senderUsername, + textMarshaled, ts, lease, r) + + //check the results on the model + if me.eventReceive.channelID != nil { + t.Errorf("Channel ID did propogated correctly when the reaction " + + "is bad") + } + + if me.eventReceive.messageID.Equals(msgID) { + t.Errorf("Message ID propogated correctly when the reaction is " + + "bad") + } + + if !me.eventReceive.reactionTo.Equals(cryptoChannel.MessageID{}) { + t.Errorf("Reaction ID propogated correctly when the reaction " + + "is bad") + } + + if me.eventReceive.senderUsername != "" { + t.Errorf("SenderID propogated correctly when the reaction " + + "is bad") + } + + if me.eventReceive.lease != 0 { + t.Errorf("Message lease propogated correctly when the " + + "reaction is bad") + } +} + +// todo: enable once ValidateReaction works +/* +func TestEvents_receiveReaction_InvalidReactionContent(t *testing.T){ + me := &MockEvent{} + + e := initEvents(me) + + //craft the input for the event + chID := &id.ID{} + chID[0]=1 + + replyMsgId := []byte("blarg") + + textPayload := &CMIXChannelReaction{ + Version: 0, + Reaction: "Im not a reaction", + ReactionMessageID: replyMsgId[:], + } + + textMarshaled, err := proto.Marshal(textPayload) + if err!=nil{ + t.Fatalf("failed to marshael the message proto: %+v", err) + } + + msgID := cryptoChannel.MakeMessageID(textMarshaled) + + senderUsername := "Alice" + ts := time.Now() + + lease := 69*time.Minute + + r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)} + r.Timestamps[states.QUEUED]=time.Now() + + + //call the handler + e.receiveReaction(chID, msgID, 0, senderUsername, + textMarshaled, ts, lease, r) + + //check the results on the model + if me.eventReceive.channelID!=nil{ + t.Errorf("Channel ID did propogated correctly when the reaction " + + "is bad") + } + + if me.eventReceive.messageID.Equals(msgID){ + t.Errorf("Message ID propogated correctly when the reaction is " + + "bad") + } + + if !me.eventReceive.reactionTo.Equals(cryptoChannel.MessageID{}){ + t.Errorf("Reaction ID propogated correctly when the reaction " + + "is bad") + } + + if me.eventReceive.senderUsername!=""{ + t.Errorf("SenderID propogated correctly when the reaction " + + "is bad") + } + + if me.eventReceive.lease!=0{ + t.Errorf("Message lease propogated correctly when the " + + "reaction is bad") + } +}*/ + +func getFuncName(i interface{}) string { + return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() +} diff --git a/channels/messages.go b/channels/messages.go index 15ec90f8a..b4de7747a 100644 --- a/channels/messages.go +++ b/channels/messages.go @@ -12,14 +12,14 @@ import ( "gitlab.com/elixxir/crypto/channel" ) -// UserMessageInternal is the internal structure of a UserMessage protobuf. -type UserMessageInternal struct { +// userMessageInternal is the internal structure of a UserMessage protobuf. +type userMessageInternal struct { userMessage *UserMessage channelMessage *ChannelMessage messageID channel.MessageID } -func NewUserMessageInternal(ursMsg *UserMessage) (*UserMessageInternal, error) { +func newUserMessageInternal(ursMsg *UserMessage) (*userMessageInternal, error) { chanMessage := &ChannelMessage{} err := proto.Unmarshal(ursMsg.Message, chanMessage) if err != nil { @@ -27,14 +27,14 @@ func NewUserMessageInternal(ursMsg *UserMessage) (*UserMessageInternal, error) { } channelMessage := chanMessage - return &UserMessageInternal{ + return &userMessageInternal{ userMessage: ursMsg, channelMessage: channelMessage, messageID: channel.MakeMessageID(ursMsg.Message), }, nil } -func UnmarshalUserMessageInternal(usrMsg []byte) (*UserMessageInternal, error) { +func unmarshalUserMessageInternal(usrMsg []byte) (*userMessageInternal, error) { um := &UserMessage{} if err := proto.Unmarshal(usrMsg, um); err != nil { @@ -49,25 +49,26 @@ func UnmarshalUserMessageInternal(usrMsg []byte) (*UserMessageInternal, error) { channelMessage := chanMessage - return &UserMessageInternal{ + return &userMessageInternal{ userMessage: um, channelMessage: channelMessage, + messageID: channel.MakeMessageID(um.Message), }, nil } // GetUserMessage retrieves the UserMessage within -// UserMessageInternal. -func (umi *UserMessageInternal) GetUserMessage() *UserMessage { +// userMessageInternal. +func (umi *userMessageInternal) GetUserMessage() *UserMessage { return umi.userMessage } // GetChannelMessage retrieves the ChannelMessage within -// UserMessageInternal. -func (umi *UserMessageInternal) GetChannelMessage() *ChannelMessage { +// userMessageInternal. +func (umi *userMessageInternal) GetChannelMessage() *ChannelMessage { return umi.channelMessage } // GetMessageID retrieves the messageID for the message. -func (umi *UserMessageInternal) GetMessageID() channel.MessageID { +func (umi *userMessageInternal) GetMessageID() channel.MessageID { return umi.messageID } diff --git a/channels/messages_test.go b/channels/messages_test.go index afcb89d56..14b54553a 100644 --- a/channels/messages_test.go +++ b/channels/messages_test.go @@ -14,27 +14,27 @@ import ( "testing" ) -func TestUserMessageInternal_GetChannelMessage(t *testing.T) { - channelMsg := &ChannelMessage{ - Lease: 69, - RoundID: 42, - PayloadType: 7, - Payload: []byte("ban_badUSer"), +func TestUnmarshalUserMessageInternal(t *testing.T) { + internal, usrMsg, _ := builtTestUMI(t, 7) + + usrMsgMarshaled, err := proto.Marshal(usrMsg) + if err != nil { + t.Fatalf("Failed to marshal user message: %+v", err) } - serialized, err := proto.Marshal(channelMsg) + umi, err := unmarshalUserMessageInternal(usrMsgMarshaled) if err != nil { - t.Fatalf("Marshal error: %v", err) + t.Fatalf("Failed to unmarshal user message: %+v", err) } - usrMsg := &UserMessage{ - Message: serialized, - ValidationSignature: []byte("sig"), - Signature: []byte("sig"), - Username: "hunter", + if !umi.GetMessageID().Equals(internal.messageID) { + t.Errorf("Message IDs were changed in the unmarshal "+ + "process, %s vs %s", internal.messageID, umi.GetMessageID()) } +} - internal, _ := NewUserMessageInternal(usrMsg) +func TestUserMessageInternal_GetChannelMessage(t *testing.T) { + internal, _, channelMsg := builtTestUMI(t, 7) received := internal.GetChannelMessage() if !reflect.DeepEqual(received.Payload, channelMsg.Payload) || @@ -48,28 +48,7 @@ func TestUserMessageInternal_GetChannelMessage(t *testing.T) { } func TestUserMessageInternal_GetUserMessage(t *testing.T) { - channelMsg := &ChannelMessage{ - Lease: 69, - RoundID: 42, - PayloadType: 7, - Payload: []byte("ban_badUSer"), - } - - serialized, err := proto.Marshal(channelMsg) - if err != nil { - t.Fatalf("Marshal error: %v", err) - } - - usrMsg := &UserMessage{ - Message: serialized, - ValidationSignature: []byte("sig"), - Signature: []byte("sig2"), - Username: "hunter2", - ECCPublicKey: []byte("key"), - UsernameLease: 666, - } - - internal, _ := NewUserMessageInternal(usrMsg) + internal, usrMsg, _ := builtTestUMI(t, 7) received := internal.GetUserMessage() if !reflect.DeepEqual(received.Message, usrMsg.Message) || @@ -85,28 +64,7 @@ func TestUserMessageInternal_GetUserMessage(t *testing.T) { } func TestUserMessageInternal_GetMessageID(t *testing.T) { - channelMsg := &ChannelMessage{ - Lease: 69, - RoundID: 42, - PayloadType: 7, - Payload: []byte("ban_badUSer"), - } - - serialized, err := proto.Marshal(channelMsg) - if err != nil { - t.Fatalf("Marshal error: %v", err) - } - - usrMsg := &UserMessage{ - Message: serialized, - ValidationSignature: []byte("sig"), - Signature: []byte("sig2"), - Username: "hunter2", - ECCPublicKey: []byte("key"), - UsernameLease: 666, - } - - internal, _ := NewUserMessageInternal(usrMsg) + internal, usrMsg, _ := builtTestUMI(t, 7) received := internal.GetMessageID() expected := channel.MakeMessageID(usrMsg.Message) @@ -125,10 +83,22 @@ func TestUserMessageInternal_GetMessageID(t *testing.T) { func TestUserMessageInternal_GetMessageID_Consistency(t *testing.T) { expected := "ChMsgID-cfw4O6M47N9pqdtTcQjm/SSVqehTPGQd7cAMrNP9bcc=" + internal, _, _ := builtTestUMI(t, 7) + + received := internal.GetMessageID() + + if expected != received.String() { + t.Fatalf("GetMessageID did not return expected data."+ + "\nExpected: %v"+ + "\nReceived: %v", expected, received) + } +} + +func builtTestUMI(t *testing.T, mt MessageType) (*userMessageInternal, *UserMessage, *ChannelMessage) { channelMsg := &ChannelMessage{ Lease: 69, RoundID: 42, - PayloadType: 7, + PayloadType: uint32(mt), Payload: []byte("ban_badUSer"), } @@ -146,12 +116,7 @@ func TestUserMessageInternal_GetMessageID_Consistency(t *testing.T) { UsernameLease: 666, } - internal, _ := NewUserMessageInternal(usrMsg) - received := internal.GetMessageID() + internal, _ := newUserMessageInternal(usrMsg) - if expected != received.String() { - t.Fatalf("GetMessageID did not return expected data."+ - "\nExpected: %v"+ - "\nReceived: %v", expected, received) - } + return internal, usrMsg, channelMsg } diff --git a/channels/userListener.go b/channels/userListener.go index 366342457..a69de61f3 100644 --- a/channels/userListener.go +++ b/channels/userListener.go @@ -31,7 +31,7 @@ func (gul *userListener) Listen(payload []byte, } //Decode the message as a user message - umi, err := UnmarshalUserMessageInternal(payloadUnpadded) + umi, err := unmarshalUserMessageInternal(payloadUnpadded) if err != nil { jww.WARN.Printf("Failed to unmarshal User Message on "+ "channel %s", gul.chID) -- GitLab