test for clearing card group

This commit is contained in:
Roland Osborne 2022-02-11 13:07:39 -08:00
parent 342c9a79d9
commit ee2e9edd68
12 changed files with 231 additions and 45 deletions

View File

@ -2050,7 +2050,7 @@ paths:
put:
tags:
- content
description: Set group for channels. Access granted to app tokens for account holder.
description: Set group for read access to channel. Access granted to app tokens for account holder.
operationId: set-channel-group
security:
- bearerAuth: []
@ -2085,7 +2085,7 @@ paths:
delete:
tags:
- content
description: Clear sharing group for channel. Access granted to app tokens for account holder.
description: Clear read access to channel for group. Access granted to app tokens for account holder.
operationId: clear-channel-group
security:
- bearerAuth: []
@ -2118,6 +2118,78 @@ paths:
'500':
description: internal server error
/content/channels/{channelId}/cards/{cardId}:
put:
tags:
- content
description: Set card for write access to channel. Access granted to app tokens for account holder.
operationId: set-channel-card
security:
- bearerAuth: []
parameters:
- name: channelId
in: path
description: specified channel id
required: true
schema:
type: string
- name: cardId
in: path
description: specified card id
required: true
schema:
type: string
responses:
'200':
description: success
content:
application/json:
schema:
$ref: '#/components/schemas/Channel'
'401':
description: permission denied
'404':
description: card or group not found
'410':
description: account disabled
'500':
description: internal server error
delete:
tags:
- content
description: Clear write access to channel for card. Access granted to app tokens for account holder.
operationId: clear-channel-card
security:
- bearerAuth: []
parameters:
- name: channelId
in: path
description: specified channel id
required: true
schema:
type: string
- name: cardId
in: path
description: specified card id
required: true
schema:
type: string
responses:
'200':
description: success
content:
application/json:
schema:
$ref: '#/components/schemas/Channel'
'401':
description: permission denied
'404':
description: card or group not found
'410':
description: account disabled
'500':
description: internal server error
/content/channels/{channelId}/topics:
get:
tags:
@ -3141,18 +3213,12 @@ components:
updated:
type: integer
format: int64
viewers:
groups:
$ref: '#/components/schemas/ChannelGroups'
cards:
type: array
items:
type: string
viewerGroups:
$ref: '#/components/schemas/ChannelGroups'
members:
type: array
items:
type: string
memberGroups:
$ref: '#/components/schemas/ChannelGroups'
ChannelSize:
type: object
@ -3520,3 +3586,4 @@ components:
scheme: bearer

View File

@ -0,0 +1,84 @@
package databag
import (
"errors"
"net/http"
"gorm.io/gorm"
"github.com/gorilla/mux"
"databag/internal/store"
)
func ClearCardGroup(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 cardSlot store.CardSlot
if err := store.DB.Preload("Card").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&cardSlot).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
ErrResponse(w, http.StatusNotFound, err)
} else {
ErrResponse(w, http.StatusInternalServerError, err)
}
return
}
if cardSlot.Card == nil {
ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted"))
return
}
// load referenced group
var groupSlot store.GroupSlot
if err := store.DB.Preload("Group").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&groupSlot).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
ErrResponse(w, http.StatusInternalServerError, err)
} else {
ErrResponse(w, http.StatusNotFound, err)
}
return
}
if groupSlot.Group == nil {
ErrResponse(w, http.StatusNotFound, errors.New("referenced deleted group"))
return
}
// save and update revision
cardSlot.Revision = account.CardRevision + 1
err = store.DB.Transaction(func(tx *gorm.DB) error {
if res := tx.Model(&cardSlot.Card).Association("Groups").Delete(groupSlot.Group); res != nil {
return res
}
if res := tx.Model(&cardSlot.Card).Update("detail_revision", cardSlot.Card.DetailRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&cardSlot.Card).Update("view_revision", cardSlot.Card.ViewRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&cardSlot).Update("revision", account.CardRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
return res
}
return nil
})
if err != nil {
ErrResponse(w, http.StatusInternalServerError, err)
return
}
SetContactViewNotification(account, cardSlot.Card)
SetStatus(account)
WriteResponse(w, getCardModel(&cardSlot))
}

View File

@ -13,11 +13,6 @@ import (
"net/http"
)
func ClearCardGroup(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
}
func GetCloseMessage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)

View File

