summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/application.js.coffee6
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee1
-rw-r--r--app/assets/javascripts/projects_list.js.coffee2
-rw-r--r--app/assets/stylesheets/pages/dashboard.scss38
-rw-r--r--app/assets/stylesheets/pages/projects.scss31
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb9
-rw-r--r--app/controllers/dashboard_controller.rb22
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml13
-rw-r--r--app/views/admin/abuse_reports/index.html.haml2
-rw-r--r--app/views/dashboard/_projects.html.haml9
-rw-r--r--app/views/dashboard/activity.html.haml6
-rw-r--r--app/views/dashboard/projects/starred.html.haml2
-rw-r--r--app/views/dashboard/show.html.haml12
-rw-r--r--app/views/events/_event_last_push.html.haml2
-rw-r--r--app/views/groups/_projects.html.haml2
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml7
-rw-r--r--app/views/projects/diffs/_warning.html.haml2
-rw-r--r--app/views/shared/_project.html.haml6
-rw-r--r--app/workers/emails_on_push_worker.rb33
-rw-r--r--config/routes.rb1
-rw-r--r--features/dashboard/dashboard.feature8
-rw-r--r--features/dashboard/event_filters.feature8
-rw-r--r--features/project/commits/commits.feature1
-rw-r--r--features/steps/project/commits/commits.rb6
-rw-r--r--features/steps/shared/paths.rb4
-rw-r--r--spec/workers/emails_on_push_worker_spec.rb34
29 files changed, 185 insertions, 93 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 5940d586d88..5222ab1e3e1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased)
+ - Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
+ - Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Remove user OAuth tokens from the database and request new tokens each session (Stan Hu)
- Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu)
- Remove satellites
@@ -12,6 +14,9 @@ v 8.0.0 (unreleased)
- Search for comments should be case insensetive
- Create cross-reference for closing references on commits pushed to non-default branches (Maƫl Valais)
- Ability to search milestones
+ - Gracefully handle SMTP user input errors (e.g. incorrect email addresses) to prevent Sidekiq retries (Stan Hu)
+ - Improve abuse reports management from admin area
+ - Move dashboard activity to separate page
v 7.14.1 (unreleased)
- Only include base URL in OmniAuth full_host parameter (Stan Hu)
diff --git a/Gemfile b/Gemfile
index 3aa3c72e088..fa54a72f025 100644
--- a/Gemfile
+++ b/Gemfile
@@ -34,7 +34,7 @@ gem 'rqrcode-rails3'
gem 'attr_encrypted', '1.3.4'
# Browser detection
-gem "browser", '~> 0.8.0'
+gem "browser", '~> 1.0.0'
# Extracting information from a git repository
# Provide access to Gitlab::Git library
diff --git a/Gemfile.lock b/Gemfile.lock
index 5278fe243a8..a7cfe6b7511 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -76,7 +76,7 @@ GEM
ruby_parser (~> 3.5.0)
sass (~> 3.0)
terminal-table (~> 1.4)
- browser (0.8.0)
+ browser (1.0.0)
builder (3.2.2)
byebug (3.2.0)
columnize (~> 0.8)
@@ -755,7 +755,7 @@ DEPENDENCIES
binding_of_caller
bootstrap-sass (~> 3.0)
brakeman
- browser (~> 0.8.0)
+ browser (~> 1.0.0)
byebug
cal-heatmap-rails (~> 0.0.1)
capybara (~> 2.4.0)
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index bb0a0c51fd4..c263912b7ea 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -116,6 +116,12 @@ $ ->
$('.remove-row').bind 'ajax:success', ->
$(this).closest('li').fadeOut()
+ $('.js-remove-tr').bind 'ajax:before', ->
+ $(this).hide()
+
+ $('.js-remove-tr').bind 'ajax:success', ->
+ $(this).closest('tr').fadeOut()
+
# Initialize select2 selects
$('select.select2').select2(width: 'resolve', dropdownAutoWidth: true)
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 81e73799271..539041c2862 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -51,6 +51,7 @@ class Dispatcher
MergeRequests.init()
when 'dashboard:show', 'root:show'
new Dashboard()
+ when 'dashboard:activity'
new Activities()
when 'dashboard:projects:starred'
new Activities()
diff --git a/app/assets/javascripts/projects_list.js.coffee b/app/assets/javascripts/projects_list.js.coffee
index c0e36d1ccc5..db5faf71faf 100644
--- a/app/assets/javascripts/projects_list.js.coffee
+++ b/app/assets/javascripts/projects_list.js.coffee
@@ -8,7 +8,7 @@ class @ProjectsList
$(".projects-list-filter").keyup ->
terms = $(this).val()
- uiBox = $(this).closest('.panel')
+ uiBox = $(this).closest('.projects-list-holder')
if terms == "" || terms == undefined
uiBox.find(".projects-list li").show()
else
diff --git a/app/assets/stylesheets/pages/dashboard.scss b/app/assets/stylesheets/pages/dashboard.scss
index 9a3b543ad10..c1103a1c2e6 100644
--- a/app/assets/stylesheets/pages/dashboard.scss
+++ b/app/assets/stylesheets/pages/dashboard.scss
@@ -23,41 +23,6 @@
}
}
-.project-row, .group-row {
- padding: 0 !important;
- font-size: 14px;
- line-height: 24px;
-
- a {
- display: block;
- padding: 8px 15px;
- }
-
- .project-name, .group-name {
- font-weight: 500;
- }
-
- .arrow {
- float: right;
- margin: 0;
- font-size: 20px;
- }
-
- .last-activity {
- float: right;
- font-size: 12px;
- color: #AAA;
- display: block;
- .date {
- color: #777;
- }
- }
-}
-
-.project-description {
- overflow: hidden;
-}
-
.project-access-icon {
margin-left: 10px;
float: left;
@@ -73,10 +38,9 @@
float: left;
.avatar {
- margin-top: -8px;
- margin-left: -15px;
@include border-radius(0px);
}
+
.identicon {
line-height: 40px;
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 29d3dbc25eb..1e138651d52 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -316,3 +316,34 @@ table.table.protected-branches-list tr.no-border {
pre.light-well {
border-color: #f1f1f1;
}
+
+.projects-search-form {
+ max-width: 600px;
+ margin: 0 auto;
+ margin-bottom: 20px;
+
+ input {
+ border-color: #BBB;
+ }
+}
+
+.project-row {
+ .project-full-name {
+ font-weight: bold;
+ font-size: 15px;
+ }
+
+ .project-description {
+ color: #888;
+ font-size: 13px;
+
+ p {
+ margin-bottom: 0;
+ color: #888;
+ }
+ }
+}
+
+.my-projects .project-row {
+ padding: 10px 0;
+}
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
index 34f37bca4ad..38a5a9fca08 100644
--- a/app/controllers/admin/abuse_reports_controller.rb
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -4,8 +4,13 @@ class Admin::AbuseReportsController < Admin::ApplicationController
end
def destroy
- AbuseReport.find(params[:id]).destroy
+ abuse_report = AbuseReport.find(params[:id])
- redirect_to admin_abuse_reports_path, notice: 'Report was removed'
+ if params[:remove_user]
+ abuse_report.user.destroy
+ end
+
+ abuse_report.destroy
+ render nothing: true
end
end
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index d2f0c43929f..d745131694b 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -1,6 +1,6 @@
class DashboardController < Dashboard::ApplicationController
before_action :load_projects
- before_action :event_filter, only: :show
+ before_action :event_filter, only: :activity
respond_to :html
@@ -10,13 +10,8 @@ class DashboardController < Dashboard::ApplicationController
respond_to do |format|
format.html
-
- format.json do
- load_events
- pager_json("events/_events", @events.count)
- end
-
format.atom do
+ event_filter
load_events
render layout: false
end
@@ -40,6 +35,19 @@ class DashboardController < Dashboard::ApplicationController
end
end
+ def activity
+ @last_push = current_user.recent_push
+
+ respond_to do |format|
+ format.html
+
+ format.json do
+ load_events
+ pager_json("events/_events", @events.count)
+ end
+ end
+ end
+
protected
def load_projects
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
index 4449721ae38..d3afc658cd6 100644
--- a/app/views/admin/abuse_reports/_abuse_report.html.haml
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -3,7 +3,7 @@
%tr
%td
- if reporter
- = link_to reporter.name, [:admin, reporter]
+ = link_to reporter.name, reporter
- else
(removed)
%td
@@ -12,12 +12,15 @@
= abuse_report.message
%td
- if user
- = link_to user.name, [:admin, user]
+ = link_to user.name, user
- else
(removed)
%td
- if user
- = link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs btn-warning"
- = link_to 'Remove user', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-xs btn-remove"
+ = link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
+ data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-xs btn-remove js-remove-tr"
+
%td
- = link_to 'Remove report', [:admin, abuse_report], method: :delete, class: "btn btn-xs btn-close"
+ - if user
+ = link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs"
+ = link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr"
diff --git a/app/views/admin/abuse_reports/index.html.haml b/app/views/admin/abuse_reports/index.html.haml
index 4a25848f156..2e8746146d1 100644
--- a/app/views/admin/abuse_reports/index.html.haml
+++ b/app/views/admin/abuse_reports/index.html.haml
@@ -9,7 +9,7 @@
%th Reported at
%th Message
%th User
- %th
+ %th Primary action
%th
= render @abuse_reports
= paginate @abuse_reports
diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml
index d676576067c..dc83d5343f2 100644
--- a/app/views/dashboard/_projects.html.haml
+++ b/app/views/dashboard/_projects.html.haml
@@ -1,5 +1,5 @@
-.panel.panel-default
- .panel-heading.clearfix
+.projects-list-holder
+ .projects-search-form
.input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
- if current_user.can_create_project?
@@ -7,4 +7,7 @@
= link_to new_project_path, class: 'btn btn-success' do
New project
- = render 'shared/projects_list', projects: @projects, projects_limit: 20
+ %ul.projects-list.bordered-list.my-projects
+ - @projects.each do |project|
+ %li.project-row
+ = render partial: 'shared/project', locals: { project: project, avatar: true, stars: true }
diff --git a/app/views/dashboard/activity.html.haml b/app/views/dashboard/activity.html.haml
new file mode 100644
index 00000000000..7a5a093add5
--- /dev/null
+++ b/app/views/dashboard/activity.html.haml
@@ -0,0 +1,6 @@
+= content_for :meta_tags do
+ - if current_user
+ = auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity")
+
+%section.activities
+ = render 'activities'
diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml
index 98b8cde4766..027387028b9 100644
--- a/app/views/dashboard/projects/starred.html.haml
+++ b/app/views/dashboard/projects/starred.html.haml
@@ -8,7 +8,7 @@
%section.activities.col-md-8
= render 'dashboard/activities'
%aside.col-md-4
- .panel.panel-default
+ .panel.panel-default.projects-list-holder
.panel-heading.clearfix
.input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml
index a3a32b6932f..4cf2feb9aa6 100644
--- a/app/views/dashboard/show.html.haml
+++ b/app/views/dashboard/show.html.haml
@@ -4,14 +4,10 @@
= render 'dashboard/projects_head'
-- if @projects.any?
- = render 'shared/show_aside'
-
- .dashboard.row
- %section.activities.col-md-8
- = render 'activities'
- %aside.col-md-4
- = render 'sidebar'
+- if @last_push
+ = render "events/event_last_push", event: @last_push
+- if @projects.any?
+ = render 'projects'
- else
= render "zero_authorized_projects"
diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml
index 501412642db..6a0c6cba41b 100644
--- a/app/views/events/_event_last_push.html.haml
+++ b/app/views/events/_event_last_push.html.haml
@@ -9,6 +9,6 @@
#{time_ago_with_tooltip(event.created_at)}
.pull-right
- = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-sm" do
+ = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do
Create Merge Request
%hr
diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml
index 4f8aec1c67e..2ae51a1c8c0 100644
--- a/app/views/groups/_projects.html.haml
+++ b/app/views/groups/_projects.html.haml
@@ -1,4 +1,4 @@
-.panel.panel-default
+.panel.panel-default.projects-list-holder
.panel-heading.clearfix
.input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 8f010196d1a..154fd418399 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -1,9 +1,14 @@
%ul.nav.nav-sidebar
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
- = icon('dashboard fw')
+ = icon('home fw')
%span
Projects
+ = nav_link(path: 'dashboard#activity') do
+ = link_to activity_dashboard_path, title: 'Activity', data: {placement: 'right'} do
+ = icon('dashboard fw')
+ %span
+ Activity
= nav_link(controller: :groups) do
= link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do
= icon('group fw')
diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml
index caed0e69dc8..f99bc9a85eb 100644
--- a/app/views/projects/diffs/_warning.html.haml
+++ b/app/views/projects/diffs/_warning.html.haml
@@ -3,7 +3,7 @@
Too many changes to show.
.pull-right
- unless diff_hard_limit_enabled?
- = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: :html)), class: "btn btn-sm btn-warning"
+ = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: nil)), class: "btn btn-sm btn-warning"
- if current_controller?(:commit) or current_controller?(:merge_requests)
- if current_controller?(:commit)
diff --git a/app/views/shared/_project.html.haml b/app/views/shared/_project.html.haml
index 6bd61455d21..15df97b1333 100644
--- a/app/views/shared/_project.html.haml
+++ b/app/views/shared/_project.html.haml
@@ -3,7 +3,7 @@
- if avatar
.dash-project-avatar
= project_icon(project, alt: '', class: 'avatar project-avatar s40')
- %span.str-truncated
+ %span.str-truncated.project-full-name
%span.namespace-name
- if project.namespace
= project.namespace.human_name
@@ -14,3 +14,7 @@
%span.pull-right.light
%i.fa.fa-star
= project.star_count
+ - if project.description.present?
+ .project-description
+ .str-truncated
+ = markdown(project.description, pipeline: :description)
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index 1d21addece6..916a99bb273 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -4,7 +4,7 @@ class EmailsOnPushWorker
def perform(project_id, recipients, push_data, options = {})
options.symbolize_keys!
options.reverse_merge!(
- send_from_committer_email: false,
+ send_from_committer_email: false,
disable_diffs: false
)
send_from_committer_email = options[:send_from_committer_email]
@@ -16,9 +16,9 @@ class EmailsOnPushWorker
ref = push_data["ref"]
author_id = push_data["user_id"]
- action =
+ action =
if Gitlab::Git.blank_ref?(before_sha)
- :create
+ :create
elsif Gitlab::Git.blank_ref?(after_sha)
:delete
else
@@ -42,17 +42,22 @@ class EmailsOnPushWorker
end
recipients.split(" ").each do |recipient|
- Notify.repository_push_email(
- project_id,
- recipient,
- author_id: author_id,
- ref: ref,
- action: action,
- compare: compare,
- reverse_compare: reverse_compare,
- send_from_committer_email: send_from_committer_email,
- disable_diffs: disable_diffs
- ).deliver
+ begin
+ Notify.repository_push_email(
+ project_id,
+ recipient,
+ author_id: author_id,
+ ref: ref,
+ action: action,
+ compare: compare,
+ reverse_compare: reverse_compare,
+ send_from_committer_email: send_from_committer_email,
+ disable_diffs: disable_diffs
+ ).deliver
+ # These are input errors and won't be corrected even if Sidekiq retries
+ rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e
+ logger.info("Failed to send e-mail for project '#{project.name_with_namespace}' to #{recipient}: #{e}")
+ end
end
ensure
compare = nil
diff --git a/config/routes.rb b/config/routes.rb
index d7307a61ede..8ba439f08b8 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -261,6 +261,7 @@ Gitlab::Application.routes.draw do
member do
get :issues
get :merge_requests
+ get :activity
end
scope module: :dashboard do
diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature
index 1959d327082..392d4235eff 100644
--- a/features/dashboard/dashboard.feature
+++ b/features/dashboard/dashboard.feature
@@ -10,6 +10,10 @@ Feature: Dashboard
Scenario: I should see projects list
Then I should see "New Project" link
Then I should see "Shop" project link
+
+ @javascript
+ Scenario: I should see activity list
+ And I visit dashboard activity page
Then I should see project "Shop" activity feed
Scenario: I should see groups list
@@ -26,12 +30,12 @@ Feature: Dashboard
@javascript
Scenario: I should see User joined Project event
Given user with name "John Doe" joined project "Shop"
- When I visit dashboard page
+ When I visit dashboard activity page
Then I should see "John Doe joined project Shop" event
@javascript
Scenario: I should see User left Project event
Given user with name "John Doe" joined project "Shop"
And user with name "John Doe" left project "Shop"
- When I visit dashboard page
+ When I visit dashboard activity page
Then I should see "John Doe left project Shop" event
diff --git a/features/dashboard/event_filters.feature b/features/dashboard/event_filters.feature
index ec5680caba6..96399ea21a6 100644
--- a/features/dashboard/event_filters.feature
+++ b/features/dashboard/event_filters.feature
@@ -6,7 +6,7 @@ Feature: Event Filters
And this project has push event
And this project has new member event
And this project has merge request event
- And I visit dashboard page
+ And I visit dashboard activity page
@javascript
Scenario: I should see all events
@@ -16,7 +16,7 @@ Feature: Event Filters
@javascript
Scenario: I should see only pushed events
- When I click "push" event filter
+ When I click "push" event filter
Then I should see push event
And I should not see new member event
And I should not see merge request event
@@ -38,11 +38,11 @@ Feature: Event Filters
@javascript
Scenario: I should see only selected events while page reloaded
When I click "push" event filter
- And I visit dashboard page
+ And I visit dashboard activity page
Then I should see push event
And I should not see new member event
When I click "team" event filter
- And I visit dashboard page
+ And I visit dashboard activity page
Then I should see push event
And I should see new member event
And I should not see merge request event
diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature
index c4b206edc95..3ebc8a39aae 100644
--- a/features/project/commits/commits.feature
+++ b/features/project/commits/commits.feature
@@ -41,6 +41,7 @@ Feature: Project Commits
Scenario: I browse big commit
Given I visit big commit page
Then I see big commit warning
+ And I see "Reload with full diff" link
Scenario: I browse a commit with an image
Given I visit a commit with an image that changed
diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb
index e6330ec457e..a8532cc18d8 100644
--- a/features/steps/project/commits/commits.rb
+++ b/features/steps/project/commits/commits.rb
@@ -79,6 +79,12 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
expect(page).to have_content "Too many changes"
end
+ step 'I see "Reload with full diff" link' do
+ link = find_link('Reload with full diff')
+ expect(link[:href]).to end_with('?force_show_diff=true')
+ expect(link[:href]).not_to include('.html')
+ end
+
step 'I visit a commit with an image that changed' do
visit namespace_project_commit_path(@project.namespace, @project, sample_image_commit.id)
end
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index ca8fbb49101..b4deccb6520 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -71,6 +71,10 @@ module SharedPaths
visit dashboard_path
end
+ step 'I visit dashboard activity page' do
+ visit activity_dashboard_path
+ end
+
step 'I visit dashboard projects page' do
visit projects_dashboard_path
end
diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb
new file mode 100644
index 00000000000..3600c771075
--- /dev/null
+++ b/spec/workers/emails_on_push_worker_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe EmailsOnPushWorker do
+ include RepoHelpers
+
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+
+ subject { EmailsOnPushWorker.new }
+
+ before do
+ allow(Project).to receive(:find).and_return(project)
+ end
+
+ describe "#perform" do
+ it "sends mail" do
+ subject.perform(project.id, user.email, data.stringify_keys)
+
+ email = ActionMailer::Base.deliveries.last
+ expect(email.subject).to include('Change some files')
+ expect(email.to).to eq([user.email])
+ end
+
+ it "gracefully handles an input SMTP error" do
+ ActionMailer::Base.deliveries.clear
+ allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError)
+
+ subject.perform(project.id, user.email, data.stringify_keys)
+
+ expect(ActionMailer::Base.deliveries.count).to eq(0)
+ end
+ end
+end