diff options
39 files changed, 250 insertions, 203 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c039335c46d..f279a57105c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 8.17.1 (2017-02-28) + +- Replace setInterval with setTimeout to prevent highly frequent requests. !9271 (Takuya Noguchi) +- Disable unused tags count cache for Projects, Builds and Runners. +- Spam check and reCAPTCHA improvements. +- Allow searching issues for strings containing colons. +- Disabled tooltip on add issues button in usse boards. +- Fixed commit search UI. +- Fix MR changes tab size count when there are over 100 files in the diff. +- Disable invalid service templates. +- Use default branch as target_branch when parameter is missing. +- Upgrade GitLab Pages to v0.3.2. +- Add performance query regression fix for !9088 affecting #27267. +- Chat slash commands show labels correctly. + ## 8.17.0 (2017-02-22) - API: Fix file downloading. !0 (8267) diff --git a/app/assets/javascripts/environments/components/environment.js.es6 b/app/assets/javascripts/environments/components/environment.js.es6 index 4b700a39d44..5869323d1e2 100644 --- a/app/assets/javascripts/environments/components/environment.js.es6 +++ b/app/assets/javascripts/environments/components/environment.js.es6 @@ -145,7 +145,7 @@ module.exports = Vue.component('environment-component', { </div> </div> - <div class="environments-container"> + <div class="content-list environments-container"> <div class="environments-list-loading text-center" v-if="isLoading"> <i class="fa fa-spinner fa-spin"></i> </div> @@ -181,12 +181,12 @@ module.exports = Vue.component('environment-component', { :terminal-icon-svg="terminalIconSvg" :commit-icon-svg="commitIconSvg"> </environment-table> - - <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" - :change="changePage" - :pageInfo="state.paginationInformation"> - </table-pagination> </div> + + <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" + :change="changePage" + :pageInfo="state.paginationInformation"> + </table-pagination> </div> </div> `, diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js.es6 index 5d780bddb0e..3f782742c56 100644 --- a/app/assets/javascripts/environments/components/environment_item.js.es6 +++ b/app/assets/javascripts/environments/components/environment_item.js.es6 @@ -503,7 +503,7 @@ module.exports = Vue.component('environment-item', { </span> </td> - <td class="hidden-xs environments-actions"> + <td class="environments-actions"> <div v-if="!model.isFolder" class="btn-group pull-right" role="group"> <actions-component v-if="hasManualActions && canCreateDeployment" :play-icon-svg="playIconSvg" diff --git a/app/assets/javascripts/environments/components/environments_table.js.es6 b/app/assets/javascripts/environments/components/environments_table.js.es6 index fd35d77fd3d..33ebca19f5d 100644 --- a/app/assets/javascripts/environments/components/environments_table.js.es6 +++ b/app/assets/javascripts/environments/components/environments_table.js.es6 @@ -46,7 +46,7 @@ module.exports = Vue.component('environment-table-component', { }, template: ` - <table class="table ci-table environments"> + <table class="table ci-table"> <thead> <tr> <th class="environments-name">Environment</th> @@ -54,7 +54,7 @@ module.exports = Vue.component('environment-table-component', { <th class="environments-build">Job</th> <th class="environments-commit">Commit</th> <th class="environments-date">Updated</th> - <th class="hidden-xs environments-actions"></th> + <th class="environments-actions"></th> </tr> </thead> <tbody> diff --git a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 index e20085d1fd2..b50afe7c594 100644 --- a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 +++ b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 @@ -32,7 +32,7 @@ }, }, template: ` - <td class="pipeline-actions hidden-xs"> + <td class="pipeline-actions"> <div class="pull-right"> <div class="btn-group"> <div class="btn-group" v-if="actions"> diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 index 4bdaef31ee9..34d3bbdd80d 100644 --- a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 +++ b/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 @@ -44,7 +44,7 @@ require('./pipelines_table_row'); <th class="js-pipeline-commit pipeline-commit">Commit</th> <th class="js-pipeline-stages pipeline-stages">Stages</th> <th class="js-pipeline-date pipeline-date"></th> - <th class="js-pipeline-actions pipeline-actions hidden-xs"></th> + <th class="js-pipeline-actions pipeline-actions"></th> </tr> </thead> <tbody> diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 3945a789c82..685a4847731 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -148,16 +148,11 @@ header { } .header-logo { - position: absolute; - left: 50%; + display: inline-block; + margin: 0 8px 0 3px; + position: relative; top: 7px; transition-duration: .3s; - z-index: 999; - - #logo { - position: relative; - left: -50%; - } svg, img { @@ -167,15 +162,6 @@ header { &:hover { cursor: pointer; } - - @media (max-width: $screen-xs-max) { - right: 20px; - left: auto; - - #logo { - left: auto; - } - } } .title { @@ -183,7 +169,6 @@ header { padding-right: 20px; margin: 0; font-size: 18px; - max-width: 385px; display: inline-block; line-height: $header-height; font-weight: normal; @@ -193,14 +178,18 @@ header { vertical-align: top; white-space: nowrap; - @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { - max-width: 300px; - } - @media (max-width: $screen-xs-max) { max-width: 190px; } + @media (min-width: $screen-sm-min) and (max-width: $screen-md-max) { + max-width: 428px; + } + + @media (min-width: $screen-lg-min) { + max-width: 685px; + } + a { color: $gl-text-color; diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index f789ae1ccd3..77e09e66340 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -15,112 +15,97 @@ padding-top: 20px; } -@media (max-width: $screen-xs-max) { - .environments-container { +.environments-container { + .table-holder { width: 100%; overflow: auto; } -} - -.environments { - table-layout: fixed; - - .environments-commit, - .environments-actions, - .environments-deploy, - .environments-build, - .environments-date { - position: static; - float: none; - display: table-cell; - } - - .environments-commit, - .environments-actions { - width: 20%; - } - - .environments-date { - width: 10%; - } - .environments-name, - .environments-deploy, - .environments-build { - width: 15%; - } - - .environment-name, - .environments-build-cell, - .deployment-column { - word-break: break-all; - } - - .deployment-column { - .avatar { - float: none; + .table.ci-table { + .environments-actions { + min-width: 200px; } - } - .btn-group { + .environments-commit, + .environments-actions { + width: 20%; + } - > a { - color: $gl-text-color-secondary; + .environments-date { + width: 10%; } - svg path { - fill: $gl-text-color-secondary; + .environments-name, + .environments-deploy, + .environments-build { + width: 15%; } - .dropdown { - outline: none; + .deployment-column { + > span { + word-break: break-all; + } + + .avatar { + float: none; + } } - } + .btn-group { - .commit-title { - margin: 0; - } + > a { + color: $gl-text-color-secondary; + } - .avatar-image-container { - text-decoration: none; - } + svg path { + fill: $gl-text-color-secondary; + } - .icon-play { - height: 13px; - width: 12px; - } + .dropdown { + outline: none; + } + } - .external-url, - .dropdown-new { - color: $gl-text-color-secondary; - } + .commit-title { + margin: 0; + } - .dropdown-menu { + .avatar-image-container { + text-decoration: none; + } - .fa { - margin-right: 6px; - color: $gl-text-color-secondary; + .icon-play { + height: 13px; + width: 12px; } - } - .build-link, - .branch-name { - color: $gl-text-color; - } + .external-url, + .dropdown-new { + color: $gl-text-color-secondary; + } - .stop-env-link, - .external-url { - color: $gl-text-color-secondary; + .dropdown-menu { + .fa { + margin-right: 6px; + color: $gl-text-color-secondary; + } + } - .stop-env-icon { - font-size: 14px; + .build-link, + .branch-name { + color: $gl-text-color; } - } - .deployment { - .build-column { + .stop-env-link, + .external-url { + color: $gl-text-color-secondary; + + .stop-env-icon { + font-size: 14px; + } + } + .deployment .build-column { .build-link { color: $gl-text-color; } @@ -129,34 +114,32 @@ float: none; } } - } - - .folder-icon { - margin-right: 3px; - color: $gl-text-color-secondary; - display: inline-block; - .fa:nth-child(1) { + .folder-icon { margin-right: 3px; + color: $gl-text-color-secondary; + display: inline-block; + + .fa:nth-child(1) { + margin-right: 3px; + } } - } - .folder-name { - cursor: pointer; - color: $gl-text-color-secondary; - display: inline-block; - } -} + .folder-name { + cursor: pointer; + color: $gl-text-color-secondary; + display: inline-block; + } -.table.ci-table.environments { - .icon-container { - width: 20px; - text-align: center; - } + .icon-container { + width: 20px; + text-align: center; + } - .branch-commit { - .commit-id { - margin-right: 0; + .branch-commit { + .commit-id { + margin-right: 0; + } } } } diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index f4707f71208..69eea1b2217 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -105,6 +105,7 @@ @media (max-width: $screen-md-max) { .content-list { &.pipelines, + &.environments-container, &.builds-content-list { width: 100%; overflow: auto; diff --git a/app/models/project_group_link.rb b/app/models/project_group_link.rb index 5cb6b0c527d..ac1e9ab2b0b 100644 --- a/app/models/project_group_link.rb +++ b/app/models/project_group_link.rb @@ -33,8 +33,15 @@ class ProjectGroupLink < ActiveRecord::Base private def different_group - if self.group && self.project && self.project.group == self.group - errors.add(:base, "Project cannot be shared with the project it is in.") + return unless self.group && self.project + + project_group = self.project.group + return unless project_group + + group_ids = project_group.ancestors.map(&:id).push(project_group.id) + + if group_ids.include?(self.group.id) + errors.add(:base, "Project cannot be shared with the group it is in or one of its ancestors.") end end diff --git a/app/views/groups/_head.html.haml b/app/views/groups/_head.html.haml index 6b296ea8dea..873504099d4 100644 --- a/app/views/groups/_head.html.haml +++ b/app/views/groups/_head.html.haml @@ -3,7 +3,7 @@ = render 'shared/nav_scroll' .nav-links.sub-nav.scrolling-tabs %ul{ class: container_class } - = nav_link(path: 'groups#show', html_options: { class: 'home' }) do + = nav_link(path: ['groups#show', 'groups#subgroups'], html_options: { class: 'home' }) do = link_to group_path(@group), title: 'Group Home' do %span Home @@ -12,8 +12,3 @@ = link_to activity_group_path(@group), title: 'Activity' do %span Activity - - = nav_link(path: 'group_members#index') do - = link_to group_group_members_path(@group), title: 'Members' do - %span - Members diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index 8cb56443191..2e4e4511bb6 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -1,5 +1,4 @@ - page_title "Members" -= render 'groups/head' .project-members-page.prepend-top-default %h4 diff --git a/app/views/groups/subgroups.html.haml b/app/views/groups/subgroups.html.haml index 8610ae7e0ef..be809083139 100644 --- a/app/views/groups/subgroups.html.haml +++ b/app/views/groups/subgroups.html.haml @@ -1,5 +1,6 @@ - @no_container = true += render 'head' = render 'groups/home_panel' .groups-header{ class: container_class } diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 0b8388cbff3..c28661c2351 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -36,6 +36,10 @@ = icon('bell fw') %span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) } = todos_count_format(todos_pending_count) + - if current_user.can_create_project? + %li + = link_to new_project_path, title: 'New project', aria: { label: "New project" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = icon('plus fw') - if Gitlab::Sherlock.enabled? %li = link_to sherlock_transactions_path, title: 'Sherlock Transactions', @@ -61,12 +65,12 @@ %div = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success' - %h1.title= title - .header-logo = link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do = brand_header_logo + %h1.title= title + = yield :header_content = render 'shared/outdated_browser' diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index e0742d70fac..a6e96942021 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -5,7 +5,7 @@ .fade-right = icon('angle-right') %ul.nav-links.scrolling-tabs - = nav_link(path: ['groups#show', 'groups#activity', 'group_members#index'], html_options: { class: 'home' }) do + = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do = link_to group_path(@group), title: 'Home' do %span Group @@ -21,3 +21,7 @@ Merge Requests - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute %span.badge.count= number_with_delimiter(merge_requests.count) + = nav_link(path: 'group_members#index') do + = link_to group_group_members_path(@group), title: 'Members' do + %span + Members diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index e2f132f7742..7f9a44e565f 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -3,7 +3,7 @@ = render "projects/commits/head" .flex-list{ class: container_class } - .top-area.flex-row + .top-area.adjust .nav-text.row-main-content Tags give the ability to mark specific points in history as being important diff --git a/changelogs/unreleased/27267-events-project-query-performance-regression.yml b/changelogs/unreleased/27267-events-project-query-performance-regression.yml deleted file mode 100644 index a1697b57eac..00000000000 --- a/changelogs/unreleased/27267-events-project-query-performance-regression.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Add performance query regression fix for !9088 affecting #27267' -merge_request: -author: diff --git a/changelogs/unreleased/27354-navigation-new-button.yml b/changelogs/unreleased/27354-navigation-new-button.yml new file mode 100644 index 00000000000..62cac9bbbd3 --- /dev/null +++ b/changelogs/unreleased/27354-navigation-new-button.yml @@ -0,0 +1,4 @@ +--- +title: Re-add the New Project button in nav bar +merge_request: +author: diff --git a/changelogs/unreleased/27934-left-align-logo.yml b/changelogs/unreleased/27934-left-align-logo.yml new file mode 100644 index 00000000000..d4e5e169465 --- /dev/null +++ b/changelogs/unreleased/27934-left-align-logo.yml @@ -0,0 +1,4 @@ +--- +title: Left align logo +merge_request: +author: diff --git a/changelogs/unreleased/27989-disable-counting-tags.yml b/changelogs/unreleased/27989-disable-counting-tags.yml deleted file mode 100644 index 988785ac454..00000000000 --- a/changelogs/unreleased/27989-disable-counting-tags.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disable unused tags count cache for Projects, Builds and Runners -merge_request: -author: diff --git a/changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml b/changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml deleted file mode 100644 index d70b5ef8fd5..00000000000 --- a/changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Spam check and reCAPTCHA improvements -merge_request: -author: diff --git a/changelogs/unreleased/28212-avoid-dos-on-build-trace.yml b/changelogs/unreleased/28212-avoid-dos-on-build-trace.yml deleted file mode 100644 index 800e0389c86..00000000000 --- a/changelogs/unreleased/28212-avoid-dos-on-build-trace.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replace setInterval with setTimeout to prevent highly frequent requests -merge_request: 9271 -author: Takuya Noguchi diff --git a/changelogs/unreleased/28357-colon-search.yml b/changelogs/unreleased/28357-colon-search.yml deleted file mode 100644 index 4bbb0dc12b2..00000000000 --- a/changelogs/unreleased/28357-colon-search.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow searching issues for strings containing colons -merge_request: -author: diff --git a/changelogs/unreleased/6073_project_api.yml b/changelogs/unreleased/6073_project_api.yml new file mode 100644 index 00000000000..fd6792a406e --- /dev/null +++ b/changelogs/unreleased/6073_project_api.yml @@ -0,0 +1,4 @@ +--- +title: 'API project create: Make name or path required' +merge_request: 9416 +author: diff --git a/changelogs/unreleased/add-issues-tooltip.yml b/changelogs/unreleased/add-issues-tooltip.yml deleted file mode 100644 index 58adb6c6b5a..00000000000 --- a/changelogs/unreleased/add-issues-tooltip.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disabled tooltip on add issues button in usse boards -merge_request: -author: diff --git a/changelogs/unreleased/commit-search-ui-fix.yml b/changelogs/unreleased/commit-search-ui-fix.yml deleted file mode 100644 index 4a5c2cf6090..00000000000 --- a/changelogs/unreleased/commit-search-ui-fix.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed commit search UI -merge_request: -author: diff --git a/changelogs/unreleased/issue-tags-layout.yml b/changelogs/unreleased/issue-tags-layout.yml new file mode 100644 index 00000000000..abf4a609932 --- /dev/null +++ b/changelogs/unreleased/issue-tags-layout.yml @@ -0,0 +1,4 @@ +--- +title: Fix 'New Tag' layout on Tags page +merge_request: +author: Robert Marcano diff --git a/changelogs/unreleased/issue_25112.yml b/changelogs/unreleased/issue_25112.yml deleted file mode 100644 index c43d2732b9a..00000000000 --- a/changelogs/unreleased/issue_25112.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disable invalid service templates -merge_request: -author: diff --git a/changelogs/unreleased/issue_28051_2.yml b/changelogs/unreleased/issue_28051_2.yml deleted file mode 100644 index 8cc32ad8493..00000000000 --- a/changelogs/unreleased/issue_28051_2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use default branch as target_branch when parameter is missing -merge_request: -author: diff --git a/changelogs/unreleased/pages-0-3-2.yml b/changelogs/unreleased/pages-0-3-2.yml deleted file mode 100644 index f660379f2e6..00000000000 --- a/changelogs/unreleased/pages-0-3-2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Upgrade GitLab Pages to v0.3.2 -merge_request: -author: diff --git a/changelogs/unreleased/zj-fix-slash-command-labels.yml b/changelogs/unreleased/zj-fix-slash-command-labels.yml deleted file mode 100644 index 93b7194dd4e..00000000000 --- a/changelogs/unreleased/zj-fix-slash-command-labels.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Chat slash commands show labels correctly -merge_request: -author: diff --git a/doc/api/projects.md b/doc/api/projects.md index 1a8c0ae758f..5de23908b42 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -435,8 +435,8 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `name` | string | yes | The name of the new project | -| `path` | string | no | Custom repository name for new project. By default generated based on name | +| `name` | string | yes if path is not provided | The name of the new project. Equals path if not provided. | +| `path` | string | yes if name is not provided | Repository name for new project. Generated based on name if not provided (generated lowercased with dashes). | | `namespace_id` | integer | no | Namespace for the new project (defaults to the current user's namespace) | | `description` | string | no | Short project description | | `issues_enabled` | boolean | no | Enable issues for this project | diff --git a/doc/development/frontend.md b/doc/development/frontend.md index ba47998de49..9ba820eaee5 100644 --- a/doc/development/frontend.md +++ b/doc/development/frontend.md @@ -238,6 +238,9 @@ readability. See the relevant style guides for our guidelines and for information on linting: - [SCSS][scss-style-guide] +- JavaScript - We defer to [AirBnb][airbnb-js-style-guide] on most style-related +conventions and enforce them with eslint. See [our current .eslintrc][eslistrc] +for specific rules and patterns. ## Testing @@ -434,3 +437,5 @@ Scenario: Developer can approve merge request [state-management]: https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch [vue-resource-repo]: https://github.com/pagekit/vue-resource [issue-boards-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/boards/services/board_service.js.es6 +[airbnb-js-style-guide]: https://github.com/airbnb/javascript +[eslintrc]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.eslintrc diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature index 92061dac7f4..b1d5e4a7acb 100644 --- a/features/dashboard/dashboard.feature +++ b/features/dashboard/dashboard.feature @@ -11,6 +11,7 @@ Feature: Dashboard And I visit dashboard page Scenario: I should see projects list + Then I should see "New Project" link Then I should see "Shop" project link Then I should see "Shop" project CI status diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 310a896e958..b8a8cee0cea 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -94,8 +94,9 @@ module API success Entities::Project end params do - requires :name, type: String, desc: 'The name of the project' + optional :name, type: String, desc: 'The name of the project' optional :path, type: String, desc: 'The path of the repository' + at_least_one_of :name, :path use :optional_params use :create_params end diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index f3cd0b22e9b..881d52e4aa4 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -172,8 +172,9 @@ module API success ::API::Entities::Project end params do - requires :name, type: String, desc: 'The name of the project' + optional :name, type: String, desc: 'The name of the project' optional :path, type: String, desc: 'The path of the repository' + at_least_one_of :name, :path use :optional_params use :create_params end diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb index 59a4ae1b799..9b711bfc007 100644 --- a/spec/models/project_group_link_spec.rb +++ b/spec/models/project_group_link_spec.rb @@ -7,12 +7,27 @@ describe ProjectGroupLink do end describe "Validation" do - let!(:project_group_link) { create(:project_group_link) } + let(:parent_group) { create(:group) } + let(:group) { create(:group, parent: parent_group) } + let(:project) { create(:project, group: group) } + let!(:project_group_link) { create(:project_group_link, project: project) } it { should validate_presence_of(:project_id) } it { should validate_uniqueness_of(:group_id).scoped_to(:project_id).with_message(/already shared/) } it { should validate_presence_of(:group) } it { should validate_presence_of(:group_access) } + + it "doesn't allow a project to be shared with the group it is in" do + project_group_link.group = group + + expect(project_group_link).not_to be_valid + end + + it "doesn't allow a project to be shared with an ancestor of the group it is in" do + project_group_link.group = parent_group + + expect(project_group_link).not_to be_valid + end end describe "destroying a record", truncate: true do diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index d2acce90a24..3a00d974633 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -269,10 +269,37 @@ describe API::Projects, api: true do end end - it 'creates new project without path and return 201' do - expect { post api('/projects', user), name: 'foo' }. + it 'creates new project without path but with name and returns 201' do + expect { post api('/projects', user), name: 'Foo Project' }. + to change { Project.count }.by(1) + expect(response).to have_http_status(201) + + project = Project.first + + expect(project.name).to eq('Foo Project') + expect(project.path).to eq('foo-project') + end + + it 'creates new project without name but with path and returns 201' do + expect { post api('/projects', user), path: 'foo_project' }. to change { Project.count }.by(1) expect(response).to have_http_status(201) + + project = Project.first + + expect(project.name).to eq('foo_project') + expect(project.path).to eq('foo_project') + end + + it 'creates new project name and path and returns 201' do + expect { post api('/projects', user), path: 'foo-Project', name: 'Foo Project' }. + to change { Project.count }.by(1) + expect(response).to have_http_status(201) + + project = Project.first + + expect(project.name).to eq('Foo Project') + expect(project.path).to eq('foo-Project') end it 'creates last project before reaching project limit' do @@ -281,7 +308,7 @@ describe API::Projects, api: true do expect(response).to have_http_status(201) end - it 'does not create new project without name and return 400' do + it 'does not create new project without name or path and returns 400' do expect { post api('/projects', user) }.not_to change { Project.count } expect(response).to have_http_status(400) end diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb index 662be3f3531..34940b2f1c7 100644 --- a/spec/requests/api/v3/projects_spec.rb +++ b/spec/requests/api/v3/projects_spec.rb @@ -309,10 +309,37 @@ describe API::V3::Projects, api: true do end end - it 'creates new project without path and return 201' do - expect { post v3_api('/projects', user), name: 'foo' }. + it 'creates new project without path but with name and returns 201' do + expect { post v3_api('/projects', user), name: 'Foo Project' }. to change { Project.count }.by(1) expect(response).to have_http_status(201) + + project = Project.first + + expect(project.name).to eq('Foo Project') + expect(project.path).to eq('foo-project') + end + + it 'creates new project without name but with path and returns 201' do + expect { post v3_api('/projects', user), path: 'foo_project' }. + to change { Project.count }.by(1) + expect(response).to have_http_status(201) + + project = Project.first + + expect(project.name).to eq('foo_project') + expect(project.path).to eq('foo_project') + end + + it 'creates new project name and path and returns 201' do + expect { post v3_api('/projects', user), path: 'foo-Project', name: 'Foo Project' }. + to change { Project.count }.by(1) + expect(response).to have_http_status(201) + + project = Project.first + + expect(project.name).to eq('Foo Project') + expect(project.path).to eq('foo-Project') end it 'creates last project before reaching project limit' do @@ -321,7 +348,7 @@ describe API::V3::Projects, api: true do expect(response).to have_http_status(201) end - it 'does not create new project without name and return 400' do + it 'does not create new project without name or path and return 400' do expect { post v3_api('/projects', user) }.not_to change { Project.count } expect(response).to have_http_status(400) end |