mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
adding group test
This commit is contained in:
parent
b9880227ed
commit
2a8fe4b6b8
53
doc/api.oa3
53
doc/api.oa3
@ -859,7 +859,11 @@ paths:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: entry created
|
||||
description: success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Group'
|
||||
'401':
|
||||
description: permission denied
|
||||
'410':
|
||||
@ -870,15 +874,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- type
|
||||
- data
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
$ref: '#/components/schemas/Subject'
|
||||
|
||||
/share/groups/{groupId}:
|
||||
put:
|
||||
@ -898,6 +894,10 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Group'
|
||||
'401':
|
||||
description: permission denied
|
||||
'404':
|
||||
@ -910,15 +910,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- type
|
||||
- data
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
$ref: '#/components/schemas/Subject'
|
||||
delete:
|
||||
tags:
|
||||
- share
|
||||
@ -4022,6 +4014,17 @@ components:
|
||||
location:
|
||||
type: string
|
||||
|
||||
Subject:
|
||||
type: object
|
||||
required:
|
||||
- dataType
|
||||
- data
|
||||
properties:
|
||||
dataType:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
|
||||
Account:
|
||||
type: object
|
||||
required:
|
||||
@ -4358,25 +4361,25 @@ components:
|
||||
type: object
|
||||
required:
|
||||
- groupId
|
||||
- groupRevision
|
||||
- type
|
||||
- revision
|
||||
- dataType
|
||||
- data
|
||||
- created
|
||||
- modified
|
||||
- updated
|
||||
properties:
|
||||
groupId:
|
||||
type: string
|
||||
groupRevision:
|
||||
revision:
|
||||
type: integer
|
||||
format: int64
|
||||
type:
|
||||
dataType:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
created:
|
||||
type: integer
|
||||
format: int64
|
||||
modified:
|
||||
updated:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
|
@ -8,7 +8,7 @@ require (
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.3 // indirect
|
||||
github.com/jinzhu/now v1.1.4 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.9 // indirect
|
||||
@ -19,5 +19,5 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
gorm.io/driver/sqlite v1.2.6 // indirect
|
||||
gorm.io/gorm v1.22.4 // indirect
|
||||
gorm.io/gorm v1.22.5 // indirect
|
||||
)
|
||||
|
@ -13,6 +13,8 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
|
||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI=
|
||||
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
@ -43,3 +45,5 @@ gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsj
|
||||
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM=
|
||||
gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk=
|
||||
gorm.io/gorm v1.22.5 h1:lYREBgc02Be/5lSCTuysZZDb6ffL2qrat6fg9CFbvXU=
|
||||
gorm.io/gorm v1.22.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
|
50
net/server/internal/api_addGroup.go
Normal file
50
net/server/internal/api_addGroup.go
Normal file
@ -0,0 +1,50 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/google/uuid"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func AddGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var subject Subject
|
||||
if err := ParseRequest(r, w, &subject); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
group := &store.Group{
|
||||
GroupId: uuid.New().String(),
|
||||
AccountID: account.ID,
|
||||
Revision: 0,
|
||||
DataType: subject.DataType,
|
||||
Data: subject.Data,
|
||||
}
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := store.DB.Save(group).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := store.DB.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getGroupModel(group))
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,11 +48,6 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetCardGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetCardNotes(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
28
net/server/internal/api_getGroups.go
Normal file
28
net/server/internal/api_getGroups.go
Normal file
@ -0,0 +1,28 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var storeGroups []store.Group
|
||||
if err := store.DB.Where("account_id = ?", account.ID).Find(&storeGroups).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
var groups []*Group
|
||||
for _, group := range storeGroups {
|
||||
groups = append(groups, getGroupModel(&group))
|
||||
}
|
||||
WriteResponse(w, groups)
|
||||
}
|
||||
|
79
net/server/internal/api_setCardGroup.go
Normal file
79
net/server/internal/api_setCardGroup.go
Normal file
@ -0,0 +1,79 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetCardGroup(w http.ResponseWriter, r *http.Request) {
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
cardId := params["cardId"]
|
||||
groupId := params["groupId"]
|
||||
|
||||
|
||||
// load referenced card
|
||||
var card store.Card
|
||||
if err := store.DB.Where("account_id = ? AND card_id = ?", account.Guid, cardId).First(&card).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// load referenced group
|
||||
var group store.Group
|
||||
if err := store.DB.Where("account_id = ? AND group_id = ?", account.ID, groupId).First(&group).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// save and update revision
|
||||
card.Groups = append(card.Groups, group)
|
||||
card.ViewRevision += 1
|
||||
card.DataRevision += 1
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := store.DB.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := store.DB.Preload("Groups").Save(&card).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
cardData := &CardData{
|
||||
Revision: card.DataRevision,
|
||||
Status: card.Status,
|
||||
Notes: card.Notes,
|
||||
Token: card.OutToken,
|
||||
Groups: nil,
|
||||
}
|
||||
for _, group := range card.Groups {
|
||||
cardData.Groups = append(cardData.Groups, group.GroupId)
|
||||
}
|
||||
WriteResponse(w, cardData)
|
||||
SetContactContentNotification(account, &card)
|
||||
SetStatus(account)
|
||||
}
|
||||
|
||||
|
@ -13,16 +13,6 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func AddGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -24,6 +24,7 @@ const APP_MODULEPROFILE = "profile"
|
||||
const APP_MODULECONTENT = "content"
|
||||
const APP_TOKENAPP = "app"
|
||||
const APP_TOKENCONTACT = "contact"
|
||||
const APP_NOTIFYBUFFER = 4096
|
||||
|
||||
func AppCardStatus(status string) bool {
|
||||
if status == APP_CARDPENDING {
|
||||
|
@ -7,6 +7,13 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestAccount struct {
|
||||
AppToken string
|
||||
ContactGuid string
|
||||
ContactToken string
|
||||
ContactCardId string
|
||||
}
|
||||
|
||||
func AddTestContacts(t *testing.T, prefix string, count int) []string {
|
||||
|
||||
var access []string
|
||||
@ -52,32 +59,35 @@ func AddTestContacts(t *testing.T, prefix string, count int) []string {
|
||||
return access
|
||||
}
|
||||
|
||||
func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact [2]string) {
|
||||
func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact [2]TestAccount) {
|
||||
var card Card
|
||||
var msg DataMessage
|
||||
var vars map[string]string
|
||||
var contactStatus ContactStatus
|
||||
var id string
|
||||
access := [2]string{accessA, accessB}
|
||||
contact[0].AppToken = accessA
|
||||
contact[1].AppToken = accessB
|
||||
|
||||
// get A identity message
|
||||
r, w, _ := NewRequest("GET", "/profile/message", nil)
|
||||
r.Header.Add("TokenType", APP_TOKENAPP)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetBearerAuth(r, accessA)
|
||||
GetProfileMessage(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &msg))
|
||||
|
||||
// add A card in B
|
||||
r, w, _ = NewRequest("POST", "/contact/cards", &msg)
|
||||
SetBearerAuth(r, access[1])
|
||||
SetBearerAuth(r, accessB)
|
||||
AddCard(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &card))
|
||||
contact[1].ContactCardId = card.CardId
|
||||
contact[1].ContactGuid = card.CardProfile.Guid
|
||||
|
||||
// update A status to connecting
|
||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING)
|
||||
vars = map[string]string{ "cardId": card.CardId }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[1])
|
||||
SetBearerAuth(r, accessB)
|
||||
SetCardStatus(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &card))
|
||||
|
||||
@ -85,7 +95,7 @@ func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact
|
||||
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}/openMessage", nil)
|
||||
vars = map[string]string{ "cardId": card.CardId }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[1])
|
||||
SetBearerAuth(r, accessB)
|
||||
GetOpenMessage(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &msg))
|
||||
id = card.CardId
|
||||
@ -97,7 +107,7 @@ func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact
|
||||
|
||||
// get view of cards in A
|
||||
r, w, _ = NewRequest("GET", "/contact/cards/view", nil)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetBearerAuth(r, accessA)
|
||||
GetCardView(w, r)
|
||||
var views []CardView
|
||||
assert.NoError(t, ReadResponse(w, &views))
|
||||
@ -107,15 +117,17 @@ func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact
|
||||
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
||||
vars = map[string]string{ "cardId": views[0].CardId }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetBearerAuth(r, accessA)
|
||||
GetCard(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &card))
|
||||
contact[0].ContactCardId = card.CardId
|
||||
contact[0].ContactGuid = card.CardProfile.Guid
|
||||
|
||||
// update B status to connecting
|
||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING)
|
||||
vars = map[string]string{ "cardId": views[0].CardId }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetBearerAuth(r, accessA)
|
||||
SetCardStatus(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &card))
|
||||
|
||||
@ -123,7 +135,7 @@ func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact
|
||||
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}/openMessage", nil)
|
||||
vars = map[string]string{ "cardId": views[0].CardId }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetBearerAuth(r, accessA)
|
||||
GetOpenMessage(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &msg))
|
||||
|
||||
@ -137,19 +149,19 @@ func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact
|
||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status?token=" + contactStatus.Token, APP_CARDCONNECTED)
|
||||
vars = map[string]string{ "cardId": views[0].CardId }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetBearerAuth(r, accessA)
|
||||
SetCardStatus(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &card))
|
||||
|
||||
// extract contact tokens
|
||||
contact[0] = card.CardData.Token
|
||||
contact[0].ContactToken = card.CardData.Token
|
||||
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
||||
vars = map[string]string{ "cardId": id }
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[1])
|
||||
SetBearerAuth(r, accessB)
|
||||
GetCard(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &card))
|
||||
contact[1] = card.CardData.Token
|
||||
contact[1].ContactToken = card.CardData.Token
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ import (
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
SetHideLog(true)
|
||||
// SetHideLog(true)
|
||||
SetKeySize(2048)
|
||||
store.SetPath("file::memory:?cache=shared");
|
||||
//store.SetPath("databag.db");
|
||||
// store.SetPath("databag.db");
|
||||
|
||||
r, w, _ := NewRequest("GET", "/admin/claimable", nil)
|
||||
GetNodeClaimable(w, r)
|
||||
|
@ -37,3 +37,13 @@ func getCardModel(card *store.Card) *Card {
|
||||
}
|
||||
}
|
||||
|
||||
func getGroupModel(group *store.Group) *Group {
|
||||
return &Group{
|
||||
GroupId: group.GroupId,
|
||||
Revision: group.Revision,
|
||||
DataType: group.DataType,
|
||||
Data: group.Data,
|
||||
Created: group.Created,
|
||||
Updated: group.Updated,
|
||||
}
|
||||
}
|
@ -38,6 +38,11 @@ type AppData struct {
|
||||
Image string `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
type Subject struct {
|
||||
DataType string `json:"dataType"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type Article struct {
|
||||
ArticleId string `json:"articleId"`
|
||||
ArticleRevision int64 `json:"articleRevision"`
|
||||
@ -137,11 +142,11 @@ type DialogueInsights struct {
|
||||
|
||||
type Group struct {
|
||||
GroupId string `json:"groupId"`
|
||||
GroupRevision int64 `json:"groupRevision"`
|
||||
Type_ string `json:"type"`
|
||||
Revision int64 `json:"revision"`
|
||||
DataType string `json:"dataType"`
|
||||
Data string `json:"data"`
|
||||
Created int64 `json:"created"`
|
||||
Modified int64 `json:"modified"`
|
||||
Updated int64 `json:"updated"`
|
||||
}
|
||||
|
||||
type GroupsGroupIdBody struct {
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
var notify = make(chan *store.Notification)
|
||||
var notify = make(chan *store.Notification, APP_NOTIFYBUFFER)
|
||||
var notifyExit = make(chan bool)
|
||||
|
||||
func ExitNotifications() {
|
||||
@ -139,33 +139,24 @@ func SetContentNotification(account *store.Account) {
|
||||
|
||||
// notify single card of content change
|
||||
// card.View incremented by adding or removing card from group or label
|
||||
func SetContactContentNotification(account *store.Account, cardId string) {
|
||||
func SetContactContentNotification(account *store.Account, card *store.Card) {
|
||||
|
||||
// select card if connected
|
||||
var cards []store.Card
|
||||
if err := store.DB.Where("account_id = ? AND status = ? AND card_id = ?", account.Guid, APP_CARDCONNECTED, cardId).Find(&cards).Error; err != nil {
|
||||
ErrMsg(err)
|
||||
if card.Status != APP_CARDCONNECTED {
|
||||
return
|
||||
}
|
||||
|
||||
// add new notification for card
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
for _, card := range cards {
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_MODULECONTENT,
|
||||
Token: card.OutToken,
|
||||
Revision: account.ViewRevision + account.ContentRevision + card.ViewRevision,
|
||||
}
|
||||
if err := tx.Save(notification).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
notify <- notification
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrMsg(err)
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_MODULECONTENT,
|
||||
Token: card.OutToken,
|
||||
Revision: account.ViewRevision + account.ContentRevision + card.ViewRevision,
|
||||
}
|
||||
|
||||
if res := store.DB.Save(notification).Error; res != nil {
|
||||
ErrMsg(res)
|
||||
} else {
|
||||
notify <- notification
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,16 +11,11 @@ func AutoMigrate(db *gorm.DB) {
|
||||
db.AutoMigrate(&Group{});
|
||||
db.AutoMigrate(&Label{});
|
||||
db.AutoMigrate(&Card{});
|
||||
db.AutoMigrate(&CardGroup{});
|
||||
db.AutoMigrate(&LabelGroup{});
|
||||
db.AutoMigrate(&Asset{});
|
||||
db.AutoMigrate(&Article{});
|
||||
db.AutoMigrate(&ArticleAsset{});
|
||||
db.AutoMigrate(&ArticleTag{});
|
||||
db.AutoMigrate(&ArticleGroup{});
|
||||
db.AutoMigrate(&ArticleLabel{});
|
||||
db.AutoMigrate(&Dialogue{});
|
||||
db.AutoMigrate(&DialogueMember{});
|
||||
db.AutoMigrate(&Insight{});
|
||||
db.AutoMigrate(&Topic{});
|
||||
db.AutoMigrate(&TopicAsset{});
|
||||
@ -54,6 +49,9 @@ type AccountToken struct {
|
||||
Account Account
|
||||
}
|
||||
|
||||
// NOTE: card & app reference account by guid, all other tables by id
|
||||
// because token lookup uses guid and is most common and wanted to avoid join
|
||||
// int foreign key should be faster, so left other tables with id reference
|
||||
type Account struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
AccountDetailID uint `gorm:"not null"`
|
||||
@ -118,6 +116,7 @@ type Label struct {
|
||||
Data string
|
||||
Created int64 `gorm:"autoCreateTime"`
|
||||
Updated int64 `gorm:"autoUpdateTime"`
|
||||
Groups []Group `gorm:"many2many:label_groups;"`
|
||||
Account Account
|
||||
}
|
||||
|
||||
@ -148,22 +147,6 @@ type Card struct {
|
||||
Account Account `gorm:"references:Guid"`
|
||||
}
|
||||
|
||||
type CardGroup struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
CardID uint `gorm:"not null;index:cardgroup,unique"`
|
||||
GroupID uint `gorm:"not null;index:cardgroup,unique"`
|
||||
Card Card
|
||||
Group Group
|
||||
}
|
||||
|
||||
type LabelGroup struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
LabelID uint `gorm:"not null;index:labelgroup,unique"`
|
||||
GroupID uint `gorm:"not null;index:labelgroup,unique"`
|
||||
Label Label
|
||||
Group Group
|
||||
}
|
||||
|
||||
type Asset struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
AssetId string `gorm:"not null;index:asset,unique"`
|
||||
@ -187,10 +170,13 @@ type Article struct {
|
||||
DataType string `gorm:"index"`
|
||||
Data string
|
||||
Status string `gorm:"not null;index"`
|
||||
Expires int64
|
||||
Created int64 `gorm:"autoCreateTime"`
|
||||
Updated int64 `gorm:"autoUpdateTime"`
|
||||
TagUpdated int64 `gorm:"not null"`
|
||||
TagRevision uint64 `gorm:"not null"`
|
||||
Groups []Group `gorm:"many2many:article_groups;"`
|
||||
Labels []Label `gorm:"many2many:article_labels;"`
|
||||
Account Account
|
||||
}
|
||||
|
||||
@ -216,22 +202,6 @@ type ArticleTag struct {
|
||||
Card Card
|
||||
}
|
||||
|
||||
type ArticleGroup struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
ArticleID uint `gorm:"not null;index"`
|
||||
GroupID uint `gorm:"not null;index"`
|
||||
Article Article
|
||||
Group Group
|
||||
}
|
||||
|
||||
type ArticleLabel struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
ArticleID uint `gorm:"not null;index"`
|
||||
LabelID uint `gorm:"not null;index"`
|
||||
Article Article
|
||||
Label Label
|
||||
}
|
||||
|
||||
type Dialogue struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
DialogueId string `gorm:"not null;index:dialogue,unique"`
|
||||
@ -245,16 +215,8 @@ type Dialogue struct {
|
||||
MemberRevision uint64 `gorm:"not null"`
|
||||
TopicUpdated int64
|
||||
TopicRevision uint64 `gorm:"not null"`
|
||||
Cards []Card `gorm:"many2many:dialog_cards;"`
|
||||
Account Account
|
||||
Cards []Card `gorm:"many2many:dialogue_member"`
|
||||
}
|
||||
|
||||
type DialogueMember struct {
|
||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||
DialogueID uint `gorm:"not null;index`
|
||||
CardID uint `gorm:"not null;index`
|
||||
Created int64 `gorm:"autoCreateTime"`
|
||||
Card Card
|
||||
}
|
||||
|
||||
type Insight struct {
|
||||
|
84
net/server/internal/ucGroupContact_test.go
Normal file
84
net/server/internal/ucGroupContact_test.go
Normal file
@ -0,0 +1,84 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"time"
|
||||
"testing"
|
||||
"encoding/json"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGroupContact(t *testing.T) {
|
||||
var subject *Subject
|
||||
var group Group
|
||||
var groups []Group
|
||||
var groupRevision int64
|
||||
var cardRevision int64
|
||||
var revision Revision
|
||||
var vars map[string]string
|
||||
var cardData CardData
|
||||
|
||||
// connect contacts
|
||||
access := AddTestContacts(t, "groupcontact", 2);
|
||||
contact := ConnectTestContacts(t, access[0], access[1])
|
||||
|
||||
// app connects websocket
|
||||
wsA := getTestWebsocket()
|
||||
announce := Announce{ AppToken: access[0] }
|
||||
data, _ := json.Marshal(&announce)
|
||||
wsA.WriteMessage(websocket.TextMessage, data)
|
||||
|
||||
// receive revision
|
||||
wsA.SetReadDeadline(time.Now().Add(2 * time.Second))
|
||||
_, data, _ = wsA.ReadMessage()
|
||||
assert.NoError(t, json.Unmarshal(data, &revision))
|
||||
groupRevision = revision.Group
|
||||
|
||||
// add group to conatact 0
|
||||
subject = &Subject{
|
||||
DataType: "imagroup",
|
||||
Data: "group data with name and logo",
|
||||
}
|
||||
r, w, _ := NewRequest("POST", "/share/groups", subject)
|
||||
SetBearerAuth(r, access[0])
|
||||
AddGroup(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &group))
|
||||
|
||||
// receive revision
|
||||
wsA.SetReadDeadline(time.Now().Add(2 * time.Second))
|
||||
_, data, _ = wsA.ReadMessage()
|
||||
assert.NoError(t, json.Unmarshal(data, &revision))
|
||||
assert.NotEqual(t, groupRevision, revision.Group)
|
||||
cardRevision = revision.Card
|
||||
|
||||
// set contact group
|
||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil)
|
||||
vars = make(map[string]string)
|
||||
vars["groupId"] = group.GroupId
|
||||
vars["cardId"] = contact[0].ContactCardId
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, access[0])
|
||||
SetCardGroup(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &cardData))
|
||||
assert.Equal(t, 1, len(cardData.Groups))
|
||||
|
||||
// receive revision
|
||||
wsA.SetReadDeadline(time.Now().Add(2 * time.Second))
|
||||
_, data, _ = wsA.ReadMessage()
|
||||
assert.NoError(t, json.Unmarshal(data, &revision))
|
||||
assert.NotEqual(t, cardRevision, revision.Card)
|
||||
|
||||
// show group view
|
||||
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
||||
SetBearerAuth(r, access[0])
|
||||
GetGroups(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &groups))
|
||||
assert.Equal(t, 1, len(groups))
|
||||
|
||||
PrintMsg(groups)
|
||||
|
||||
// add group
|
||||
|
||||
// show group view
|
||||
}
|
Loading…
Reference in New Issue
Block a user