Only soft-delete messages
This commit is contained in:
parent
98b1e8bd80
commit
66ecad27a7
@ -1237,7 +1237,7 @@ func (h APIHandler) GetMessage(g *gin.Context) ginresp.HTTPResponse {
|
||||
return *permResp
|
||||
}
|
||||
|
||||
msg, err := h.database.GetMessage(ctx, u.MessageID)
|
||||
msg, err := h.database.GetMessage(ctx, u.MessageID, false)
|
||||
if err == sql.ErrNoRows {
|
||||
return ginresp.APIError(g, 404, apierr.MESSAGE_NOT_FOUND, "message not found", err)
|
||||
}
|
||||
@ -1307,7 +1307,7 @@ func (h APIHandler) DeleteMessage(g *gin.Context) ginresp.HTTPResponse {
|
||||
return *permResp
|
||||
}
|
||||
|
||||
msg, err := h.database.GetMessage(ctx, u.MessageID)
|
||||
msg, err := h.database.GetMessage(ctx, u.MessageID, false)
|
||||
if err == sql.ErrNoRows {
|
||||
return ginresp.APIError(g, 404, apierr.MESSAGE_NOT_FOUND, "message not found", err)
|
||||
}
|
||||
|
@ -533,7 +533,7 @@ func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse {
|
||||
return ginresp.CompatAPIError(204, "Authentification failed")
|
||||
}
|
||||
|
||||
msg, err := h.database.GetMessage(ctx, models.SCNMessageID(*data.MessageID))
|
||||
msg, err := h.database.GetMessage(ctx, models.SCNMessageID(*data.MessageID), false)
|
||||
if err == sql.ErrNoRows {
|
||||
return ginresp.CompatAPIError(301, "Message not found")
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex
|
||||
return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, hl.NONE, "Failed to query existing message", err)
|
||||
}
|
||||
if msg != nil {
|
||||
//the found message can be deleted (!), but we still return NO_ERROR here...
|
||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{
|
||||
Success: true,
|
||||
ErrorID: apierr.NO_ERROR,
|
||||
|
@ -30,13 +30,20 @@ func (db *Database) GetMessageByUserMessageID(ctx TxContext, usrMsgId string) (*
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetMessage(ctx TxContext, scnMessageID models.SCNMessageID) (models.Message, error) {
|
||||
func (db *Database) GetMessage(ctx TxContext, scnMessageID models.SCNMessageID, allowDeleted bool) (models.Message, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Message{}, err
|
||||
}
|
||||
|
||||
rows, err := tx.Query(ctx, "SELECT * FROM messages WHERE scn_message_id = :mid LIMIT 1", sq.PP{"mid": scnMessageID})
|
||||
var sqlcmd string
|
||||
if allowDeleted {
|
||||
sqlcmd = "SELECT * FROM messages WHERE scn_message_id = :mid LIMIT 1"
|
||||
} else {
|
||||
sqlcmd = "SELECT * FROM messages WHERE scn_message_id = :mid AND deleted=0 LIMIT 1"
|
||||
}
|
||||
|
||||
rows, err := tx.Query(ctx, sqlcmd, sq.PP{"mid": scnMessageID})
|
||||
if err != nil {
|
||||
return models.Message{}, err
|
||||
}
|
||||
@ -103,7 +110,7 @@ func (db *Database) DeleteMessage(ctx TxContext, scnMessageID models.SCNMessageI
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "DELETE FROM messages WHERE scn_message_id = :mid", sq.PP{"mid": scnMessageID})
|
||||
_, err = tx.Exec(ctx, "UPDATE messages SET deleted=1 WHERE scn_message_id = :mid AND deleted=0", sq.PP{"mid": scnMessageID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -90,7 +90,9 @@ CREATE TABLE messages
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NULL,
|
||||
priority INTEGER CHECK(priority IN (0, 1, 2)) NOT NULL,
|
||||
usr_message_id TEXT NULL
|
||||
usr_message_id TEXT NULL,
|
||||
|
||||
deleted INTEGER CHECK(deleted IN (0, 1)) NOT NULL DEFAULT '0'
|
||||
) STRICT;
|
||||
CREATE INDEX "idx_messages_owner_channel" ON messages (owner_user_id, channel_name COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_owner_channel_nc" ON messages (owner_user_id, channel_name COLLATE NOCASE);
|
||||
@ -102,6 +104,7 @@ CREATE INDEX "idx_messages_sendername" ON messages (sender_name COL
|
||||
CREATE INDEX "idx_messages_sendername_nc" ON messages (sender_name COLLATE NOCASE);
|
||||
CREATE INDEX "idx_messages_title" ON messages (title COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_title_nc" ON messages (title COLLATE NOCASE);
|
||||
CREATE INDEX "idx_messages_deleted" ON messages (deleted);
|
||||
|
||||
|
||||
CREATE VIRTUAL TABLE messages_fts USING fts5
|
||||
|
@ -93,36 +93,47 @@ func (j *DeliveryRetryJob) redeliver(ctx *logic.SimpleContext, delivery models.D
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := j.app.Database.GetMessage(ctx, delivery.SCNMessageID)
|
||||
msg, err := j.app.Database.GetMessage(ctx, delivery.SCNMessageID, true)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Msg("Failed to get message")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
}
|
||||
|
||||
fcmDelivID, err := j.app.DeliverMessage(ctx, client, msg)
|
||||
if err == nil {
|
||||
err = j.app.Database.SetDeliverySuccess(ctx, delivery, *fcmDelivID)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Failed to update delivery")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
}
|
||||
} else if delivery.RetryCount+1 > delivery.MaxRetryCount() {
|
||||
if msg.Deleted {
|
||||
err = j.app.Database.SetDeliveryFailed(ctx, delivery)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Failed to update delivery")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
}
|
||||
log.Warn().Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Delivery failed after <max> retries (set to FAILURE)")
|
||||
} else {
|
||||
err = j.app.Database.SetDeliveryRetry(ctx, delivery)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Failed to update delivery")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
|
||||
fcmDelivID, err := j.app.DeliverMessage(ctx, client, msg)
|
||||
if err == nil {
|
||||
err = j.app.Database.SetDeliverySuccess(ctx, delivery, *fcmDelivID)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Failed to update delivery")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
}
|
||||
} else if delivery.RetryCount+1 > delivery.MaxRetryCount() {
|
||||
err = j.app.Database.SetDeliveryFailed(ctx, delivery)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Failed to update delivery")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
}
|
||||
log.Warn().Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Delivery failed after <max> retries (set to FAILURE)")
|
||||
} else {
|
||||
err = j.app.Database.SetDeliveryRetry(ctx, delivery)
|
||||
if err != nil {
|
||||
log.Err(err).Int64("SCNMessageID", delivery.SCNMessageID.IntID()).Int64("DeliveryID", delivery.DeliveryID.IntID()).Msg("Failed to update delivery")
|
||||
ctx.RollbackTransaction()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = ctx.CommitTransaction()
|
||||
|
@ -26,6 +26,7 @@ type Message struct {
|
||||
Content *string
|
||||
Priority int
|
||||
UserMessageID *string
|
||||
Deleted bool
|
||||
}
|
||||
|
||||
func (m Message) FullJSON() MessageJSON {
|
||||
@ -122,6 +123,7 @@ type MessageDB struct {
|
||||
Content *string `db:"content"`
|
||||
Priority int `db:"priority"`
|
||||
UserMessageID *string `db:"usr_message_id"`
|
||||
Deleted int `db:"deleted"`
|
||||
}
|
||||
|
||||
func (m MessageDB) Model() Message {
|
||||
@ -139,6 +141,7 @@ func (m MessageDB) Model() Message {
|
||||
Content: m.Content,
|
||||
Priority: m.Priority,
|
||||
UserMessageID: m.UserMessageID,
|
||||
Deleted: m.Deleted != 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ type MessageFilter struct {
|
||||
TitleCI *string // case-insensitive
|
||||
Priority *[]int
|
||||
UserMessageID *[]string
|
||||
OnlyDeleted bool
|
||||
IncludeDeleted bool
|
||||
}
|
||||
|
||||
func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
||||
@ -53,6 +55,14 @@ func (f MessageFilter) SQL() (string, string, sq.PP, error) {
|
||||
|
||||
params := sq.PP{}
|
||||
|
||||
if f.OnlyDeleted {
|
||||
sqlClauses = append(sqlClauses, "(deleted=1)")
|
||||
} else if f.IncludeDeleted {
|
||||
// nothing, return all
|
||||
} else {
|
||||
sqlClauses = append(sqlClauses, "(deleted=0)") // default
|
||||
}
|
||||
|
||||
if f.ConfirmedSubscriptionBy != nil {
|
||||
sqlClauses = append(sqlClauses, "(subs.subscriber_user_id = :sub_uid AND subs.confirmed = 1)")
|
||||
params["sub_uid"] = *f.ConfirmedSubscriptionBy
|
||||
|
@ -1,12 +1,15 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
||||
tt "blackforestbytes.com/simplecloudnotifier/test/util"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSearchMessageFTSSimple(t *testing.T) {
|
||||
@ -31,4 +34,154 @@ func TestSearchMessageFTSMulti(t *testing.T) {
|
||||
//TODO search for messages by FTS
|
||||
}
|
||||
|
||||
//TODO test missing message-xx methods
|
||||
//TODO more search/list/filter message tests
|
||||
|
||||
//TODO list messages by chan_key
|
||||
|
||||
//TODO list messages from channel that you cannot see
|
||||
|
||||
func TestDeleteMessage(t *testing.T) {
|
||||
ws, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
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": "Message_1",
|
||||
})
|
||||
|
||||
tt.RequestAuthGet[tt.Void](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]))
|
||||
|
||||
tt.RequestAuthDelete[tt.Void](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]), gin.H{})
|
||||
|
||||
tt.RequestAuthGetShouldFail(t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]), 404, apierr.MESSAGE_NOT_FOUND)
|
||||
}
|
||||
|
||||
func TestDeleteMessageAndResendUsrMsgId(t *testing.T) {
|
||||
ws, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
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": "Message_1",
|
||||
"msg_id": "bef8dd3d-078e-4f89-abf4-5258ad22a2e4",
|
||||
})
|
||||
|
||||
tt.AssertEqual(t, "suppress_send", false, msg1["suppress_send"])
|
||||
|
||||
tt.RequestAuthGet[tt.Void](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]))
|
||||
|
||||
msg2 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
|
||||
"user_key": sendtok,
|
||||
"user_id": uid,
|
||||
"title": "Message_1",
|
||||
"msg_id": "bef8dd3d-078e-4f89-abf4-5258ad22a2e4",
|
||||
})
|
||||
|
||||
tt.AssertEqual(t, "suppress_send", true, msg2["suppress_send"])
|
||||
|
||||
tt.RequestAuthDelete[tt.Void](t, admintok, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msg1["scn_msg_id"]), gin.H{})
|
||||
|
||||
// even though message is deleted, we still get a `suppress_send` on send_message
|
||||
|
||||
msg3 := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
|
||||
"user_key": sendtok,
|
||||
"user_id": uid,
|
||||
"title": "Message_1",
|
||||
"msg_id": "bef8dd3d-078e-4f89-abf4-5258ad22a2e4",
|
||||
})
|
||||
|
||||
tt.AssertEqual(t, "suppress_send", true, msg3["suppress_send"])
|
||||
|
||||
}
|
||||
|
||||
func TestGetMessageSimple(t *testing.T) {
|
||||
ws, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
msgOut := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
|
||||
"user_key": data.User[0].SendKey,
|
||||
"user_id": data.User[0].UID,
|
||||
"title": "Message_1",
|
||||
})
|
||||
|
||||
msgIn := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msgOut["scn_msg_id"]))
|
||||
|
||||
tt.AssertEqual(t, "msg.title", "Message_1", msgIn["title"])
|
||||
}
|
||||
|
||||
func TestGetMessageNotFound(t *testing.T) {
|
||||
ws, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
tt.RequestAuthGetShouldFail(t, data.User[0].AdminKey, baseUrl, "/api/messages/8963586", 404, apierr.MESSAGE_NOT_FOUND)
|
||||
}
|
||||
|
||||
func TestGetMessageFull(t *testing.T) {
|
||||
ws, stop := tt.StartSimpleWebserver(t)
|
||||
defer stop()
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
data := tt.InitDefaultData(t, ws)
|
||||
|
||||
ts := time.Now().Unix() - 735
|
||||
content := tt.Lipsum0(2)
|
||||
|
||||
msgOut := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{
|
||||
"user_key": data.User[0].SendKey,
|
||||
"user_id": data.User[0].UID,
|
||||
"title": "Message_1",
|
||||
"content": content,
|
||||
"channel": "demo-channel-007",
|
||||
"msg_id": "580b5055-a9b5-4cee-b53c-28cf304d25b0",
|
||||
"priority": 0,
|
||||
"sender_name": "unit-test-[TestGetMessageFull]",
|
||||
"timestamp": ts,
|
||||
})
|
||||
|
||||
msgIn := tt.RequestAuthGet[gin.H](t, data.User[0].AdminKey, baseUrl, "/api/messages/"+fmt.Sprintf("%v", msgOut["scn_msg_id"]))
|
||||
|
||||
tt.AssertEqual(t, "msg.title", "Message_1", msgIn["title"])
|
||||
tt.AssertEqual(t, "msg.content", content, msgIn["content"])
|
||||
tt.AssertEqual(t, "msg.channel", "demo-channel-007", msgIn["channel_name"])
|
||||
tt.AssertEqual(t, "msg.msg_id", "580b5055-a9b5-4cee-b53c-28cf304d25b0", msgIn["usr_message_id"])
|
||||
tt.AssertStrRepEqual(t, "msg.priority", 0, msgIn["priority"])
|
||||
tt.AssertEqual(t, "msg.sender_name", "unit-test-[TestGetMessageFull]", msgIn["sender_name"])
|
||||
tt.AssertEqual(t, "msg.timestamp", time.Unix(ts, 0).In(timeext.TimezoneBerlin).Format(time.RFC3339Nano), msgIn["timestamp"])
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ var messageExamples = []msgex{
|
||||
{0, "", "", P0, SKEY, "Congratulations", "You have been selected as Employee of the Month. Please come to the front desk to pick up your prize", 0},
|
||||
{0, "", "", PX, AKEY, "Attention", "The water cooler is empty. Could someone please refill it?", timeext.FromHours(-11.29)},
|
||||
{0, "Chatting Chamber", "Mobile Mate", P2, SKEY, "Important", "All employees are required to complete a safety training course by the end of the month", 0},
|
||||
{0, "", "", P1, AKEY, "FAQ Update", lipsum(10001, 1), 0},
|
||||
{0, "", "", P1, AKEY, "FAQ Update", Lipsum(10001, 1), 0},
|
||||
{0, "", "", PX, AKEY, "Notice", "There will be a fire drill at 10:00am tomorrow. Please follow the instructions of the fire marshal", 0},
|
||||
{0, "", "Cellular Confidant", P2, SKEY, "Invitation", "You are invited to a celebration in honor of our 10-year anniversary. The party will be held on Friday at 7:00pm", 0},
|
||||
{0, "", "", P0, SKEY, "Deadline reminder", "Please remember to submit your project proposal by the end of the day \U0001f638", 0},
|
||||
@ -156,9 +156,9 @@ var messageExamples = []msgex{
|
||||
{3, "", "", PX, AKEY, "Payment confirmation", "Your payment of $100 has been successfully processed. Thank you for your business.", 0},
|
||||
{3, "", "", P2, SKEY, "Task completed", "Your task \"Update website content\" has been completed and is ready for review.", 0},
|
||||
{3, "Innovations", "", PX, AKEY, "Invitation to join a group", "You have been invited to join the \"Marketing Team\" group on our collaboration platform.", 0},
|
||||
{3, "", "", P2, SKEY, "Password reset", lipsum(10002, 1), 0},
|
||||
{3, "", "", P2, SKEY, "Low battery alert", lipsum(10003, 2), 0},
|
||||
{3, "Innovations", "", P2, SKEY, "System update available", lipsum(10004, 5), 0},
|
||||
{3, "", "", P2, SKEY, "Password reset", Lipsum(10002, 1), 0},
|
||||
{3, "", "", P2, SKEY, "Low battery alert", Lipsum(10003, 2), 0},
|
||||
{3, "Innovations", "", P2, SKEY, "System update available", Lipsum(10004, 5), 0},
|
||||
{3, "", "", P2, SKEY, "Appointment confirmation", "Your appointment for a physical exam on Monday, March 15th at 10 AM has been confirmed.", 0},
|
||||
{3, "\U0001f5ff", "", P2, SKEY, "Order shipped", "Your order #123456 has been shipped and is on its way to your address.", 0},
|
||||
{3, "", "", P2, SKEY, "Order cancelled", "Your order #123456 has been cancelled. We apologize for any inconvenience this may have caused.", 0},
|
||||
@ -166,7 +166,7 @@ var messageExamples = []msgex{
|
||||
{3, "Reminders", "", PX, AKEY, "Account verification", "", timeext.FromHours(1.15)},
|
||||
{3, "Reminders", "", PX, AKEY, "Overdue payment", "", 0},
|
||||
{3, "Reminders", "", P2, SKEY, "Security alert", "We have detected suspicious activity on your account. Please take the necessary steps to secure your account.", timeext.FromHours(0.80)},
|
||||
{3, "Reminders", "", PX, AKEY, "Product back in stock", lipsum(10001, 6), 0},
|
||||
{3, "Reminders", "", PX, AKEY, "Product back in stock", Lipsum(10001, 6), 0},
|
||||
{3, "", "", PX, AKEY, "Connection lost", "Your device has lost its connection to the internet. Please check your network settings and try again.", 0},
|
||||
{3, "", "", P2, SKEY, "Subscription renewal", "Your subscription is set to renew in one week. Please update your payment information to avoid any interruption in service.", 0},
|
||||
{3, "", "", PX, AKEY, "Work order assigned", "You have been assigned a new work order #123456. Please review the details and complete the task as soon as possible.", 0},
|
||||
@ -202,22 +202,22 @@ var messageExamples = []msgex{
|
||||
{6, "", "server1", P2, SKEY, "Server performance improvement", "Thanks to recent upgrades, the server is now performing better than ever", 0},
|
||||
{6, "", "server1", PX, AKEY, "Server security update", "The server has been updated with the latest security patches and enhancements", 0},
|
||||
{6, "", "server1", P1, AKEY, "Server downtime schedule change", "The server downtime schedule has been changed to every other Friday at 8am EST", 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", lipsum(20001, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", lipsum(20002, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", lipsum(20003, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", lipsum(20004, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", lipsum(20005, 1), 0},
|
||||
{6, "Lipsum", "", P1, AKEY, "Lorem Ipsum", lipsum(20006, 1), 0},
|
||||
{6, "Lipsum", "", P1, AKEY, "Lorem Ipsum", lipsum(20007, 1), timeext.FromHours(-3.39)},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", lipsum(20008, 1), 0},
|
||||
{6, "Lipsum", "", PX, AKEY, "Lorem Ipsum", lipsum(20009, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", lipsum(20010, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", lipsum(20011, 1), 0},
|
||||
{6, "Lipsum", "", PX, AKEY, "Lorem Ipsum", lipsum(20012, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", lipsum(20013, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", lipsum(20014, 1), timeext.FromHours(-2.33)},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", lipsum(20015, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", lipsum(20016, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", Lipsum(20001, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", Lipsum(20002, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", Lipsum(20003, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", Lipsum(20004, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", Lipsum(20005, 1), 0},
|
||||
{6, "Lipsum", "", P1, AKEY, "Lorem Ipsum", Lipsum(20006, 1), 0},
|
||||
{6, "Lipsum", "", P1, AKEY, "Lorem Ipsum", Lipsum(20007, 1), timeext.FromHours(-3.39)},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", Lipsum(20008, 1), 0},
|
||||
{6, "Lipsum", "", PX, AKEY, "Lorem Ipsum", Lipsum(20009, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", Lipsum(20010, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", Lipsum(20011, 1), 0},
|
||||
{6, "Lipsum", "", PX, AKEY, "Lorem Ipsum", Lipsum(20012, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", Lipsum(20013, 1), 0},
|
||||
{6, "Lipsum", "", P2, SKEY, "Lorem Ipsum", Lipsum(20014, 1), timeext.FromHours(-2.33)},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", Lipsum(20015, 1), 0},
|
||||
{6, "Lipsum", "", P0, SKEY, "Lorem Ipsum", Lipsum(20016, 1), 0},
|
||||
|
||||
{7, "", "localhost", P2, SKEY, "Server outage resolution update", "We are still working on resolving the server outage and will provide updates as soon as possible", 0},
|
||||
{7, "", "localhost", P0, SKEY, "New server release update", "A new update for the server has been released. Please update to the latest version for optimal performance", 0},
|
||||
@ -369,6 +369,10 @@ func InitDefaultData(t *testing.T, ws *logic.Application) DefData {
|
||||
return DefData{User: users}
|
||||
}
|
||||
|
||||
func lipsum(seed int64, paracount int) string {
|
||||
func Lipsum(seed int64, paracount int) string {
|
||||
return loremipsum.NewWithSeed(seed).Paragraphs(paracount)
|
||||
}
|
||||
|
||||
func Lipsum0(paracount int) string {
|
||||
return loremipsum.NewWithSeed(0).Paragraphs(paracount)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user