Stop counting today in `7d` and `30d` periods + add `28d` and `90d` (#5240)
* change 7d and 30d periods in API v2 * change 7d and 30d periods in legacy API * add 28d and 90d into the dashboard * add tests * add 28d and 90d to public API v2 * changelog * npm run generate-types * typo * fix NPM test * fix interval_test * add P shortcut for last month * hide last 30d from datepicker but keep keybind functional * fix keybind hints * Timex to Date + helpful comment * prettier format * adjust comment * mention 30d -> 28d in changelog as well * make period hidden param new default
This commit is contained in:
parent
02370c5335
commit
1b4aefb7d2
|
|
@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
|
|||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Two new shorthand time periods `28d` and `90d` available on both dashboard and in public API
|
||||
- Average scroll depth metric
|
||||
- Scroll Depth goals
|
||||
- Dashboard shows comparisons for all reports
|
||||
|
|
@ -25,6 +26,8 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### Changed
|
||||
|
||||
- The "Last 30 days" period is now "Last 28 days" on the dashboard and also the new default. Keyboard shortcut `T` still works for last 30 days.
|
||||
- Last `7d` and `30d` periods do not include today anymore
|
||||
- Filters appear in the search bar as ?f=is,page,/docs,/blog&f=... instead of ?filters=((is,page,(/docs,/blog)),...) for Plausible links sent on various platforms to work reliably.
|
||||
- Details modal search inputs are now case-insensitive.
|
||||
- Improved report performance in cases where site has a lot of unique pathnames
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { QueryPeriodsPicker } from './query-periods-picker'
|
|||
const domain = 'picking-query-dates.test'
|
||||
const periodStorageKey = `period__${domain}`
|
||||
|
||||
test('if no period is stored, loads with default value of "Last 30 days", all expected options are present', async () => {
|
||||
test('if no period is stored, loads with default value of "Last 28 days", all expected options are present', async () => {
|
||||
expect(localStorage.getItem(periodStorageKey)).toBe(null)
|
||||
render(<QueryPeriodsPicker />, {
|
||||
wrapper: (props) => (
|
||||
|
|
@ -18,7 +18,7 @@ test('if no period is stored, loads with default value of "Last 30 days", all ex
|
|||
)
|
||||
})
|
||||
|
||||
await userEvent.click(screen.getByText('Last 30 days'))
|
||||
await userEvent.click(screen.getByText('Last 28 days'))
|
||||
|
||||
expect(screen.getByTestId('datemenu')).toBeVisible()
|
||||
expect(screen.getAllByRole('link').map((el) => el.textContent)).toEqual(
|
||||
|
|
@ -27,9 +27,10 @@ test('if no period is stored, loads with default value of "Last 30 days", all ex
|
|||
['Yesterday', 'E'],
|
||||
['Realtime', 'R'],
|
||||
['Last 7 Days', 'W'],
|
||||
['Last 30 Days', 'T'],
|
||||
['Last 28 Days', 'F'],
|
||||
['Last 90 Days', 'N'],
|
||||
['Month to Date', 'M'],
|
||||
['Last Month', ''],
|
||||
['Last Month', 'P'],
|
||||
['Year to Date', 'Y'],
|
||||
['Last 12 Months', 'L'],
|
||||
['All time', 'A'],
|
||||
|
|
@ -46,7 +47,7 @@ test('user can select a new period and its value is stored', async () => {
|
|||
)
|
||||
})
|
||||
|
||||
await userEvent.click(screen.getByText('Last 30 days'))
|
||||
await userEvent.click(screen.getByText('Last 28 days'))
|
||||
expect(screen.getByTestId('datemenu')).toBeVisible()
|
||||
await userEvent.click(screen.getByText('All time'))
|
||||
expect(screen.queryByTestId('datemenu')).toBeNull()
|
||||
|
|
@ -162,7 +163,7 @@ test('going back resets the stored query period to previous value', async () =>
|
|||
}
|
||||
)
|
||||
|
||||
await userEvent.click(screen.getByText('Last 30 days'))
|
||||
await userEvent.click(screen.getByText('Last 28 days'))
|
||||
await userEvent.click(screen.getByText('Year to Date'))
|
||||
expect(localStorage.getItem(periodStorageKey)).toBe('year')
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import {
|
|||
} from '../../navigation/use-app-navigate'
|
||||
import {
|
||||
getCompareLinkItem,
|
||||
last6MonthsLinkItem,
|
||||
getDatePeriodGroups,
|
||||
LinkItem,
|
||||
QueryPeriod,
|
||||
|
|
@ -54,7 +53,7 @@ function QueryPeriodMenuKeybinds({
|
|||
}
|
||||
return (
|
||||
<>
|
||||
{groups.concat([[last6MonthsLinkItem]]).flatMap((group) =>
|
||||
{groups.flatMap((group) =>
|
||||
group
|
||||
.filter(([[_name, keyboardKey]]) => !!keyboardKey)
|
||||
.map(([[_name, keyboardKey], { search, onEvent }]) => (
|
||||
|
|
@ -163,7 +162,12 @@ const QueryPeriodMenuInner = ({
|
|||
{groups.map((group, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{group.map(
|
||||
([[label, keyboardKey], { search, isActive, onEvent }]) => (
|
||||
([
|
||||
[label, keyboardKey],
|
||||
{ search, isActive, onEvent, hidden }
|
||||
]) => {
|
||||
if (!hidden) {
|
||||
return (
|
||||
<AppNavigationLink
|
||||
key={label}
|
||||
data-selected={isActive({ site, query })}
|
||||
|
|
@ -172,9 +176,13 @@ const QueryPeriodMenuInner = ({
|
|||
onClick={onEvent && ((e) => onEvent(e))}
|
||||
>
|
||||
{label}
|
||||
{!!keyboardKey && <KeybindHint>{keyboardKey}</KeybindHint>}
|
||||
{!!keyboardKey && (
|
||||
<KeybindHint>{keyboardKey}</KeybindHint>
|
||||
)}
|
||||
</AppNavigationLink>
|
||||
)
|
||||
}
|
||||
}
|
||||
)}
|
||||
{index < groups.length - 1 && <MenuSeparator />}
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ export enum QueryPeriod {
|
|||
'day' = 'day',
|
||||
'month' = 'month',
|
||||
'7d' = '7d',
|
||||
'28d' = '28d',
|
||||
'30d' = '30d',
|
||||
'90d' = '90d',
|
||||
'6mo' = '6mo',
|
||||
'12mo' = '12mo',
|
||||
'year' = 'year',
|
||||
|
|
@ -248,6 +250,7 @@ export type LinkItem = [
|
|||
query: DashboardQuery
|
||||
}) => boolean
|
||||
onEvent?: (event: Pick<Event, 'preventDefault' | 'stopPropagation'>) => void
|
||||
hidden?: boolean
|
||||
}
|
||||
]
|
||||
|
||||
|
|
@ -329,9 +332,23 @@ export const getDatePeriodGroups = ({
|
|||
onEvent
|
||||
}
|
||||
],
|
||||
[
|
||||
['Last 28 Days', 'F'],
|
||||
{
|
||||
search: (s) => ({
|
||||
...s,
|
||||
...clearedDateSearch,
|
||||
period: QueryPeriod['28d'],
|
||||
keybindHint: 'F'
|
||||
}),
|
||||
isActive: ({ query }) => query.period === QueryPeriod['28d'],
|
||||
onEvent
|
||||
}
|
||||
],
|
||||
[
|
||||
['Last 30 Days', 'T'],
|
||||
{
|
||||
hidden: true,
|
||||
search: (s) => ({
|
||||
...s,
|
||||
...clearedDateSearch,
|
||||
|
|
@ -341,6 +358,19 @@ export const getDatePeriodGroups = ({
|
|||
isActive: ({ query }) => query.period === QueryPeriod['30d'],
|
||||
onEvent
|
||||
}
|
||||
],
|
||||
[
|
||||
['Last 90 Days', 'N'],
|
||||
{
|
||||
search: (s) => ({
|
||||
...s,
|
||||
...clearedDateSearch,
|
||||
period: QueryPeriod['90d'],
|
||||
keybindHint: 'N'
|
||||
}),
|
||||
isActive: ({ query }) => query.period === QueryPeriod['90d'],
|
||||
onEvent
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
|
|
@ -360,14 +390,14 @@ export const getDatePeriodGroups = ({
|
|||
}
|
||||
],
|
||||
[
|
||||
['Last Month'],
|
||||
['Last Month', 'P'],
|
||||
{
|
||||
search: (s) => ({
|
||||
...s,
|
||||
...clearedDateSearch,
|
||||
period: QueryPeriod.month,
|
||||
date: formatISO(lastMonth(site)),
|
||||
keybindHint: null
|
||||
keybindHint: 'P'
|
||||
}),
|
||||
isActive: ({ query }) =>
|
||||
query.period === QueryPeriod.month &&
|
||||
|
|
@ -391,6 +421,19 @@ export const getDatePeriodGroups = ({
|
|||
onEvent
|
||||
}
|
||||
],
|
||||
[
|
||||
['Last 6 months', 'S'],
|
||||
{
|
||||
hidden: true,
|
||||
search: (s) => ({
|
||||
...s,
|
||||
...clearedDateSearch,
|
||||
period: QueryPeriod['6mo'],
|
||||
keybindHint: 'S'
|
||||
}),
|
||||
isActive: ({ query }) => query.period === QueryPeriod['6mo']
|
||||
}
|
||||
],
|
||||
[
|
||||
['Last 12 Months', 'L'],
|
||||
{
|
||||
|
|
@ -428,19 +471,6 @@ export const getDatePeriodGroups = ({
|
|||
.concat(extraGroups)
|
||||
}
|
||||
|
||||
export const last6MonthsLinkItem: LinkItem = [
|
||||
['Last 6 months', 'S'],
|
||||
{
|
||||
search: (s) => ({
|
||||
...s,
|
||||
...clearedDateSearch,
|
||||
period: QueryPeriod['6mo'],
|
||||
keybindHint: 'S'
|
||||
}),
|
||||
isActive: ({ query }) => query.period === QueryPeriod['6mo']
|
||||
}
|
||||
]
|
||||
|
||||
export const getCompareLinkItem = ({
|
||||
query,
|
||||
site
|
||||
|
|
@ -570,9 +600,15 @@ export function getCurrentPeriodDisplayName({
|
|||
if (query.period === '7d') {
|
||||
return 'Last 7 days'
|
||||
}
|
||||
if (query.period === '28d') {
|
||||
return 'Last 28 days'
|
||||
}
|
||||
if (query.period === '30d') {
|
||||
return 'Last 30 days'
|
||||
}
|
||||
if (query.period === '90d') {
|
||||
return 'Last 90 days'
|
||||
}
|
||||
if (query.period === 'month') {
|
||||
if (isThisMonth(site, query.date)) {
|
||||
return 'Month to Date'
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export type DashboardQuery = {
|
|||
}
|
||||
|
||||
export const queryDefaultValue: DashboardQuery = {
|
||||
period: '30d' as QueryPeriod,
|
||||
period: '28d' as QueryPeriod,
|
||||
comparison: null,
|
||||
match_day_of_week: true,
|
||||
date: null,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ describe('parseSiteFromDataset', () => {
|
|||
data-current-user-role="owner"
|
||||
data-current-user-id="1"
|
||||
data-flags="{}"
|
||||
data-valid-intervals-by-period='{"12mo":["day","week","month"],"30d":["day","week"],"6mo":["day","week","month"],"7d":["hour","day"],"all":["week","month"],"custom":["day","week","month"],"day":["minute","hour"],"month":["day","week"],"realtime":["minute"],"year":["day","week","month"]}'
|
||||
data-valid-intervals-by-period='{"12mo":["day","week","month"],"7d":["hour","day"],"28d":["day","week"],"30d":["day","week"],"90d":["day","week","month"],"6mo":["day","week","month"],"all":["week","month"],"custom":["day","week","month"],"day":["minute","hour"],"month":["day","week"],"realtime":["minute"],"year":["day","week","month"]}'
|
||||
{...attrs}
|
||||
/>
|
||||
)
|
||||
|
|
@ -55,9 +55,11 @@ describe('parseSiteFromDataset', () => {
|
|||
flags: {},
|
||||
validIntervalsByPeriod: {
|
||||
'12mo': ['day', 'week', 'month'],
|
||||
'30d': ['day', 'week'],
|
||||
'6mo': ['day', 'week', 'month'],
|
||||
'7d': ['hour', 'day'],
|
||||
'28d': ['day', 'week'],
|
||||
'30d': ['day', 'week'],
|
||||
'90d': ['day', 'week', 'month'],
|
||||
'6mo': ['day', 'week', 'month'],
|
||||
all: ['week', 'month'],
|
||||
custom: ['day', 'week', 'month'],
|
||||
day: ['minute', 'hour'],
|
||||
|
|
|
|||
|
|
@ -20,7 +20,19 @@ export type Metric =
|
|||
| "total_revenue"
|
||||
| "average_revenue"
|
||||
| "scroll_depth";
|
||||
export type DateRangeShorthand = "30m" | "realtime" | "all" | "day" | "7d" | "30d" | "month" | "6mo" | "12mo" | "year";
|
||||
export type DateRangeShorthand =
|
||||
| "30m"
|
||||
| "realtime"
|
||||
| "all"
|
||||
| "day"
|
||||
| "7d"
|
||||
| "28d"
|
||||
| "30d"
|
||||
| "90d"
|
||||
| "month"
|
||||
| "6mo"
|
||||
| "12mo"
|
||||
| "year";
|
||||
/**
|
||||
* @minItems 2
|
||||
* @maxItems 2
|
||||
|
|
|
|||
|
|
@ -225,14 +225,12 @@ defmodule Plausible.Stats.Filters.QueryParser do
|
|||
{:ok, DateTimeRange.new!(date, date, site.timezone)}
|
||||
end
|
||||
|
||||
defp parse_time_range(site, "7d", date, _now) do
|
||||
first = date |> Date.add(-6)
|
||||
{:ok, DateTimeRange.new!(first, date, site.timezone)}
|
||||
end
|
||||
|
||||
defp parse_time_range(site, "30d", date, _now) do
|
||||
first = date |> Date.add(-30)
|
||||
{:ok, DateTimeRange.new!(first, date, site.timezone)}
|
||||
defp parse_time_range(site, shorthand, date, _now)
|
||||
when shorthand in ["7d", "28d", "30d", "90d"] do
|
||||
{days, "d"} = Integer.parse(shorthand)
|
||||
last = date |> Date.add(-1)
|
||||
first = date |> Date.add(-days)
|
||||
{:ok, DateTimeRange.new!(first, last, site.timezone)}
|
||||
end
|
||||
|
||||
defp parse_time_range(site, "month", date, _now) do
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ defmodule Plausible.Stats.Interval do
|
|||
case period do
|
||||
period when period in ["realtime", "30m"] -> "minute"
|
||||
"day" -> "hour"
|
||||
period when period in ["custom", "7d", "30d", "month"] -> "day"
|
||||
period when period in ["custom", "7d", "28d", "30d", "90d", "month"] -> "day"
|
||||
period when period in ["6mo", "12mo", "year"] -> "month"
|
||||
end
|
||||
end
|
||||
|
|
@ -57,8 +57,10 @@ defmodule Plausible.Stats.Interval do
|
|||
"realtime" => ["minute"],
|
||||
"day" => ["minute", "hour"],
|
||||
"7d" => ["hour", "day"],
|
||||
"month" => ["day", "week"],
|
||||
"28d" => ["day", "week"],
|
||||
"30d" => ["day", "week"],
|
||||
"90d" => ["day", "week", "month"],
|
||||
"month" => ["day", "week"],
|
||||
"6mo" => ["day", "week", "month"],
|
||||
"12mo" => ["day", "week", "month"],
|
||||
"year" => ["day", "week", "month"],
|
||||
|
|
|
|||
|
|
@ -91,26 +91,18 @@ defmodule Plausible.Stats.Legacy.QueryBuilder do
|
|||
struct!(query, period: "day", utc_time_range: datetime_range)
|
||||
end
|
||||
|
||||
defp put_period(query, site, %{"period" => "7d"} = params) do
|
||||
end_date = parse_single_date(query, params)
|
||||
start_date = end_date |> Date.shift(day: -6)
|
||||
defp put_period(query, site, %{"period" => period} = params)
|
||||
when period in ["7d", "28d", "30d", "90d"] do
|
||||
{days, "d"} = Integer.parse(period)
|
||||
|
||||
end_date = parse_single_date(query, params) |> Date.shift(day: -1)
|
||||
start_date = end_date |> Date.shift(day: 1 - days)
|
||||
|
||||
datetime_range =
|
||||
DateTimeRange.new!(start_date, end_date, site.timezone)
|
||||
|> DateTimeRange.to_timezone("Etc/UTC")
|
||||
|
||||
struct!(query, period: "7d", utc_time_range: datetime_range)
|
||||
end
|
||||
|
||||
defp put_period(query, site, %{"period" => "30d"} = params) do
|
||||
end_date = parse_single_date(query, params)
|
||||
start_date = end_date |> Date.shift(day: -30)
|
||||
|
||||
datetime_range =
|
||||
DateTimeRange.new!(start_date, end_date, site.timezone)
|
||||
|> DateTimeRange.to_timezone("Etc/UTC")
|
||||
|
||||
struct!(query, period: "30d", utc_time_range: datetime_range)
|
||||
struct!(query, period: period, utc_time_range: datetime_range)
|
||||
end
|
||||
|
||||
defp put_period(query, site, %{"period" => "month"} = params) do
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ defmodule Plausible.Workers.SendEmailReport do
|
|||
last_month =
|
||||
DateTime.now!(site.timezone)
|
||||
|> DateTime.shift(month: -1)
|
||||
|> Timex.beginning_of_month()
|
||||
|> DateTime.to_date()
|
||||
|> Date.beginning_of_month()
|
||||
|> Date.to_iso8601()
|
||||
|
||||
query = Query.from(site, %{"period" => "month", "date" => last_month})
|
||||
|
|
@ -73,9 +74,18 @@ defmodule Plausible.Workers.SendEmailReport do
|
|||
end
|
||||
|
||||
defp put_last_week_query(%{site: site} = assigns) do
|
||||
today = DateTime.now!(site.timezone) |> DateTime.to_date()
|
||||
date = Date.shift(today, week: -1) |> Timex.end_of_week() |> Date.to_iso8601()
|
||||
query = Query.from(site, %{"period" => "7d", "date" => date})
|
||||
# In production, evaluating and sending the date param to `Query.from`
|
||||
# is redundant since the default value is today for `site.timezone` and
|
||||
# weekly reports are always sent on Monday morning. However, this makes
|
||||
# it easier to test - no need for a `now` argument.
|
||||
date_param =
|
||||
site.timezone
|
||||
|> DateTime.now!()
|
||||
|> DateTime.to_date()
|
||||
|> Date.beginning_of_week()
|
||||
|> Date.to_iso8601()
|
||||
|
||||
query = Query.from(site, %{"period" => "7d", "date" => date_param})
|
||||
|
||||
Map.put(assigns, :query, query)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -197,10 +197,18 @@
|
|||
"const": "7d",
|
||||
"description": "Last 7 days relative to today"
|
||||
},
|
||||
{
|
||||
"const": "28d",
|
||||
"description": "Last 28 days relative to today"
|
||||
},
|
||||
{
|
||||
"const": "30d",
|
||||
"description": "Last 30 days relative to today"
|
||||
},
|
||||
{
|
||||
"const": "90d",
|
||||
"description": "Last 90 days relative to today"
|
||||
},
|
||||
{
|
||||
"const": "month",
|
||||
"description": "Current calendar month"
|
||||
|
|
|
|||
|
|
@ -173,8 +173,8 @@ defmodule Plausible.Stats.ComparisonsTest do
|
|||
|
||||
comparison_query = Comparisons.get_comparison_query(query)
|
||||
|
||||
assert comparison_query.utc_time_range.first == ~U[2019-12-30 00:00:00Z]
|
||||
assert comparison_query.utc_time_range.last == ~U[2020-01-05 23:59:59Z]
|
||||
assert comparison_query.utc_time_range.first == ~U[2019-12-29 00:00:00Z]
|
||||
assert comparison_query.utc_time_range.last == ~U[2020-01-04 23:59:59Z]
|
||||
assert date_range_length(comparison_query) == 7
|
||||
end
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ defmodule Plausible.Stats.ComparisonsTest do
|
|||
query =
|
||||
Query.from(site, %{
|
||||
"period" => "7d",
|
||||
"date" => "2021-03-03",
|
||||
"date" => "2021-03-04",
|
||||
"comparison" => "year_over_year"
|
||||
})
|
||||
|
||||
|
|
@ -204,8 +204,8 @@ defmodule Plausible.Stats.ComparisonsTest do
|
|||
|
||||
comparison_query = Comparisons.get_comparison_query(query)
|
||||
|
||||
assert comparison_query.utc_time_range.first == ~U[2020-11-19 00:00:00Z]
|
||||
assert comparison_query.utc_time_range.last == ~U[2020-11-25 23:59:59Z]
|
||||
assert comparison_query.utc_time_range.first == ~U[2020-11-18 00:00:00Z]
|
||||
assert comparison_query.utc_time_range.last == ~U[2020-11-24 23:59:59Z]
|
||||
assert date_range_length(comparison_query) == 7
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@ defmodule Plausible.Stats.IntervalTest do
|
|||
assert valid_by_period(site: site) == %{
|
||||
"realtime" => ["minute"],
|
||||
"day" => ["minute", "hour"],
|
||||
"7d" => ["hour", "day"],
|
||||
"month" => ["day", "week"],
|
||||
"7d" => ["hour", "day"],
|
||||
"28d" => ["day", "week"],
|
||||
"30d" => ["day", "week"],
|
||||
"90d" => ["day", "week", "month"],
|
||||
"6mo" => ["day", "week", "month"],
|
||||
"12mo" => ["day", "week", "month"],
|
||||
"year" => ["day", "week", "month"],
|
||||
|
|
@ -45,9 +47,11 @@ defmodule Plausible.Stats.IntervalTest do
|
|||
assert valid_by_period(site: site) == %{
|
||||
"realtime" => ["minute"],
|
||||
"day" => ["minute", "hour"],
|
||||
"7d" => ["hour", "day"],
|
||||
"month" => ["day", "week"],
|
||||
"7d" => ["hour", "day"],
|
||||
"28d" => ["day", "week"],
|
||||
"30d" => ["day", "week"],
|
||||
"90d" => ["day", "week", "month"],
|
||||
"6mo" => ["day", "week", "month"],
|
||||
"12mo" => ["day", "week", "month"],
|
||||
"year" => ["day", "week", "month"],
|
||||
|
|
@ -63,9 +67,11 @@ defmodule Plausible.Stats.IntervalTest do
|
|||
assert valid_by_period(site: site, from: ago_13m, to: Date.utc_today()) == %{
|
||||
"realtime" => ["minute"],
|
||||
"day" => ["minute", "hour"],
|
||||
"7d" => ["hour", "day"],
|
||||
"month" => ["day", "week"],
|
||||
"7d" => ["hour", "day"],
|
||||
"28d" => ["day", "week"],
|
||||
"30d" => ["day", "week"],
|
||||
"90d" => ["day", "week", "month"],
|
||||
"6mo" => ["day", "week", "month"],
|
||||
"12mo" => ["day", "week", "month"],
|
||||
"year" => ["day", "week", "month"],
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ defmodule Plausible.Stats.Filters.QueryParserTest do
|
|||
last: DateTime.new!(~D[2021-05-05], ~T[23:59:59], "Etc/UTC")
|
||||
}
|
||||
@date_range_7d %DateTimeRange{
|
||||
first: DateTime.new!(~D[2021-04-29], ~T[00:00:00], "Etc/UTC"),
|
||||
last: DateTime.new!(~D[2021-05-05], ~T[23:59:59], "Etc/UTC")
|
||||
first: DateTime.new!(~D[2021-04-28], ~T[00:00:00], "Etc/UTC"),
|
||||
last: DateTime.new!(~D[2021-05-04], ~T[23:59:59], "Etc/UTC")
|
||||
}
|
||||
@date_range_30d %DateTimeRange{
|
||||
first: DateTime.new!(~D[2021-04-05], ~T[00:00:00], "Etc/UTC"),
|
||||
last: DateTime.new!(~D[2021-05-05], ~T[23:59:59], "Etc/UTC")
|
||||
last: DateTime.new!(~D[2021-05-04], ~T[23:59:59], "Etc/UTC")
|
||||
}
|
||||
@date_range_month %DateTimeRange{
|
||||
first: DateTime.new!(~D[2021-05-01], ~T[00:00:00], "Etc/UTC"),
|
||||
|
|
@ -988,7 +988,7 @@ defmodule Plausible.Stats.Filters.QueryParserTest do
|
|||
"metrics" => ["visitors"],
|
||||
"date_range" => "all",
|
||||
"include" => %{
|
||||
"comparisons" => %{"mode" => "custom", "date_range" => ["2021-04-05", "2021-05-05"]}
|
||||
"comparisons" => %{"mode" => "custom", "date_range" => ["2021-04-05", "2021-05-04"]}
|
||||
}
|
||||
}
|
||||
|> check_success(
|
||||
|
|
|
|||
|
|
@ -883,7 +883,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => "visit:referrer==**a.com**"
|
||||
|
|
@ -1506,7 +1506,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => "event:page==/en/**"
|
||||
|
|
@ -1523,7 +1523,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => "event:page!=/en/**"
|
||||
|
|
@ -1541,7 +1541,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => "event:page==/en/**|/pl/**"
|
||||
|
|
@ -1559,7 +1559,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => "event:page==**post\\|1|/something-else"
|
||||
|
|
@ -1579,7 +1579,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "pageviews",
|
||||
"filters" => "visit:country==EE"
|
||||
|
|
@ -1672,7 +1672,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
insert(:goal, %{site: site, event_name: "Signup"})
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "conversion_rate",
|
||||
"filters" => "event:goal==Signup"
|
||||
|
|
@ -1695,7 +1695,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
insert(:goal, %{site: site, event_name: "Signup"})
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "conversion_rate,visitors,events",
|
||||
"filters" => "event:goal==Signup;event:props:author==Uku"
|
||||
|
|
@ -1724,7 +1724,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
insert(:goal, %{site: site, event_name: "Signup"})
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "conversion_rate,visitors,events",
|
||||
"filters" => "visit:browser==Firefox;event:goal==Signup"
|
||||
|
|
@ -1754,7 +1754,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
insert(:goal, %{site: site, event_name: "Signup"})
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "conversion_rate,visitors,events",
|
||||
"filters" => "event:page==/this;event:goal==Signup"
|
||||
|
|
@ -1796,7 +1796,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
@ -1865,7 +1865,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
@ -1886,7 +1886,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
@ -1918,7 +1918,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
@ -1951,7 +1951,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
@ -1983,7 +1983,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
@ -2015,7 +2015,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/aggregate", %{
|
||||
get(conn, "/api/v1/stats/aggregate?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors",
|
||||
"filters" => [
|
||||
|
|
|
|||
|
|
@ -1666,7 +1666,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/breakdown", %{
|
||||
get(conn, "/api/v1/stats/breakdown?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => "visitors,pageviews",
|
||||
"property" => "event:goal"
|
||||
|
|
@ -2387,7 +2387,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
|||
])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/v1/stats/breakdown", %{
|
||||
get(conn, "/api/v1/stats/breakdown?period=day", %{
|
||||
"site_id" => site.domain,
|
||||
"filters" => "visit:browser != Chrome",
|
||||
"property" => "visit:browser"
|
||||
|
|
|
|||
|
|
@ -113,6 +113,128 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryComparisonsTest do
|
|||
]
|
||||
end
|
||||
|
||||
test "timeseries last 28d period compares the same period with and without match_day_of_week=true",
|
||||
%{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
today = ~D[2021-06-10]
|
||||
|
||||
make_request = fn match_day_of_week ->
|
||||
conn
|
||||
|> post("/api/v2/query-internal-test", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => ["visitors"],
|
||||
"date_range" => "28d",
|
||||
"date" => Date.to_iso8601(today),
|
||||
"dimensions" => ["time"],
|
||||
"include" => %{
|
||||
"time_labels" => true,
|
||||
"comparisons" => %{
|
||||
"mode" => "previous_period",
|
||||
"match_day_of_week" => match_day_of_week
|
||||
}
|
||||
}
|
||||
})
|
||||
|> json_response(200)
|
||||
end
|
||||
|
||||
assert %{"results" => results1} = make_request.(false)
|
||||
assert %{"results" => results2} = make_request.(true)
|
||||
|
||||
assert results1 == results2
|
||||
|
||||
expected_first_date = today |> Date.shift(day: -28) |> Date.to_iso8601()
|
||||
expected_last_date = today |> Date.shift(day: -1) |> Date.to_iso8601()
|
||||
expected_comparison_first_date = today |> Date.shift(day: -56) |> Date.to_iso8601()
|
||||
expected_comparison_last_date = today |> Date.shift(day: -29) |> Date.to_iso8601()
|
||||
|
||||
assert %{
|
||||
"dimensions" => [actual_first_date],
|
||||
"comparison" => %{
|
||||
"dimensions" => [actual_comparison_first_date]
|
||||
}
|
||||
} = List.first(results1)
|
||||
|
||||
assert %{
|
||||
"dimensions" => [actual_last_date],
|
||||
"comparison" => %{
|
||||
"dimensions" => [actual_comparison_last_date]
|
||||
}
|
||||
} = List.last(results1)
|
||||
|
||||
assert actual_first_date == expected_first_date
|
||||
assert actual_last_date == expected_last_date
|
||||
assert actual_comparison_first_date == expected_comparison_first_date
|
||||
assert actual_comparison_last_date == expected_comparison_last_date
|
||||
end
|
||||
|
||||
test "timeseries last 90d period in year_over_year comparison", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, timestamp: ~N[2021-04-01 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2021-04-01 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2021-04-05 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2021-04-05 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2021-06-29 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2022-04-01 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2022-04-05 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2022-06-29 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2022-06-30 00:00:00])
|
||||
])
|
||||
|
||||
conn =
|
||||
post(conn, "/api/v2/query-internal-test", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => ["visitors"],
|
||||
"date_range" => "90d",
|
||||
"date" => "2022-06-30",
|
||||
"dimensions" => ["time:day"],
|
||||
"include" => %{
|
||||
"time_labels" => true,
|
||||
"comparisons" => %{"mode" => "year_over_year"}
|
||||
}
|
||||
})
|
||||
|
||||
assert %{
|
||||
"results" => results,
|
||||
"meta" => %{"time_labels" => time_labels}
|
||||
} = json_response(conn, 200)
|
||||
|
||||
assert "2022-04-01" = List.first(time_labels)
|
||||
assert "2022-04-05" = Enum.at(time_labels, 4)
|
||||
assert "2022-06-29" = List.last(time_labels)
|
||||
|
||||
assert %{
|
||||
"dimensions" => ["2022-04-01"],
|
||||
"metrics" => [1],
|
||||
"comparison" => %{
|
||||
"dimensions" => ["2021-04-01"],
|
||||
"metrics" => [2]
|
||||
}
|
||||
} = Enum.find(results, &(&1["dimensions"] == ["2022-04-01"]))
|
||||
|
||||
assert %{
|
||||
"dimensions" => ["2022-04-05"],
|
||||
"metrics" => [1],
|
||||
"comparison" => %{
|
||||
"dimensions" => ["2021-04-05"],
|
||||
"metrics" => [2]
|
||||
}
|
||||
} = Enum.find(results, &(&1["dimensions"] == ["2022-04-05"]))
|
||||
|
||||
assert %{
|
||||
"dimensions" => ["2022-06-29"],
|
||||
"metrics" => [1],
|
||||
"comparison" => %{
|
||||
"dimensions" => ["2021-06-29"],
|
||||
"metrics" => [1]
|
||||
}
|
||||
} = Enum.find(results, &(&1["dimensions"] == ["2022-06-29"]))
|
||||
end
|
||||
|
||||
test "dimensional comparison with low limit", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, browser: "Firefox", timestamp: ~N[2021-01-01 00:00:00]),
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
get(conn, "/api/v1/stats/timeseries", %{
|
||||
"site_id" => site.domain,
|
||||
"period" => "7d",
|
||||
"date" => "2021-01-07"
|
||||
"date" => "2021-01-08"
|
||||
})
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
|
|
@ -1240,7 +1240,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"metrics" => "conversion_rate",
|
||||
"filters" => "event:goal==Signup",
|
||||
"period" => "7d",
|
||||
"date" => "2021-01-10"
|
||||
"date" => "2021-01-11"
|
||||
})
|
||||
|
||||
assert [first, second | _] = json_response(conn, 200)["results"]
|
||||
|
|
@ -1290,7 +1290,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"metrics" => "conversion_rate",
|
||||
"filters" => "event:goal==Signup;event:props:author==Teet",
|
||||
"period" => "7d",
|
||||
"date" => "2021-01-10"
|
||||
"date" => "2021-01-11"
|
||||
})
|
||||
|
||||
[first | _] = json_response(conn, 200)["results"]
|
||||
|
|
@ -1329,7 +1329,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"metrics" => "conversion_rate",
|
||||
"filters" => "event:goal==Signup;event:page==/yes",
|
||||
"period" => "7d",
|
||||
"date" => "2021-01-10"
|
||||
"date" => "2021-01-11"
|
||||
})
|
||||
|
||||
[first | _] = json_response(conn, 200)["results"]
|
||||
|
|
@ -1368,7 +1368,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"metrics" => "conversion_rate",
|
||||
"filters" => "event:goal==Signup;visit:device==Mobile",
|
||||
"period" => "7d",
|
||||
"date" => "2021-01-10"
|
||||
"date" => "2021-01-11"
|
||||
})
|
||||
|
||||
[first | _] = json_response(conn, 200)["results"]
|
||||
|
|
@ -1414,7 +1414,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"site_id" => site.domain,
|
||||
"period" => "7d",
|
||||
"metrics" => "pageviews,visits,views_per_visit",
|
||||
"date" => "2021-01-07"
|
||||
"date" => "2021-01-08"
|
||||
})
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
|
|
@ -1477,7 +1477,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"site_id" => site.domain,
|
||||
"period" => "7d",
|
||||
"metrics" => "events",
|
||||
"date" => "2021-01-07"
|
||||
"date" => "2021-01-08"
|
||||
})
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
|
|
@ -1545,7 +1545,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"site_id" => site.domain,
|
||||
"period" => "7d",
|
||||
"metrics" => "views_per_visit",
|
||||
"date" => "2021-01-07"
|
||||
"date" => "2021-01-08"
|
||||
})
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
|
|
@ -1579,7 +1579,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"site_id" => site.domain,
|
||||
"period" => "7d",
|
||||
"metrics" => "events",
|
||||
"date" => "2021-01-07",
|
||||
"date" => "2021-01-08",
|
||||
"with_imported" => "true"
|
||||
})
|
||||
|
||||
|
|
@ -1615,7 +1615,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
|
|||
"site_id" => site.domain,
|
||||
"period" => "7d",
|
||||
"metrics" => "events",
|
||||
"date" => "2021-01-07",
|
||||
"date" => "2021-01-08",
|
||||
"with_imported" => "true",
|
||||
"filters" => "event:props:package==large"
|
||||
})
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/browsers?period=7d&date=2021-01-13&comparison=previous_period"
|
||||
"/api/stats/#{site.domain}/browsers?period=7d&date=2021-01-14&comparison=previous_period"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
|
|
@ -267,8 +267,8 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
|
|||
]
|
||||
|
||||
assert json_response(conn, 200)["meta"] == %{
|
||||
"date_range_label" => "7 Jan - 13 Jan 2021",
|
||||
"comparison_date_range_label" => "31 Dec 2020 - 6 Jan 2021"
|
||||
"date_range_label" => "6 Jan - 12 Jan 2021",
|
||||
"comparison_date_range_label" => "30 Dec 2020 - 5 Jan 2021"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -367,7 +367,10 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
|
|||
filters = Jason.encode!([[:is, "visit:browser", ["Chrome"]]])
|
||||
|
||||
conn =
|
||||
get(conn, "/api/stats/#{site.domain}/browser-versions?filters=#{filters}&detailed=true")
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/browser-versions?filters=#{filters}&detailed=true&period=day"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -147,6 +147,46 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
assert Enum.sum(plot) == 2
|
||||
end
|
||||
|
||||
test "displays visitors for last 28d", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, timestamp: ~N[2021-01-01 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2021-01-28 00:00:00])
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=28d&date=2021-01-29&metric=visitors"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot} = json_response(conn, 200)
|
||||
|
||||
assert Enum.count(plot) == 28
|
||||
assert List.first(plot) == 1
|
||||
assert List.last(plot) == 1
|
||||
assert Enum.sum(plot) == 2
|
||||
end
|
||||
|
||||
test "displays visitors for last 90d", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, timestamp: ~N[2021-01-16 00:00:00]),
|
||||
build(:pageview, timestamp: ~N[2021-04-15 00:00:00])
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=90d&date=2021-04-16&metric=visitors"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot} = json_response(conn, 200)
|
||||
|
||||
assert Enum.count(plot) == 90
|
||||
assert List.first(plot) == 1
|
||||
assert List.last(plot) == 1
|
||||
assert Enum.sum(plot) == 2
|
||||
end
|
||||
|
||||
test "displays visitors for a month with imported data", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, timestamp: ~N[2021-01-01 00:00:00]),
|
||||
|
|
@ -373,7 +413,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
assert %{"labels" => labels} = json_response(conn, 200)
|
||||
|
||||
{:ok, first} = Timex.today() |> Timex.shift(days: -30) |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.shift(days: -1) |> Timex.format("{ISOdate}")
|
||||
assert List.first(labels) == first
|
||||
assert List.last(labels) == last
|
||||
end
|
||||
|
|
@ -382,8 +422,8 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn = get(conn, "/api/stats/#{site.domain}/main-graph?period=7d&metric=visitors")
|
||||
assert %{"labels" => labels} = json_response(conn, 200)
|
||||
|
||||
{:ok, first} = Timex.today() |> Timex.shift(days: -6) |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.format("{ISOdate}")
|
||||
{:ok, first} = Timex.today() |> Timex.shift(days: -7) |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.shift(days: -1) |> Timex.format("{ISOdate}")
|
||||
assert List.first(labels) == first
|
||||
assert List.last(labels) == last
|
||||
end
|
||||
|
|
@ -553,7 +593,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-07&metric=visitors&interval=day"
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-08&metric=visitors&interval=day"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot} = json_response(conn, 200)
|
||||
|
|
@ -626,7 +666,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2020-01-07&metric=scroll_depth&filters=#{filters}"
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2020-01-08&metric=scroll_depth&filters=#{filters}"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot} = json_response(conn, 200)
|
||||
|
|
@ -671,7 +711,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2020-01-07&metric=scroll_depth&filters=#{filters}&with_imported=true"
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2020-01-08&metric=scroll_depth&filters=#{filters}&with_imported=true"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot} = json_response(conn, 200)
|
||||
|
|
@ -1135,7 +1175,8 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "shows perfect week-split range on week scale with full week indicators", %{
|
||||
test "shows perfect week-split range on week scale with full week indicators for custom period",
|
||||
%{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
|
|
@ -1168,7 +1209,52 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "shows imperfect month-split period on month scale with full month indicators", %{
|
||||
test "shows imperfect week-split for last 28d with full week indicators", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=28d&metric=visitors&interval=week&date=2021-10-30"
|
||||
)
|
||||
|
||||
assert %{"labels" => labels, "full_intervals" => full_intervals} = json_response(conn, 200)
|
||||
|
||||
assert labels == ["2021-10-02", "2021-10-04", "2021-10-11", "2021-10-18", "2021-10-25"]
|
||||
|
||||
assert full_intervals == %{
|
||||
"2021-10-02" => false,
|
||||
"2021-10-04" => true,
|
||||
"2021-10-11" => true,
|
||||
"2021-10-18" => true,
|
||||
"2021-10-25" => false
|
||||
}
|
||||
end
|
||||
|
||||
test "shows perfect week-split for last 28d with full week indicators", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=28d&date=2021-02-08&metric=visitors&interval=week"
|
||||
)
|
||||
|
||||
assert %{"labels" => labels, "full_intervals" => full_intervals} = json_response(conn, 200)
|
||||
|
||||
assert labels == ["2021-01-11", "2021-01-18", "2021-01-25", "2021-02-01"]
|
||||
|
||||
assert full_intervals == %{
|
||||
"2021-01-11" => true,
|
||||
"2021-01-18" => true,
|
||||
"2021-01-25" => true,
|
||||
"2021-02-01" => true
|
||||
}
|
||||
end
|
||||
|
||||
test "shows imperfect month-split for custom period with full month indicators", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
|
|
@ -1190,6 +1276,49 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "shows imperfect month-split for last 90d with full month indicators", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=90d&metric=visitors&interval=month&date=2021-12-13"
|
||||
)
|
||||
|
||||
assert %{"labels" => labels, "full_intervals" => full_intervals} = json_response(conn, 200)
|
||||
|
||||
assert labels == ["2021-09-01", "2021-10-01", "2021-11-01", "2021-12-01"]
|
||||
|
||||
assert full_intervals == %{
|
||||
"2021-09-01" => false,
|
||||
"2021-10-01" => true,
|
||||
"2021-11-01" => true,
|
||||
"2021-12-01" => false
|
||||
}
|
||||
end
|
||||
|
||||
test "shows half-perfect month-split for last 90d with full month indicators", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=90d&metric=visitors&interval=month&date=2021-12-01"
|
||||
)
|
||||
|
||||
assert %{"labels" => labels, "full_intervals" => full_intervals} = json_response(conn, 200)
|
||||
|
||||
assert labels == ["2021-09-01", "2021-10-01", "2021-11-01"]
|
||||
|
||||
assert full_intervals == %{
|
||||
"2021-09-01" => false,
|
||||
"2021-10-01" => true,
|
||||
"2021-11-01" => true
|
||||
}
|
||||
end
|
||||
|
||||
test "returns stats for a day with a minute interval", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, timestamp: ~N[2023-03-01 12:00:00])
|
||||
|
|
@ -1227,12 +1356,12 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
json_response(conn, 200)
|
||||
|
||||
{:ok, first} = Timex.today() |> Timex.shift(days: -30) |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.shift(days: -1) |> Timex.format("{ISOdate}")
|
||||
|
||||
assert List.first(labels) == first
|
||||
assert List.last(labels) == last
|
||||
|
||||
{:ok, first} = Timex.today() |> Timex.shift(days: -61) |> Timex.format("{ISOdate}")
|
||||
{:ok, first} = Timex.today() |> Timex.shift(days: -60) |> Timex.format("{ISOdate}")
|
||||
{:ok, last} = Timex.today() |> Timex.shift(days: -31) |> Timex.format("{ISOdate}")
|
||||
|
||||
assert List.first(comparison_labels) == first
|
||||
|
|
@ -1375,7 +1504,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-14&comparison=previous_period&metric=conversion_rate&filters=#{filters}"
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-15&comparison=previous_period&metric=conversion_rate&filters=#{filters}"
|
||||
)
|
||||
|
||||
assert %{"plot" => this_week_plot, "comparison_plot" => last_week_plot} =
|
||||
|
|
@ -1511,7 +1640,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-14&metric=total_revenue&filters=#{filters}&comparison=previous_period"
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-15&metric=total_revenue&filters=#{filters}&comparison=previous_period"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot, "comparison_plot" => prev} = json_response(conn, 200)
|
||||
|
|
@ -1669,7 +1798,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-14&metric=average_revenue&filters=#{filters}&comparison=previous_period"
|
||||
"/api/stats/#{site.domain}/main-graph?period=7d&date=2021-01-15&metric=average_revenue&filters=#{filters}&comparison=previous_period"
|
||||
)
|
||||
|
||||
assert %{"plot" => plot, "comparison_plot" => prev} = json_response(conn, 200)
|
||||
|
|
@ -1733,5 +1862,23 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
|
|||
|
||||
refute present_index
|
||||
end
|
||||
|
||||
for period <- ["7d", "28d", "30d", "90d"] do
|
||||
test "#{period} period does not include today", %{conn: conn, site: site} do
|
||||
today = "2021-01-01"
|
||||
yesterday = "2020-12-31"
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/main-graph?period=#{unquote(period)}&date=#{today}&metric=pageviews"
|
||||
)
|
||||
|
||||
assert %{"labels" => labels, "present_index" => present_index} = json_response(conn, 200)
|
||||
|
||||
refute present_index
|
||||
assert List.last(labels) == yesterday
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ defmodule PlausibleWeb.Api.StatsController.OperatingSystemsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/operating-system-versions?filters=#{filters}&detailed=true"
|
||||
"/api/stats/#{site.domain}/operating-system-versions?filters=#{filters}&detailed=true&period=day"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
|||
build(:pageview)
|
||||
])
|
||||
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources")
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?period=day")
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
%{"name" => "Google", "visitors" => 3},
|
||||
|
|
@ -273,14 +273,14 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
|||
)
|
||||
])
|
||||
|
||||
conn1 = get(conn, "/api/stats/#{site.domain}/sources")
|
||||
conn1 = get(conn, "/api/stats/#{site.domain}/sources?period=day")
|
||||
|
||||
assert json_response(conn1, 200)["results"] == [
|
||||
%{"name" => "Google", "visitors" => 2},
|
||||
%{"name" => "DuckDuckGo", "visitors" => 1}
|
||||
]
|
||||
|
||||
conn2 = get(conn, "/api/stats/#{site.domain}/sources?with_imported=true")
|
||||
conn2 = get(conn, "/api/stats/#{site.domain}/sources?period=day&with_imported=true")
|
||||
|
||||
assert json_response(conn2, 200)["results"] == [
|
||||
%{"name" => "Google", "visitors" => 4},
|
||||
|
|
@ -466,13 +466,17 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
|||
)
|
||||
])
|
||||
|
||||
conn1 = get(conn, "/api/stats/#{site.domain}/sources?limit=1&page=2")
|
||||
conn1 = get(conn, "/api/stats/#{site.domain}/sources?period=day&limit=1&page=2")
|
||||
|
||||
assert json_response(conn1, 200)["results"] == [
|
||||
%{"name" => "DuckDuckGo", "visitors" => 1}
|
||||
]
|
||||
|
||||
conn2 = get(conn, "/api/stats/#{site.domain}/sources?limit=1&page=2&with_imported=true")
|
||||
conn2 =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/sources?period=day&limit=1&page=2&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn2, 200)["results"] == [
|
||||
%{"name" => "Google", "visitors" => 2}
|
||||
|
|
@ -496,7 +500,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
|||
])
|
||||
|
||||
filters = Jason.encode!([[:is, "event:page", ["/page1"]]])
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?filters=#{filters}")
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?period=day&filters=#{filters}")
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
%{"name" => "Google", "visitors" => 2},
|
||||
|
|
@ -521,7 +525,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
|||
])
|
||||
|
||||
filters = Jason.encode!([[:is, "event:page", ["/page1"]]])
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?filters=#{filters}")
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?period=day&filters=#{filters}")
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
%{"name" => "Google", "visitors" => 2},
|
||||
|
|
@ -537,7 +541,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
|||
])
|
||||
|
||||
order_by = Jason.encode!([["visit:source", "desc"]])
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?order_by=#{order_by}")
|
||||
conn = get(conn, "/api/stats/#{site.domain}/sources?order_by=#{order_by}&period=day")
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
%{"name" => "C", "visitors" => 1},
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/region?q=Har"
|
||||
"/api/stats/#{site.domain}/suggestions/region?period=day&q=Har"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [%{"value" => "EE-37", "label" => "Harjumaa"}]
|
||||
|
|
@ -164,7 +164,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/city?q=Kär"
|
||||
"/api/stats/#{site.domain}/suggestions/city?period=day&q=Kär"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [%{"value" => 591_632, "label" => "Kärdla"}]
|
||||
|
|
@ -291,7 +291,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn1,
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?q=alice"
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?period=day&q=alice"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
|
|
@ -301,7 +301,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn1,
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?q=host"
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?period=day&q=host"
|
||||
)
|
||||
|
||||
suggestions = json_response(conn, 200)
|
||||
|
|
@ -344,7 +344,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn1,
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?q=host"
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?period=day&q=host"
|
||||
)
|
||||
|
||||
results = json_response(conn, 200)
|
||||
|
|
@ -360,7 +360,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn1,
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?q=dave"
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?period=day&q=dave"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == []
|
||||
|
|
@ -368,7 +368,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn1,
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?q=rogue"
|
||||
"/api/stats/#{site.domain}/suggestions/hostname?period=day&q=rogue"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
|
|
@ -820,7 +820,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/country?filters=#{filters}&q=&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/country?period=day&filters=#{filters}&q=&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [%{"value" => "EE", "label" => "Estonia"}]
|
||||
|
|
@ -880,7 +880,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/region?q=#{unquote(q)}&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/region?period=day&q=#{unquote(q)}&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
|
|
@ -908,7 +908,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn1 =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/region?q=&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/region?period=day&q=&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn1, 200) == [
|
||||
|
|
@ -919,7 +919,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn2 =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/region?q=H&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/region?period=day&q=H&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn2, 200) == [
|
||||
|
|
@ -948,7 +948,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/region?filters=#{filters}&q=&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/region?period=day&filters=#{filters}&q=&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [%{"value" => "EE-39", "label" => "Hiiumaa"}]
|
||||
|
|
@ -1020,7 +1020,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/city?q=#{unquote(q)}&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/city?period=day&q=#{unquote(q)}&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
|
|
@ -1050,7 +1050,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
|
|||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/suggestions/city?filters=#{filters}&q=&with_imported=true"
|
||||
"/api/stats/#{site.domain}/suggestions/city?period=day&filters=#{filters}&q=&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [%{"value" => 591_632, "label" => "Kärdla"}]
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
|
||||
pages =
|
||||
conn
|
||||
|> get("/#{site.domain}/export?date=2020-01-01")
|
||||
|> get("/#{site.domain}/export?period=day&date=2020-01-01")
|
||||
|> response(200)
|
||||
|> unzip_and_parse_csv(~c"pages.csv")
|
||||
|
||||
|
|
@ -411,7 +411,10 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
|
||||
test "exports data in zipped csvs", %{conn: conn, site: site} do
|
||||
populate_exported_stats(site)
|
||||
conn = get(conn, "/" <> site.domain <> "/export?date=2021-10-20")
|
||||
|
||||
conn =
|
||||
get(conn, "/" <> site.domain <> "/export?period=custom&from=2021-09-20&to=2021-10-20")
|
||||
|
||||
assert_zip(conn, "30d")
|
||||
end
|
||||
|
||||
|
|
@ -459,7 +462,10 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
|
||||
visitors =
|
||||
conn
|
||||
|> get("/" <> site.domain <> "/export?date=2021-10-20&period=30d&interval=week")
|
||||
|> get(
|
||||
"/" <>
|
||||
site.domain <> "/export?period=custom&from=2021-09-20&to=2021-10-20&interval=week"
|
||||
)
|
||||
|> response(200)
|
||||
|> unzip_and_parse_csv(~c"visitors.csv")
|
||||
|
||||
|
|
@ -500,7 +506,7 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
|
||||
os_versions =
|
||||
conn
|
||||
|> get("/#{site.domain}/export")
|
||||
|> get("/#{site.domain}/export?period=day")
|
||||
|> response(200)
|
||||
|> unzip_and_parse_csv(~c"operating_system_versions.csv")
|
||||
|
||||
|
|
@ -550,7 +556,9 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
)
|
||||
])
|
||||
|
||||
conn = get(conn, "/#{site.domain}/export?with_imported=true")
|
||||
tomorrow = Date.utc_today() |> Date.add(1) |> Date.to_iso8601()
|
||||
|
||||
conn = get(conn, "/#{site.domain}/export?date=#{tomorrow}&with_imported=true")
|
||||
|
||||
assert response = response(conn, 200)
|
||||
{:ok, zip} = :zip.unzip(response, [:memory])
|
||||
|
|
@ -750,7 +758,14 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
link = insert(:shared_link, site: site)
|
||||
|
||||
populate_exported_stats(site)
|
||||
conn = get(conn, "/" <> site.domain <> "/export?auth=#{link.slug}&date=2021-10-20")
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/" <>
|
||||
site.domain <> "/export?auth=#{link.slug}&period=custom&from=2021-09-20&to=2021-10-20"
|
||||
)
|
||||
|
||||
assert_zip(conn, "30d")
|
||||
end
|
||||
end
|
||||
|
|
@ -772,7 +787,13 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
populate_exported_stats(site)
|
||||
|
||||
filters = Jason.encode!([[:is, "event:page", ["/some-other-page"]]])
|
||||
conn = get(conn, "/#{site.domain}/export?date=2021-10-20&filters=#{filters}")
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/#{site.domain}/export?period=custom&from=2021-09-20&to=2021-10-20&filters=#{filters}"
|
||||
)
|
||||
|
||||
assert_zip(conn, "30d-filter-path")
|
||||
end
|
||||
|
||||
|
|
@ -805,7 +826,7 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
|
||||
pages =
|
||||
conn
|
||||
|> get("/#{site.domain}/export?date=2020-01-07&period=7d&filters=#{filters}")
|
||||
|> get("/#{site.domain}/export?date=2020-01-08&period=7d&filters=#{filters}")
|
||||
|> response(200)
|
||||
|> unzip_and_parse_csv(~c"visitors.csv")
|
||||
|
||||
|
|
@ -973,7 +994,13 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
test "exports goal-filtered data in zipped csvs", %{conn: conn, site: site} do
|
||||
populate_exported_stats(site)
|
||||
filters = Jason.encode!([[:is, "event:goal", ["Signup"]]])
|
||||
conn = get(conn, "/#{site.domain}/export?date=2021-10-20&filters=#{filters}")
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/#{site.domain}/export?period=custom&from=2021-09-20&to=2021-10-20&filters=#{filters}"
|
||||
)
|
||||
|
||||
assert_zip(conn, "30d-filter-goal")
|
||||
end
|
||||
|
||||
|
|
@ -1051,7 +1078,7 @@ defmodule PlausibleWeb.StatsControllerTest do
|
|||
|
||||
os_versions =
|
||||
conn
|
||||
|> get("/#{site.domain}/export?filters=#{filters}")
|
||||
|> get("/#{site.domain}/export?period=day&filters=#{filters}")
|
||||
|> response(200)
|
||||
|> unzip_and_parse_csv(~c"operating_system_versions.csv")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue