Export main graph as csv (#24)

* Export main graph as csv

* Remove unused deps from mix-lock

* Update bamboo dependency
This commit is contained in:
Uku Taht 2020-01-13 15:16:35 +02:00 committed by GitHub
parent 0dfd5b448d
commit 9f30e9eb1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 69 additions and 23 deletions

View File

@ -9,12 +9,16 @@ function serialize(obj) {
return str.join("&");
}
export function get(url, query, ...extraQuery) {
export function serializeQuery(query, ...extraQuery) {
query = Object.assign({}, query, {
date: query.date ? formatISO(query.date) : undefined,
filters: query.filters ? JSON.stringify(query.filters) : undefined
}, ...extraQuery)
url = url + `?${serialize(query)}`
return '?' + serialize(query)
}
export function get(url, query, ...extraQuery) {
url = url + serializeQuery(query, extraQuery)
return fetch(url).then(res => res.json())
}

View File

@ -288,15 +288,28 @@ class LineGraph extends React.Component {
})
}
downloadLink() {
const endpoint = `/${this.props.site.domain}/visitors.csv${api.serializeQuery(this.props.query)}`
return (
<a href={endpoint} download>
<svg className="w-4 h-5 absolute text-grey-darker" style={{right: '2rem', top: '-2rem'}}>
<use xlinkHref="#feather-download" />
</svg>
</a>
)
}
render() {
const extraClass = this.props.graphData.interval === 'hour' ? '' : 'cursor-pointer'
return (
<React.Fragment>
<div className="border-b border-grey-light flex flex-wrap">
<div className="flex flex-wrap">
{ this.renderTopStats() }
</div>
<div className="p-4">
<div className="px-2 relative">
{ this.downloadLink() }
<canvas id="main-graph-canvas" className={'mt-4 ' + extraClass} width="1054" height="342"></canvas>
</div>
</React.Fragment>

View File

@ -40,7 +40,6 @@ defmodule PlausibleWeb do
use Phoenix.HTML
import PlausibleWeb.ErrorHelpers
import PhoenixActiveLink
alias PlausibleWeb.Router.Helpers, as: Routes
end
end

View File

@ -1,6 +1,7 @@
defmodule PlausibleWeb.StatsController do
use PlausibleWeb, :controller
use Plausible.Repo
alias Plausible.Stats
def stats(conn, %{"website" => website}) do
site = Repo.get_by(Plausible.Site, domain: website)
@ -36,6 +37,30 @@ defmodule PlausibleWeb.StatsController do
end
end
def csv_export(conn, %{"website" => website}) do
site = Repo.get_by(Plausible.Site, domain: website)
if site && current_user_can_access?(conn, site) do
query = Stats.Query.from(site.timezone, conn.params)
{plot, _, labels, _} = Stats.calculate_plot(site, query)
csv_content = Enum.zip(labels, plot)
|> Enum.map(fn {k, v} -> [k, v] end)
|> (fn data -> [["Date", "Visitors"] | data] end).()
|> CSV.encode
|> Enum.into([])
|> Enum.join()
filename = "Visitors #{website} #{Timex.format!(query.date_range.first, "{ISOdate} ")} to #{Timex.format!(query.date_range.last, "{ISOdate} ")}.csv"
conn
|> put_resp_content_type("text/csv")
|> put_resp_header("content-disposition", "attachment; filename=\"#{filename}\"")
|> send_resp(200, csv_content)
else
render_error(conn, 404)
end
end
defp current_user_can_access?(_conn, %Plausible.Site{public: true}) do
true
end

View File

@ -114,6 +114,7 @@ defmodule PlausibleWeb.Router do
put "/:website/settings/google", SiteController, :update_google_auth
delete "/:website", SiteController, :delete_site
get "/:website/visitors.csv", StatsController, :csv_export
get "/:website/*path", StatsController, :stats
end

View File

@ -22,5 +22,6 @@
<symbol id="feather-maximize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></symbol>
<symbol id="feather-download" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></symbol>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -41,7 +41,6 @@ defmodule Plausible.MixProject do
{:gettext, "~> 0.11"},
{:jason, "~> 1.0"},
{:phoenix, "~> 1.4.0"},
{:phoenix_active_link, "~> 0.2.1"},
{:phoenix_ecto, "~> 4.0"},
{:phoenix_html, "~> 2.11"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
@ -51,15 +50,15 @@ defmodule Plausible.MixProject do
{:ref_inspector, "~> 1.3"},
{:timex, "~> 3.6"},
{:ua_inspector, "~> 0.18"},
{:bamboo, "~> 1.2"},
{:bamboo, "~> 1.3"},
{:bamboo_postmark, "~> 0.5"},
{:poison, ">= 1.5.0"}, # For bamboo_postmark
{:sentry, "~> 7.0"},
{:httpoison, "~> 1.4"},
{:ex_machina, "~> 2.3", only: :test},
{:excoveralls, "~> 0.10", only: :test},
{:joken, "~> 2.0"},
{:php_serializer, "~> 0.9.0"}
{:php_serializer, "~> 0.9.0"},
{:csv, "~> 2.3"}
]
end

View File

@ -1,6 +1,5 @@
%{
"appsignal": {:hex, :appsignal, "1.10.6", "3b84ab3a3f7390a4295d883e0e5a3615d57161c2f8eec1957ca6fef193263010", [:make, :mix], [{:decorator, "~> 1.2.3", [hex: :decorator, repo: "hexpm", optional: false]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.2.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, ">= 1.1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, ">= 1.3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"bamboo": {:hex, :bamboo, "1.2.0", "8aebd24f7c606c32d0163c398004a11608ca1028182a169b2e527793bfab7561", [:mix], [{:hackney, ">= 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"bamboo": {:hex, :bamboo, "1.3.0", "9ab7c054f1c3435464efcba939396c29c5e1b28f73c34e1f169e0881297a3141", [:mix], [{:hackney, ">= 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"bamboo_postmark": {:hex, :bamboo_postmark, "0.5.0", "a0f238fd19cd178bc503dd8c40b46819b9cc57472c274a5e5bb3d9c0d7444cff", [:mix], [{:bamboo, ">= 1.2.0", [hex: :bamboo, repo: "hexpm", optional: false]}, {:hackney, ">= 1.6.5", [hex: :hackney, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"bcrypt_elixir": {:hex, :bcrypt_elixir, "2.0.1", "1061e2114aaac554c12e5c1e4608bf4aadaca839f30d1b85224272facd5e6427", [:make, :mix], [{:comeonin, "~> 5.1", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
@ -12,14 +11,13 @@
"cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"cowboy": {:hex, :cowboy, "2.6.1", "f2e06f757c337b3b311f9437e6e072b678fcd71545a7b2865bdaa154d078593f", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"},
"csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"},
"db_connection": {:hex, :db_connection, "2.0.6", "bde2f85d047969c5b5800cb8f4b3ed6316c8cb11487afedac4aa5f93fd39abfa", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.7.0", "30d6b52c88541f9a66637359ddf85016df9eb266170d53105f02e4a67e00c5aa", [:mix], [], "hexpm"},
"decorator": {:hex, :decorator, "1.2.4", "31dfff6143d37f0b68d0bffb3b9f18ace14fea54d4f1b5e4f86ead6f00d9ff6e", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.0.8", "9eb6a1fcfc593e6619d45ef51afe607f1554c21ca188a1cd48eecc27223567f1", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.0.5", "7e44172b4f7aca4469f38d7f6a3da394dbf43a1bcf0ca975e958cb957becd74e", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.6", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.5.2", "96a28c79f5b8d34879cd95ebc04d2a0d678cfbbd3e74c43cb63a76adf0ee8054", [:mix], [], "hexpm"},
"elixir_uuid": {:hex, :elixir_uuid, "1.2.0", "ff26e938f95830b1db152cb6e594d711c10c02c6391236900ddd070a6b01271d", [:mix], [], "hexpm"},
"ex_crypto": {:hex, :ex_crypto, "0.10.0", "af600a89b784b36613a989da6e998c1b200ff1214c3cfbaf8deca4aa2f0a1739", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.12.0", "50e17a1b116fdb7facc2fe127a94db246169f38d7627b391376a0bc418413ce1", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
@ -30,14 +28,12 @@
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"joken": {:hex, :joken, "2.0.1", "ec9ab31bf660f343380da033b3316855197c8d4c6ef597fa3fcb451b326beb14", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm"},
"jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
"jsone": {:git, "https://github.com/sile/jsone.git", "b0b037df7c1a8ee99c9f1bd124cd72e550a87936", [tag: "1.4.5"]},
"liburi": {:git, "https://github.com/silviucpp/liburi.git", "1f4033fbff1ec3efb55fbf296087e7ed42a64916", [ref: "1f4033fbff1ec3efb55fbf296087e7ed42a64916"]},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.4.0", "56fe9a809e0e735f3e3b9b31c1b749d4b436e466d8da627b8d82f90eaae714d2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"},
"phoenix_active_link": {:hex, :phoenix_active_link, "0.2.1", "2f51a08c24872350fb6da33e49c489f2dd37ffd22e912254f6e2d777b25df228", [:mix], [{:phoenix_html, "~> 2.10", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_html": {:hex, :phoenix_html, "2.13.1", "fa8f034b5328e2dfa0e4131b5569379003f34bc1fafdaa84985b0b9d2f12e68b", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.0", "3bb31a9fbd40ffe8652e60c8660dffd72dd231efcdf49b744fb75b9ef7db5dd2", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
@ -50,18 +46,13 @@
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.14.1", "63247d4a5ad6b9de57a0bac5d807e1c32d41e39c04b8a4156a26c63bcd8a2e49", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
"rebar_vsn_plugin": {:git, "https://github.com/erlware/rebar_vsn_plugin.git", "fd40c960c7912193631d948fe962e1162a8d1334", [branch: "master"]},
"ref_inspector": {:hex, :ref_inspector, "1.3.0", "a02b89647440d084f2867ecece7a99895bcd4683482397fe086508bb22a165f3", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm"},
"referrerparser": {:git, "https://github.com/silviucpp/refererparser.git", "3e0efdd5da6588972552bffb4bd6f1ccf7faadfd", [branch: "master"]},
"sentry": {:hex, :sentry, "7.0.3", "093fa4b6937760afb9a5fcb0e4a9092a305b6c0ff26a710e977614b201feab75", [:mix], [{:hackney, "~> 1.8 or 1.6.5", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm"},
"telemetry": {:hex, :telemetry, "0.3.0", "099a7f3ce31e4780f971b4630a3c22ec66d22208bc090fe33a2a3a6a67754a73", [:rebar3], [], "hexpm"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"tzdata": {:hex, :tzdata, "1.0.2", "6c4242c93332b8590a7979eaf5e11e77d971e579805c44931207e32aa6ad3db1", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"ua_inspector": {:hex, :ua_inspector, "0.19.1", "cb5d894b16ca60bd88bae09a90ba344f6f7346c22238312b2f92d7a10b82c52c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.0", [hex: :poolboy, repo: "hexpm", optional: false]}, {:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm"},
"ua_parser": {:hex, :ua_parser, "1.5.0", "a6964fd35b6d79ab3860ca83709274cb20fc533c4638d276fc356f7e8f0a5d68", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm"},
"ua_parser2": {:git, "https://github.com/nazipov/ua_parser2-elixir.git", "aabd8dce449726e1e4fe825f148ed5c0c8b806ed", []},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
"yamerl": {:hex, :yamerl, "0.7.0", "e51dba652dce74c20a88294130b48051ebbbb0be7d76f22de064f0f3ccf0aaf5", [:rebar3], [], "hexpm"},
"yaml_elixir": {:hex, :yaml_elixir, "1.0.0", "a0b703148aa8926a08fc14619c83e9cdf7555ff7e8bb9e74c08aa716eaf8c609", [:mix], [], "hexpm"},
}

View File

@ -3,7 +3,7 @@ defmodule PlausibleWeb.StatsControllerTest do
use Plausible.Repo
import Plausible.TestUtils
describe "as an anonymous visitor" do
describe "GET /:website - anonymous user" do
test "public site - shows site stats", %{conn: conn} do
insert(:site, domain: "public-site.io", public: true)
insert(:pageview, hostname: "public-site.io")
@ -20,7 +20,7 @@ defmodule PlausibleWeb.StatsControllerTest do
end
end
describe "as a logged in user" do
describe "GET /:website - as a logged in user" do
setup [:create_user, :log_in, :create_site]
test "can view stats of a website I've created", %{conn: conn, site: site} do
@ -37,4 +37,17 @@ defmodule PlausibleWeb.StatsControllerTest do
assert html_response(conn, 404) =~ "There&#39;s nothing here"
end
end
describe "GET /:website/visitors.csv" do
setup [:create_user, :log_in, :create_site]
test "exports graph as csv", %{conn: conn, site: site} do
insert(:pageview, hostname: site.domain)
today = Timex.today() |> Timex.format!("{ISOdate}")
conn = get(conn, "/" <> site.domain <> "/visitors.csv")
assert response(conn, 200) =~ "Date,Visitors"
assert response(conn, 200) =~ "#{today},1"
end
end
end