project_wiki_spec.rb 11.0 KB
Newer Older
1 2
require "spec_helper"

3
describe ProjectWiki do
4
  let(:project) { create(:project) }
5 6 7
  let(:repository) { project.repository }
  let(:user) { project.owner }
  let(:gitlab_shell) { Gitlab::Shell.new }
8
  let(:project_wiki) { described_class.new(project, user) }
9
  let(:raw_repository) { Gitlab::Git::Repository.new(project.repository_storage, subject.disk_path + '.git', 'foo') }
10

11
  subject { project_wiki }
12

13 14 15 16
  it { is_expected.to delegate_method(:empty?).to :pages }
  it { is_expected.to delegate_method(:repository_storage_path).to :project }
  it { is_expected.to delegate_method(:hashed_storage?).to :project }

17
  describe "#full_path" do
18
    it "returns the project path with namespace with the .wiki extension" do
19
      expect(subject.full_path).to eq(project.full_path + '.wiki')
20 21 22
    end

    it 'returns the same value as #full_path' do
23
      expect(subject.full_path).to eq(subject.full_path)
24 25 26
    end
  end

27 28
  describe '#web_url' do
    it 'returns the full web URL to the wiki' do
29
      expect(subject.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.full_path}/wikis/home")
30 31 32
    end
  end

33 34
  describe "#url_to_repo" do
    it "returns the correct ssh url to the repo" do
35
      expect(subject.url_to_repo).to eq(gitlab_shell.url_to_repo(subject.full_path))
36 37 38 39 40
    end
  end

  describe "#ssh_url_to_repo" do
    it "equals #url_to_repo" do
41
      expect(subject.ssh_url_to_repo).to eq(subject.url_to_repo)
42 43 44 45
    end
  end

  describe "#http_url_to_repo" do
46
    let(:project) { create :project }
47

48
    it 'returns the full http url to the repo' do
49
      expected_url = "#{Gitlab.config.gitlab.url}/#{subject.full_path}.git"
50

51 52
      expect(project_wiki.http_url_to_repo).to eq(expected_url)
      expect(project_wiki.http_url_to_repo).not_to include('@')
53 54 55
    end
  end

56 57
  describe "#wiki_base_path" do
    it "returns the wiki base path" do
58
      wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.full_path}/wikis"
59

60 61 62 63
      expect(subject.wiki_base_path).to eq(wiki_base_path)
    end
  end

64
  describe "#wiki" do
65 66
    it "contains a Gitlab::Git::Wiki instance" do
      expect(subject.wiki).to be_a Gitlab::Git::Wiki
67 68 69
    end

    it "creates a new wiki repo if one does not yet exist" do
70
      expect(project_wiki.create_page("index", "test content")).to be_truthy
71 72 73
    end

    it "raises CouldNotCreateWikiError if it can't create the wiki repository" do
74 75 76
      # Create a fresh project which will not have a wiki
      project_wiki = described_class.new(create(:project), user)
      gitlab_shell = double(:gitlab_shell)
77
      allow(gitlab_shell).to receive(:create_repository)
78 79 80
      allow(project_wiki).to receive(:gitlab_shell).and_return(gitlab_shell)

      expect { project_wiki.send(:wiki) }.to raise_exception(ProjectWiki::CouldNotCreateWikiError)
81 82 83
    end
  end

J
Jacob Vosmaer 已提交
84 85
  describe "#empty?" do
    context "when the wiki repository is empty" do
86 87 88 89
      describe '#empty?' do
        subject { super().empty? }
        it { is_expected.to be_truthy }
      end
J
Jacob Vosmaer 已提交
90 91 92 93
    end

    context "when the wiki has pages" do
      before do
94
        project_wiki.create_page("index", "This is an awesome new Gollum Wiki")
J
Jacob Vosmaer 已提交
95 96
      end

97 98 99 100
      describe '#empty?' do
        subject { super().empty? }
        it { is_expected.to be_falsey }
      end
J
Jacob Vosmaer 已提交
101 102 103
    end
  end

104 105 106 107 108 109 110 111 112 113 114
  describe "#pages" do
    before do
      create_page("index", "This is an awesome new Gollum Wiki")
      @pages = subject.pages
    end

    after do
      destroy_page(@pages.first.page)
    end

    it "returns an array of WikiPage instances" do
