mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29: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: []
|
- bearerAuth: []
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: entry created
|
description: success
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Group'
|
||||||
'401':
|
'401':
|
||||||
description: permission denied
|
description: permission denied
|
||||||
'410':
|
'410':
|
||||||
@ -870,15 +874,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
$ref: '#/components/schemas/Subject'
|
||||||
required:
|
|
||||||
- type
|
|
||||||
- data
|
|
||||||
properties:
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
data:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/share/groups/{groupId}:
|
/share/groups/{groupId}:
|
||||||
put:
|
put:
|
||||||
@ -898,6 +894,10 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: success
|
description: success
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Group'
|
||||||
'401':
|
'401':
|
||||||
description: permission denied
|
description: permission denied
|
||||||
'404':
|
'404':
|
||||||
@ -910,15 +910,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
$ref: '#/components/schemas/Subject'
|
||||||
required:
|
|
||||||
- type
|
|
||||||
- data
|
|
||||||
properties:
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
data:
|
|
||||||
type: string
|
|
||||||
delete:
|
delete:
|
||||||
tags:
|
tags:
|
||||||
- share
|
- share
|
||||||
@ -4022,6 +4014,17 @@ components:
|
|||||||
location:
|
location:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
Subject:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- dataType
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
dataType:
|
||||||
|
type: string
|
||||||
|
data:
|
||||||
|
type: string
|
||||||
|
|
||||||
Account:
|
Account:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
@ -4358,25 +4361,25 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- groupId
|
- groupId
|
||||||
- groupRevision
|
- revision
|
||||||
- type
|
- dataType
|
||||||
- data
|
- data
|
||||||
- created
|
- created
|
||||||
- modified
|
- updated
|
||||||
properties:
|
properties:
|
||||||
groupId:
|
groupId:
|
||||||
type: string
|
type: string
|
||||||
groupRevision:
|
revision:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
type:
|
dataType:
|
||||||
type: string
|
type: string
|
||||||
data:
|
data:
|
||||||
type: string
|
type: string
|
||||||
created:
|
created:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
modified:
|
updated:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ require (
|
|||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // 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/pretty v0.3.0 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.9 // 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
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
gorm.io/driver/sqlite v1.2.6 // 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.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI=
|
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.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.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
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.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||||
gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM=
|
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.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)
|
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) {
|
func SetCardNotes(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||||
w.WriteHeader(http.StatusOK)
|
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"
|
"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) {
|
func RemoveGroup(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
@ -24,6 +24,7 @@ const APP_MODULEPROFILE = "profile"
|
|||||||
const APP_MODULECONTENT = "content"
|
const APP_MODULECONTENT = "content"
|
||||||
const APP_TOKENAPP = "app"
|
const APP_TOKENAPP = "app"
|
||||||
const APP_TOKENCONTACT = "contact"
|
const APP_TOKENCONTACT = "contact"
|
||||||
|
const APP_NOTIFYBUFFER = 4096
|
||||||
|
|
||||||
func AppCardStatus(status string) bool {
|
func AppCardStatus(status string) bool {
|
||||||
if status == APP_CARDPENDING {
|
if status == APP_CARDPENDING {
|
||||||
|
@ -7,6 +7,13 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"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 {
|
func AddTestContacts(t *testing.T, prefix string, count int) []string {
|
||||||
|
|
||||||
var access []string
|
var access []string
|
||||||
@ -52,32 +59,35 @@ func AddTestContacts(t *testing.T, prefix string, count int) []string {
|
|||||||
return access
|
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 card Card
|
||||||
var msg DataMessage
|
var msg DataMessage
|
||||||
var vars map[string]string
|
var vars map[string]string
|
||||||
var contactStatus ContactStatus
|
var contactStatus ContactStatus
|
||||||
var id string
|
var id string
|
||||||
access := [2]string{accessA, accessB}
|
contact[0].AppToken = accessA
|
||||||
|
contact[1].AppToken = accessB
|
||||||
|
|
||||||
// get A identity message
|
// get A identity message
|
||||||
r, w, _ := NewRequest("GET", "/profile/message", nil)
|
r, w, _ := NewRequest("GET", "/profile/message", nil)
|
||||||
r.Header.Add("TokenType", APP_TOKENAPP)
|
r.Header.Add("TokenType", APP_TOKENAPP)
|
||||||
SetBearerAuth(r, access[0])
|
SetBearerAuth(r, accessA)
|
||||||
GetProfileMessage(w, r)
|
GetProfileMessage(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &msg))
|
assert.NoError(t, ReadResponse(w, &msg))
|
||||||
|
|
||||||
// add A card in B
|
// add A card in B
|
||||||
r, w, _ = NewRequest("POST", "/contact/cards", &msg)
|
r, w, _ = NewRequest("POST", "/contact/cards", &msg)
|
||||||
SetBearerAuth(r, access[1])
|
SetBearerAuth(r, accessB)
|
||||||
AddCard(w, r)
|
AddCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
|
contact[1].ContactCardId = card.CardId
|
||||||
|
contact[1].ContactGuid = card.CardProfile.Guid
|
||||||
|
|
||||||
// update A status to connecting
|
// update A status to connecting
|
||||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING)
|
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING)
|
||||||
vars = map[string]string{ "cardId": card.CardId }
|
vars = map[string]string{ "cardId": card.CardId }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[1])
|
SetBearerAuth(r, accessB)
|
||||||
SetCardStatus(w, r)
|
SetCardStatus(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
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)
|
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}/openMessage", nil)
|
||||||
vars = map[string]string{ "cardId": card.CardId }
|
vars = map[string]string{ "cardId": card.CardId }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[1])
|
SetBearerAuth(r, accessB)
|
||||||
GetOpenMessage(w, r)
|
GetOpenMessage(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &msg))
|
assert.NoError(t, ReadResponse(w, &msg))
|
||||||
id = card.CardId
|
id = card.CardId
|
||||||
@ -97,7 +107,7 @@ func ConnectTestContacts(t *testing.T, accessA string, accessB string) (contact
|
|||||||
|
|
||||||
// get view of cards in A
|
// get view of cards in A
|
||||||
r, w, _ = NewRequest("GET", "/contact/cards/view", nil)
|
r, w, _ = NewRequest("GET", "/contact/cards/view", nil)
|
||||||
SetBearerAuth(r, access[0])
|
SetBearerAuth(r, accessA)
|
||||||
GetCardView(w, r)
|
GetCardView(w, r)
|
||||||
var views []CardView
|
var views []CardView
|
||||||
assert.NoError(t, ReadResponse(w, &views))
|
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)
|
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
||||||
vars = map[string]string{ "cardId": views[0].CardId }
|
vars = map[string]string{ "cardId": views[0].CardId }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[0])
|
SetBearerAuth(r, accessA)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
|
contact[0].ContactCardId = card.CardId
|
||||||
|
contact[0].ContactGuid = card.CardProfile.Guid
|
||||||
|
|
||||||
// update B status to connecting
|
// update B status to connecting
|
||||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING)
|
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status", APP_CARDCONNECTING)
|
||||||
vars = map[string]string{ "cardId": views[0].CardId }
|
vars = map[string]string{ "cardId": views[0].CardId }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[0])
|
SetBearerAuth(r, accessA)
|
||||||
SetCardStatus(w, r)
|
SetCardStatus(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
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)
|
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}/openMessage", nil)
|
||||||
vars = map[string]string{ "cardId": views[0].CardId }
|
vars = map[string]string{ "cardId": views[0].CardId }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[0])
|
SetBearerAuth(r, accessA)
|
||||||
GetOpenMessage(w, r)
|
GetOpenMessage(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &msg))
|
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)
|
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/status?token=" + contactStatus.Token, APP_CARDCONNECTED)
|
||||||
vars = map[string]string{ "cardId": views[0].CardId }
|
vars = map[string]string{ "cardId": views[0].CardId }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[0])
|
SetBearerAuth(r, accessA)
|
||||||
SetCardStatus(w, r)
|
SetCardStatus(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
|
|
||||||
// extract contact tokens
|
// extract contact tokens
|
||||||
contact[0] = card.CardData.Token
|
contact[0].ContactToken = card.CardData.Token
|
||||||
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
r, w, _ = NewRequest("GET", "/contact/cards/{cardId}", nil)
|
||||||
vars = map[string]string{ "cardId": id }
|
vars = map[string]string{ "cardId": id }
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, access[1])
|
SetBearerAuth(r, accessB)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
contact[1] = card.CardData.Token
|
contact[1].ContactToken = card.CardData.Token
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
|
||||||
SetHideLog(true)
|
// SetHideLog(true)
|
||||||
SetKeySize(2048)
|
SetKeySize(2048)
|
||||||
store.SetPath("file::memory:?cache=shared");
|
store.SetPath("file::memory:?cache=shared");
|
||||||
// store.SetPath("databag.db");
|
// store.SetPath("databag.db");
|
||||||
|
@ -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"`
|
Image string `json:"image,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Subject struct {
|
||||||
|
DataType string `json:"dataType"`
|
||||||
|
Data string `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
type Article struct {
|
type Article struct {
|
||||||
ArticleId string `json:"articleId"`
|
ArticleId string `json:"articleId"`
|
||||||
ArticleRevision int64 `json:"articleRevision"`
|
ArticleRevision int64 `json:"articleRevision"`
|
||||||
@ -137,11 +142,11 @@ type DialogueInsights struct {
|
|||||||
|
|
||||||
type Group struct {
|
type Group struct {
|
||||||
GroupId string `json:"groupId"`
|
GroupId string `json:"groupId"`
|
||||||
GroupRevision int64 `json:"groupRevision"`
|
Revision int64 `json:"revision"`
|
||||||
Type_ string `json:"type"`
|
DataType string `json:"dataType"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
Created int64 `json:"created"`
|
Created int64 `json:"created"`
|
||||||
Modified int64 `json:"modified"`
|
Updated int64 `json:"updated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupsGroupIdBody struct {
|
type GroupsGroupIdBody struct {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"databag/internal/store"
|
"databag/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
var notify = make(chan *store.Notification)
|
var notify = make(chan *store.Notification, APP_NOTIFYBUFFER)
|
||||||
var notifyExit = make(chan bool)
|
var notifyExit = make(chan bool)
|
||||||
|
|
||||||
func ExitNotifications() {
|
func ExitNotifications() {
|
||||||
@ -139,34 +139,25 @@ func SetContentNotification(account *store.Account) {
|
|||||||
|
|
||||||
// notify single card of content change
|
// notify single card of content change
|
||||||
// card.View incremented by adding or removing card from group or label
|
// 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
|
if card.Status != APP_CARDCONNECTED {
|
||||||
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)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// add new notification for card
|
// add new notification for card
|
||||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
for _, card := range cards {
|
|
||||||
notification := &store.Notification{
|
notification := &store.Notification{
|
||||||
Node: card.Node,
|
Node: card.Node,
|
||||||
Module: APP_MODULECONTENT,
|
Module: APP_MODULECONTENT,
|
||||||
Token: card.OutToken,
|
Token: card.OutToken,
|
||||||
Revision: account.ViewRevision + account.ContentRevision + card.ViewRevision,
|
Revision: account.ViewRevision + account.ContentRevision + card.ViewRevision,
|
||||||
}
|
}
|
||||||
if err := tx.Save(notification).Error; err != nil {
|
|
||||||
return err
|
if res := store.DB.Save(notification).Error; res != nil {
|
||||||
}
|
ErrMsg(res)
|
||||||
|
} else {
|
||||||
notify <- notification
|
notify <- notification
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ErrMsg(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,16 +11,11 @@ func AutoMigrate(db *gorm.DB) {
|
|||||||
db.AutoMigrate(&Group{});
|
db.AutoMigrate(&Group{});
|
||||||
db.AutoMigrate(&Label{});
|
db.AutoMigrate(&Label{});
|
||||||
db.AutoMigrate(&Card{});
|
db.AutoMigrate(&Card{});
|
||||||
db.AutoMigrate(&CardGroup{});
|
|
||||||
db.AutoMigrate(&LabelGroup{});
|
|
||||||
db.AutoMigrate(&Asset{});
|
db.AutoMigrate(&Asset{});
|
||||||
db.AutoMigrate(&Article{});
|
db.AutoMigrate(&Article{});
|
||||||
db.AutoMigrate(&ArticleAsset{});
|
db.AutoMigrate(&ArticleAsset{});
|
||||||
db.AutoMigrate(&ArticleTag{});
|
db.AutoMigrate(&ArticleTag{});
|
||||||
db.AutoMigrate(&ArticleGroup{});
|
|
||||||
db.AutoMigrate(&ArticleLabel{});
|
|
||||||
db.AutoMigrate(&Dialogue{});
|
db.AutoMigrate(&Dialogue{});
|
||||||
db.AutoMigrate(&DialogueMember{});
|
|
||||||
db.AutoMigrate(&Insight{});
|
db.AutoMigrate(&Insight{});
|
||||||
db.AutoMigrate(&Topic{});
|
db.AutoMigrate(&Topic{});
|
||||||
db.AutoMigrate(&TopicAsset{});
|
db.AutoMigrate(&TopicAsset{});
|
||||||
@ -54,6 +49,9 @@ type AccountToken struct {
|
|||||||
Account Account
|
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 {
|
type Account struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
AccountDetailID uint `gorm:"not null"`
|
AccountDetailID uint `gorm:"not null"`
|
||||||
@ -118,6 +116,7 @@ type Label struct {
|
|||||||
Data string
|
Data string
|
||||||
Created int64 `gorm:"autoCreateTime"`
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
|
Groups []Group `gorm:"many2many:label_groups;"`
|
||||||
Account Account
|
Account Account
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,22 +147,6 @@ type Card struct {
|
|||||||
Account Account `gorm:"references:Guid"`
|
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 {
|
type Asset struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
AssetId string `gorm:"not null;index:asset,unique"`
|
AssetId string `gorm:"not null;index:asset,unique"`
|
||||||
@ -187,10 +170,13 @@ type Article struct {
|
|||||||
DataType string `gorm:"index"`
|
DataType string `gorm:"index"`
|
||||||
Data string
|
Data string
|
||||||
Status string `gorm:"not null;index"`
|
Status string `gorm:"not null;index"`
|
||||||
|
Expires int64
|
||||||
Created int64 `gorm:"autoCreateTime"`
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
TagUpdated int64 `gorm:"not null"`
|
TagUpdated int64 `gorm:"not null"`
|
||||||
TagRevision uint64 `gorm:"not null"`
|
TagRevision uint64 `gorm:"not null"`
|
||||||
|
Groups []Group `gorm:"many2many:article_groups;"`
|
||||||
|
Labels []Label `gorm:"many2many:article_labels;"`
|
||||||
Account Account
|
Account Account
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,22 +202,6 @@ type ArticleTag struct {
|
|||||||
Card Card
|
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 {
|
type Dialogue struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
DialogueId string `gorm:"not null;index:dialogue,unique"`
|
DialogueId string `gorm:"not null;index:dialogue,unique"`
|
||||||
@ -245,16 +215,8 @@ type Dialogue struct {
|
|||||||
MemberRevision uint64 `gorm:"not null"`
|
MemberRevision uint64 `gorm:"not null"`
|
||||||
TopicUpdated int64
|
TopicUpdated int64
|
||||||
TopicRevision uint64 `gorm:"not null"`
|
TopicRevision uint64 `gorm:"not null"`
|
||||||
|
Cards []Card `gorm:"many2many:dialog_cards;"`
|
||||||
Account Account
|
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 {
|
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