2015-10-11 17:41:23 +08:00
|
|
|
|
require 'rails_helper'
|
2013-03-21 01:54:32 +08:00
|
|
|
|
|
|
|
|
|
describe Report do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
shared_examples 'no data' do
|
|
|
|
|
context "with no data" do
|
|
|
|
|
it 'returns an empty report' do
|
|
|
|
|
expect(report.data).to be_blank
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
shared_examples 'category filtering' do
|
|
|
|
|
it 'returns the filtered data' do
|
|
|
|
|
expect(report.total).to eq 1
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
shared_examples 'with data x/y' do
|
|
|
|
|
it "returns today's data" do
|
|
|
|
|
expect(report.data.select { |v| v[:x].today? }).to be_present
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns correct data for period' do
|
|
|
|
|
expect(report.data[0][:y]).to eq 3
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns total' do
|
|
|
|
|
expect(report.total).to eq 4
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns previous 30 day’s data' do
|
|
|
|
|
expect(report.prev30Days).to be_present
|
|
|
|
|
end
|
|
|
|
|
end
|
2013-03-21 01:54:32 +08:00
|
|
|
|
|
2018-02-02 04:50:41 +08:00
|
|
|
|
describe "counting" do
|
|
|
|
|
describe "requests" do
|
|
|
|
|
before do
|
|
|
|
|
freeze_time DateTime.parse('2017-03-01 12:00')
|
|
|
|
|
|
|
|
|
|
# today, an incomplete day:
|
|
|
|
|
ApplicationRequest.create(date: 0.days.ago.to_time, req_type: ApplicationRequest.req_types['http_total'], count: 1)
|
|
|
|
|
|
|
|
|
|
# 60 complete days:
|
|
|
|
|
30.times do |i|
|
|
|
|
|
ApplicationRequest.create(date: (i + 1).days.ago.to_time, req_type: ApplicationRequest.req_types['http_total'], count: 10)
|
|
|
|
|
end
|
|
|
|
|
30.times do |i|
|
|
|
|
|
ApplicationRequest.create(date: (31 + i).days.ago.to_time, req_type: ApplicationRequest.req_types['http_total'], count: 100)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subject(:json) { Report.find("http_total_reqs").as_json }
|
|
|
|
|
|
|
|
|
|
it "counts the correct records" do
|
|
|
|
|
expect(json[:data].size).to eq(31) # today and 30 full days
|
|
|
|
|
expect(json[:data][0..-2].sum { |d| d[:y] }).to eq(300)
|
|
|
|
|
expect(json[:prev30Days]).to eq(3000)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "topics" do
|
|
|
|
|
before do
|
2018-05-11 11:30:21 +08:00
|
|
|
|
Report.clear_cache
|
2018-02-02 04:50:41 +08:00
|
|
|
|
freeze_time DateTime.parse('2017-03-01 12:00')
|
|
|
|
|
|
|
|
|
|
((0..32).to_a + [60, 61, 62, 63]).each do |i|
|
|
|
|
|
Fabricate(:topic, created_at: i.days.ago)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "counts the correct records" do
|
2018-05-11 11:30:21 +08:00
|
|
|
|
json = Report.find("topics").as_json
|
2018-02-02 04:50:41 +08:00
|
|
|
|
expect(json[:data].size).to eq(31)
|
|
|
|
|
expect(json[:prev30Days]).to eq(3)
|
2018-05-11 11:30:21 +08:00
|
|
|
|
|
|
|
|
|
# lets make sure we can ask for the correct options for the report
|
|
|
|
|
json = Report.find("topics",
|
|
|
|
|
start_date: 5.days.ago.beginning_of_day,
|
|
|
|
|
end_date: 1.day.ago.end_of_day,
|
|
|
|
|
facets: [:prev_period]
|
|
|
|
|
).as_json
|
|
|
|
|
|
|
|
|
|
expect(json[:prev_period]).to eq(5)
|
|
|
|
|
expect(json[:data].length).to eq(5)
|
|
|
|
|
expect(json[:prev30Days]).to eq(nil)
|
2018-02-02 04:50:41 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2013-04-04 01:25:52 +08:00
|
|
|
|
describe 'visits report' do
|
|
|
|
|
let(:report) { Report.find('visits') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2013-04-04 01:25:52 +08:00
|
|
|
|
|
|
|
|
|
context "with visits" do
|
|
|
|
|
let(:user) { Fabricate(:user) }
|
|
|
|
|
|
2015-02-05 08:33:13 +08:00
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
freeze_time DateTime.parse('2000-01-01')
|
|
|
|
|
user.user_visits.create(visited_at: 1.hour.from_now)
|
2013-04-04 01:25:52 +08:00
|
|
|
|
user.user_visits.create(visited_at: 1.day.ago)
|
|
|
|
|
user.user_visits.create(visited_at: 2.days.ago)
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data).to be_present
|
|
|
|
|
expect(report.data.select { |v| v[:x].today? }).to be_present
|
2014-12-29 20:29:09 +08:00
|
|
|
|
end
|
2015-02-05 08:33:13 +08:00
|
|
|
|
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
[:signup, :topic, :post, :flag, :like, :email].each do |arg|
|
|
|
|
|
describe "#{arg} report" do
|
|
|
|
|
pluralized = arg.to_s.pluralize
|
|
|
|
|
|
|
|
|
|
let(:report) { Report.find(pluralized) }
|
|
|
|
|
|
|
|
|
|
context "no #{pluralized}" do
|
|
|
|
|
it 'returns an empty report' do
|
2014-12-31 22:55:03 +08:00
|
|
|
|
expect(report.data).to be_blank
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "with #{pluralized}" do
|
2014-12-30 22:06:15 +08:00
|
|
|
|
before(:each) do
|
2018-05-25 12:22:31 +08:00
|
|
|
|
freeze_time DateTime.parse('2017-03-01 12:00')
|
2013-04-04 01:25:52 +08:00
|
|
|
|
fabricator = case arg
|
2017-07-28 09:20:09 +08:00
|
|
|
|
when :signup
|
|
|
|
|
:user
|
|
|
|
|
when :email
|
|
|
|
|
:email_log
|
2013-04-04 01:25:52 +08:00
|
|
|
|
else
|
2017-07-28 09:20:09 +08:00
|
|
|
|
arg
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
2014-12-30 22:06:15 +08:00
|
|
|
|
Fabricate(fabricator)
|
2013-04-04 01:25:52 +08:00
|
|
|
|
Fabricate(fabricator, created_at: 1.hours.ago)
|
|
|
|
|
Fabricate(fabricator, created_at: 1.hours.ago)
|
2014-12-30 22:06:15 +08:00
|
|
|
|
Fabricate(fabricator, created_at: 1.day.ago)
|
|
|
|
|
Fabricate(fabricator, created_at: 2.days.ago)
|
|
|
|
|
Fabricate(fabricator, created_at: 30.days.ago)
|
|
|
|
|
Fabricate(fabricator, created_at: 35.days.ago)
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
|
2018-02-02 04:50:41 +08:00
|
|
|
|
it "returns today's data" do
|
|
|
|
|
expect(report.data.select { |v| v[:x].today? }).to be_present
|
|
|
|
|
end
|
2014-12-30 22:06:15 +08:00
|
|
|
|
|
2018-02-02 04:50:41 +08:00
|
|
|
|
it 'returns total data' do
|
|
|
|
|
expect(report.total).to eq 7
|
|
|
|
|
end
|
2014-12-30 22:06:15 +08:00
|
|
|
|
|
2018-02-02 04:50:41 +08:00
|
|
|
|
it "returns previous 30 day's data" do
|
|
|
|
|
expect(report.prev30Days).to be_present
|
|
|
|
|
end
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
2017-07-28 09:20:09 +08:00
|
|
|
|
end
|
2013-04-04 01:25:52 +08:00
|
|
|
|
|
2015-04-13 01:46:13 +08:00
|
|
|
|
[:http_total, :http_2xx, :http_background, :http_3xx, :http_4xx, :http_5xx, :page_view_crawler, :page_view_logged_in, :page_view_anon].each do |request_type|
|
|
|
|
|
describe "#{request_type} request reports" do
|
2018-05-04 14:02:08 +08:00
|
|
|
|
let(:report) { Report.find("#{request_type}_reqs", start_date: 10.days.ago.to_time, end_date: Time.now) }
|
2015-04-13 01:46:13 +08:00
|
|
|
|
|
|
|
|
|
context "with no #{request_type} records" do
|
|
|
|
|
it 'returns an empty report' do
|
|
|
|
|
expect(report.data).to be_blank
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "with #{request_type}" do
|
|
|
|
|
before(:each) do
|
2018-05-25 12:22:31 +08:00
|
|
|
|
freeze_time DateTime.parse('2017-03-01 12:00')
|
2015-04-13 01:46:13 +08:00
|
|
|
|
ApplicationRequest.create(date: 35.days.ago.to_time, req_type: ApplicationRequest.req_types[request_type.to_s], count: 35)
|
|
|
|
|
ApplicationRequest.create(date: 7.days.ago.to_time, req_type: ApplicationRequest.req_types[request_type.to_s], count: 8)
|
2018-05-04 14:02:08 +08:00
|
|
|
|
ApplicationRequest.create(date: Time.now, req_type: ApplicationRequest.req_types[request_type.to_s], count: 1)
|
2015-04-13 01:46:13 +08:00
|
|
|
|
ApplicationRequest.create(date: 1.day.ago.to_time, req_type: ApplicationRequest.req_types[request_type.to_s], count: 2)
|
|
|
|
|
ApplicationRequest.create(date: 2.days.ago.to_time, req_type: ApplicationRequest.req_types[request_type.to_s], count: 3)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'returns a report with data' do
|
|
|
|
|
it "returns expected number of recoords" do
|
|
|
|
|
expect(report.data.count).to eq 4
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'sorts the data from oldest to latest dates' do
|
|
|
|
|
expect(report.data[0][:y]).to eq(8) # 7 days ago
|
|
|
|
|
expect(report.data[1][:y]).to eq(3) # 2 days ago
|
|
|
|
|
expect(report.data[2][:y]).to eq(2) # 1 day ago
|
|
|
|
|
expect(report.data[3][:y]).to eq(1) # today
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns today's data" do
|
|
|
|
|
expect(report.data.select { |value| value[:x] == Date.today }).to be_present
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns total data' do
|
|
|
|
|
expect(report.total).to eq 49
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns previous 30 days of data' do
|
2015-07-07 02:57:11 +08:00
|
|
|
|
expect(report.prev30Days).to eq 35
|
2015-04-13 01:46:13 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-07-23 22:33:12 +08:00
|
|
|
|
describe 'user to user private messages with replies' do
|
2018-03-27 16:30:08 +08:00
|
|
|
|
let(:report) { Report.find('user_to_user_private_messages_with_replies') }
|
2013-04-04 01:25:52 +08:00
|
|
|
|
|
2015-01-06 00:04:23 +08:00
|
|
|
|
it 'topic report).to not include private messages' do
|
2013-04-04 01:25:52 +08:00
|
|
|
|
Fabricate(:private_message_topic, created_at: 1.hour.ago)
|
|
|
|
|
Fabricate(:topic, created_at: 1.hour.ago)
|
|
|
|
|
report = Report.find('topics')
|
2014-12-31 22:55:03 +08:00
|
|
|
|
expect(report.data[0][:y]).to eq(1)
|
|
|
|
|
expect(report.total).to eq(1)
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
|
2015-01-06 00:04:23 +08:00
|
|
|
|
it 'post report).to not include private messages' do
|
2013-04-04 01:25:52 +08:00
|
|
|
|
Fabricate(:private_message_post, created_at: 1.hour.ago)
|
|
|
|
|
Fabricate(:post)
|
|
|
|
|
report = Report.find('posts')
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data[0][:y]).to eq 1
|
|
|
|
|
expect(report.total).to eq 1
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'no private messages' do
|
|
|
|
|
it 'returns an empty report' do
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data).to be_blank
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'some public posts' do
|
|
|
|
|
it 'returns an empty report' do
|
|
|
|
|
Fabricate(:post); Fabricate(:post)
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data).to be_blank
|
|
|
|
|
expect(report.total).to eq 0
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'some private messages' do
|
|
|
|
|
before do
|
|
|
|
|
Fabricate(:private_message_post, created_at: 25.hours.ago)
|
|
|
|
|
Fabricate(:private_message_post, created_at: 1.hour.ago)
|
|
|
|
|
Fabricate(:private_message_post, created_at: 1.hour.ago)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns correct data' do
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data[0][:y]).to eq 1
|
|
|
|
|
expect(report.data[1][:y]).to eq 2
|
|
|
|
|
expect(report.total).to eq 3
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'and some public posts' do
|
|
|
|
|
before do
|
|
|
|
|
Fabricate(:post); Fabricate(:post)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'returns correct data' do
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data[0][:y]).to eq 1
|
|
|
|
|
expect(report.data[1][:y]).to eq 2
|
|
|
|
|
expect(report.total).to eq 3
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-07-23 22:33:12 +08:00
|
|
|
|
|
|
|
|
|
context 'private message from system user' do
|
|
|
|
|
before do
|
|
|
|
|
Fabricate(:private_message_post, created_at: 1.hour.ago, user: Discourse.system_user)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'does not include system users' do
|
|
|
|
|
expect(report.data).to be_blank
|
|
|
|
|
expect(report.total).to eq 0
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'user to user private messages' do
|
|
|
|
|
let(:report) { Report.find('user_to_user_private_messages') }
|
|
|
|
|
|
|
|
|
|
context 'private message from system user' do
|
|
|
|
|
before do
|
|
|
|
|
Fabricate(:private_message_post, created_at: 1.hour.ago, user: Discourse.system_user)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'does not include system users' do
|
|
|
|
|
expect(report.data).to be_blank
|
|
|
|
|
expect(report.total).to eq 0
|
|
|
|
|
end
|
|
|
|
|
end
|
2013-04-04 01:25:52 +08:00
|
|
|
|
end
|
2013-03-21 01:54:32 +08:00
|
|
|
|
|
|
|
|
|
describe 'users by trust level report' do
|
2013-04-04 01:25:52 +08:00
|
|
|
|
let(:report) { Report.find('users_by_trust_level') }
|
2013-03-21 01:54:32 +08:00
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2013-03-21 01:54:32 +08:00
|
|
|
|
|
|
|
|
|
context "with users at different trust levels" do
|
|
|
|
|
before do
|
2014-09-05 13:20:39 +08:00
|
|
|
|
3.times { Fabricate(:user, trust_level: TrustLevel[0]) }
|
|
|
|
|
2.times { Fabricate(:user, trust_level: TrustLevel[2]) }
|
|
|
|
|
Fabricate(:user, trust_level: TrustLevel[4])
|
2013-03-21 01:54:32 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
2015-01-06 00:04:23 +08:00
|
|
|
|
expect(report.data).to be_present
|
2017-07-28 09:20:09 +08:00
|
|
|
|
expect(report.data.find { |d| d[:x] == TrustLevel[0] }[:y]).to eq 3
|
|
|
|
|
expect(report.data.find { |d| d[:x] == TrustLevel[2] }[:y]).to eq 2
|
|
|
|
|
expect(report.data.find { |d| d[:x] == TrustLevel[4] }[:y]).to eq 1
|
2013-03-21 01:54:32 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-01-06 00:04:23 +08:00
|
|
|
|
|
2018-04-26 20:49:41 +08:00
|
|
|
|
describe 'new contributors report' do
|
|
|
|
|
let(:report) { Report.find('new_contributors') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-04-26 20:49:41 +08:00
|
|
|
|
|
|
|
|
|
context "with contributors" do
|
|
|
|
|
before do
|
|
|
|
|
jeff = Fabricate(:user)
|
|
|
|
|
jeff.user_stat = UserStat.new(new_since: 1.hour.ago, first_post_created_at: 1.day.ago)
|
|
|
|
|
|
|
|
|
|
regis = Fabricate(:user)
|
|
|
|
|
regis.user_stat = UserStat.new(new_since: 1.hour.ago, first_post_created_at: 2.days.ago)
|
|
|
|
|
|
|
|
|
|
hawk = Fabricate(:user)
|
|
|
|
|
hawk.user_stat = UserStat.new(new_since: 1.hour.ago, first_post_created_at: 2.days.ago)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
expect(report.data).to be_present
|
|
|
|
|
|
|
|
|
|
expect(report.data[0][:y]).to eq 2
|
|
|
|
|
expect(report.data[1][:y]).to eq 1
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-04-16 19:03:43 +08:00
|
|
|
|
describe 'users by types level report' do
|
2018-04-19 03:30:41 +08:00
|
|
|
|
let(:report) { Report.find('users_by_type') }
|
2018-04-16 19:03:43 +08:00
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-04-16 19:03:43 +08:00
|
|
|
|
|
|
|
|
|
context "with users at different trust levels" do
|
|
|
|
|
before do
|
|
|
|
|
3.times { Fabricate(:user, admin: true) }
|
|
|
|
|
2.times { Fabricate(:user, moderator: true) }
|
|
|
|
|
UserSilencer.silence(Fabricate(:user), Fabricate.build(:admin))
|
|
|
|
|
Fabricate(:user, suspended_till: 1.week.from_now, suspended_at: 1.day.ago)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
expect(report.data).to be_present
|
2018-04-16 19:40:44 +08:00
|
|
|
|
|
2018-04-19 03:30:41 +08:00
|
|
|
|
label = Proc.new { |key| I18n.t("reports.users_by_type.xaxis_labels.#{key}") }
|
2018-04-16 19:40:44 +08:00
|
|
|
|
expect(report.data.find { |d| d[:x] == label.call("admin") }[:y]).to eq 3
|
|
|
|
|
expect(report.data.find { |d| d[:x] == label.call("moderator") }[:y]).to eq 2
|
|
|
|
|
expect(report.data.find { |d| d[:x] == label.call("silenced") }[:y]).to eq 1
|
|
|
|
|
expect(report.data.find { |d| d[:x] == label.call("suspended") }[:y]).to eq 1
|
2018-04-16 19:03:43 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-04-20 00:19:21 +08:00
|
|
|
|
describe 'trending search report' do
|
|
|
|
|
let(:report) { Report.find('trending_search') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-04-20 00:19:21 +08:00
|
|
|
|
|
|
|
|
|
context "with different searches" do
|
|
|
|
|
before do
|
|
|
|
|
SearchLog.log(term: 'ruby', search_type: :header, ip_address: '127.0.0.1')
|
2018-05-11 11:30:21 +08:00
|
|
|
|
|
|
|
|
|
SearchLog.create!(term: 'ruby', search_result_id: 1, search_type: 1, ip_address: '127.0.0.1', user_id: Fabricate(:user).id)
|
|
|
|
|
|
2018-04-20 00:19:21 +08:00
|
|
|
|
SearchLog.log(term: 'ruby', search_type: :header, ip_address: '127.0.0.2')
|
|
|
|
|
SearchLog.log(term: 'php', search_type: :header, ip_address: '127.0.0.1')
|
|
|
|
|
end
|
|
|
|
|
|
2018-04-23 10:00:37 +08:00
|
|
|
|
after do
|
|
|
|
|
SearchLog.clear_debounce_cache!
|
|
|
|
|
end
|
2018-04-20 00:19:21 +08:00
|
|
|
|
|
2018-04-23 10:00:37 +08:00
|
|
|
|
it "returns a report with data" do
|
2018-05-15 13:20:36 +08:00
|
|
|
|
expect(report.data[0][:term]).to eq("ruby")
|
|
|
|
|
expect(report.data[0][:unique_searches]).to eq(2)
|
2018-07-20 02:33:11 +08:00
|
|
|
|
expect(report.data[0][:ctr]).to eq(33.4)
|
2018-04-20 00:19:21 +08:00
|
|
|
|
|
2018-05-15 13:20:36 +08:00
|
|
|
|
expect(report.data[1][:term]).to eq("php")
|
|
|
|
|
expect(report.data[1][:unique_searches]).to eq(1)
|
2018-04-20 00:19:21 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-05-03 21:41:41 +08:00
|
|
|
|
describe 'DAU/MAU report' do
|
|
|
|
|
let(:report) { Report.find('dau_by_mau') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-05-03 21:41:41 +08:00
|
|
|
|
|
|
|
|
|
context "with different users/visits" do
|
|
|
|
|
before do
|
2018-05-25 12:22:31 +08:00
|
|
|
|
freeze_time DateTime.parse('2017-03-01 12:00')
|
2018-05-03 21:41:41 +08:00
|
|
|
|
|
|
|
|
|
arpit = Fabricate(:user)
|
|
|
|
|
arpit.user_visits.create(visited_at: 1.day.ago)
|
|
|
|
|
|
|
|
|
|
sam = Fabricate(:user)
|
|
|
|
|
sam.user_visits.create(visited_at: 2.days.ago)
|
|
|
|
|
|
|
|
|
|
robin = Fabricate(:user)
|
|
|
|
|
robin.user_visits.create(visited_at: 2.days.ago)
|
|
|
|
|
|
|
|
|
|
michael = Fabricate(:user)
|
|
|
|
|
michael.user_visits.create(visited_at: 35.days.ago)
|
|
|
|
|
|
|
|
|
|
gerhard = Fabricate(:user)
|
|
|
|
|
gerhard.user_visits.create(visited_at: 45.days.ago)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
expect(report.data.first[:y]).to eq(100)
|
2018-05-11 11:30:21 +08:00
|
|
|
|
expect(report.data.last[:y]).to eq(33.34)
|
2018-05-03 21:41:41 +08:00
|
|
|
|
expect(report.prev30Days).to eq(75)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'Daily engaged users' do
|
|
|
|
|
let(:report) { Report.find('daily_engaged_users') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-05-03 21:41:41 +08:00
|
|
|
|
|
|
|
|
|
context "with different activities" do
|
|
|
|
|
before do
|
2018-05-25 12:22:31 +08:00
|
|
|
|
freeze_time DateTime.parse('2017-03-01 12:00')
|
2018-05-03 21:41:41 +08:00
|
|
|
|
|
|
|
|
|
UserActionCreator.enable
|
|
|
|
|
|
|
|
|
|
arpit = Fabricate(:user)
|
|
|
|
|
sam = Fabricate(:user)
|
|
|
|
|
|
|
|
|
|
jeff = Fabricate(:user, created_at: 1.day.ago)
|
|
|
|
|
topic = Fabricate(:topic, user: jeff, created_at: 1.day.ago)
|
|
|
|
|
post = Fabricate(:post, topic: topic, user: jeff, created_at: 1.day.ago)
|
|
|
|
|
|
|
|
|
|
PostAction.act(arpit, post, PostActionType.types[:like])
|
|
|
|
|
PostAction.act(sam, post, PostActionType.types[:like])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
expect(report.data.first[:y]).to eq(1)
|
|
|
|
|
expect(report.data.last[:y]).to eq(2)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2017-02-22 03:45:34 +08:00
|
|
|
|
describe 'posts counts' do
|
|
|
|
|
it "only counts regular posts" do
|
|
|
|
|
post = Fabricate(:post)
|
|
|
|
|
Fabricate(:moderator_post, topic: post.topic)
|
|
|
|
|
Fabricate.build(:post, post_type: Post.types[:whisper], topic: post.topic)
|
|
|
|
|
post.topic.add_small_action(Fabricate(:admin), "invited_group", 'coolkids')
|
|
|
|
|
r = Report.find('posts')
|
|
|
|
|
expect(r.total).to eq(1)
|
2017-11-03 06:24:43 +08:00
|
|
|
|
expect(r.data[0][:y]).to eq(1)
|
2017-02-22 03:45:34 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
2018-07-20 02:33:11 +08:00
|
|
|
|
|
|
|
|
|
describe 'flags_status' do
|
|
|
|
|
let(:report) { Report.find('flags_status') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-07-20 02:33:11 +08:00
|
|
|
|
|
|
|
|
|
context "with flags" do
|
|
|
|
|
let(:flagger) { Fabricate(:user) }
|
|
|
|
|
let(:post) { Fabricate(:post) }
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
PostAction.act(flagger, post, PostActionType.types[:spam], message: 'bad')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
expect(report.data).to be_present
|
|
|
|
|
|
|
|
|
|
row = report.data[0]
|
|
|
|
|
expect(row[:action_type]).to eq("spam")
|
|
|
|
|
expect(row[:staff_username]).to eq(nil)
|
|
|
|
|
expect(row[:staff_id]).to eq(nil)
|
|
|
|
|
expect(row[:staff_url]).to eq(nil)
|
|
|
|
|
expect(row[:poster_username]).to eq(post.user.username)
|
|
|
|
|
expect(row[:poster_id]).to eq(post.user.id)
|
|
|
|
|
expect(row[:poster_url]).to eq("/admin/users/#{post.user.id}/#{post.user.username}")
|
|
|
|
|
expect(row[:flagger_id]).to eq(flagger.id)
|
|
|
|
|
expect(row[:flagger_username]).to eq(flagger.username)
|
|
|
|
|
expect(row[:flagger_url]).to eq("/admin/users/#{flagger.id}/#{flagger.username}")
|
|
|
|
|
expect(row[:resolution]).to eq("No action")
|
|
|
|
|
expect(row[:response_time]).to eq(nil)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'post_edits' do
|
|
|
|
|
let(:report) { Report.find('post_edits') }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-07-20 02:33:11 +08:00
|
|
|
|
|
|
|
|
|
context "with edits" do
|
|
|
|
|
let(:editor) { Fabricate(:user) }
|
|
|
|
|
let(:post) { Fabricate(:post) }
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
post.revise(editor, raw: 'updated body', edit_reason: 'not cool')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
|
|
|
|
expect(report.data).to be_present
|
|
|
|
|
expect(report.data.count).to be(1)
|
|
|
|
|
|
|
|
|
|
row = report.data[0]
|
|
|
|
|
expect(row[:editor_id]).to eq(editor.id)
|
|
|
|
|
expect(row[:editor_username]).to eq(editor.username)
|
|
|
|
|
expect(row[:editor_url]).to eq("/admin/users/#{editor.id}/#{editor.username}")
|
|
|
|
|
expect(row[:author_id]).to eq(post.user.id)
|
|
|
|
|
expect(row[:author_username]).to eq(post.user.username)
|
|
|
|
|
expect(row[:author_url]).to eq("/admin/users/#{post.user.id}/#{post.user.username}")
|
|
|
|
|
expect(row[:edit_reason]).to eq("not cool")
|
|
|
|
|
expect(row[:post_id]).to eq(post.id)
|
|
|
|
|
expect(row[:post_url]).to eq("/t/-/#{post.topic.id}/#{post.post_number}")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'moderator activity' do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
let(:report) { Report.find('moderators_activity', start_date: 1.months.ago.beginning_of_day, end_date: Date.today) }
|
2018-07-20 02:33:11 +08:00
|
|
|
|
let(:previous_report) { Report.find('moderators_activity', start_date: 2.months.ago.beginning_of_day, end_date: 1.month.ago.end_of_day) }
|
|
|
|
|
|
2018-07-27 07:24:18 +08:00
|
|
|
|
include_examples 'no data'
|
2018-07-20 02:33:11 +08:00
|
|
|
|
|
|
|
|
|
context "with moderators" do
|
|
|
|
|
before do
|
|
|
|
|
freeze_time(Date.today)
|
|
|
|
|
|
|
|
|
|
bob = Fabricate(:user, moderator: true, username: 'bob')
|
|
|
|
|
bob.user_visits.create(visited_at: 2.days.ago, time_read: 200)
|
|
|
|
|
bob.user_visits.create(visited_at: 1.day.ago, time_read: 100)
|
|
|
|
|
Fabricate(:topic, user: bob, created_at: 1.day.ago)
|
|
|
|
|
sally = Fabricate(:user, moderator: true, username: 'sally')
|
|
|
|
|
sally.user_visits.create(visited_at: 2.days.ago, time_read: 1000)
|
|
|
|
|
sally.user_visits.create(visited_at: 1.day.ago, time_read: 2000)
|
|
|
|
|
topic = Fabricate(:topic)
|
|
|
|
|
2.times {
|
|
|
|
|
Fabricate(:post, user: sally, topic: topic, created_at: 1.day.ago)
|
|
|
|
|
}
|
|
|
|
|
flag_user = Fabricate(:user)
|
|
|
|
|
flag_post = Fabricate(:post, user: flag_user)
|
|
|
|
|
action = PostAction.new(user_id: flag_user.id,
|
|
|
|
|
post_action_type_id: PostActionType.types[:off_topic],
|
|
|
|
|
post_id: flag_post.id,
|
|
|
|
|
agreed_by_id: sally.id,
|
|
|
|
|
created_at: 1.day.ago,
|
|
|
|
|
agreed_at: Time.now)
|
|
|
|
|
action.save
|
|
|
|
|
bob.user_visits.create(visited_at: 45.days.ago, time_read: 200)
|
|
|
|
|
old_topic = Fabricate(:topic, user: bob, created_at: 45.days.ago)
|
|
|
|
|
3.times {
|
|
|
|
|
Fabricate(:post, user: bob, topic: old_topic, created_at: 45.days.ago)
|
|
|
|
|
}
|
|
|
|
|
old_flag_user = Fabricate(:user)
|
|
|
|
|
old_flag_post = Fabricate(:post, user: old_flag_user, created_at: 45.days.ago)
|
|
|
|
|
old_action = PostAction.new(user_id: old_flag_user.id,
|
|
|
|
|
post_action_type_id: PostActionType.types[:spam],
|
|
|
|
|
post_id: old_flag_post.id,
|
|
|
|
|
agreed_by_id: bob.id,
|
|
|
|
|
created_at: 44.days.ago,
|
|
|
|
|
agreed_at: 44.days.ago)
|
|
|
|
|
old_action.save
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns a report with data" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data).to be_present
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns data for two moderators" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data.count).to eq(2)
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns the correct usernames" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data[0][:username]).to eq('bob')
|
|
|
|
|
expect(report.data[1][:username]).to eq('sally')
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns the correct read times" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data[0][:time_read]).to eq(300)
|
|
|
|
|
expect(report.data[1][:time_read]).to eq(3000)
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns the correct agreed flag count" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data[0][:flag_count]).to be_blank
|
|
|
|
|
expect(report.data[1][:flag_count]).to eq(1)
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns the correct topic count" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data[0][:topic_count]).to eq(1)
|
|
|
|
|
expect(report.data[1][:topic_count]).to be_blank
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns the correct post count" do
|
2018-07-27 07:24:18 +08:00
|
|
|
|
expect(report.data[0][:post_count]).to be_blank
|
|
|
|
|
expect(report.data[1][:post_count]).to eq(2)
|
2018-07-20 02:33:11 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "returns the correct data for the time period" do
|
|
|
|
|
expect(previous_report.data[0][:flag_count]).to eq(1)
|
|
|
|
|
expect(previous_report.data[0][:topic_count]).to eq(1)
|
|
|
|
|
expect(previous_report.data[0][:post_count]).to eq(3)
|
|
|
|
|
expect(previous_report.data[0][:time_read]).to eq(200)
|
|
|
|
|
|
|
|
|
|
expect(previous_report.data[1][:flag_count]).to be_blank
|
|
|
|
|
expect(previous_report.data[1][:topic_count]).to be_blank
|
|
|
|
|
expect(previous_report.data[1][:post_count]).to be_blank
|
|
|
|
|
expect(previous_report.data[1][:time_read]).to be_blank
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-07-27 07:24:18 +08:00
|
|
|
|
|
|
|
|
|
describe 'flags' do
|
|
|
|
|
let(:report) { Report.find('flags') }
|
|
|
|
|
|
|
|
|
|
include_examples 'no data'
|
|
|
|
|
|
|
|
|
|
context 'with data' do
|
|
|
|
|
include_examples 'with data x/y'
|
|
|
|
|
|
|
|
|
|
before(:each) do
|
|
|
|
|
user = Fabricate(:user)
|
|
|
|
|
post0 = Fabricate(:post)
|
|
|
|
|
post1 = Fabricate(:post, topic: Fabricate(:topic, category_id: 2))
|
|
|
|
|
post2 = Fabricate(:post)
|
|
|
|
|
post3 = Fabricate(:post)
|
|
|
|
|
PostAction.act(user, post0, PostActionType.types[:off_topic])
|
|
|
|
|
PostAction.act(user, post1, PostActionType.types[:off_topic])
|
|
|
|
|
PostAction.act(user, post2, PostActionType.types[:off_topic])
|
|
|
|
|
PostAction.act(user, post3, PostActionType.types[:off_topic]).tap do |pa|
|
|
|
|
|
pa.created_at = 45.days.ago
|
|
|
|
|
end.save
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "with category filtering" do
|
|
|
|
|
let(:report) { Report.find('flags', category_id: 2) }
|
|
|
|
|
|
|
|
|
|
include_examples 'category filtering'
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'topics' do
|
|
|
|
|
let(:report) { Report.find('topics') }
|
|
|
|
|
|
|
|
|
|
include_examples 'no data'
|
|
|
|
|
|
|
|
|
|
context 'with data' do
|
|
|
|
|
include_examples 'with data x/y'
|
|
|
|
|
|
|
|
|
|
before(:each) do
|
|
|
|
|
Fabricate(:topic)
|
|
|
|
|
Fabricate(:topic, category_id: 2)
|
|
|
|
|
Fabricate(:topic)
|
|
|
|
|
Fabricate(:topic, created_at: 45.days.ago)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "with category filtering" do
|
|
|
|
|
let(:report) { Report.find('topics', category_id: 2) }
|
|
|
|
|
|
|
|
|
|
include_examples 'category filtering'
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2017-02-22 03:45:34 +08:00
|
|
|
|
end
|