1
0
Fork 0

Adding upstream version 0.8.9.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-22 10:16:14 +02:00
parent 3b2c48b5e4
commit c0c4addb85
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
285 changed files with 25880 additions and 0 deletions

View file

@ -0,0 +1,252 @@
package rocketchat
import (
"crypto/tls"
"crypto/x509"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"github.com/nicholas-fedor/shoutrrr/internal/testutils"
"github.com/nicholas-fedor/shoutrrr/pkg/types"
)
var (
service *Service
envRocketchatURL *url.URL
_ = ginkgo.BeforeSuite(func() {
service = &Service{}
envRocketchatURL, _ = url.Parse(os.Getenv("SHOUTRRR_ROCKETCHAT_URL"))
})
)
// Constants for repeated test values.
const (
testTokenA = "tokenA"
testTokenB = "tokenB"
)
func TestRocketchat(t *testing.T) {
gomega.RegisterFailHandler(ginkgo.Fail)
ginkgo.RunSpecs(t, "Shoutrrr Rocketchat Suite")
}
var _ = ginkgo.Describe("the rocketchat service", func() {
// Add tests for Initialize()
ginkgo.Describe("Initialize method", func() {
ginkgo.When("initializing with a valid URL", func() {
ginkgo.It("should set logger and config without error", func() {
service := &Service{}
testURL, _ := url.Parse(
"rocketchat://testUser@rocketchat.my-domain.com:5055/" + testTokenA + "/" + testTokenB + "/#testChannel",
)
err := service.Initialize(testURL, testutils.TestLogger())
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(service.Config).NotTo(gomega.BeNil())
gomega.Expect(service.Config.Host).To(gomega.Equal("rocketchat.my-domain.com"))
gomega.Expect(service.Config.Port).To(gomega.Equal("5055"))
gomega.Expect(service.Config.UserName).To(gomega.Equal("testUser"))
gomega.Expect(service.Config.TokenA).To(gomega.Equal(testTokenA))
gomega.Expect(service.Config.TokenB).To(gomega.Equal(testTokenB))
gomega.Expect(service.Config.Channel).To(gomega.Equal("#testChannel"))
})
})
ginkgo.When("initializing with an invalid URL", func() {
ginkgo.It("should return an error", func() {
service := &Service{}
testURL, _ := url.Parse("rocketchat://rocketchat.my-domain.com") // Missing tokens
err := service.Initialize(testURL, testutils.TestLogger())
gomega.Expect(err).To(gomega.HaveOccurred())
gomega.Expect(err).
To(gomega.Equal(ErrNotEnoughArguments))
// Updated to use the error variable
})
})
})
// Add tests for Send()
ginkgo.Describe("Send method", func() {
var (
mockServer *httptest.Server
service *Service
client *http.Client
)
ginkgo.BeforeEach(func() {
// Create TLS server
mockServer = httptest.NewTLSServer(nil) // Handler set in each test
// Configure client to trust the mock server's certificate
certPool := x509.NewCertPool()
for _, cert := range mockServer.TLS.Certificates {
certPool.AddCert(cert.Leaf)
}
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
MinVersion: tls.VersionTLS12, // Explicitly set minimum TLS version to 1.2
},
},
}
service = &Service{
Config: &Config{},
Client: client, // Assign the custom client here
}
service.SetLogger(testutils.TestLogger())
})
ginkgo.AfterEach(func() {
if mockServer != nil {
mockServer.Close()
}
})
ginkgo.When("sending a message to a mock server with success", func() {
ginkgo.It("should return no error", func() {
mockServer.Config.Handler = http.HandlerFunc(
func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
},
)
mockURL, _ := url.Parse(mockServer.URL)
service.Config.Host = mockURL.Hostname()
service.Config.Port = mockURL.Port()
service.Config.TokenA = testTokenA
service.Config.TokenB = testTokenB
err := service.Send("test message", nil)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
})
})
ginkgo.When("sending a message to a mock server with failure", func() {
ginkgo.It("should return an error with status code and body", func() {
mockServer.Config.Handler = http.HandlerFunc(
func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("bad request"))
},
)
mockURL, _ := url.Parse(mockServer.URL)
service.Config.Host = mockURL.Hostname()
service.Config.Port = mockURL.Port()
service.Config.TokenA = testTokenA
service.Config.TokenB = testTokenB
err := service.Send("test message", nil)
gomega.Expect(err).To(gomega.HaveOccurred())
gomega.Expect(err.Error()).
To(gomega.ContainSubstring("notification failed: 400 bad request"))
})
})
ginkgo.When("sending a message to an unreachable server", func() {
ginkgo.It("should return a connection error", func() {
service.Client = http.DefaultClient // Reset to default client for this test
service.Config.Host = "nonexistent.domain"
service.Config.TokenA = testTokenA
service.Config.TokenB = testTokenB
err := service.Send("test message", nil)
gomega.Expect(err).To(gomega.HaveOccurred())
gomega.Expect(err.Error()).To(gomega.ContainSubstring("posting to URL"))
})
})
ginkgo.When("sending a message with params overriding username and channel", func() {
ginkgo.It("should use params values in the payload", func() {
mockServer.Config.Handler = http.HandlerFunc(
func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
},
)
mockURL, _ := url.Parse(mockServer.URL)
service.Config.Host = mockURL.Hostname()
service.Config.Port = mockURL.Port()
service.Config.TokenA = testTokenA
service.Config.TokenB = testTokenB
service.Config.UserName = "defaultUser"
service.Config.Channel = "#defaultChannel"
params := types.Params{
"username": "overrideUser",
"channel": "#overrideChannel",
}
err := service.Send("test message", &params)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Note: We can't directly inspect the payload here without mocking CreateJSONPayload,
// but this ensures the params path is exercised.
})
})
})
// Add tests for GetURL() and SetURL()
ginkgo.Describe("the rocketchat config", func() {
ginkgo.When("generating a URL from a config with all fields", func() {
ginkgo.It("should construct a correct URL", func() {
config := &Config{
Host: "rocketchat.my-domain.com",
Port: "5055",
TokenA: testTokenA,
TokenB: testTokenB,
}
url := config.GetURL()
gomega.Expect(url.String()).
To(gomega.Equal("rocketchat://rocketchat.my-domain.com:5055/" + testTokenA + "/" + testTokenB))
})
})
ginkgo.When("generating a URL from a config without port", func() {
ginkgo.It("should construct a correct URL without port", func() {
config := &Config{
Host: "rocketchat.my-domain.com",
TokenA: testTokenA,
TokenB: testTokenB,
}
url := config.GetURL()
gomega.Expect(url.String()).
To(gomega.Equal("rocketchat://rocketchat.my-domain.com/" + testTokenA + "/" + testTokenB))
})
})
ginkgo.When("setting URL with a channel starting with @", func() {
ginkgo.It("should set channel without adding #", func() {
config := &Config{}
testURL, _ := url.Parse(
"rocketchat://rocketchat.my-domain.com/" + testTokenA + "/" + testTokenB + "/@user",
)
err := config.SetURL(testURL)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(config.Channel).To(gomega.Equal("@user"))
})
})
ginkgo.When("setting URL with a regular channel without fragment", func() {
ginkgo.It("should prepend # to the channel", func() {
config := &Config{}
testURL, _ := url.Parse(
"rocketchat://rocketchat.my-domain.com/" + testTokenA + "/" + testTokenB + "/general",
)
err := config.SetURL(testURL)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(config.Channel).To(gomega.Equal("#general"))
})
})
})
// Add test for GetID()
ginkgo.Describe("GetID method", func() {
ginkgo.It("should return the correct scheme", func() {
service := &Service{}
id := service.GetID()
gomega.Expect(id).To(gomega.Equal(Scheme))
})
})
})