From 1cd28600652e23c8605b9344e269c34e83edccd1 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Mon, 27 Jul 2015 15:29:10 +0900 Subject: Fix the image file that contains non-ascii character is not displayed --- CHANGELOG | 1 + lib/gitlab/markdown/relative_link_filter.rb | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e198b48e86e..808f66b9483 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) + - Fix the image file that contains non-ascii character is not displayed(Hiroyuki Sato) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix Error 500 when browsing projects with no HEAD (Stan Hu) - Fix full screen mode for snippet comments (Daniel Gerhardt) diff --git a/lib/gitlab/markdown/relative_link_filter.rb b/lib/gitlab/markdown/relative_link_filter.rb index 9de2b24a9da..3eaceba5323 100644 --- a/lib/gitlab/markdown/relative_link_filter.rb +++ b/lib/gitlab/markdown/relative_link_filter.rb @@ -98,9 +98,10 @@ module Gitlab # # Returns a String def path_type(path) - if repository.tree(current_sha, path).entries.any? + unescaped_path = Addressable::URI.unescape(path) + if repository.tree(current_sha, unescaped_path).entries.any? 'tree' - elsif repository.blob_at(current_sha, path).try(:image?) + elsif repository.blob_at(current_sha, unescaped_path).try(:image?) 'raw' else 'blob' -- cgit v1.2.1 From a784b996b3071cfe1807b1108316143dbc64492f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 28 Jul 2015 15:49:44 +0200 Subject: Add project star and fork count, group avatar URL and user/group web URL attributes to API --- CHANGELOG | 1 + app/models/group.rb | 11 +++++++++++ app/models/user.rb | 4 ++++ lib/api/entities.rb | 4 +++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index cf0fa36bd47..eef3c3e7c01 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,7 @@ v 7.14.0 (unreleased) - Expire Rails cache entries after two weeks to prevent endless Redis growth - Add support for destroying project milestones (Stan Hu) - Add fetch command to the MR page + - Add project star and fork count, group avatar URL and user/group web URL attributes to API v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list diff --git a/app/models/group.rb b/app/models/group.rb index 051c672cb33..adcbbec465e 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -17,6 +17,7 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Group < Namespace + include Gitlab::ConfigHelper include Referable has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' @@ -56,6 +57,16 @@ class Group < Namespace name end + def avatar_url(size = nil) + if avatar.present? + [gitlab_config.url, avatar.url].join + end + end + + def web_url + [gitlab_config.url, "groups", self.path].join('/') + end + def owners @owners ||= group_members.owners.map(&:user) end diff --git a/app/models/user.rb b/app/models/user.rb index 4a10520b209..00a37cd9135 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -637,6 +637,10 @@ class User < ActiveRecord::Base end end + def web_url + [gitlab_config.url, "u", self.username].join('/') + end + def all_emails [self.email, *self.emails.map(&:email)] end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index ecf1412dee5..c1b0cece344 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -5,7 +5,7 @@ module API end class UserBasic < UserSafe - expose :id, :state, :avatar_url + expose :id, :state, :avatar_url, :web_url end class User < UserBasic @@ -59,6 +59,7 @@ module API expose :namespace expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ | project, options | project.forked? } expose :avatar_url + expose :star_count, :forks_count end class ProjectMember < UserBasic @@ -69,6 +70,7 @@ module API class Group < Grape::Entity expose :id, :name, :path, :description + expose :avatar_url, :web_url end class GroupDetail < Group -- cgit v1.2.1 From b07ecbb5e37530e7754dc267da4ded1d7d2d736d Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 19 Jul 2015 19:41:54 -0400 Subject: Simplify AutolinkFilter specs --- spec/features/markdown_spec.rb | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index b8199aa5e61..b8a846c7015 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -195,45 +195,41 @@ describe 'GitLab Markdown', feature: true do end describe 'AutolinkFilter' do - let(:list) { get_section('autolinkfilter').next_element } + def body + get_section('autolinkfilter').next_element + end - def item(index) - list.at_css("li:nth-child(#{index})") + # Override Capybara's `have_link` matcher to simplify our use case + def have_link(link) + super(link, href: link) end it 'autolinks http://' do - expect(item(1).children.first.name).to eq 'a' - expect(item(1).children.first['href']).to eq 'http://about.gitlab.com/' + expect(body).to have_link('http://about.gitlab.com/') end it 'autolinks https://' do - expect(item(2).children.first.name).to eq 'a' - expect(item(2).children.first['href']).to eq 'https://google.com/' + expect(body).to have_link('https://google.com/') end it 'autolinks ftp://' do - expect(item(3).children.first.name).to eq 'a' - expect(item(3).children.first['href']).to eq 'ftp://ftp.us.debian.org/debian/' + expect(body).to have_link('ftp://ftp.us.debian.org/debian/') end it 'autolinks smb://' do - expect(item(4).children.first.name).to eq 'a' - expect(item(4).children.first['href']).to eq 'smb://foo/bar/baz' + expect(body).to have_link('smb://foo/bar/baz') end it 'autolinks irc://' do - expect(item(5).children.first.name).to eq 'a' - expect(item(5).children.first['href']).to eq 'irc://irc.freenode.net/git' + expect(body).to have_link('irc://irc.freenode.net/git') end it 'autolinks short, invalid URLs' do - expect(item(6).children.first.name).to eq 'a' - expect(item(6).children.first['href']).to eq 'http://localhost:3000' + expect(body).to have_link('http://localhost:3000') end %w(code a kbd).each do |elem| it "ignores links inside '#{elem}' element" do - body = get_section('autolinkfilter') expect(body).not_to have_selector("#{elem} a") end end -- cgit v1.2.1 From 06478ef3ecba80625e5cff70cb3697f442e24cba Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 20 Jul 2015 22:22:17 -0400 Subject: Minor Markdown feature spec reorganization --- spec/features/markdown_spec.rb | 93 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index b8a846c7015..f1be4e49c8a 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -33,39 +33,31 @@ require 'erb' # See the MarkdownFeature class for setup details. describe 'GitLab Markdown', feature: true do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::UrlHelper include Capybara::Node::Matchers include GitlabMarkdownHelper - # `markdown` calls these two methods - def current_user - @feat.user - end - - def user_color_scheme_class - :white - end - # Let's only parse this thing once before(:all) do @feat = MarkdownFeature.new - # `markdown` expects a `@project` variable + # `gfm_with_options` depends on a `@project` variable @project = @feat.project - @md = markdown(@feat.raw_markdown) - @doc = Nokogiri::HTML::DocumentFragment.parse(@md) + @html = markdown(@feat.raw_markdown) end after(:all) do @feat.teardown end + def doc + @doc ||= Nokogiri::HTML::DocumentFragment.parse(@html) + end + # Given a header ID, goes to that element's parent (the header itself), then # its next sibling element (the body). def get_section(id) - @doc.at_css("##{id}").parent.next_element + doc.at_css("##{id}").parent.next_element end # Sometimes it can be useful to see the parsed output of the Markdown document @@ -74,11 +66,11 @@ describe 'GitLab Markdown', feature: true do # # it 'writes to a file' do # File.open(Rails.root.join('tmp/capybara/markdown_spec.html'), 'w') do |file| - # file.puts @md + # file.puts @html # end # end - describe 'Markdown' do + describe 'Redcarpet extensions' do describe 'No Intra Emphasis' do it 'does not parse emphasis inside of words' do body = get_section('no-intra-emphasis') @@ -95,21 +87,21 @@ describe 'GitLab Markdown', feature: true do end it 'allows Markdown in tables' do - expect(@doc.at_css('td:contains("Baz")').children.to_html). + expect(doc.at_css('td:contains("Baz")').children.to_html). to eq 'Baz' end end describe 'Fenced Code Blocks' do it 'parses fenced code blocks' do - expect(@doc).to have_selector('pre.code.highlight.white.c') - expect(@doc).to have_selector('pre.code.highlight.white.python') + expect(doc).to have_selector('pre.code.highlight.white.c') + expect(doc).to have_selector('pre.code.highlight.white.python') end end describe 'Strikethrough' do it 'parses strikethroughs' do - expect(@doc).to have_selector(%{del:contains("and this text doesn't")}) + expect(doc).to have_selector(%{del:contains("and this text doesn't")}) end end @@ -125,28 +117,28 @@ describe 'GitLab Markdown', feature: true do describe 'HTML::Pipeline' do describe 'SanitizationFilter' do it 'uses a permissive whitelist' do - expect(@doc).to have_selector('b:contains("b tag")') - expect(@doc).to have_selector('em:contains("em tag")') - expect(@doc).to have_selector('code:contains("code tag")') - expect(@doc).to have_selector('kbd:contains("s")') - expect(@doc).to have_selector('strike:contains(Emoji)') - expect(@doc).to have_selector('img[src*="smile.png"]') - expect(@doc).to have_selector('br') - expect(@doc).to have_selector('hr') + expect(doc).to have_selector('b:contains("b tag")') + expect(doc).to have_selector('em:contains("em tag")') + expect(doc).to have_selector('code:contains("code tag")') + expect(doc).to have_selector('kbd:contains("s")') + expect(doc).to have_selector('strike:contains(Emoji)') + expect(doc).to have_selector('img[src*="smile.png"]') + expect(doc).to have_selector('br') + expect(doc).to have_selector('hr') end it 'permits span elements' do - expect(@doc).to have_selector('span:contains("span tag")') + expect(doc).to have_selector('span:contains("span tag")') end it 'permits table alignment' do - expect(@doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' - expect(@doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' - expect(@doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' + expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' + expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' + expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' - expect(@doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' - expect(@doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' - expect(@doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' + expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' + expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' + expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' end it 'removes `rel` attribute from links' do @@ -155,12 +147,12 @@ describe 'GitLab Markdown', feature: true do end it "removes `href` from `a` elements if it's fishy" do - expect(@doc).not_to have_selector('a[href*="javascript"]') + expect(doc).not_to have_selector('a[href*="javascript"]') end end describe 'Escaping' do - let(:table) { @doc.css('table').last.at_css('tbody') } + let(:table) { doc.css('table').last.at_css('tbody') } it 'escapes non-tag angle brackets' do expect(table.at_xpath('.//tr[1]/td[3]').inner_html).to eq '1 < 3 & 5' @@ -169,28 +161,28 @@ describe 'GitLab Markdown', feature: true do describe 'Edge Cases' do it 'allows markup inside link elements' do - expect(@doc.at_css('a[href="#link-emphasis"]').to_html). + expect(doc.at_css('a[href="#link-emphasis"]').to_html). to eq %{text} - expect(@doc.at_css('a[href="#link-strong"]').to_html). + expect(doc.at_css('a[href="#link-strong"]').to_html). to eq %{text} - expect(@doc.at_css('a[href="#link-code"]').to_html). + expect(doc.at_css('a[href="#link-code"]').to_html). to eq %{text} end end describe 'EmojiFilter' do it 'parses Emoji' do - expect(@doc).to have_selector('img.emoji', count: 10) + expect(doc).to have_selector('img.emoji', count: 10) end end describe 'TableOfContentsFilter' do it 'creates anchors inside header elements' do - expect(@doc).to have_selector('h1 a#gitlab-markdown') - expect(@doc).to have_selector('h2 a#markdown') - expect(@doc).to have_selector('h3 a#autolinkfilter') + expect(doc).to have_selector('h1 a#gitlab-markdown') + expect(doc).to have_selector('h2 a#markdown') + expect(doc).to have_selector('h3 a#autolinkfilter') end end @@ -249,7 +241,7 @@ describe 'GitLab Markdown', feature: true do describe 'ReferenceFilter' do it 'handles references in headers' do - header = @doc.at_css('#reference-filters-eg-1').parent + header = doc.at_css('#reference-filters-eg-1').parent expect(header.css('a').size).to eq 2 end @@ -304,6 +296,15 @@ describe 'GitLab Markdown', feature: true do end end end + + # `markdown` calls these two methods + def current_user + @feat.user + end + + def user_color_scheme_class + :white + end end # This is a helper class used by the GitLab Markdown feature spec -- cgit v1.2.1 From 3cafa74387d707dac37d0e81bf2bb194e94957e4 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 20 Jul 2015 22:31:05 -0400 Subject: Use aggregate_failures where appropriate --- spec/features/markdown_spec.rb | 87 +++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index f1be4e49c8a..dadb1c3589f 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -81,9 +81,12 @@ describe 'GitLab Markdown', feature: true do describe 'Tables' do it 'parses table Markdown' do body = get_section('tables') - expect(body).to have_selector('th:contains("Header")') - expect(body).to have_selector('th:contains("Row")') - expect(body).to have_selector('th:contains("Example")') + + aggregate_failures do + expect(body).to have_selector('th:contains("Header")') + expect(body).to have_selector('th:contains("Row")') + expect(body).to have_selector('th:contains("Example")') + end end it 'allows Markdown in tables' do @@ -94,8 +97,10 @@ describe 'GitLab Markdown', feature: true do describe 'Fenced Code Blocks' do it 'parses fenced code blocks' do - expect(doc).to have_selector('pre.code.highlight.white.c') - expect(doc).to have_selector('pre.code.highlight.white.python') + aggregate_failures do + expect(doc).to have_selector('pre.code.highlight.white.c') + expect(doc).to have_selector('pre.code.highlight.white.python') + end end end @@ -108,8 +113,11 @@ describe 'GitLab Markdown', feature: true do describe 'Superscript' do it 'parses superscript' do body = get_section('superscript') - expect(body.to_html).to match('1st') - expect(body.to_html).to match('2nd') + + aggregate_failures do + expect(body.to_html).to match('1st') + expect(body.to_html).to match('2nd') + end end end end @@ -117,14 +125,16 @@ describe 'GitLab Markdown', feature: true do describe 'HTML::Pipeline' do describe 'SanitizationFilter' do it 'uses a permissive whitelist' do - expect(doc).to have_selector('b:contains("b tag")') - expect(doc).to have_selector('em:contains("em tag")') - expect(doc).to have_selector('code:contains("code tag")') - expect(doc).to have_selector('kbd:contains("s")') - expect(doc).to have_selector('strike:contains(Emoji)') - expect(doc).to have_selector('img[src*="smile.png"]') - expect(doc).to have_selector('br') - expect(doc).to have_selector('hr') + aggregate_failures do + expect(doc).to have_selector('b:contains("b tag")') + expect(doc).to have_selector('em:contains("em tag")') + expect(doc).to have_selector('code:contains("code tag")') + expect(doc).to have_selector('kbd:contains("s")') + expect(doc).to have_selector('strike:contains(Emoji)') + expect(doc).to have_selector('img[src*="smile.png"]') + expect(doc).to have_selector('br') + expect(doc).to have_selector('hr') + end end it 'permits span elements' do @@ -132,13 +142,15 @@ describe 'GitLab Markdown', feature: true do end it 'permits table alignment' do - expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' - expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' - expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' - - expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' - expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' - expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' + aggregate_failures do + expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' + expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' + expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' + + expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' + expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' + expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' + end end it 'removes `rel` attribute from links' do @@ -161,14 +173,16 @@ describe 'GitLab Markdown', feature: true do describe 'Edge Cases' do it 'allows markup inside link elements' do - expect(doc.at_css('a[href="#link-emphasis"]').to_html). - to eq %{text} + aggregate_failures do + expect(doc.at_css('a[href="#link-emphasis"]').to_html). + to eq %{text} - expect(doc.at_css('a[href="#link-strong"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-strong"]').to_html). + to eq %{text} - expect(doc.at_css('a[href="#link-code"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-code"]').to_html). + to eq %{text} + end end end @@ -180,9 +194,11 @@ describe 'GitLab Markdown', feature: true do describe 'TableOfContentsFilter' do it 'creates anchors inside header elements' do - expect(doc).to have_selector('h1 a#gitlab-markdown') - expect(doc).to have_selector('h2 a#markdown') - expect(doc).to have_selector('h3 a#autolinkfilter') + aggregate_failures do + expect(doc).to have_selector('h1 a#gitlab-markdown') + expect(doc).to have_selector('h2 a#markdown') + expect(doc).to have_selector('h3 a#autolinkfilter') + end end end @@ -290,9 +306,12 @@ describe 'GitLab Markdown', feature: true do describe 'Task Lists' do it 'generates task lists' do body = get_section('task-lists') - expect(body).to have_selector('ul.task-list', count: 2) - expect(body).to have_selector('li.task-list-item', count: 7) - expect(body).to have_selector('input[checked]', count: 3) + + aggregate_failures do + expect(body).to have_selector('ul.task-list', count: 2) + expect(body).to have_selector('li.task-list-item', count: 7) + expect(body).to have_selector('input[checked]', count: 3) + end end end end -- cgit v1.2.1 From 97cedc5d1b023af56c035cccc5914d11bf6299de Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 20 Jul 2015 23:57:26 -0400 Subject: Break up SanitizationFilter feature specs --- spec/features/markdown_spec.rb | 53 +++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index dadb1c3589f..5adf19980dd 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -124,29 +124,52 @@ describe 'GitLab Markdown', feature: true do describe 'HTML::Pipeline' do describe 'SanitizationFilter' do - it 'uses a permissive whitelist' do - aggregate_failures do - expect(doc).to have_selector('b:contains("b tag")') - expect(doc).to have_selector('em:contains("em tag")') - expect(doc).to have_selector('code:contains("code tag")') - expect(doc).to have_selector('kbd:contains("s")') - expect(doc).to have_selector('strike:contains(Emoji)') - expect(doc).to have_selector('img[src*="smile.png"]') - expect(doc).to have_selector('br') - expect(doc).to have_selector('hr') - end + it 'permits b elements' do + expect(doc).to have_selector('b:contains("b tag")') + end + + it 'permits em elements' do + expect(doc).to have_selector('em:contains("em tag")') + end + + it 'permits code elements' do + expect(doc).to have_selector('code:contains("code tag")') + end + + it 'permits kbd elements' do + expect(doc).to have_selector('kbd:contains("s")') + end + + it 'permits strike elements' do + expect(doc).to have_selector('strike:contains(Emoji)') + end + + it 'permits img elements' do + expect(doc).to have_selector('img[src*="smile.png"]') + end + + it 'permits br elements' do + expect(doc).to have_selector('br') + end + + it 'permits hr elements' do + expect(doc).to have_selector('hr') end it 'permits span elements' do expect(doc).to have_selector('span:contains("span tag")') end - it 'permits table alignment' do + it 'permits style attribute in th elements' do aggregate_failures do expect(doc.at_css('th:contains("Header")')['style']).to eq 'text-align: center' expect(doc.at_css('th:contains("Row")')['style']).to eq 'text-align: right' expect(doc.at_css('th:contains("Example")')['style']).to eq 'text-align: left' + end + end + it 'permits style attribute in td elements' do + aggregate_failures do expect(doc.at_css('td:contains("Foo")')['style']).to eq 'text-align: center' expect(doc.at_css('td:contains("Bar")')['style']).to eq 'text-align: right' expect(doc.at_css('td:contains("Baz")')['style']).to eq 'text-align: left' @@ -154,8 +177,7 @@ describe 'GitLab Markdown', feature: true do end it 'removes `rel` attribute from links' do - body = get_section('sanitizationfilter') - expect(body).not_to have_selector('a[rel="bookmark"]') + expect(doc).not_to have_selector('a[rel="bookmark"]') end it "removes `href` from `a` elements if it's fishy" do @@ -164,9 +186,8 @@ describe 'GitLab Markdown', feature: true do end describe 'Escaping' do - let(:table) { doc.css('table').last.at_css('tbody') } - it 'escapes non-tag angle brackets' do + table = doc.css('table').last.at_css('tbody') expect(table.at_xpath('.//tr[1]/td[3]').inner_html).to eq '1 < 3 & 5' end end -- cgit v1.2.1 From b07df8b1b05117352bc77fd4be0227dc588255fe Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 21 Jul 2015 00:21:51 -0400 Subject: Make links inside ignored elements unique This is to prevent false matches since the Autolink section uses about.gitlab.com as well. --- spec/fixtures/markdown.md.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb index 02ab46c905a..75f6528ccdf 100644 --- a/spec/fixtures/markdown.md.erb +++ b/spec/fixtures/markdown.md.erb @@ -123,9 +123,9 @@ These are all plain text that should get turned into links: But it shouldn't autolink text inside certain tags: -- http://about.gitlab.com/ -- http://about.gitlab.com/ -- http://about.gitlab.com/ +- http://code.gitlab.com/ +- http://a.gitlab.com/ +- http://kbd.gitlab.com/ ### ExternalLinkFilter -- cgit v1.2.1 From 590fca0f06c4a21dbac90480bc6622f4da97dc86 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 21 Jul 2015 00:23:27 -0400 Subject: Move MarkdownFeature to its own support file This file's about to get much bigger and this removes some of the extra noise. --- spec/features/markdown_spec.rb | 115 --------------------------------------- spec/support/markdown_feature.rb | 114 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 spec/support/markdown_feature.rb diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 5adf19980dd..46814fdfb8e 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -346,118 +346,3 @@ describe 'GitLab Markdown', feature: true do :white end end - -# This is a helper class used by the GitLab Markdown feature spec -# -# Because the feature spec only cares about the output of the Markdown, and the -# test setup and teardown and parsing is fairly expensive, we only want to do it -# once. Unfortunately RSpec will not let you access `let`s in a `before(:all)` -# block, so we fake it by encapsulating all the shared setup in this class. -# -# The class renders `spec/fixtures/markdown.md.erb` using ERB, allowing for -# reference to the factory-created objects. -class MarkdownFeature - include FactoryGirl::Syntax::Methods - - def initialize - DatabaseCleaner.start - end - - def teardown - DatabaseCleaner.clean - end - - def user - @user ||= create(:user) - end - - def group - unless @group - @group = create(:group) - @group.add_user(user, Gitlab::Access::DEVELOPER) - end - - @group - end - - # Direct references ---------------------------------------------------------- - - def project - @project ||= create(:project) - end - - def issue - @issue ||= create(:issue, project: project) - end - - def merge_request - @merge_request ||= create(:merge_request, :simple, source_project: project) - end - - def snippet - @snippet ||= create(:project_snippet, project: project) - end - - def commit - @commit ||= project.commit - end - - def commit_range - unless @commit_range - commit2 = project.commit('HEAD~3') - @commit_range = CommitRange.new("#{commit.id}...#{commit2.id}", project) - end - - @commit_range - end - - def simple_label - @simple_label ||= create(:label, name: 'gfm', project: project) - end - - def label - @label ||= create(:label, name: 'awaiting feedback', project: project) - end - - # Cross-references ----------------------------------------------------------- - - def xproject - unless @xproject - namespace = create(:namespace, name: 'cross-reference') - @xproject = create(:project, namespace: namespace) - @xproject.team << [user, :developer] - end - - @xproject - end - - def xissue - @xissue ||= create(:issue, project: xproject) - end - - def xmerge_request - @xmerge_request ||= create(:merge_request, :simple, source_project: xproject) - end - - def xsnippet - @xsnippet ||= create(:project_snippet, project: xproject) - end - - def xcommit - @xcommit ||= xproject.commit - end - - def xcommit_range - unless @xcommit_range - xcommit2 = xproject.commit('HEAD~2') - @xcommit_range = CommitRange.new("#{xcommit.id}...#{xcommit2.id}", xproject) - end - - @xcommit_range - end - - def raw_markdown - fixture = Rails.root.join('spec/fixtures/markdown.md.erb') - ERB.new(File.read(fixture)).result(binding) - end -end diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb new file mode 100644 index 00000000000..5e18ffa4143 --- /dev/null +++ b/spec/support/markdown_feature.rb @@ -0,0 +1,114 @@ +# This is a helper class used by the GitLab Markdown feature spec +# +# Because the feature spec only cares about the output of the Markdown, and the +# test setup and teardown and parsing is fairly expensive, we only want to do it +# once. Unfortunately RSpec will not let you access `let`s in a `before(:all)` +# block, so we fake it by encapsulating all the shared setup in this class. +# +# The class renders `spec/fixtures/markdown.md.erb` using ERB, allowing for +# reference to the factory-created objects. +class MarkdownFeature + include FactoryGirl::Syntax::Methods + + def initialize + DatabaseCleaner.start + end + + def teardown + DatabaseCleaner.clean + end + + def user + @user ||= create(:user) + end + + def group + unless @group + @group = create(:group) + @group.add_user(user, Gitlab::Access::DEVELOPER) + end + + @group + end + + # Direct references ---------------------------------------------------------- + + def project + @project ||= create(:project) + end + + def issue + @issue ||= create(:issue, project: project) + end + + def merge_request + @merge_request ||= create(:merge_request, :simple, source_project: project) + end + + def snippet + @snippet ||= create(:project_snippet, project: project) + end + + def commit + @commit ||= project.commit + end + + def commit_range + unless @commit_range + commit2 = project.commit('HEAD~3') + @commit_range = CommitRange.new("#{commit.id}...#{commit2.id}", project) + end + + @commit_range + end + + def simple_label + @simple_label ||= create(:label, name: 'gfm', project: project) + end + + def label + @label ||= create(:label, name: 'awaiting feedback', project: project) + end + + # Cross-references ----------------------------------------------------------- + + def xproject + unless @xproject + namespace = create(:namespace, name: 'cross-reference') + @xproject = create(:project, namespace: namespace) + @xproject.team << [user, :developer] + end + + @xproject + end + + def xissue + @xissue ||= create(:issue, project: xproject) + end + + def xmerge_request + @xmerge_request ||= create(:merge_request, :simple, source_project: xproject) + end + + def xsnippet + @xsnippet ||= create(:project_snippet, project: xproject) + end + + def xcommit + @xcommit ||= xproject.commit + end + + def xcommit_range + unless @xcommit_range + xcommit2 = xproject.commit('HEAD~2') + @xcommit_range = CommitRange.new("#{xcommit.id}...#{xcommit2.id}", xproject) + end + + @xcommit_range + end + + def raw_markdown + fixture = Rails.root.join('spec/fixtures/markdown.md.erb') + ERB.new(File.read(fixture)).result(binding) + end +end -- cgit v1.2.1 From 0673ca36812ac3f709032938b77e5ab6e1d63885 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 22 Jul 2015 21:22:16 -0400 Subject: Add RelativeLinkFilter section to Markdown fixture --- spec/fixtures/markdown.md.erb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb index 75f6528ccdf..41d12afa9ce 100644 --- a/spec/fixtures/markdown.md.erb +++ b/spec/fixtures/markdown.md.erb @@ -100,6 +100,13 @@ Markdown should be usable inside a link. Let's try! - [**text**](#link-strong) - [`text`](#link-code) +### RelativeLinkFilter + +Linking to a file relative to this project's repository should work. + +[Relative Link](doc/README.md) +![Relative Image](app/assets/images/touch-icon-ipad.png) + ### EmojiFilter Because life would be :zzz: without Emoji, right? :rocket: -- cgit v1.2.1 From 05f9a6a9c44c094d281d3dc8d80eb30c4e7dff27 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 22 Jul 2015 21:22:57 -0400 Subject: Update Markdown feature to allow for multiple pipelines --- spec/features/markdown_spec.rb | 216 +++++++---------------------- spec/support/matchers/markdown_matchers.rb | 156 +++++++++++++++++++++ 2 files changed, 209 insertions(+), 163 deletions(-) create mode 100644 spec/support/matchers/markdown_matchers.rb diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 46814fdfb8e..ddef2317e1c 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -17,16 +17,8 @@ require 'erb' # -> Post-process HTML # -> `gfm_with_options` helper # -> HTML::Pipeline -# -> Sanitize -# -> RelativeLink -# -> Emoji -# -> Table of Contents -# -> Autolinks -# -> Rinku (http, https, ftp) -# -> Other schemes -# -> ExternalLink -# -> References -# -> TaskList +# -> SanitizationFilter +# -> Other filters, depending on pipeline # -> `html_safe` # -> Template # @@ -35,6 +27,7 @@ require 'erb' describe 'GitLab Markdown', feature: true do include Capybara::Node::Matchers include GitlabMarkdownHelper + include MarkdownMatchers # Let's only parse this thing once before(:all) do @@ -42,50 +35,37 @@ describe 'GitLab Markdown', feature: true do # `gfm_with_options` depends on a `@project` variable @project = @feat.project - - @html = markdown(@feat.raw_markdown) end after(:all) do @feat.teardown end - def doc - @doc ||= Nokogiri::HTML::DocumentFragment.parse(@html) + def doc(html = @html) + Nokogiri::HTML::DocumentFragment.parse(html) end - # Given a header ID, goes to that element's parent (the header itself), then - # its next sibling element (the body). - def get_section(id) - doc.at_css("##{id}").parent.next_element + # Sometimes it can be useful to see the parsed output of the Markdown document + # for debugging. Call this method to write the output to + # `tmp/capybara/.html`. + def write_markdown(filename = 'markdown_spec') + File.open(Rails.root.join("tmp/capybara/#{filename}.html"), 'w') do |file| + file.puts @html + end end - # Sometimes it can be useful to see the parsed output of the Markdown document - # for debugging. Uncomment this block to write the output to - # tmp/capybara/markdown_spec.html. - # - # it 'writes to a file' do - # File.open(Rails.root.join('tmp/capybara/markdown_spec.html'), 'w') do |file| - # file.puts @html - # end - # end - - describe 'Redcarpet extensions' do - describe 'No Intra Emphasis' do + # Shared behavior that all pipelines should exhibit + shared_examples 'all pipelines' do + describe 'Redcarpet extensions' do it 'does not parse emphasis inside of words' do - body = get_section('no-intra-emphasis') - expect(body.to_html).not_to match('foobarbaz') + expect(doc.to_html).not_to match('foobarbaz') end - end - describe 'Tables' do it 'parses table Markdown' do - body = get_section('tables') - aggregate_failures do - expect(body).to have_selector('th:contains("Header")') - expect(body).to have_selector('th:contains("Row")') - expect(body).to have_selector('th:contains("Example")') + expect(doc).to have_selector('th:contains("Header")') + expect(doc).to have_selector('th:contains("Row")') + expect(doc).to have_selector('th:contains("Example")') end end @@ -93,36 +73,23 @@ describe 'GitLab Markdown', feature: true do expect(doc.at_css('td:contains("Baz")').children.to_html). to eq 'Baz' end - end - describe 'Fenced Code Blocks' do it 'parses fenced code blocks' do aggregate_failures do expect(doc).to have_selector('pre.code.highlight.white.c') expect(doc).to have_selector('pre.code.highlight.white.python') end end - end - describe 'Strikethrough' do it 'parses strikethroughs' do expect(doc).to have_selector(%{del:contains("and this text doesn't")}) end - end - describe 'Superscript' do it 'parses superscript' do - body = get_section('superscript') - - aggregate_failures do - expect(body.to_html).to match('1st') - expect(body.to_html).to match('2nd') - end + expect(doc).to have_selector('sup', count: 2) end end - end - describe 'HTML::Pipeline' do describe 'SanitizationFilter' do it 'permits b elements' do expect(doc).to have_selector('b:contains("b tag")') @@ -207,133 +174,56 @@ describe 'GitLab Markdown', feature: true do end end - describe 'EmojiFilter' do - it 'parses Emoji' do - expect(doc).to have_selector('img.emoji', count: 10) - end - end - - describe 'TableOfContentsFilter' do - it 'creates anchors inside header elements' do - aggregate_failures do - expect(doc).to have_selector('h1 a#gitlab-markdown') - expect(doc).to have_selector('h2 a#markdown') - expect(doc).to have_selector('h3 a#autolinkfilter') - end - end - end - - describe 'AutolinkFilter' do - def body - get_section('autolinkfilter').next_element - end - - # Override Capybara's `have_link` matcher to simplify our use case - def have_link(link) - super(link, href: link) - end - - it 'autolinks http://' do - expect(body).to have_link('http://about.gitlab.com/') - end - - it 'autolinks https://' do - expect(body).to have_link('https://google.com/') - end - - it 'autolinks ftp://' do - expect(body).to have_link('ftp://ftp.us.debian.org/debian/') - end - - it 'autolinks smb://' do - expect(body).to have_link('smb://foo/bar/baz') - end - - it 'autolinks irc://' do - expect(body).to have_link('irc://irc.freenode.net/git') - end - - it 'autolinks short, invalid URLs' do - expect(body).to have_link('http://localhost:3000') - end - - %w(code a kbd).each do |elem| - it "ignores links inside '#{elem}' element" do - expect(body).not_to have_selector("#{elem} a") - end - end - end - describe 'ExternalLinkFilter' do - let(:links) { get_section('externallinkfilter').next_element } - it 'adds nofollow to external link' do - expect(links.css('a').first.to_html).to match 'nofollow' + link = doc.at_css('a:contains("Google")') + expect(link.attr('rel')).to match 'nofollow' end it 'ignores internal link' do - expect(links.css('a').last.to_html).not_to match 'nofollow' + link = doc.at_css('a:contains("GitLab Root")') + expect(link.attr('rel')).not_to match 'nofollow' end end + end - describe 'ReferenceFilter' do - it 'handles references in headers' do - header = doc.at_css('#reference-filters-eg-1').parent - - expect(header.css('a').size).to eq 2 - end - - it "handles references in Markdown" do - body = get_section('reference-filters-eg-1') - expect(body).to have_selector('em a.gfm-merge_request', count: 1) - end - - it 'parses user references' do - body = get_section('userreferencefilter') - expect(body).to have_selector('a.gfm.gfm-project_member', count: 3) - end + context 'default pipeline' do + before(:all) do + @html = markdown(@feat.raw_markdown) + end - it 'parses issue references' do - body = get_section('issuereferencefilter') - expect(body).to have_selector('a.gfm.gfm-issue', count: 2) - end + it_behaves_like 'all pipelines' - it 'parses merge request references' do - body = get_section('mergerequestreferencefilter') - expect(body).to have_selector('a.gfm.gfm-merge_request', count: 2) - end + it 'includes RelativeLinkFilter' do + expect(doc).to parse_relative_links + end - it 'parses snippet references' do - body = get_section('snippetreferencefilter') - expect(body).to have_selector('a.gfm.gfm-snippet', count: 2) - end + it 'includes EmojiFilter' do + expect(doc).to parse_emoji + end - it 'parses commit range references' do - body = get_section('commitrangereferencefilter') - expect(body).to have_selector('a.gfm.gfm-commit_range', count: 2) - end + it 'includes TableOfContentsFilter' do + expect(doc).to create_header_links + end - it 'parses commit references' do - body = get_section('commitreferencefilter') - expect(body).to have_selector('a.gfm.gfm-commit', count: 2) - end + it 'includes AutolinkFilter' do + expect(doc).to create_autolinks + end - it 'parses label references' do - body = get_section('labelreferencefilter') - expect(body).to have_selector('a.gfm.gfm-label', count: 3) + it 'includes all reference filters' do + aggregate_failures do + expect(doc).to reference_users + expect(doc).to reference_issues + expect(doc).to reference_merge_requests + expect(doc).to reference_snippets + expect(doc).to reference_commit_ranges + expect(doc).to reference_commits + expect(doc).to reference_labels end end - describe 'Task Lists' do - it 'generates task lists' do - body = get_section('task-lists') - - aggregate_failures do - expect(body).to have_selector('ul.task-list', count: 2) - expect(body).to have_selector('li.task-list-item', count: 7) - expect(body).to have_selector('input[checked]', count: 3) - end - end + it 'includes TaskListFilter' do + expect(doc).to parse_task_lists end end diff --git a/spec/support/matchers/markdown_matchers.rb b/spec/support/matchers/markdown_matchers.rb new file mode 100644 index 00000000000..9df226c3af8 --- /dev/null +++ b/spec/support/matchers/markdown_matchers.rb @@ -0,0 +1,156 @@ +# MarkdownMatchers +# +# Custom matchers for our custom HTML::Pipeline filters. These are used to test +# that specific filters are or are not used by our defined pipelines. +# +# Must be included manually. +module MarkdownMatchers + extend RSpec::Matchers::DSL + include Capybara::Node::Matchers + + # RelativeLinkFilter + matcher :parse_relative_links do + set_default_markdown_messages + + match do |actual| + link = actual.at_css('a:contains("Relative Link")') + image = actual.at_css('img[alt="Relative Image"]') + + expect(link['href']).to end_with('master/doc/README.md') + expect(image['src']).to end_with('master/app/assets/images/touch-icon-ipad.png') + end + end + + # EmojiFilter + matcher :parse_emoji do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('img.emoji', count: 10) + end + end + + # TableOfContentsFilter + matcher :create_header_links do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('h1 a#gitlab-markdown') + expect(actual).to have_selector('h2 a#markdown') + expect(actual).to have_selector('h3 a#autolinkfilter') + end + end + + # AutolinkFilter + matcher :create_autolinks do + def have_autolink(link) + have_link(link, href: link) + end + + set_default_markdown_messages + + match do |actual| + expect(actual).to have_autolink('http://about.gitlab.com/') + expect(actual).to have_autolink('https://google.com/') + expect(actual).to have_autolink('ftp://ftp.us.debian.org/debian/') + expect(actual).to have_autolink('smb://foo/bar/baz') + expect(actual).to have_autolink('irc://irc.freenode.net/git') + expect(actual).to have_autolink('http://localhost:3000') + + %w(code a kbd).each do |elem| + expect(body).not_to have_selector("#{elem} a") + end + end + end + + # UserReferenceFilter + matcher :reference_users do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-project_member', count: 3) + end + end + + # IssueReferenceFilter + matcher :reference_issues do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-issue', count: 3) + end + end + + # MergeRequestReferenceFilter + matcher :reference_merge_requests do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-merge_request', count: 3) + expect(actual).to have_selector('em a.gfm-merge_request') + end + end + + # SnippetReferenceFilter + matcher :reference_snippets do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-snippet', count: 2) + end + end + + # CommitRangeReferenceFilter + matcher :reference_commit_ranges do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-commit_range', count: 2) + end + end + + # CommitReferenceFilter + matcher :reference_commits do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-commit', count: 2) + end + end + + # LabelReferenceFilter + matcher :reference_labels do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('a.gfm.gfm-label', count: 3) + end + end + + # TaskListFilter + matcher :parse_task_lists do + set_default_markdown_messages + + match do |actual| + expect(actual).to have_selector('ul.task-list', count: 2) + expect(actual).to have_selector('li.task-list-item', count: 7) + expect(actual).to have_selector('input[checked]', count: 3) + end + end +end + +# Monkeypatch the matcher DSL so that we can reduce some noisy duplication for +# setting the failure messages for these matchers +module RSpec::Matchers::DSL::Macros + def set_default_markdown_messages + failure_message do + # expected to parse emoji, but didn't + "expected to #{description}, but didn't" + end + + failure_message_when_negated do + # expected not to parse task lists, but did + "expected not to #{description}, but did" + end + end +end -- cgit v1.2.1 From 8c957b54f5a70d07a0c70f15c84cdf9fc7eb0f23 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 28 Jul 2015 23:27:08 -0400 Subject: Fix setup/teardown for Markdown feature spec Prior, CI seemed to be freezing after running these specs. --- spec/features/markdown_spec.rb | 25 +++++++++---------------- spec/support/markdown_feature.rb | 8 -------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index ddef2317e1c..859a62f740f 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -29,22 +29,6 @@ describe 'GitLab Markdown', feature: true do include GitlabMarkdownHelper include MarkdownMatchers - # Let's only parse this thing once - before(:all) do - @feat = MarkdownFeature.new - - # `gfm_with_options` depends on a `@project` variable - @project = @feat.project - end - - after(:all) do - @feat.teardown - end - - def doc(html = @html) - Nokogiri::HTML::DocumentFragment.parse(html) - end - # Sometimes it can be useful to see the parsed output of the Markdown document # for debugging. Call this method to write the output to # `tmp/capybara/.html`. @@ -54,6 +38,10 @@ describe 'GitLab Markdown', feature: true do end end + def doc(html = @html) + Nokogiri::HTML::DocumentFragment.parse(html) + end + # Shared behavior that all pipelines should exhibit shared_examples 'all pipelines' do describe 'Redcarpet extensions' do @@ -189,6 +177,11 @@ describe 'GitLab Markdown', feature: true do context 'default pipeline' do before(:all) do + @feat = MarkdownFeature.new + + # `gfm_with_options` depends on a `@project` variable + @project = @feat.project + @html = markdown(@feat.raw_markdown) end diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb index 5e18ffa4143..2a868aed73b 100644 --- a/spec/support/markdown_feature.rb +++ b/spec/support/markdown_feature.rb @@ -10,14 +10,6 @@ class MarkdownFeature include FactoryGirl::Syntax::Methods - def initialize - DatabaseCleaner.start - end - - def teardown - DatabaseCleaner.clean - end - def user @user ||= create(:user) end -- cgit v1.2.1 From c5aae3077335ab0eaafb73f51548d4c85413a1d1 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 29 Jul 2015 11:18:55 +0200 Subject: Set internal backup directory modes on create This sidesteps problems with running 'chmod' on some CIFS mounts. --- lib/backup/database.rb | 2 +- lib/backup/manager.rb | 2 -- lib/backup/repository.rb | 2 +- lib/backup/uploads.rb | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/backup/database.rb b/lib/backup/database.rb index c5a5396cbbf..8450019980f 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -7,7 +7,7 @@ module Backup def initialize @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] @db_dir = File.join(Gitlab.config.backup.path, 'db') - FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir) + FileUtils.mkdir_p(@db_dir, mode: 0700)unless Dir.exists?(@db_dir) end def dump diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index 6fa2079d1a8..9ae4b346436 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -16,8 +16,6 @@ module Backup file << s.to_yaml.gsub(/^---\n/,'') end - FileUtils.chmod(0700, folders_to_backup) - # create archive $progress.print "Creating backup archive: #{tar_file} ... " orig_umask = File.umask(0077) diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb index dfb2da9f84e..36d43d62982 100644 --- a/lib/backup/repository.rb +++ b/lib/backup/repository.rb @@ -130,7 +130,7 @@ module Backup def prepare FileUtils.rm_rf(backup_repos_path) - FileUtils.mkdir_p(backup_repos_path) + FileUtils.mkdir_p(backup_repos_path, mode: 0700) end def silent diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb index bf43610acf6..ed445f79084 100644 --- a/lib/backup/uploads.rb +++ b/lib/backup/uploads.rb @@ -10,7 +10,7 @@ module Backup # Copy uploads from public/uploads to backup/uploads def dump - FileUtils.mkdir_p(backup_uploads_dir) + FileUtils.mkdir_p(backup_uploads_dir, mode: 0700) FileUtils.cp_r(app_uploads_dir, backup_dir) end -- cgit v1.2.1 From 05cca9342b3cff4e9f2785a062822cd3af9fcdd4 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 29 Jul 2015 12:03:53 +0200 Subject: Use URL helpers --- app/models/group.rb | 4 ++-- app/models/project.rb | 2 +- app/models/user.rb | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/models/group.rb b/app/models/group.rb index adcbbec465e..885d3b1e5ab 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -17,7 +17,7 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Group < Namespace - include Gitlab::ConfigHelper + include Rails.application.routes.url_helpers include Referable has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' @@ -64,7 +64,7 @@ class Group < Namespace end def web_url - [gitlab_config.url, "groups", self.path].join('/') + group_url(self) end def owners diff --git a/app/models/project.rb b/app/models/project.rb index ff372ea9aa5..0608133b2cb 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -316,7 +316,7 @@ class Project < ActiveRecord::Base end def web_url - [gitlab_config.url, path_with_namespace].join('/') + namespace_project_url(self.namespace, self) end def web_url_without_protocol diff --git a/app/models/user.rb b/app/models/user.rb index 00a37cd9135..6dd2271abe2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -67,6 +67,7 @@ class User < ActiveRecord::Base include Gitlab::ConfigHelper include Gitlab::CurrentSettings + include Rails.application.routes.url_helpers include Referable include Sortable include TokenAuthenticatable @@ -638,7 +639,7 @@ class User < ActiveRecord::Base end def web_url - [gitlab_config.url, "u", self.username].join('/') + user_url(self) end def all_emails -- cgit v1.2.1 From 72c552c2d4ea985a9ab1470ba2e44fc7e52673d9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 29 Jul 2015 13:23:28 +0200 Subject: Fix specs --- app/models/project.rb | 2 +- spec/models/project_spec.rb | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 0608133b2cb..2d029962557 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -571,7 +571,7 @@ class Project < ActiveRecord::Base end def http_url_to_repo - [gitlab_config.url, '/', path_with_namespace, '.git'].join('') + "#{web_url}.git" end # Check if current branch name is marked as protected in the system diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 63091e913ff..1ffd92b9bd9 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -111,14 +111,20 @@ describe Project do expect(project.url_to_repo).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git') end - it 'returns the full web URL for this repo' do - project = Project.new(path: 'somewhere') - expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/somewhere") + describe "#web_url" do + let(:project) { create(:empty_project, path: "somewhere") } + + it 'returns the full web URL for this repo' do + expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.path}/somewhere") + end end - it 'returns the web URL without the protocol for this repo' do - project = Project.new(path: 'somewhere') - expect(project.web_url_without_protocol).to eq("#{Gitlab.config.gitlab.url.split('://')[1]}/somewhere") + describe "#web_url_without_protocol" do + let(:project) { create(:empty_project, path: "somewhere") } + + it 'returns the web URL without the protocol for this repo' do + expect(project.web_url_without_protocol).to eq("#{Gitlab.config.gitlab.url.split('://')[1]}/#{project.namespace.path}/somewhere") + end end describe 'last_activity methods' do -- cgit v1.2.1 From baa157926d432f404a41c31ad6514ff8d5366269 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 30 Jul 2015 10:17:34 +0200 Subject: Stricter mkdir's in 'rake gitlab:backup:create' --- lib/backup/database.rb | 7 +++++-- lib/backup/repository.rb | 5 ++++- lib/backup/uploads.rb | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/backup/database.rb b/lib/backup/database.rb index 8450019980f..bbb230a10f0 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -7,7 +7,11 @@ module Backup def initialize @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] @db_dir = File.join(Gitlab.config.backup.path, 'db') - FileUtils.mkdir_p(@db_dir, mode: 0700)unless Dir.exists?(@db_dir) + FileUtils.rm_rf(@db_dir) + # Ensure the parent dir of @db_dir exists + FileUtils.mkdir_p(Gitlab.config.backup.path) + # Fail if somebody raced to create @db_dir before us + FileUtils.mkdir(@db_dir, mode: 0700) end def dump @@ -25,7 +29,6 @@ module Backup abort 'Backup failed' unless success $progress.print 'Compressing database ... ' - FileUtils.rm_f db_file_name_gz success = system('gzip', db_file_name) report_success(success) abort 'Backup failed: compress error' unless success diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb index 36d43d62982..4d70f7883dd 100644 --- a/lib/backup/repository.rb +++ b/lib/backup/repository.rb @@ -130,7 +130,10 @@ module Backup def prepare FileUtils.rm_rf(backup_repos_path) - FileUtils.mkdir_p(backup_repos_path, mode: 0700) + # Ensure the parent dir of backup_repos_path exists + FileUtils.mkdir_p(Gitlab.config.backup.path) + # Fail if somebody raced to create backup_repos_path before us + FileUtils.mkdir(backup_repos_path, mode: 0700) end def silent diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb index ed445f79084..1f9626644e6 100644 --- a/lib/backup/uploads.rb +++ b/lib/backup/uploads.rb @@ -10,7 +10,11 @@ module Backup # Copy uploads from public/uploads to backup/uploads def dump - FileUtils.mkdir_p(backup_uploads_dir, mode: 0700) + FileUtils.rm_rf(backup_uploads_dir) + # Ensure the parent dir of backup_uploads_dir exists + FileUtils.mkdir_p(Gitlab.config.backup.path) + # Fail if somebody raced to create backup_uploads_dir before us + FileUtils.mkdir(backup_uploads_dir, mode: 0700) FileUtils.cp_r(app_uploads_dir, backup_dir) end -- cgit v1.2.1 From b8066e2cd0c8ae8384b68c81ea3a6c071cd44c51 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 30 Jul 2015 11:56:15 +0200 Subject: No more web url --- app/models/group.rb | 5 ----- app/models/project.rb | 3 +-- app/models/user.rb | 5 ----- lib/api/entities.rb | 12 ++++++++++-- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/models/group.rb b/app/models/group.rb index 885d3b1e5ab..cfb8faa1491 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -17,7 +17,6 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Group < Namespace - include Rails.application.routes.url_helpers include Referable has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' @@ -63,10 +62,6 @@ class Group < Namespace end end - def web_url - group_url(self) - end - def owners @owners ||= group_members.owners.map(&:user) end diff --git a/app/models/project.rb b/app/models/project.rb index 2d029962557..99be170731b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -36,7 +36,6 @@ class Project < ActiveRecord::Base include Gitlab::ConfigHelper include Gitlab::ShellAdapter include Gitlab::VisibilityLevel - include Rails.application.routes.url_helpers include Referable include Sortable @@ -316,7 +315,7 @@ class Project < ActiveRecord::Base end def web_url - namespace_project_url(self.namespace, self) + Rails.application.routes.url_helpers.namespace_project_url(self.namespace, self) end def web_url_without_protocol diff --git a/app/models/user.rb b/app/models/user.rb index 6dd2271abe2..4a10520b209 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -67,7 +67,6 @@ class User < ActiveRecord::Base include Gitlab::ConfigHelper include Gitlab::CurrentSettings - include Rails.application.routes.url_helpers include Referable include Sortable include TokenAuthenticatable @@ -638,10 +637,6 @@ class User < ActiveRecord::Base end end - def web_url - user_url(self) - end - def all_emails [self.email, *self.emails.map(&:email)] end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index c1b0cece344..dcfd7a8e1a7 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -5,7 +5,11 @@ module API end class UserBasic < UserSafe - expose :id, :state, :avatar_url, :web_url + expose :id, :state, :avatar_url + + expose :web_url do |user, options| + Rails.application.routes.url_helpers.user_url(user) + end end class User < UserBasic @@ -70,7 +74,11 @@ module API class Group < Grape::Entity expose :id, :name, :path, :description - expose :avatar_url, :web_url + expose :avatar_url + + expose :web_url do |group, options| + Rails.application.routes.url_helpers.group_url(group) + end end class GroupDetail < Group -- cgit v1.2.1 From 2a60b8006b1374aec998370f9cfe5b574255712f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 30 Jul 2015 12:35:09 +0200 Subject: Fix Project --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 99be170731b..cc2b936ba2a 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -432,7 +432,7 @@ class Project < ActiveRecord::Base if avatar.present? [gitlab_config.url, avatar.url].join elsif avatar_in_git - [gitlab_config.url, namespace_project_avatar_path(namespace, self)].join + Rails.application.routes.url_helpers.namespace_project_avatar_url(namespace, self) end end -- cgit v1.2.1 From ee1710284883d4cf61fc89d5197beef63646a220 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 29 Jul 2015 09:03:15 -0700 Subject: Check that hooks directory exists before attempting to call realpath Closes #2121 --- lib/tasks/gitlab/check.rake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index aed84226a2f..badb47c6779 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -485,7 +485,8 @@ namespace :gitlab do if project.empty_repo? puts "repository is empty".magenta - elsif File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path) + elsif File.directory?(project_hook_directory) && File.directory?(gitlab_shell_hooks_path) && + (File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path)) puts 'ok'.green else puts "wrong or missing hooks".red @@ -754,7 +755,7 @@ namespace :gitlab do print "Ruby version >= #{required_version} ? ... " if current_version.valid? && required_version <= current_version - puts "yes (#{current_version})".green + puts "yes (#{current_version})".green else puts "no".red try_fixing_it( @@ -772,7 +773,7 @@ namespace :gitlab do print "Git version >= #{required_version} ? ... " if current_version.valid? && required_version <= current_version - puts "yes (#{current_version})".green + puts "yes (#{current_version})".green else puts "no".red try_fixing_it( @@ -806,4 +807,3 @@ namespace :gitlab do end end end - -- cgit v1.2.1 From bd72b5bd32c64606a498066cadf9f765be059b9d Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 30 Jul 2015 13:40:30 -0700 Subject: Fix version for CHANGELOG entry --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c03e5053d17..a3b1b82e0eb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ v 7.14.0 (unreleased) - Add fetch command to the MR page - Fix bug causing Bitbucket importer to crash when OAuth application had been removed. - Add fetch command to the MR page. + - Disabled autocapitalize and autocorrect on login field (Daryl Chan) v 7.13.2 - Fix randomly failed spec @@ -29,7 +30,6 @@ v 7.13.2 - Show the first tab automatically on MergeRequests#new - Add rake task 'gitlab:update_commit_count' (Daniel Gerhardt) - Fix Gmail Actions - - Disabled autocapitalize and autocorrect on login field (Daryl Chan) v 7.13.1 - Fix: Label modifications are not reflected in existing notes and in the issue list -- cgit v1.2.1 From 4e22dcb6a34f43e5b3b2700ec72b32354315adc0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 30 Jul 2015 17:25:07 -0400 Subject: Add spec to RelativeLinkFilter for Unicode filenames --- lib/gitlab/markdown/relative_link_filter.rb | 13 +++++++++++-- spec/lib/gitlab/markdown/relative_link_filter_spec.rb | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/markdown/relative_link_filter.rb b/lib/gitlab/markdown/relative_link_filter.rb index 3eaceba5323..30f50b82996 100644 --- a/lib/gitlab/markdown/relative_link_filter.rb +++ b/lib/gitlab/markdown/relative_link_filter.rb @@ -99,15 +99,24 @@ module Gitlab # Returns a String def path_type(path) unescaped_path = Addressable::URI.unescape(path) - if repository.tree(current_sha, unescaped_path).entries.any? + + if tree?(unescaped_path) 'tree' - elsif repository.blob_at(current_sha, unescaped_path).try(:image?) + elsif image?(unescaped_path) 'raw' else 'blob' end end + def tree?(path) + repository.tree(current_sha, path).entries.any? + end + + def image?(path) + repository.blob_at(current_sha, path).try(:image?) + end + def current_sha context[:commit].try(:id) || ref ? repository.commit(ref).try(:sha) : repository.head_commit.sha diff --git a/spec/lib/gitlab/markdown/relative_link_filter_spec.rb b/spec/lib/gitlab/markdown/relative_link_filter_spec.rb index 5ee5310825d..7f4d67e403f 100644 --- a/spec/lib/gitlab/markdown/relative_link_filter_spec.rb +++ b/spec/lib/gitlab/markdown/relative_link_filter_spec.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + require 'spec_helper' module Gitlab::Markdown @@ -101,6 +103,20 @@ module Gitlab::Markdown expect(doc.at_css('a')['href']).to eq 'http://example.com' end + it 'supports Unicode filenames' do + path = 'files/images/한글.png' + escaped = Addressable::URI.escape(path) + + # Stub these methods so the file doesn't actually need to be in the repo + allow_any_instance_of(described_class).to receive(:file_exists?). + and_return(true) + allow_any_instance_of(described_class). + to receive(:image?).with(path).and_return(true) + + doc = filter(image(escaped)) + expect(doc.at_css('img')['src']).to match '/raw/' + end + context 'when requested path is a file in the repo' do let(:requested_path) { 'doc/api/README.md' } include_examples :relative_to_requested -- cgit v1.2.1 From 7ca7770e984d802f9f35579d6b5c08ad63a3052a Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 30 Jul 2015 17:27:25 -0400 Subject: Fix CHANGELOG entry --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 86927eae79f..c1f7da82f5e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,7 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.14.0 (unreleased) - Fix network graph when branch name has single quotes (Stan Hu) - Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu) - - Fix the image file that contains non-ascii character is not displayed(Hiroyuki Sato) + - Add support for Unicode filenames in relative links (Hiroyuki Sato) - Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki) - Fix commit data retrieval when branch name has single quotes (Stan Hu) - Check that project was actually created rather than just validated in import:repos task (Stan Hu) -- cgit v1.2.1