mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-01-18 16:17:26 +01:00
Add tests, fix firebase
This commit is contained in:
@@ -143,6 +143,15 @@ func toFirebaseMessage(m *message, auther user.Auther) (*messaging.Message, erro
|
||||
"poll_id": m.PollID,
|
||||
}
|
||||
apnsConfig = createAPNSAlertConfig(m, data)
|
||||
case messageDeleteEvent, messageClearEvent:
|
||||
data = map[string]string{
|
||||
"id": m.ID,
|
||||
"time": fmt.Sprintf("%d", m.Time),
|
||||
"event": m.Event,
|
||||
"topic": m.Topic,
|
||||
"sequence_id": m.SequenceID,
|
||||
}
|
||||
apnsConfig = createAPNSBackgroundConfig(data)
|
||||
case messageEvent:
|
||||
if auther != nil {
|
||||
// If "anonymous read" for a topic is not allowed, we cannot send the message along
|
||||
@@ -161,6 +170,7 @@ func toFirebaseMessage(m *message, auther user.Auther) (*messaging.Message, erro
|
||||
"time": fmt.Sprintf("%d", m.Time),
|
||||
"event": m.Event,
|
||||
"topic": m.Topic,
|
||||
"sequence_id": m.SequenceID,
|
||||
"priority": fmt.Sprintf("%d", m.Priority),
|
||||
"tags": strings.Join(m.Tags, ","),
|
||||
"click": m.Click,
|
||||
|
||||
@@ -177,6 +177,7 @@ func TestToFirebaseMessage_Message_Normal_Allowed(t *testing.T) {
|
||||
"time": fmt.Sprintf("%d", m.Time),
|
||||
"event": "message",
|
||||
"topic": "mytopic",
|
||||
"sequence_id": "",
|
||||
"priority": "4",
|
||||
"tags": strings.Join(m.Tags, ","),
|
||||
"click": "https://google.com",
|
||||
@@ -199,6 +200,7 @@ func TestToFirebaseMessage_Message_Normal_Allowed(t *testing.T) {
|
||||
"time": fmt.Sprintf("%d", m.Time),
|
||||
"event": "message",
|
||||
"topic": "mytopic",
|
||||
"sequence_id": "",
|
||||
"priority": "4",
|
||||
"tags": strings.Join(m.Tags, ","),
|
||||
"click": "https://google.com",
|
||||
@@ -232,6 +234,7 @@ func TestToFirebaseMessage_Message_Normal_Not_Allowed(t *testing.T) {
|
||||
"time": fmt.Sprintf("%d", m.Time),
|
||||
"event": "poll_request",
|
||||
"topic": "mytopic",
|
||||
"sequence_id": "",
|
||||
"message": "New message",
|
||||
"title": "",
|
||||
"tags": "",
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"heckel.io/ntfy/v2/user"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -24,7 +22,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"heckel.io/ntfy/v2/log"
|
||||
"heckel.io/ntfy/v2/user"
|
||||
"heckel.io/ntfy/v2/util"
|
||||
)
|
||||
|
||||
@@ -3289,6 +3289,212 @@ func TestServer_MessageTemplate_Until100_000(t *testing.T) {
|
||||
require.Contains(t, toHTTPError(t, response.Body.String()).Message, "too many iterations")
|
||||
}
|
||||
|
||||
func TestServer_DeleteMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
|
||||
// Publish a message with a sequence ID
|
||||
response := request(t, s, "PUT", "/mytopic/seq123", "original message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq123", msg.SequenceID)
|
||||
require.Equal(t, "message", msg.Event)
|
||||
|
||||
// Delete the message using DELETE method
|
||||
response = request(t, s, "DELETE", "/mytopic/seq123", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
deleteMsg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq123", deleteMsg.SequenceID)
|
||||
require.Equal(t, "message_delete", deleteMsg.Event)
|
||||
|
||||
// Poll and verify both messages are returned
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
lines := strings.Split(strings.TrimSpace(response.Body.String()), "\n")
|
||||
require.Equal(t, 2, len(lines))
|
||||
|
||||
msg1 := toMessage(t, lines[0])
|
||||
msg2 := toMessage(t, lines[1])
|
||||
require.Equal(t, "message", msg1.Event)
|
||||
require.Equal(t, "message_delete", msg2.Event)
|
||||
require.Equal(t, "seq123", msg1.SequenceID)
|
||||
require.Equal(t, "seq123", msg2.SequenceID)
|
||||
}
|
||||
|
||||
func TestServer_ClearMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
|
||||
// Publish a message with a sequence ID
|
||||
response := request(t, s, "PUT", "/mytopic/seq456", "original message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq456", msg.SequenceID)
|
||||
require.Equal(t, "message", msg.Event)
|
||||
|
||||
// Clear the message using PUT /topic/seq/clear
|
||||
response = request(t, s, "PUT", "/mytopic/seq456/clear", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
clearMsg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq456", clearMsg.SequenceID)
|
||||
require.Equal(t, "message_clear", clearMsg.Event)
|
||||
|
||||
// Poll and verify both messages are returned
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
lines := strings.Split(strings.TrimSpace(response.Body.String()), "\n")
|
||||
require.Equal(t, 2, len(lines))
|
||||
|
||||
msg1 := toMessage(t, lines[0])
|
||||
msg2 := toMessage(t, lines[1])
|
||||
require.Equal(t, "message", msg1.Event)
|
||||
require.Equal(t, "message_clear", msg2.Event)
|
||||
require.Equal(t, "seq456", msg1.SequenceID)
|
||||
require.Equal(t, "seq456", msg2.SequenceID)
|
||||
}
|
||||
|
||||
func TestServer_ClearMessage_ReadEndpoint(t *testing.T) {
|
||||
// Test that /topic/seq/read also works
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
|
||||
// Publish a message
|
||||
response := request(t, s, "PUT", "/mytopic/seq789", "original message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
|
||||
// Clear using /read endpoint
|
||||
response = request(t, s, "PUT", "/mytopic/seq789/read", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
clearMsg := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "seq789", clearMsg.SequenceID)
|
||||
require.Equal(t, "message_clear", clearMsg.Event)
|
||||
}
|
||||
|
||||
func TestServer_UpdateMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
|
||||
// Publish original message
|
||||
response := request(t, s, "PUT", "/mytopic/update-seq", "original message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg1 := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "update-seq", msg1.SequenceID)
|
||||
require.Equal(t, "original message", msg1.Message)
|
||||
|
||||
// Update the message (same sequence ID, new content)
|
||||
response = request(t, s, "PUT", "/mytopic/update-seq", "updated message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg2 := toMessage(t, response.Body.String())
|
||||
require.Equal(t, "update-seq", msg2.SequenceID)
|
||||
require.Equal(t, "updated message", msg2.Message)
|
||||
require.NotEqual(t, msg1.ID, msg2.ID) // Different message IDs
|
||||
|
||||
// Poll and verify both versions are returned
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
lines := strings.Split(strings.TrimSpace(response.Body.String()), "\n")
|
||||
require.Equal(t, 2, len(lines))
|
||||
|
||||
polledMsg1 := toMessage(t, lines[0])
|
||||
polledMsg2 := toMessage(t, lines[1])
|
||||
require.Equal(t, "original message", polledMsg1.Message)
|
||||
require.Equal(t, "updated message", polledMsg2.Message)
|
||||
require.Equal(t, "update-seq", polledMsg1.SequenceID)
|
||||
require.Equal(t, "update-seq", polledMsg2.SequenceID)
|
||||
}
|
||||
|
||||
func TestServer_UpdateMessage_UsingMessageID(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
|
||||
// Publish original message without a sequence ID
|
||||
response := request(t, s, "PUT", "/mytopic", "original message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg1 := toMessage(t, response.Body.String())
|
||||
require.NotEmpty(t, msg1.ID)
|
||||
require.Empty(t, msg1.SequenceID) // No sequence ID provided
|
||||
require.Equal(t, "original message", msg1.Message)
|
||||
|
||||
// Update the message using the message ID as the sequence ID
|
||||
response = request(t, s, "PUT", "/mytopic/"+msg1.ID, "updated message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
msg2 := toMessage(t, response.Body.String())
|
||||
require.Equal(t, msg1.ID, msg2.SequenceID) // Message ID is now used as sequence ID
|
||||
require.Equal(t, "updated message", msg2.Message)
|
||||
require.NotEqual(t, msg1.ID, msg2.ID) // Different message IDs
|
||||
|
||||
// Poll and verify both versions are returned
|
||||
response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
lines := strings.Split(strings.TrimSpace(response.Body.String()), "\n")
|
||||
require.Equal(t, 2, len(lines))
|
||||
|
||||
polledMsg1 := toMessage(t, lines[0])
|
||||
polledMsg2 := toMessage(t, lines[1])
|
||||
require.Equal(t, "original message", polledMsg1.Message)
|
||||
require.Equal(t, "updated message", polledMsg2.Message)
|
||||
require.Empty(t, polledMsg1.SequenceID) // Original has no sequence ID
|
||||
require.Equal(t, msg1.ID, polledMsg2.SequenceID) // Update uses original message ID as sequence ID
|
||||
}
|
||||
|
||||
func TestServer_DeleteAndClear_InvalidSequenceID(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
|
||||
// Test invalid sequence ID for delete (returns 404 because route doesn't match)
|
||||
response := request(t, s, "DELETE", "/mytopic/invalid*seq", "", nil)
|
||||
require.Equal(t, 404, response.Code)
|
||||
|
||||
// Test invalid sequence ID for clear (returns 404 because route doesn't match)
|
||||
response = request(t, s, "PUT", "/mytopic/invalid*seq/clear", "", nil)
|
||||
require.Equal(t, 404, response.Code)
|
||||
}
|
||||
|
||||
func TestServer_DeleteMessage_WithFirebase(t *testing.T) {
|
||||
sender := newTestFirebaseSender(10)
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
s.firebaseClient = newFirebaseClient(sender, &testAuther{Allow: true})
|
||||
|
||||
// Publish a message
|
||||
response := request(t, s, "PUT", "/mytopic/firebase-seq", "test message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
|
||||
time.Sleep(100 * time.Millisecond) // Firebase publishing happens
|
||||
require.Equal(t, 1, len(sender.Messages()))
|
||||
require.Equal(t, "message", sender.Messages()[0].Data["event"])
|
||||
|
||||
// Delete the message
|
||||
response = request(t, s, "DELETE", "/mytopic/firebase-seq", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
|
||||
time.Sleep(100 * time.Millisecond) // Firebase publishing happens
|
||||
require.Equal(t, 2, len(sender.Messages()))
|
||||
require.Equal(t, "message_delete", sender.Messages()[1].Data["event"])
|
||||
require.Equal(t, "firebase-seq", sender.Messages()[1].Data["sequence_id"])
|
||||
}
|
||||
|
||||
func TestServer_ClearMessage_WithFirebase(t *testing.T) {
|
||||
sender := newTestFirebaseSender(10)
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
s.firebaseClient = newFirebaseClient(sender, &testAuther{Allow: true})
|
||||
|
||||
// Publish a message
|
||||
response := request(t, s, "PUT", "/mytopic/firebase-clear-seq", "test message", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
require.Equal(t, 1, len(sender.Messages()))
|
||||
|
||||
// Clear the message
|
||||
response = request(t, s, "PUT", "/mytopic/firebase-clear-seq/clear", "", nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
require.Equal(t, 2, len(sender.Messages()))
|
||||
require.Equal(t, "message_clear", sender.Messages()[1].Data["event"])
|
||||
require.Equal(t, "firebase-clear-seq", sender.Messages()[1].Data["sequence_id"])
|
||||
}
|
||||
|
||||
func newTestConfig(t *testing.T) *Config {
|
||||
conf := NewConfig()
|
||||
conf.BaseURL = "http://127.0.0.1:12345"
|
||||
|
||||
Reference in New Issue
Block a user