@ -33,6 +33,11 @@ func AddChannelTopicTag(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func ClearChannelCard(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
}
func ClearChannelGroup(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
@ -118,6 +123,11 @@ func RemoveChannelTopicTag(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func SetChannelCard(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
}
func SetChannelConfirmed(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)

View File

@ -18,7 +18,7 @@ func GetCard(w http.ResponseWriter, r *http.Request) {
cardId := mux.Vars(r)["cardId"]
var slot store.CardSlot
if err := store.DB.Preload("Card.Groups").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil {
if err := store.DB.Preload("Card.Groups.GroupSlot").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
ErrResponse(w, http.StatusNotFound, err)
} else {

View File

@ -32,7 +32,7 @@ func NotifyArticleRevision(card *store.Card, revision int64) error {
act := &card.Account
err := store.DB.Transaction(func(tx *gorm.DB) error {
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_article", revision).Error; res != nil {
return res
}
if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil {

View File

@ -51,19 +51,22 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) {
}
// save and update revision
slot.Card.Groups = append(slot.Card.Groups, *groupSlot.Group)
slot.Card.ViewRevision += 1
slot.Revision = account.CardRevision + 1
err = store.DB.Transaction(func(tx *gorm.DB) error {
if res := tx.Model(&slot.Card).Association("Groups").Append(groupSlot.Group); res != nil {
return res
}
if res := tx.Model(&slot.Card).Update("detail_revision", slot.Card.DetailRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&slot.Card).Update("view_revision", slot.Card.ViewRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&slot).Update("revision", account.CardRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
return res
}
if res := tx.Save(&slot.Card).Error; res != nil {
return res
}
if res := tx.Preload("CardData.Groups").Save(&slot).Error; res != nil {
return res
}
return nil
})
if err != nil {

View File

@ -32,7 +32,7 @@ func NotifyChannelRevision(card *store.Card, revision int64) error {
act := &card.Account
err := store.DB.Transaction(func(tx *gorm.DB) error {
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_channel", revision).Error; res != nil {
return res
}
if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil {

View File

@ -32,7 +32,7 @@ func NotifyViewRevision(card *store.Card, revision int64) error {
act := &card.Account
err := store.DB.Transaction(func(tx *gorm.DB) error {
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_view", revision).Error; res != nil {
return res
}
if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil {

View File

@ -177,13 +177,9 @@ type ChannelDetail struct {
Updated int64 `json:"updated"`
Viewers []string `json:"viewers,omitempty"`
Groups *ChannelGroups `json:"groups,omitempty"`
ViewerGroups *ChannelGroups `json:"viewerGroups,omitempty"`
Members []string `json:"members,omitempty"`
MemberGroups *ChannelGroups `json:"memberGroups,omitempty"`
Cards []string `json:"cards"`
}
type ChannelGroups struct {

View File

@ -145,13 +145,6 @@ var routes = Routes{
GetAccountUsername,
},
Route{
"GetCard",
strings.ToUpper("Get"),
"/contact/cards/{cardId}",
GetCard,
},
Route{
"GetPublicStatus",
strings.ToUpper("Get"),
@ -523,6 +516,13 @@ var routes = Routes{
AddChannelTopicTag,
},
Route{
"ClearChannelCard",
strings.ToUpper("Delete"),
"/content/channels/{channelId}/cards/{cardId}",
ClearChannelCard,
},
Route{
"ClearChannelGroup",
strings.ToUpper("Delete"),
@ -642,6 +642,13 @@ var routes = Routes{
RemoveChannelTopicTag,
},
Route{
"SetChannelCard",
strings.ToUpper("Put"),
"/content/channels/{channelId}/cards/{cardId}",
SetChannelCard,
},
Route{
"SetChannelConfirmed",
strings.ToUpper("Put"),
@ -719,3 +726,4 @@ var routes = Routes{
Status,
},
}

View File

@ -10,7 +10,7 @@ import (
func TestContactSync(t *testing.T) {
var profile Profile
var msg DataMessage
var card Card
var card *Card
param := map[string]string{}
var img []byte
var data []byte
@ -21,6 +21,7 @@ func TestContactSync(t *testing.T) {
var detailRevision int64
var detail CardDetail
var rev *Revision
var viewRevision int64
// setup testing group
set, err := AddTestGroup("contactsync")
@ -72,7 +73,7 @@ func TestContactSync(t *testing.T) {
// clear card notes
GetTestRevision(set.B.Revisions)
assert.NoError(t, ApiTestMsg(ClearCardNotes, "DELETE", "/conact/cards/{cardId}/notes",
assert.NoError(t, ApiTestMsg(ClearCardNotes, "DELETE", "/contact/cards/{cardId}/notes",
&param, nil, APP_TOKENAPP, set.B.Token, &detail, nil))
assert.NotEqual(t, rev.Card, GetTestRevision(set.B.Revisions).Card)
cards = &[]Card{}
@ -81,4 +82,26 @@ func TestContactSync(t *testing.T) {
assert.Equal(t, 1, len(*cards))
assert.NotEqual(t, detailRevision, (*cards)[0].Data.DetailRevision)
// remove card from group
card = &Card{}
param["cardId"] = set.B.A.CardId
assert.NoError(t, ApiTestMsg(GetCard, "GET", "/contact/cards/{cardId}",
&param, nil, APP_TOKENAPP, set.B.Token, card, nil))
viewRevision = card.Data.NotifiedView
card = &Card{}
param["cardId"] = set.A.B.CardId
param["groupId"] = set.A.B.GroupId
assert.NoError(t, ApiTestMsg(ClearCardGroup, "DELETE", "/contact/cards/{cardId}/groups/{groupId}",
&param, nil, APP_TOKENAPP, set.A.Token, card, nil))
assert.Equal(t, 0, len(card.Data.CardDetail.Groups))
assert.NotEqual(t, rev.Card, GetTestRevision(set.B.Revisions).Card)
card = &Card{}
param["cardId"] = set.B.A.CardId
assert.NoError(t, ApiTestMsg(GetCard, "GET", "/contact/cards/{cardId}",
&param, nil, APP_TOKENAPP, set.B.Token, card, nil))
assert.NotEqual(t, viewRevision, card.Data.NotifiedView)
PrintMsg(card)
}