From f7e2d724dd5bbf500e0d2ec5f8c51e394e14f118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Tue, 23 Apr 2024 23:58:02 +0200 Subject: [PATCH] Replace ahoy events with real data We were tracking some events with Ahoy, but in an inconsistent way. For example, we were tracking when a debate was created, but (probably accidentally) we were only tracking proposals when they were created from the management section. For budget investments and their supports, we weren't using Ahoy events but checking their database tables instead. And we were only using ahoy events for the charts; for the other stats, we were using the real data. While we could actually fix these issues and start tracking events correctly, existing production data would remain broken because we didn't track a certain event when it happened. And, besides, why should we bother, for instance, to track when a debate is created, when we can instead access that information in the debates table? There are probably some features related to tracking an event and their visits, but we weren't using them, and we were storing more user data than we needed to. So we're removing the track events, allowing us to simplify the code and make it more consistent. We aren't removing the `ahoy_events` table in case existing Consul Democracy installations use it, but we'll remove it after releasing version 2.2.0 and adding a warning in the release notes. This change fixes the proposal created chart, since we were only tracking proposals created in the management section, and opens the possibility to add more charts in the future using data we didn't track with Ahoy. Also note the "Level 2 user Graph" test wasn't testing the graph, so we're changing it in order to test it. We're also moving it next to the other graphs test and, since we were tracking the event when we were confirming the phone, we're renaming to "Level 3 users". Finally, note that, since we were tracking events when something was created, we're including the `with_hidden` scope. This is also consistent with the other stats shown in the admin section as well as the public stats. --- .../budget_supporting_component.html.erb | 2 +- .../stats/budget_supporting_component.rb | 4 + .../admin/stats/chart_component.html.erb | 4 +- app/components/admin/stats/chart_component.rb | 26 +++---- app/controllers/admin/api/stats_controller.rb | 27 +------ app/controllers/admin/stats_controller.rb | 9 +-- .../concerns/commentable_actions.rb | 4 - app/controllers/debates_controller.rb | 1 - .../legislation/annotations_controller.rb | 7 -- .../legislation/answers_controller.rb | 8 -- .../management/proposals_controller.rb | 1 - .../verification/sms_controller.rb | 1 - app/helpers/stats_helper.rb | 6 -- app/models/ahoy/chart.rb | 47 +++++++++++- app/models/visit.rb | 1 + app/views/admin/stats/graph.html.erb | 2 +- app/views/admin/stats/show.html.erb | 11 +-- config/locales/en/admin.yml | 4 +- config/locales/es/admin.yml | 4 +- .../admin/api/stats_controller_spec.rb | 48 ++---------- spec/controllers/debates_controller_spec.rb | 28 ------- .../annotations_controller_spec.rb | 21 ----- .../legislation/answers_controller_spec.rb | 14 ---- spec/factories/analytics.rb | 6 -- spec/models/ahoy/chart_spec.rb | 76 +++++++++++++++++++ spec/models/ahoy/data_source_spec.rb | 21 ++--- spec/system/admin/stats_spec.rb | 37 ++++----- 27 files changed, 178 insertions(+), 242 deletions(-) create mode 100644 spec/models/ahoy/chart_spec.rb diff --git a/app/components/admin/stats/budget_supporting_component.html.erb b/app/components/admin/stats/budget_supporting_component.html.erb index c946d73bf..957908e9c 100644 --- a/app/components/admin/stats/budget_supporting_component.html.erb +++ b/app/components/admin/stats/budget_supporting_component.html.erb @@ -30,7 +30,7 @@ -<%= render Admin::Stats::ChartComponent.new(name: "user_supported_budgets", event: "", count: user_count) %> +<%= render Admin::Stats::ChartComponent.new(chart) %> diff --git a/app/components/admin/stats/budget_supporting_component.rb b/app/components/admin/stats/budget_supporting_component.rb index 249deed5c..9626b033f 100644 --- a/app/components/admin/stats/budget_supporting_component.rb +++ b/app/components/admin/stats/budget_supporting_component.rb @@ -28,4 +28,8 @@ class Admin::Stats::BudgetSupportingComponent < ApplicationComponent [heading, headings_stats[heading.id][:total_participants_support_phase]] end end + + def chart + @chart ||= Ahoy::Chart.new("user_supported_budgets") + end end diff --git a/app/components/admin/stats/chart_component.html.erb b/app/components/admin/stats/chart_component.html.erb index f31b0e21a..99f2ec4bf 100644 --- a/app/components/admin/stats/chart_component.html.erb +++ b/app/components/admin/stats/chart_component.html.erb @@ -1,4 +1,4 @@
-

