Skip to content

Commit

Permalink
Add AuthorID and Data fields to ReceiveMessageEvent and Message type
Browse files Browse the repository at this point in the history
  • Loading branch information
fgrosse committed Mar 30, 2019
1 parent abd7a6e commit 146639b
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 13 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
Nothing so far
- Add ReceiveMessageEvent.Data field to allow using the underlying message type of the adapters
- Add ReceiveMessageEvent.AuthorID field to identify the author of the message
- Add Message.Data field which contains a copy of the ReceiveMessageEvent.Data value
- Add Message.AuthorID field which contains a copy of the ReceiveMessageEvent.AuthorID value

## [v0.6.0] - 2019-03-30
### Added
Expand Down
6 changes: 5 additions & 1 deletion adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ type Adapter interface {
// The CLIAdapter is the default Adapter implementation that the bot uses if no
// other adapter was configured. It emits a ReceiveMessageEvent for each line it
// receives from stdin and prints all sent messages to stdout.
//
// The CLIAdapter does not set the Message.Data field.
type CLIAdapter struct {
Prefix string
Input io.ReadCloser
Output io.Writer
Logger *zap.Logger
Author string // used to set the author of the messages, defaults to os.Getenv("USER)
mu sync.Mutex // protects the Output and closing channel
closing chan chan error
}
Expand All @@ -44,6 +47,7 @@ func NewCLIAdapter(name string, logger *zap.Logger) *CLIAdapter {
Input: os.Stdin,
Output: os.Stdout,
Logger: logger,
Author: os.Getenv("USER"),
closing: make(chan chan error),
}
}
Expand Down Expand Up @@ -88,7 +92,7 @@ func (a *CLIAdapter) loop(brain *Brain) {
}

lines = nil // disable this case and wait for the callback
brain.Emit(ReceiveMessageEvent{Text: msg}, callbackFun)
brain.Emit(ReceiveMessageEvent{Text: msg, AuthorID: a.Author}, callbackFun)

case <-callback:
// This case is executed after all ReceiveMessageEvent handlers have
Expand Down
21 changes: 21 additions & 0 deletions adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func cliTestAdapter(t *testing.T) (a *joe.CLIAdapter, output *bytes.Buffer) {
a = joe.NewCLIAdapter("test", logger)
output = new(bytes.Buffer)
a.Output = output
a.Author = "TestUser" // ensure tests never depend on external factors such as os.Getenv(…)
return a, output
}

Expand Down Expand Up @@ -62,6 +63,26 @@ func TestCLIAdapter_Send(t *testing.T) {
assert.Equal(t, "Hello World\n", output.String())
}

func TestCLIAdapter_Send_Author(t *testing.T) {
input := new(bytes.Buffer)
a, _ := cliTestAdapter(t)
a.Input = ioutil.NopCloser(input)
a.Author = "Friedrich"
brain := joetest.NewBrain(t)
messages := brain.Events()

input.WriteString("Test\n")

// Start the Goroutine of the adapter which consumes the input
a.RegisterAt(brain.Brain)

msg := <-messages
assert.Equal(t, "Friedrich", msg.Data.(joe.ReceiveMessageEvent).AuthorID)

brain.Finish()
assert.NoError(t, a.Close())
}

func TestCLIAdapter_Close(t *testing.T) {
input := new(bytes.Buffer)
a, output := cliTestAdapter(t)
Expand Down
12 changes: 7 additions & 5 deletions bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,13 @@ func (b *Bot) RespondRegex(expr string, fun func(Message) error) {
}

return fun(Message{
Context: ctx,
Text: evt.Text,
Channel: evt.Channel,
Matches: matches[1:],
adapter: b.Adapter,
Context: ctx,
Text: evt.Text,
AuthorID: evt.AuthorID,
Data: evt.Data,
Channel: evt.Channel,
Matches: matches[1:],
adapter: b.Adapter,
})
})
}
Expand Down
55 changes: 55 additions & 0 deletions bot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,61 @@ func TestBot_Respond(t *testing.T) {
}
}

func TestBot_Respond_Data(t *testing.T) {
b := joetest.NewBot(t)
handledMessages := make(chan joe.Message)
b.Respond("Test message", func(msg joe.Message) error {
handledMessages <- msg
return nil
})

b.Start()
defer b.Stop()

type CustomData struct {
Foo string
}

// Test if extra data passed via the ReceiveMessageEvent is copied to the Message
data := &CustomData{Foo: "bar"}
b.Brain.Emit(joe.ReceiveMessageEvent{
Text: "Test message",
Data: data,
})

select {
case msg := <-handledMessages:
assert.Equal(t, data, msg.Data)
case <-time.After(time.Second):
t.Error("Timeout")
}
}

func TestBot_Respond_AuthorID(t *testing.T) {
b := joetest.NewBot(t)
handledMessages := make(chan joe.Message)
b.Respond("Test message", func(msg joe.Message) error {
handledMessages <- msg
return nil
})

b.Start()
defer b.Stop()

// Test if extra data passed via the ReceiveMessageEvent is copied to the Message
b.Brain.Emit(joe.ReceiveMessageEvent{
Text: "Test message",
AuthorID: "Friedrich",
})

select {
case msg := <-handledMessages:
assert.Equal(t, "Friedrich", msg.AuthorID)
case <-time.After(time.Second):
t.Error("Timeout")
}
}

func TestBot_Respond_Matches(t *testing.T) {
b := joetest.NewBot(t)
handledMessages := make(chan joe.Message)
Expand Down
11 changes: 9 additions & 2 deletions events.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ type ShutdownEvent struct{}
// The ReceiveMessageEvent is typically emitted by an Adapter when the Bot sees
// a new message from the chat.
type ReceiveMessageEvent struct {
Text string
Channel string
Text string // The message text.
AuthorID string // A string identifying the author of the message on the adapter.
Channel string // The channel over which the message was received.

// A message may optionally also contain additional information that was
// received by the Adapter (e.g. with the slack adapter this may be the
// *slack.MessageEvent. Each Adapter implementation should document if and
// what information is available here, if any at all.
Data interface{}
}

// The UserTypingEvent is emitted by the Adapter and indicates that the Bot
Expand Down
10 changes: 6 additions & 4 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
// to the RespondFunc that was registered via Bot.Respond(…) or Bot.RespondRegex(…)
// when the message matches the regular expression of the handler.
type Message struct {
Context context.Context
Text string
Channel string
Matches []string // contains all sub matches of the regular expression that matched the Text
Context context.Context
Text string
AuthorID string
Channel string
Matches []string // contains all sub matches of the regular expression that matched the Text
Data interface{} // corresponds to the ReceiveMessageEvent.Data field

adapter Adapter
}
Expand Down

0 comments on commit 146639b

Please sign in to comment.