Commit 7ceea539 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'master' into fix-deploy-board

* master:
  Fixed failing tests with ajax spinner
  API: Return 400 for all validation erros in the mebers API
  Remove repository_storage from V4 "/application/settings" settings API
  Add repository storage field back to projects API
parents 2ee68d0a 02b67f1f
......@@ -46,6 +46,7 @@ require('./shortcuts_issuable');
require('./shortcuts_network');
require('vendor/jquery.nicescroll');
require('./geo/geo_bundle');
require('./ajax_loading_spinner');
// behaviors
require('./behaviors/autosize');
......
---
title: Remove repository_storage from V4 "/application/settings" settings API
merge_request:
author:
---
title: Add repository_storage field back to projects API for admin users
merge_request:
author:
---
title: 'API: Return 400 for all validation erros in the mebers API'
merge_request: 9523
author: Robert Schilling
......@@ -41,7 +41,6 @@ Example response:
"gravatar_enabled" : true,
"sign_in_text" : null,
"container_registry_token_expire_delay": 5,
"repository_storage": "default",
"repository_storages": ["default"],
"koding_enabled": false,
"koding_url": null,
......@@ -78,7 +77,6 @@ PUT /application/settings
| `after_sign_out_path` | string | no | Where to redirect users after logout |
| `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes |
| `repository_storages` | array of strings | no | A list of names of enabled storage paths, taken from `gitlab.yml`. New projects will be created in one of these stores, chosen at random. |
| `repository_storage` | string | no | The first entry in `repository_storages`. Deprecated, but retained for compatibility reasons |
| `enabled_git_access_protocol` | string | no | Enabled protocols for Git access. Allowed values are: `ssh`, `http`, and `nil` to allow both protocols. |
| `koding_enabled` | boolean | no | Enable Koding integration. Default is `false`. |
| `koding_url` | string | yes (if `koding_enabled` is `true`) | The Koding instance URL for integration. |
......@@ -123,7 +121,7 @@ Example response:
"user_oauth_applications": true,
"after_sign_out_path": "",
"container_registry_token_expire_delay": 5,
"repository_storage": "default",
"repository_storages": ["default"],
"koding_enabled": false,
"koding_url": null,
"plantuml_enabled": false,
......
......@@ -40,5 +40,10 @@ changes are in V4:
- POST/PUT/DELETE `:id/repository/files`
- Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936)
- Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736)
- Remove the ProjectGitHook API. Use the ProjectPushRule API instead [!1301](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1301)
- Notes do not return deprecated field `upvote` and `downvote` [!9384](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384)
- Return HTTP status code `400` for all validation errors when creating or updating a member instead of sometimes `422` error. [!9523](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9523)
#### EE-specific
- Remove the ProjectGitHook API. Use the ProjectPushRule API instead [!1301](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1301)
- Removed `repository_storage` from `PUT /application/settings` and `GET /application/settings` (use `repository_storages` instead) [!1307](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1307)
\ No newline at end of file
......@@ -21,6 +21,7 @@ module API
mount ::API::V3::Projects
mount ::API::V3::ProjectSnippets
mount ::API::V3::Repositories
mount ::API::V3::Settings
mount ::API::V3::Subscriptions
mount ::API::V3::SystemHooks
mount ::API::V3::Tags
......
......@@ -110,7 +110,7 @@ module API
expose :shared_with_groups do |project, options|
SharedGroup.represent(project.project_group_links.all, options)
end
expose :repository_storage, if: lambda { |_project, options| options[:user].try(:admin?) }
expose :repository_storage, if: lambda { |_project, options| options[:current_user].try(:admin?) }
expose :only_allow_merge_if_build_succeeds
expose :request_access_enabled
expose :only_allow_merge_if_all_discussions_are_resolved
......@@ -616,7 +616,6 @@ module API
expose :user_oauth_applications
expose :after_sign_out_path
expose :container_registry_token_expire_delay
expose :repository_storage
expose :repository_storages
expose :koding_enabled
expose :koding_url
......
......@@ -61,7 +61,6 @@ module API
## EE specific
member = source.members.find_by(user_id: params[:user_id])
conflict!('Member already exists') if member
member = source.add_user(params[:user_id], params[:access_level], current_user: current_user, expires_at: params[:expires_at])
......@@ -69,9 +68,6 @@ module API
if member.persisted? && member.valid?
present member.user, with: Entities::Member, member: member
else
# This is to ensure back-compatibility but 400 behavior should be used
# for all validation errors in 9.0!
render_api_error!('Access level is not known', 422) if member.errors.key?(:access_level)
render_validation_error!(member)
end
end
......@@ -93,9 +89,6 @@ module API
if member.update_attributes(declared_params(include_missing: false))
present member.user, with: Entities::Member, member: member
else
# This is to ensure back-compatibility but 400 behavior should be used
# for all validation errors in 9.0!
render_api_error!('Access level is not known', 422) if member.errors.key?(:access_level)
render_validation_error!(member)
end
end
......
......@@ -118,8 +118,6 @@ module API
requires :elasticsearch_port, type: Integer, desc: 'The TCP/IP port that Elasticsearch listens to. The default value is 9200'
end
optional :usage_ping_enabled, type: Boolean, desc: 'Every week GitLab will report license usage back to GitLab, Inc.'
# TODO: Remove repository_storage in 9.0
optional :repository_storage, type: String, desc: 'The first entry in `repository_storages`. Deprecated, but retained for compatibility reasons'
optional :repository_storages, type: Array[String], desc: 'A list of names of enabled storage paths, taken from `gitlab.yml`. New projects will be created in one of these stores, chosen at random.'
optional :repository_size_limit, type: Integer, desc: 'Size limit per repository (MB)'
at_least_one_of :default_branch_protection, :default_project_visibility, :default_snippet_visibility,
......@@ -137,7 +135,7 @@ module API
:version_check_enabled, :email_author_in_body, :html_emails_enabled,
# GitLab-EE specific settings
:help_text, :elasticsearch_indexing, :usage_ping_enabled,
:repository_storage, :repository_storages, :repository_size_limit
:repository_storages, :repository_size_limit
end
put "application/settings" do
if current_settings.update_attributes(declared_params(include_missing: false))
......
......@@ -45,6 +45,39 @@ module API
expose :created_at, :updated_at
expose :awardable_id, :awardable_type
end
class ApplicationSetting < Grape::Entity
expose :id
expose :default_projects_limit
expose :signup_enabled
expose :signin_enabled
expose :gravatar_enabled
expose :sign_in_text
expose :after_sign_up_text
expose :created_at
expose :updated_at
expose :home_page_url
expose :default_branch_protection
expose :restricted_visibility_levels
expose :max_attachment_size
expose :session_expire_delay
expose :default_project_visibility
expose :default_snippet_visibility
expose :default_group_visibility
expose :domain_whitelist
expose :domain_blacklist_enabled
expose :domain_blacklist
expose :user_oauth_applications
expose :after_sign_out_path
expose :container_registry_token_expire_delay
expose :repository_storage
expose :repository_storages
expose :koding_enabled
expose :koding_url
expose :plantuml_enabled
expose :plantuml_url
expose :terminal_max_session_time
end
end
end
end
This diff is collapsed.
......@@ -173,11 +173,11 @@ describe API::Members, api: true do
expect(response).to have_http_status(400)
end
it 'returns 422 when access_level is not valid' do
it 'returns 400 when access_level is not valid' do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id, access_level: 1234
expect(response).to have_http_status(422)
expect(response).to have_http_status(400)
end
end
end
......@@ -247,11 +247,11 @@ describe API::Members, api: true do
expect(response).to have_http_status(400)
end
it 'returns 422 when access level is not valid' do
it 'returns 400 when access level is not valid' do
put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
access_level: 1234
expect(response).to have_http_status(422)
expect(response).to have_http_status(400)
end
end
end
......@@ -363,7 +363,7 @@ describe API::Members, api: true do
post api("/projects/#{project.id}/members", master),
user_id: stranger.id, access_level: Member::OWNER
expect(response).to have_http_status(422)
expect(response).to have_http_status(400)
end.to change { project.members.count }.by(0)
end
end
......
......@@ -512,7 +512,57 @@ describe API::Projects, api: true do
end
end
context 'when authenticated' do
context 'when authenticated as an admin' do
it 'returns a project by id including repository_storage' do
project
project_member
group = create(:group)
link = create(:project_group_link, project: project, group: group)
get api("/projects/#{project.id}", admin)
expect(response).to have_http_status(200)
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
expect(json_response['tag_list']).to be_an Array
expect(json_response['public']).to be_falsey
expect(json_response['archived']).to be_falsey
expect(json_response['visibility_level']).to be_present
expect(json_response['ssh_url_to_repo']).to be_present
expect(json_response['http_url_to_repo']).to be_present
expect(json_response['web_url']).to be_present
expect(json_response['owner']).to be_a Hash
expect(json_response['owner']).to be_a Hash
expect(json_response['name']).to eq(project.name)
expect(json_response['path']).to be_present
expect(json_response['issues_enabled']).to be_present
expect(json_response['merge_requests_enabled']).to be_present
expect(json_response['wiki_enabled']).to be_present
expect(json_response['builds_enabled']).to be_present
expect(json_response['snippets_enabled']).to be_present
expect(json_response['container_registry_enabled']).to be_present
expect(json_response['created_at']).to be_present
expect(json_response['last_activity_at']).to be_present
expect(json_response['shared_runners_enabled']).to be_present
expect(json_response['creator_id']).to be_present
expect(json_response['namespace']).to be_present
expect(json_response['avatar_url']).to be_nil
expect(json_response['star_count']).to be_present
expect(json_response['forks_count']).to be_present
expect(json_response['public_builds']).to be_present
expect(json_response['shared_with_groups']).to be_an Array
expect(json_response['shared_with_groups'].length).to eq(1)
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)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['repository_storage']).to eq(project.repository_storage)
end
end
context 'when authenticated as a regular user' do
before do
project
project_member
......@@ -561,6 +611,7 @@ describe API::Projects, api: true do
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)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response).not_to have_key('repository_storage')
end
it 'returns a project by path name' do
......
......@@ -9,11 +9,12 @@ describe API::Settings, 'Settings', api: true do
describe "GET /application/settings" do
it "returns application settings" do
get api("/application/settings", admin)
expect(response).to have_http_status(200)
expect(json_response).to be_an Hash
expect(json_response['default_projects_limit']).to eq(42)
expect(json_response['signin_enabled']).to be_truthy
expect(json_response['repository_storage']).to eq('default')
expect(json_response['repository_storages']).to eq(['default'])
expect(json_response['koding_enabled']).to be_falsey
expect(json_response['koding_url']).to be_nil
expect(json_response['plantuml_enabled']).to be_falsey
......@@ -30,12 +31,12 @@ describe API::Settings, 'Settings', api: true do
it "updates application settings" do
put api("/application/settings", admin),
default_projects_limit: 3, signin_enabled: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com',
default_projects_limit: 3, signin_enabled: false, repository_storages: ['custom'], koding_enabled: true, koding_url: 'http://koding.example.com',
plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com'
expect(response).to have_http_status(200)
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['signin_enabled']).to be_falsey
expect(json_response['repository_storage']).to eq('custom')
expect(json_response['repository_storages']).to eq(['custom'])
expect(json_response['koding_enabled']).to be_truthy
expect(json_response['koding_url']).to eq('http://koding.example.com')
......
......@@ -595,6 +595,56 @@ describe API::V3::Projects, api: true do
end
end
context 'when authenticated as an admin' do
it 'returns a project by id including repository_storage' do
project
project_member
group = create(:group)
link = create(:project_group_link, project: project, group: group)
get v3_api("/projects/#{project.id}", admin)
expect(response).to have_http_status(200)
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
expect(json_response['tag_list']).to be_an Array
expect(json_response['public']).to be_falsey
expect(json_response['archived']).to be_falsey
expect(json_response['visibility_level']).to be_present
expect(json_response['ssh_url_to_repo']).to be_present
expect(json_response['http_url_to_repo']).to be_present
expect(json_response['web_url']).to be_present
expect(json_response['owner']).to be_a Hash
expect(json_response['owner']).to be_a Hash
expect(json_response['name']).to eq(project.name)
expect(json_response['path']).to be_present
expect(json_response['issues_enabled']).to be_present
expect(json_response['merge_requests_enabled']).to be_present
expect(json_response['wiki_enabled']).to be_present
expect(json_response['builds_enabled']).to be_present
expect(json_response['snippets_enabled']).to be_present
expect(json_response['container_registry_enabled']).to be_present
expect(json_response['created_at']).to be_present
expect(json_response['last_activity_at']).to be_present
expect(json_response['shared_runners_enabled']).to be_present
expect(json_response['creator_id']).to be_present
expect(json_response['namespace']).to be_present
expect(json_response['avatar_url']).to be_nil
expect(json_response['star_count']).to be_present
expect(json_response['forks_count']).to be_present
expect(json_response['public_builds']).to be_present
expect(json_response['shared_with_groups']).to be_an Array
expect(json_response['shared_with_groups'].length).to eq(1)
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)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['repository_storage']).to eq(project.repository_storage)
end
end
context 'when authenticated' do
before do
project
......@@ -644,6 +694,7 @@ describe API::V3::Projects, api: true do
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)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response).not_to have_key('repository_storage')
end
it 'returns a project by path name' do
......
require 'spec_helper'
describe API::V3::Settings, 'Settings', api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:admin) { create(:admin) }
describe "GET /application/settings" do
it "returns application settings" do
get v3_api("/application/settings", admin)
expect(response).to have_http_status(200)
expect(json_response).to be_an Hash
expect(json_response['default_projects_limit']).to eq(42)
expect(json_response['signin_enabled']).to be_truthy
expect(json_response['repository_storage']).to eq('default')
expect(json_response['koding_enabled']).to be_falsey
expect(json_response['koding_url']).to be_nil
expect(json_response['plantuml_enabled']).to be_falsey
expect(json_response['plantuml_url']).to be_nil
end
end
describe "PUT /application/settings" do
context "custom repository storage type set in the config" do
before do
storages = { 'custom' => 'tmp/tests/custom_repositories' }
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
end
it "updates application settings" do
put v3_api("/application/settings", admin),
default_projects_limit: 3, signin_enabled: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com',
plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com'
expect(response).to have_http_status(200)
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['signin_enabled']).to be_falsey
expect(json_response['repository_storage']).to eq('custom')
expect(json_response['repository_storages']).to eq(['custom'])
expect(json_response['koding_enabled']).to be_truthy
expect(json_response['koding_url']).to eq('http://koding.example.com')
expect(json_response['plantuml_enabled']).to be_truthy
expect(json_response['plantuml_url']).to eq('http://plantuml.example.com')
end
end
context "missing koding_url value when koding_enabled is true" do
it "returns a blank parameter error message" do
put v3_api("/application/settings", admin), koding_enabled: true
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('koding_url is missing')
end
end
context "missing plantuml_url value when plantuml_enabled is true" do
it "returns a blank parameter error message" do
put v3_api("/application/settings", admin), plantuml_enabled: true
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('plantuml_url is missing')
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment