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
5 changes: 1 addition & 4 deletions assets/js/types/query-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,8 @@ export interface QueryApiSchema {
match_day_of_week?: boolean;
/**
* If custom period. A list of two ISO8601 dates or timestamps to compare against.
*
* @minItems 2
* @maxItems 2
*/
date_range: [string, string];
date_range: DateTimeRange | DateRange;
};
};
pagination?: {
Expand Down
2 changes: 1 addition & 1 deletion lib/plausible/stats/comparisons.ex
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ defmodule Plausible.Stats.Comparisons do
end

defp get_comparison_date_range(source_query, %{mode: "custom"} = options) do
DateTimeRange.to_date_range(options.date_range, source_query.timezone)
DateTimeRange.new!(options.date_range.first, options.date_range.last, source_query.timezone)
end

defp maybe_match_day_of_week(comparison_date_range, source_date_range, options) do
Expand Down
4 changes: 4 additions & 0 deletions lib/plausible/stats/datetime_range.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ defmodule Plausible.Stats.DateTimeRange do
new!(first, last)
end

def new!(%DateTime{} = first, %DateTime{} = last, _timezone) do
new!(first, last)
end

def new!(%DateTime{} = first, %DateTime{} = last) do
first = DateTime.truncate(first, :second)
last = DateTime.truncate(last, :second)
Expand Down
2 changes: 1 addition & 1 deletion lib/plausible/stats/filters/query_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ defmodule Plausible.Stats.Filters.QueryParser do
end

defp update_comparisons_date_range(%{comparisons: %{date_range: date_range}} = include, site) do
with {:ok, parsed_date_range} <- parse_date_range_pair(site, date_range) do
with {:ok, parsed_date_range} <- parse_time_range(site, date_range, nil, nil) do
{:ok, put_in(include, [:comparisons, :date_range], parsed_date_range)}
end
end
Expand Down
15 changes: 5 additions & 10 deletions priv/json-schemas/query-api-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,11 @@
"description": "If set and using time:day dimensions, day-of-week of comparison query is matched"
},
"date_range": {
"type": "array",
"additionalItems": false,
"minItems": 2,
"maxItems": 2,
"items": {
"type": "string",
"format": "date"
},
"description": "If custom period. A list of two ISO8601 dates or timestamps to compare against.",
"examples": [["2024-01-01", "2024-01-31"]]
"oneOf": [
{ "$ref": "#/definitions/date_time_range" },
{ "$ref": "#/definitions/date_range" }
],
"description": "If custom period. A list of two ISO8601 dates or timestamps to compare against."
}
},
"required": ["mode", "date_range"],
Expand Down
4 changes: 2 additions & 2 deletions test/plausible/stats/query_result_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ defmodule Plausible.Stats.QueryResultTest do
"pageviews"
],
"date_range": [
"2024-01-01T00:00:00+00:00",
"2024-02-01T23:59:59+00:00"
"2024-01-01T00:00:00Z",
"2024-02-01T23:59:59Z"
],
"filters": [],
"dimensions": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerSitesCrudApiTest do

