Implement message filter scubscription_status
and sender_user_id
[skip-tests]
This commit is contained in:
parent
b989a8359e
commit
e9c5c5fb99
@ -24,6 +24,7 @@ import (
|
|||||||
// @Description Simply start the pagination without a next_page_token and get the next page by calling this endpoint with the returned next_page_token of the last query
|
// @Description Simply start the pagination without a next_page_token and get the next page by calling this endpoint with the returned next_page_token of the last query
|
||||||
// @Description If there are no more entries the token "@end" will be returned
|
// @Description If there are no more entries the token "@end" will be returned
|
||||||
// @Description By default we return long messages with a trimmed body, if trimmed=false is supplied we return full messages (this reduces the max page_size)
|
// @Description By default we return long messages with a trimmed body, if trimmed=false is supplied we return full messages (this reduces the max page_size)
|
||||||
|
// @Description By default returns only messages with an [active+confirmed] subscription, can supply subscription_status=all to als include inactive subscriptions or owned messages without subscriptions
|
||||||
// @ID api-messages-list
|
// @ID api-messages-list
|
||||||
// @Tags API-v2
|
// @Tags API-v2
|
||||||
//
|
//
|
||||||
@ -50,6 +51,8 @@ func (h APIHandler) ListMessages(pctx ginext.PreContext) ginext.HTTPResponse {
|
|||||||
Priority []int `json:"priority" form:"priority"`
|
Priority []int `json:"priority" form:"priority"`
|
||||||
KeyTokens []string `json:"used_key" form:"used_key"`
|
KeyTokens []string `json:"used_key" form:"used_key"`
|
||||||
HasSender *bool `json:"has_sender" form:"has_sender"`
|
HasSender *bool `json:"has_sender" form:"has_sender"`
|
||||||
|
SenderUserID []string `json:"sender_user_id" form:"sender_user_id"`
|
||||||
|
SubscriptionStatus *string `json:"subscription_status" form:"subscription_status" enums:"subscribed,all"`
|
||||||
}
|
}
|
||||||
type response struct {
|
type response struct {
|
||||||
Messages []models.Message `json:"messages"`
|
Messages []models.Message `json:"messages"`
|
||||||
@ -89,8 +92,30 @@ func (h APIHandler) ListMessages(pctx ginext.PreContext) ginext.HTTPResponse {
|
|||||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to update last-read", err)
|
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to update last-read", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := models.MessageFilter{
|
filter := models.MessageFilter{}
|
||||||
ConfirmedAndActiveSubscriptionBy: langext.Ptr(userid),
|
|
||||||
|
if q.SubscriptionStatus != nil {
|
||||||
|
if *q.SubscriptionStatus == "subscribed" {
|
||||||
|
filter.ConfirmedAndActiveSubscriptionBy = langext.Ptr(userid)
|
||||||
|
} else if *q.SubscriptionStatus == "all" {
|
||||||
|
filter.ConfirmedSubscriptionOrOwnedBy = langext.Ptr(userid)
|
||||||
|
} else {
|
||||||
|
return ginresp.APIError(g, 400, apierr.BINDFAIL_QUERY_PARAM, "Invalid value for param 'subscription_status'", nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filter.ConfirmedAndActiveSubscriptionBy = langext.Ptr(userid) // default
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(q.SenderUserID) != 0 {
|
||||||
|
uids := make([]models.UserID, 0, len(q.SenderUserID))
|
||||||
|
for _, v := range q.SenderUserID {
|
||||||
|
uid := models.UserID(v)
|
||||||
|
if err = uid.Valid(); err != nil {
|
||||||
|
return ginresp.APIError(g, 400, apierr.BINDFAIL_QUERY_PARAM, "Invalid sender-user-id", err)
|
||||||
|
}
|
||||||
|
uids = append(uids, uid)
|
||||||
|
}
|
||||||
|
filter.Sender = &uids
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(q.Search) != 0 {
|
if len(q.Search) != 0 {
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
type MessageFilter struct {
|
type MessageFilter struct {
|
||||||
ConfirmedAndActiveSubscriptionBy *UserID
|
ConfirmedAndActiveSubscriptionBy *UserID
|
||||||
|
ConfirmedSubscriptionOrOwnedBy *UserID
|
||||||
SearchStringFTS *[]string
|
SearchStringFTS *[]string
|
||||||
SearchStringPlain *[]string
|
SearchStringPlain *[]string
|
||||||
Sender *[]UserID
|
Sender *[]UserID
|
||||||
@ -49,7 +50,10 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
|
|
||||||
joinClause := ""
|
joinClause := ""
|
||||||
if f.ConfirmedAndActiveSubscriptionBy != nil {
|
if f.ConfirmedAndActiveSubscriptionBy != nil {
|
||||||
joinClause += fmt.Sprintf(" LEFT JOIN subscriptions AS subs ON (messages.channel_id = subs.channel_id AND subs.subscriber_user_id = :%s AND subs.confirmed=1 AND subs.active=1 AND subs.deleted=0) ", params.Add(*f.ConfirmedAndActiveSubscriptionBy))
|
joinClause += fmt.Sprintf(" LEFT JOIN subscriptions AS __filter_subs_1 ON (messages.channel_id = __filter_subs_1.channel_id AND __filter_subs_1.subscriber_user_id = :%s AND __filter_subs_1.confirmed=1 AND __filter_subs_1.active=1 AND __filter_subs_1.deleted=0) ", params.Add(*f.ConfirmedAndActiveSubscriptionBy))
|
||||||
|
}
|
||||||
|
if f.ConfirmedSubscriptionOrOwnedBy != nil {
|
||||||
|
joinClause += fmt.Sprintf(" LEFT JOIN subscriptions AS __filter_subs_2 ON (messages.channel_id = __filter_subs_2.channel_id AND __filter_subs_2.subscriber_user_id = :%s AND __filter_subs_2.confirmed=1 AND __filter_subs_2.deleted=0) ", params.Add(*f.ConfirmedSubscriptionOrOwnedBy))
|
||||||
}
|
}
|
||||||
if f.SearchStringFTS != nil {
|
if f.SearchStringFTS != nil {
|
||||||
joinClause += " JOIN messages_fts AS mfts ON (mfts.rowid = messages.rowid) "
|
joinClause += " JOIN messages_fts AS mfts ON (mfts.rowid = messages.rowid) "
|
||||||
@ -66,7 +70,11 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if f.ConfirmedAndActiveSubscriptionBy != nil {
|
if f.ConfirmedAndActiveSubscriptionBy != nil {
|
||||||
sqlClauses = append(sqlClauses, "(subs.confirmed=1 AND subs.active=1 AND subs.deleted=0)")
|
sqlClauses = append(sqlClauses, "(__filter_subs_1.confirmed=1 AND __filter_subs_1.active=1 AND __filter_subs_1.deleted=0)")
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.ConfirmedSubscriptionOrOwnedBy != nil {
|
||||||
|
sqlClauses = append(sqlClauses, fmt.Sprintf("((__filter_subs_2.confirmed=1 AND __filter_subs_2.deleted=0) OR (messages.channel_owner_user_id = :%s) OR (messages.sender_user_id = :%s))", params.Add(*f.ConfirmedSubscriptionOrOwnedBy), params.Add(*f.ConfirmedSubscriptionOrOwnedBy)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Sender != nil {
|
if f.Sender != nil {
|
||||||
|
@ -1192,3 +1192,124 @@ func TestUnconfirmedSubscriptionListMessages(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tt.AssertFalse(t, "foundActivatedMessage", foundActivatedMessage)
|
tt.AssertFalse(t, "foundActivatedMessage", foundActivatedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListMessagesSenderUserID(t *testing.T) {
|
||||||
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
|
defer stop()
|
||||||
|
data := tt.InitDefaultData(t, ws)
|
||||||
|
|
||||||
|
user16 := data.User[16]
|
||||||
|
|
||||||
|
type msg struct {
|
||||||
|
MessageId string `json:"message_id"`
|
||||||
|
}
|
||||||
|
type mglist struct {
|
||||||
|
Messages []msg `json:"messages"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
allMessages := tt.RequestAuthGet[mglist](t, user16.AdminKey, baseUrl, "/api/v2/messages")
|
||||||
|
tt.AssertTrue(t, "allMessages count > 0", allMessages.TotalCount > 0)
|
||||||
|
|
||||||
|
filteredMessages := tt.RequestAuthGet[mglist](t, user16.AdminKey, baseUrl, fmt.Sprintf("/api/v2/messages?sender_user_id=%s", user16.UID))
|
||||||
|
|
||||||
|
tt.AssertEqual(t, "Filtered message count should equal total count", allMessages.TotalCount, filteredMessages.TotalCount)
|
||||||
|
tt.AssertEqual(t, "Filtered message len should equal total len", len(allMessages.Messages), len(filteredMessages.Messages))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListMessagesSubscriptionStatusAllInactiveSubscription(t *testing.T) {
|
||||||
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
|
defer stop()
|
||||||
|
data := tt.InitDefaultData(t, ws)
|
||||||
|
|
||||||
|
user14 := data.User[14] // Subscriber
|
||||||
|
user15 := data.User[15] // Owner
|
||||||
|
chanName := "chan_other_accepted"
|
||||||
|
|
||||||
|
subscriptionID, _ := tt.FindSubscriptionByChanName(t, baseUrl, user14, user15.UID, chanName)
|
||||||
|
|
||||||
|
newMessageTitle := langext.RandBase62(48)
|
||||||
|
tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{"key": user15.AdminKey, "user_id": user15.UID, "channel": chanName, "title": newMessageTitle})
|
||||||
|
|
||||||
|
type msg struct {
|
||||||
|
MessageId string `json:"message_id"`
|
||||||
|
ChannelId string `json:"channel_id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
type mglist struct {
|
||||||
|
Messages []msg `json:"messages"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user14.AdminKey, baseUrl, "/api/v2/messages")
|
||||||
|
foundInitial := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertTrue(t, "foundInitial", foundInitial)
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.RequestAuthPatch[gin.H](t, user14.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", user14.UID, subscriptionID), gin.H{"active": false})
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user14.AdminKey, baseUrl, "/api/v2/messages")
|
||||||
|
foundInactive := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertFalse(t, "foundInactive", foundInactive)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user14.AdminKey, baseUrl, "/api/v2/messages?subscription_status=all")
|
||||||
|
foundAllStatus := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertTrue(t, "foundAllStatus", foundAllStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListMessagesSubscriptionStatusAllNoSubscription(t *testing.T) {
|
||||||
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
|
defer stop()
|
||||||
|
data := tt.InitDefaultData(t, ws)
|
||||||
|
|
||||||
|
user0 := data.User[0]
|
||||||
|
|
||||||
|
type msg struct {
|
||||||
|
MessageId string `json:"message_id"`
|
||||||
|
ChannelId string `json:"channel_id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
type mglist struct {
|
||||||
|
Messages []msg `json:"messages"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
chan2 := data.User[0].Channels[2]
|
||||||
|
|
||||||
|
newMessageTitle := langext.RandBase62(48)
|
||||||
|
tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{"key": user0.AdminKey, "user_id": user0.UID, "channel": chan2.InternalName, "title": newMessageTitle})
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user0.AdminKey, baseUrl, "/api/v2/messages")
|
||||||
|
foundInitial := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertTrue(t, "foundInitial", foundInitial)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user0.AdminKey, baseUrl, "/api/v2/messages?subscription_status=all")
|
||||||
|
foundAllStatusAndSubscribed := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertTrue(t, "foundAllStatusAndSubscribed", foundAllStatusAndSubscribed)
|
||||||
|
}
|
||||||
|
|
||||||
|
subscriptionID, _ := tt.FindSubscriptionByChanName(t, baseUrl, user0, user0.UID, chan2.InternalName)
|
||||||
|
|
||||||
|
tt.RequestAuthDelete[gin.H](t, user0.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", user0.UID, subscriptionID), gin.H{})
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user0.AdminKey, baseUrl, "/api/v2/messages")
|
||||||
|
foundNoSub := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertFalse(t, "foundNoSub", foundNoSub)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
messages := tt.RequestAuthGet[mglist](t, user0.AdminKey, baseUrl, "/api/v2/messages?subscription_status=all")
|
||||||
|
foundAllStatus := langext.ArrAny(messages.Messages, func(m msg) bool { return m.Title == newMessageTitle })
|
||||||
|
tt.AssertTrue(t, "foundAllStatus", foundAllStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user