diff --git a/app/clients/plausible_client.rb b/app/clients/plausible_client.rb index edc2232..f3579da 100644 --- a/app/clients/plausible_client.rb +++ b/app/clients/plausible_client.rb @@ -3,15 +3,33 @@ class PlausibleClient include HTTParty - base_uri "https://analytics.nindika.com/api/v1" - headers "Authorization" => "Bearer #{Rails.application.credentials.plausible_api_key}" - default_params site_id: "nindika.com" + attr_reader :api_url, :default_headers, :default_params + + def initialize + @api_url = Rails.application.credentials.plausible_api_url + @default_headers = { "Authorization" => "Bearer #{Rails.application.credentials.plausible_api_key}" } + @default_params = { site_id: Rails.application.credentials.plausible_api_site_id } + end def stats_grouped_by_page(period:, page:, limit:) - date = "#{period.first.to_date.iso8601},#{period.last.to_date.iso8601}" - query = { property: "event:page", period: "custom", date: date, page: page, limit: limit } - response = self.class.get("/stats/breakdown", query: query) + query = build_query_params(period: period, page: page, limit: limit) + response = self.class.get("#{api_url}/stats/breakdown", query: query, headers: default_headers) response.parsed_response["results"] end + + private + + def build_query_params(period:, page:, limit:) + date = "#{period.first.to_date.iso8601},#{period.last.to_date.iso8601}" + default_params.merge( + { + property: "event:page", + period: "custom", + date: date, + page: page, + limit: limit + } + ) + end end diff --git a/app/operations/items/update_visits.rb b/app/operations/items/update_visits.rb index b883971..fde65dc 100644 --- a/app/operations/items/update_visits.rb +++ b/app/operations/items/update_visits.rb @@ -3,6 +3,8 @@ module Items class UpdateVisits < Actor def call + fail! unless Settings.enable_analytics_import? + Item.update_all(all_time_visits: 0, last_week_visits: 0) update_all_time_visits update_last_week_visits diff --git a/bin/setup_dev_credentials b/bin/setup_dev_credentials index c6bb352..c6045d6 100755 --- a/bin/setup_dev_credentials +++ b/bin/setup_dev_credentials @@ -23,6 +23,8 @@ CONTENT="secret_key_base: $(rake secret) # TO ENABLE PLAUSIBLE DATA IMPORT (Privacy-friendly analytics). (OPTIONAL) # plausible_api_key: +# plausible_api_url: +# plausible_api_site_id: # TO ENABLE SIGN IN WITH TWITTER. (OPTIONAL) # twitter_app_id: diff --git a/config/credentials/production.yml.enc b/config/credentials/production.yml.enc index 0e2dbc2..995a89d 100644 --- a/config/credentials/production.yml.enc +++ b/config/credentials/production.yml.enc @@ -1 +1 @@ -1y0LzLKm7RmLmRp7S4zhih7BW0ZsER7glMmwdQkFkusV0/4YeJNsfbag0GKqa9HaYorXSRvY6+zL4manzfL/EwBppfBlPLsYmKh6XMTp5LlDL7nncwdKWzQjuT/FEJiIvbTJ/EzfZlVe1CEKCrTXSlZyvlXuFnvpIS//9pt7Tuw/GXFzu0jo7Q+TYQ9C2rzOBb/UGPU7c3Cx2uRgh+fAY40ycX7/onsyTyvP3KIuGeYx4xIZkSknWrXN4VPREObZkGBVoLZOZGWf2RH4TJtNuQKkQ97TbTc9z5cdwtOiEFAZZZ7/dPUQEIL1GgdF01ryf+I88cG7m2oJlZ75X8AW9g/J8z+rd1F0J1VtoLpSDOQbiqEna/x3ZofrygfV1CK+6bD15nn6jKN2poEXd3X+xS3dnFCCuMLK8+0szftGugLS+bEPO8LXXnA8IMRQIrDDoWoJu2fclt8q0xVtPx/9UHJVI3AUW4ZvpIKs1e6IkJGQ27LPYyEZXWEMtkKETTE0cyfZ5IjXMAJ0mMBcWMiTthFHTPsh8x7OcT1LqCokFdLtIsdPfbUsd6mDmm2yll2X4/aJL7K477Atw5isT4uZ8nJmNoBsVzdL2rymlAkXGq+jRVa3b4MQJRIb+spjBx7tO+3GA8uJyFux69TSzbVFiLjS/oEViqnd5c7r4NZmxOfDq/IXNvG0Jotj42u978JLgThlgGbfDfYng/kQaJEjL3YV+fyRDVkvZskiu0CxSnqsX9vZ6YESEHHmN2peS0h411NOUurZcq2gXP0TKXwSchcwjjXVXCpHOp+VbtR4Fcf2zCTkAIYoUs77oVaHxanCDsgnogpwHWHa92wMzETmt+o/PGnA//ZSWlv239XA+Xn1Olg9Mg1wKkF7DtlWQ16M7dpEGdnAsgDHo1qXE2767en/YRJqyO29NHAUwVd6fSlTur1L79FWi8wEFntSlEC2nt0MMFRZz/V3E9CzKfTsSjPdCqWzSiPsoqZUqLPVOLjw0UmKqGAJaHlql0fHNkAJ5/QFCuJJS7IBRqIvlIWgNjsoIdkCUHh40coc2mNhoOhOBscZx7Wici8txIgKGmItnE9pCuRtQxI5MZk4Sgzy+FzrVQwzPlBq/SbHPJgQVa+5mfFxvrZgjSjpC/h8qN8wgnd/bODg7Dc1/BeQhv0crIGKP8NwEs4OuTFn3IBQFfsTNpJz/UZX--d1Il7LYHL+zB/j3B--+qBmL/UAoIy4FwwEr/eCyQ== \ No newline at end of file +GinjxKsnOLr7l7nxVGvw5DfbOcEAWDRvthQCSLmYGBukr1FsPGZoNfO3+SNV8lj7sdVl0YG8Y5EdJuQbavFe7njHvPIfLmGF9BjKcf6vA4aH/lSq7NCOo6R+/PwrEJKe4U3oJ2dNnqoDd5HZ7SnclyJWPyI5KDRhj/WB97JCiPvCaYm/FHURRio2ewJvkyMzocLQL5Ntl+TtJ0y7Rn8d1iF5VnEdr75fdLK/ASFIEGsjC/Rl6P013v8QSFHxoDw/Tzem5OuLQK/dew8ZLDaz2S/UGmlxf0beBNeqNPXe5bbazHKdzDpTkaUUTYiK8VnbXDYPMQGvooipdUj5WHdqAo3lsgfZ0NDJ2f0PD9oIxgy1sqL01pexbKBm5l7DgflRBH9yzq126FqRZEs8O6t9t25+wTApteEU3gbXRVmAFd2Z626Yl+rPj/Fev8eV3BACxifCRuafIaWaFK1TX6/EA4DTg7UuS0TtFMhcZN05eV2vRweepKv6ZyOoYSXZhsmjKBKBucLT8/dYknYLi548uj8RK7T+Ny5Ryc7QqgUckoEr+k+d1Y5VCc3eklSMSF1cBzUHpZ1P2Qtby+wChTJt3YPxig35jOWMF3qneUx2/LPW4/kKedQxKMfi+eDNh02cM/geo1kuZya/GfNO7wcUsDy0GALpWMcK9+1Hf/W8p5CbPJlekt3SjBt9CsVWBjDC2kE9CBIpqjdtUKlGFJS6NQxFD9fEmGiML3DDiEsARe9TYAWbwNZP1/pL2h1/xEtWgQhez/5p0dXEG9ISNV8chR+2B1iy0Fe/jCMNz7KwMg2jQN/MhlnoXFx63Xk+4Kwye0A1MxJXJmUdJsjhzkLtVI2IIrbFknsRMcSa0eM6+yXi/p+dgvVDuARL0khb9UWdFwtBQuHOiNjtt0HT86TUL279GAtRTje2aH5q3osPpspy3nKdAg1p/JafHJpQM2myjY4PE+cTTKmzw15hMqXj3ccfLHakHCRsewPd9dkKjkvdZoJCSWiuTHe3JTJ74l1AOpMZ3AXhP6L85+594BFwheCQWmrGccDbCe2OwSEpEaBo5UFDxDlKFeMXnEFdVWNLkAEZbCuNJoG1EF8uNi+rc1AlLpynl13NpCY6igXSLAyRmN+zonmGJAj4CYfAN4zEpcc+mBP1F2/v+KlSgyrdNF9Rb7ZHnspYHUD18QovgGSAY5PZ0UDH68ESYdWnxjey2DK9XVFs8KsGyCFsH2o8r8kq+7YrBQr8mia4XdU0jr4szSatrtVz78alpjLVjK0NYfFP2IH3zw02B+s7DVczHF9m+HvGGYgutHXgkPX6kzDO7g==--o4KyHe568SDEmdKB--7Iebh7/SDhrEsQXlt3QqpQ== \ No newline at end of file diff --git a/config/initializers/01_settings.rb b/config/initializers/01_settings.rb index 8b7c5eb..cd168ee 100644 --- a/config/initializers/01_settings.rb +++ b/config/initializers/01_settings.rb @@ -17,7 +17,9 @@ def self.enable_telegram_notifications? end def self.enable_analytics_import? - @@enable_analytics_import ||= Rails.application.credentials.plausible_api_key.present? + @@enable_analytics_import ||= Rails.application.credentials.plausible_api_key.present? && + Rails.application.credentials.plausible_api_url.present? && + Rails.application.credentials.plausible_api_site_id.present? end def self.enable_twitter_sign_in? diff --git a/spec/clients/plausible_client_spec.rb b/spec/clients/plausible_client_spec.rb index 5461ea4..da309a4 100644 --- a/spec/clients/plausible_client_spec.rb +++ b/spec/clients/plausible_client_spec.rb @@ -3,41 +3,35 @@ require "rails_helper" RSpec.describe PlausibleClient, type: :clients do - describe "Configurations" do - it "has default base_uri" do - expect(described_class.base_uri).to eq "https://analytics.nindika.com/api/v1" - end - - it "has default params" do - expect(described_class.default_params).to eq(site_id: "nindika.com") - end - - it "has default headers" do - expect(described_class.headers).to eq( - "Authorization" => "Bearer #{Rails.application.credentials.plausible_api_key}" - ) - end - end - describe "#stats_grouped_by_page" do - subject(:client) { described_class.new } - - let(:period) { Date.parse("2020-01-01")..Date.parse("2020-04-25") } - let(:page) { 4 } - let(:limit) { 200 } - let(:results) { [Faker::Types.rb_hash(number: 4).stringify_keys, Faker::Types.rb_hash(number: 4).stringify_keys] } - - before do - query = described_class.default_params.merge( - property: "event:page", period: "custom", date: "2020-01-01,2020-04-25", page: page, limit: limit - ) - stub_request(:get, "#{described_class.base_uri}/stats/breakdown") - .with(query: query) - .to_return(body: { "results" => results }.to_json, headers: { "Content-Type" => "application/json" }) - end - it "requests /stats/breakdown grouping by page and filtering by period" do - expect(client.stats_grouped_by_page(period: period, page: page, limit: limit)).to eq results + api_url = "https://some_plausible.api" + api_key = "some_api_key" + api_site_id = "some_site_id" + + allow(Rails.application.credentials).to receive(:plausible_api_url).and_return(api_url) + allow(Rails.application.credentials).to receive(:plausible_api_key).and_return(api_key) + allow(Rails.application.credentials).to receive(:plausible_api_site_id).and_return(api_site_id) + + client = described_class.new + period = Date.parse("2020-01-01")..Date.parse("2020-04-25") + page = 4 + limit = 200 + fake_result = [Faker::Types.rb_hash(number: 4).stringify_keys, Faker::Types.rb_hash(number: 4).stringify_keys] + query = { + property: "event:page", + period: "custom", + date: "2020-01-01,2020-04-25", + page: page, + limit: limit, + site_id: api_site_id + } + + stub_request(:get, "#{api_url}/stats/breakdown") + .with(query: query, headers: { "Authorization" => "Bearer #{api_key}" }) + .to_return(body: { "results" => fake_result }.to_json, headers: { "Content-Type" => "application/json" }) + + expect(client.stats_grouped_by_page(period: period, page: page, limit: limit)).to eq fake_result end end end diff --git a/spec/initializers/settings_spec.rb b/spec/initializers/settings_spec.rb index e57f14d..09bb263 100644 --- a/spec/initializers/settings_spec.rb +++ b/spec/initializers/settings_spec.rb @@ -73,15 +73,41 @@ it "returns false" do described_class.class_variable_set(:@@enable_analytics_import, nil) allow(Rails.application.credentials).to receive(:plausible_api_key).and_return(nil) + allow(Rails.application.credentials).to receive(:plausible_api_url).and_return("value") + allow(Rails.application.credentials).to receive(:plausible_api_site_id).and_return("value") expect(described_class.enable_analytics_import?).to be false end end - context "when plausible_api_key is present" do + context "when plausible_api_url credential is blank" do + it "returns false" do + described_class.class_variable_set(:@@enable_analytics_import, nil) + allow(Rails.application.credentials).to receive(:plausible_api_key).and_return("value") + allow(Rails.application.credentials).to receive(:plausible_api_url).and_return(nil) + allow(Rails.application.credentials).to receive(:plausible_api_site_id).and_return("value") + + expect(described_class.enable_analytics_import?).to be false + end + end + + context "when plausible_api_site_id credential is blank" do + it "returns false" do + described_class.class_variable_set(:@@enable_analytics_import, nil) + allow(Rails.application.credentials).to receive(:plausible_api_key).and_return("value") + allow(Rails.application.credentials).to receive(:plausible_api_url).and_return("value") + allow(Rails.application.credentials).to receive(:plausible_api_site_id).and_return(nil) + + expect(described_class.enable_analytics_import?).to be false + end + end + + context "when plausible_api_key, plausible_api_url and plausible_api_site_id are present" do it "returns true" do described_class.class_variable_set(:@@enable_analytics_import, nil) allow(Rails.application.credentials).to receive(:plausible_api_key).and_return("value") + allow(Rails.application.credentials).to receive(:plausible_api_url).and_return("value") + allow(Rails.application.credentials).to receive(:plausible_api_site_id).and_return("value") expect(described_class.enable_analytics_import?).to be true end diff --git a/spec/operations/items/update_visits_spec.rb b/spec/operations/items/update_visits_spec.rb index e967101..132ac09 100644 --- a/spec/operations/items/update_visits_spec.rb +++ b/spec/operations/items/update_visits_spec.rb @@ -40,10 +40,29 @@ before do mega_man.update(title: "mega man") + allow(Settings).to receive(:enable_analytics_import?).and_return(true) allow(VisitsCollector).to receive(:all_time_game_pages_stats).and_return(all_time_stats) allow(VisitsCollector).to receive(:last_week_game_pages_stats).and_return(last_week_stats) end + context "when analytics import isn't enabled" do + it "fails" do + allow(Settings).to receive(:enable_analytics_import?).and_return(false) + + result = described_class.result + + expect(result).to be_failure + end + + it "doesn't import analytics data" do + allow(Settings).to receive(:enable_analytics_import?).and_return(false) + + expect(VisitsCollector).not_to receive(:all_time_game_pages_stats) + + described_class.result + end + end + context "when game doesn`t have stats" do it "updates all visit counters to zero" do described_class.call