diff options
26 files changed, 243 insertions, 60 deletions
diff --git a/CHANGELOG b/CHANGELOG index b3cb9d4b3e1..d9d4a515a39 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,14 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.12.0 (unreleased) - Change merge_error column from string to text type + - Add `web_url` field to issue, merge request, and snippet API objects (Ben Boeckel) - Optimistic locking for Issues and Merge Requests (title and description overriding prevention) + - Add `wiki_page_events` to project hook APIs (Ben Boeckel) - Added tests for diff notes + - Added 'only_allow_merge_if_build_succeeds' project setting in the API. !5930 (Duck) + +v 8.11.2 (unreleased) + - Show "Create Merge Request" widget for push events to fork projects on the source project v 8.11.1 (unreleased) - Does not halt the GitHub import process when an error occurs @@ -172,6 +178,7 @@ v 8.11.0 - Eliminate unneeded calls to Repository#blob_at when listing commits with no path - Update gitlab_git gem to 10.4.7 - Simplify SQL queries of marking a todo as done + - Update merge_requests.md with a simpler way to check out a merge request. !5944 v 8.10.7 - Upgrade Hamlit to 2.6.1. !5873 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 5b209ea2067..b4d6d12101f 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -0.7.10 +0.7.11 diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 2a6385c1029..fc52cd2f367 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -5,7 +5,7 @@ class ProjectsController < Projects::ApplicationController before_action :project, except: [:new, :create] before_action :repository, except: [:new, :create] before_action :assign_ref_vars, only: [:show], if: :repo_exists? - before_action :assign_tree_vars, only: [:show], if: [:repo_exists?, :project_view_files?] + before_action :tree, only: [:show], if: [:repo_exists?, :project_view_files?] # Authorize before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export] @@ -332,11 +332,4 @@ class ProjectsController < Projects::ApplicationController def get_id project.repository.root_ref end - - # ExtractsPath will set @id = project.path on the show route, but it has to be the - # branch name for the tree view to work correctly. - def assign_tree_vars - @id = get_id - tree - end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 249d18c4486..356f27f2d5d 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -116,6 +116,17 @@ module ProjectsHelper license.nickname || license.name end + def last_push_event + return unless current_user + + project_ids = [@project.id] + if fork = current_user.fork_of(@project) + project_ids << fork.id + end + + current_user.recent_push(project_ids) + end + private def get_project_nav_tabs(project, current_user) @@ -351,16 +362,6 @@ module ProjectsHelper namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'LICENSE') end - def last_push_event - return unless current_user - - if fork = current_user.fork_of(@project) - current_user.recent_push(fork.id) - else - current_user.recent_push(@project.id) - end - end - def readme_cache_key sha = @project.commit.try(:sha) || 'nil' [@project.path_with_namespace, sha, "readme"].join('-') diff --git a/app/models/user.rb b/app/models/user.rb index 48e83ab7e56..ad3cfbc03e4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -489,10 +489,10 @@ class User < ActiveRecord::Base (personal_projects.count.to_f / projects_limit) * 100 end - def recent_push(project_id = nil) + def recent_push(project_ids = nil) # Get push events not earlier than 2 hours ago events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours) - events = events.where(project_id: project_id) if project_id + events = events.where(project_id: project_ids) if project_ids # Use the latest event that has not been pushed or merged recently events.recent.find do |event| diff --git a/doc/api/issues.md b/doc/api/issues.md index a665645ad0e..b194799ccbf 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -79,7 +79,8 @@ Example response: "labels" : [], "subscribed" : false, "user_notes_count": 1, - "due_date": "2016-07-22" + "due_date": "2016-07-22", + "web_url": "http://example.com/example/example/issues/6" } ] ``` @@ -156,7 +157,8 @@ Example response: "created_at" : "2016-01-04T15:31:46.176Z", "subscribed" : false, "user_notes_count": 1, - "due_date": null + "due_date": null, + "web_url": "http://example.com/example/example/issues/1" } ] ``` @@ -235,7 +237,8 @@ Example response: "created_at" : "2016-01-04T15:31:46.176Z", "subscribed" : false, "user_notes_count": 1, - "due_date": "2016-07-22" + "due_date": "2016-07-22", + "web_url": "http://example.com/example/example/issues/1" } ] ``` @@ -299,7 +302,8 @@ Example response: "created_at" : "2016-01-04T15:31:46.176Z", "subscribed": false, "user_notes_count": 1, - "due_date": null + "due_date": null, + "web_url": "http://example.com/example/example/issues/1" } ``` @@ -323,8 +327,8 @@ POST /projects/:id/issues | `assignee_id` | integer | no | The ID of a user to assign issue | | `milestone_id` | integer | no | The ID of a milestone to assign issue | | `labels` | string | no | Comma-separated label names for an issue | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` | -| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | +| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/4/issues?title=Issues%20with%20auth&labels=bug @@ -357,7 +361,8 @@ Example response: "milestone" : null, "subscribed" : true, "user_notes_count": 0, - "due_date": null + "due_date": null, + "web_url": "http://example.com/example/example/issues/14" } ``` @@ -384,8 +389,8 @@ PUT /projects/:id/issues/:issue_id | `milestone_id` | integer | no | The ID of a milestone to assign the issue to | | `labels` | string | no | Comma-separated label names for an issue | | `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it | -| `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` | -| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | +| `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | +| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | ```bash curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/4/issues/85?state_event=close @@ -418,7 +423,8 @@ Example response: "milestone" : null, "subscribed" : true, "user_notes_count": 0, - "due_date": "2016-07-22" + "due_date": "2016-07-22", + "web_url": "http://example.com/example/example/issues/15" } ``` @@ -496,7 +502,8 @@ Example response: "avatar_url": "http://www.gravatar.com/avatar/7a190fecbaa68212a4b68aeb6e3acd10?s=80&d=identicon", "web_url": "https://gitlab.example.com/u/solon.cremin" }, - "due_date": null + "due_date": null, + "web_url": "http://example.com/example/example/issues/11" } ``` @@ -551,7 +558,8 @@ Example response: "avatar_url": "http://www.gravatar.com/avatar/7a190fecbaa68212a4b68aeb6e3acd10?s=80&d=identicon", "web_url": "https://gitlab.example.com/u/solon.cremin" }, - "due_date": null + "due_date": null, + "web_url": "http://example.com/example/example/issues/11" } ``` @@ -607,7 +615,8 @@ Example response: "web_url": "https://gitlab.example.com/u/orville" }, "subscribed": false, - "due_date": null + "due_date": null, + "web_url": "http://example.com/example/example/issues/12" } ``` @@ -693,7 +702,9 @@ Example response: "subscribed": true, "user_notes_count": 7, "upvotes": 0, - "downvotes": 0 + "downvotes": 0, + "due_date": null, + "web_url": "http://example.com/example/example/issues/110" }, "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ci/issues/10", "body": "Vel voluptas atque dicta mollitia adipisci qui at.", diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 3e88a758936..f275762da3e 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -70,7 +70,8 @@ Parameters: "subscribed" : false, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" } ] ``` @@ -136,7 +137,8 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" } ``` @@ -239,6 +241,7 @@ Parameters: "user_notes_count": 1, "should_remove_source_branch": true, "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1", "changes": [ { "old_path": "VERSION", @@ -321,7 +324,8 @@ Parameters: "subscribed" : true, "user_notes_count": 0, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" } ``` @@ -395,7 +399,8 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" } ``` @@ -496,7 +501,8 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" } ``` @@ -565,7 +571,8 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" } ``` @@ -886,7 +893,8 @@ Example response: "subscribed": true, "user_notes_count": 7, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": false, + "web_url": "http://example.com/example/example/merge_requests/1" }, "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ci/merge_requests/7", "body": "Et voluptas laudantium minus nihil recusandae ut accusamus earum aut non.", diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md index a7acf37b5bc..c6685f54a9d 100644 --- a/doc/api/project_snippets.md +++ b/doc/api/project_snippets.md @@ -53,7 +53,8 @@ Parameters: }, "expires_at": null, "updated_at": "2012-06-28T10:52:04Z", - "created_at": "2012-06-28T10:52:04Z" + "created_at": "2012-06-28T10:52:04Z", + "web_url": "http://example.com/example/example/snippets/1" } ``` diff --git a/doc/api/projects.md b/doc/api/projects.md index 37d97b2db44..0e4806e31c5 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -84,7 +84,8 @@ Parameters: "star_count": 0, "runners_token": "b8547b1dc37721d05889db52fa2f02", "public_builds": true, - "shared_with_groups": [] + "shared_with_groups": [], + "only_allow_merge_if_build_succeeds": false }, { "id": 6, @@ -144,7 +145,8 @@ Parameters: "star_count": 0, "runners_token": "b8547b1dc37721d05889db52fa2f02", "public_builds": true, - "shared_with_groups": [] + "shared_with_groups": [], + "only_allow_merge_if_build_succeeds": false } ] ``` @@ -280,7 +282,8 @@ Parameters: "group_name": "Gitlab Org", "group_access_level": 10 } - ] + ], + "only_allow_merge_if_build_succeeds": false } ``` @@ -448,6 +451,7 @@ Parameters: - `visibility_level` (optional) - `import_url` (optional) - `public_builds` (optional) +- `only_allow_merge_if_build_succeeds` (optional) ### Create project for user @@ -473,6 +477,7 @@ Parameters: - `visibility_level` (optional) - `import_url` (optional) - `public_builds` (optional) +- `only_allow_merge_if_build_succeeds` (optional) ### Edit project @@ -499,6 +504,7 @@ Parameters: - `public` (optional) - if `true` same as setting visibility_level = 20 - `visibility_level` (optional) - `public_builds` (optional) +- `only_allow_merge_if_build_succeeds` (optional) On success, method returns 200 with the updated project. If parameters are invalid, 400 is returned. @@ -577,7 +583,8 @@ Example response: "forks_count": 0, "star_count": 1, "public_builds": true, - "shared_with_groups": [] + "shared_with_groups": [], + "only_allow_merge_if_build_succeeds": false } ``` @@ -643,7 +650,8 @@ Example response: "forks_count": 0, "star_count": 0, "public_builds": true, - "shared_with_groups": [] + "shared_with_groups": [], + "only_allow_merge_if_build_succeeds": false } ``` @@ -729,7 +737,8 @@ Example response: "star_count": 0, "runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b", "public_builds": true, - "shared_with_groups": [] + "shared_with_groups": [], + "only_allow_merge_if_build_succeeds": false } ``` @@ -815,7 +824,8 @@ Example response: "star_count": 0, "runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b", "public_builds": true, - "shared_with_groups": [] + "shared_with_groups": [], + "only_allow_merge_if_build_succeeds": false } ``` @@ -914,7 +924,11 @@ Parameters: "push_events": true, "issues_events": true, "merge_requests_events": true, + "tag_push_events": true, "note_events": true, + "build_events": true, + "pipeline_events": true, + "wiki_page_events": true, "enable_ssl_verification": true, "created_at": "2012-10-12T17:04:47Z" } @@ -937,6 +951,9 @@ Parameters: - `merge_requests_events` - Trigger hook on merge_requests events - `tag_push_events` - Trigger hook on push_tag events - `note_events` - Trigger hook on note events +- `build_events` - Trigger hook on build events +- `pipeline_events` - Trigger hook on pipeline events +- `wiki_page_events` - Trigger hook on wiki page events - `enable_ssl_verification` - Do SSL verification when triggering the hook ### Edit project hook @@ -957,6 +974,9 @@ Parameters: - `merge_requests_events` - Trigger hook on merge_requests events - `tag_push_events` - Trigger hook on push_tag events - `note_events` - Trigger hook on note events +- `build_events` - Trigger hook on build events +- `pipeline_events` - Trigger hook on pipeline events +- `wiki_page_events` - Trigger hook on wiki page events - `enable_ssl_verification` - Do SSL verification when triggering the hook ### Delete project hook diff --git a/doc/install/installation.md b/doc/install/installation.md index b0ec9b4a961..d4b89fa8345 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -397,7 +397,7 @@ If you are not using Linux you may have to run `gmake` instead of cd /home/git sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git cd gitlab-workhorse - sudo -u git -H git checkout v0.7.10 + sudo -u git -H git checkout v0.7.11 sudo -u git -H make ### Initialize Database and Activate Advanced Features diff --git a/doc/workflow/merge_requests.md b/doc/workflow/merge_requests.md index d2ec56e6504..91fcfb02d39 100644 --- a/doc/workflow/merge_requests.md +++ b/doc/workflow/merge_requests.md @@ -15,6 +15,25 @@ Please note that you need to have builds configured to enable this feature. ## Checkout merge requests locally +### By adding a git alias + +Add the following alias to your `~/.gitconfig`: + +``` +[alias] + mr = !sh -c 'git fetch $1 merge-requests/$2/head:mr-$1-$2 && git checkout mr-$1-$2' - +``` + +Now you can check out a particular merge request from any repository and any remote, e.g. to check out a merge request number 5 as shown in GitLab from the `upstream` remote, do: + +``` +$ git mr upstream 5 +``` + +This will fetch the merge request into a local `mr-upstream-5` branch and check it out. + +### By modifying `.git/config` for a given repository + Locate the section for your GitLab remote in the `.git/config` file. It looks like this: ``` diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 66b85ab1793..aaeb3d4800b 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -49,7 +49,7 @@ module API class ProjectHook < Hook expose :project_id, :push_events expose :issues_events, :merge_requests_events, :tag_push_events - expose :note_events, :build_events, :pipeline_events + expose :note_events, :build_events, :pipeline_events, :wiki_page_events expose :enable_ssl_verification end @@ -90,6 +90,7 @@ module API expose :shared_with_groups do |project, options| SharedGroup.represent(project.project_group_links.all, options) end + expose :only_allow_merge_if_build_succeeds end class Member < UserBasic @@ -177,6 +178,10 @@ module API # TODO (rspeicher): Deprecated; remove in 9.0 expose(:expires_at) { |snippet| nil } + + expose :web_url do |snippet, options| + Gitlab::UrlBuilder.build(snippet) + end end class ProjectEntity < Grape::Entity @@ -206,6 +211,10 @@ module API expose :user_notes_count expose :upvotes, :downvotes expose :due_date + + expose :web_url do |issue, options| + Gitlab::UrlBuilder.build(issue) + end end class ExternalIssue < Grape::Entity @@ -229,6 +238,10 @@ module API expose :user_notes_count expose :should_remove_source_branch?, as: :should_remove_source_branch expose :force_remove_source_branch?, as: :force_remove_source_branch + + expose :web_url do |merge_request, options| + Gitlab::UrlBuilder.build(merge_request) + end end class MergeRequestChanges < MergeRequest diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 3f63cd678e8..14f5be3b5f6 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -46,6 +46,7 @@ module API :note_events, :build_events, :pipeline_events, + :wiki_page_events, :enable_ssl_verification ] @hook = user_project.hooks.new(attrs) @@ -80,6 +81,7 @@ module API :note_events, :build_events, :pipeline_events, + :wiki_page_events, :enable_ssl_verification ] diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 60cfc103afd..71efd4f33ca 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -123,7 +123,8 @@ module API :public, :visibility_level, :import_url, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(current_user, attrs).execute if @project.saved? @@ -172,7 +173,8 @@ module API :public, :visibility_level, :import_url, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(user, attrs).execute if @project.saved? @@ -234,7 +236,8 @@ module API :shared_runners_enabled, :public, :visibility_level, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) authorize_admin_project authorize! :rename_project, user_project if attrs[:name].present? diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index a293fa2752f..a4558d157c0 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -94,9 +94,7 @@ module ExtractsPath @options = params.select {|key, value| allowed_options.include?(key) && !value.blank? } @options = HashWithIndifferentAccess.new(@options) - @id = params[:id] || params[:ref] - @id += "/" + params[:path] unless params[:path].blank? - + @id = get_id @ref, @path = extract_ref(@id) @repo = @project.repository if @options[:extended_sha1].blank? @@ -118,4 +116,13 @@ module ExtractsPath def tree @tree ||= @repo.tree(@commit.id, @path) end + + private + + # overriden in subclasses, do not remove + def get_id + id = params[:id] || params[:ref] + id += "/" + params[:path] unless params[:path].blank? + id + end end diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index fe65c246101..99d0c28e749 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -22,6 +22,8 @@ module Gitlab note_url when WikiPage wiki_page_url + when ProjectSnippet + project_snippet_url(object) else raise NotImplementedError.new("No URL builder defined for #{object.class}") end diff --git a/spec/factories/project_hooks.rb b/spec/factories/project_hooks.rb index 4fd51a23490..424ecc65759 100644 --- a/spec/factories/project_hooks.rb +++ b/spec/factories/project_hooks.rb @@ -14,6 +14,7 @@ FactoryGirl.define do note_events true build_events true pipeline_events true + wiki_page_events true end end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 604204cca0a..284b58d8d5c 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -136,4 +136,42 @@ describe ProjectsHelper do expect(sanitize_repo_path(project, import_error)).to eq('Could not clone [REPOS PATH]/namespace/test.git') end end + + describe '#last_push_event' do + let(:user) { double(:user, fork_of: nil) } + let(:project) { double(:project, id: 1) } + + before do + allow(helper).to receive(:current_user).and_return(user) + helper.instance_variable_set(:@project, project) + end + + context 'when there is no current_user' do + let(:user) { nil } + + it 'returns nil' do + expect(helper.last_push_event).to eq(nil) + end + end + + it 'returns recent push on the current project' do + event = double(:event) + expect(user).to receive(:recent_push).with([project.id]).and_return(event) + + expect(helper.last_push_event).to eq(event) + end + + context 'when current user has a fork of the current project' do + let(:fork) { double(:fork, id: 2) } + + it 'returns recent push considering fork events' do + expect(user).to receive(:fork_of).with(project).and_return(fork) + + event_on_fork = double(:event) + expect(user).to receive(:recent_push).with([project.id, fork.id]).and_return(event_on_fork) + + expect(helper.last_push_event).to eq(event_on_fork) + end + end + end end diff --git a/spec/javascripts/fixtures/projects.json b/spec/javascripts/fixtures/projects.json index 84e8d0ba1e4..4919d77e5a4 100644 --- a/spec/javascripts/fixtures/projects.json +++ b/spec/javascripts/fixtures/projects.json @@ -1 +1 @@ -[{"id":9,"description":"","default_branch":null,"tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:root/test.git","http_url_to_repo":"http://localhost:3000/root/test.git","web_url":"http://localhost:3000/root/test","owner":{"name":"Administrator","username":"root","id":1,"state":"active","avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon","web_url":"http://localhost:3000/u/root"},"name":"test","name_with_namespace":"Administrator / test","path":"test","path_with_namespace":"root/test","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-14T19:08:05.364Z","last_activity_at":"2016-01-14T19:08:07.418Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":1,"name":"root","path":"root","owner_id":1,"created_at":"2016-01-13T20:19:44.439Z","updated_at":"2016-01-13T20:19:44.439Z","description":"","avatar":null},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":0,"permissions":{"project_access":null,"group_access":null}},{"id":8,"description":"Voluptatem quae nulla eius numquam ullam voluptatibus quia modi.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:h5bp/html5-boilerplate.git","http_url_to_repo":"http://localhost:3000/h5bp/html5-boilerplate.git","web_url":"http://localhost:3000/h5bp/html5-boilerplate","name":"Html5 Boilerplate","name_with_namespace":"H5bp / Html5 Boilerplate","path":"html5-boilerplate","path_with_namespace":"h5bp/html5-boilerplate","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:57.525Z","last_activity_at":"2016-01-13T20:27:57.280Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":5,"name":"H5bp","path":"h5bp","owner_id":null,"created_at":"2016-01-13T20:19:57.239Z","updated_at":"2016-01-13T20:19:57.239Z","description":"Tempore accusantium possimus aut libero.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":5,"permissions":{"project_access":{"access_level":10,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}},{"id":7,"description":"Modi odio mollitia dolorem qui.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:twitter/typeahead-js.git","http_url_to_repo":"http://localhost:3000/twitter/typeahead-js.git","web_url":"http://localhost:3000/twitter/typeahead-js","name":"Typeahead.Js","name_with_namespace":"Twitter / Typeahead.Js","path":"typeahead-js","path_with_namespace":"twitter/typeahead-js","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:56.212Z","last_activity_at":"2016-01-13T20:27:51.496Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":4,"name":"Twitter","path":"twitter","owner_id":null,"created_at":"2016-01-13T20:19:54.480Z","updated_at":"2016-01-13T20:19:54.480Z","description":"Id voluptatem ipsa maiores omnis repudiandae et et.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":4,"permissions":{"project_access":null,"group_access":{"access_level":10,"notification_level":3}}},{"id":6,"description":"Omnis asperiores ipsa et beatae quidem necessitatibus quia.","default_branch":"master","tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:twitter/flight.git","http_url_to_repo":"http://localhost:3000/twitter/flight.git","web_url":"http://localhost:3000/twitter/flight","name":"Flight","name_with_namespace":"Twitter / Flight","path":"flight","path_with_namespace":"twitter/flight","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:54.754Z","last_activity_at":"2016-01-13T20:27:50.502Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":4,"name":"Twitter","path":"twitter","owner_id":null,"created_at":"2016-01-13T20:19:54.480Z","updated_at":"2016-01-13T20:19:54.480Z","description":"Id voluptatem ipsa maiores omnis repudiandae et et.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":4,"permissions":{"project_access":null,"group_access":{"access_level":10,"notification_level":3}}},{"id":5,"description":"Voluptatem commodi voluptate placeat architecto beatae illum dolores fugiat.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-test.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-test.git","web_url":"http://localhost:3000/gitlab-org/gitlab-test","name":"Gitlab Test","name_with_namespace":"Gitlab Org / Gitlab Test","path":"gitlab-test","path_with_namespace":"gitlab-org/gitlab-test","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:53.202Z","last_activity_at":"2016-01-13T20:27:41.626Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":5,"permissions":{"project_access":null,"group_access":{"access_level":50,"notification_level":3}}},{"id":4,"description":"Aut molestias quas est ut aperiam officia quod libero.","default_branch":"master","tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-shell.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-shell.git","web_url":"http://localhost:3000/gitlab-org/gitlab-shell","name":"Gitlab Shell","name_with_namespace":"Gitlab Org / Gitlab Shell","path":"gitlab-shell","path_with_namespace":"gitlab-org/gitlab-shell","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:51.882Z","last_activity_at":"2016-01-13T20:27:35.678Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":5,"permissions":{"project_access":{"access_level":20,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}},{"id":3,"description":"Excepturi molestiae quia repellendus omnis est illo illum eligendi.","default_branch":"master","tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-ci.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-ci.git","web_url":"http://localhost:3000/gitlab-org/gitlab-ci","name":"Gitlab Ci","name_with_namespace":"Gitlab Org / Gitlab Ci","path":"gitlab-ci","path_with_namespace":"gitlab-org/gitlab-ci","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:50.346Z","last_activity_at":"2016-01-13T20:27:30.115Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":3,"permissions":{"project_access":null,"group_access":{"access_level":50,"notification_level":3}}},{"id":2,"description":"Adipisci quaerat dignissimos enim sed ipsam dolorem quia.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":10,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-ce.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-ce.git","web_url":"http://localhost:3000/gitlab-org/gitlab-ce","name":"Gitlab Ce","name_with_namespace":"Gitlab Org / Gitlab Ce","path":"gitlab-ce","path_with_namespace":"gitlab-org/gitlab-ce","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:49.065Z","last_activity_at":"2016-01-13T20:26:58.454Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":5,"permissions":{"project_access":{"access_level":30,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}},{"id":1,"description":"Vel voluptatem maxime saepe ex quia.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:documentcloud/underscore.git","http_url_to_repo":"http://localhost:3000/documentcloud/underscore.git","web_url":"http://localhost:3000/documentcloud/underscore","name":"Underscore","name_with_namespace":"Documentcloud / Underscore","path":"underscore","path_with_namespace":"documentcloud/underscore","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:45.862Z","last_activity_at":"2016-01-13T20:25:03.106Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":2,"name":"Documentcloud","path":"documentcloud","owner_id":null,"created_at":"2016-01-13T20:19:44.464Z","updated_at":"2016-01-13T20:19:44.464Z","description":"Aut impedit perferendis fuga et ipsa repellat cupiditate et.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"open_issues_count":5,"permissions":{"project_access":null,"group_access":{"access_level":50,"notification_level":3}}}] +[{"id":9,"description":"","default_branch":null,"tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:root/test.git","http_url_to_repo":"http://localhost:3000/root/test.git","web_url":"http://localhost:3000/root/test","owner":{"name":"Administrator","username":"root","id":1,"state":"active","avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon","web_url":"http://localhost:3000/u/root"},"name":"test","name_with_namespace":"Administrator / test","path":"test","path_with_namespace":"root/test","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-14T19:08:05.364Z","last_activity_at":"2016-01-14T19:08:07.418Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":1,"name":"root","path":"root","owner_id":1,"created_at":"2016-01-13T20:19:44.439Z","updated_at":"2016-01-13T20:19:44.439Z","description":"","avatar":null},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":0,"permissions":{"project_access":null,"group_access":null}},{"id":8,"description":"Voluptatem quae nulla eius numquam ullam voluptatibus quia modi.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:h5bp/html5-boilerplate.git","http_url_to_repo":"http://localhost:3000/h5bp/html5-boilerplate.git","web_url":"http://localhost:3000/h5bp/html5-boilerplate","name":"Html5 Boilerplate","name_with_namespace":"H5bp / Html5 Boilerplate","path":"html5-boilerplate","path_with_namespace":"h5bp/html5-boilerplate","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:57.525Z","last_activity_at":"2016-01-13T20:27:57.280Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":5,"name":"H5bp","path":"h5bp","owner_id":null,"created_at":"2016-01-13T20:19:57.239Z","updated_at":"2016-01-13T20:19:57.239Z","description":"Tempore accusantium possimus aut libero.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":5,"permissions":{"project_access":{"access_level":10,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}},{"id":7,"description":"Modi odio mollitia dolorem qui.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:twitter/typeahead-js.git","http_url_to_repo":"http://localhost:3000/twitter/typeahead-js.git","web_url":"http://localhost:3000/twitter/typeahead-js","name":"Typeahead.Js","name_with_namespace":"Twitter / Typeahead.Js","path":"typeahead-js","path_with_namespace":"twitter/typeahead-js","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:56.212Z","last_activity_at":"2016-01-13T20:27:51.496Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":4,"name":"Twitter","path":"twitter","owner_id":null,"created_at":"2016-01-13T20:19:54.480Z","updated_at":"2016-01-13T20:19:54.480Z","description":"Id voluptatem ipsa maiores omnis repudiandae et et.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":true,"open_issues_count":4,"permissions":{"project_access":null,"group_access":{"access_level":10,"notification_level":3}}},{"id":6,"description":"Omnis asperiores ipsa et beatae quidem necessitatibus quia.","default_branch":"master","tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:twitter/flight.git","http_url_to_repo":"http://localhost:3000/twitter/flight.git","web_url":"http://localhost:3000/twitter/flight","name":"Flight","name_with_namespace":"Twitter / Flight","path":"flight","path_with_namespace":"twitter/flight","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:54.754Z","last_activity_at":"2016-01-13T20:27:50.502Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":4,"name":"Twitter","path":"twitter","owner_id":null,"created_at":"2016-01-13T20:19:54.480Z","updated_at":"2016-01-13T20:19:54.480Z","description":"Id voluptatem ipsa maiores omnis repudiandae et et.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":true,"open_issues_count":4,"permissions":{"project_access":null,"group_access":{"access_level":10,"notification_level":3}}},{"id":5,"description":"Voluptatem commodi voluptate placeat architecto beatae illum dolores fugiat.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-test.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-test.git","web_url":"http://localhost:3000/gitlab-org/gitlab-test","name":"Gitlab Test","name_with_namespace":"Gitlab Org / Gitlab Test","path":"gitlab-test","path_with_namespace":"gitlab-org/gitlab-test","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:53.202Z","last_activity_at":"2016-01-13T20:27:41.626Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":5,"permissions":{"project_access":null,"group_access":{"access_level":50,"notification_level":3}}},{"id":4,"description":"Aut molestias quas est ut aperiam officia quod libero.","default_branch":"master","tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-shell.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-shell.git","web_url":"http://localhost:3000/gitlab-org/gitlab-shell","name":"Gitlab Shell","name_with_namespace":"Gitlab Org / Gitlab Shell","path":"gitlab-shell","path_with_namespace":"gitlab-org/gitlab-shell","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:51.882Z","last_activity_at":"2016-01-13T20:27:35.678Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":5,"permissions":{"project_access":{"access_level":20,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}},{"id":3,"description":"Excepturi molestiae quia repellendus omnis est illo illum eligendi.","default_branch":"master","tag_list":[],"public":true,"archived":false,"visibility_level":20,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-ci.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-ci.git","web_url":"http://localhost:3000/gitlab-org/gitlab-ci","name":"Gitlab Ci","name_with_namespace":"Gitlab Org / Gitlab Ci","path":"gitlab-ci","path_with_namespace":"gitlab-org/gitlab-ci","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:50.346Z","last_activity_at":"2016-01-13T20:27:30.115Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":3,"permissions":{"project_access":null,"group_access":{"access_level":50,"notification_level":3}}},{"id":2,"description":"Adipisci quaerat dignissimos enim sed ipsam dolorem quia.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":10,"ssh_url_to_repo":"phil@localhost:gitlab-org/gitlab-ce.git","http_url_to_repo":"http://localhost:3000/gitlab-org/gitlab-ce.git","web_url":"http://localhost:3000/gitlab-org/gitlab-ce","name":"Gitlab Ce","name_with_namespace":"Gitlab Org / Gitlab Ce","path":"gitlab-ce","path_with_namespace":"gitlab-org/gitlab-ce","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:49.065Z","last_activity_at":"2016-01-13T20:26:58.454Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":3,"name":"Gitlab Org","path":"gitlab-org","owner_id":null,"created_at":"2016-01-13T20:19:48.851Z","updated_at":"2016-01-13T20:19:48.851Z","description":"Magni mollitia quod quidem soluta nesciunt impedit.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":5,"permissions":{"project_access":{"access_level":30,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}},{"id":1,"description":"Vel voluptatem maxime saepe ex quia.","default_branch":"master","tag_list":[],"public":false,"archived":false,"visibility_level":0,"ssh_url_to_repo":"phil@localhost:documentcloud/underscore.git","http_url_to_repo":"http://localhost:3000/documentcloud/underscore.git","web_url":"http://localhost:3000/documentcloud/underscore","name":"Underscore","name_with_namespace":"Documentcloud / Underscore","path":"underscore","path_with_namespace":"documentcloud/underscore","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"builds_enabled":true,"snippets_enabled":false,"created_at":"2016-01-13T20:19:45.862Z","last_activity_at":"2016-01-13T20:25:03.106Z","shared_runners_enabled":true,"creator_id":1,"namespace":{"id":2,"name":"Documentcloud","path":"documentcloud","owner_id":null,"created_at":"2016-01-13T20:19:44.464Z","updated_at":"2016-01-13T20:19:44.464Z","description":"Aut impedit perferendis fuga et ipsa repellat cupiditate et.","avatar":{"url":null}},"avatar_url":null,"star_count":0,"forks_count":0,"only_allow_merge_if_build_succeeds":false,"open_issues_count":5,"permissions":{"project_access":null,"group_access":{"access_level":50,"notification_level":3}}}] diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb index 86d04ecfa36..e10c1f5c547 100644 --- a/spec/lib/extracts_path_spec.rb +++ b/spec/lib/extracts_path_spec.rb @@ -51,6 +51,16 @@ describe ExtractsPath, lib: true do expect(@path).to eq(params[:path]) end end + + context 'subclass overrides get_id' do + it 'uses ref returned by get_id' do + allow_any_instance_of(self.class).to receive(:get_id){ '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' } + + assign_ref_vars + + expect(@id).to eq(get_id) + end + end end describe '#extract_ref' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 51e4780e2b1..8eb0c5033c9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -920,6 +920,16 @@ describe User, models: true do expect(subject.recent_push).to eq(nil) end + + it "includes push events on any of the provided projects" do + expect(subject.recent_push(project1)).to eq(nil) + expect(subject.recent_push(project2)).to eq(push_event) + + push_data1 = Gitlab::DataBuilder::Push.build_sample(project1, subject) + push_event1 = create(:event, action: Event::PUSHED, project: project1, target: project1, author: subject, data: push_data1) + + expect(subject.recent_push([project1, project2])).to eq(push_event1) # Newest + end end describe '#authorized_groups' do diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index a40e1a93b71..b8038fc85a1 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -61,6 +61,7 @@ describe API::API, api: true do expect(response).to have_http_status(200) expect(json_response).to be_an Array expect(json_response.first['title']).to eq(issue.title) + expect(json_response.last).to have_key('web_url') end it "adds pagination headers and keep query params" do diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 617600d6173..baff872e28e 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -33,6 +33,7 @@ describe API::API, api: true do expect(json_response).to be_an Array expect(json_response.length).to eq(3) expect(json_response.last['title']).to eq(merge_request.title) + expect(json_response.last).to have_key('web_url') end it "returns an array of all merge_requests" do diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb index 914e88c9487..765dc8a8f66 100644 --- a/spec/requests/api/project_hooks_spec.rb +++ b/spec/requests/api/project_hooks_spec.rb @@ -34,6 +34,7 @@ describe API::API, 'ProjectHooks', api: true do expect(json_response.first['note_events']).to eq(true) expect(json_response.first['build_events']).to eq(true) expect(json_response.first['pipeline_events']).to eq(true) + expect(json_response.first['wiki_page_events']).to eq(true) expect(json_response.first['enable_ssl_verification']).to eq(true) end end @@ -57,6 +58,9 @@ describe API::API, 'ProjectHooks', api: true do expect(json_response['merge_requests_events']).to eq(hook.merge_requests_events) expect(json_response['tag_push_events']).to eq(hook.tag_push_events) expect(json_response['note_events']).to eq(hook.note_events) + expect(json_response['build_events']).to eq(hook.build_events) + expect(json_response['pipeline_events']).to eq(hook.pipeline_events) + expect(json_response['wiki_page_events']).to eq(hook.wiki_page_events) expect(json_response['enable_ssl_verification']).to eq(hook.enable_ssl_verification) end @@ -93,6 +97,7 @@ describe API::API, 'ProjectHooks', api: true do expect(json_response['note_events']).to eq(false) expect(json_response['build_events']).to eq(false) expect(json_response['pipeline_events']).to eq(false) + expect(json_response['wiki_page_events']).to eq(false) expect(json_response['enable_ssl_verification']).to eq(true) end @@ -118,6 +123,9 @@ describe API::API, 'ProjectHooks', api: true do expect(json_response['merge_requests_events']).to eq(hook.merge_requests_events) expect(json_response['tag_push_events']).to eq(hook.tag_push_events) expect(json_response['note_events']).to eq(hook.note_events) + expect(json_response['build_events']).to eq(hook.build_events) + expect(json_response['pipeline_events']).to eq(hook.pipeline_events) + expect(json_response['wiki_page_events']).to eq(hook.wiki_page_events) expect(json_response['enable_ssl_verification']).to eq(hook.enable_ssl_verification) end diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index 42757ff21b0..01148f0a05e 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -30,6 +30,7 @@ describe API::API, api: true do expect(response).to have_http_status(200) expect(json_response.size).to eq(3) expect(json_response.map{ |snippet| snippet['id']} ).to include(public_snippet.id, internal_snippet.id, private_snippet.id) + expect(json_response.last).to have_key('web_url') end it 'hides private snippets from regular user' do diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 4742b3d0e37..63f2467be63 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -224,7 +224,8 @@ describe API::API, api: true do description: FFaker::Lorem.sentence, issues_enabled: false, merge_requests_enabled: false, - wiki_enabled: false + wiki_enabled: false, + only_allow_merge_if_build_succeeds: false }) post api('/projects', user), project @@ -276,6 +277,18 @@ describe API::API, api: true do expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) end + it 'sets a project as allowing merge even if build fails' do + project = attributes_for(:project, { only_allow_merge_if_build_succeeds: false }) + post api('/projects', user), project + expect(json_response['only_allow_merge_if_build_succeeds']).to be_falsey + end + + it 'sets a project as allowing merge only if build succeeds' do + project = attributes_for(:project, { only_allow_merge_if_build_succeeds: true }) + post api('/projects', user), project + expect(json_response['only_allow_merge_if_build_succeeds']).to be_truthy + end + context 'when a visibility level is restricted' do before do @project = attributes_for(:project, { public: true }) @@ -384,6 +397,18 @@ describe API::API, api: true do expect(json_response['public']).to be_falsey expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) end + + it 'sets a project as allowing merge even if build fails' do + project = attributes_for(:project, { only_allow_merge_if_build_succeeds: false }) + post api("/projects/user/#{user.id}", admin), project + expect(json_response['only_allow_merge_if_build_succeeds']).to be_falsey + end + + it 'sets a project as allowing merge only if build succeeds' do + project = attributes_for(:project, { only_allow_merge_if_build_succeeds: true }) + post api("/projects/user/#{user.id}", admin), project + expect(json_response['only_allow_merge_if_build_succeeds']).to be_truthy + end end describe "POST /projects/:id/uploads" do @@ -444,6 +469,7 @@ describe API::API, api: true do expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id) expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name) expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access) + expect(json_response['only_allow_merge_if_build_succeeds']).to eq(project.only_allow_merge_if_build_succeeds) end it 'returns a project by path name' do |