testing article update

This commit is contained in:
Roland Osborne 2022-02-13 21:36:29 -08:00
parent 29e84ebbb9
commit 579052d7bc
10 changed files with 100 additions and 21 deletions

View File

@ -878,12 +878,12 @@ paths:
schema: schema:
$ref: '#/components/schemas/Subject' $ref: '#/components/schemas/Subject'
/alias/groups/{groupId}: /alias/groups/{groupId}/subject:
put: put:
tags: tags:
- alias - alias
description: Update group description for sharing. Access granted to app tokens of account holder. description: Update group description for sharing. Access granted to app tokens of account holder.
operationId: update-group operationId: set-group-subject
security: security:
- bearerAuth: [] - bearerAuth: []
parameters: parameters:

View File

@ -33,8 +33,4 @@ func SetArticleGroup(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
func SetArticleSubject(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
}

View File

@ -0,0 +1,81 @@
package databag
import (
"errors"
"net/http"
"gorm.io/gorm"
"github.com/gorilla/mux"
"databag/internal/store"
)
func SetArticleSubject(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)
articleId := params["articleId"]
var subject Subject
if err := ParseRequest(r, w, &subject); err != nil {
ErrResponse(w, http.StatusBadRequest, err)
return
}
// load referenced article
var slot store.ArticleSlot
if err := store.DB.Preload("Article.Groups.Cards").Where("account_id = ? AND article_slot_id = ?", account.ID, articleId).First(&slot).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
ErrResponse(w, http.StatusInternalServerError, err)
} else {
ErrResponse(w, http.StatusNotFound, err)
}
return
}
if slot.Article == nil {
ErrResponse(w, http.StatusNotFound, errors.New("article has been deleted"))
return
}
// determine affected contact list
cards := make(map[string]*store.Card)
for _, group := range slot.Article.Groups {
for _, card := range group.Cards {
cards[card.Guid] = &card
}
}
// save and update contact revision
err = store.DB.Transaction(func(tx *gorm.DB) error {
if res := tx.Model(&slot.Article).Update("data", subject.Data).Error; res != nil {
return res
}
if res := tx.Model(&slot.Article).Update("data_type", subject.DataType).Error; res != nil {
return res
}
if res := tx.Model(&slot).Update("revision", account.ArticleRevision + 1).Error; res != nil {
return res
}
if res := tx.Model(&account).Update("article_revision", account.ArticleRevision + 1).Error; res != nil {
return res
}
return nil
})
if err != nil {
ErrResponse(w, http.StatusInternalServerError, err)
return
}
// notify contacts of content change
SetStatus(account)
for _, card := range cards {
SetContactArticleNotification(account, card)
}
WriteResponse(w, getArticleModel(&slot, true));
}

View File

