diff options
-rw-r--r-- | app/assets/javascripts/filtered_search/dropdown_utils.js | 2 | ||||
-rw-r--r-- | app/helpers/todos_helper.rb | 3 | ||||
-rw-r--r-- | app/models/wiki_page.rb | 6 | ||||
-rw-r--r-- | app/views/projects/wikis/_main_links.html.haml | 2 | ||||
-rw-r--r-- | changelogs/unreleased/28991-viewing-old-wiki-page-version-edit-button-exists.yml | 4 | ||||
-rw-r--r-- | doc/api/issues.md | 12 | ||||
-rw-r--r-- | doc/development/changelog.md | 20 | ||||
-rw-r--r-- | doc/user/project/repository/web_editor.md | 7 | ||||
-rw-r--r-- | lib/gitlab/emoji.rb | 18 | ||||
-rw-r--r-- | spec/features/boards/add_issues_modal_spec.rb | 4 | ||||
-rw-r--r-- | spec/features/issues/award_emoji_spec.rb | 15 | ||||
-rw-r--r-- | spec/features/projects/wiki/user_views_project_wiki_page_spec.rb | 44 | ||||
-rw-r--r-- | spec/helpers/todos_helper_spec.rb | 23 | ||||
-rw-r--r-- | spec/requests/api/issues_spec.rb | 10 |
14 files changed, 142 insertions, 28 deletions
diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js b/app/assets/javascripts/filtered_search/dropdown_utils.js index 59998c2108c..432b0c0dfd2 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js @@ -117,7 +117,7 @@ import FilteredSearchContainer from './container'; const { isLastVisualTokenValid } = gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); - const input = document.querySelector('.filtered-search'); + const input = FilteredSearchContainer.container.querySelector('.filtered-search'); const inputValue = input && input.value; if (isLastVisualTokenValid) { diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 7f8efb0a4ac..4f5adf623f2 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -99,8 +99,7 @@ module TodosHelper end def todo_projects_options - projects = current_user.authorized_projects.sorted_by_activity.non_archived - projects = projects.includes(:namespace) + projects = current_user.authorized_projects.sorted_by_activity.non_archived.with_route projects = projects.map do |project| { id: project.id, text: project.name_with_namespace } diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 2caebb496db..465c4d903ac 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -149,6 +149,12 @@ class WikiPage end # Returns boolean True or False if this instance + # is the latest commit version of the page. + def latest? + !historical? + end + + # Returns boolean True or False if this instance # has been fully saved to disk or not. def persisted? @persisted == true diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index 763c2fea39b..5211ade1a5f 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -4,6 +4,6 @@ New Page = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do Page History - - if can?(current_user, :create_wiki, @project) + - if can?(current_user, :create_wiki, @project) && @page.latest? = link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn" do Edit diff --git a/changelogs/unreleased/28991-viewing-old-wiki-page-version-edit-button-exists.yml b/changelogs/unreleased/28991-viewing-old-wiki-page-version-edit-button-exists.yml new file mode 100644 index 00000000000..26989c14958 --- /dev/null +++ b/changelogs/unreleased/28991-viewing-old-wiki-page-version-edit-button-exists.yml @@ -0,0 +1,4 @@ +--- +title: When viewing old wiki page version, edit button should be disabled +merge_request: 9966 +author: TM Lee diff --git a/doc/api/issues.md b/doc/api/issues.md index cb437ffb174..a19c965a8c3 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -23,7 +23,6 @@ GET /issues?state=closed GET /issues?labels=foo GET /issues?labels=foo,bar GET /issues?labels=foo,bar&state=opened -GET /projects/:id/issues?labels_name=No+Label GET /issues?milestone=1.0.0 GET /issues?milestone=1.0.0&state=opened GET /issues?iids[]=42&iids[]=43 @@ -32,8 +31,7 @@ GET /issues?iids[]=42&iids[]=43 | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `state` | string | no | Return all issues or just those that are `opened` or `closed`| -| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned | -| `labels_name` | string | no | Return all issues with the mentioned label. `No+Label` lists all issues with no labels | +| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `milestone` | string| no | The milestone title | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | @@ -103,7 +101,6 @@ GET /groups/:id/issues?state=closed GET /groups/:id/issues?labels=foo GET /groups/:id/issues?labels=foo,bar GET /groups/:id/issues?labels=foo,bar&state=opened -GET /projects/:id/issues?labels_name=No+Label GET /groups/:id/issues?milestone=1.0.0 GET /groups/:id/issues?milestone=1.0.0&state=opened GET /groups/:id/issues?iids[]=42&iids[]=43 @@ -113,8 +110,7 @@ GET /groups/:id/issues?iids[]=42&iids[]=43 | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a group | | `state` | string | no | Return all issues or just those that are `opened` or `closed`| -| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned | -| `labels_name` | string | no | Return all issues with the mentioned label. `No+Label` lists all issues with no labels | +| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `milestone` | string| no | The milestone title | | `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | @@ -185,7 +181,6 @@ GET /projects/:id/issues?state=closed GET /projects/:id/issues?labels=foo GET /projects/:id/issues?labels=foo,bar GET /projects/:id/issues?labels=foo,bar&state=opened -GET /projects/:id/issues?labels_name=No+Label GET /projects/:id/issues?milestone=1.0.0 GET /projects/:id/issues?milestone=1.0.0&state=opened GET /projects/:id/issues?iids[]=42&iids[]=43 @@ -196,8 +191,7 @@ GET /projects/:id/issues?iids[]=42&iids[]=43 | `id` | integer | yes | The ID of a project | | `iids` | Array[integer] | no | Return only the milestone having the given `iid` | | `state` | string | no | Return all issues or just those that are `opened` or `closed`| -| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned | -| `labels_name` | string | no | Return all issues with the mentioned label. `No+Label` lists all issues with no labels | +| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `milestone` | string| no | The milestone title | | `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | diff --git a/doc/development/changelog.md b/doc/development/changelog.md index ff9a4fc4fec..ce39a379a0e 100644 --- a/doc/development/changelog.md +++ b/doc/development/changelog.md @@ -51,14 +51,34 @@ making it both concise and descriptive, err on the side of descriptive. - **Bad:** Go to a project order. - **Good:** Show a user's starred projects at the top of the "Go to project" dropdown. + +The first example provides no context of where the change was made, or why, or +how it benefits the user. + - **Bad:** Copy [some text] to clipboard. - **Good:** Update the "Copy to clipboard" tooltip to indicate what's being copied. + +Again, the first example is too vague and provides no context. + - **Bad:** Fixes and Improves CSS and HTML problems in mini pipeline graph and builds dropdown. - **Good:** Fix tooltips and hover states in mini pipeline graph and builds dropdown. +The first example is too focused on implementation details. The user doesn't +care that we changed CSS and HTML, they care about the _end result_ of those +changes. + +- **Bad:** Strip out `nil`s in the Array of Commit objects returned from + `find_commits_by_message_with_elastic` +- **Good:** Fix 500 errors caused by elasticsearch results referencing + garbage-collected commits + +The first example focuses on _how_ we fixed something, not on _what_ it fixes. +The rewritten version clearly describes the _end benefit_ to the user (fewer 500 +errors), and _when_ (searching commits with ElasticSearch). + Use your best judgement and try to put yourself in the mindset of someone reading the compiled changelog. Does this entry add value? Does it offer context about _where_ and _why_ the change was made? diff --git a/doc/user/project/repository/web_editor.md b/doc/user/project/repository/web_editor.md index c415d566a7c..d47a3acdbe9 100644 --- a/doc/user/project/repository/web_editor.md +++ b/doc/user/project/repository/web_editor.md @@ -109,12 +109,19 @@ the title of the issue and as suffix it will have its ID. Thus, the example screenshot above will yield a branch named `2-et-cum-et-sed-expedita-repellat-consequatur-ut-assumenda-numquam-rerum`. +Since GitLab 9.0, when you click the `New branch` in an empty repository project, GitLab automatically creates the master branch, commits a blank `README.md` file to it and creates and redirects you to a new branch based on the issue title. +If your [project is already configured with a deployment service][project-services-doc] (e.g. Kubernetes), GitLab takes one step further and prompts you to set up [auto deploy][auto-deploy-doc] by helping you create a `.gitlab-ci.yml` file. + + After the branch is created, you can edit files in the repository to fix the issue. When a merge request is created based on the newly created branch, the description field will automatically display the [issue closing pattern] `Closes #ID`, where `ID` the ID of the issue. This will close the issue once the merge request is merged. +[project-services-doc]: ../integrations/project_services.md +[auto-deploy-doc]: ../../../ci/autodeploy/index.md + ### Create a new branch from a project's dashboard If you want to make changes to several files before creating a new merge diff --git a/lib/gitlab/emoji.rb b/lib/gitlab/emoji.rb index 35871fd1b7b..a16d9fc2265 100644 --- a/lib/gitlab/emoji.rb +++ b/lib/gitlab/emoji.rb @@ -44,27 +44,17 @@ module Gitlab end # CSS sprite fallback takes precedence over image fallback - def gl_emoji_tag(name, image: false, sprite: false, force_fallback: false) + def gl_emoji_tag(name) emoji_name = emojis_aliases[name] || name emoji_info = emojis[emoji_name] - emoji_fallback_image_source = ActionController::Base.helpers.url_to_image("emoji/#{emoji_info['name']}.png") - emoji_fallback_sprite_class = "emoji-#{emoji_name}" + return unless emoji_info data = { name: emoji_name, unicode_version: emoji_unicode_version(emoji_name) } - data[:fallback_src] = emoji_fallback_image_source if image - data[:fallback_sprite_class] = emoji_fallback_sprite_class if sprite - ActionController::Base.helpers.content_tag 'gl-emoji', - class: ("emoji-icon #{emoji_fallback_sprite_class}" if force_fallback && sprite), - data: data do - if force_fallback && !sprite - emoji_image_tag(emoji_name, emoji_fallback_image_source) - else - emoji_info['moji'] - end - end + + ActionController::Base.helpers.content_tag('gl-emoji', emoji_info['moji'], data: data) end end end diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index c87c0632cb5..d17a418b8c3 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -109,6 +109,8 @@ describe 'Issue Boards add issue modal', :feature, :js do find('.form-control').native.send_keys(issue.title) find('.form-control').native.send_keys(:enter) + wait_for_vue_resource + expect(page).to have_selector('.card', count: 1) end end @@ -118,6 +120,8 @@ describe 'Issue Boards add issue modal', :feature, :js do find('.form-control').native.send_keys('testing search') find('.form-control').native.send_keys(:enter) + wait_for_vue_resource + expect(page).not_to have_selector('.card') expect(page).not_to have_content("You haven't added any issues to your project yet") end diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index f424186cf30..16e453bc328 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -17,8 +17,21 @@ describe 'Awards Emoji', feature: true do login_as(user) end + describe 'visiting an issue with a legacy award emoji that is not valid anymore' do + before do + # The `heart_tip` emoji is not valid anymore so we need to skip validation + issue.award_emoji.build(user: user, name: 'heart_tip').save!(validate: false) + visit namespace_project_issue_path(project.namespace, project, issue) + end + + # Regression test: https://gitlab.com/gitlab-org/gitlab-ce/issues/29529 + it 'does not shows a 500 page' do + expect(page).to have_text(issue.title) + end + end + describe 'Click award emoji from issue#show' do - let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") } + let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") } before do visit namespace_project_issue_path(project.namespace, project, issue) diff --git a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb new file mode 100644 index 00000000000..c17e06612de --- /dev/null +++ b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +feature 'Projects > Wiki > User views the wiki page', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, :public) } + let(:old_page_version_id) { wiki_page.versions.last.id } + let(:wiki_page) do + WikiPages::CreateService.new( + project, + user, + title: 'home', + content: '[some link](other-page)' + ).execute + end + + background do + project.team << [user, :master] + login_as(user) + WikiPages::UpdateService.new( + project, + user, + message: 'updated home', + content: 'updated [some link](other-page)', + format: :markdown + ).execute(wiki_page) + end + + scenario 'Visit Wiki Page Current Commit' do + visit namespace_project_wiki_path(project.namespace, project, wiki_page) + + expect(page).to have_selector('a.btn', text: 'Edit') + end + + scenario 'Visit Wiki Page Historical Commit' do + visit namespace_project_wiki_path( + project.namespace, + project, + wiki_page, + version_id: old_page_version_id + ) + + expect(page).not_to have_selector('a.btn', text: 'Edit') + end +end diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb new file mode 100644 index 00000000000..50060a0925d --- /dev/null +++ b/spec/helpers/todos_helper_spec.rb @@ -0,0 +1,23 @@ +require "spec_helper" + +describe TodosHelper do + describe '#todo_projects_options' do + let(:projects) { create_list(:empty_project, 3) } + let(:user) { create(:user) } + + it 'returns users authorised projects in json format' do + projects.first.add_developer(user) + projects.second.add_developer(user) + + allow(helper).to receive(:current_user).and_return(user) + + expected_results = [ + { 'id' => '', 'text' => 'Any Project' }, + { 'id' => projects.second.id, 'text' => projects.second.name_with_namespace }, + { 'id' => projects.first.id, 'text' => projects.first.name_with_namespace } + ] + + expect(JSON.parse(helper.todo_projects_options)).to match_array(expected_results) + end + end +end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index de7dbca0b22..e7738ca3034 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -153,6 +153,16 @@ describe API::Issues, api: true do expect(json_response.first['state']).to eq('opened') end + it 'returns unlabeled issues for "No Label" label' do + get api("/issues", user), labels: 'No Label' + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.length).to eq(1) + expect(json_response.first['labels']).to be_empty + end + it 'returns an empty array if no issue matches labels and state filters' do get api("/issues?labels=#{label.title}&state=closed", user) |