Tests[SendWithPriority]

This commit is contained in:
Mike Schwörer 2022-11-30 21:39:14 +01:00
parent a7df476e79
commit 1ca09c16d3
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
7 changed files with 172 additions and 4 deletions

View File

@ -250,7 +250,7 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex
sendTimestamp = langext.Ptr(timeext.UnixFloatSeconds(*SendTimestamp)) sendTimestamp = langext.Ptr(timeext.UnixFloatSeconds(*SendTimestamp))
} }
priority := langext.Coalesce(Priority, 1) priority := langext.Coalesce(Priority, user.DefaultPriority())
clientIP := g.ClientIP() clientIP := g.ClientIP()

View File

@ -102,7 +102,7 @@ type MessageJSON struct {
SenderIP string `json:"sender_ip"` SenderIP string `json:"sender_ip"`
Timestamp string `json:"timestamp"` Timestamp string `json:"timestamp"`
Title string `json:"title"` Title string `json:"title"`
Content *string `json:"body"` Content *string `json:"content"`
Priority int `json:"priority"` Priority int `json:"priority"`
UserMessageID *string `json:"usr_message_id"` UserMessageID *string `json:"usr_message_id"`
Trimmed bool `json:"trimmed"` Trimmed bool `json:"trimmed"`

View File

@ -86,6 +86,10 @@ func (u User) DefaultChannel() string {
return "main" return "main"
} }
func (u User) DefaultPriority() int {
return 1
}
func (u User) MaxChannelNameLength() int { func (u User) MaxChannelNameLength() int {
return 120 return 120
} }

View File

@ -212,6 +212,7 @@ func TestSendContentMessage(t *testing.T) {
}) })
uid := int(r0["user_id"].(float64)) uid := int(r0["user_id"].(float64))
admintok := r0["admin_key"].(string)
sendtok := r0["send_key"].(string) sendtok := r0["send_key"].(string)
msg1 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ msg1 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
@ -225,6 +226,18 @@ func TestSendContentMessage(t *testing.T) {
tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", pusher.Last().Message.Title) tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", pusher.Last().Message.Title)
tt.AssertStrRepEqual(t, "msg.content", "I am Content\nasdf", pusher.Last().Message.Content) tt.AssertStrRepEqual(t, "msg.content", "I am Content\nasdf", pusher.Last().Message.Content)
tt.AssertStrRepEqual(t, "msg.scn_msg_id", msg1["scn_msg_id"], pusher.Last().Message.SCNMessageID) tt.AssertStrRepEqual(t, "msg.scn_msg_id", msg1["scn_msg_id"], pusher.Last().Message.SCNMessageID)
type mglist struct {
Messages []gin.H `json:"messages"`
}
msgList1 := tt.RequestAuthGet[mglist](t, admintok, baseUrl, "/api/messages")
tt.AssertEqual(t, "len(messages)", 1, len(msgList1.Messages))
msg1Get := tt.RequestAuthGet[gin.H](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]))
tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", msg1Get["title"])
tt.AssertStrRepEqual(t, "msg.content", "I am Content\nasdf", msg1Get["content"])
tt.AssertStrRepEqual(t, "msg.channel_name", "main", msg1Get["channel_name"])
} }
func TestSendWithSendername(t *testing.T) { func TestSendWithSendername(t *testing.T) {
@ -276,6 +289,7 @@ func TestSendLongContent(t *testing.T) {
}) })
uid := int(r0["user_id"].(float64)) uid := int(r0["user_id"].(float64))
admintok := r0["admin_key"].(string)
sendtok := r0["send_key"].(string) sendtok := r0["send_key"].(string)
longContent := "" longContent := ""
@ -294,6 +308,30 @@ func TestSendLongContent(t *testing.T) {
tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", pusher.Last().Message.Title) tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", pusher.Last().Message.Title)
tt.AssertStrRepEqual(t, "msg.content", longContent, pusher.Last().Message.Content) tt.AssertStrRepEqual(t, "msg.content", longContent, pusher.Last().Message.Content)
tt.AssertStrRepEqual(t, "msg.scn_msg_id", msg1["scn_msg_id"], pusher.Last().Message.SCNMessageID) tt.AssertStrRepEqual(t, "msg.scn_msg_id", msg1["scn_msg_id"], pusher.Last().Message.SCNMessageID)
type mglist struct {
Messages []gin.H `json:"messages"`
}
msgList1 := tt.RequestAuthGet[mglist](t, admintok, baseUrl, "/api/messages")
tt.AssertEqual(t, "len(messages)", 1, len(msgList1.Messages))
tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", msgList1.Messages[0]["title"])
tt.AssertNotStrRepEqual(t, "msg.content", longContent, msgList1.Messages[0]["content"])
tt.AssertStrRepEqual(t, "msg.channel_name", "main", msgList1.Messages[0]["channel_name"])
tt.AssertStrRepEqual(t, "msg.trimmmed", true, msgList1.Messages[0]["trimmed"])
msgList2 := tt.RequestAuthGet[mglist](t, admintok, baseUrl, "/api/messages?trimmed=false")
tt.AssertEqual(t, "len(messages)", 1, len(msgList2.Messages))
tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", msgList2.Messages[0]["title"])
tt.AssertStrRepEqual(t, "msg.content", longContent, msgList2.Messages[0]["content"])
tt.AssertStrRepEqual(t, "msg.channel_name", "main", msgList2.Messages[0]["channel_name"])
tt.AssertStrRepEqual(t, "msg.trimmmed", false, msgList2.Messages[0]["trimmed"])
msg1Get := tt.RequestAuthGet[gin.H](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]))
tt.AssertStrRepEqual(t, "msg.title", "HelloWorld_042", msg1Get["title"])
tt.AssertStrRepEqual(t, "msg.titcontentle", longContent, msg1Get["content"])
tt.AssertStrRepEqual(t, "msg.channel_name", "main", msg1Get["channel_name"])
tt.AssertStrRepEqual(t, "msg.trimmmed", false, msg1Get["trimmed"])
} }
func TestSendTooLongContent(t *testing.T) { func TestSendTooLongContent(t *testing.T) {
@ -364,6 +402,7 @@ func TestSendIdempotent(t *testing.T) {
}) })
uid := int(r0["user_id"].(float64)) uid := int(r0["user_id"].(float64))
readtok := r0["admin_key"].(string)
sendtok := r0["send_key"].(string) sendtok := r0["send_key"].(string)
msg1 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ msg1 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
@ -381,6 +420,13 @@ func TestSendIdempotent(t *testing.T) {
tt.AssertStrRepEqual(t, "msg.title", "Hello SCN", pusher.Last().Message.Title) tt.AssertStrRepEqual(t, "msg.title", "Hello SCN", pusher.Last().Message.Title)
tt.AssertStrRepEqual(t, "msg.content", "mamma mia", pusher.Last().Message.Content) tt.AssertStrRepEqual(t, "msg.content", "mamma mia", pusher.Last().Message.Content)
type mglist struct {
Messages []gin.H `json:"messages"`
}
msgList1 := tt.RequestAuthGet[mglist](t, readtok, baseUrl, "/api/messages")
tt.AssertEqual(t, "len(messages)", 1, len(msgList1.Messages))
msg2 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ msg2 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
"user_key": sendtok, "user_key": sendtok,
"user_id": uid, "user_id": uid,
@ -397,6 +443,9 @@ func TestSendIdempotent(t *testing.T) {
tt.AssertStrRepEqual(t, "msg.title", "Hello SCN", pusher.Last().Message.Title) tt.AssertStrRepEqual(t, "msg.title", "Hello SCN", pusher.Last().Message.Title)
tt.AssertStrRepEqual(t, "msg.content", "mamma mia", pusher.Last().Message.Content) tt.AssertStrRepEqual(t, "msg.content", "mamma mia", pusher.Last().Message.Content)
msgList2 := tt.RequestAuthGet[mglist](t, readtok, baseUrl, "/api/messages")
tt.AssertEqual(t, "len(messages)", 1, len(msgList2.Messages))
msg3 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ msg3 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
"user_key": sendtok, "user_key": sendtok,
"user_id": uid, "user_id": uid,
@ -413,21 +462,127 @@ func TestSendIdempotent(t *testing.T) {
tt.AssertStrRepEqual(t, "msg.title", "Hello third", pusher.Last().Message.Title) tt.AssertStrRepEqual(t, "msg.title", "Hello third", pusher.Last().Message.Title)
tt.AssertStrRepEqual(t, "msg.content", "let me go", pusher.Last().Message.Content) tt.AssertStrRepEqual(t, "msg.content", "let me go", pusher.Last().Message.Content)
msgList3 := tt.RequestAuthGet[mglist](t, readtok, baseUrl, "/api/messages")
tt.AssertEqual(t, "len(messages)", 2, len(msgList3.Messages))
}
func TestSendWithPriority(t *testing.T) {
ws, stop := tt.StartSimpleWebserver(t)
defer stop()
pusher := ws.Pusher.(*push.TestSink)
baseUrl := "http://127.0.0.1:" + ws.Port
r0 := tt.RequestPost[gin.H](t, baseUrl, "/api/users", gin.H{
"agent_model": "DUMMY_PHONE",
"agent_version": "4X",
"client_type": "ANDROID",
"fcm_token": "DUMMY_FCM",
})
uid := int(r0["user_id"].(float64))
sendtok := r0["send_key"].(string)
admintok := r0["admin_key"].(string)
{
msg1 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
"user_key": sendtok,
"user_id": uid,
"title": "M_001",
"content": "TestSendWithPriority#001",
})
tt.AssertEqual(t, "messageCount", 1, len(pusher.Data))
tt.AssertStrRepEqual(t, "msg.prio", 1, pusher.Last().Message.Priority)
msg1Get := tt.RequestAuthGet[gin.H](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]))
tt.AssertStrRepEqual(t, "msg.title", "M_001", msg1Get["title"])
tt.AssertStrRepEqual(t, "msg.content", "TestSendWithPriority#001", msg1Get["content"])
tt.AssertStrRepEqual(t, "msg.content", 1, msg1Get["priority"])
}
{
msg2 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
"user_key": sendtok,
"user_id": uid,
"title": "M_002",
"content": "TestSendWithPriority#002",
"priority": 0,
})
tt.AssertEqual(t, "messageCount", 2, len(pusher.Data))
tt.AssertStrRepEqual(t, "msg.prio", 0, pusher.Last().Message.Priority)
msg2Get := tt.RequestAuthGet[gin.H](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg2["scn_msg_id"]))
tt.AssertStrRepEqual(t, "msg.title", "M_002", msg2Get["title"])
tt.AssertStrRepEqual(t, "msg.content", "TestSendWithPriority#002", msg2Get["content"])
tt.AssertStrRepEqual(t, "msg.content", 0, msg2Get["priority"])
}
{
msg3 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
"user_key": sendtok,
"user_id": uid,
"title": "M_003",
"content": "TestSendWithPriority#003",
"priority": 1,
})
tt.AssertEqual(t, "messageCount", 3, len(pusher.Data))
tt.AssertStrRepEqual(t, "msg.prio", 1, pusher.Last().Message.Priority)
msg3Get := tt.RequestAuthGet[gin.H](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg3["scn_msg_id"]))
tt.AssertStrRepEqual(t, "msg.title", "M_003", msg3Get["title"])
tt.AssertStrRepEqual(t, "msg.content", "TestSendWithPriority#003", msg3Get["content"])
tt.AssertStrRepEqual(t, "msg.content", 1, msg3Get["priority"])
}
{
msg4 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
"user_key": sendtok,
"user_id": uid,
"title": "M_004",
"content": "TestSendWithPriority#004",
"priority": 2,
})
tt.AssertEqual(t, "messageCount", 4, len(pusher.Data))
tt.AssertStrRepEqual(t, "msg.prio", 2, pusher.Last().Message.Priority)
msg4Get := tt.RequestAuthGet[gin.H](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg4["scn_msg_id"]))
tt.AssertStrRepEqual(t, "msg.title", "M_004", msg4Get["title"])
tt.AssertStrRepEqual(t, "msg.content", "TestSendWithPriority#004", msg4Get["content"])
tt.AssertStrRepEqual(t, "msg.content", 2, msg4Get["priority"])
}
} }
//TODO compat route //TODO compat route
//TODO post to channel //TODO post to channel
//TODO post to newly-created-channel //TODO post to newly-created-channel
//TODO post to foreign channel via send-key //TODO post to foreign channel via send-key
//TODO quota exceed (+ quota counter) //TODO quota exceed (+ quota counter)
//TODO invalid priority //TODO invalid priority
//TODO chan_naem too long //TODO chan_naem too long
//TODO chan_name normalization //TODO chan_name normalization
//TODO custom_timestamp //TODO custom_timestamp
//TODO invalid time //TODO invalid time
//TODO check message_counter + last_sent in channel //TODO check message_counter + last_sent in channel
//TODO check message_counter + last_sent in user //TODO check message_counter + last_sent in user
//todo test pagination

