[TEST] review threema bot component : WIP

This commit is contained in:
Martin/Geno 2019-06-01 19:26:03 +02:00
parent bd87c4ac86
commit 6531916ce9
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
6 changed files with 212 additions and 41 deletions

View File

@ -1,6 +1,7 @@
package component package component
import ( import (
"errors"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -16,10 +17,27 @@ func TestAddComponent(t *testing.T) {
} }
func TestLoad(t *testing.T) { func TestLoad(t *testing.T) {
AddComponent("a", func(config map[string]interface{}) (Component, error) { return nil, nil }) assert := assert.New(t)
AddComponent("error", func(config map[string]interface{}) (Component, error) {
return nil, errors.New("dummy")
})
// load correct
Load([]Config{ Load([]Config{
{}, {},
// {Type: "a", Connection: "[::1]:10001"}, })
// error on component
assert.Panics(func() {
Load([]Config{
{Type: "error", Connection: "[::1]:10001"},
})
})
// error on connect
assert.Panics(func() {
Load([]Config{
{Type: "a", Connection: "[::1]:10001"},
})
}) })
} }

View File

@ -1,6 +1,7 @@
package threema package threema
import ( import (
"errors"
"strconv" "strconv"
"github.com/bdlm/log" "github.com/bdlm/log"
@ -27,6 +28,10 @@ func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
} }
account := models.AccountThreema{} account := models.AccountThreema{}
if database.Read == nil {
return nil, errors.New("no database connection")
}
database.Read.Where("xmpp_id = (?)", database.Read.Where("xmpp_id = (?)",
database.Read.Table(jid.TableName()).Select("id").Where(map[string]interface{}{ database.Read.Table(jid.TableName()).Select("id").Where(map[string]interface{}{
"local": jid.Local, "local": jid.Local,

View File

@ -11,51 +11,91 @@ import (
"dev.sum7.eu/genofire/thrempp/models" "dev.sum7.eu/genofire/thrempp/models"
) )
func (t *Threema) Bot(from *models.JID, request string) string { type Bot struct {
server := o3.ThreemaRest{} jid *models.JID
logger := log.WithFields(map[string]interface{}{ threema *Threema
"type": "threema", server o3.ThreemaRest
"jid": from.String(), logger *log.Entry
}) }
func (t *Threema) getBot(jid *models.JID) *Bot {
jidStr := jid.String()
if bot, ok := t.bot[jidStr]; ok {
return bot
}
if db := database.Read; db != nil && db.DB().Ping() == nil {
if err := db.Where(jid).First(jid); err.RecordNotFound() {
database.Write.Create(jid)
} else if err != nil {
log.Errorf("error getting jid %s from datatbase: %s", jid.String(), err.Error)
}
}
bot := &Bot{
jid: jid,
threema: t,
server: o3.ThreemaRest{},
logger: log.WithFields(map[string]interface{}{
"type": "threema",
"jid": jidStr,
}),
}
t.bot[jidStr] = bot
return bot
}
func (b *Bot) getAccount() (*Account, error) {
return b.threema.getAccount(b.jid)
}
func (b *Bot) Handle(request string) string {
switch request { switch request {
case "generate": case "generate":
return b.cmdGenerate()
case "help":
return b.cmdHelp()
}
return fmt.Sprintf("command not found\n%s", b.cmdHelp())
}
// test if account already exists func (b *Bot) cmdHelp() string {
account, err := t.getAccount(from) return `
if err == nil { generate : generate a threema id (if not exists)
return fmt.Sprintf("you already has the threema account with id: %s", string(account.TID)) `
} }
// create account func (b *Bot) cmdGenerate() string {
id, err := server.CreateIdentity() logger := b.logger.WithField("bot", "generate")
if err != nil { // test if account already exists
logger.Warnf("failed to generate: %s", err) account, err := b.getAccount()
return fmt.Sprintf("failed to create a threema account: %s", err) if err == nil {
} return fmt.Sprintf("you already has the threema account with id: %s", string(account.TID))
//TODO works it }
if err := database.Read.Where(from).First(from); err != nil {
database.Write.Create(from)
}
// store account // create account
a := models.AccountThreema{} id, err := b.server.CreateIdentity()
a.XMPPID = from.ID if err != nil {
a.TID = make([]byte, len(id.ID)) logger.Warnf("failed to generate: %s", err)
a.LSK = make([]byte, len(id.LSK)) return fmt.Sprintf("failed to create a threema account: %s", err)
copy(a.TID, id.ID[:]) }
copy(a.LSK, id.LSK[:])
database.Write.Create(&a)
// fetch account and connect // store account
account, err = t.getAccount(from) a := models.AccountThreema{}
tid := string(account.TID) a.XMPPID = b.jid.ID
if tid != "" { a.TID = make([]byte, len(id.ID))
a.LSK = make([]byte, len(id.LSK))
copy(a.TID, id.ID[:])
copy(a.LSK, id.LSK[:])
database.Write.Create(&a)
// fetch account and connect
account, err = b.getAccount()
if err != nil {
logger.Warnf("failed to generate: %s", err)
} else {
if tid := string(account.TID); tid != "" {
logger.WithField("threema", tid).Info("generate") logger.WithField("threema", tid).Info("generate")
return fmt.Sprintf("threema account with id: %s", tid) return fmt.Sprintf("threema account with id: %s", tid)
} }
logger.Warn("failed to generate") logger.Warn("failed to generate")
return "failed to create a threema account"
} }
return "command not supported" return "failed to create a threema account"
} }

View File

@ -0,0 +1,98 @@
package threema
import (
"testing"
"dev.sum7.eu/genofire/golang-lib/database"
"github.com/stretchr/testify/assert"
"dev.sum7.eu/genofire/thrempp/models"
)
func TestBot(t *testing.T) {
assert := assert.New(t)
b := Bot{
jid: &models.JID{},
threema: &Threema{
bot: make(map[string]*Bot),
},
}
msg := b.Handle("help")
assert.NotEqual("", msg)
// getAccount
a, err := b.getAccount()
assert.Error(err)
assert.Nil(a)
}
func TestGetBot(t *testing.T) {
assert := assert.New(t)
tr := Threema{
bot: make(map[string]*Bot),
}
jid := &models.JID{
Local: "a",
Domain: "example.org",
}
//
b := tr.getBot(jid)
assert.NotNil(b)
// getBot from cache
b = tr.getBot(jid)
assert.NotNil(b)
// reset cache + test jid db
tr.bot = make(map[string]*Bot)
database.Open(database.Config{
Type: "sqlite3",
Connection: "file::memory:?mode=memory",
})
defer database.Close()
b = tr.getBot(jid)
assert.NotNil(b)
}
func TestBotGenerate(t *testing.T) {
assert := assert.New(t)
threema := &Threema{
bot: make(map[string]*Bot),
accountJID: make(map[string]*Account),
}
b := threema.getBot(&models.JID{
Local: "generate",
Domain: "example.org",
})
// failed to generate without db
msg := b.Handle("generate")
assert.Equal("failed to create a threema account", msg)
database.Open(database.Config{
Type: "sqlite3",
Connection: "file::memory:?mode=memory",
})
threema = &Threema{
bot: make(map[string]*Bot),
accountJID: make(map[string]*Account),
}
b = threema.getBot(&models.JID{
Local: "generate",
Domain: "example.org",
})
// generate
msg = b.Handle("generate")
assert.Contains(msg, "threema account with id")
// alread generated
msg = b.Handle("generate")
assert.Contains(msg, "threema account with id")
database.Close()
}

View File

@ -16,12 +16,14 @@ type Threema struct {
component.Component component.Component
out chan xmpp.Packet out chan xmpp.Packet
accountJID map[string]*Account accountJID map[string]*Account
bot map[string]*Bot
} }
func NewThreema(config map[string]interface{}) (component.Component, error) { func NewThreema(config map[string]interface{}) (component.Component, error) {
return &Threema{ return &Threema{
out: make(chan xmpp.Packet), out: make(chan xmpp.Packet),
accountJID: make(map[string]*Account), accountJID: make(map[string]*Account),
bot: make(map[string]*Bot),
}, nil }, nil
} }
@ -52,8 +54,12 @@ func (t *Threema) send(packet xmpp.Packet) xmpp.Packet {
to := models.ParseJID(p.PacketAttrs.To) to := models.ParseJID(p.PacketAttrs.To)
if to.IsDomain() { if to.IsDomain() {
if from == nil {
log.Warn("recieve message without sender")
return nil
}
msg := xmpp.NewMessage("chat", "", from.String(), "", "en") msg := xmpp.NewMessage("chat", "", from.String(), "", "en")
msg.Body = t.Bot(from, p.Body) msg.Body = t.getBot(from).Handle(p.Body)
return msg return msg
} }
@ -71,7 +77,7 @@ func (t *Threema) send(packet xmpp.Packet) xmpp.Packet {
return msg return msg
} }
default: default:
log.Warnf("unkown package%v", p) log.Warnf("unkown package: %v", p)
} }
return nil return nil
} }

View File

@ -58,6 +58,7 @@ func TestSend(t *testing.T) {
tr := Threema{ tr := Threema{
out: out, out: out,
accountJID: make(map[string]*Account), accountJID: make(map[string]*Account),
bot: make(map[string]*Bot),
} }
go func() { go func() {
tr.Send(xmpp.Message{ tr.Send(xmpp.Message{
@ -76,11 +77,14 @@ func TestSend(t *testing.T) {
// chat with bot // chat with bot
p = tr.send(xmpp.Message{ p = tr.send(xmpp.Message{
PacketAttrs: xmpp.PacketAttrs{To: "example.org"}, PacketAttrs: xmpp.PacketAttrs{
From: "a@example.com",
To: "example.org",
},
}) })
assert.NotNil(p) assert.NotNil(p)
msg = p.(xmpp.Message) msg = p.(xmpp.Message)
assert.Equal("command not supported", msg.Body) assert.Contains(msg.Body, "command not found")
// chat with delivier error // chat with delivier error
database.Open(database.Config{ database.Open(database.Config{