26f897c1ec
release / release-please (push) Failing after 1m49s
docs / build (push) Failing after 6m34s
release / build-and-upload (arm64, linux) (push) Has been cancelled
release / build-and-upload (arm64, windows) (push) Has been cancelled
release / build-darwin (amd64, darwin) (push) Has been cancelled
release / checksums (push) Has been cancelled
release / finalize (push) Has been cancelled
release / build-darwin (arm64, darwin) (push) Has been cancelled
release / build-and-upload (amd64, linux) (push) Has been cancelled
release / build-and-upload (amd64, windows) (push) Has been cancelled
docs / deploy (push) Has been cancelled
188 lines
5.0 KiB
Go
188 lines
5.0 KiB
Go
package telemetry
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestClientTrackSendsUmamiEventPayload(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type requestBody struct {
|
|
Type string `json:"type"`
|
|
Payload struct {
|
|
Website string `json:"website"`
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
Title string `json:"title"`
|
|
Data map[string]any `json:"data"`
|
|
} `json:"payload"`
|
|
}
|
|
|
|
reqCh := make(chan requestBody, 1)
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
t.Fatalf("method = %s, want POST", r.Method)
|
|
}
|
|
if r.URL.Path != "/api/send" {
|
|
t.Fatalf("path = %s, want /api/send", r.URL.Path)
|
|
}
|
|
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
t.Fatalf("read body: %v", err)
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
var got requestBody
|
|
if err := json.Unmarshal(body, &got); err != nil {
|
|
t.Fatalf("unmarshal body: %v\nbody=%s", err, string(body))
|
|
}
|
|
reqCh <- got
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = io.WriteString(w, `{"disabled":false}`)
|
|
}))
|
|
defer server.Close()
|
|
|
|
client, err := NewClient(Config{
|
|
Host: server.URL,
|
|
WebsiteID: "website-123",
|
|
App: "no-mistakes",
|
|
Version: "v1.2.3",
|
|
GOOS: "darwin",
|
|
GOARCH: "arm64",
|
|
HTTPClient: server.Client(),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
client.Track("command", Fields{
|
|
"command": "init",
|
|
"status": "success",
|
|
})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
if err := client.Close(ctx); err != nil {
|
|
t.Fatalf("Close() error = %v", err)
|
|
}
|
|
|
|
select {
|
|
case got := <-reqCh:
|
|
if got.Type != "event" {
|
|
t.Fatalf("type = %q, want %q", got.Type, "event")
|
|
}
|
|
if got.Payload.Website != "website-123" {
|
|
t.Fatalf("website = %q, want %q", got.Payload.Website, "website-123")
|
|
}
|
|
if got.Payload.Name != "command" {
|
|
t.Fatalf("name = %q, want %q", got.Payload.Name, "command")
|
|
}
|
|
if got.Payload.URL != "app://no-mistakes/command" {
|
|
t.Fatalf("url = %q, want %q", got.Payload.URL, "app://no-mistakes/command")
|
|
}
|
|
if got.Payload.Title != "no-mistakes CLI" {
|
|
t.Fatalf("title = %q, want %q", got.Payload.Title, "no-mistakes CLI")
|
|
}
|
|
if got.Payload.Data["command"] != "init" {
|
|
t.Fatalf("data.command = %v, want %q", got.Payload.Data["command"], "init")
|
|
}
|
|
if got.Payload.Data["status"] != "success" {
|
|
t.Fatalf("data.status = %v, want %q", got.Payload.Data["status"], "success")
|
|
}
|
|
for _, key := range []string{"app_version", "goos", "goarch", "build_channel"} {
|
|
if _, ok := got.Payload.Data[key]; ok {
|
|
t.Fatalf("data.%s should be omitted to keep Umami event-data volume low", key)
|
|
}
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatal("timed out waiting for telemetry request")
|
|
}
|
|
}
|
|
|
|
func TestClientPageviewSendsUmamiPageviewPayload(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type requestBody struct {
|
|
Type string `json:"type"`
|
|
Payload struct {
|
|
Website string `json:"website"`
|
|
Name *string `json:"name,omitempty"`
|
|
URL string `json:"url"`
|
|
Title string `json:"title"`
|
|
Data map[string]any `json:"data"`
|
|
} `json:"payload"`
|
|
}
|
|
|
|
reqCh := make(chan requestBody, 1)
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
t.Fatalf("read body: %v", err)
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
var got requestBody
|
|
if err := json.Unmarshal(body, &got); err != nil {
|
|
t.Fatalf("unmarshal body: %v\nbody=%s", err, string(body))
|
|
}
|
|
reqCh <- got
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = io.WriteString(w, `{"disabled":false}`)
|
|
}))
|
|
defer server.Close()
|
|
|
|
client, err := NewClient(Config{
|
|
Host: server.URL,
|
|
WebsiteID: "website-123",
|
|
App: "no-mistakes",
|
|
Version: "v1.2.3",
|
|
GOOS: "darwin",
|
|
GOARCH: "arm64",
|
|
HTTPClient: server.Client(),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
client.Pageview("/tui", Fields{"entrypoint": "attach"})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
if err := client.Close(ctx); err != nil {
|
|
t.Fatalf("Close() error = %v", err)
|
|
}
|
|
|
|
select {
|
|
case got := <-reqCh:
|
|
if got.Type != "event" {
|
|
t.Fatalf("type = %q, want %q", got.Type, "event")
|
|
}
|
|
if got.Payload.Website != "website-123" {
|
|
t.Fatalf("website = %q, want %q", got.Payload.Website, "website-123")
|
|
}
|
|
if got.Payload.Name != nil {
|
|
t.Fatalf("name = %v, want omitted for pageview", *got.Payload.Name)
|
|
}
|
|
if got.Payload.URL != "/tui" {
|
|
t.Fatalf("url = %q, want %q", got.Payload.URL, "/tui")
|
|
}
|
|
if got.Payload.Title != "no-mistakes CLI" {
|
|
t.Fatalf("title = %q, want %q", got.Payload.Title, "no-mistakes CLI")
|
|
}
|
|
if got.Payload.Data["entrypoint"] != "attach" {
|
|
t.Fatalf("data.entrypoint = %v, want %q", got.Payload.Data["entrypoint"], "attach")
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatal("timed out waiting for telemetry request")
|
|
}
|
|
}
|