View File

@ -147,8 +147,15 @@ func TestFailErr(t *testing.T, e error) {
} }
func unpointer(v any) any { func unpointer(v any) any {
if v == nil {
return v
}
val := reflect.ValueOf(v) val := reflect.ValueOf(v)
if val.Kind() == reflect.Ptr { if val.Kind() == reflect.Ptr {
if val.IsNil() {
return v
}
val = val.Elem() val = val.Elem()
return unpointer(val.Interface()) return unpointer(val.Interface())
} }

View File

@ -102,6 +102,8 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, func()) {
stop := func() { app.Stop(); _ = os.Remove(dbfile) } stop := func() { app.Stop(); _ = os.Remove(dbfile) }
go func() { app.Run() }() go func() { app.Run() }()
time.Sleep(100 * time.Millisecond)
time.Sleep(100 * time.Millisecond) // wait until http server is up
return app, stop return app, stop
} }

View File

@ -165,7 +165,7 @@
{{config|baseURL}}/</pre> {{config|baseURL}}/</pre>
</div> </div>
<h2>Message Uniqueness</h2> <h2>Message Uniqueness (Idempotency)</h2>
<div class="section"> <div class="section">
<p> <p>
Sometimes your script can run in an environment with an unstable connection and you want to implement an automatic re-try mechanism to send a message again if the last try failed due to bad connectivity. Sometimes your script can run in an environment with an unstable connection and you want to implement an automatic re-try mechanism to send a message again if the last try failed due to bad connectivity.