<%= t "admin.stats.graph.#{name || event}" %> (<%= count %>)

- <%= chart_tag id: name, event: event %> +

<%= t "admin.stats.graph.#{event}" %> (<%= count %>)

+ <%= chart_tag %>
diff --git a/app/components/admin/stats/chart_component.rb b/app/components/admin/stats/chart_component.rb index 2528e1e49..94c729910 100644 --- a/app/components/admin/stats/chart_component.rb +++ b/app/components/admin/stats/chart_component.rb @@ -1,25 +1,21 @@ class Admin::Stats::ChartComponent < ApplicationComponent - attr_reader :name, :event, :count + attr_reader :chart - def initialize(name:, event:, count:) - @name = name - @event = event - @count = count + def initialize(chart) + @chart = chart end private - def chart_tag(opt = {}) - opt[:data] ||= {} - opt[:data][:graph] = admin_api_stats_path(chart_data(opt)) - tag.div(**opt) + def count + chart.count end - def chart_data(opt = {}) - if opt[:id].present? - { opt[:id] => true } - elsif opt[:event].present? - { event: opt[:event] } - end + def event + chart.event_name + end + + def chart_tag + tag.div("data-graph": admin_api_stats_path(event: event)) end end diff --git a/app/controllers/admin/api/stats_controller.rb b/app/controllers/admin/api/stats_controller.rb index b025e3195..577d11fff 100644 --- a/app/controllers/admin/api/stats_controller.rb +++ b/app/controllers/admin/api/stats_controller.rb @@ -1,30 +1,9 @@ class Admin::Api::StatsController < Admin::Api::BaseController def show - if params[:event].blank? && - params[:visits].blank? && - params[:budget_investments].blank? && - params[:user_supported_budgets].blank? - return render json: {}, status: :bad_request - end - - ds = Ahoy::DataSource.new - if params[:event].present? - ds.add params[:event].titleize, Ahoy::Chart.new(params[:event]).group_by_day(:time).count + render json: Ahoy::Chart.new(params[:event]).data_points + else + render json: {}, status: :bad_request end - - if params[:visits].present? - ds.add "Visits", Visit.group_by_day(:started_at).count - end - - if params[:budget_investments].present? - ds.add "Budget Investments", Budget::Investment.group_by_day(:created_at).count - end - - if params[:user_supported_budgets].present? - ds.add "User supported budgets", - Vote.where(votable_type: "Budget::Investment").group_by_day(:updated_at).count - end - render json: ds.build end end diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb index fbfc06618..4cd913f27 100644 --- a/app/controllers/admin/stats_controller.rb +++ b/app/controllers/admin/stats_controller.rb @@ -30,14 +30,7 @@ class Admin::StatsController < Admin::BaseController end def graph - @name = params[:id] - @event = params[:event] - - if params[:event] - @count = Ahoy::Chart.new(params[:event]).count - else - @count = params[:count] - end + @chart = Ahoy::Chart.new(params[:event]) end def proposal_notifications diff --git a/app/controllers/concerns/commentable_actions.rb b/app/controllers/concerns/commentable_actions.rb index 8a47f509e..f02a7bcf2 100644 --- a/app/controllers/concerns/commentable_actions.rb +++ b/app/controllers/concerns/commentable_actions.rb @@ -59,10 +59,6 @@ module CommentableActions private - def track_event - ahoy.track :"#{resource_name}_created", "#{resource_name}_id": resource.id - end - def tag_cloud TagCloud.new(resource_model, params[:search]) end diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb index e2b1a1efb..0bf0f3e04 100644 --- a/app/controllers/debates_controller.rb +++ b/app/controllers/debates_controller.rb @@ -24,7 +24,6 @@ class DebatesController < ApplicationController @debate.author = current_user if @debate.save - track_event redirect_to debate_path(@debate), notice: t("flash.actions.create.debate") else render :new diff --git a/app/controllers/legislation/annotations_controller.rb b/app/controllers/legislation/annotations_controller.rb index ba1b55f89..ce83d684b 100644 --- a/app/controllers/legislation/annotations_controller.rb +++ b/app/controllers/legislation/annotations_controller.rb @@ -51,7 +51,6 @@ class Legislation::AnnotationsController < Legislation::BaseController @annotation = @draft_version.annotations.new(annotation_params) @annotation.author = current_user if @annotation.save - track_event render json: @annotation.to_json else render json: @annotation.errors.full_messages, status: :unprocessable_entity @@ -100,12 +99,6 @@ class Legislation::AnnotationsController < Legislation::BaseController [:quote, :text, ranges: [:start, :startOffset, :end, :endOffset]] end - def track_event - ahoy.track :legislation_annotation_created, - legislation_annotation_id: @annotation.id, - legislation_draft_version_id: @draft_version.id - end - def convert_ranges_parameters annotation = params[:legislation_annotation] if annotation && annotation[:ranges] && annotation[:ranges].is_a?(String) diff --git a/app/controllers/legislation/answers_controller.rb b/app/controllers/legislation/answers_controller.rb index 3c718617f..bbe55c3a8 100644 --- a/app/controllers/legislation/answers_controller.rb +++ b/app/controllers/legislation/answers_controller.rb @@ -12,7 +12,6 @@ class Legislation::AnswersController < Legislation::BaseController if @process.debate_phase.open? @answer.user = current_user @answer.save! - track_event respond_to do |format| format.js format.html { redirect_to legislation_process_question_path(@process, @question) } @@ -35,11 +34,4 @@ class Legislation::AnswersController < Legislation::BaseController def allowed_params [:legislation_question_option_id] end - - def track_event - ahoy.track :legislation_answer_created, - legislation_answer_id: @answer.id, - legislation_question_option_id: @answer.legislation_question_option_id, - legislation_question_id: @answer.legislation_question_id - end end diff --git a/app/controllers/management/proposals_controller.rb b/app/controllers/management/proposals_controller.rb index 83bfadb5c..d319d24a5 100644 --- a/app/controllers/management/proposals_controller.rb +++ b/app/controllers/management/proposals_controller.rb @@ -17,7 +17,6 @@ class Management::ProposalsController < Management::BaseController published_at: Time.current)) if @resource.save - track_event redirect_path = url_for(controller: controller_name, action: :show, id: @resource.id) redirect_to redirect_path, notice: t("flash.actions.create.#{resource_name.underscore}") else diff --git a/app/controllers/verification/sms_controller.rb b/app/controllers/verification/sms_controller.rb index 2dc628f6b..57d51ed09 100644 --- a/app/controllers/verification/sms_controller.rb +++ b/app/controllers/verification/sms_controller.rb @@ -28,7 +28,6 @@ class Verification::SmsController < ApplicationController @sms = Verification::Sms.new(sms_params.merge(user: current_user)) if @sms.verified? current_user.update!(confirmed_phone: current_user.unconfirmed_phone) - ahoy.track(:level_2_user, user_id: current_user.id) rescue nil if VerifiedUser.phone?(current_user) current_user.update(verified_at: Time.current) diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb index 30facd211..89046e525 100644 --- a/app/helpers/stats_helper.rb +++ b/app/helpers/stats_helper.rb @@ -1,10 +1,4 @@ module StatsHelper - def budget_investments_chart_tag(opt = {}) - opt[:data] ||= {} - opt[:data][:graph] = admin_api_stats_path(budget_investments: true) - tag.div(**opt) - end - def number_to_stats_percentage(number, options = {}) number_to_percentage(number, { strip_insignificant_zeros: true, precision: 2 }.merge(options)) end diff --git a/app/models/ahoy/chart.rb b/app/models/ahoy/chart.rb index fa71186e7..d4ff7c739 100644 --- a/app/models/ahoy/chart.rb +++ b/app/models/ahoy/chart.rb @@ -1,20 +1,59 @@ module Ahoy class Chart attr_reader :event_name - delegate :count, :group_by_day, to: :events + delegate :count, to: :records def initialize(event_name) @event_name = event_name end def self.active_event_names - Ahoy::Event.distinct.order(:name).pluck(:name) + event_names_with_collections.select { |name, collection| collection.any? }.keys + end + + def self.event_names_with_collections + { + budget_investment_created: Budget::Investment.with_hidden, + debate_created: Debate.with_hidden, + legislation_annotation_created: Legislation::Annotation.with_hidden, + legislation_answer_created: Legislation::Answer.with_hidden, + level_3_user: User.with_hidden.level_three_verified, + proposal_created: Proposal.with_hidden + } + end + + def data_points + ds = Ahoy::DataSource.new + ds.add event_name.to_s.titleize, records_by_day.count + + ds.build end private - def events - Ahoy::Event.where(name: event_name) + def records + case event_name.to_sym + when :user_supported_budgets + Vote.where(votable_type: "Budget::Investment") + when :visits + Visit.all + else + self.class.event_names_with_collections[event_name.to_sym] + end + end + + def records_by_day + raise "Unknown event #{event_name}" unless records.respond_to?(:group_by_day) + + records.group_by_day(date_field) + end + + def date_field + if event_name.to_sym == :level_3_user + :verified_at + else + :created_at + end end end end diff --git a/app/models/visit.rb b/app/models/visit.rb index 9bcf891d7..f34d979a1 100644 --- a/app/models/visit.rb +++ b/app/models/visit.rb @@ -1,4 +1,5 @@ class Visit < ApplicationRecord + alias_attribute :created_at, :started_at has_many :ahoy_events, class_name: "Ahoy::Event" belongs_to :user end diff --git a/app/views/admin/stats/graph.html.erb b/app/views/admin/stats/graph.html.erb index 85c8395de..de76aee54 100644 --- a/app/views/admin/stats/graph.html.erb +++ b/app/views/admin/stats/graph.html.erb @@ -4,4 +4,4 @@ <%= back_link_to admin_stats_path %> -<%= render Admin::Stats::ChartComponent.new(name: @name, event: @event, count: @count) %> +<%= render Admin::Stats::ChartComponent.new(@chart) %> diff --git a/app/views/admin/stats/show.html.erb b/app/views/admin/stats/show.html.erb index 0e8594da9..7c06341ef 100644 --- a/app/views/admin/stats/show.html.erb +++ b/app/views/admin/stats/show.html.erb @@ -1,7 +1,3 @@ -<% content_for :head do %> - <%= javascript_include_tag "stat_graphs", "data-turbolinks-track" => "reload" %> -<% end %> -
@@ -28,7 +24,7 @@

