From 53866711d4c4f728f86d061984437bdd65f15bed Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 17 May 2016 17:12:23 +0100 Subject: [PATCH 01/14] Show loading indicator for autocomplete Closes #15435 --- .../javascripts/gfm_auto_complete.js.coffee | 78 +++++++++++++++++-- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 41dba34210..b13a431a52 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -22,6 +22,24 @@ GitLab.GfmAutoComplete = Milestones: template: '
  • ${title}
  • ' + Loading: + template: '
  • Loading...
  • ' + + DefaultOptions: + sorter: (query, items, searchKey) -> + return items if items[0].name? and items[0].name is 'loading' + + $.fn.atwho.default.callbacks.sorter(query, items, searchKey) + filter: (query, data, searchKey) -> + return data if data[0] is 'loading' + + $.fn.atwho.default.callbacks.filter(query, data, searchKey) + beforeInsert: (value) -> + if value.indexOf('undefined') + @at + else + value + # Add GFM auto-completion to all input fields, that accept GFM input. setup: (wrap) -> @input = $('.js-gfm-input') @@ -53,18 +71,37 @@ GitLab.GfmAutoComplete = # Emoji @input.atwho at: ':' - displayTpl: @Emoji.template + displayTpl: (value) => + if value.path? + @Emoji.template + else + @Loading.template insertTpl: ':${name}:' + data: ['loading'] + callbacks: + sorter: @DefaultOptions.sorter + filter: @DefaultOptions.filter + beforeInsert: @DefaultOptions.beforeInsert # Team Members @input.atwho at: '@' - displayTpl: @Members.template + displayTpl: (value) => + if value.username? + @Members.template + else + @Loading.template insertTpl: '${atwho-at}${username}' searchKey: 'search' + data: ['loading'] callbacks: + sorter: @DefaultOptions.sorter + filter: @DefaultOptions.filter + beforeInsert: @DefaultOptions.beforeInsert beforeSave: (members) -> $.map members, (m) -> + return m if not m.username? + title = m.name title += " (#{m.count})" if m.count @@ -76,11 +113,21 @@ GitLab.GfmAutoComplete = at: '#' alias: 'issues' searchKey: 'search' - displayTpl: @Issues.template + displayTpl: (value) => + if value.title? + @Issues.template + else + @Loading.template + data: ['loading'] insertTpl: '${atwho-at}${id}' callbacks: + sorter: @DefaultOptions.sorter + filter: @DefaultOptions.filter + beforeInsert: @DefaultOptions.beforeInsert beforeSave: (issues) -> $.map issues, (i) -> + return i if not i.title? + id: i.iid title: sanitize(i.title) search: "#{i.iid} #{i.title}" @@ -89,11 +136,18 @@ GitLab.GfmAutoComplete = at: '%' alias: 'milestones' searchKey: 'search' - displayTpl: @Milestones.template + displayTpl: (value) => + if value.title? + @Milestones.template + else + @Loading.template insertTpl: '${atwho-at}"${title}"' + data: ['loading'] callbacks: beforeSave: (milestones) -> $.map milestones, (m) -> + return m if not m.title? + id: m.iid title: sanitize(m.title) search: "#{m.title}" @@ -102,11 +156,21 @@ GitLab.GfmAutoComplete = at: '!' alias: 'mergerequests' searchKey: 'search' - displayTpl: @Issues.template + displayTpl: (value) => + if value.title? + @Issues.template + else + @Loading.template + data: ['loading'] insertTpl: '${atwho-at}${id}' callbacks: + sorter: @DefaultOptions.sorter + filter: @DefaultOptions.filter + beforeInsert: @DefaultOptions.beforeInsert beforeSave: (merges) -> $.map merges, (m) -> + return m if not m.title? + id: m.iid title: sanitize(m.title) search: "#{m.iid} #{m.title}" @@ -128,3 +192,7 @@ GitLab.GfmAutoComplete = @input.atwho 'load', 'mergerequests', data.mergerequests # load emojis @input.atwho 'load', ':', data.emojis + + # This trigger at.js again + # otherwise we would be stuck with loading until the user types + $(':focus').trigger('keyup') From 7038440e342a521807b1e5ffb6d47d4c0b13048d Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Mon, 6 Jun 2016 18:47:49 -0500 Subject: [PATCH 02/14] Adjust the SAML control flow to allow LDAP identities to be added to an existing SAML user. --- lib/gitlab/o_auth/user.rb | 2 +- lib/gitlab/saml/user.rb | 28 ++++++++++++++++++++++++++-- spec/lib/gitlab/saml/user_spec.rb | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 356e96fcba..268ee11502 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -96,7 +96,7 @@ module Gitlab # Look for a corresponding person with same uid in any of the configured LDAP providers Gitlab::LDAP::Config.providers.each do |provider| adapter = Gitlab::LDAP::Adapter.new(provider) - @ldap_person = Gitlab::LDAP::Person.find_by_uid(auth_hash.uid, adapter) + @ldap_person = Gitlab::LDAP::Person.find_by_dn(auth_hash.uid, adapter) break if @ldap_person end @ldap_person diff --git a/lib/gitlab/saml/user.rb b/lib/gitlab/saml/user.rb index dba4bbfc89..6f7d4825ae 100644 --- a/lib/gitlab/saml/user.rb +++ b/lib/gitlab/saml/user.rb @@ -12,12 +12,12 @@ module Gitlab end def gl_user - @user ||= find_by_uid_and_provider - if auto_link_ldap_user? @user ||= find_or_create_ldap_user end + @user ||= find_by_uid_and_provider + if auto_link_saml_user? @user ||= find_by_email end @@ -62,6 +62,30 @@ module Gitlab !Gitlab::Saml::Config.external_groups.nil? end + def find_or_create_ldap_user + return unless ldap_person + + # If a corresponding person exists with same uid in a LDAP server, + # check if the user already has a GitLab account + user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider) + if user + # Case when a LDAP user already exists in Gitlab. Add the SAML identity to existing account. + user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) + else + # No account found using LDAP in Gitlab yet: check if there is a SAML account with + # the passed uid and provider + user = find_by_uid_and_provider + if user.nil? + # No SAML account found, build a new user. + user = build_new_user + end + # Correct account is present, add the LDAP Identity to the user. + user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn) + end + + user + end + def auth_hash=(auth_hash) @auth_hash = Gitlab::Saml::AuthHash.new(auth_hash) end diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index c2a51d9249..f0a17244ff 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -145,6 +145,7 @@ describe Gitlab::Saml::User, lib: true do allow(ldap_user).to receive(:email) { %w(john@mail.com john2@example.com) } allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' } allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(ldap_user) + allow(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(ldap_user) end context 'and no account for the LDAP user' do @@ -177,6 +178,24 @@ describe Gitlab::Saml::User, lib: true do ]) end end + + context 'user has SAML user, and wants to add their LDAP identity' do + it 'adds the LDAP identity to the existing SAML user' do + create(:omniauth_user, email: 'john@mail.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'saml', username: 'john') + local_hash = OmniAuth::AuthHash.new(uid: 'uid=user1,ou=People,dc=example', provider: provider, info: info_hash, extra: { raw_info: OneLogin::RubySaml::Attributes.new({ 'groups' => %w(Developers Freelancers Designers) }) }) + local_saml_user = described_class.new(local_hash) + + local_saml_user.save + local_gl_user = local_saml_user.gl_user + expect(local_gl_user).to be_valid + expect(local_gl_user.identities.length).to eql 2 + identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } + expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } + ]) + end + + end end end end From c593154cb4f0215851fbbae1dde753dacbaa6713 Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Tue, 7 Jun 2016 11:19:19 -0500 Subject: [PATCH 03/14] Moved `find_or_create_ldap_user` method to parent class and added logging. --- lib/gitlab/o_auth/user.rb | 18 ++++++++++++------ lib/gitlab/saml/user.rb | 24 ------------------------ spec/lib/gitlab/saml/user_spec.rb | 2 +- 3 files changed, 13 insertions(+), 31 deletions(-) diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 268ee11502..5e52979093 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -69,13 +69,19 @@ module Gitlab return unless ldap_person # If a corresponding person exists with same uid in a LDAP server, - # set up a Gitlab user with dual LDAP and Omniauth identities. - if user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider) - # Case when a LDAP user already exists in Gitlab. Add the Omniauth identity to existing account. + # check if the user already has a GitLab account. + if (user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider)) + # Case when a LDAP user already exists in Gitlab. Add the OAuth identity to existing account. + log.info "LDAP account found for user #{user.username}. Building new identity." user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) else - # No account in Gitlab yet: create it and add the LDAP identity - user = build_new_user + log.info 'No existing LDAP account was found in GitLab. Checking for OAuth account.' + user = find_by_uid_and_provider + if user.nil? + log.info 'No user found with the specified OAuth provider. Creating a new one.' + user = build_new_user + end + log.info "Correct account has been found. Adding LDAP identity to user: #{user.username}." user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn) end @@ -96,7 +102,7 @@ module Gitlab # Look for a corresponding person with same uid in any of the configured LDAP providers Gitlab::LDAP::Config.providers.each do |provider| adapter = Gitlab::LDAP::Adapter.new(provider) - @ldap_person = Gitlab::LDAP::Person.find_by_dn(auth_hash.uid, adapter) + @ldap_person = Gitlab::LDAP::Person.find_by_uid(auth_hash.uid, adapter) break if @ldap_person end @ldap_person diff --git a/lib/gitlab/saml/user.rb b/lib/gitlab/saml/user.rb index 6f7d4825ae..8943022612 100644 --- a/lib/gitlab/saml/user.rb +++ b/lib/gitlab/saml/user.rb @@ -62,30 +62,6 @@ module Gitlab !Gitlab::Saml::Config.external_groups.nil? end - def find_or_create_ldap_user - return unless ldap_person - - # If a corresponding person exists with same uid in a LDAP server, - # check if the user already has a GitLab account - user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider) - if user - # Case when a LDAP user already exists in Gitlab. Add the SAML identity to existing account. - user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) - else - # No account found using LDAP in Gitlab yet: check if there is a SAML account with - # the passed uid and provider - user = find_by_uid_and_provider - if user.nil? - # No SAML account found, build a new user. - user = build_new_user - end - # Correct account is present, add the LDAP Identity to the user. - user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn) - end - - user - end - def auth_hash=(auth_hash) @auth_hash = Gitlab::Saml::AuthHash.new(auth_hash) end diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index f0a17244ff..5957998e0f 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -182,7 +182,7 @@ describe Gitlab::Saml::User, lib: true do context 'user has SAML user, and wants to add their LDAP identity' do it 'adds the LDAP identity to the existing SAML user' do create(:omniauth_user, email: 'john@mail.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'saml', username: 'john') - local_hash = OmniAuth::AuthHash.new(uid: 'uid=user1,ou=People,dc=example', provider: provider, info: info_hash, extra: { raw_info: OneLogin::RubySaml::Attributes.new({ 'groups' => %w(Developers Freelancers Designers) }) }) + local_hash = OmniAuth::AuthHash.new(uid: 'uid=user1,ou=People,dc=example', provider: provider, info: info_hash) local_saml_user = described_class.new(local_hash) local_saml_user.save From 1558876ac0c7e521dabfc2b1efe3418d34fe531f Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 7 Jun 2016 12:37:44 -0500 Subject: [PATCH 04/14] Side nav scrolls if content height taller than screen --- app/assets/stylesheets/framework/sidebar.scss | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 46d46368d2..83d6467968 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -38,6 +38,11 @@ .header-logo { height: $header-height; padding: 8px 26px; + width: $sidebar_width; + position: fixed; + z-index: 999; + overflow: hidden; + transition-duration: .3s; &:hover { background-color: #eee; @@ -73,7 +78,8 @@ .nav-sidebar { - margin: 22px 0; + margin-top: 22 + $header-height; + margin-bottom: 116px; transition-duration: .3s; list-style: none; overflow: hidden; @@ -167,6 +173,7 @@ .header-logo { width: 0; + padding: 8px 0; a { padding-left: ($sidebar_collapsed_width - 36) / 2; From ae736d81e1f64fe9439ac0675538d359cfdb5be9 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Tue, 17 May 2016 17:04:01 +0100 Subject: [PATCH 05/14] Added a line to find the currently saved text and replace the markdown textarea text when cancelling Updated CHANGELOG Corrected the changes to store the markdown in a hidden input when edit starts and retrieve the original from that input when edit is cancelled Replaced hidden input with form attribute --- CHANGELOG | 1 + app/assets/javascripts/notes.js.coffee | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b9189b8088..ff5a7c22e6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -57,6 +57,7 @@ v 8.8.4 (unreleased) - Fix importer for GitHub comments on diff - Disable Webhooks before proceeding with the GitHub import - Added descriptions to notification settings dropdown + - Markdown editor now correctly resets the input value on edit cancellation !4175 v 8.8.3 - Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312 diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index 8e33e915ba..ad216910c8 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -354,8 +354,7 @@ class @Notes Called in response to clicking the edit note link Replaces the note text with the note edit form - Adds a hidden div with the original content of the note to fill the edit note form with - if the user cancels + Adds a data attribute to the form with the original content of the note for cancellations ### showEditForm: (e, scrollTo, myLastNote) -> e.preventDefault() @@ -371,6 +370,8 @@ class @Notes done = ($noteText) -> # Neat little trick to put the cursor at the end noteTextVal = $noteText.val() + # Store the original note text in a data attribute to retrieve if a user cancels edit. + form.find('form.edit-note').data 'original-note', noteTextVal $noteText.val('').val(noteTextVal); new GLForm form @@ -393,14 +394,16 @@ class @Notes ### Called in response to clicking the edit note link - Hides edit form + Hides edit form and restores the original note text to the editor textarea. ### cancelEdit: (e) -> e.preventDefault() note = $(this).closest(".note") + form = note.find(".current-note-edit-form") note.removeClass "is-editting" - note.find(".current-note-edit-form") - .removeClass("current-note-edit-form") + form.removeClass("current-note-edit-form") + # Replace markdown textarea text with original note text. + form.find(".js-note-text").val(form.find('form.edit-note').data('original-note')) ### Called in response to deleting a note of any kind. From 13d941e185c3ca1e9ad54c97f878e9cfdd32e5aa Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 8 Jun 2016 16:49:01 +0200 Subject: [PATCH 06/14] Make Omniauth providers specs to not modify global configuration --- CHANGELOG | 1 + spec/controllers/import/import_spec_helper.rb | 2 +- spec/lib/gitlab/bitbucket_import/client_spec.rb | 4 +++- spec/lib/gitlab/bitbucket_import/importer_spec.rb | 4 +++- spec/lib/gitlab/gitlab_import/client_spec.rb | 4 +++- spec/services/projects/import_service_spec.rb | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0506854599..ca312a111f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -36,6 +36,7 @@ v 8.9.0 (unreleased) - Use downcased path to container repository as this is expected path by Docker - Projects pending deletion will render a 404 page - Measure queue duration between gitlab-workhorse and Rails + - Make Omniauth providers specs to not modify global configuration - Make authentication service for Container Registry to be compatible with < Docker 1.11 - Add Application Setting to configure Container Registry token expire delay (default 5min) - Cache assigned issue and merge request counts in sidebar nav diff --git a/spec/controllers/import/import_spec_helper.rb b/spec/controllers/import/import_spec_helper.rb index 9d7648e25a..6710962f08 100644 --- a/spec/controllers/import/import_spec_helper.rb +++ b/spec/controllers/import/import_spec_helper.rb @@ -28,6 +28,6 @@ module ImportSpecHelper app_id: 'asd123', app_secret: 'asd123' ) - Gitlab.config.omniauth.providers << provider + allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) end end diff --git a/spec/lib/gitlab/bitbucket_import/client_spec.rb b/spec/lib/gitlab/bitbucket_import/client_spec.rb index 7718689e6d..760d66a148 100644 --- a/spec/lib/gitlab/bitbucket_import/client_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/client_spec.rb @@ -1,12 +1,14 @@ require 'spec_helper' describe Gitlab::BitbucketImport::Client, lib: true do + include ImportSpecHelper + let(:token) { '123456' } let(:secret) { 'secret' } let(:client) { Gitlab::BitbucketImport::Client.new(token, secret) } before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket") + stub_omniauth_provider('bitbucket') end it 'all OAuth client options are symbols' do diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb index 1a833f255a..aa00f32bec 100644 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -1,8 +1,10 @@ require 'spec_helper' describe Gitlab::BitbucketImport::Importer, lib: true do + include ImportSpecHelper + before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket") + stub_omniauth_provider('bitbucket') end let(:statuses) do diff --git a/spec/lib/gitlab/gitlab_import/client_spec.rb b/spec/lib/gitlab/gitlab_import/client_spec.rb index e6831e7c38..cd8e805466 100644 --- a/spec/lib/gitlab/gitlab_import/client_spec.rb +++ b/spec/lib/gitlab/gitlab_import/client_spec.rb @@ -1,11 +1,13 @@ require 'spec_helper' describe Gitlab::GitlabImport::Client, lib: true do + include ImportSpecHelper + let(:token) { '123456' } let(:client) { Gitlab::GitlabImport::Client.new(token) } before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "gitlab") + stub_omniauth_provider('gitlab') end it 'all OAuth2 client options are symbols' do diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb index 9d90bfceb7..068c9a1219 100644 --- a/spec/services/projects/import_service_spec.rb +++ b/spec/services/projects/import_service_spec.rb @@ -124,7 +124,7 @@ describe Projects::ImportService, services: true do } ) - Gitlab.config.omniauth.providers << provider + allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) end end end From 9560639e817147064e3929243668e49336a4f3f5 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 8 Jun 2016 17:21:08 +0200 Subject: [PATCH 07/14] Move ImportSpecHelper to spec/support/ --- spec/{controllers/import => support}/import_spec_helper.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/{controllers/import => support}/import_spec_helper.rb (100%) diff --git a/spec/controllers/import/import_spec_helper.rb b/spec/support/import_spec_helper.rb similarity index 100% rename from spec/controllers/import/import_spec_helper.rb rename to spec/support/import_spec_helper.rb From a0adafddd0ce40c4ce9f052d2ee5e8ea38a2fb58 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 8 Jun 2016 18:18:49 +0200 Subject: [PATCH 08/14] Remove require_relative 'import_spec_helper' --- spec/controllers/import/bitbucket_controller_spec.rb | 1 - spec/controllers/import/fogbugz_controller_spec.rb | 1 - spec/controllers/import/github_controller_spec.rb | 1 - spec/controllers/import/gitlab_controller_spec.rb | 1 - spec/controllers/import/gitorious_controller_spec.rb | 1 - spec/controllers/import/google_code_controller_spec.rb | 1 - 6 files changed, 6 deletions(-) diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 81c03c9059..07bf8d2d1c 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require_relative 'import_spec_helper' describe Import::BitbucketController do include ImportSpecHelper diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb index 27b11267d2..5f0f6dea82 100644 --- a/spec/controllers/import/fogbugz_controller_spec.rb +++ b/spec/controllers/import/fogbugz_controller_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require_relative 'import_spec_helper' describe Import::FogbugzController do include ImportSpecHelper diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index bcc713dce2..c55a3c2820 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require_relative 'import_spec_helper' describe Import::GithubController do include ImportSpecHelper diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 198d006af7..e8cf6aa776 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require_relative 'import_spec_helper' describe Import::GitlabController do include ImportSpecHelper diff --git a/spec/controllers/import/gitorious_controller_spec.rb b/spec/controllers/import/gitorious_controller_spec.rb index 7cb1b85a46..4ae2b78e11 100644 --- a/spec/controllers/import/gitorious_controller_spec.rb +++ b/spec/controllers/import/gitorious_controller_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require_relative 'import_spec_helper' describe Import::GitoriousController do include ImportSpecHelper diff --git a/spec/controllers/import/google_code_controller_spec.rb b/spec/controllers/import/google_code_controller_spec.rb index 66088139a6..4241db6e77 100644 --- a/spec/controllers/import/google_code_controller_spec.rb +++ b/spec/controllers/import/google_code_controller_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require_relative 'import_spec_helper' describe Import::GoogleCodeController do include ImportSpecHelper From 63ed80321b00b96b79e064d1932528b8617d1625 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 8 Jun 2016 18:36:43 +0200 Subject: [PATCH 09/14] Skip authenticity token checks for Git HTTP --- app/controllers/projects/git_http_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb index 380139a9c3..348d6cf4d9 100644 --- a/app/controllers/projects/git_http_controller.rb +++ b/app/controllers/projects/git_http_controller.rb @@ -1,6 +1,8 @@ class Projects::GitHttpController < Projects::ApplicationController attr_reader :user + # Git clients will not know what authenticity token to send along + skip_before_action :verify_authenticity_token skip_before_action :repository before_action :authenticate_user before_action :ensure_project_found! From 9282810fb7b6102657a0ddb2a02f71b6da22067f Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Wed, 8 Jun 2016 18:09:43 -0500 Subject: [PATCH 10/14] Syntax fixes and better logging around the `ldap_person` method. --- lib/gitlab/o_auth/user.rb | 9 +++++---- spec/lib/gitlab/saml/user_spec.rb | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 5e52979093..78f3ecb4cb 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -70,15 +70,16 @@ module Gitlab # If a corresponding person exists with same uid in a LDAP server, # check if the user already has a GitLab account. - if (user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider)) + user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider) + if user # Case when a LDAP user already exists in Gitlab. Add the OAuth identity to existing account. - log.info "LDAP account found for user #{user.username}. Building new identity." + log.info "LDAP account found for user #{user.username}. Building new #{auth_hash.provider} identity." user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) else - log.info 'No existing LDAP account was found in GitLab. Checking for OAuth account.' + log.info "No existing LDAP account was found in GitLab. Checking for #{auth_hash.provider} account." user = find_by_uid_and_provider if user.nil? - log.info 'No user found with the specified OAuth provider. Creating a new one.' + log.info "No user found using #{auth_hash.provider} provider. Creating a new one." user = build_new_user end log.info "Correct account has been found. Adding LDAP identity to user: #{user.username}." diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index 5957998e0f..84c21ceefd 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -184,9 +184,9 @@ describe Gitlab::Saml::User, lib: true do create(:omniauth_user, email: 'john@mail.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'saml', username: 'john') local_hash = OmniAuth::AuthHash.new(uid: 'uid=user1,ou=People,dc=example', provider: provider, info: info_hash) local_saml_user = described_class.new(local_hash) - local_saml_user.save local_gl_user = local_saml_user.gl_user + expect(local_gl_user).to be_valid expect(local_gl_user.identities.length).to eql 2 identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } @@ -194,7 +194,6 @@ describe Gitlab::Saml::User, lib: true do { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } ]) end - end end end From bdc995bf00794f96af46d92f61a940896c1404d0 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Wed, 8 Jun 2016 17:09:48 -0600 Subject: [PATCH 11/14] Shows award emoji for comments to all users who are logged in. --- app/views/projects/notes/_note.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 5ddd0ecc4c..bcdbff0801 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -20,10 +20,11 @@ - access = note.project.team.human_max_access(note.author.id) - if access %span.note-role.hidden-xs= access - - if note_editable + - if current_user = link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do = icon('spinner spin') = icon('smile-o') + - if note_editable = link_to '#', title: 'Edit comment', class: 'note-action-button js-note-edit' do = icon('pencil') = link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button hidden-xs js-note-delete danger' do From 8e71c19a6940b8d82c70ee9b2550b62b5169eb54 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 8 Jun 2016 10:29:20 +0530 Subject: [PATCH 12/14] Implement the correct linking behaviour in `WikiLinkFilter`. Original Comments ================= - Linking behaves as per rules documented here: https://gitlab.com/gitlab-org/gitlab-ce/blob/16568-document-wiki-linking-behavior/doc/markdown/wiki.md - All links (to other wiki pages) are rewritten to be at the level of the app root. We can't use links relative to the current page ('./foo', 'foo', '../foo'), because they won't work in the markdown preview, where the current page is suffixed with `/edit` - Move existing `WikiLinkFilter` specs to `WikiPipeline` spec. It makes sense to run these tests on the combined output of the pipeline, rather than a single filter, since we can catch issues with conflicting filters. - Add more tests to cover the new linking @rymai's Review =============== - Classes nested under `WikiLinkFilter` should declare `WikiLinkFilter`'s inherit, so nothing changes if the nested class is loaded first. - Add a blank line after a guard clause - Use keyword arguments for the `Rewriter` constructor - Invert a condition - use `if` instead of `unless` - Inline a `let` in `WikiPipeline` spec - it was only used in a single place - Change out of date spec names - Add a comment for every rewrite rule in `Rewriter` --- lib/banzai/filter/wiki_link_filter.rb | 32 +----- .../filter/wiki_link_filter/rewriter.rb | 40 +++++++ spec/factories/wiki_pages.rb | 2 +- .../banzai/filter/wiki_link_filter_spec.rb | 85 -------------- .../lib/banzai/pipeline/wiki_pipeline_spec.rb | 108 ++++++++++++++++++ 5 files changed, 155 insertions(+), 112 deletions(-) create mode 100644 lib/banzai/filter/wiki_link_filter/rewriter.rb delete mode 100644 spec/lib/banzai/filter/wiki_link_filter_spec.rb diff --git a/lib/banzai/filter/wiki_link_filter.rb b/lib/banzai/filter/wiki_link_filter.rb index 7dc771afd7..37a2779d45 100644 --- a/lib/banzai/filter/wiki_link_filter.rb +++ b/lib/banzai/filter/wiki_link_filter.rb @@ -2,7 +2,8 @@ require 'uri' module Banzai module Filter - # HTML filter that "fixes" relative links to files in a repository. + # HTML filter that "fixes" links to pages/files in a wiki. + # Rewrite rules are documented in the `WikiPipeline` spec. # # Context options: # :project_wiki @@ -25,36 +26,15 @@ module Banzai end def process_link_attr(html_attr) - return if html_attr.blank? || file_reference?(html_attr) || hierarchical_link?(html_attr) + return if html_attr.blank? - uri = URI(html_attr.value) - if uri.relative? && uri.path.present? - html_attr.value = rebuild_wiki_uri(uri).to_s - end + html_attr.value = apply_rewrite_rules(html_attr.value) rescue URI::Error # noop end - def rebuild_wiki_uri(uri) - uri.path = ::File.join(project_wiki_base_path, uri.path) - uri - end - - def project_wiki - context[:project_wiki] - end - - def file_reference?(html_attr) - !File.extname(html_attr.value).blank? - end - - # Of the form `./link`, `../link`, or similar - def hierarchical_link?(html_attr) - html_attr.value[0] == '.' - end - - def project_wiki_base_path - project_wiki && project_wiki.wiki_base_path + def apply_rewrite_rules(link_string) + Rewriter.new(link_string, wiki: context[:project_wiki], slug: context[:page_slug]).apply_rules end end end diff --git a/lib/banzai/filter/wiki_link_filter/rewriter.rb b/lib/banzai/filter/wiki_link_filter/rewriter.rb new file mode 100644 index 0000000000..2e2c8da311 --- /dev/null +++ b/lib/banzai/filter/wiki_link_filter/rewriter.rb @@ -0,0 +1,40 @@ +module Banzai + module Filter + class WikiLinkFilter < HTML::Pipeline::Filter + class Rewriter + def initialize(link_string, wiki:, slug:) + @uri = Addressable::URI.parse(link_string) + @wiki_base_path = wiki && wiki.wiki_base_path + @slug = slug + end + + def apply_rules + apply_file_link_rules! + apply_hierarchical_link_rules! + apply_relative_link_rules! + @uri.to_s + end + + private + + # Of the form 'file.md' + def apply_file_link_rules! + @uri = Addressable::URI.join(@slug, @uri) if @uri.extname.present? + end + + # Of the form `./link`, `../link`, or similar + def apply_hierarchical_link_rules! + @uri = Addressable::URI.join(@slug, @uri) if @uri.to_s[0] == '.' + end + + # Any link _not_ of the form `http://example.com/` + def apply_relative_link_rules! + if @uri.relative? && @uri.path.present? + link = ::File.join(@wiki_base_path, @uri.path) + @uri = Addressable::URI.parse(link) + end + end + end + end + end +end diff --git a/spec/factories/wiki_pages.rb b/spec/factories/wiki_pages.rb index 938ccf2306..efa6cbe5bb 100644 --- a/spec/factories/wiki_pages.rb +++ b/spec/factories/wiki_pages.rb @@ -2,7 +2,7 @@ require 'ostruct' FactoryGirl.define do factory :wiki_page do - page = OpenStruct.new(url_path: 'some-name') + page { OpenStruct.new(url_path: 'some-name') } association :wiki, factory: :project_wiki, strategy: :build initialize_with { new(wiki, page, true) } end diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb deleted file mode 100644 index 185abbb210..0000000000 --- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'spec_helper' - -describe Banzai::Filter::WikiLinkFilter, lib: true do - include FilterSpecHelper - - let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") } - let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) } - let(:user) { double } - let(:project_wiki) { ProjectWiki.new(project, user) } - - describe "links within the wiki (relative)" do - describe "hierarchical links to the current directory" do - it "doesn't rewrite non-file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('./page') - end - - it "doesn't rewrite file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('./page.md') - end - end - - describe "hierarchical links to the parent directory" do - it "doesn't rewrite non-file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('../page') - end - - it "doesn't rewrite file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('../page.md') - end - end - - describe "hierarchical links to a sub-directory" do - it "doesn't rewrite non-file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('./subdirectory/page') - end - - it "doesn't rewrite file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('./subdirectory/page.md') - end - end - - describe "non-hierarchical links" do - it 'rewrites non-file links to be at the scope of the wiki root' do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to match('/wiki_link_ns/wiki_link_project/wikis/page') - end - - it "doesn't rewrite file links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('page.md') - end - end - end - - describe "links outside the wiki (absolute)" do - it "doesn't rewrite links" do - link = "Link to Page" - filtered_link = filter(link, project_wiki: project_wiki).children[0] - - expect(filtered_link.attribute('href').value).to eq('http://example.com/page') - end - end -end diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb index 7aa1b4a3bf..ea4ab2c852 100644 --- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb @@ -50,4 +50,112 @@ describe Banzai::Pipeline::WikiPipeline do end end end + + describe "Links" do + let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") } + let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) } + let(:project_wiki) { ProjectWiki.new(project, double(:user)) } + let(:page) { build(:wiki_page, wiki: project_wiki, page: OpenStruct.new(url_path: 'nested/twice/start-page')) } + + { "when GitLab is hosted at a root URL" => '/', + "when GitLab is hosted at a relative URL" => '/nested/relative/gitlab' }.each do |test_name, relative_url_root| + + context test_name do + before do + allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return(relative_url_root) + end + + describe "linking to pages within the wiki" do + context "when creating hierarchical links to the current directory" do + it "rewrites non-file links to be at the scope of the current directory" do + markdown = "[Page](./page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page\"") + end + + it "rewrites file links to be at the scope of the current directory" do + markdown = "[Link to Page](./page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"") + end + end + + context "when creating hierarchical links to the parent directory" do + it "rewrites non-file links to be at the scope of the parent directory" do + markdown = "[Link to Page](../page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page\"") + end + + it "rewrites file links to be at the scope of the parent directory" do + markdown = "[Link to Page](../page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page.md\"") + end + end + + context "when creating hierarchical links to a sub-directory" do + it "rewrites non-file links to be at the scope of the sub-directory" do + markdown = "[Link to Page](./subdirectory/page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page\"") + end + + it "rewrites file links to be at the scope of the sub-directory" do + markdown = "[Link to Page](./subdirectory/page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page.md\"") + end + end + + describe "when creating non-hierarchical links" do + it 'rewrites non-file links to be at the scope of the wiki root' do + markdown = "[Link to Page](page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"") + end + + it "rewrites file links to be at the scope of the current directory" do + markdown = "[Link to Page](page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"") + end + end + + describe "when creating root links" do + it 'rewrites non-file links to be at the scope of the wiki root' do + markdown = "[Link to Page](/page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"") + end + + it 'rewrites file links to be at the scope of the wiki root' do + markdown = "[Link to Page](/page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page.md\"") + end + end + end + + describe "linking to pages outside the wiki (absolute)" do + it "doesn't rewrite links" do + markdown = "[Link to Page](http://example.com/page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include('href="http://example.com/page"') + end + end + end + end + end end From e6b1d1669b362ad4cea27ac44e89e73f4d6e92fd Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 8 Jun 2016 10:32:50 +0530 Subject: [PATCH 13/14] Hook up the updated `WikiLinkFilter` to the wiki controllers. - Need to pass in a `page_slug` to the filter, so it can rewrite based on the current page (all links are rewritten to the level of the app root). - The earlier `markdown_preview` endpoint was at the level of the wiki. We need to know the current page (for rewriting, as above), so this commit moves the endpoint to the level of a wiki page. - Fix all tests --- app/controllers/projects/wikis_controller.rb | 2 +- app/helpers/gitlab_markdown_helper.rb | 2 +- app/views/layouts/project.html.haml | 4 ++-- config/routes.rb | 2 +- features/steps/project/wiki.rb | 4 ++-- spec/features/markdown_spec.rb | 3 ++- spec/helpers/gitlab_markdown_helper_spec.rb | 3 ++- spec/support/markdown_feature.rb | 4 ++++ 8 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 4b404eb03f..2aa6bed072 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -95,7 +95,7 @@ class Projects::WikisController < Projects::ApplicationController ext.analyze(text, author: current_user) render json: { - body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki), + body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id]), references: { users: ext.users.map(&:username) } diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 0a1b48af21..067a00660a 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -108,7 +108,7 @@ module GitlabMarkdownHelper def render_wiki_content(wiki_page) case wiki_page.format when :markdown - markdown(wiki_page.content, pipeline: :wiki, project_wiki: @project_wiki) + markdown(wiki_page.content, pipeline: :wiki, project_wiki: @project_wiki, page_slug: wiki_page.slug) when :asciidoc asciidoc(wiki_page.content) else diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 20d6cdf724..2049b20495 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -5,8 +5,8 @@ - content_for :scripts_body_top do - project = @target_project || @project - - if @project_wiki - - markdown_preview_path = namespace_project_wikis_markdown_preview_path(project.namespace, project) + - if @project_wiki && @page + - markdown_preview_path = namespace_project_wiki_markdown_preview_path(project.namespace, project, params[:id]) - else - markdown_preview_path = markdown_preview_namespace_project_path(project.namespace, project) - if current_user diff --git a/config/routes.rb b/config/routes.rb index 428302d0fd..34126bbe91 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -591,7 +591,6 @@ Rails.application.routes.draw do # Order matters to give priority to these matches get '/wikis/git_access', to: 'wikis#git_access' get '/wikis/pages', to: 'wikis#pages', as: 'wiki_pages' - post '/wikis/markdown_preview', to:'wikis#markdown_preview' post '/wikis', to: 'wikis#create' get '/wikis/*id/history', to: 'wikis#history', as: 'wiki_history', constraints: WIKI_SLUG_ID @@ -600,6 +599,7 @@ Rails.application.routes.draw do get '/wikis/*id', to: 'wikis#show', as: 'wiki', constraints: WIKI_SLUG_ID delete '/wikis/*id', to: 'wikis#destroy', constraints: WIKI_SLUG_ID put '/wikis/*id', to: 'wikis#update', constraints: WIKI_SLUG_ID + post '/wikis/*id/markdown_preview', to:'wikis#markdown_preview', constraints: WIKI_SLUG_ID, as: 'wiki_markdown_preview' end resource :repository, only: [:show, :create] do diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index 9f6aed1c5b..3cbf832c72 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -97,7 +97,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps file = Gollum::File.new(wiki.wiki) Gollum::Wiki.any_instance.stub(:file).with("image.jpg", "master", true).and_return(file) Gollum::File.any_instance.stub(:mime_type).and_return("image/jpeg") - expect(page).to have_link('image', href: "image.jpg") + expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/image.jpg") click_on "image" end @@ -113,7 +113,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I click on image link' do - expect(page).to have_link('image', href: "image.jpg") + expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/image.jpg") click_on "image" end diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 1d892fe1a5..07275bfb3d 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -231,13 +231,14 @@ describe 'GitLab Markdown', feature: true do context 'wiki pipeline' do before do @project_wiki = @feat.project_wiki + @project_wiki_page = @feat.project_wiki_page file = Gollum::File.new(@project_wiki.wiki) expect(file).to receive(:path).and_return('images/example.jpg') expect(@project_wiki).to receive(:find_file).with('images/example.jpg').and_return(file) allow(@project_wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' } - @html = markdown(@feat.raw_markdown, { pipeline: :wiki, project_wiki: @project_wiki }) + @html = markdown(@feat.raw_markdown, { pipeline: :wiki, project_wiki: @project_wiki, page_slug: @project_wiki_page.slug }) end it_behaves_like 'all pipelines' diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 13de88e2f2..ade5c3b02d 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -121,13 +121,14 @@ describe GitlabMarkdownHelper do before do @wiki = double('WikiPage') allow(@wiki).to receive(:content).and_return('wiki content') + allow(@wiki).to receive(:slug).and_return('nested/page') helper.instance_variable_set(:@project_wiki, @wiki) end it "should use Wiki pipeline for markdown files" do allow(@wiki).to receive(:format).and_return(:markdown) - expect(helper).to receive(:markdown).with('wiki content', pipeline: :wiki, project_wiki: @wiki) + expect(helper).to receive(:markdown).with('wiki content', pipeline: :wiki, project_wiki: @wiki, page_slug: "nested/page") helper.render_wiki_content(@wiki) end diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb index 7fc6d6fcc5..a79386b5db 100644 --- a/spec/support/markdown_feature.rb +++ b/spec/support/markdown_feature.rb @@ -32,6 +32,10 @@ class MarkdownFeature @project_wiki ||= ProjectWiki.new(project, user) end + def project_wiki_page + @project_wiki_page ||= build(:wiki_page, wiki: project_wiki) + end + def issue @issue ||= create(:issue, project: project) end From 19b91e749a6320d12fb299d33f1f6440777e0e26 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Thu, 9 Jun 2016 10:16:46 +0530 Subject: [PATCH 14/14] Add #18019 to the CHANGELOG. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index d1cde40c1c..1e51bbff4e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,7 @@ v 8.9.0 (unreleased) - Add DB index on users.state - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database - Changed the Slack build message to use the singular duration if necessary (Aran Koning) + - Links from a wiki page to other wiki pages should be rewritten as expected - Fix issues filter when ordering by milestone - Todos will display target state if issuable target is 'Closed' or 'Merged' - Fix bug when sorting issues by milestone due date and filtering by two or more labels