Add tests [TestListSenderNames] [TestListUserSenderNames]
This commit is contained in:
parent
5dd94eca38
commit
584a9e983f
@ -12,7 +12,7 @@
|
||||
|
||||
- exerr.New | exerr.Wrap
|
||||
|
||||
- (!!!) Run tests in pipeline !!
|
||||
- Fork go-sqlite with always-on fts5
|
||||
|
||||
#### UNSURE
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
||||
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
||||
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/ginext"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ListUserSenderNames swaggerdoc
|
||||
@ -26,6 +29,7 @@ func (h APIHandler) ListUserSenderNames(pctx ginext.PreContext) ginext.HTTPRespo
|
||||
UserID models.UserID `uri:"uid" binding:"entityid"`
|
||||
}
|
||||
type response struct {
|
||||
SenderNames []models.SenderNameStatistics `json:"sender_names"`
|
||||
}
|
||||
|
||||
var u uri
|
||||
@ -41,7 +45,12 @@ func (h APIHandler) ListUserSenderNames(pctx ginext.PreContext) ginext.HTTPRespo
|
||||
return *permResp
|
||||
}
|
||||
|
||||
return nil //TODO
|
||||
names, err := h.database.ListSenderNames(ctx, u.UserID, false)
|
||||
if err != nil {
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to query messages", err)
|
||||
}
|
||||
|
||||
return finishSuccess(ginext.JSON(http.StatusOK, response{SenderNames: names}))
|
||||
|
||||
})
|
||||
}
|
||||
@ -61,6 +70,7 @@ func (h APIHandler) ListUserSenderNames(pctx ginext.PreContext) ginext.HTTPRespo
|
||||
// @Router /api/v2/sender-names [GET]
|
||||
func (h APIHandler) ListSenderNames(pctx ginext.PreContext) ginext.HTTPResponse {
|
||||
type response struct {
|
||||
SenderNames []models.SenderNameStatistics `json:"sender_names"`
|
||||
}
|
||||
|
||||
ctx, g, errResp := pctx.Start()
|
||||
@ -75,13 +85,18 @@ func (h APIHandler) ListSenderNames(pctx ginext.PreContext) ginext.HTTPResponse
|
||||
return *permResp
|
||||
}
|
||||
|
||||
userid := *ctx.GetPermissionUserID()
|
||||
userID := *ctx.GetPermissionUserID()
|
||||
|
||||
if permResp := ctx.CheckPermissionUserRead(userid); permResp != nil {
|
||||
if permResp := ctx.CheckPermissionUserRead(userID); permResp != nil {
|
||||
return *permResp
|
||||
}
|
||||
|
||||
return nil //TODO
|
||||
names, err := h.database.ListSenderNames(ctx, userID, true)
|
||||
if err != nil {
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to query messages", err)
|
||||
}
|
||||
|
||||
return finishSuccess(ginext.JSON(http.StatusOK, response{SenderNames: names}))
|
||||
|
||||
})
|
||||
}
|
||||
|
26
scnserver/db/impl/primary/senderNames.go
Normal file
26
scnserver/db/impl/primary/senderNames.go
Normal file
@ -0,0 +1,26 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
)
|
||||
|
||||
func (db *Database) ListSenderNames(ctx db.TxContext, userid models.UserID, includeForeignSubscribed bool) ([]models.SenderNameStatistics, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sqlStr string
|
||||
|
||||
prepParams := sq.PP{"uid": userid}
|
||||
|
||||
if includeForeignSubscribed {
|
||||
sqlStr = "SELECT sender_name AS name, MAX(timestamp_real) AS ts_last, MIN(timestamp_real) AS ts_first, COUNT(*) AS count FROM messages LEFT JOIN subscriptions AS subs on messages.channel_id = subs.channel_id WHERE (subs.subscriber_user_id = :uid AND subs.confirmed = 1) AND sender_NAME NOT NULL GROUP BY sender_name ORDER BY ts_last DESC"
|
||||
} else {
|
||||
sqlStr = "SELECT sender_name AS name, MAX(timestamp_real) AS ts_last, MIN(timestamp_real) AS ts_first, COUNT(*) AS count FROM messages WHERE sender_user_id = :uid AND sender_NAME NOT NULL GROUP BY sender_name ORDER BY ts_last DESC"
|
||||
}
|
||||
|
||||
return sq.QueryAll[models.SenderNameStatistics](ctx, tx, sqlStr, prepParams, sq.SModeExtended, sq.Safe)
|
||||
}
|
8
scnserver/models/senderNames.go
Normal file
8
scnserver/models/senderNames.go
Normal file
@ -0,0 +1,8 @@
|
||||
package models
|
||||
|
||||
type SenderNameStatistics struct {
|
||||
SenderName string `json:"name" db:"name"`
|
||||
LastTimestamp SCNTime `json:"last_timestamp" db:"ts_last"`
|
||||
FirstTimestamp SCNTime `json:"first_timestamp" db:"ts_first"`
|
||||
Count int `json:"count" db:"count"`
|
||||
}
|
@ -13,7 +13,7 @@ func TestResponseChannel(t *testing.T) {
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
response := tt.RequestAuthGetRaw(t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", data.User[0].UID, data.User[0].Channels[0]))
|
||||
response := tt.RequestAuthGetRaw(t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", data.User[0].UID, data.User[0].Channels[0].ChannelID))
|
||||
|
||||
tt.AssertJsonStructureMatch(t, "json[channel]", response, map[string]any{
|
||||
"channel_id": "id",
|
||||
@ -63,7 +63,7 @@ func TestResponseKeyToken1(t *testing.T) {
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
response := tt.RequestAuthGetRaw(t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, data.User[0].Keys[0]))
|
||||
response := tt.RequestAuthGetRaw(t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.User[0].UID, data.User[0].Keys[0].KeyID))
|
||||
|
||||
tt.AssertJsonStructureMatch(t, "json[key]", response, map[string]any{
|
||||
"keytoken_id": "id",
|
||||
@ -246,7 +246,7 @@ func TestResponseChannelPreview(t *testing.T) {
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
response := tt.RequestAuthGetRaw(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", data.User[0].Channels[0]))
|
||||
response := tt.RequestAuthGetRaw(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/channels/%s", data.User[0].Channels[0].ChannelID))
|
||||
|
||||
tt.AssertJsonStructureMatch(t, "json[channel]", response, map[string]any{
|
||||
"channel_id": "id",
|
||||
@ -277,7 +277,7 @@ func TestResponseKeyTokenPreview(t *testing.T) {
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
response := tt.RequestAuthGetRaw(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].Keys[0]))
|
||||
response := tt.RequestAuthGetRaw(t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/preview/keys/%s", data.User[0].Keys[0].KeyID))
|
||||
|
||||
tt.AssertJsonStructureMatch(t, "json[key]", response, map[string]any{
|
||||
"keytoken_id": "id",
|
||||
|
@ -1,11 +1,105 @@
|
||||
package test
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
tt "blackforestbytes.com/simplecloudnotifier/test/util"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListSenderNames(t *testing.T) {
|
||||
t.Fail()
|
||||
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
type sn struct {
|
||||
SenderName string `json:"name"`
|
||||
LastTimestamp string `json:"last_timestamp"`
|
||||
FirstTimestamp string `json:"first_timestamp"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
type snlistS struct {
|
||||
SNList []sn `json:"sender_names"`
|
||||
}
|
||||
type snlistH struct {
|
||||
SNList []gin.H `json:"sender_names"`
|
||||
}
|
||||
|
||||
responses := []struct {
|
||||
Idx int
|
||||
Resp []string
|
||||
}{
|
||||
{0, []string{"Pocket Pal", "Cellular Confidant", "Mobile Mate"}},
|
||||
{1, []string{}},
|
||||
{2, []string{}},
|
||||
{3, []string{}},
|
||||
{4, []string{"Server0"}},
|
||||
{5, []string{"example.org", "example.com", "localhost"}},
|
||||
{6, []string{"server1", "server2"}},
|
||||
{7, []string{"localhost"}},
|
||||
{8, []string{}},
|
||||
{9, []string{"Vincent", "Tim", "Max"}},
|
||||
{10, []string{}},
|
||||
{11, []string{"192.168.0.1", "#S0", "localhost"}},
|
||||
{12, []string{}},
|
||||
{13, []string{}},
|
||||
{14, []string{"dummy-man"}},
|
||||
{15, []string{"dummy-man"}},
|
||||
{16, []string{}},
|
||||
}
|
||||
|
||||
for _, resp := range responses {
|
||||
msgList := tt.RequestAuthGet[snlistH](t, data.User[resp.Idx].AdminKey, baseUrl, "/api/v2/sender-names")
|
||||
tt.AssertMappedArr(t, "sender_names_"+strconv.Itoa(resp.Idx), resp.Resp, msgList.SNList, "name")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListUserSenderNames(t *testing.T) {
|
||||
t.Fail()
|
||||
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
type sn struct {
|
||||
SenderName string `json:"name"`
|
||||
LastTimestamp string `json:"last_timestamp"`
|
||||
FirstTimestamp string `json:"first_timestamp"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
type snlistS struct {
|
||||
SNList []sn `json:"sender_names"`
|
||||
}
|
||||
type snlistH struct {
|
||||
SNList []gin.H `json:"sender_names"`
|
||||
}
|
||||
|
||||
responses := []struct {
|
||||
Idx int
|
||||
Resp []string
|
||||
}{
|
||||
{0, []string{"Pocket Pal", "Cellular Confidant", "Mobile Mate"}},
|
||||
{1, []string{}},
|
||||
{2, []string{}},
|
||||
{3, []string{}},
|
||||
{4, []string{"Server0"}},
|
||||
{5, []string{"example.org", "example.com", "localhost"}},
|
||||
{6, []string{"server1", "server2"}},
|
||||
{7, []string{"localhost"}},
|
||||
{8, []string{}},
|
||||
{9, []string{"Vincent", "Tim", "Max"}},
|
||||
{10, []string{}},
|
||||
{11, []string{"192.168.0.1", "#S0", "localhost"}},
|
||||
{12, []string{}},
|
||||
{13, []string{}},
|
||||
{14, []string{}},
|
||||
{15, []string{"dummy-man"}},
|
||||
{16, []string{}},
|
||||
}
|
||||
|
||||
for _, resp := range responses {
|
||||
msgList := tt.RequestAuthGet[snlistH](t, data.User[resp.Idx].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/sender-names", data.User[resp.Idx].UID))
|
||||
tt.AssertMappedArr(t, "sender_names_"+strconv.Itoa(resp.Idx), resp.Resp, msgList.SNList, "name")
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,8 @@ var messageExamples = []msgex{
|
||||
{15, "", "", P0, SKEY, "New Feature Available", "ability to schedule appointments", 0},
|
||||
{15, "chan_other_nosub", "", P0, SKEY, "Account Suspended", "Please contact us", 0},
|
||||
{15, "chan_other_request", "", P0, SKEY, "Invitation to Beta Test", "", 0},
|
||||
{15, "chan_other_accepted", "", P0, SKEY, "New Blog Post", "Congratulations on your promotion! We are proud", 0},
|
||||
{15, "chan_other_request", "", P0, SKEY, "Invitation to Beta Test (with sendername)", "", 0},
|
||||
{15, "chan_other_accepted", "dummy-man", P0, SKEY, "New Blog Post", "Congratulations on your promotion! We are proud", 0},
|
||||
|
||||
{16, "Chan1", "", P2, SKEY, "Lorem Ipsum 01", Lipsum(30001, 1), 0},
|
||||
{16, "Chan2", "", P0, SKEY, "Lorem Ipsum 02", Lipsum(30002, 1), 0},
|
||||
|
Loading…
Reference in New Issue
Block a user