diff --git a/net/server/internal/api_status.go b/net/server/internal/api_status.go index 02d4077f..c7385089 100644 --- a/net/server/internal/api_status.go +++ b/net/server/internal/api_status.go @@ -138,7 +138,7 @@ func AddStatusListener(act uint, ch chan<-[]byte) { // add new listener to map chs, ok := statusListener[act] if ok { - chs = append(chs, ch) + statusListener[act] = append(chs, ch) } else { statusListener[act] = []chan<-[]byte{ch} } diff --git a/net/server/internal/testApp.go b/net/server/internal/testApp.go new file mode 100644 index 00000000..6261cc93 --- /dev/null +++ b/net/server/internal/testApp.go @@ -0,0 +1,147 @@ +package databag + +import ( + "time" + "errors" + "sync" + "encoding/json" + "github.com/gorilla/websocket" +) + +const TEST_TIMEOUT = 5 + +type TestCondition struct { + check func(*TestApp) bool + channel chan bool +} + +type TestChannel struct { + channel Channel + topics map[string]Topic +} + +type TestContactData struct { + card Card + articles map[string]Article + channels map[string]TestChannel +} + +func NewTestApp() *TestApp { + return &TestApp{ + articles: make(map[string]Article), + channels: make(map[string]TestChannel), + contacts: make(map[string]TestContactData), + } +} + +type TestApp struct { + name string + revision Revision + profile Profile + articles map[string]Article + channels map[string]TestChannel + contacts map[string]TestContactData + + token string + + mutex sync.Mutex + condition *TestCondition +} + +func (a *TestApp) UpdateProfile() error { + var profile Profile + err := ApiTestMsg(GetProfile, "GET", "/profile", nil, nil, APP_TOKENAPP, a.token, &profile, nil) + if err == nil { + a.profile = profile + } + return err +} + +func (a *TestApp) UpdateApp(rev *Revision) { + a.mutex.Lock() + defer a.mutex.Unlock() + + if rev.Profile != a.revision.Profile { + if err := a.UpdateProfile(); err != nil { + PrintMsg(err) + } else { + a.revision.Profile = rev.Profile + } + } + + if a.condition != nil { + if a.condition.check(a) { + a.condition.channel <- true + } + } +} + +func (a *TestApp) Connect(token string) error { + var revision Revision + var data []byte + var dataType int + + a.token = token + + // connect websocket + ws, err := StatusConnection(token, &revision) + if err != nil { + return err + } + a.UpdateApp(&revision) + + // reset any timeout + ws.SetReadDeadline(time.Time{}) + + // read revision update + for ;; { + if dataType, data, err = ws.ReadMessage(); err != nil { + return errors.New("failed to read status conenction") + } + if dataType != websocket.TextMessage { + return errors.New("invalid status data type") + } + rev := &Revision{} + if err = json.Unmarshal(data, rev); err != nil { + return errors.New("invalid status data") + } + a.UpdateApp(rev) + } + +} + +func (a *TestApp) setCondition(test *TestCondition) { + a.mutex.Lock() + if test.check(a) { + test.channel <- true + } else { + a.condition = test + } + a.mutex.Unlock() +} + +func (a *TestApp) clearCondition() { + a.mutex.Lock() + a.condition = nil + a.mutex.Unlock() +} + +func (a *TestApp) WaitFor(check func(*TestApp) bool) error { + var done = make(chan bool, 1) + var wake = make(chan bool, 1) + a.setCondition(&TestCondition{channel: done, check: check, }) + go func(){ + time.Sleep(TEST_TIMEOUT * time.Second) + wake <- true + }() + select { + case <-done: + a.clearCondition() + return nil + case <-wake: + a.clearCondition() + return errors.New("timeout waiting for condition") + } +} + + diff --git a/net/server/internal/ucContactApp_test.go b/net/server/internal/ucContactApp_test.go new file mode 100644 index 00000000..6b274e2a --- /dev/null +++ b/net/server/internal/ucContactApp_test.go @@ -0,0 +1,43 @@ +package databag + +import ( + "testing" + "github.com/stretchr/testify/assert" +) + +func TestContactApp(t *testing.T) { + + // allocate test accounts + set, err := AddTestGroup("contactapp") + assert.NoError(t, err) + + // allocate new test app + app := NewTestApp() + go app.Connect(set.A.Token) + + // wait for test + assert.NoError(t, app.WaitFor(func(testApp *TestApp)bool{ + if testApp.profile.Handle == "contactappA" { + return true + } + return false + })) + + // update profile name + profileData := &ProfileData{ + Name: "Roland", + Location: "San Diago", + }; + assert.NoError(t, ApiTestMsg(SetProfile, "PUT", "/profile/data", nil, profileData, + APP_TOKENAPP, set.A.Token, nil, nil)) + + // wait for test + assert.NoError(t, app.WaitFor(func(testApp *TestApp)bool{ + if testApp.profile.Location == "San Diago" { + return true + } + return false + })) + + +}