submodule_helper_spec.rb 10.7 KB
Newer Older
1 2 3
require 'spec_helper'

describe SubmoduleHelper do
4 5
  include RepoHelpers

6
  describe 'submodule links' do
7
    let(:submodule_item) { double(id: 'hash', path: 'rack') }
8
    let(:config) { Gitlab.config.gitlab }
9 10 11 12 13
    let(:repo) { double() }

    before do
      self.instance_variable_set(:@repository, repo)
    end
14 15 16

    context 'submodule on self' do
      before do
17
        allow(Gitlab.config.gitlab).to receive(:protocol).and_return('http') # set this just to be sure
18 19
      end

20
      it 'detects ssh on standard port' do
21 22
        allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(22) # set this just to be sure
        allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
23 24
        stub_url([config.user, '@', config.host, ':gitlab-org/gitlab-ce.git'].join(''))
        expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
25
      end
26

27
      it 'detects ssh on non-standard port' do
28 29
        allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(2222)
        allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
30 31
        stub_url(['ssh://', config.user, '@', config.host, ':2222/gitlab-org/gitlab-ce.git'].join(''))
        expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
32 33
      end

34
      it 'detects http on standard port' do
35 36
        allow(Gitlab.config.gitlab).to receive(:port).and_return(80)
        allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
37 38
        stub_url(['http://', config.host, '/gitlab-org/gitlab-ce.git'].join(''))
        expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
39 40
      end

41
      it 'detects http on non-standard port' do
42 43
        allow(Gitlab.config.gitlab).to receive(:port).and_return(3000)
        allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
44 45
        stub_url(['http://', config.host, ':3000/gitlab-org/gitlab-ce.git'].join(''))
        expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
46 47
      end

48
      it 'works with relative_url_root' do
49 50 51
        allow(Gitlab.config.gitlab).to receive(:port).and_return(80) # set this just to be sure
        allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return('/gitlab/root')
        allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
52 53
        stub_url(['http://', config.host, '/gitlab/root/gitlab-org/gitlab-ce.git'].join(''))
        expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')])
54
      end
55 56 57 58 59 60 61 62

      it 'works with subgroups' do
        allow(Gitlab.config.gitlab).to receive(:port).and_return(80) # set this just to be sure
        allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return('/gitlab/root')
        allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
        stub_url(['http://', config.host, '/gitlab/root/gitlab-org/sub/gitlab-ce.git'].join(''))
        expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org/sub', 'gitlab-ce'), namespace_project_tree_path('gitlab-org/sub', 'gitlab-ce', 'hash')])
      end
63
    end
64

65
    context 'submodule on github.com' do
66
      it 'detects ssh' do
67
        stub_url('git@github.com:gitlab-org/gitlab-ce.git')
68
        expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
69
      end
70

71
      it 'detects http' do
72
        stub_url('http://github.com/gitlab-org/gitlab-ce.git')
73
        expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
74
      end
75

76
      it 'detects https' do
77
        stub_url('https://github.com/gitlab-org/gitlab-ce.git')
78
        expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
79
      end
80

81
      it 'handles urls with no .git on the end' do
82
        stub_url('http://github.com/gitlab-org/gitlab-ce')
83 84
        expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash'])
      end
85

86
      it 'returns original with non-standard url' do
87
        stub_url('http://github.com/another/gitlab-org/gitlab-ce.git')
88
        expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
89 90
      end
    end
91

92 93
    context 'in-repository submodule' do
      let(:group) { create(:group, name: "Master Project", path: "master-project") }
94
      let(:project) { create(:project, group: group) }
95 96

      it 'in-repository' do
97 98
        allow(repo).to receive(:project).and_return(project)

99 100 101 102 103
        stub_url('./')
        expect(submodule_links(submodule_item)).to eq(["/master-project/#{project.path}", "/master-project/#{project.path}/tree/hash"])
      end
    end

104
    context 'submodule on gitlab.com' do
105
      it 'detects ssh' do
106
        stub_url('git@gitlab.com:gitlab-org/gitlab-ce.git')
107
        expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
108
      end
109

110
      it 'detects http' do
111
        stub_url('http://gitlab.com/gitlab-org/gitlab-ce.git')
112
        expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
113
      end
114

115
      it 'detects https' do