@ -8,7 +8,7 @@ import (
"databag/internal/store" "databag/internal/store"
) )
func UpdateGroup(w http.ResponseWriter, r *http.Request) { func SetGroupSubject(w http.ResponseWriter, r *http.Request) {
account, code, err := BearerAppToken(r, false); account, code, err := BearerAppToken(r, false);
if err != nil { if err != nil {

View File

@ -27,11 +27,10 @@ const APP_NOTIFYVIEW = "view"
const APP_TOKENAPP = "app" const APP_TOKENAPP = "app"
const APP_TOKENCONTACT = "contact" const APP_TOKENCONTACT = "contact"
const APP_NOTIFYBUFFER = 4096 const APP_NOTIFYBUFFER = 4096
const APP_ARTICLEUNCONFIRMED = "unconfirmed" const APP_TOPICUNCONFIRMED = "unconfirmed"
const APP_ARTICLECONFIRMED = "confirmed" const APP_TOPICCONFIRMED = "confirmed"
const APP_ARTICLEINCOMPLETE = "incomplete" const APP_TOPICINCOMPLETE = "incomplete"
const APP_ARTICLEERROR = "error" const APP_TOPICERROR = "error"
const APP_ARTICLEBLOCKSIZE = 128
func AppCardStatus(status string) bool { func AppCardStatus(status string) bool {
if status == APP_CARDPENDING { if status == APP_CARDPENDING {

View File

@ -70,8 +70,6 @@ type ArticleData struct {
Updated int64 `json:"updated"` Updated int64 `json:"updated"`
Status string `json:"status"`
Groups *ArticleGroups `json:"groups,omitempty"` Groups *ArticleGroups `json:"groups,omitempty"`
} }

View File

@ -286,10 +286,10 @@ var routes = Routes{
}, },
Route{ Route{
"UpdateGroup", "SetGroupSubject",
strings.ToUpper("Put"), strings.ToUpper("Put"),
"/alias/groups/{groupId}", "/alias/groups/{groupId}/subject",
UpdateGroup, SetGroupSubject,
}, },
Route{ Route{

View File

@ -176,7 +176,6 @@ type Article struct {
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"` ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
DataType string `gorm:"index"` DataType string `gorm:"index"`
Data string Data string
Status string `gorm:"not null;index"`
Created int64 `gorm:"autoCreateTime"` Created int64 `gorm:"autoCreateTime"`
Updated int64 `gorm:"autoUpdateTime"` Updated int64 `gorm:"autoUpdateTime"`
Groups []Group `gorm:"many2many:article_groups;"` Groups []Group `gorm:"many2many:article_groups;"`

View File

@ -148,7 +148,7 @@ func TestContactSync(t *testing.T) {
// update and delete group // update and delete group
param["groupId"] = set.D.C.GroupId param["groupId"] = set.D.C.GroupId
subject := &Subject{ DataType: "contactsynctype", Data: "contactsyncdata" } subject := &Subject{ DataType: "contactsynctype", Data: "contactsyncdata" }
assert.NoError(t, ApiTestMsg(UpdateGroup, "PUT", "/alias/groups/{groupId}", assert.NoError(t, ApiTestMsg(SetGroupSubject, "PUT", "/alias/groups/{groupId}",
&param, subject, APP_TOKENAPP, set.D.Token, nil, nil)) &param, subject, APP_TOKENAPP, set.D.Token, nil, nil))
groups = &[]Group{} groups = &[]Group{}
assert.NoError(t, ApiTestMsg(GetGroups, "GET", "/alias/groups", assert.NoError(t, ApiTestMsg(GetGroups, "GET", "/alias/groups",

View File

@ -9,6 +9,7 @@ func TestShareAttribute(t *testing.T) {
var articles *[]Article var articles *[]Article
var subject *Subject var subject *Subject
var article *Article var article *Article
param := map[string]string{}
// setup testing group // setup testing group
set, err := AddTestGroup("shareattribute") set, err := AddTestGroup("shareattribute")
@ -19,7 +20,6 @@ func TestShareAttribute(t *testing.T) {
assert.NoError(t, ApiTestMsg(GetArticles, "GET", "/attribute/articles", assert.NoError(t, ApiTestMsg(GetArticles, "GET", "/attribute/articles",
nil, nil, APP_TOKENAPP, set.A.Token, articles, nil)) nil, nil, APP_TOKENAPP, set.A.Token, articles, nil))
assert.Equal(t, 0, len(*articles)) assert.Equal(t, 0, len(*articles))
article = &Article{} article = &Article{}
subject = &Subject{ Data: "subjectdata", DataType: "subjectdatatype" } subject = &Subject{ Data: "subjectdata", DataType: "subjectdatatype" }
assert.NoError(t, ApiTestMsg(AddArticle, "POST", "/attributes/articles", assert.NoError(t, ApiTestMsg(AddArticle, "POST", "/attributes/articles",
@ -31,8 +31,14 @@ func TestShareAttribute(t *testing.T) {
nil, nil, APP_TOKENAPP, set.A.Token, articles, nil)) nil, nil, APP_TOKENAPP, set.A.Token, articles, nil))
assert.Equal(t, 1, len(*articles)) assert.Equal(t, 1, len(*articles))
// update attribute
data := "{ \"nested\" : { \"image\" : \"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\" } }"
subject = &Subject{ Data: data, DataType: "nestedimage" }
param["articleId"] = article.Id
article = &Article{}
assert.NoError(t, ApiTestMsg(SetArticleSubject, "PUT", "/attribute/articles/{articleId}/subject",
&param, subject, APP_TOKENAPP, set.A.Token, article, nil))
PrintMsg(article) PrintMsg(article)
PrintMsg(articles)
} }