[TEST] review threema bot component : WIP
This commit is contained in:
parent
bd87c4ac86
commit
6531916ce9
|
@ -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"},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -11,36 +11,75 @@ 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())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bot) cmdHelp() string {
|
||||||
|
return `
|
||||||
|
generate : generate a threema id (if not exists)
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bot) cmdGenerate() string {
|
||||||
|
logger := b.logger.WithField("bot", "generate")
|
||||||
// test if account already exists
|
// test if account already exists
|
||||||
account, err := t.getAccount(from)
|
account, err := b.getAccount()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return fmt.Sprintf("you already has the threema account with id: %s", string(account.TID))
|
return fmt.Sprintf("you already has the threema account with id: %s", string(account.TID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// create account
|
// create account
|
||||||
id, err := server.CreateIdentity()
|
id, err := b.server.CreateIdentity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnf("failed to generate: %s", err)
|
logger.Warnf("failed to generate: %s", err)
|
||||||
return fmt.Sprintf("failed to create a threema account: %s", err)
|
return fmt.Sprintf("failed to create a threema account: %s", err)
|
||||||
}
|
}
|
||||||
//TODO works it
|
|
||||||
if err := database.Read.Where(from).First(from); err != nil {
|
|
||||||
database.Write.Create(from)
|
|
||||||
}
|
|
||||||
|
|
||||||
// store account
|
// store account
|
||||||
a := models.AccountThreema{}
|
a := models.AccountThreema{}
|
||||||
a.XMPPID = from.ID
|
a.XMPPID = b.jid.ID
|
||||||
a.TID = make([]byte, len(id.ID))
|
a.TID = make([]byte, len(id.ID))
|
||||||
a.LSK = make([]byte, len(id.LSK))
|
a.LSK = make([]byte, len(id.LSK))
|
||||||
copy(a.TID, id.ID[:])
|
copy(a.TID, id.ID[:])
|
||||||
|
@ -48,14 +87,15 @@ func (t *Threema) Bot(from *models.JID, request string) string {
|
||||||
database.Write.Create(&a)
|
database.Write.Create(&a)
|
||||||
|
|
||||||
// fetch account and connect
|
// fetch account and connect
|
||||||
account, err = t.getAccount(from)
|
account, err = b.getAccount()
|
||||||
tid := string(account.TID)
|
if err != nil {
|
||||||
if tid != "" {
|
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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{
|
||||||
|
|
Reference in New Issue