Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ View pageview statistics.
- `--site DOMAIN`: Filter by site domain
- `--last PERIOD`: Relative time period (24h, 7d, 30d, 1mo, 3mo, 6mo)
- `--from DATE`: Start date (YYYY-MM-DD). Without --to, goes from this date to now.
- `--to DATE`: End date (YYYY-MM-DD). Without --from, goes from all time to this date.
- `--to DATE`: End date (YYYY-MM-DD). Without --from, queries all time up to this date. Requires --to alone (do not combine with --from or --last).
- `--verbose`, `-v`: Show detailed view

**Examples:**
Expand Down
50 changes: 46 additions & 4 deletions internal/api/stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,68 @@ func TestStatsFromOnly(t *testing.T) {
_, ts := setupTestServer(t)
token := generateTestToken(t, ts)

req, _ := http.NewRequest("GET", ts.URL+"/api/stats?from=2024-01-01", nil)
body := `{"domain":"example.com"}`
req, _ := http.NewRequest("POST", ts.URL+"/api/sites", strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
http.DefaultClient.Do(req)

collectBody := `{"origin":"https://example.com","path":"/","referrer":"","screen":"1920x1080"}`
req, _ = http.NewRequest("POST", ts.URL+"/collect", strings.NewReader(collectBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Origin", "https://example.com")
http.DefaultClient.Do(req)

req, _ = http.NewRequest("GET", ts.URL+"/api/stats?from=2000-01-01", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
if resp.StatusCode != 200 {
t.Errorf("from only: expected 200, got %d", resp.StatusCode)
t.Fatalf("from only: expected 200, got %d", resp.StatusCode)
}

var stats []struct {
Site string `json:"site"`
Path string `json:"path"`
}
json.NewDecoder(resp.Body).Decode(&stats)
resp.Body.Close()
if len(stats) == 0 {
t.Error("expected data with from-only filter, got empty")
}
}

func TestStatsToOnly(t *testing.T) {
_, ts := setupTestServer(t)
token := generateTestToken(t, ts)

req, _ := http.NewRequest("GET", ts.URL+"/api/stats?to=2024-01-31", nil)
body := `{"domain":"example.com"}`
req, _ := http.NewRequest("POST", ts.URL+"/api/sites", strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
http.DefaultClient.Do(req)

collectBody := `{"origin":"https://example.com","path":"/","referrer":"","screen":"1920x1080"}`
req, _ = http.NewRequest("POST", ts.URL+"/collect", strings.NewReader(collectBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Origin", "https://example.com")
http.DefaultClient.Do(req)

req, _ = http.NewRequest("GET", ts.URL+"/api/stats?to=2099-01-01", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
if resp.StatusCode != 200 {
t.Errorf("to only: expected 200, got %d", resp.StatusCode)
t.Fatalf("to only: expected 200, got %d", resp.StatusCode)
}

var stats []struct {
Site string `json:"site"`
Path string `json:"path"`
}
json.NewDecoder(resp.Body).Decode(&stats)
resp.Body.Close()
if len(stats) == 0 {
t.Error("expected data with to-only filter, got empty")
}
}

func TestStatsDefaultTimeRange(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Options:
--site DOMAIN Filter by site domain
--last PERIOD Relative period: 24h, 7d, 30d, 1mo, 3mo, 6mo (default: 24h)
--from DATE Start date (YYYY-MM-DD). Without --to, goes to now.
--to DATE End date (YYYY-MM-DD). Without --from, goes from all time.
--to DATE End date (YYYY-MM-DD). Without --from, queries all time up to this date.
--verbose, -v Show detailed view

Examples:
Expand Down
16 changes: 8 additions & 8 deletions internal/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ func TestGetAggregateStats(t *testing.T) {
}
}

func TestGetAggregateStatsFromOnly(t *testing.T) {
func TestGetAggregateStatsToOnly(t *testing.T) {
db := setupTestDB(t)
site, _ := db.AddSite("example.com")
db.InsertPageview(models.PageviewInput{SiteID: site.ID, IP: "1.2.3.4", Path: "/"})
Expand All @@ -449,14 +449,14 @@ func TestGetAggregateStatsFromOnly(t *testing.T) {

rows, err := db.GetAggregateStats(q)
if err != nil {
t.Fatalf("get aggregate stats with zero from: %v", err)
t.Fatalf("get aggregate stats with to only: %v", err)
}
if len(rows) != 1 {
t.Errorf("expected 1 stat row, got %d", len(rows))
}
}

func TestGetAggregateStatsToOnly(t *testing.T) {
func TestGetAggregateStatsFromOnly(t *testing.T) {
db := setupTestDB(t)
site, _ := db.AddSite("example.com")
db.InsertPageview(models.PageviewInput{SiteID: site.ID, IP: "1.2.3.4", Path: "/"})
Expand All @@ -468,7 +468,7 @@ func TestGetAggregateStatsToOnly(t *testing.T) {

rows, err := db.GetAggregateStats(q)
if err != nil {
t.Fatalf("get aggregate stats with zero to: %v", err)
t.Fatalf("get aggregate stats with from only: %v", err)
}
if len(rows) != 1 {
t.Errorf("expected 1 stat row, got %d", len(rows))
Expand Down Expand Up @@ -551,7 +551,7 @@ func TestGetVerboseStats(t *testing.T) {
}
}

func TestGetVerboseStatsFromOnly(t *testing.T) {
func TestGetVerboseStatsToOnly(t *testing.T) {
db := setupTestDB(t)
site, _ := db.AddSite("example.com")
db.InsertPageview(models.PageviewInput{SiteID: site.ID, IP: "1.2.3.4", Path: "/"})
Expand All @@ -563,14 +563,14 @@ func TestGetVerboseStatsFromOnly(t *testing.T) {

rows, err := db.GetVerboseStats(q)
if err != nil {
t.Fatalf("get verbose stats with zero from: %v", err)
t.Fatalf("get verbose stats with to only: %v", err)
}
if len(rows) != 1 {
t.Errorf("expected 1 row, got %d", len(rows))
}
}

func TestGetVerboseStatsToOnly(t *testing.T) {
func TestGetVerboseStatsFromOnly(t *testing.T) {
db := setupTestDB(t)
site, _ := db.AddSite("example.com")
db.InsertPageview(models.PageviewInput{SiteID: site.ID, IP: "1.2.3.4", Path: "/"})
Expand All @@ -582,7 +582,7 @@ func TestGetVerboseStatsToOnly(t *testing.T) {

rows, err := db.GetVerboseStats(q)
if err != nil {
t.Fatalf("get verbose stats with zero to: %v", err)
t.Fatalf("get verbose stats with from only: %v", err)
}
if len(rows) != 1 {
t.Errorf("expected 1 row, got %d", len(rows))
Expand Down
Loading