115
      expect(@pages.first).to be_a WikiPage
116 117 118
    end

    it "returns the correct number of pages" do
119
      expect(@pages.count).to eq(1)
120 121 122 123
    end
  end

  describe "#find_page" do
124 125 126 127
    shared_examples 'finding a wiki page' do
      before do
        create_page("index page", "This is an awesome Gollum Wiki")
      end
128

129
      after do
130
        subject.pages.each { |page| destroy_page(page.page) }
131
      end
132

133 134 135 136 137 138 139 140
      it "returns the latest version of the page if it exists" do
        page = subject.find_page("index page")
        expect(page.title).to eq("index page")
      end

      it "returns nil if the page does not exist" do
        expect(subject.find_page("non-existant")).to eq(nil)
      end
141

142 143 144 145 146 147 148 149 150
      it "can find a page by slug" do
        page = subject.find_page("index-page")
        expect(page.title).to eq("index page")
      end

      it "returns a WikiPage instance" do
        page = subject.find_page("index page")
        expect(page).to be_a WikiPage
      end
151 152 153 154 155 156 157 158 159 160 161

      context 'pages with multibyte-character title' do
        before do
          create_page("autre pagé", "C'est un génial Gollum Wiki")
        end

        it "can find a page by slug" do
          page = subject.find_page("autre pagé")
          expect(page.title).to eq("autre pagé")
        end
      end
162 163
    end

164 165
    context 'when Gitaly wiki_find_page is enabled' do
      it_behaves_like 'finding a wiki page'
166 167
    end

168 169
    context 'when Gitaly wiki_find_page is disabled', :skip_gitaly_mock do
      it_behaves_like 'finding a wiki page'
170 171 172
    end
  end

173
  describe '#find_file' do
174
    shared_examples 'finding a wiki file' do
175 176
      let(:image) { File.open(Rails.root.join('spec', 'fixtures', 'big-image.png')) }

177 178
      before do
        subject.wiki # Make sure the wiki repo exists
179

180
        BareRepoOperations.new(subject.repository.path_to_repo).commit_file(image, 'image.png')
181
      end
182

183 184 185 186 187 188 189 190 191 192 193 194 195
      it 'returns the latest version of the file if it exists' do
        file = subject.find_file('image.png')
        expect(file.mime_type).to eq('image/png')
      end

      it 'returns nil if the page does not exist' do
        expect(subject.find_file('non-existant')).to eq(nil)
      end

      it 'returns a Gitlab::Git::WikiFile instance' do
        file = subject.find_file('image.png')
        expect(file).to be_a Gitlab::Git::WikiFile
      end
196 197 198 199 200 201 202

      it 'returns the whole file' do
        file = subject.find_file('image.png')
        image.rewind

        expect(file.raw_data.b).to eq(image.read.b)
      end
203 204
    end

205 206
    context 'when Gitaly wiki_find_file is enabled' do
      it_behaves_like 'finding a wiki file'
207 208
    end

209 210
    context 'when Gitaly wiki_find_file is disabled', :skip_gitaly_mock do
      it_behaves_like 'finding a wiki file'
211 212 213
    end
  end

214
  describe "#create_page" do
215 216 217 218
    shared_examples 'creating a wiki page' do
      after do
        destroy_page(subject.pages.first.page)
      end
219

220 221 222 223
      it "creates a new wiki page" do
        expect(subject.create_page("test page", "this is content")).not_to eq(false)
        expect(subject.pages.count).to eq(1)
      end
224

225 226 227 228
      it "returns false when a duplicate page exists" do
        subject.create_page("test page", "content")
        expect(subject.create_page("test page", "content")).to eq(false)
      end
229

230 231 232 233
      it "stores an error message when a duplicate page exists" do
        2.times { subject.create_page("test page", "content") }
        expect(subject.error_message).to match(/Duplicate page:/)
      end
234

235 236 237 238 239 240 241
      it "sets the correct commit message" do
        subject.create_page("test page", "some content", :markdown, "commit message")
        expect(subject.pages.first.page.version.message).to eq("commit message")
      end

      it 'updates project activity' do
        subject.create_page('Test Page', 'This is content')