116
        stub_url('https://gitlab.com/gitlab-org/gitlab-ce.git')
117
        expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
118
      end
119

120
      it 'handles urls with no .git on the end' do
121
        stub_url('http://gitlab.com/gitlab-org/gitlab-ce')
122 123
        expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
      end
124

125 126 127 128 129
      it 'handles urls with trailing whitespace' do
        stub_url('http://gitlab.com/gitlab-org/gitlab-ce.git  ')
        expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
      end

130
      it 'returns original with non-standard url' do
131
        stub_url('http://gitlab.com/another/gitlab-org/gitlab-ce.git')
132
        expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
133 134
      end
    end
135

136
    context 'submodule on unsupported' do
137 138 139 140 141 142 143 144 145 146 147 148
      it 'sanitizes unsupported protocols' do
        stub_url('javascript:alert("XSS");')

        expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
      end

      it 'sanitizes unsupported protocols disguised as a repository URL' do
        stub_url('javascript:alert("XSS");foo/bar.git')

        expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
      end

149 150 151 152 153 154
      it 'sanitizes invalid URL with extended ASCII' do
        stub_url('é')

        expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
      end

155
      it 'returns original' do
156
        stub_url('http://mygitserver.com/gitlab-org/gitlab-ce')
157
        expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
158

159
        stub_url('http://mygitserver.com/gitlab-org/gitlab-ce.git')
160
        expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
161 162
      end
    end
163 164

    context 'submodules with relative links' do
165
      let(:group) { create(:group, name: "top group", path: "top-group") }
166
      let(:project) { create(:project, group: group) }
167 168 169 170 171 172 173 174 175
      let(:repo) { double(:repo, project: project) }

      def expect_relative_link_to_resolve_to(relative_path, expected_path)
        allow(repo).to receive(:submodule_url_for).and_return(relative_path)

        result = submodule_links(submodule_item)

        expect(result).to eq([expected_path, "#{expected_path}/tree/#{submodule_item.id}"])
      end
176

177 178
      it 'handles project under same group' do
        expect_relative_link_to_resolve_to('../test.git', "/#{group.path}/test")
179 180
      end

181 182
      it 'handles trailing whitespace' do
        expect_relative_link_to_resolve_to('../test.git ', "/#{group.path}/test")
183 184
      end

185 186 187 188 189 190 191 192 193 194 195 196
      it 'handles project under another top group' do
        expect_relative_link_to_resolve_to('../../baz/test.git ', "/baz/test")
      end

      context 'repo path resolves to be located at root (namespace absent)' do
        it 'returns nil' do
          allow(repo).to receive(:submodule_url_for).and_return('../../test.git')

          result = submodule_links(submodule_item)

          expect(result).to eq([nil, nil])
        end
197 198
      end

199 200 201 202 203 204 205 206
      context 'repo path resolves to be located underneath current project path' do
        it 'returns nil because it is not possible to have repo nested under another repo' do
          allow(repo).to receive(:submodule_url_for).and_return('./test.git')

          result = submodule_links(submodule_item)

          expect(result).to eq([nil, nil])
        end
207 208
      end

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
      context 'subgroup' do
        let(:sub_group) { create(:group, parent: group, name: "sub group", path: "sub-group") }
        let(:sub_project) { create(:project, group: sub_group) }

        context 'project in sub group' do
          let(:project) { sub_project }

          it "handles referencing ancestor group's project" do
            expect_relative_link_to_resolve_to('../../../top-group/test.git', "/#{group.path}/test")
          end
        end

        it "handles referencing descendent group's project" do
          expect_relative_link_to_resolve_to('../sub-group/test.git', "/top-group/sub-group/test")
        end

        it "handles referencing another top group's project" do
          expect_relative_link_to_resolve_to('../../frontend/css/test.git', "/frontend/css/test")
        end
228
      end
229 230 231

      context 'personal project' do
        let(:user) { create(:user) }
232
        let(:project) { create(:project, namespace: user.namespace) }
233

234 235
        it 'handles referencing another personal project' do
          expect_relative_link_to_resolve_to('../test.git', "/#{user.username}/test")
236 237
        end
      end
238
    end
239
  end
240 241

  def stub_url(url)
242
    allow(repo).to receive(:submodule_url_for).and_return(url)
243
  end
244
end