Add single article functionality to articles analytics (#2339)

* Add specs for single article functionality

* Add single article functionality

* Use article_id instead of single_article_id

* Add published: true when querying for one article

* Use article_id in specs oops
This commit is contained in:
Andy Zhao 2019-04-08 19:57:13 -04:00 committed by Ben Halpern
parent f1d371c670
commit 53d3091f73
4 changed files with 56 additions and 9 deletions

View file

@ -11,9 +11,9 @@ module Api
org = Organization.find_by(id: params[:organization_id])
raise UnauthorizedError unless org && belongs_to_org?(user, org)
AnalyticsService.new(org).totals
AnalyticsService.new(org, article_id: params[:article_id]).totals
else
AnalyticsService.new(user).totals
AnalyticsService.new(user, article_id: params[:article_id]).totals
end
render json: data.to_json
end
@ -28,9 +28,9 @@ module Api
org = Organization.find_by(id: params[:organization_id])
raise UnauthorizedError unless org && belongs_to_org?(user, org)
AnalyticsService.new(org, start_date: params[:start], end_date: params[:end]).stats_grouped_by_day
AnalyticsService.new(org, start_date: params[:start], end_date: params[:end], article_id: params[:article_id]).stats_grouped_by_day
else
AnalyticsService.new(user, start_date: params[:start], end_date: params[:end]).stats_grouped_by_day
AnalyticsService.new(user, start_date: params[:start], end_date: params[:end], article_id: params[:article_id]).stats_grouped_by_day
end
render json: data.to_json
end
@ -42,9 +42,9 @@ module Api
org = Organization.find_by(id: params[:organization_id])
raise UnauthorizedError unless org && belongs_to_org?(user, org)
AnalyticsService.new(org, start_date: 1.day.ago).stats_grouped_by_day
AnalyticsService.new(org, start_date: 1.day.ago, article_id: params[:article_id]).stats_grouped_by_day
else
AnalyticsService.new(user, start_date: 1.day.ago).stats_grouped_by_day
AnalyticsService.new(user, start_date: 1.day.ago, article_id: params[:article_id]).stats_grouped_by_day
end
render json: data.to_json
end

View file

@ -1,6 +1,7 @@
class AnalyticsService
def initialize(user_or_org, start_date: "", end_date: "")
def initialize(user_or_org, start_date: "", end_date: "", article_id: nil)
@user_or_org = user_or_org
@article_id = article_id
@start_date = Time.zone.parse(start_date.to_s)&.beginning_of_day
@end_date = Time.zone.parse(end_date.to_s)&.end_of_day || Time.current.end_of_day
@ -71,8 +72,15 @@ class AnalyticsService
attr_reader :user_or_org, :start_date, :end_date, :article_data, :reaction_data, :comment_data, :follow_data, :page_view_data
def load_data
@article_data = Article.where("#{user_or_org.class.name.downcase}_id" => user_or_org.id, published: true)
article_ids = @article_data.pluck(:id)
if @article_id
@article_data = Article.where(id: @article_id, published: true, "#{user_or_org.class.name.downcase}_id" => user_or_org.id)
raise UnauthorizedError if @article_data.blank?
article_ids = @article_id
else
@article_data = Article.where("#{user_or_org.class.name.downcase}_id" => user_or_org.id, published: true)
article_ids = @article_data.pluck(:id)
end
if @start_date && @end_date
@reaction_data = Reaction.where(reactable_id: article_ids, reactable_type: "Article").

View file

@ -2,6 +2,8 @@ require "rails_helper"
RSpec.describe AnalyticsService, type: :service do
let(:user) { create(:user) }
let(:second_user) { create(:user) }
let(:article) { create(:article, user: second_user) }
let(:organization) { create(:organization) }
describe "initialization" do
@ -12,6 +14,10 @@ RSpec.describe AnalyticsService, type: :service do
it "raises an error if end date is invalid" do
expect(-> { described_class.new(user, end_date: "2000-") }).to raise_error(ArgumentError)
end
it "raises an error if an article id is invalid" do
expect(-> { described_class.new(user, article_id: article.id) }).to raise_error(UnauthorizedError)
end
end
describe "#totals" do

View file

@ -6,6 +6,9 @@ RSpec.shared_examples "GET /api/analytics/:endpoint authorization examples" do |
let(:pro_api_token) { create(:api_secret, user: pro_user) }
let(:pro_org_member) { create(:user, :pro, :org_member) }
let(:org_member_token) { create(:api_secret, user: pro_org_member) }
let(:article) { create(:article, user: user) }
let(:pro_user_article) { create(:article, user: pro_user) }
let(:pro_org_article) { create(:article, user: pro_user, organization: org) }
context "when an invalid token is given" do
before { get "/api/analytics/#{endpoint}?#{params}", headers: { "api-key" => "abadskajdlsak" } }
@ -70,4 +73,34 @@ RSpec.shared_examples "GET /api/analytics/:endpoint authorization examples" do |
expect(response.status).to eq 401
end
end
context "when attempting to view someone else's article analytics" do
it "responds with status 401 unauthorized" do
get "/api/analytics/#{endpoint}?article_id=#{article.id}#{params}"
expect(response.status).to eq 401
end
end
context "when viewing as current user" do
it "responds with status 200 OK" do
sign_in pro_user
get "/api/analytics/#{endpoint}?#{params}"
expect(response.status).to eq 200
end
end
context "when viewing your own single article's analytics" do
it "responds with status 200 OK" do
sign_in pro_user
get "/api/analytics/#{endpoint}?article_id=#{pro_user_article.id}#{params}"
expect(response.status).to eq 200
end
end
context "when viewing your own organizaiton's single article's analytics" do
it "responds with status 200 OK" do
sign_in pro_org_member
get "/api/analytics/#{endpoint}?article_id=#{pro_org_article.id}#{params}"
end
end
end