diff --git a/channels/emoji.go b/channels/emoji.go
index 8d0a20a44c5c1eaa9422168fc7013302ce50d3f9..4823f6fcab737f3b0b7f9e044fcdc69b69d1c67f 100644
--- a/channels/emoji.go
+++ b/channels/emoji.go
@@ -1,14 +1,15 @@
 package channels
 
 import (
+	"bufio"
+	"bytes"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"regexp"
 )
 
-// found at https://www.regextester.com/106421
-const findEmoji = `(\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-` +
-	`\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])`
+//based on emojis found at https://unicode.org/emoji/charts/full-emoji-list.html
+const findEmoji = `[\xA9\xAE\x{2000}-\x{3300}\x{1F000}-\x{1FBFF}]`
 
 var InvalidReaction = errors.New(
 	"The reaction is not valid, it must be a single emoji")
@@ -35,8 +36,10 @@ func ValidateReaction(reaction string) error {
 		return InvalidReaction
 	}
 
-	// make sure it is only one emoji
-	if !compiledRegex.Match([]byte(reaction)) {
+	reader := bufio.NewReader(bytes.NewReader([]byte(reaction)))
+
+	// make sure it has emojis
+	if !compiledRegex.MatchReader(reader) {
 		return InvalidReaction
 	}
 
diff --git a/channels/emoji_test.go b/channels/emoji_test.go
index 2486a1c960d66f8b162b3073d26cc184a5b3cb87..f8b9f43c355574887a135fa1c6c22021c4372b19 100644
--- a/channels/emoji_test.go
+++ b/channels/emoji_test.go
@@ -1,26 +1,24 @@
 package channels
 
 import (
-	"fmt"
-	"regexp"
 	"testing"
 )
 
 func TestValidateReaction(t *testing.T) {
-	r := "🍆"
 
-	reg, _ := regexp.Compile(findEmoji)
+	testReactions := []string{"🍆", "😂", "❤", "🤣", "👍", "😭", "🙏", "😘", "🥰", "😍",
+		"😊", "☺", "A", "b", "AA", "1", "🍆🍆", "🍆A", "👍👍👍", "👍😘A", "O"}
+	expected := []error{
+		nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+		InvalidReaction, InvalidReaction, InvalidReaction, InvalidReaction,
+		InvalidReaction, InvalidReaction, InvalidReaction, InvalidReaction,
+		InvalidReaction}
 
-	fmt.Println(reg.Match([]byte("🍆")))
-	fmt.Println(reg.Match([]byte("😋")))
-	fmt.Println(reg.Match([]byte("A")))
-	fmt.Println(reg.Match([]byte("R")))
-	fmt.Println(reg.Match([]byte("#⃣")))
-	fmt.Println(reg.Match([]byte("#️⃣")))
-	fmt.Println(reg.Match([]byte("💁🏽‍♀")))
-
-	err := ValidateReaction(r)
-	if err != nil {
-		t.Errorf("Got error: %+v", err)
+	for i, r := range testReactions {
+		err := ValidateReaction(r)
+		if err != expected[i] {
+			t.Errorf("Got incorrect response for `%s` (%d): "+
+				"`%s` vs `%s`", r, i, err, expected[i])
+		}
 	}
 }
diff --git a/channels/errors.go b/channels/errors.go
index 3fd5dac363b82893946de5e5dd751c29245a3afe..008b64fccb849f556b0b86aa03b3e2a6f87fd39c 100644
--- a/channels/errors.go
+++ b/channels/errors.go
@@ -9,4 +9,6 @@ var (
 		"the channel cannot be found")
 	MessageTooLongErr = errors.New(
 		"the passed message is too long")
+	WrongPrivateKey = errors.New(
+		"the passed private key does not match the channel")
 )
diff --git a/channels/eventModel_test.go b/channels/eventModel_test.go
index 9379c19459aa81a2232503a7644342ea202dcc0b..c329ce022453e59a667c6c5f91d43bf8de1ab358 100644
--- a/channels/eventModel_test.go
+++ b/channels/eventModel_test.go
@@ -683,27 +683,25 @@ func TestEvents_receiveReaction_InvalidReactionMessageID(t *testing.T) {
 	}
 }
 
