Commit 478e01ce authored by Sean McGivern's avatar Sean McGivern

Merge branch '22645-add-discussion-contribs-to-calendar' into 'master'

Add discussion events to contributions calendar

Closes #22645

See merge request !8821
parents 640e977d 4f51e1fa
...@@ -45,9 +45,10 @@ class Event < ActiveRecord::Base ...@@ -45,9 +45,10 @@ class Event < ActiveRecord::Base
class << self class << self
# Update Gitlab::ContributionsCalendar#activity_dates if this changes # Update Gitlab::ContributionsCalendar#activity_dates if this changes
def contributions def contributions
where("action = ? OR (target_type in (?) AND action in (?))", where("action = ? OR (target_type IN (?) AND action IN (?)) OR (target_type = ? AND action = ?)",
Event::PUSHED, ["MergeRequest", "Issue"], Event::PUSHED,
[Event::CREATED, Event::CLOSED, Event::MERGED]) ["MergeRequest", "Issue"], [Event::CREATED, Event::CLOSED, Event::MERGED],
"Note", Event::COMMENTED)
end end
def limit_recent(limit = 20, offset = nil) def limit_recent(limit = 20, offset = nil)
......
.clearfix.calendar .clearfix.calendar
.js-contrib-calendar .js-contrib-calendar
.calendar-hint .calendar-hint
Summary of issues, merge requests, and push events Summary of issues, merge requests, push events, and comments
:javascript :javascript
new Calendar( new Calendar(
#{@activity_dates.to_json}, #{@activity_dates.to_json},
......
...@@ -13,8 +13,10 @@ ...@@ -13,8 +13,10 @@
#{event.action_name} #{event.ref_type} #{event.ref_name} #{event.action_name} #{event.ref_type} #{event.ref_name}
- else - else
= event_action_name(event) = event_action_name(event)
- if event.target - if event.note?
%strong= link_to "#{event.target.to_reference}", [event.project.namespace.becomes(Namespace), event.project, event.target] %strong= link_to event.note_target.to_reference, event_note_target_path(event)
- elsif event.target
%strong= link_to event.target.to_reference, [event.project.namespace.becomes(Namespace), event.project, event.target]
at at
%strong %strong
......
---
title: Add discussion events to contributions calendar
merge_request: 8821
author:
...@@ -22,8 +22,10 @@ module Gitlab ...@@ -22,8 +22,10 @@ module Gitlab
having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue") having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue")
mr_events = event_counts(date_from, :merge_requests). mr_events = event_counts(date_from, :merge_requests).
having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest") having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest")
note_events = event_counts(date_from, :merge_requests).
having(action: [Event::COMMENTED], target_type: "Note")
union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events]) union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events, note_events])
events = Event.find_by_sql(union.to_sql).map(&:attributes) events = Event.find_by_sql(union.to_sql).map(&:attributes)
@activity_events = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities| @activity_events = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities|
...@@ -38,7 +40,7 @@ module Gitlab ...@@ -38,7 +40,7 @@ module Gitlab
# Use visible_to_user? instead of the complicated logic in activity_dates # Use visible_to_user? instead of the complicated logic in activity_dates
# because we're only viewing the events for a single day. # because we're only viewing the events for a single day.
events.select {|event| event.visible_to_user?(current_user) } events.select { |event| event.visible_to_user?(current_user) }
end end
def starting_year def starting_year
......
require 'spec_helper' require 'spec_helper'
feature 'Contributions Calendar', js: true, feature: true do feature 'Contributions Calendar', :feature, :js do
include WaitForAjax include WaitForAjax
let(:user) { create(:user) }
let(:contributed_project) { create(:project, :public) } let(:contributed_project) { create(:project, :public) }
let(:issue_note) { create(:note, project: contributed_project) }
# Ex/ Sunday Jan 1, 2016 # Ex/ Sunday Jan 1, 2016
date_format = '%A %b %-d, %Y' date_format = '%A %b %-d, %Y'
...@@ -12,30 +14,30 @@ feature 'Contributions Calendar', js: true, feature: true do ...@@ -12,30 +14,30 @@ feature 'Contributions Calendar', js: true, feature: true do
issue_params = { title: issue_title } issue_params = { title: issue_title }
def get_cell_color_selector(contributions) def get_cell_color_selector(contributions)
contribution_cell = '.user-contrib-cell' activity_colors = %w[#ededed #acd5f2 #7fa8c9 #527ba0 #254e77]
activity_colors = Array['#ededed', '#acd5f2', '#7fa8c9', '#527ba0', '#254e77'] # We currently don't actually test the cases with contributions >= 20
activity_colors_index = 0 activity_colors_index =
if contributions > 0 && contributions < 10 if contributions > 0 && contributions < 10
activity_colors_index = 1 1
elsif contributions >= 10 && contributions < 20 elsif contributions >= 10 && contributions < 20
activity_colors_index = 2 2
elsif contributions >= 20 && contributions < 30 elsif contributions >= 20 && contributions < 30
activity_colors_index = 3 3
elsif contributions >= 30 elsif contributions >= 30
activity_colors_index = 4 4
else
0
end end
"#{contribution_cell}[fill='#{activity_colors[activity_colors_index]}']" ".user-contrib-cell[fill='#{activity_colors[activity_colors_index]}']"
end end
def get_cell_date_selector(contributions, date) def get_cell_date_selector(contributions, date)
contribution_text = 'No contributions' contribution_text =
if contributions.zero?
if contributions === 1 'No contributions'
contribution_text = '1 contribution' else
elsif contributions > 1 "#{contributions} #{'contribution'.pluralize(contributions)}"
contribution_text = "#{contributions} contributions"
end end
"#{get_cell_color_selector(contributions)}[data-original-title='#{contribution_text}<br />#{date}']" "#{get_cell_color_selector(contributions)}[data-original-title='#{contribution_text}<br />#{date}']"
...@@ -45,129 +47,155 @@ feature 'Contributions Calendar', js: true, feature: true do ...@@ -45,129 +47,155 @@ feature 'Contributions Calendar', js: true, feature: true do
push_params = { push_params = {
project: contributed_project, project: contributed_project,
action: Event::PUSHED, action: Event::PUSHED,
author_id: @user.id, author_id: user.id,
data: { commit_count: 3 } data: { commit_count: 3 }
} }
Event.create(push_params) Event.create(push_params)
end end
def get_first_cell_content def note_comment_contribution
note_comment_params = {
project: contributed_project,
action: Event::COMMENTED,
target: issue_note,
author_id: user.id
}
Event.create(note_comment_params)
end
def selected_day_activities
find('.user-calendar-activities').text find('.user-calendar-activities').text
end end
before do before do
login_as :user login_as user
visit @user.username end
describe 'calendar day selection' do
before do
visit user.username
wait_for_ajax wait_for_ajax
end end
it 'displays calendar', js: true do it 'displays calendar' do
expect(page).to have_css('.js-contrib-calendar') expect(page).to have_css('.js-contrib-calendar')
end end
describe 'select calendar day', js: true do describe 'select calendar day' do
let(:cells) { page.all('.user-contrib-cell') } let(:cells) { page.all('.user-contrib-cell') }
let(:first_cell_content_before) { get_first_cell_content }
before do before do
cells[0].click cells[0].click
wait_for_ajax wait_for_ajax
first_cell_content_before @first_day_activities = selected_day_activities
end end
it 'displays calendar day activities', js: true do it 'displays calendar day activities' do
expect(get_first_cell_content).not_to eq('') expect(selected_day_activities).not_to be_empty
end end
describe 'select another calendar day', js: true do describe 'select another calendar day' do
before do before do
cells[1].click cells[1].click
wait_for_ajax wait_for_ajax
end end
it 'displays different calendar day activities', js: true do it 'displays different calendar day activities' do
expect(get_first_cell_content).not_to eq(first_cell_content_before) expect(selected_day_activities).not_to eq(@first_day_activities)
end end
end end
describe 'deselect calendar day', js: true do describe 'deselect calendar day' do
before do before do
cells[0].click cells[0].click
wait_for_ajax wait_for_ajax
end end
it 'hides calendar day activities', js: true do it 'hides calendar day activities' do
expect(get_first_cell_content).to eq('') expect(selected_day_activities).to be_empty
end
end end
end end
end end
describe '1 calendar activity' do describe 'calendar daily activities' do
shared_context 'visit user page' do
before do before do
Issues::CreateService.new(contributed_project, @user, issue_params).execute visit user.username
visit @user.username
wait_for_ajax wait_for_ajax
end end
it 'displays calendar activity log', js: true do
expect(find('.content_list .event-note')).to have_content issue_title
end end
it 'displays calendar activity square color for 1 contribution', js: true do shared_examples 'a day with activity' do |contribution_count:|
expect(page).to have_selector(get_cell_color_selector(1), count: 1) include_context 'visit user page'
it 'displays calendar activity square color for 1 contribution' do
expect(page).to have_selector(get_cell_color_selector(contribution_count), count: 1)
end end
it 'displays calendar activity square on the correct date', js: true do it 'displays calendar activity square on the correct date' do
today = Date.today.strftime(date_format) today = Date.today.strftime(date_format)
expect(page).to have_selector(get_cell_date_selector(1, today), count: 1) expect(page).to have_selector(get_cell_date_selector(contribution_count, today), count: 1)
end end
end end
describe '10 calendar activities' do describe '1 issue creation calendar activity' do
before do before do
(0..9).each do |i| Issues::CreateService.new(contributed_project, user, issue_params).execute
push_code_contribution()
end end
visit @user.username it_behaves_like 'a day with activity', contribution_count: 1
wait_for_ajax
describe 'issue title is shown on activity page' do
include_context 'visit user page'
it 'displays calendar activity log' do
expect(find('.content_list .event-note')).to have_content issue_title
end
end
end end
it 'displays calendar activity square color for 10 contributions', js: true do describe '1 comment calendar activity' do
expect(page).to have_selector(get_cell_color_selector(10), count: 1) before do
note_comment_contribution
end end
it 'displays calendar activity square on the correct date', js: true do it_behaves_like 'a day with activity', contribution_count: 1
today = Date.today.strftime(date_format) end
expect(page).to have_selector(get_cell_date_selector(10, today), count: 1)
describe '10 calendar activities' do
before do
10.times { push_code_contribution }
end end
it_behaves_like 'a day with activity', contribution_count: 10
end end
describe 'calendar activity on two days' do describe 'calendar activity on two days' do
before do before do
push_code_contribution() push_code_contribution
Timecop.freeze(Date.yesterday) Timecop.freeze(Date.yesterday) do
Issues::CreateService.new(contributed_project, @user, issue_params).execute Issues::CreateService.new(contributed_project, user, issue_params).execute
Timecop.return
visit @user.username
wait_for_ajax
end end
end
include_context 'visit user page'
it 'displays calendar activity squares for both days', js: true do it 'displays calendar activity squares for both days' do
expect(page).to have_selector(get_cell_color_selector(1), count: 2) expect(page).to have_selector(get_cell_color_selector(1), count: 2)
end end
it 'displays calendar activity square for yesterday', js: true do it 'displays calendar activity square for yesterday' do
yesterday = Date.yesterday.strftime(date_format) yesterday = Date.yesterday.strftime(date_format)
expect(page).to have_selector(get_cell_date_selector(1, yesterday), count: 1) expect(page).to have_selector(get_cell_date_selector(1, yesterday), count: 1)
end end
it 'displays calendar activity square for today', js: true do it 'displays calendar activity square for today' do
today = Date.today.strftime(date_format) today = Date.today.strftime(date_format)
expect(page).to have_selector(get_cell_date_selector(1, today), count: 1) expect(page).to have_selector(get_cell_date_selector(1, today), count: 1)
end end
end end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment