Commit 90b1ecfa authored by Jacob Vosmaer's avatar Jacob Vosmaer

Merge remote-tracking branch 'gitlab.com/master' into gitlab-git-http-server

parents 4027a26e e334ec06
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased) v 8.0.0 (unreleased)
- Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
- Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu) - Prevent too many redirects upon login when home page URL is set to external_url (Stan Hu)
- Improve dropdown positioning on the project home page (Hannes Rosenögger) - Improve dropdown positioning on the project home page (Hannes Rosenögger)
- Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu) - Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
...@@ -22,6 +23,9 @@ v 8.0.0 (unreleased) ...@@ -22,6 +23,9 @@ v 8.0.0 (unreleased)
- Fix 500 error when submit project snippet without body - Fix 500 error when submit project snippet without body
- Improve search page usability - Improve search page usability
- Bring more UI consistency in way how projects, snippets and groups lists are rendered - Bring more UI consistency in way how projects, snippets and groups lists are rendered
- Make all profiles public
- Fixed login failure when extern_uid changes (Joel Koglin)
- Don't notify users without access to the project when they are (accidentally) mentioned in a note.
v 7.14.1 v 7.14.1
- Improve abuse reports management from admin area - Improve abuse reports management from admin area
......
...@@ -38,7 +38,7 @@ gem "browser", '~> 1.0.0' ...@@ -38,7 +38,7 @@ gem "browser", '~> 1.0.0'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
gem "gitlab_git", '~> 7.2.14' gem "gitlab_git", '~> 7.2.15'
# LDAP Auth # LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes # GitLab fork with several improvements to original library. For full list of changes
......
...@@ -274,7 +274,7 @@ GEM ...@@ -274,7 +274,7 @@ GEM
mime-types (~> 1.19) mime-types (~> 1.19)
gitlab_emoji (0.1.0) gitlab_emoji (0.1.0)
gemojione (~> 2.0) gemojione (~> 2.0)
gitlab_git (7.2.14) gitlab_git (7.2.15)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0) gitlab-linguist (~> 3.0)
...@@ -787,7 +787,7 @@ DEPENDENCIES ...@@ -787,7 +787,7 @@ DEPENDENCIES
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-linguist (~> 3.0.1) gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.1) gitlab_emoji (~> 0.1)
gitlab_git (~> 7.2.14) gitlab_git (~> 7.2.15)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.1) gitlab_omniauth-ldap (= 1.2.1)
gollum-lib (~> 4.0.2) gollum-lib (~> 4.0.2)
......
# Applies a syntax highlighting color scheme CSS class to any element with the
# `js-syntax-highlight` class
#
# ### Example Markup
#
# <div class="js-syntax-highlight"></div>
#
$(document).on 'ready page:load', ->
$('.js-syntax-highlight').addClass(gon.user_color_scheme)
...@@ -132,10 +132,6 @@ p.time { ...@@ -132,10 +132,6 @@ p.time {
text-shadow: none; text-shadow: none;
} }
.highlight_word {
background: #fafe3d;
}
.thin_area{ .thin_area{
height: 150px; height: 150px;
} }
......
...@@ -21,6 +21,12 @@ pre.code.highlight.dark, ...@@ -21,6 +21,12 @@ pre.code.highlight.dark,
background-color: #557 !important; background-color: #557 !important;
} }
// Search result highlight
span.highlight_word {
background: #ffe792;
color: #000000;
}
.hll { background-color: #373b41 } .hll { background-color: #373b41 }
.c { color: #969896 } /* Comment */ .c { color: #969896 } /* Comment */
.err { color: #cc6666 } /* Error */ .err { color: #cc6666 } /* Error */
......
...@@ -21,6 +21,12 @@ pre.code.monokai, ...@@ -21,6 +21,12 @@ pre.code.monokai,
background-color: #49483e !important; background-color: #49483e !important;
} }
// Search result highlight
span.highlight_word {
background: #ffe792;
color: #000000;
}
.hll { background-color: #49483e } .hll { background-color: #49483e }
.c { color: #75715e } /* Comment */ .c { color: #75715e } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */ .err { color: #960050; background-color: #1e0010 } /* Error */
......
...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-dark, ...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-dark,
background-color: #174652 !important; background-color: #174652 !important;
} }
// Search result highlight
span.highlight_word {
background: #094554;
}
/* Solarized Dark /* Solarized Dark
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-light, ...@@ -21,6 +21,11 @@ pre.code.highlight.solarized-light,
background-color: #ddd8c5 !important; background-color: #ddd8c5 !important;
} }
// Search result highlight
span.highlight_word {
background: #eee8d5;
}
/* Solarized Light /* Solarized Light
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -21,6 +21,11 @@ pre.code.highlight.white, ...@@ -21,6 +21,11 @@ pre.code.highlight.white,
background-color: #f8eec7 !important; background-color: #f8eec7 !important;
} }
// Search result highlight
span.highlight_word {
background: #fafe3d;
}
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8 }
.c { color: #999988; font-style: italic; } .c { color: #999988; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
......
...@@ -192,11 +192,12 @@ class ApplicationController < ActionController::Base ...@@ -192,11 +192,12 @@ class ApplicationController < ActionController::Base
end end
def add_gon_variables def add_gon_variables
gon.default_issues_tracker = Project.new.default_issue_tracker.to_param
gon.api_version = API::API.version gon.api_version = API::API.version
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s
gon.max_file_size = current_application_settings.max_attachment_size; gon.default_issues_tracker = Project.new.default_issue_tracker.to_param
gon.max_file_size = current_application_settings.max_attachment_size
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
if current_user if current_user
gon.current_user_id = current_user.id gon.current_user_id = current_user.id
......
...@@ -51,10 +51,6 @@ class UsersController < ApplicationController ...@@ -51,10 +51,6 @@ class UsersController < ApplicationController
def set_user def set_user
@user = User.find_by_username!(params[:username]) @user = User.find_by_username!(params[:username])
unless current_user || @user.public_profile?
return authenticate_user!
end
end end
def authorized_projects_ids def authorized_projects_ids
......
...@@ -58,7 +58,7 @@ module GitlabMarkdownHelper ...@@ -58,7 +58,7 @@ module GitlabMarkdownHelper
@options = options @options = options
# see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch
rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, options) rend = Redcarpet::Render::GitlabHTML.new(self, options)
# see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use # see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@markdown = Redcarpet::Markdown.new(rend, MARKDOWN_OPTIONS) @markdown = Redcarpet::Markdown.new(rend, MARKDOWN_OPTIONS)
......
# Helper methods for per-User preferences # Helper methods for per-User preferences
module PreferencesHelper module PreferencesHelper
COLOR_SCHEMES = {
1 => 'white',
2 => 'dark',
3 => 'solarized-light',
4 => 'solarized-dark',
5 => 'monokai',
}
COLOR_SCHEMES.default = 'white'
# Helper method to access the COLOR_SCHEMES
#
# The keys are the `color_scheme_ids`
# The values are the `name` of the scheme.
#
# The preview images are `name-scheme-preview.png`
# The stylesheets should use the css class `.name`
def color_schemes
COLOR_SCHEMES.freeze
end
# Maps `dashboard` values to more user-friendly option text # Maps `dashboard` values to more user-friendly option text
DASHBOARD_CHOICES = { DASHBOARD_CHOICES = {
projects: 'Your Projects (default)', projects: 'Your Projects (default)',
...@@ -50,12 +30,11 @@ module PreferencesHelper ...@@ -50,12 +30,11 @@ module PreferencesHelper
end end
def user_application_theme def user_application_theme
theme = Gitlab::Themes.by_id(current_user.try(:theme_id)) Gitlab::Themes.for_user(current_user).css_class
theme.css_class
end end
def user_color_scheme_class def user_color_scheme
COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user) Gitlab::ColorSchemes.for_user(current_user).css_class
end end
def prefer_readme? def prefer_readme?
......
...@@ -104,7 +104,7 @@ class User < ActiveRecord::Base ...@@ -104,7 +104,7 @@ class User < ActiveRecord::Base
# Profile # Profile
has_many :keys, dependent: :destroy has_many :keys, dependent: :destroy
has_many :emails, dependent: :destroy has_many :emails, dependent: :destroy
has_many :identities, dependent: :destroy has_many :identities, dependent: :destroy, autosave: true
# Groups # Groups
has_many :members, dependent: :destroy has_many :members, dependent: :destroy
...@@ -637,10 +637,6 @@ class User < ActiveRecord::Base ...@@ -637,10 +637,6 @@ class User < ActiveRecord::Base
email.start_with?('temp-email-for-oauth') email.start_with?('temp-email-for-oauth')
end end
def public_profile?
authorized_projects.public_only.any?
end
def avatar_url(size = nil) def avatar_url(size = nil)
if avatar.present? if avatar.present?
[gitlab_config.url, avatar.url].join [gitlab_config.url, avatar.url].join
......
...@@ -107,12 +107,17 @@ class NotificationService ...@@ -107,12 +107,17 @@ class NotificationService
recipients = [] recipients = []
mentioned_users = note.mentioned_users
mentioned_users.select! do |user|
user.can?(:read_project, note.project)
end
# Add all users participating in the thread (author, assignee, comment authors) # Add all users participating in the thread (author, assignee, comment authors)
participants = participants =
if target.respond_to?(:participants) if target.respond_to?(:participants)
target.participants(note.author) target.participants(note.author)
else else
note.mentioned_users mentioned_users
end end
recipients = recipients.concat(participants) recipients = recipients.concat(participants)
...@@ -120,8 +125,8 @@ class NotificationService ...@@ -120,8 +125,8 @@ class NotificationService
recipients = add_project_watchers(recipients, note.project) recipients = add_project_watchers(recipients, note.project)
# Reject users with Mention notification level, except those mentioned in _this_ note. # Reject users with Mention notification level, except those mentioned in _this_ note.
recipients = reject_mention_users(recipients - note.mentioned_users, note.project) recipients = reject_mention_users(recipients - mentioned_users, note.project)
recipients = recipients + note.mentioned_users recipients = recipients + mentioned_users
recipients = reject_muted_users(recipients, note.project) recipients = reject_muted_users(recipients, note.project)
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
.panel-heading .panel-heading
Syntax highlighting theme Syntax highlighting theme
.panel-body .panel-body
- color_schemes.each do |color_scheme_id, color_scheme| - Gitlab::ColorSchemes.each do |scheme|
= label_tag do = label_tag do
.preview= image_tag "#{color_scheme}-scheme-preview.png" .preview= image_tag "#{scheme.css_class}-scheme-preview.png"
= f.radio_button :color_scheme_id, color_scheme_id = f.radio_button :color_scheme_id, scheme.id
= color_scheme.tr('-_', ' ').titleize = scheme.name
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
......
...@@ -100,11 +100,6 @@ ...@@ -100,11 +100,6 @@
%hr %hr
= link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" = link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar"
- if @user.public_profile?
.alert.alert-info
%h4 Public profile
%p Your profile is publicly visible because you joined public project(s)
.row .row
.col-md-7 .col-md-7
......
...@@ -7,4 +7,4 @@ ...@@ -7,4 +7,4 @@
%strong %strong
= blob.filename = blob.filename
.file-content.code.term .file-content.code.term
= render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, user_color_scheme_class: 'white' = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
.nothing-here-block Empty file .nothing-here-block Empty file
- else - else
.file-content.code .file-content.code
%div.highlighted-data{class: user_color_scheme_class} %div.highlighted-data{ class: user_color_scheme }
.line-numbers .line-numbers
- snippet_blob[:snippet_chunks].each do |snippet| - snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty? - unless snippet[:data].empty?
......
...@@ -7,4 +7,4 @@ ...@@ -7,4 +7,4 @@
%strong %strong
= wiki_blob.filename = wiki_blob.filename
.file-content.code.term .file-content.code.term
= render 'shared/file_highlight', blob: wiki_blob, first_line_number: wiki_blob.startline, user_color_scheme_class: 'white' = render 'shared/file_highlight', blob: wiki_blob, first_line_number: wiki_blob.startline
.file-content.code{class: user_color_scheme_class} .file-content.code.js-syntax-highlight{ class: user_color_scheme }
.line-numbers .line-numbers
- if blob.data.present? - if blob.data.present?
- blob.data.lines.each_index do |index| - blob.data.lines.each_index do |index|
......
class DeduplicateUserIdentities < ActiveRecord::Migration
def change
execute 'DROP TABLE IF EXISTS tt_migration_DeduplicateUserIdentities;'
execute 'CREATE TEMPORARY TABLE tt_migration_DeduplicateUserIdentities AS SELECT id,provider,user_id FROM identities;'
execute 'DELETE FROM identities WHERE id NOT IN ( SELECT MIN(id) FROM tt_migration_DeduplicateUserIdentities GROUP BY user_id, provider);'
execute 'DROP TABLE IF EXISTS tt_migration_DeduplicateUserIdentities;'
end
def down
# This is an irreversible migration;
# If someone is trying to rollback for other reasons, we should not throw an Exception.
# raise ActiveRecord::IrreversibleMigration
end
end
...@@ -17,4 +17,4 @@ If you want to import from a GitHub Enterprise instance, you need to use GitLab ...@@ -17,4 +17,4 @@ If you want to import from a GitHub Enterprise instance, you need to use GitLab
* To import a project, you can simple click "Add". The importer will import your repository and issues. Once the importer is done, a new GitLab project will be created with your imported data. * To import a project, you can simple click "Add". The importer will import your repository and issues. Once the importer is done, a new GitLab project will be created with your imported data.
### Note ### Note
When you import your projects from GitHub, it is not possible to keep your labels and milestones and issue numbers won't match. We are working on improving this in the near future. When you import your projects from GitHub, it is not possible to keep your labels and milestones. We are working on improving this in the near future.
...@@ -14,11 +14,6 @@ Feature: User ...@@ -14,11 +14,6 @@ Feature: User
And I should not see project "Internal" And I should not see project "Internal"
And I should see project "Community" And I should see project "Community"
Scenario: I visit user "John Doe" page while not signed in when he is not authorized to a public project
Given "John Doe" owns internal project "Internal"
When I visit user "John Doe" page
Then I should be redirected to sign in page
# Signed in as someone else # Signed in as someone else
Scenario: I visit user "John Doe" page while signed in as someone else when he owns a public project Scenario: I visit user "John Doe" page while signed in as someone else when he owns a public project
......
module Gitlab
# Module containing GitLab's syntax color scheme definitions and helper
# methods for accessing them.
module ColorSchemes
# Struct class representing a single Scheme
Scheme = Struct.new(:id, :name, :css_class)
SCHEMES = [
Scheme.new(1, 'White', 'white'),
Scheme.new(2, 'Dark', 'dark'),
Scheme.new(3, 'Solarized Light', 'solarized-light'),
Scheme.new(4, 'Solarized Dark', 'solarized-dark'),
Scheme.new(5, 'Monokai', 'monokai')
].freeze
# Convenience method to get a space-separated String of all the color scheme
# classes that might be applied to a code block.
#
# Returns a String
def self.body_classes
SCHEMES.collect(&:css_class).uniq.join(' ')
end
# Get a Scheme by its ID
#
# If the ID is invalid, returns the default Scheme.
#
# id - Integer ID
#
# Returns a Scheme
def self.by_id(id)
SCHEMES.detect { |s| s.id == id } || default
end
# Returns the number of defined Schemes
def self.count
SCHEMES.size
end
# Get the default Scheme
#
# Returns a Scheme
def self.default
by_id(1)
end
# Iterate through each Scheme
#
# Yields the Scheme object
def self.each(&block)
SCHEMES.each(&block)
end
# Get the Scheme for the specified user, or the default
#
# user - User record
#
# Returns a Scheme
def self.for_user(user)
if user
by_id(user.color_scheme_id)
else
default
end
end
end
end
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
key = :current_application_settings key = :current_application_settings
RequestStore.store[key] ||= begin RequestStore.store[key] ||= begin
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('application_settings') if ActiveRecord::Base.connection.active? && ActiveRecord::Base.connection.table_exists?('application_settings')
ApplicationSetting.current || ApplicationSetting.create_from_defaults ApplicationSetting.current || ApplicationSetting.create_from_defaults
else else
fake_application_settings fake_application_settings
......
...@@ -44,9 +44,14 @@ module Gitlab ...@@ -44,9 +44,14 @@ module Gitlab
gl_user.skip_reconfirmation! gl_user.skip_reconfirmation!
gl_user.email = auth_hash.email gl_user.email = auth_hash.email
# Build new identity only if we dont have have same one # find_or_initialize_by doesn't update `gl_user.identities`, and isn't autosaved.
gl_user.identities.find_or_initialize_by(provider: auth_hash.provider, identity = gl_user.identities.find { |identity| identity.provider == auth_hash.provider }
extern_uid: auth_hash.uid) identity ||= gl_user.identities.build(provider: auth_hash.provider)
# For a new user set extern_uid to the LDAP DN
# For an existing user with matching email but changed DN, update the DN.
# For an existing user with no change in DN, this line changes nothing.
identity.extern_uid = auth_hash.uid
gl_user gl_user
end end
......
...@@ -37,6 +37,11 @@ module Gitlab ...@@ -37,6 +37,11 @@ module Gitlab
THEMES.detect { |t| t.id == id } || default THEMES.detect { |t| t.id == id } || default
end end
# Returns the number of defined Themes
def self.count
THEMES.size
end
# Get the default Theme # Get the default Theme
# #
# Returns a Theme # Returns a Theme
...@@ -51,6 +56,19 @@ module Gitlab ...@@ -51,6 +56,19 @@ module Gitlab
THEMES.each(&block) THEMES.each(&block)
end end
# Get the Theme for the specified user, or the default
#
# user - User record
#
# Returns a Theme
def self.for_user(user)
if user
by_id(user.theme_id)
else
default
end
end
private private
def self.default_id def self.default_id
......
...@@ -4,9 +4,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML ...@@ -4,9 +4,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
attr_reader :template attr_reader :template
alias_method :h, :template alias_method :h, :template
def initialize(template, color_scheme, options = {}) def initialize(template, options = {})
@template = template @template = template
@color_scheme = color_scheme
@options = options.dup @options = options.dup
@options.reverse_merge!( @options.reverse_merge!(
...@@ -35,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML ...@@ -35,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
end end
formatter = Rouge::Formatters::HTMLGitlab.new( formatter = Rouge::Formatters::HTMLGitlab.new(
cssclass: "code highlight #{@color_scheme} #{lexer.tag}" cssclass: "code highlight js-syntax-highlight #{lexer.tag}"
) )
formatter.format(lexer.lex(code)) formatter.format(lexer.lex(code))
end end
......
...@@ -64,8 +64,8 @@ describe 'GitLab Markdown', feature: true do ...@@ -64,8 +64,8 @@ describe 'GitLab Markdown', feature: true do
it 'parses fenced code blocks' do it 'parses fenced code blocks' do
aggregate_failures do aggregate_failures do
expect(doc).to have_selector('pre.code.highlight.white.c') expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.c')
expect(doc).to have_selector('pre.code.highlight.white.python') expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.python')
end end
end end
...@@ -224,8 +224,4 @@ describe 'GitLab Markdown', feature: true do ...@@ -224,8 +224,4 @@ describe 'GitLab Markdown', feature: true do
def current_user def current_user
@feat.user @feat.user
end end
def user_color_scheme_class
:white
end
end end
...@@ -28,8 +28,7 @@ describe EventsHelper do ...@@ -28,8 +28,7 @@ describe EventsHelper do
it 'should display the first line of a code block' do it 'should display the first line of a code block' do
input = "```\nCode block\nwith two lines\n```" input = "```\nCode block\nwith two lines\n```"
expected = '<pre class="code highlight white plaintext"><code>' \ expected = %r{<pre.+><code>Code block\.\.\.</code></pre>}
'Code block...</code></pre>'
expect(event_note(input)).to match(expected) expect(event_note(input)).to match(expected)
end end
...@@ -55,7 +54,7 @@ describe EventsHelper do ...@@ -55,7 +54,7 @@ describe EventsHelper do
it 'should preserve code color scheme' do it 'should preserve code color scheme' do
input = "```ruby\ndef test\n 'hello world'\nend\n```" input = "```ruby\ndef test\n 'hello world'\nend\n```"
expected = '<pre class="code highlight white ruby">' \ expected = '<pre class="code highlight js-syntax-highlight ruby">' \
"<code><span class=\"k\">def</span> <span class=\"nf\">test</span>\n" \ "<code><span class=\"k\">def</span> <span class=\"nf\">test</span>\n" \
" <span class=\"s1\">\'hello world\'</span>\n" \ " <span class=\"s1\">\'hello world\'</span>\n" \
"<span class=\"k\">end</span>" \ "<span class=\"k\">end</span>" \
......
require 'spec_helper' require 'spec_helper'
describe PreferencesHelper do describe PreferencesHelper do
describe 'dashboard_choices' do
it 'raises an exception when defined choices may be missing' do
expect(User).to receive(:dashboards).and_return(foo: 'foo')
expect { helper.dashboard_choices }.to raise_error(RuntimeError)
end
it 'raises an exception when defined choices may be using the wrong key' do
expect(User).to receive(:dashboards).and_return(foo: 'foo', bar: 'bar')
expect { helper.dashboard_choices }.to raise_error(KeyError)
end
it 'provides better option descriptions' do
expect(helper.dashboard_choices).to match_array [
['Your Projects (default)', 'projects'],
['Starred Projects', 'stars']
]
end
end
describe 'user_application_theme' do describe 'user_application_theme' do
context 'with a user' do context 'with a user' do
it "returns user's theme's css_class" do it "returns user's theme's css_class" do
user = double('user', theme_id: 3) stub_user(theme_id: 3)
allow(self).to receive(:current_user).and_return(user)
expect(user_application_theme).to eq 'ui_green' expect(helper.user_application_theme).to eq 'ui_green'
end end
it 'returns the default when id is invalid' do it 'returns the default when id is invalid' do
user = double('user', theme_id: Gitlab::Themes::THEMES.size + 5) stub_user(theme_id: Gitlab::Themes.count + 5)
allow(Gitlab.config.gitlab).to receive(:default_theme).and_return(2) allow(Gitlab.config.gitlab).to receive(:default_theme).and_return(2)
allow(self).to receive(:current_user).and_return(user)
expect(user_application_theme).to eq 'ui_charcoal' expect(helper.user_application_theme).to eq 'ui_charcoal'
end end
end end
context 'without a user' do context 'without a user' do
before do
allow(self).to receive(:current_user).and_return(nil)
end
it 'returns the default theme' do it 'returns the default theme' do
expect(user_application_theme).to eq Gitlab::Themes.default.css_class stub_user
expect(helper.user_application_theme).to eq Gitlab::Themes.default.css_class
end end
end end
end end
describe 'dashboard_choices' do describe 'user_color_scheme' do
it 'raises an exception when defined choices may be missing' do context 'with a user' do
expect(User).to receive(:dashboards).and_return(foo: 'foo') it "returns user's scheme's css_class" do
expect { dashboard_choices }.to raise_error(RuntimeError) allow(helper).to receive(:current_user).
end and_return(double(color_scheme_id: 3))
it 'raises an exception when defined choices may be using the wrong key' do expect(helper.user_color_scheme).to eq 'solarized-light'
expect(User).to receive(:dashboards).and_return(foo: 'foo', bar: 'bar')
expect { dashboard_choices }.to raise_error(KeyError)
end end
it 'provides better option descriptions' do it 'returns the default when id is invalid' do
expect(dashboard_choices).to match_array [ allow(helper).to receive(:current_user).
['Your Projects (default)', 'projects'], and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5))
['Starred Projects', 'stars']
]
end end
end end
describe 'user_color_scheme_class' do context 'without a user' do
context 'with current_user is nil' do it 'returns the default theme' do
it 'should return a string' do stub_user
allow(self).to receive(:current_user).and_return(nil)
expect(user_color_scheme_class).to be_kind_of(String)
end
end
context 'with a current_user' do expect(helper.user_color_scheme).
(1..5).each do |color_scheme_id| to eq Gitlab::ColorSchemes.default.css_class
context "with color_scheme_id == #{color_scheme_id}" do
it 'should return a string' do
current_user = double(color_scheme_id: color_scheme_id)
allow(self).to receive(:current_user).and_return(current_user)
expect(user_color_scheme_class).to be_kind_of(String)
end end
end end
end end
def stub_user(messages = {})
if messages.empty?
allow(helper).to receive(:current_user).and_return(nil)
else
allow(helper).to receive(:current_user).
and_return(double('user', messages))
end end
end end
end end
require 'spec_helper'
describe Gitlab::ColorSchemes do
describe '.body_classes' do
it 'returns a space-separated list of class names' do
css = described_class.body_classes
expect(css).to include('white')
expect(css).to include(' solarized-light ')
expect(css).to include(' monokai')
end
end
describe '.by_id' do
it 'returns a scheme by its ID' do
expect(described_class.by_id(1).name).to eq 'White'
expect(described_class.by_id(4).name).to eq 'Solarized Dark'
end
end
describe '.default' do
it 'returns the default scheme' do
expect(described_class.default.id).to eq 1
end
end
describe '.each' do
it 'passes the block to the SCHEMES Array' do
ids = []
described_class.each { |scheme| ids << scheme.id }
expect(ids).not_to be_empty
end
end
describe '.for_user' do
it 'returns default when user is nil' do
expect(described_class.for_user(nil).id).to eq 1
end
it "returns user's preferred color scheme" do
user = double(color_scheme_id: 5)
expect(described_class.for_user(user).id).to eq 5
end
end
end
...@@ -47,6 +47,28 @@ describe Gitlab::LDAP::User do ...@@ -47,6 +47,28 @@ describe Gitlab::LDAP::User do
expect(existing_user.ldap_identity.provider).to eql 'ldapmain' expect(existing_user.ldap_identity.provider).to eql 'ldapmain'
end end
it 'connects to existing ldap user if the extern_uid changes' do
existing_user = create(:omniauth_user, email: 'john@example.com', extern_uid: 'old-uid', provider: 'ldapmain')
expect{ ldap_user.save }.not_to change{ User.count }
existing_user.reload
expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid'
expect(existing_user.ldap_identity.provider).to eql 'ldapmain'
expect(existing_user.id).to eql ldap_user.gl_user.id
end
it 'maintains an identity per provider' do
existing_user = create(:omniauth_user, email: 'john@example.com', provider: 'twitter')
expect(existing_user.identities.count).to eql(1)
ldap_user.save
expect(ldap_user.gl_user.identities.count).to eql(2)
# Expect that find_by provider only returns a single instance of an identity and not an Enumerable
expect(ldap_user.gl_user.identities.find_by(provider: 'twitter')).to be_instance_of Identity
expect(ldap_user.gl_user.identities.find_by(provider: auth_hash.provider)).to be_instance_of Identity
end
it "creates a new user if not found" do it "creates a new user if not found" do
expect{ ldap_user.save }.to change{ User.count }.by(1) expect{ ldap_user.save }.to change{ User.count }.by(1)
end end
......
...@@ -43,9 +43,6 @@ describe Gitlab::Themes do ...@@ -43,9 +43,6 @@ describe Gitlab::Themes do
ids = [] ids = []
described_class.each { |theme| ids << theme.id } described_class.each { |theme| ids << theme.id }
expect(ids).not_to be_empty expect(ids).not_to be_empty
# TODO (rspeicher): RSpec 3.x
# expect(described_class.each).to yield_with_arg(described_class::Theme)
end end
end end
end end
...@@ -31,13 +31,16 @@ describe NotificationService do ...@@ -31,13 +31,16 @@ describe NotificationService do
describe 'Notes' do describe 'Notes' do
context 'issue note' do context 'issue note' do
let(:project) { create(:empty_project, :public) } let(:project) { create(:empty_project, :private) }
let(:issue) { create(:issue, project: project, assignee: create(:user)) } let(:issue) { create(:issue, project: project, assignee: create(:user)) }
let(:mentioned_issue) { create(:issue, assignee: issue.assignee) } let(:mentioned_issue) { create(:issue, assignee: issue.assignee) }
let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') } let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced, @outsider also') }
before do before do
build_team(note.project) build_team(note.project)
project.team << [issue.author, :master]
project.team << [issue.assignee, :master]
project.team << [note.author, :master]
end end
describe :new_note do describe :new_note do
...@@ -53,6 +56,7 @@ describe NotificationService do ...@@ -53,6 +56,7 @@ describe NotificationService do
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
should_not_email(@u_disabled.id) should_not_email(@u_disabled.id)
should_not_email(@unsubscriber.id) should_not_email(@unsubscriber.id)
should_not_email(@u_outsider_mentioned)
notification.new_note(note) notification.new_note(note)
end end
...@@ -444,12 +448,15 @@ describe NotificationService do ...@@ -444,12 +448,15 @@ describe NotificationService do
@u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_MENTION) @u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_MENTION)
@u_committer = create(:user, username: 'committer') @u_committer = create(:user, username: 'committer')
@u_not_mentioned = create(:user, username: 'regular', notification_level: Notification::N_PARTICIPATING) @u_not_mentioned = create(:user, username: 'regular', notification_level: Notification::N_PARTICIPATING)
@u_outsider_mentioned = create(:user, username: 'outsider')
project.team << [@u_watcher, :master] project.team << [@u_watcher, :master]
project.team << [@u_participating, :master] project.team << [@u_participating, :master]
project.team << [@u_participant_mentioned, :master]
project.team << [@u_disabled, :master] project.team << [@u_disabled, :master]
project.team << [@u_mentioned, :master] project.team << [@u_mentioned, :master]
project.team << [@u_committer, :master] project.team << [@u_committer, :master]
project.team << [@u_not_mentioned, :master]
end end
def add_users_with_subscription(project, issuable) def add_users_with_subscription(project, issuable)
......
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