-// todo: enable once ValidateReaction works
-/*
-func TestEvents_receiveReaction_InvalidReactionContent(t *testing.T){
+func TestEvents_receiveReaction_InvalidReactionContent(t *testing.T) {
 	me := &MockEvent{}
 
 	e := initEvents(me)
 
 	//craft the input for the event
 	chID := &id.ID{}
-	chID[0]=1
+	chID[0] = 1
 
 	replyMsgId := []byte("blarg")
 
 	textPayload := &CMIXChannelReaction{
-		Version:        0,
-		Reaction:           "Im not a reaction",
+		Version:           0,
+		Reaction:          "I'm not a reaction",
 		ReactionMessageID: replyMsgId[:],
 	}
 
 	textMarshaled, err := proto.Marshal(textPayload)
-	if err!=nil{
+	if err != nil {
 		t.Fatalf("failed to marshael the message proto: %+v", err)
 	}
 
@@ -712,42 +710,41 @@ func TestEvents_receiveReaction_InvalidReactionContent(t *testing.T){
 	senderUsername := "Alice"
 	ts := time.Now()
 
-	lease := 69*time.Minute
+	lease := 69 * time.Minute
 
 	r := rounds.Round{ID: 420, Timestamps: make(map[states.Round]time.Time)}
-	r.Timestamps[states.QUEUED]=time.Now()
-
+	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{
+	if me.eventReceive.channelID != nil {
 		t.Errorf("Channel ID did propogated correctly when the reaction " +
 			"is bad")
 	}
 
-	if me.eventReceive.messageID.Equals(msgID){
+	if me.eventReceive.messageID.Equals(msgID) {
 		t.Errorf("Message ID propogated correctly when the reaction is " +
 			"bad")
 	}
 
-	if !me.eventReceive.reactionTo.Equals(cryptoChannel.MessageID{}){
+	if !me.eventReceive.reactionTo.Equals(cryptoChannel.MessageID{}) {
 		t.Errorf("Reaction ID propogated correctly when the reaction " +
 			"is bad")
 	}
 
-	if me.eventReceive.senderUsername!=""{
+	if me.eventReceive.senderUsername != "" {
 		t.Errorf("SenderID propogated correctly when the reaction " +
 			"is bad")
 	}
 
-	if me.eventReceive.lease!=0{
+	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/interface.go b/channels/interface.go
index ee5f385ae5ad1e187fb58e1325d3ecddea94037a..3d60c7a7aefb14f497e1fe9ff87969dc3c7b92cd 100644
--- a/channels/interface.go
+++ b/channels/interface.go
@@ -30,7 +30,7 @@ type Manager interface {
 	// If the final message, before being sent over the wire, is too long, this will
 	// return an error. The message must be at most 510 bytes long.
 	SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID,
-		msg []byte, validUntil time.Duration, messageType MessageType,
+		messageType MessageType, msg []byte, validUntil time.Duration,
 		params cmix.CMIXParams) (cryptoChannel.MessageID, id.Round, ephemeral.Id,
 		error)
 
diff --git a/channels/send.go b/channels/send.go
index 2523822e3166adf73cc84be8e4e8707f367fc8bc..558023c99def46f369bdb971bb74dadaed64a9c0 100644
--- a/channels/send.go
+++ b/channels/send.go
@@ -102,7 +102,7 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType,
 // If the final message, before being sent over the wire, is too long, this will
 // return an error. The message must be at most 510 bytes long.
 func (m *manager) SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID,
-	msg []byte, validUntil time.Duration, messageType MessageType,
+	messageType MessageType, msg []byte, validUntil time.Duration,
 	params cmix.CMIXParams) (cryptoChannel.MessageID, id.Round, ephemeral.Id,
 	error) {
 
@@ -112,6 +112,11 @@ func (m *manager) SendAdminGeneric(privKey *rsa.PrivateKey, channelID *id.ID,
 		return cryptoChannel.MessageID{}, 0, ephemeral.Id{}, err
 	}
 
+	//verify the private key is correct
+	if ch.broadcast.Get().RsaPubKey.N.Cmp(privKey.GetPublic().N) != 0 {
+		return cryptoChannel.MessageID{}, 0, ephemeral.Id{}, WrongPrivateKey
+	}
+
 	var msgId cryptoChannel.MessageID
 	//Note: we are not checking check if message is too long before trying to
 	//find a round
diff --git a/channels/send_test.go b/channels/send_test.go
index cf0fe39927e0c77c0b5d8a7809471133bd3ddd22..d6eb9df91dd3299c4322482a71739748d67baf73 100644
--- a/channels/send_test.go
+++ b/channels/send_test.go
@@ -1,52 +1,75 @@
 package channels
 
 import (
+	"bytes"
 	"crypto/ed25519"
+	"gitlab.com/xx_network/crypto/csprng"
 	"testing"
 	"time"
 
-	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/crypto/multicastRSA"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
 
 	"gitlab.com/elixxir/client/broadcast"
 	"gitlab.com/elixxir/client/cmix"
-	"gitlab.com/elixxir/client/cmix/message"
-	"gitlab.com/elixxir/client/cmix/rounds"
-	"gitlab.com/elixxir/client/storage/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
-	cryptoChannel "gitlab.com/elixxir/crypto/channel"
-	"gitlab.com/elixxir/crypto/fastRNG"
-	"gitlab.com/elixxir/ekv"
 )
 
-type mockBroadcastChannel struct{}
+type mockBroadcastChannel struct {
+	hasRun bool
+
+	payload []byte
+	params  cmix.CMIXParams
+
+	pk multicastRSA.PrivateKey
+
+	crypto *cryptoBroadcast.Channel
+}
 
 func (m *mockBroadcastChannel) MaxPayloadSize() int {
-	return 12345
+	return 1024
 }
 
 func (m *mockBroadcastChannel) MaxAsymmetricPayloadSize() int {
-	return 123
+	return 512
 }
 
 func (m *mockBroadcastChannel) Get() *cryptoBroadcast.Channel {
-	return &cryptoBroadcast.Channel{}
+	return m.crypto
 }
 
 func (m *mockBroadcastChannel) Broadcast(payload []byte, cMixParams cmix.CMIXParams) (
 	id.Round, ephemeral.Id, error) {
+
+	m.hasRun = true
+
+	m.payload = payload
+	m.params = cMixParams
+
 	return id.Round(123), ephemeral.Id{}, nil
 }
 
 func (m *mockBroadcastChannel) BroadcastWithAssembler(assembler broadcast.Assembler, cMixParams cmix.CMIXParams) (
 	id.Round, ephemeral.Id, error) {
-	return id.Round(123), ephemeral.Id{}, nil
+	m.hasRun = true
+
+	var err error
+
+	m.payload, err = assembler(42)
+	m.params = cMixParams
+
+	return id.Round(123), ephemeral.Id{}, err
 }
 
 func (m *mockBroadcastChannel) BroadcastAsymmetric(pk multicastRSA.PrivateKey, payload []byte,
 	cMixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
+	m.hasRun = true
+
+	m.payload = payload
+	m.params = cMixParams
+
+	m.pk = pk
 	return id.Round(123), ephemeral.Id{}, nil
 }
 
@@ -54,48 +77,25 @@ func (m *mockBroadcastChannel) BroadcastAsymmetricWithAssembler(
 	pk multicastRSA.PrivateKey, assembler broadcast.Assembler,
 	cMixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
 
-	return id.Round(123), ephemeral.Id{}, nil
-}
-
-func (m *mockBroadcastChannel) RegisterListener(listenerCb broadcast.ListenerFunc, method broadcast.Method) error {
-	return nil
-}
-
-func (m *mockBroadcastChannel) Stop() {
-}
-
-type mockBroadcastClient struct{}
-
-func (m *mockBroadcastClient) GetMaxMessageLength() int {
-	return 123
-}
-
-func (m *mockBroadcastClient) SendWithAssembler(recipient *id.ID, assembler cmix.MessageAssembler,
-	cmixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
+	m.hasRun = true
 
-	ephemeralId := ephemeral.Id{}
+	var err error
 
-	return id.Round(567), ephemeralId, nil
+	m.payload, err = assembler(42)
+	m.params = cMixParams
 
-}
+	m.pk = pk
 
-func (m *mockBroadcastClient) IsHealthy() bool {
-	return true
+	return id.Round(123), ephemeral.Id{}, err
 }
 
-func (m *mockBroadcastClient) AddIdentity(id *id.ID, validUntil time.Time, persistent bool) {
-
+func (m *mockBroadcastChannel) RegisterListener(listenerCb broadcast.ListenerFunc, method broadcast.Method) error {
+	return nil
 }
 
-func (m *mockBroadcastClient) AddService(clientID *id.ID, newService message.Service,
-	response message.Processor) {
-
+func (m *mockBroadcastChannel) Stop() {
 }
 
-func (m *mockBroadcastClient) DeleteClientService(clientID *id.ID) {}
-
-func (m *mockBroadcastClient) RemoveIdentity(id *id.ID) {}
-
 type mockNameService struct {
 	validChMsg bool
 }
@@ -105,15 +105,15 @@ func (m *mockNameService) GetUsername() string {
 }
 
 func (m *mockNameService) GetChannelValidationSignature() (signature []byte, lease time.Time) {
-	return nil, time.Now()
+	return []byte("fake validation sig"), time.Now()
 }
 
 func (m *mockNameService) GetChannelPubkey() ed25519.PublicKey {
-	return nil
+	return []byte("fake pubkey")
 }
 
 func (m *mockNameService) SignChannelMessage(message []byte) (signature []byte, err error) {
-	return nil, nil
+	return []byte("fake sig"), nil
 }
 
 func (m *mockNameService) ValidateChannelMessage(username string, lease time.Time,
@@ -121,54 +121,29 @@ func (m *mockNameService) ValidateChannelMessage(username string, lease time.Tim
 	return m.validChMsg
 }
 
-type mockEventModel struct{}
-
-func (m *mockEventModel) JoinChannel(channel *cryptoBroadcast.Channel) {}
-
-func (m *mockEventModel) LeaveChannel(channelID *id.ID) {}
-
-func (m *mockEventModel) ReceiveMessage(channelID *id.ID, messageID cryptoChannel.MessageID,
-	senderUsername string, text string,
-	timestamp time.Time, lease time.Duration, round rounds.Round) {
-}
-
-func (m *mockEventModel) ReceiveReply(ChannelID *id.ID, messageID cryptoChannel.MessageID,
-	replyTo cryptoChannel.MessageID, SenderUsername string,
-	text string, timestamp time.Time, lease time.Duration,
-	round rounds.Round) {
-
-}
-
-func (m *mockEventModel) ReceiveReaction(channelID *id.ID, messageID cryptoChannel.MessageID,
-	reactionTo cryptoChannel.MessageID, senderUsername string,
-	reaction string, timestamp time.Time, lease time.Duration,
-	round rounds.Round) {
-
-}
-
 func TestSendGeneric(t *testing.T) {
 
-	kv := versioned.NewKV(ekv.MakeMemstore())
-	client := new(mockBroadcastClient)
-	rngGen := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG)
 	nameService := new(mockNameService)
 	nameService.validChMsg = true
-	model := new(mockEventModel)
 
-	mm := NewManager(kv, client, rngGen, nameService, model)
-	m := mm.(*manager)
+	m := &manager{
+		channels: make(map[id.ID]*joinedChannel),
+		name:     nameService,
+	}
 
 	channelID := new(id.ID)
-	messageType := MessageType(Text)
+	messageType := Text
 	msg := []byte("hello world")
 	validUntil := time.Hour
 	params := new(cmix.CMIXParams)
 
+	mbc := &mockBroadcastChannel{}
+
 	m.channels[*channelID] = &joinedChannel{
-		broadcast: &mockBroadcastChannel{},
+		broadcast: mbc,
 	}
 
-	messageId, roundId, ephemeralId, err := mm.SendGeneric(
+	messageId, roundId, ephemeralId, err := m.SendGeneric(
 		channelID,
 		messageType,
 		msg,
@@ -180,4 +155,89 @@ func TestSendGeneric(t *testing.T) {
 	}
 	t.Logf("messageId %v, roundId %v, ephemeralId %v", messageId, roundId, ephemeralId)
 
+	//verify the message was handled correctly
+
+	//Unsize the broadcast
+	unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload)
+	if err != nil {
+		t.Fatalf("Failed to decode the sized broadcast: %s", err)
+	}
+
+	//decode the user message
+	umi, err := unmarshalUserMessageInternal(unsized)
+	if err != nil {
+		t.Fatalf("Failed to decode the user message: %s", err)
+	}
+
+	// do checks of the data
+	if !umi.GetMessageID().Equals(messageId) {
+		t.Errorf("The message IDs do not match. %s vs %s ",
+			umi.messageID, messageId)
+	}
+
+	if !bytes.Equal(umi.GetChannelMessage().Payload, msg) {
+		t.Errorf("The payload does not match. %s vs %s ",
+			umi.GetChannelMessage().Payload, msg)
+	}
+}
+
+func TestAdminGeneric(t *testing.T) {
+
+	nameService := new(mockNameService)
+	nameService.validChMsg = true
+
+	m := &manager{
+		channels: make(map[id.ID]*joinedChannel),
+		name:     nameService,
+	}
+
+	messageType := Text
+	msg := []byte("hello world")
+	validUntil := time.Hour
+
+	rng := &csprng.SystemRNG{}
+	ch, priv, err := cryptoBroadcast.NewChannel("test", "test", rng)
+	if err != nil {
+		t.Fatalf("Failed to generate channel: %+v", err)
+	}
+
+	mbc := &mockBroadcastChannel{crypto: ch}
+
+	m.channels[*ch.ReceptionID] = &joinedChannel{
+		broadcast: mbc,
+	}
+
+	messageId, roundId, ephemeralId, err := m.SendAdminGeneric(priv,
+		ch.ReceptionID, messageType, msg, validUntil, cmix.GetDefaultCMIXParams())
+	if err != nil {
+		t.Fatalf("Failed to SendAdminGeneric: %v", err)
+	}
+	t.Logf("messageId %v, roundId %v, ephemeralId %v", messageId, roundId, ephemeralId)
+
+	//verify the message was handled correctly
+
+	//Unsize the broadcast
+	unsized, err := broadcast.DecodeSizedBroadcast(mbc.payload)
+	if err != nil {
+		t.Fatalf("Failed to decode the sized broadcast: %s", err)
+	}
+
+	//decode the channel message
+
+	umi, err := unmarshalUserMessageInternal(unsized)
+	if err != nil {
+		t.Fatalf("Failed to decode the user message: %s", err)
+	}
+
+	// do checks of the data
+	if !umi.GetMessageID().Equals(messageId) {
+		t.Errorf("The message IDs do not match. %s vs %s ",
+			umi.messageID, messageId)
+	}
+
+	if !bytes.Equal(umi.GetChannelMessage().Payload, msg) {
+		t.Errorf("The payload does not match. %s vs %s ",
+			umi.GetChannelMessage().Payload, msg)
+	}
+	* /
 }