Merge remote-tracking branch 'gitlab.com/master' into gitlab-git-http-server
This commit is contained in:
commit
90b1ecfa01
37 changed files with 316 additions and 134 deletions
|
@ -1,6 +1,7 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
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)
|
||||
- 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)
|
||||
|
@ -22,6 +23,9 @@ v 8.0.0 (unreleased)
|
|||
- Fix 500 error when submit project snippet without body
|
||||
- Improve search page usability
|
||||
- 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
|
||||
- Improve abuse reports management from admin area
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -38,7 +38,7 @@ gem "browser", '~> 1.0.0'
|
|||
|
||||
# Extracting information from a git repository
|
||||
# Provide access to Gitlab::Git library
|
||||
gem "gitlab_git", '~> 7.2.14'
|
||||
gem "gitlab_git", '~> 7.2.15'
|
||||
|
||||
# LDAP Auth
|
||||
# GitLab fork with several improvements to original library. For full list of changes
|
||||
|
|
|
@ -274,7 +274,7 @@ GEM
|
|||
mime-types (~> 1.19)
|
||||
gitlab_emoji (0.1.0)
|
||||
gemojione (~> 2.0)
|
||||
gitlab_git (7.2.14)
|
||||
gitlab_git (7.2.15)
|
||||
activesupport (~> 4.0)
|
||||
charlock_holmes (~> 0.6)
|
||||
gitlab-linguist (~> 3.0)
|
||||
|
@ -787,7 +787,7 @@ DEPENDENCIES
|
|||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab-linguist (~> 3.0.1)
|
||||
gitlab_emoji (~> 0.1)
|
||||
gitlab_git (~> 7.2.14)
|
||||
gitlab_git (~> 7.2.15)
|
||||
gitlab_meta (= 7.0)
|
||||
gitlab_omniauth-ldap (= 1.2.1)
|
||||
gollum-lib (~> 4.0.2)
|
||||
|
|
9
app/assets/javascripts/syntax_highlight.coffee
Normal file
9
app/assets/javascripts/syntax_highlight.coffee
Normal file
|
@ -0,0 +1,9 @@
|
|||
# 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 {
|
|||
text-shadow: none;
|
||||
}
|
||||
|
||||
.highlight_word {
|
||||
background: #fafe3d;
|
||||
}
|
||||
|
||||
.thin_area{
|
||||
height: 150px;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,12 @@ pre.code.highlight.dark,
|
|||
background-color: #557 !important;
|
||||
}
|
||||
|
||||
// Search result highlight
|
||||
span.highlight_word {
|
||||
background: #ffe792;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.hll { background-color: #373b41 }
|
||||
.c { color: #969896 } /* Comment */
|
||||
.err { color: #cc6666 } /* Error */
|
||||
|
|
|
@ -21,6 +21,12 @@ pre.code.monokai,
|
|||
background-color: #49483e !important;
|
||||
}
|
||||
|
||||
// Search result highlight
|
||||
span.highlight_word {
|
||||
background: #ffe792;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.hll { background-color: #49483e }
|
||||
.c { color: #75715e } /* Comment */
|
||||
.err { color: #960050; background-color: #1e0010 } /* Error */
|
||||
|
|
|
@ -21,6 +21,11 @@ pre.code.highlight.solarized-dark,
|
|||
background-color: #174652 !important;
|
||||
}
|
||||
|
||||
// Search result highlight
|
||||
span.highlight_word {
|
||||
background: #094554;
|
||||
}
|
||||
|
||||
/* Solarized Dark
|
||||
|
||||
For use with Jekyll and Pygments
|
||||
|
|
|
@ -21,6 +21,11 @@ pre.code.highlight.solarized-light,
|
|||
background-color: #ddd8c5 !important;
|
||||
}
|
||||
|
||||
// Search result highlight
|
||||
span.highlight_word {
|
||||
background: #eee8d5;
|
||||
}
|
||||
|
||||
/* Solarized Light
|
||||
|
||||
For use with Jekyll and Pygments
|
||||
|
|
|
@ -21,6 +21,11 @@ pre.code.highlight.white,
|
|||
background-color: #f8eec7 !important;
|
||||
}
|
||||
|
||||
// Search result highlight
|
||||
span.highlight_word {
|
||||
background: #fafe3d;
|
||||
}
|
||||
|
||||
.hll { background-color: #f8f8f8 }
|
||||
.c { color: #999988; font-style: italic; }
|
||||
.err { color: #a61717; background-color: #e3d2d2; }
|
||||
|
|
|
@ -192,11 +192,12 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def add_gon_variables
|
||||
gon.api_version = API::API.version
|
||||
gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s
|
||||
gon.default_issues_tracker = Project.new.default_issue_tracker.to_param
|
||||
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.max_file_size = current_application_settings.max_attachment_size;
|
||||
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
|
||||
gon.current_user_id = current_user.id
|
||||
|
|
|
@ -51,10 +51,6 @@ class UsersController < ApplicationController
|
|||
|
||||
def set_user
|
||||
@user = User.find_by_username!(params[:username])
|
||||
|
||||
unless current_user || @user.public_profile?
|
||||
return authenticate_user!
|
||||
end
|
||||
end
|
||||
|
||||
def authorized_projects_ids
|
||||
|
|
|
@ -58,7 +58,7 @@ module GitlabMarkdownHelper
|
|||
@options = options
|
||||
|
||||
# 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
|
||||
@markdown = Redcarpet::Markdown.new(rend, MARKDOWN_OPTIONS)
|
||||
|
|
|
@ -1,25 +1,5 @@
|
|||
# Helper methods for per-User preferences
|
||||
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
|
||||
DASHBOARD_CHOICES = {
|
||||
projects: 'Your Projects (default)',
|
||||
|
@ -50,12 +30,11 @@ module PreferencesHelper
|
|||
end
|
||||
|
||||
def user_application_theme
|
||||
theme = Gitlab::Themes.by_id(current_user.try(:theme_id))
|
||||
theme.css_class
|
||||
Gitlab::Themes.for_user(current_user).css_class
|
||||
end
|
||||
|
||||
def user_color_scheme_class
|
||||
COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user)
|
||||
def user_color_scheme
|
||||
Gitlab::ColorSchemes.for_user(current_user).css_class
|
||||
end
|
||||
|
||||
def prefer_readme?
|
||||
|
|
|
@ -104,7 +104,7 @@ class User < ActiveRecord::Base
|
|||
# Profile
|
||||
has_many :keys, dependent: :destroy
|
||||
has_many :emails, dependent: :destroy
|
||||
has_many :identities, dependent: :destroy
|
||||
has_many :identities, dependent: :destroy, autosave: true
|
||||
|
||||
# Groups
|
||||
has_many :members, dependent: :destroy
|
||||
|
@ -637,10 +637,6 @@ class User < ActiveRecord::Base
|
|||
email.start_with?('temp-email-for-oauth')
|
||||
end
|
||||
|
||||
def public_profile?
|
||||
authorized_projects.public_only.any?
|
||||
end
|
||||
|
||||
def avatar_url(size = nil)
|
||||
if avatar.present?
|
||||
[gitlab_config.url, avatar.url].join
|
||||
|
|
|
@ -107,12 +107,17 @@ class NotificationService
|
|||
|
||||
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)
|
||||
participants =
|
||||
if target.respond_to?(:participants)
|
||||
target.participants(note.author)
|
||||
else
|
||||
note.mentioned_users
|
||||
mentioned_users
|
||||
end
|
||||
recipients = recipients.concat(participants)
|
||||
|
||||
|
@ -120,8 +125,8 @@ class NotificationService
|
|||
recipients = add_project_watchers(recipients, note.project)
|
||||
|
||||
# Reject users with Mention notification level, except those mentioned in _this_ note.
|
||||
recipients = reject_mention_users(recipients - note.mentioned_users, note.project)
|
||||
recipients = recipients + note.mentioned_users
|
||||
recipients = reject_mention_users(recipients - mentioned_users, note.project)
|
||||
recipients = recipients + mentioned_users
|
||||
|
||||
recipients = reject_muted_users(recipients, note.project)
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
.panel-heading
|
||||
Syntax highlighting theme
|
||||
.panel-body
|
||||
- color_schemes.each do |color_scheme_id, color_scheme|
|
||||
- Gitlab::ColorSchemes.each do |scheme|
|
||||
= label_tag do
|
||||
.preview= image_tag "#{color_scheme}-scheme-preview.png"
|
||||
= f.radio_button :color_scheme_id, color_scheme_id
|
||||
= color_scheme.tr('-_', ' ').titleize
|
||||
.preview= image_tag "#{scheme.css_class}-scheme-preview.png"
|
||||
= f.radio_button :color_scheme_id, scheme.id
|
||||
= scheme.name
|
||||
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
|
|
|
@ -100,11 +100,6 @@
|
|||
%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"
|
||||
|
||||
- if @user.public_profile?
|
||||
.alert.alert-info
|
||||
%h4 Public profile
|
||||
%p Your profile is publicly visible because you joined public project(s)
|
||||
|
||||
|
||||
.row
|
||||
.col-md-7
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
%strong
|
||||
= blob.filename
|
||||
.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 @@
|
|||
.nothing-here-block Empty file
|
||||
- else
|
||||
.file-content.code
|
||||
%div.highlighted-data{class: user_color_scheme_class}
|
||||
%div.highlighted-data{ class: user_color_scheme }
|
||||
.line-numbers
|
||||
- snippet_blob[:snippet_chunks].each do |snippet|
|
||||
- unless snippet[:data].empty?
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
%strong
|
||||
= wiki_blob.filename
|
||||
.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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.file-content.code{class: user_color_scheme_class}
|
||||
.file-content.code.js-syntax-highlight{ class: user_color_scheme }
|
||||
.line-numbers
|
||||
- if blob.data.present?
|
||||
- blob.data.lines.each_index do |index|
|
||||
|
|
14
db/migrate/20150817163600_deduplicate_user_identities.rb
Normal file
14
db/migrate/20150817163600_deduplicate_user_identities.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
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
|
|||
* 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
|
||||
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
|
|||
And I should not see project "Internal"
|
||||
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
|
||||
|
||||
Scenario: I visit user "John Doe" page while signed in as someone else when he owns a public project
|
||||
|
|
67
lib/gitlab/color_schemes.rb
Normal file
67
lib/gitlab/color_schemes.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
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
|
|||
key = :current_application_settings
|
||||
|
||||
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
|
||||
else
|
||||
fake_application_settings
|
||||
|
|
|
@ -44,9 +44,14 @@ module Gitlab
|
|||
gl_user.skip_reconfirmation!
|
||||
gl_user.email = auth_hash.email
|
||||
|
||||
# Build new identity only if we dont have have same one
|
||||
gl_user.identities.find_or_initialize_by(provider: auth_hash.provider,
|
||||
extern_uid: auth_hash.uid)
|
||||
# find_or_initialize_by doesn't update `gl_user.identities`, and isn't autosaved.
|
||||
identity = gl_user.identities.find { |identity| identity.provider == auth_hash.provider }
|
||||
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
|
||||
end
|
||||
|
|
|
@ -37,6 +37,11 @@ module Gitlab
|
|||
THEMES.detect { |t| t.id == id } || default
|
||||
end
|
||||
|
||||
# Returns the number of defined Themes
|
||||
def self.count
|
||||
THEMES.size
|
||||
end
|
||||
|
||||
# Get the default Theme
|
||||
#
|
||||
# Returns a Theme
|
||||
|
@ -51,6 +56,19 @@ module Gitlab
|
|||
THEMES.each(&block)
|
||||
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
|
||||
|
||||
def self.default_id
|
||||
|
|
|
@ -4,9 +4,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
|
|||
attr_reader :template
|
||||
alias_method :h, :template
|
||||
|
||||
def initialize(template, color_scheme, options = {})
|
||||
def initialize(template, options = {})
|
||||
@template = template
|
||||
@color_scheme = color_scheme
|
||||
@options = options.dup
|
||||
|
||||
@options.reverse_merge!(
|
||||
|
@ -35,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
|
|||
end
|
||||
|
||||
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))
|
||||
end
|
||||
|
|
|
@ -64,8 +64,8 @@ describe 'GitLab Markdown', feature: true do
|
|||
|
||||
it 'parses fenced code blocks' do
|
||||
aggregate_failures do
|
||||
expect(doc).to have_selector('pre.code.highlight.white.c')
|
||||
expect(doc).to have_selector('pre.code.highlight.white.python')
|
||||
expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.c')
|
||||
expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.python')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -224,8 +224,4 @@ describe 'GitLab Markdown', feature: true do
|
|||
def current_user
|
||||
@feat.user
|
||||
end
|
||||
|
||||
def user_color_scheme_class
|
||||
:white
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,8 +28,7 @@ describe EventsHelper do
|
|||
|
||||
it 'should display the first line of a code block' do
|
||||
input = "```\nCode block\nwith two lines\n```"
|
||||
expected = '<pre class="code highlight white plaintext"><code>' \
|
||||
'Code block...</code></pre>'
|
||||
expected = %r{<pre.+><code>Code block\.\.\.</code></pre>}
|
||||
|
||||
expect(event_note(input)).to match(expected)
|
||||
end
|
||||
|
@ -55,7 +54,7 @@ describe EventsHelper do
|
|||
|
||||
it 'should preserve code color scheme' do
|
||||
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" \
|
||||
" <span class=\"s1\">\'hello world\'</span>\n" \
|
||||
"<span class=\"k\">end</span>" \
|
||||
|
|
|
@ -1,72 +1,82 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe PreferencesHelper do
|
||||
describe 'user_application_theme' do
|
||||
context 'with a user' do
|
||||
it "returns user's theme's css_class" do
|
||||
user = double('user', theme_id: 3)
|
||||
allow(self).to receive(:current_user).and_return(user)
|
||||
expect(user_application_theme).to eq 'ui_green'
|
||||
end
|
||||
|
||||
it 'returns the default when id is invalid' do
|
||||
user = double('user', theme_id: Gitlab::Themes::THEMES.size + 5)
|
||||
|
||||
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'
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a user' do
|
||||
before do
|
||||
allow(self).to receive(:current_user).and_return(nil)
|
||||
end
|
||||
|
||||
it 'returns the default theme' do
|
||||
expect(user_application_theme).to eq Gitlab::Themes.default.css_class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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 { dashboard_choices }.to raise_error(RuntimeError)
|
||||
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 { dashboard_choices }.to raise_error(KeyError)
|
||||
expect { helper.dashboard_choices }.to raise_error(KeyError)
|
||||
end
|
||||
|
||||
it 'provides better option descriptions' do
|
||||
expect(dashboard_choices).to match_array [
|
||||
expect(helper.dashboard_choices).to match_array [
|
||||
['Your Projects (default)', 'projects'],
|
||||
['Starred Projects', 'stars']
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'user_color_scheme_class' do
|
||||
context 'with current_user is nil' do
|
||||
it 'should return a string' do
|
||||
allow(self).to receive(:current_user).and_return(nil)
|
||||
expect(user_color_scheme_class).to be_kind_of(String)
|
||||
describe 'user_application_theme' do
|
||||
context 'with a user' do
|
||||
it "returns user's theme's css_class" do
|
||||
stub_user(theme_id: 3)
|
||||
|
||||
expect(helper.user_application_theme).to eq 'ui_green'
|
||||
end
|
||||
|
||||
it 'returns the default when id is invalid' do
|
||||
stub_user(theme_id: Gitlab::Themes.count + 5)
|
||||
|
||||
allow(Gitlab.config.gitlab).to receive(:default_theme).and_return(2)
|
||||
|
||||
expect(helper.user_application_theme).to eq 'ui_charcoal'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a current_user' do
|
||||
(1..5).each do |color_scheme_id|
|
||||
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
|
||||
context 'without a user' do
|
||||
it 'returns the default theme' do
|
||||
stub_user
|
||||
|
||||
expect(helper.user_application_theme).to eq Gitlab::Themes.default.css_class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'user_color_scheme' do
|
||||
context 'with a user' do
|
||||
it "returns user's scheme's css_class" do
|
||||
allow(helper).to receive(:current_user).
|
||||
and_return(double(color_scheme_id: 3))
|
||||
|
||||
expect(helper.user_color_scheme).to eq 'solarized-light'
|
||||
end
|
||||
|
||||
it 'returns the default when id is invalid' do
|
||||
allow(helper).to receive(:current_user).
|
||||
and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5))
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a user' do
|
||||
it 'returns the default theme' do
|
||||
stub_user
|
||||
|
||||
expect(helper.user_color_scheme).
|
||||
to eq Gitlab::ColorSchemes.default.css_class
|
||||
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
|
||||
|
|
45
spec/lib/gitlab/color_schemes_spec.rb
Normal file
45
spec/lib/gitlab/color_schemes_spec.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
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
|
|||
expect(existing_user.ldap_identity.provider).to eql 'ldapmain'
|
||||
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
|
||||
expect{ ldap_user.save }.to change{ User.count }.by(1)
|
||||
end
|
||||
|
|
|
@ -43,9 +43,6 @@ describe Gitlab::Themes do
|
|||
ids = []
|
||||
described_class.each { |theme| ids << theme.id }
|
||||
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
|
||||
|
|
|
@ -31,13 +31,16 @@ describe NotificationService do
|
|||
|
||||
describe 'Notes' 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(: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
|
||||
build_team(note.project)
|
||||
project.team << [issue.author, :master]
|
||||
project.team << [issue.assignee, :master]
|
||||
project.team << [note.author, :master]
|
||||
end
|
||||
|
||||
describe :new_note do
|
||||
|
@ -53,6 +56,7 @@ describe NotificationService do
|
|||
should_not_email(@u_participating.id)
|
||||
should_not_email(@u_disabled.id)
|
||||
should_not_email(@unsubscriber.id)
|
||||
should_not_email(@u_outsider_mentioned)
|
||||
|
||||
notification.new_note(note)
|
||||
end
|
||||
|
@ -444,12 +448,15 @@ describe NotificationService do
|
|||
@u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_MENTION)
|
||||
@u_committer = create(:user, username: 'committer')
|
||||
@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_participating, :master]
|
||||
project.team << [@u_participant_mentioned, :master]
|
||||
project.team << [@u_disabled, :master]
|
||||
project.team << [@u_mentioned, :master]
|
||||
project.team << [@u_committer, :master]
|
||||
project.team << [@u_not_mentioned, :master]
|
||||
end
|
||||
|
||||
def add_users_with_subscription(project, issuable)
|
||||
|
|
Loading…
Reference in a new issue