242

243
        project.reload
244

245 246 247 248 249 250 251 252
        expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
        expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
      end
    end

    context 'when Gitaly wiki_write_page is enabled' do
      it_behaves_like 'creating a wiki page'
    end
253

254 255
    context 'when Gitaly wiki_write_page is disabled', :skip_gitaly_mock do
      it_behaves_like 'creating a wiki page'
256
    end
257 258 259 260 261
  end

  describe "#update_page" do
    before do
      create_page("update-page", "some content")
262
      @gitlab_git_wiki_page = subject.wiki.page(title: "update-page")
263
      subject.update_page(
264
        @gitlab_git_wiki_page,
265 266 267 268
        content: "some other content",
        format: :markdown,
        message: "updated page"
      )
269 270 271 272 273 274 275 276
      @page = subject.pages.first.page
    end

    after do
      destroy_page(@page)
    end

    it "updates the content of the page" do
277
      expect(@page.raw_data).to eq("some other content")
278 279 280
    end

    it "sets the correct commit message" do
281
      expect(@page.version.message).to eq("updated page")
282
    end
283 284

    it 'updates project activity' do
285
      subject.update_page(
286
        @gitlab_git_wiki_page,
287 288 289 290
        content: 'Yet more content',
        format: :markdown,
        message: 'Updated page again'
      )
291 292 293 294 295

      project.reload

      expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
      expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
296
    end
297 298 299
  end

  describe "#delete_page" do
300 301 302 303 304
    shared_examples 'deleting a wiki page' do
      before do
        create_page("index", "some content")
        @page = subject.wiki.page(title: "index")
      end
305

306 307 308 309
      it "deletes the page" do
        subject.delete_page(@page)
        expect(subject.pages.count).to eq(0)
      end
310

311 312
      it 'updates project activity' do
        subject.delete_page(@page)
313

314
        project.reload
315

316 317 318 319 320 321 322 323 324 325 326
        expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
        expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
      end
    end

    context 'when Gitaly wiki_delete_page is enabled' do
      it_behaves_like 'deleting a wiki page'
    end

    context 'when Gitaly wiki_delete_page is disabled', :skip_gitaly_mock do
      it_behaves_like 'deleting a wiki page'
327
    end
328 329
  end

330 331
  describe '#create_repo!' do
    it 'creates a repository' do
332
      expect(raw_repository.exists?).to eq(false)
333 334
      expect(subject.repository).to receive(:after_create)

335 336 337
      subject.send(:create_repo!, raw_repository)

      expect(raw_repository.exists?).to eq(true)
338 339 340
    end
  end

341 342
  describe '#ensure_repository' do
    it 'creates the repository if it not exist' do
343
      expect(raw_repository.exists?).to eq(false)
344

345
      expect(subject).to receive(:create_repo!).and_call_original
346
      subject.ensure_repository
347 348

      expect(raw_repository.exists?).to eq(true)
349 350 351
    end

    it 'does not create the repository if it exists' do
352 353
      subject.wiki
      expect(raw_repository.exists?).to eq(true)
354 355 356 357 358 359 360

      expect(subject).not_to receive(:create_repo!)

      subject.ensure_repository
    end
  end

361 362 363 364 365 366 367
  describe '#hook_attrs' do
    it 'returns a hash with values' do
      expect(subject.hook_attrs).to be_a Hash
      expect(subject.hook_attrs.keys).to contain_exactly(:web_url, :git_ssh_url, :git_http_url, :path_with_namespace, :default_branch)
    end
  end

368 369 370 371
  private

  def create_temp_repo(path)
    FileUtils.mkdir_p path
372
    system(*%W(#{Gitlab.config.git.bin_path} init --quiet --bare -- #{path}))
373 374 375 376 377 378 379
  end

  def remove_temp_repo(path)
    FileUtils.rm_rf path
  end

  def commit_details
380
    Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "test commit")
381 382 383 384 385 386 387
  end

  def create_page(name, content)
    subject.wiki.write_page(name, :markdown, content, commit_details)
  end

  def destroy_page(page)
388
    subject.delete_page(page, "test commit")
389
  end
390
end