@@ -115,11 +111,6 @@

<%= render Admin::Stats::EventLinksComponent.new(@event_names) %> - - <% if feature?(:budgets) %> -

<%= t "admin.stats.show.budgets_title" %>

- <%= budget_investments_chart_tag id: "budget_investments" %> - <% end %>
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 727be148e..333bd6bcd 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1480,7 +1480,6 @@ en: verified_users_who_didnt_vote_proposals: Verified users who didn't votes proposals visits: Visits votes: Total votes - budgets_title: Participatory budgeting participatory_budgets: Participatory Budgets direct_messages: Direct messages proposal_notifications: Proposal notifications @@ -1488,9 +1487,10 @@ en: polls: Polls sdg: SDG graph: + budget_investment_created: Budget investments created debate_created: Debates visit: Visits - level_2_user: Level 2 users + level_3_user: Level 3 users proposal_created: Citizen proposals title: Graphs budgets: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index c562e63a3..bac399ade 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1480,7 +1480,6 @@ es: verified_users_who_didnt_vote_proposals: Usuarios verificados que no han votado propuestas visits: Visitas votes: Votos - budgets_title: Presupuestos participativos participatory_budgets: Presupuestos Participativos direct_messages: Mensajes directos proposal_notifications: Notificaciones de propuestas @@ -1488,9 +1487,10 @@ es: polls: Votaciones sdg: ODS graph: + budget_investment_created: Proyectos de gasto creados debate_created: Debates visit: Visitas - level_2_user: Usuarios nivel 2 + level_3_user: Usuarios nivel 3 proposal_created: Propuestas Ciudadanas title: Gráficos budgets: diff --git a/spec/controllers/admin/api/stats_controller_spec.rb b/spec/controllers/admin/api/stats_controller_spec.rb index ee9fd7605..b30008bed 100644 --- a/spec/controllers/admin/api/stats_controller_spec.rb +++ b/spec/controllers/admin/api/stats_controller_spec.rb @@ -17,51 +17,19 @@ describe Admin::Api::StatsController, :admin do time_2 = Time.zone.local(2015, 01, 02) time_3 = Time.zone.local(2015, 01, 03) - create(:ahoy_event, name: "foo", time: time_1) - create(:ahoy_event, name: "foo", time: time_1) - create(:ahoy_event, name: "foo", time: time_2) - create(:ahoy_event, name: "bar", time: time_1) - create(:ahoy_event, name: "bar", time: time_3) - create(:ahoy_event, name: "bar", time: time_3) + create(:proposal, created_at: time_1) + create(:proposal, created_at: time_1) + create(:proposal, created_at: time_2) + create(:debate, created_at: time_1) + create(:debate, created_at: time_3) + create(:debate, created_at: time_3) end it "returns single events formated for working with c3.js" do - get :show, params: { event: "foo" } + get :show, params: { event: "proposal_created" } expect(response).to be_ok - expect(response.parsed_body).to eq "x" => ["2015-01-01", "2015-01-02"], "Foo" => [2, 1] - end - end - - context "visits present" do - it "returns visits formated for working with c3.js" do - time_1 = Time.zone.local(2015, 01, 01) - time_2 = Time.zone.local(2015, 01, 02) - - create(:visit, started_at: time_1) - create(:visit, started_at: time_1) - create(:visit, started_at: time_2) - - get :show, params: { visits: true } - - expect(response).to be_ok - expect(response.parsed_body).to eq "x" => ["2015-01-01", "2015-01-02"], "Visits" => [2, 1] - end - end - - context "budget investments present" do - it "returns budget investments formated for working with c3.js" do - time_1 = Time.zone.local(2017, 04, 01) - time_2 = Time.zone.local(2017, 04, 02) - - create(:budget_investment, created_at: time_1) - create(:budget_investment, created_at: time_2) - create(:budget_investment, created_at: time_2) - - get :show, params: { budget_investments: true } - - expect(response).to be_ok - expect(response.parsed_body).to eq "x" => ["2017-04-01", "2017-04-02"], "Budget Investments" => [1, 2] + expect(response.parsed_body).to eq "x" => ["2015-01-01", "2015-01-02"], "Proposal Created" => [2, 1] end end end diff --git a/spec/controllers/debates_controller_spec.rb b/spec/controllers/debates_controller_spec.rb index c3d96dcea..a9ed78059 100644 --- a/spec/controllers/debates_controller_spec.rb +++ b/spec/controllers/debates_controller_spec.rb @@ -9,34 +9,6 @@ describe DebatesController do end end - describe "POST create" do - before do - InvisibleCaptcha.timestamp_enabled = false - end - - after do - InvisibleCaptcha.timestamp_enabled = true - end - - it "creates an ahoy event" do - debate_attributes = { - terms_of_service: "1", - translations_attributes: { - "0" => { - title: "A sample debate", - description: "this is a sample debate", - locale: "en" - } - } - } - sign_in create(:user) - - post :create, params: { debate: debate_attributes } - expect(Ahoy::Event.where(name: :debate_created).count).to eq 1 - expect(Ahoy::Event.last.properties["debate_id"]).to eq Debate.last.id - end - end - describe "PUT mark_featured" do it "ignores query parameters" do debate = create(:debate) diff --git a/spec/controllers/legislation/annotations_controller_spec.rb b/spec/controllers/legislation/annotations_controller_spec.rb index 575e9626d..cbefc4721 100644 --- a/spec/controllers/legislation/annotations_controller_spec.rb +++ b/spec/controllers/legislation/annotations_controller_spec.rb @@ -36,27 +36,6 @@ describe Legislation::AnnotationsController do end let(:user) { create(:user, :level_two) } - it "creates an ahoy event" do - sign_in user - - post :create, params: { - process_id: legal_process.id, - draft_version_id: draft_version.id, - legislation_annotation: { - "quote" => "ipsum", - "ranges" => [{ - "start" => "/p[1]", - "startOffset" => 6, - "end" => "/p[1]", - "endOffset" => 11 - }], - "text" => "una anotacion" - } - } - expect(Ahoy::Event.where(name: :legislation_annotation_created).count).to eq 1 - expect(Ahoy::Event.last.properties["legislation_annotation_id"]).to eq Legislation::Annotation.last.id - end - it "does not create an annotation if the draft version is a final version" do sign_in user diff --git a/spec/controllers/legislation/answers_controller_spec.rb b/spec/controllers/legislation/answers_controller_spec.rb index 04bc21dce..11dc1bc2a 100644 --- a/spec/controllers/legislation/answers_controller_spec.rb +++ b/spec/controllers/legislation/answers_controller_spec.rb @@ -10,20 +10,6 @@ describe Legislation::AnswersController do let(:question_option) { create(:legislation_question_option, question: question, value: "Yes") } let(:user) { create(:user, :level_two) } - it "creates an ahoy event" do - sign_in user - - post :create, params: { - process_id: legal_process.id, - question_id: question.id, - legislation_answer: { - legislation_question_option_id: question_option.id - } - } - expect(Ahoy::Event.where(name: :legislation_answer_created).count).to eq 1 - expect(Ahoy::Event.last.properties["legislation_answer_id"]).to eq Legislation::Answer.last.id - end - it "creates an answer if the process debate phase is open" do sign_in user diff --git a/spec/factories/analytics.rb b/spec/factories/analytics.rb index 0d564336e..8afd58ffa 100644 --- a/spec/factories/analytics.rb +++ b/spec/factories/analytics.rb @@ -1,10 +1,4 @@ FactoryBot.define do - factory :ahoy_event, class: "Ahoy::Event" do - id { SecureRandom.uuid } - time { DateTime.current } - sequence(:name) { |n| "Event #{n} type" } - end - factory :visit do id { SecureRandom.uuid } started_at { DateTime.current } diff --git a/spec/models/ahoy/chart_spec.rb b/spec/models/ahoy/chart_spec.rb new file mode 100644 index 000000000..086e340b1 --- /dev/null +++ b/spec/models/ahoy/chart_spec.rb @@ -0,0 +1,76 @@ +require "rails_helper" + +describe Ahoy::Chart do + describe "#data_points" do + it "raises an exception for unknown events" do + chart = Ahoy::Chart.new(:mystery) + + expect { chart.data_points }.to raise_exception "Unknown event mystery" + end + + it "returns data associated with the event" do + time_1 = Time.zone.local(2015, 01, 01) + time_2 = Time.zone.local(2015, 01, 02) + time_3 = Time.zone.local(2015, 01, 03) + + create(:proposal, created_at: time_1) + create(:proposal, created_at: time_1) + create(:proposal, created_at: time_2) + create(:debate, created_at: time_1) + create(:debate, created_at: time_3) + + chart = Ahoy::Chart.new(:proposal_created) + + expect(chart.data_points).to eq x: ["2015-01-01", "2015-01-02"], "Proposal Created" => [2, 1] + end + + it "accepts strings as the event name" do + create(:proposal, created_at: Time.zone.local(2015, 01, 01)) + create(:debate, created_at: Time.zone.local(2015, 01, 02)) + + chart = Ahoy::Chart.new("proposal_created") + + expect(chart.data_points).to eq x: ["2015-01-01"], "Proposal Created" => [1] + end + + it "returns visits data for the visits event" do + time_1 = Time.zone.local(2015, 01, 01) + time_2 = Time.zone.local(2015, 01, 02) + + create(:visit, started_at: time_1) + create(:visit, started_at: time_1) + create(:visit, started_at: time_2) + + chart = Ahoy::Chart.new(:visits) + + expect(chart.data_points).to eq x: ["2015-01-01", "2015-01-02"], "Visits" => [2, 1] + end + + it "returns user supports for the user_supported_budgets event" do + time_1 = Time.zone.local(2017, 04, 01) + time_2 = Time.zone.local(2017, 04, 02) + + create(:vote, votable: create(:budget_investment), created_at: time_1) + create(:vote, votable: create(:budget_investment), created_at: time_2) + create(:vote, votable: create(:budget_investment), created_at: time_2) + create(:vote, votable: create(:proposal), created_at: time_2) + + chart = Ahoy::Chart.new(:user_supported_budgets) + + expect(chart.data_points).to eq x: ["2017-04-01", "2017-04-02"], "User Supported Budgets" => [1, 2] + end + + it "returns level three verified dates for the level_3_user event" do + time_1 = Time.zone.local(2001, 01, 01) + time_2 = Time.zone.local(2001, 01, 02) + + create(:user, :level_two, level_two_verified_at: time_1) + create(:user, :level_three, verified_at: time_2) + create(:user, :level_three, verified_at: time_2, level_two_verified_at: time_1) + + chart = Ahoy::Chart.new(:level_3_user) + + expect(chart.data_points).to eq x: ["2001-01-02"], "Level 3 User" => [2] + end + end +end diff --git a/spec/models/ahoy/data_source_spec.rb b/spec/models/ahoy/data_source_spec.rb index df8d2756d..2766d1391 100644 --- a/spec/models/ahoy/data_source_spec.rb +++ b/spec/models/ahoy/data_source_spec.rb @@ -2,18 +2,9 @@ require "rails_helper" describe Ahoy::DataSource do describe "#build" do - before do - time_1 = Time.zone.local(2015, 01, 01) - time_2 = Time.zone.local(2015, 01, 02) - time_3 = Time.zone.local(2015, 01, 03) - - create(:ahoy_event, name: "foo", time: time_1) - create(:ahoy_event, name: "foo", time: time_1) - create(:ahoy_event, name: "foo", time: time_2) - create(:ahoy_event, name: "bar", time: time_1) - create(:ahoy_event, name: "bar", time: time_3) - create(:ahoy_event, name: "bar", time: time_3) - end + let(:january_first) { Time.zone.local(2015, 01, 01) } + let(:january_second) { Time.zone.local(2015, 01, 02) } + let(:january_third) { Time.zone.local(2015, 01, 03) } it "works without data sources" do ds = Ahoy::DataSource.new @@ -22,14 +13,14 @@ describe Ahoy::DataSource do it "works with single data sources" do ds = Ahoy::DataSource.new - ds.add "foo", Ahoy::Event.where(name: "foo").group_by_day(:time).count + ds.add "foo", { january_first => 2, january_second => 1 } expect(ds.build).to eq :x => ["2015-01-01", "2015-01-02"], "foo" => [2, 1] end it "combines data sources" do ds = Ahoy::DataSource.new - ds.add "foo", Ahoy::Event.where(name: "foo").group_by_day(:time).count - ds.add "bar", Ahoy::Event.where(name: "bar").group_by_day(:time).count + ds.add "foo", { january_first => 2, january_second => 1 } + ds.add "bar", { january_first => 1, january_third => 2 } expect(ds.build).to eq :x => ["2015-01-01", "2015-01-02", "2015-01-03"], "foo" => [2, 1, 0], "bar" => [1, 0, 2] diff --git a/spec/system/admin/stats_spec.rb b/spec/system/admin/stats_spec.rb index 86a7a8afa..085f71c15 100644 --- a/spec/system/admin/stats_spec.rb +++ b/spec/system/admin/stats_spec.rb @@ -72,18 +72,6 @@ describe "Stats", :admin do expect(page).to have_content "UNVERIFIED USERS\n1" expect(page).to have_content "TOTAL USERS\n1" end - - scenario "Level 2 user Graph" do - create(:geozone) - visit account_path - click_link "Verify my account" - verify_residence - confirm_phone - - visit admin_stats_path - - expect(page).to have_content "LEVEL TWO USERS\n1" - end end describe "Budget investments" do @@ -150,15 +138,9 @@ describe "Stats", :admin do end end - context "graphs" do - scenario "event graphs", :with_frozen_time do - visit new_debate_path - fill_in_new_debate_title with: "A title for a debate" - fill_in_ckeditor "Initial debate text", with: "This is very important because..." - check "debate_terms_of_service" - click_button "Start a debate" - - expect(page).to have_content "Debate created successfully." + describe "graphs", :with_frozen_time do + scenario "event graphs" do + create(:debate) visit admin_stats_path @@ -172,6 +154,19 @@ describe "Stats", :admin do expect(page).to have_content Date.current.strftime("%Y-%m-%d") end end + + scenario "Level 3 user Graph" do + create(:user, :level_three) + + visit admin_stats_path + click_link "level_3_user" + + expect(page).to have_content "Level 3 User (1)" + + within("#graph") do + expect(page).to have_content Date.current.strftime("%Y-%m-%d") + end + end end context "Proposal notifications" do