assert_matches ^strict_map(%{
"domain" => "new.example.com",
"timezone" => "UTC",
"timezone" => "Etc/UTC",
"custom_properties" => [],
"tracker_script_configuration" =>
^strict_map(%{
Expand Down Expand Up @@ -772,7 +772,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerSitesCrudApiTest do

assert_matches ^strict_map(%{
"domain" => ^site.domain,
"timezone" => "UTC",
"timezone" => "Etc/UTC",
"custom_properties" => [],
"tracker_script_configuration" =>
^strict_map(%{
Expand Down Expand Up @@ -807,7 +807,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerSitesCrudApiTest do

assert_matches ^strict_map(%{
"domain" => "new.example.com",
"timezone" => "UTC",
"timezone" => "Etc/UTC",
"custom_properties" => [],
"tracker_script_configuration" =>
^strict_map(%{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1961,7 +1961,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do

assert json_response(conn, 200) == %{
"domain" => "new.example.com",
"timezone" => "UTC",
"timezone" => "Etc/UTC",
"custom_properties" => []
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule PlausibleWeb.Api.ExternalStatsController.QueryComparisonsTest do
use PlausibleWeb.ConnCase
import Plausible.Teams.Test

setup [:create_user, :create_site, :create_api_key, :use_api_key, :create_site_import]

Expand Down Expand Up @@ -377,4 +378,99 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryComparisonsTest do
}
]
end

describe "custom comparison range" do
test "can use date range for custom comparison", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview, timestamp: ~N[2021-01-01 00:00:00]),
build(:pageview, timestamp: ~N[2021-01-01 00:25:00]),
build(:pageview, timestamp: ~N[2021-01-07 00:00:00])
])

conn =
post(conn, "/api/v2/query-internal-test", %{
"site_id" => site.domain,
"metrics" => ["pageviews"],
"date_range" => ["2021-01-07", "2021-01-13"],
"include" => %{
"comparisons" => %{"mode" => "custom", "date_range" => ["2021-01-01", "2021-01-06"]}
}
})

assert json_response(conn, 200)["results"] == [
%{
"dimensions" => [],
"metrics" => [1],
"comparison" => %{"change" => [-50], "dimensions" => [], "metrics" => [2]}
}
]
end

test "can use datetime range for custom comparison", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview, timestamp: ~N[2021-01-01 01:00:00]),
build(:pageview, user_id: 1, timestamp: ~N[2021-01-01 05:25:00]),
build(:pageview, user_id: 1, timestamp: ~N[2021-01-01 05:26:00]),
build(:pageview, timestamp: ~N[2021-01-02 04:00:00]),
build(:pageview, timestamp: ~N[2021-01-03 02:00:00])
])

conn =
post(conn, "/api/v2/query-internal-test", %{
"site_id" => site.domain,
"metrics" => ["visitors", "pageviews"],
"date_range" => ["2021-01-02T03:00:00Z", "2021-01-03T02:59:59Z"],
"include" => %{
"comparisons" => %{
"mode" => "custom",
"date_range" => ["2021-01-01T03:00:00Z", "2021-01-02T02:59:59Z"]
}
}
})

assert json_response(conn, 200)["results"] == [
%{
"dimensions" => [],
"metrics" => [2, 2],
"comparison" => %{"change" => [100, 0], "dimensions" => [], "metrics" => [1, 2]}
}
]
end

test "custom datetime range comparison handles timezones correctly", %{conn: conn, user: user} do
weird_tz_site = new_site(owner: user, timezone: "America/Havana")

populate_stats(weird_tz_site, [
# 03:00 America/Havana
build(:pageview, timestamp: ~N[2021-01-01 08:00:00]),
# 05:25 America/Havana
build(:pageview, timestamp: ~N[2021-01-01 10:25:00]),
# 04:00 America/Havana
build(:pageview, timestamp: ~N[2021-01-02 09:00:00]),
# 02:00 America/Havana
build(:pageview, timestamp: ~N[2021-01-03 08:00:00])
])

conn =
post(conn, "/api/v2/query-internal-test", %{
"site_id" => weird_tz_site.domain,
"metrics" => ["pageviews"],
"date_range" => ["2021-01-02T03:00:00Z", "2021-01-03T02:59:59Z"],
"include" => %{
"comparisons" => %{
"mode" => "custom",
"date_range" => ["2021-01-01T03:00:00Z", "2021-01-02T02:59:59Z"]
}
}
})

assert json_response(conn, 200)["results"] == [
%{
"dimensions" => [],
"metrics" => [1],
"comparison" => %{"change" => [-50], "dimensions" => [], "metrics" => [2]}
}
]
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -1615,8 +1615,8 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryTest do
]

assert json_response(conn, 200)["query"]["date_range"] == [
"2021-01-01T00:00:00+00:00",
"2021-01-15T23:59:59+00:00"
"2021-01-01T00:00:00Z",
"2021-01-15T23:59:59Z"
]
end

Expand Down
2 changes: 1 addition & 1 deletion test/support/factory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ defmodule Plausible.Factory do
site = %Plausible.Site{
native_stats_start_at: ~N[2000-01-01 00:00:00],
domain: domain,
timezone: "UTC"
timezone: "Etc/UTC"
}

merge_attributes(site, attrs)
Expand Down
Loading