diff options
60 files changed, 418 insertions, 323 deletions
diff --git a/CHANGELOG b/CHANGELOG index 624dd3a5c48..9d558b15ab9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,10 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.12.0 (unreleased) + - Update oauth button logos for Twitter and Google to recommended assets + - Update browser gem to version 0.8.0 for IE11 support (Stan Hu) - Fix timeout when rendering file with thousands of lines. + - Add "Remember me" checkbox to LDAP signin form. - Don't notify users mentioned in code blocks or blockquotes. - Omit link to generate labels if user does not have access to create them (Stan Hu) - Show warning when a comment will add 10 or more people to the discussion. @@ -30,7 +30,7 @@ gem 'rqrcode-rails3' gem 'attr_encrypted', '1.3.4' # Browser detection -gem "browser" +gem "browser", '~> 0.8.0' # Extracting information from a git repository # Provide access to Gitlab::Git library @@ -81,7 +81,7 @@ gem "carrierwave" gem 'dropzonejs-rails' # for aws storage -gem "fog", "~> 1.14" +gem "fog", "~> 1.25.0" gem "unf" # Authorization @@ -254,10 +254,10 @@ group :development, :test do end group :test do - gem "simplecov", require: false - gem "shoulda-matchers", "~> 2.7.0" + gem 'simplecov', require: false + gem 'shoulda-matchers', '~> 2.8.0', require: false gem 'email_spec' - gem "webmock" + gem 'webmock', '~> 1.21.0' gem 'test_after_commit' end diff --git a/Gemfile.lock b/Gemfile.lock index 9d87de7d4e0..1de29ad8f8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + CFPropertyList (2.3.1) RedCloth (4.2.9) ace-rails-ap (2.0.1) actionmailer (4.1.9) @@ -35,7 +36,7 @@ GEM tzinfo (~> 1.1) acts-as-taggable-on (3.5.0) activerecord (>= 3.2, < 5) - addressable (2.3.5) + addressable (2.3.8) annotate (2.6.0) activerecord (>= 2.3.0) rake (>= 0.8.7) @@ -75,7 +76,7 @@ GEM ruby_parser (~> 3.5.0) sass (~> 3.0) terminal-table (~> 1.4) - browser (0.7.2) + browser (0.8.0) builder (3.2.2) byebug (3.2.0) columnize (~> 0.8) @@ -118,8 +119,8 @@ GEM simplecov (>= 0.7) term-ansicolor thor - crack (0.4.1) - safe_yaml (~> 0.9.0) + crack (0.4.2) + safe_yaml (~> 1.0.0) creole (0.3.8) d3_rails (3.5.5) railties (>= 3.1.0) @@ -163,7 +164,7 @@ GEM erubis (2.7.0) escape_utils (0.2.4) eventmachine (1.0.4) - excon (0.32.1) + excon (0.45.3) execjs (2.5.2) expression_parser (0.9.0) factory_girl (4.3.0) @@ -178,29 +179,69 @@ GEM fastercsv (1.5.5) ffaker (2.0.0) ffi (1.9.8) - fog (1.21.0) - fog-brightbox - fog-core (~> 1.21, >= 1.21.1) + fission (0.5.0) + CFPropertyList (~> 2.2) + fog (1.25.0) + fog-brightbox (~> 0.4) + fog-core (~> 1.25) fog-json + fog-profitbricks + fog-radosgw (>= 0.0.2) + fog-sakuracloud (>= 0.0.4) + fog-softlayer + fog-terremark + fog-vmfusion + fog-voxel + fog-xml (~> 0.1.1) + ipaddress (~> 0.5) nokogiri (~> 1.5, >= 1.5.11) - fog-brightbox (0.0.1) - fog-core + opennebula + fog-brightbox (0.7.1) + fog-core (~> 1.22) fog-json - fog-core (1.21.1) + inflecto (~> 0.0.2) + fog-core (1.30.0) builder - excon (~> 0.32) - formatador (~> 0.2.0) + excon (~> 0.45) + formatador (~> 0.2) mime-types net-scp (~> 1.1) net-ssh (>= 2.1.3) - fog-json (1.0.0) - multi_json (~> 1.0) + fog-json (1.0.2) + fog-core (~> 1.0) + multi_json (~> 1.10) + fog-profitbricks (0.0.3) + fog-core + fog-xml + nokogiri + fog-radosgw (0.0.4) + fog-core (>= 1.21.0) + fog-json + fog-xml (>= 0.0.1) + fog-sakuracloud (1.0.1) + fog-core + fog-json + fog-softlayer (0.4.6) + fog-core + fog-json + fog-terremark (0.1.0) + fog-core + fog-xml + fog-vmfusion (0.1.0) + fission + fog-core + fog-voxel (0.1.0) + fog-core + fog-xml + fog-xml (0.1.2) + fog-core + nokogiri (~> 1.5, >= 1.5.11) font-awesome-rails (4.2.0.0) railties (>= 3.2, < 5.0) foreman (0.63.0) dotenv (>= 0.7) thor (>= 0.13.6) - formatador (0.2.4) + formatador (0.2.5) gemnasium-gitlab-service (0.2.6) rugged (~> 0.21) gemojione (2.0.0) @@ -287,6 +328,8 @@ GEM i18n (0.7.0) ice_cube (0.11.1) ice_nine (0.10.0) + inflecto (0.0.2) + ipaddress (0.8.0) jquery-atwho-rails (1.0.1) jquery-rails (3.1.2) railties (>= 3.0, < 5.0) @@ -328,9 +371,9 @@ GEM multipart-post (1.2.0) mysql2 (0.3.16) net-ldap (0.11) - net-scp (1.1.2) + net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (2.8.0) + net-ssh (2.9.2) newrelic_rpm (3.9.4.245) nokogiri (1.6.6.2) mini_portile (~> 0.6.0) @@ -379,6 +422,10 @@ GEM omniauth-twitter (1.0.1) multi_json (~> 1.3) omniauth-oauth (~> 1.0) + opennebula (4.12.1) + json + nokogiri + rbvmomi org-ruby (0.9.12) rubypants (~> 0.2) orm_adapter (0.5.0) @@ -446,6 +493,10 @@ GEM rb-fsevent (0.9.4) rb-inotify (0.9.5) ffi (>= 0.5.0) + rbvmomi (1.8.2) + builder + nokogiri (>= 1.4.1) + trollop rdoc (3.12.2) json (~> 1.4) redcarpet (3.2.3) @@ -513,7 +564,7 @@ GEM rubypants (0.2.0) rugged (0.22.2) rugments (1.0.0.beta7) - safe_yaml (0.9.7) + safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) sass (3.2.19) @@ -535,7 +586,7 @@ GEM thor (~> 0.14) settingslogic (2.0.9) sexp_processor (4.4.5) - shoulda-matchers (2.7.0) + shoulda-matchers (2.8.0) activesupport (>= 3.0.0) sidekiq (3.3.0) celluloid (>= 0.16.0) @@ -621,6 +672,7 @@ GEM multi_json (~> 1.7) twitter-stream (~> 0.1) tins (0.13.1) + trollop (2.1.2) turbolinks (2.5.3) coffee-rails twitter-stream (0.1.16) @@ -652,8 +704,8 @@ GEM equalizer (~> 0.0.7) warden (1.2.3) rack (>= 1.0) - webmock (1.16.0) - addressable (>= 2.2.7) + webmock (1.21.0) + addressable (>= 2.3.6) crack (>= 0.3.2) websocket-driver (0.3.3) wikicloth (0.8.1) @@ -680,7 +732,7 @@ DEPENDENCIES binding_of_caller bootstrap-sass (~> 3.0) brakeman - browser + browser (~> 0.8.0) byebug cal-heatmap-rails (~> 0.0.1) capybara (~> 2.2.1) @@ -704,7 +756,7 @@ DEPENDENCIES enumerize factory_girl_rails ffaker (~> 2.0.0) - fog (~> 1.14) + fog (~> 1.25.0) font-awesome-rails (~> 4.2) foreman gemnasium-gitlab-service (~> 0.2) @@ -772,7 +824,7 @@ DEPENDENCIES seed-fu select2-rails settingslogic - shoulda-matchers (~> 2.7.0) + shoulda-matchers (~> 2.8.0) sidekiq (~> 3.3) sidetiq (= 0.6.3) simplecov @@ -801,5 +853,5 @@ DEPENDENCIES unicorn-worker-killer version_sorter virtus - webmock + webmock (~> 1.21.0) wikicloth (= 0.8.1) diff --git a/app/assets/images/authbuttons/google_64.png b/app/assets/images/authbuttons/google_64.png Binary files differindex 94a0e089c6e..fb64f8bee68 100644 --- a/app/assets/images/authbuttons/google_64.png +++ b/app/assets/images/authbuttons/google_64.png diff --git a/app/assets/images/authbuttons/twitter_64.png b/app/assets/images/authbuttons/twitter_64.png Binary files differindex 5c9f14cb077..e3bd9169a34 100644 --- a/app/assets/images/authbuttons/twitter_64.png +++ b/app/assets/images/authbuttons/twitter_64.png diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index b9bd5c730bf..21656f59149 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -63,13 +63,11 @@ class @Notes # fetch notes when tab becomes visible $(document).on "visibilitychange", @visibilityChange - @notes_forms = '.js-main-target-form textarea, .js-discussion-note-form textarea' # Chrome doesn't fire keypress or keyup for Command+Enter, so we need keydown. - $(document).on('keydown', @notes_forms, (e) -> + $(document).on 'keydown', '.js-note-text', (e) -> return if e.originalEvent.repeat if e.keyCode == 10 || ((e.metaKey || e.ctrlKey) && e.keyCode == 13) - $(@).parents('form').submit() - ) + $(@).closest('form').submit() cleanBinding: -> $(document).off "ajax:success", ".js-main-target-form" @@ -84,7 +82,7 @@ class @Notes $(document).off "click", ".js-discussion-reply-button" $(document).off "click", ".js-add-diff-note-button" $(document).off "visibilitychange" - $(document).off "keydown", @notes_forms + $(document).off "keydown", ".js-note-text" $(document).off "keyup", ".js-note-text" $(document).off "click", ".js-note-target-reopen" $(document).off "click", ".js-note-target-close" diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index a767815b311..765adaf2128 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -24,7 +24,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController @user = Gitlab::LDAP::User.new(oauth) @user.save if @user.changed? # will also save new users gl_user = @user.gl_user - gl_user.remember_me = true if @user.persisted? + gl_user.remember_me = params[:remember_me] if @user.persisted? # Do additional LDAP checks for the user filter and EE features if @user.allowed? diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index b110de11013..b82b6f45d59 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -2,8 +2,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController # Authorize before_action :authorize_admin_project!, except: :leave - layout "project_settings" - def index @project_members = @project.project_members @project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project) diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index a1d263d9d3a..77727337f07 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -89,7 +89,7 @@ module TabHelper def project_tab_class return "active" if current_page?(controller: "/projects", action: :edit, id: @project) - if ['services', 'hooks', 'deploy_keys', 'project_members', 'protected_branches'].include? controller.controller_name + if ['services', 'hooks', 'deploy_keys', 'protected_branches'].include? controller.controller_name "active" end end diff --git a/app/models/commit.rb b/app/models/commit.rb index f02fe240540..9d721661629 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -172,10 +172,8 @@ class Commit @raw.send(m, *args, &block) end - def respond_to?(method) - return true if @raw.respond_to?(method) - - super + def respond_to_missing?(method, include_private = false) + @raw.respond_to?(method, include_private) || super end # Truncate sha to 8 characters diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb index 33b4814d7ec..660e58b876d 100644 --- a/app/models/concerns/taskable.rb +++ b/app/models/concerns/taskable.rb @@ -1,4 +1,5 @@ require 'task_list' +require 'task_list/filter' # Contains functionality for objects that can have task lists in their # descriptions. Task list items can be added with Markdown like "* [x] Fix diff --git a/app/models/repository.rb b/app/models/repository.rb index 1ca97017637..2c6347222aa 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -163,10 +163,8 @@ class Repository end end - def respond_to?(method) - return true if raw_repository.respond_to?(method) - - super + def respond_to_missing?(method, include_private = false) + raw_repository.respond_to?(method, include_private) || super end def blob_at(sha, path) diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index 812e22373a7..6ec741e4882 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -1,4 +1,9 @@ = form_tag(user_omniauth_callback_path(server['provider_name']), id: 'new_ldap_user' ) do = text_field_tag :username, nil, {class: "form-control top", placeholder: "#{server['label']} Login", autofocus: "autofocus"} = password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} + - if devise_mapping.rememberable? + .remember-me.checkbox + %label{for: "remember_me"} + = check_box_tag :remember_me, '1', false, id: 'remember_me' + %span Remember me = button_tag "#{server['label']} Sign in", class: "btn-save btn" diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 172f5197b24..cbcf560d0af 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -56,6 +56,13 @@ Merge Requests %span.count.merge_counter= @project.merge_requests.opened.count + - if project_nav_tab? :settings + = nav_link(controller: [:project_members, :teams]) do + = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab', data: {placement: 'right'} do + = icon('users fw') + %span + Members + - if project_nav_tab? :labels = nav_link(controller: :labels) do = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels', data: {placement: 'right'} do diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml index 7dd14449def..633c6ae6bfb 100644 --- a/app/views/layouts/nav/_project_settings.html.haml +++ b/app/views/layouts/nav/_project_settings.html.haml @@ -10,32 +10,27 @@ %ul.project-settings-nav.sidebar-subnav = nav_link(path: 'projects#edit') do = link_to edit_project_path(@project), title: 'Project', class: 'stat-tab tab', data: {placement: 'right'} do - = icon('pencil-square-o') + = icon('pencil-square-o fw') %span Project Settings - = nav_link(controller: [:project_members, :teams]) do - = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab', data: {placement: 'right'} do - = icon('users') - %span - Members = nav_link(controller: :deploy_keys) do = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys', data: {placement: 'right'} do - = icon('key') + = icon('key fw') %span Deploy Keys = nav_link(controller: :hooks) do = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Web Hooks', data: {placement: 'right'} do - = icon('link') + = icon('link fw') %span Web Hooks = nav_link(controller: :services) do = link_to namespace_project_services_path(@project.namespace, @project), title: 'Services', data: {placement: 'right'} do - = icon('cogs') + = icon('cogs fw') %span Services = nav_link(controller: :protected_branches) do = link_to namespace_project_protected_branches_path(@project.namespace, @project), title: 'Protected Branches', data: {placement: 'right'} do - = icon('lock') + = icon('lock fw') %span Protected branches diff --git a/app/views/profiles/two_factor_auths/new.html.haml b/app/views/profiles/two_factor_auths/new.html.haml index b9f3e2380fe..74268c9bde2 100644 --- a/app/views/profiles/two_factor_auths/new.html.haml +++ b/app/views/profiles/two_factor_auths/new.html.haml @@ -2,8 +2,10 @@ %h2.page-title Two-Factor Authentication (2FA) %p - Download the Google Authenticator application from App Store for iOS or - Google Play for Android and scan this code. + Download the Google Authenticator application from App Store for iOS or Google + Play for Android and scan this code. + + More information is available in the #{link_to('documentation', help_page_path('workflow', 'two_factor_authentication'))}. %hr @@ -12,10 +14,9 @@ .alert.alert-danger = @error .form-group - .col-sm-2 - .col-sm-2 + .col-lg-2.col-lg-offset-2 = raw @qr_code - .col-sm-8.manual-instructions + .col-lg-7.col-lg-offset-1.manual-instructions %h3 Can't scan the code? %p @@ -33,7 +34,7 @@ %dd Yes .form-group = label_tag :pin_code, nil, class: "control-label" - .col-sm-10 + .col-lg-10 = text_field_tag :pin_code, nil, class: "form-control", required: true, autofocus: true .form-actions = submit_tag 'Submit', class: 'btn btn-success' diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index c09d794ef7f..2765f63c6bc 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -6,7 +6,7 @@ Project settings %hr .panel-body - = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal" }, authenticity_token: true do |f| + = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f| %fieldset .form-group.project_name_holder @@ -41,32 +41,40 @@ %legend Features: .form-group - = f.label :issues_enabled, "Issues", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :issues_enabled - %span.descr Lightweight issue tracking system for this project + = f.label :issues_enabled do + = f.check_box :issues_enabled + %strong Issues + %br + %span.descr Lightweight issue tracking system for this project .form-group - = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :merge_requests_enabled - %span.descr Submit changes to be merged upstream. + = f.label :merge_requests_enabled do + = f.check_box :merge_requests_enabled + %strong Merge Requests + %br + %span.descr Submit changes to be merged upstream. .form-group - = f.label :wiki_enabled, "Wiki", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :wiki_enabled - %span.descr Pages for project documentation + = f.label :wiki_enabled do + = f.check_box :wiki_enabled + %strong Wiki + %br + %span.descr Pages for project documentation .form-group - = f.label :snippets_enabled, "Snippets", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :snippets_enabled - %span.descr Share code pastes with others out of git repository + = f.label :snippets_enabled do + = f.check_box :snippets_enabled + %strong Snippets + %br + %span.descr Share code pastes with others out of git repository %fieldset.features %legend diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 787b3ccfc56..f48c99fd901 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -252,6 +252,9 @@ production: &base # aws_secret_access_key: 'secret123' # # The remote 'directory' to store your backups. For S3, this would be the bucket name. # remote_directory: 'my.s3.bucket' + # # Use multipart uploads when file size reaches 100MB, see + # # http://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + # multipart_chunk_size: 104857600 ## GitLab Shell settings gitlab_shell: diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 1bd14a3a89f..c2c3c5bfde7 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -174,6 +174,7 @@ Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'co if Settings.backup['upload']['connection'] Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }] end +Settings.backup['upload']['multipart_chunk_size'] ||= 104857600 # # Git diff --git a/doc/api/groups.md b/doc/api/groups.md index c903a850fdd..0b9f6406d8d 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -1,178 +1,192 @@ -# Groups - -## List project groups - -Get a list of groups. (As user: my groups, as admin: all groups) - -``` -GET /groups -``` - -```json -[ - { - "id": 1, - "name": "Foobar Group", - "path": "foo-bar", - "description": "An interesting group" - } -] -``` - -You can search for groups by name or path, see below. - -## Details of a group - -Get all details of a group. - -``` -GET /groups/:id -``` - -Parameters: - -- `id` (required) - The ID or path of a group - -## New group - -Creates a new project group. Available only for users who can create groups. - -``` -POST /groups -``` - -Parameters: - -- `name` (required) - The name of the group -- `path` (required) - The path of the group -- `description` (optional) - The group's description - -## Transfer project to group - -Transfer a project to the Group namespace. Available only for admin - -``` -POST /groups/:id/projects/:project_id -``` - -Parameters: - -- `id` (required) - The ID or path of a group -- `project_id` (required) - The ID of a project - -## Remove group - -Removes group with all projects inside. - -``` -DELETE /groups/:id -``` - -Parameters: - -- `id` (required) - The ID or path of a user group - -## Search for group - -Get all groups that match your string in their name or path. - -``` -GET /groups?search=foobar -``` - -```json -[ - { - "id": 1, - "name": "Foobar Group", - "path": "foo-bar", - "description": "An interesting group" - } -] -``` - -## Group members - -**Group access levels** - -The group access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized: - -``` -GUEST = 10 -REPORTER = 20 -DEVELOPER = 30 -MASTER = 40 -OWNER = 50 -``` - -### List group members - -Get a list of group members viewable by the authenticated user. - -``` -GET /groups/:id/members -``` - -```json -[ - { - "id": 1, - "username": "raymond_smith", - "email": "ray@smith.org", - "name": "Raymond Smith", - "state": "active", - "created_at": "2012-10-22T14:13:35Z", - "access_level": 30 - }, - { - "id": 2, - "username": "john_doe", - "email": "joh@doe.org", - "name": "John Doe", - "state": "active", - "created_at": "2012-10-22T14:13:35Z", - "access_level": 30 - } -] -``` - -### Add group member - -Adds a user to the list of group members. - -``` -POST /groups/:id/members -``` - -Parameters: - -- `id` (required) - The ID or path of a group -- `user_id` (required) - The ID of a user to add -- `access_level` (required) - Project access level - -### Edit group team member - -Updates a group team member to a specified access level. - -``` -PUT /groups/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID of a group -- `user_id` (required) - The ID of a group member -- `access_level` (required) - Project access level - -### Remove user team member - -Removes user from user team. - -``` -DELETE /groups/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID or path of a user group -- `user_id` (required) - The ID of a group member +# Groups
+
+## List project groups
+
+Get a list of groups. (As user: my groups, as admin: all groups)
+
+```
+GET /groups
+```
+
+```json
+[
+ {
+ "id": 1,
+ "name": "Foobar Group",
+ "path": "foo-bar",
+ "description": "An interesting group"
+ }
+]
+```
+
+You can search for groups by name or path, see below.
+
+## Details of a group
+
+Get all details of a group.
+
+```
+GET /groups/:id
+```
+
+Parameters:
+
+- `id` (required) - The ID or path of a group
+
+## New group
+
+Creates a new project group. Available only for users who can create groups.
+
+```
+POST /groups
+```
+
+Parameters:
+
+- `name` (required) - The name of the group
+- `path` (required) - The path of the group
+- `description` (optional) - The group's description
+
+## Transfer project to group
+
+Transfer a project to the Group namespace. Available only for admin
+
+```
+POST /groups/:id/projects/:project_id
+```
+
+Parameters:
+
+- `id` (required) - The ID or path of a group
+- `project_id` (required) - The ID of a project
+
+## Remove group
+
+Removes group with all projects inside.
+
+```
+DELETE /groups/:id
+```
+
+Parameters:
+
+- `id` (required) - The ID or path of a user group
+
+## Search for group
+
+Get all groups that match your string in their name or path.
+
+```
+GET /groups?search=foobar
+```
+
+```json
+[
+ {
+ "id": 1,
+ "name": "Foobar Group",
+ "path": "foo-bar",
+ "description": "An interesting group"
+ }
+]
+```
+
+## Group members
+
+**Group access levels**
+
+The group access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized:
+
+```
+GUEST = 10
+REPORTER = 20
+DEVELOPER = 30
+MASTER = 40
+OWNER = 50
+```
+
+### List group members
+
+Get a list of group members viewable by the authenticated user.
+
+```
+GET /groups/:id/members
+```
+
+```json
+[
+ {
+ "id": 1,
+ "username": "raymond_smith",
+ "email": "ray@smith.org",
+ "name": "Raymond Smith",
+ "state": "active",
+ "created_at": "2012-10-22T14:13:35Z",
+ "access_level": 30
+ },
+ {
+ "id": 2,
+ "username": "john_doe",
+ "email": "joh@doe.org",
+ "name": "John Doe",
+ "state": "active",
+ "created_at": "2012-10-22T14:13:35Z",
+ "access_level": 30
+ }
+]
+```
+
+### Add group member
+
+Adds a user to the list of group members.
+
+```
+POST /groups/:id/members
+```
+
+Parameters:
+
+- `id` (required) - The ID or path of a group
+- `user_id` (required) - The ID of a user to add
+- `access_level` (required) - Project access level
+
+### Edit group team member
+
+Updates a group team member to a specified access level.
+
+```
+PUT /groups/:id/members/:user_id
+```
+
+Parameters:
+
+- `id` (required) - The ID of a group
+- `user_id` (required) - The ID of a group member
+- `access_level` (required) - Project access level
+
+### Remove user team member
+
+Removes user from user team.
+
+```
+DELETE /groups/:id/members/:user_id
+```
+
+Parameters:
+
+- `id` (required) - The ID or path of a user group
+- `user_id` (required) - The ID of a group member
+
+## Namespaces in groups
+
+By default, groups only get 20 namespaces at a time because the API results are paginated.
+
+To get more (up to 100), pass the following as an argument to the API call:
+```
+/groups?per_page=100
+```
+
+And to switch pages add:
+```
+/groups?per_page=100&page=2
+```
\ No newline at end of file diff --git a/doc/release/monthly.md b/doc/release/monthly.md index eb97f3cd7f6..57d904ff389 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -71,9 +71,14 @@ Xth: (1 working day before the 22nd) - [ ] Update GitLab.com with the stable version (#LINK) - [ ] Update ci.gitLab.com with the stable version (#LINK) -22nd: +22nd before 12AM CET: + +Release before 12AM CET / 3AM PST, to make sure the majority of our users +get the new version on the 22nd and there is sufficient time in the European +workday to quickly fix any issues. - [ ] Release CE, EE and CI (#LINK) +- [ ] Schedule a second tweet of the release announcement at 6PM CET / 9AM PST ``` diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_grant_access.jpg b/doc/workflow/bitbucket_importer/bitbucket_import_grant_access.jpg Binary files differdeleted file mode 100644 index f3432e923c4..00000000000 --- a/doc/workflow/bitbucket_importer/bitbucket_import_grant_access.jpg +++ /dev/null diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_new_project.jpg b/doc/workflow/bitbucket_importer/bitbucket_import_new_project.jpg Binary files differdeleted file mode 100644 index d0befa430b5..00000000000 --- a/doc/workflow/bitbucket_importer/bitbucket_import_new_project.jpg +++ /dev/null diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_select_bitbucket.jpg b/doc/workflow/bitbucket_importer/bitbucket_import_select_bitbucket.jpg Binary files differdeleted file mode 100644 index 53080e8104d..00000000000 --- a/doc/workflow/bitbucket_importer/bitbucket_import_select_bitbucket.jpg +++ /dev/null diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_select_project.png b/doc/workflow/bitbucket_importer/bitbucket_import_select_project.png Binary files differdeleted file mode 100644 index 8312825eb18..00000000000 --- a/doc/workflow/bitbucket_importer/bitbucket_import_select_project.png +++ /dev/null diff --git a/doc/workflow/importing/README.md b/doc/workflow/importing/README.md index 3cab541f955..2b2e9037425 100644 --- a/doc/workflow/importing/README.md +++ b/doc/workflow/importing/README.md @@ -1,6 +1,6 @@ -# Migrating projects to a GitLab instance - -1. [Bitbucket](doc/workflow/import_projects_from_bitbucket.md) -2. [GitHub](doc/workflow/import_projects_from_github.md) -3. [GitLab.com](doc/workflow/import_projects_from_gitlab_com.md) -4. [SVN](doc/workflow/migrating_from_svn.md) +# Migrating projects to a GitLab instance
+
+1. [Bitbucket](import_projects_from_bitbucket.md)
+2. [GitHub](import_projects_from_github.md)
+3. [GitLab.com](import_projects_from_gitlab_com.md)
+4. [SVN](migrating_from_svn.md)
diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.png Binary files differnew file mode 100644 index 00000000000..df55a081803 --- /dev/null +++ b/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.png diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.png Binary files differnew file mode 100644 index 00000000000..5253889d251 --- /dev/null +++ b/doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.png diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.png Binary files differnew file mode 100644 index 00000000000..ffa87ce5b2e --- /dev/null +++ b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.png diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png Binary files differnew file mode 100644 index 00000000000..0e08703f421 --- /dev/null +++ b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png diff --git a/doc/workflow/github_importer/importer.png b/doc/workflow/importing/github_importer/importer.png Binary files differindex 57636717571..57636717571 100644 --- a/doc/workflow/github_importer/importer.png +++ b/doc/workflow/importing/github_importer/importer.png diff --git a/doc/workflow/github_importer/new_project_page.png b/doc/workflow/importing/github_importer/new_project_page.png Binary files differindex 002f22d81d7..002f22d81d7 100644 --- a/doc/workflow/github_importer/new_project_page.png +++ b/doc/workflow/importing/github_importer/new_project_page.png diff --git a/doc/workflow/gitlab_importer/importer.png b/doc/workflow/importing/gitlab_importer/importer.png Binary files differindex d2a286d8cac..d2a286d8cac 100644 --- a/doc/workflow/gitlab_importer/importer.png +++ b/doc/workflow/importing/gitlab_importer/importer.png diff --git a/doc/workflow/gitlab_importer/new_project_page.png b/doc/workflow/importing/gitlab_importer/new_project_page.png Binary files differindex 5e239208e1e..5e239208e1e 100644 --- a/doc/workflow/gitlab_importer/new_project_page.png +++ b/doc/workflow/importing/gitlab_importer/new_project_page.png diff --git a/doc/workflow/import_projects_from_bitbucket.md b/doc/workflow/importing/import_projects_from_bitbucket.md index 20d65f1925a..1e9825e2e10 100644 --- a/doc/workflow/import_projects_from_bitbucket.md +++ b/doc/workflow/importing/import_projects_from_bitbucket.md @@ -6,15 +6,15 @@ It takes just a few steps to import your existing Bitbucket projects to GitLab. * Click on "New project"
-
+
* Click on the "Bitbucket" button
-
+
* Grant GitLab access to your Bitbucket account
-
+
* Click on the projects that you'd like to import or "Import all projects"
@@ -23,4 +23,4 @@ It takes just a few steps to import your existing Bitbucket projects to GitLab. A new GitLab project will be created with your imported data.
### Note
-Milestones and wiki pages are not imported from Bitbucket.
\ No newline at end of file +Milestones and wiki pages are not imported from Bitbucket.
diff --git a/doc/workflow/import_projects_from_github.md b/doc/workflow/importing/import_projects_from_github.md index aad2c63817d..aad2c63817d 100644 --- a/doc/workflow/import_projects_from_github.md +++ b/doc/workflow/importing/import_projects_from_github.md diff --git a/doc/workflow/import_projects_from_gitlab_com.md b/doc/workflow/importing/import_projects_from_gitlab_com.md index f4c4e955d46..f4c4e955d46 100644 --- a/doc/workflow/import_projects_from_gitlab_com.md +++ b/doc/workflow/importing/import_projects_from_gitlab_com.md diff --git a/doc/workflow/migrating_from_svn.md b/doc/workflow/importing/migrating_from_svn.md index 485db4834e9..485db4834e9 100644 --- a/doc/workflow/migrating_from_svn.md +++ b/doc/workflow/importing/migrating_from_svn.md diff --git a/doc/workflow/two_factor_authentication.md b/doc/workflow/two_factor_authentication.md index 7c45d23c99d..fb215c8b269 100644 --- a/doc/workflow/two_factor_authentication.md +++ b/doc/workflow/two_factor_authentication.md @@ -45,7 +45,7 @@ storage in a safe place. **Each code can be used only once** to log in to your account. If you lose the recovery codes or just want to generate new ones, you can do so -from the **Profile Settings** > **Acount** page where you first enabled 2FA. +from the **Profile Settings** > **Account** page where you first enabled 2FA. ## Logging in with 2FA Enabled @@ -60,8 +60,8 @@ your phone's application or a recovery code to log in. 1. Log in to your GitLab account. 1. Go to your **Profile Settings**. -1. Go to **Acount**. +1. Go to **Account**. 1. Click **Disable Two-factor Authentication**. [Google Authenticator]: https://support.google.com/accounts/answer/1066447?hl=en -[FreeOTP]: https://fedorahosted.org/freeotp/
\ No newline at end of file +[FreeOTP]: https://fedorahosted.org/freeotp/ diff --git a/docker/README.md b/docker/README.md index 46b21348364..3edce5ef561 100644 --- a/docker/README.md +++ b/docker/README.md @@ -80,7 +80,7 @@ sudo docker pull sytse/gitlab-app:7.10.1 ```bash sudo docker run --name gitlab-data sytse/gitlab-data /bin/true -sudo docker run --detach --name gitlab_app --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data sytse/gitlab-app:7.10.1 +sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab-data sytse/gitlab-app:7.10.1 ``` After this you can login to the web interface as explained above in 'After starting a container'. @@ -130,7 +130,7 @@ It Assumes that you're upgrading from 7.8.1 to 7.10.1 and you're in the updated sudo docker stop gitlab-app sudo docker rm gitlab-app sudo docker build --tag gitlab-app:7.10.1 docker/app/ -sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data gitlab-app:7.10.1 +sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab-data gitlab-app:7.10.1 ``` On the first run GitLab will reconfigure and update itself. If everything runs OK don't forget to cleanup the app image: @@ -143,13 +143,13 @@ sudo docker rmi gitlab-app:7.8.1 - Ensure the containers are running - Login to Dockerhub with `sudo docker login` -- Run the following (replace '7.9.2' with the version you're using and 'Sytse Sijbrandij' with your name): +- Run the following (replace '7.10.1' with the version you're using and 'Sytse Sijbrandij' with your name): ```bash sudo docker commit -m "Initial commit" -a "Sytse Sijbrandij" gitlab-app sytse/gitlab-app:7.10.1 sudo docker push sytse/gitlab-app:7.10.1 -sudo docker commit -m "Initial commit" -a "Sytse Sijbrandij" gitlab_data sytse/gitlab_data -sudo docker push sytse/gitlab_data +sudo docker commit -m "Initial commit" -a "Sytse Sijbrandij" gitlab-data sytse/gitlab-data +sudo docker push sytse/gitlab-data ``` ## Troubleshooting diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index 05faad4e645..8661ea98c20 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -35,6 +35,11 @@ Feature: Project Active Tab Then the active main tab should be Merge Requests And no other main tabs should be active + Scenario: On Project Members + Given I visit my project's members page + Then the active main tab should be Members + And no other main tabs should be active + Scenario: On Project Wiki Given I visit my project's wiki page Then the active main tab should be Wiki @@ -49,13 +54,6 @@ Feature: Project Active Tab # Sub Tabs: Settings - Scenario: On Project Settings/Team - Given I visit my project's settings page - And I click the "Team" tab - Then the active sub nav should be Team - And no other sub navs should be active - And the active main tab should be Settings - Scenario: On Project Settings/Edit Given I visit my project's settings page And I click the "Edit" tab diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index c888e82e207..30d53333b78 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -69,14 +69,13 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I visit big commit page' do - Commit::DIFF_SAFE_FILES = 20 + stub_const('Commit::DIFF_SAFE_FILES', 20) visit namespace_project_commit_path(@project.namespace, @project, sample_big_commit.id) end step 'I see big commit warning' do page.should have_content sample_big_commit.message page.should have_content "Too many changes" - Commit::DIFF_SAFE_FILES = 100 end step 'I visit a commit with an image that changed' do diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index d9401bd540c..46493876805 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -227,6 +227,10 @@ module SharedPaths visit namespace_project_merge_requests_path(@project.namespace, @project) end + step "I visit my project's members page" do + visit namespace_project_project_members_path(@project.namespace, @project) + end + step "I visit my project's wiki page" do visit namespace_project_wiki_path(@project.namespace, @project, :home) end diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index c5aed19331c..71fe89f634f 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -28,6 +28,10 @@ module SharedProjectTab ensure_active_main_tab('Issues') end + step 'the active main tab should be Members' do + ensure_active_main_tab('Members') + end + step 'the active main tab should be Merge Requests' do ensure_active_main_tab('Merge Requests') end diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index b69aebf9fe1..6fa2079d1a8 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -46,7 +46,8 @@ module Backup connection = ::Fog::Storage.new(connection_settings) directory = connection.directories.get(remote_directory) - if directory.files.create(key: tar_file, body: File.open(tar_file), public: false) + if directory.files.create(key: tar_file, body: File.open(tar_file), public: false, + multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size) $progress.puts "done".green else puts "uploading backup to #{remote_directory} failed".red diff --git a/lib/gitlab/gitorious_import.rb b/lib/gitlab/gitorious_import.rb new file mode 100644 index 00000000000..8d0132a744c --- /dev/null +++ b/lib/gitlab/gitorious_import.rb @@ -0,0 +1,5 @@ +module Gitlab + module GitoriousImport + GITORIOUS_HOST = "https://gitorious.org" + end +end diff --git a/lib/gitlab/gitorious_import/client.rb b/lib/gitlab/gitorious_import/client.rb index 1fa89dba448..99fe5bdebfc 100644 --- a/lib/gitlab/gitorious_import/client.rb +++ b/lib/gitlab/gitorious_import/client.rb @@ -1,7 +1,5 @@ module Gitlab module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - class Client attr_reader :repo_list diff --git a/lib/gitlab/gitorious_import/repository.rb b/lib/gitlab/gitorious_import/repository.rb index f702797dc6e..c88f1ae358d 100644 --- a/lib/gitlab/gitorious_import/repository.rb +++ b/lib/gitlab/gitorious_import/repository.rb @@ -1,7 +1,5 @@ module Gitlab module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - Repository = Struct.new(:full_name) do def id Digest::SHA1.hexdigest(full_name) diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb index 581a8c20bdb..0dab7bcfa4d 100644 --- a/lib/gitlab/project_search_results.rb +++ b/lib/gitlab/project_search_results.rb @@ -4,7 +4,11 @@ module Gitlab def initialize(project_id, query, repository_ref = nil) @project = Project.find(project_id) - @repository_ref = repository_ref + @repository_ref = if repository_ref.present? + repository_ref + else + nil + end @query = Shellwords.shellescape(query) if query.present? end diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index 557c71b4d2c..86c395a8e8e 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -16,7 +16,7 @@ describe Issue, "Issuable" do it { is_expected.to validate_presence_of(:iid) } it { is_expected.to validate_presence_of(:author) } it { is_expected.to validate_presence_of(:title) } - it { is_expected.to ensure_length_of(:title).is_at_least(0).is_at_most(255) } + it { is_expected.to validate_length_of(:title).is_at_least(0).is_at_most(255) } end describe "Scope" do diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb index 7032b777144..705ef257d86 100644 --- a/spec/models/deploy_keys_project_spec.rb +++ b/spec/models/deploy_keys_project_spec.rb @@ -36,9 +36,7 @@ describe DeployKeysProject do it "doesn't destroy the deploy key" do subject.destroy - expect { - deploy_key.reload - }.not_to raise_error(ActiveRecord::RecordNotFound) + expect { deploy_key.reload }.not_to raise_error end end @@ -63,9 +61,7 @@ describe DeployKeysProject do it "doesn't destroy the deploy key" do subject.destroy - expect { - deploy_key.reload - }.not_to raise_error(ActiveRecord::RecordNotFound) + expect { deploy_key.reload }.not_to raise_error end end end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 6eb1208a7f2..fbb9e162952 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -26,8 +26,8 @@ describe Key do describe "Validation" do it { is_expected.to validate_presence_of(:title) } it { is_expected.to validate_presence_of(:key) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } - it { is_expected.to ensure_length_of(:key).is_within(0..5000) } + it { is_expected.to validate_length_of(:title).is_within(0..255) } + it { is_expected.to validate_length_of(:key).is_within(0..5000) } end describe "Methods" do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 48568e2a3ff..87c67fa32c3 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -69,14 +69,14 @@ describe Project do it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) } - it { is_expected.to ensure_length_of(:name).is_within(0..255) } + it { is_expected.to validate_length_of(:name).is_within(0..255) } it { is_expected.to validate_presence_of(:path) } it { is_expected.to validate_uniqueness_of(:path).scoped_to(:namespace_id) } - it { is_expected.to ensure_length_of(:path).is_within(0..255) } - it { is_expected.to ensure_length_of(:description).is_within(0..2000) } + it { is_expected.to validate_length_of(:path).is_within(0..255) } + it { is_expected.to validate_length_of(:description).is_within(0..2000) } it { is_expected.to validate_presence_of(:creator) } - it { is_expected.to ensure_length_of(:issues_tracker_id).is_within(0..255) } + it { is_expected.to validate_length_of(:issues_tracker_id).is_within(0..255) } it { is_expected.to validate_presence_of(:namespace) } it 'should not allow new projects beyond user limits' do diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index c81dd36ef4b..c786d0bf103 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -38,10 +38,10 @@ describe Snippet do it { is_expected.to validate_presence_of(:author) } it { is_expected.to validate_presence_of(:title) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } + it { is_expected.to validate_length_of(:title).is_within(0..255) } it { is_expected.to validate_presence_of(:file_name) } - it { is_expected.to ensure_length_of(:file_name).is_within(0..255) } + it { is_expected.to validate_length_of(:file_name).is_within(0..255) } it { is_expected.to validate_presence_of(:content) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index be0b70395d6..f1b8afa5854 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -96,7 +96,7 @@ describe User do it { is_expected.to allow_value(0).for(:projects_limit) } it { is_expected.not_to allow_value(-1).for(:projects_limit) } - it { is_expected.to ensure_length_of(:bio).is_within(0..255) } + it { is_expected.to validate_length_of(:bio).is_within(0..255) } describe 'email' do it 'accepts info@example.com' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8fe51cf4add..9c8004ab555 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,16 +1,7 @@ -if ENV['SIMPLECOV'] - require 'simplecov' -end - -if ENV['COVERALLS'] - require 'coveralls' - Coveralls.wear_merged! -end - ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' -require 'webmock/rspec' +require 'shoulda/matchers' require 'email_spec' require 'sidekiq/testing/inline' @@ -18,8 +9,6 @@ require 'sidekiq/testing/inline' # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } -WebMock.disable_net_connect!(allow_localhost: true) - RSpec.configure do |config| config.use_transactional_fixtures = false config.use_instantiated_fixtures = false diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb index ec9a326a1ea..f63322776d4 100644 --- a/spec/support/api_helpers.rb +++ b/spec/support/api_helpers.rb @@ -29,6 +29,6 @@ module ApiHelpers end def json_response - JSON.parse(response.body) + @_json_response ||= JSON.parse(response.body) end end diff --git a/spec/support/coverage.rb b/spec/support/coverage.rb new file mode 100644 index 00000000000..a54bf03380c --- /dev/null +++ b/spec/support/coverage.rb @@ -0,0 +1,8 @@ +if ENV['SIMPLECOV'] + require 'simplecov' +end + +if ENV['COVERALLS'] + require 'coveralls' + Coveralls.wear_merged! +end diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 52b11bd6323..f8cce2ea5a3 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -70,7 +70,7 @@ end # Extend shoulda-matchers module Shoulda::Matchers::ActiveModel - class EnsureLengthOfMatcher + class ValidateLengthOfMatcher # Shortcut for is_at_least and is_at_most def is_within(range) is_at_least(range.min) && is_at_most(range.max) diff --git a/spec/support/webmock.rb b/spec/support/webmock.rb new file mode 100644 index 00000000000..af2906b7568 --- /dev/null +++ b/spec/support/webmock.rb @@ -0,0 +1,4 @@ +require 'webmock' +require 'webmock/rspec' + +WebMock.disable_net_connect!(allow_localhost: true) |