wiki_page_spec.rb 10.5 KB
Newer Older
1 2
require "spec_helper"

3
describe WikiPage do
4
  let(:project) { create(:project) }
5
  let(:user) { project.owner }
6
  let(:wiki) { ProjectWiki.new(project, user) }
7

8
  subject { described_class.new(wiki) }
9

10
  describe '.group_by_directory' do
11
    context 'when there are no pages' do
12
      it 'returns an empty array' do
13 14
        expect(described_class.group_by_directory(nil)).to eq([])
        expect(described_class.group_by_directory([])).to eq([])
15 16 17 18
      end
    end

    context 'when there are pages' do
19
      before do
20
        create_page('dir_1/dir_1_1/page_3', 'content')
21
        create_page('dir_1/page_2', 'content')
22 23 24
        create_page('dir_2/page_5', 'content')
        create_page('dir_2/page_4', 'content')
        create_page('page_1', 'content')
25
      end
26 27 28 29 30 31 32 33 34 35 36 37
      let(:page_1) { wiki.find_page('page_1') }
      let(:dir_1) do
        WikiDirectory.new('dir_1', [wiki.find_page('dir_1/page_2')])
      end
      let(:dir_1_1) do
        WikiDirectory.new('dir_1/dir_1_1', [wiki.find_page('dir_1/dir_1_1/page_3')])
      end
      let(:dir_2) do
        pages = [wiki.find_page('dir_2/page_5'),
                 wiki.find_page('dir_2/page_4')]
        WikiDirectory.new('dir_2', pages)
      end
38

39 40
      it 'returns an array with pages and directories' do
        expected_grouped_entries = [page_1, dir_1, dir_1_1, dir_2]
41

42
        grouped_entries = described_class.group_by_directory(wiki.pages)
43

44 45 46 47
        grouped_entries.each_with_index do |page_or_dir, i|
          expected_page_or_dir = expected_grouped_entries[i]
          expected_slugs = get_slugs(expected_page_or_dir)
          slugs = get_slugs(page_or_dir)
48

49 50
          expect(slugs).to match_array(expected_slugs)
        end
51
      end
52

53 54 55 56 57
      it 'returns an array sorted by alphabetical position' do
        # Directories and pages within directories are sorted alphabetically.
        # Pages at root come before everything.
        expected_order = ['page_1', 'dir_1/page_2', 'dir_1/dir_1_1/page_3',
                          'dir_2/page_4', 'dir_2/page_5']
58

59
        grouped_entries = described_class.group_by_directory(wiki.pages)
60

61 62 63
        actual_order =
          grouped_entries.map do |page_or_dir|
            get_slugs(page_or_dir)
64 65
          end
          .flatten
66
        expect(actual_order).to eq(expected_order)
67
      end
68 69 70
    end
  end

A
Alex Braha Stoll 已提交
71 72 73 74
  describe '.unhyphenize' do
    it 'removes hyphens from a name' do
      name = 'a-name--with-hyphens'

75
      expect(described_class.unhyphenize(name)).to eq('a name with hyphens')
A
Alex Braha Stoll 已提交
76 77 78
    end
  end

79 80 81 82 83
  describe "#initialize" do
    context "when initialized with an existing gollum page" do
      before do
        create_page("test page", "test content")
        @page = wiki.wiki.paged("test page")
84
        @wiki_page = described_class.new(wiki, @page, true)
85 86 87
      end

      it "sets the slug attribute" do
88
        expect(@wiki_page.slug).to eq("test-page")
89 90 91
      end

      it "sets the title attribute" do
92
        expect(@wiki_page.title).to eq("test page")
93 94 95
      end

      it "sets the formatted content attribute" do
96
        expect(@wiki_page.content).to eq("test content")
97 98 99
      end

      it "sets the format attribute" do
100
        expect(@wiki_page.format).to eq(:markdown)
101 102 103
      end

      it "sets the message attribute" do
104
        expect(@wiki_page.message).to eq("test commit")
105 106 107
      end

      it "sets the version attribute" do
108
        expect(@wiki_page.version).to be_a Gollum::Git::Commit
109 110 111 112 113 114
      end
    end
  end

  describe "validations" do
    before do
115
      subject.attributes = { title: 'title', content: 'content' }
116 117 118 119
    end

    it "validates presence of title" do
      subject.attributes.delete(:title)
120
      expect(subject.valid?).to be_falsey
121 122 123 124
    end

    it "validates presence of content" do
      subject.attributes.delete(:content)
125
      expect(subject.valid?).to be_falsey
126 127 128 129
    end
  end

  before do
130
    @wiki_attr = { title: "Index", content: "Home Page", format: "markdown" }
131 132 133 134 135 136 137 138 139 140
  end

  describe "#create" do
    after do
      destroy_page("Index")
    end

    context "with valid attributes" do
      it "saves the wiki page" do
        subject.create(@wiki_attr)
141
        expect(wiki.find_page("Index")).not_to be_nil
142 143 144
      end

      it "returns true" do
145
        expect(subject.create(@wiki_attr)).to eq(true)
146 147 148 149
      end
    end
  end

S
Stan Hu 已提交
150 151 152 153
  describe "dot in the title" do
    let(:title) { 'Index v1.2.3' }

    before do
154
      @wiki_attr = { title: title, content: "Home Page", format: "markdown" }
S
Stan Hu 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    end

    describe "#create" do
      after do
        destroy_page(title)
      end

      context "with valid attributes" do
        it "saves the wiki page" do
          subject.create(@wiki_attr)
          expect(wiki.find_page(title)).not_to be_nil
        end

        it "returns true" do
          expect(subject.create(@wiki_attr)).to eq(true)
        end
      end
    end

    describe "#update" do
      before do
        create_page(title, "content")
        @page = wiki.find_page(title)
      end

      it "updates the content of the page" do
181
        @page.update(content: "new content")
S
Stan Hu 已提交
182 183 184 185
        @page = wiki.find_page(title)
      end

      it "returns true" do
186
        expect(@page.update(content: "more content")).to be_truthy
S
Stan Hu 已提交
187 188 189 190
      end
    end
  end

191 192 193 194 195 196 197
  describe "#update" do
    before do
      create_page("Update", "content")
      @page = wiki.find_page("Update")
    end

    after do
198
      destroy_page(@page.title)
199 200 201 202
    end

    context "with valid attributes" do
      it "updates the content of the page" do
203 204 205
        new_content = "new content"

        @page.update(content: new_content)
206
        @page = wiki.find_page("Update")
207 208 209 210 211 212 213 214 215 216 217

        expect(@page.content).to eq("new content")
      end

      it "updates the title of the page" do
        new_title = "Index v.1.2.4"

        @page.update(title: new_title)
        @page = wiki.find_page(new_title)

        expect(@page.title).to eq(new_title)
218 219 220
      end

      it "returns true" do
221
        expect(@page.update(content: "more content")).to be_truthy
222 223
      end
    end
H
Hiroyuki Sato 已提交
224

225 226
    context 'with same last commit sha' do
      it 'returns true' do
227
        expect(@page.update(content: 'more content', last_commit_sha: @page.last_commit_sha)).to be_truthy
H
Hiroyuki Sato 已提交
228 229 230
      end
    end

231 232
    context 'with different last commit sha' do
      it 'raises exception' do
233
        expect { @page.update(content: 'more content', last_commit_sha: 'xxx') }.to raise_error(WikiPage::PageChangedError)
H
Hiroyuki Sato 已提交
234 235
      end
    end
236 237 238 239 240 241 242 243
  end

  describe "#destroy" do
    before do
      create_page("Delete Page", "content")
      @page = wiki.find_page("Delete Page")
    end

244
    it "deletes the page" do
245
      @page.delete
246
      expect(wiki.pages).to be_empty
247 248
    end

249
    it "returns true" do
250
      expect(@page.delete).to eq(true)
251 252 253 254 255 256 257 258 259 260 261 262 263 264
    end
  end

  describe "#versions" do
    before do
      create_page("Update", "content")
      @page = wiki.find_page("Update")
    end

    after do
      destroy_page("Update")
    end

    it "returns an array of all commits for the page" do
265
      3.times { |i| @page.update(content: "content #{i}") }
266
      expect(@page.versions.count).to eq(4)
267 268 269
    end
  end

270 271 272 273 274 275 276 277 278 279
  describe "#title" do
    before do
      create_page("Title", "content")
      @page = wiki.find_page("Title")
    end

    after do
      destroy_page("Title")
    end

280
    it "replaces a hyphen to a space" do
281
      @page.title = "Import-existing-repositories-into-GitLab"
282
      expect(@page.title).to eq("Import existing repositories into GitLab")
283
    end
J
Jacopo 已提交
284 285 286 287 288 289

    it 'unescapes html' do
      @page.title = 'foo & bar'

      expect(@page.title).to eq('foo & bar')
    end
290 291
  end

292 293
  describe '#directory' do
    context 'when the page is at the root directory' do
A
Alex Braha Stoll 已提交
294
      it 'returns an empty string' do
295 296 297
        create_page('file', 'content')
        page = wiki.find_page('file')

A
Alex Braha Stoll 已提交
298
        expect(page.directory).to eq('')
299 300 301 302 303 304 305 306
      end
    end

    context 'when the page is inside an actual directory' do
      it 'returns the full directory hierarchy' do
        create_page('dir_1/dir_1_1/file', 'content')
        page = wiki.find_page('dir_1/dir_1_1/file')

A
Alex Braha Stoll 已提交
307
        expect(page.directory).to eq('dir_1/dir_1_1')
308 309 310 311
      end
    end
  end

312 313 314 315
  describe '#historical?' do
    before do
      create_page('Update', 'content')
      @page = wiki.find_page('Update')
316
      3.times { |i| @page.update(content: "content #{i}") }
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
    end

    after do
      destroy_page('Update')
    end

    it 'returns true when requesting an old version' do
      old_version = @page.versions.last.to_s
      old_page = wiki.find_page('Update', old_version)

      expect(old_page.historical?).to eq true
    end

    it 'returns false when requesting latest version' do
      latest_version = @page.versions.first.to_s
      latest_page = wiki.find_page('Update', latest_version)

      expect(latest_page.historical?).to eq false
    end

    it 'returns false when version is nil' do
      latest_page = wiki.find_page('Update', nil)

      expect(latest_page.historical?).to eq false
    end
  end

A
Alex Braha Stoll 已提交
344 345 346 347 348 349 350 351
  describe '#to_partial_path' do
    it 'returns the relative path to the partial to be used' do
      page = build(:wiki_page)

      expect(page.to_partial_path).to eq('projects/wikis/wiki_page')
    end
  end

352 353 354 355 356 357 358 359
  describe '#==' do
    let(:original_wiki_page) { create(:wiki_page) }

    it 'returns true for identical wiki page' do
      expect(original_wiki_page).to eq(original_wiki_page)
    end

    it 'returns false for updated wiki page' do
360
      updated_wiki_page = original_wiki_page.update(content: "Updated content")
361 362 363 364
      expect(original_wiki_page).not_to eq(updated_wiki_page)
    end
  end

H
Hiroyuki Sato 已提交
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
  describe '#last_commit_sha' do
    before do
      create_page("Update", "content")
      @page = wiki.find_page("Update")
    end

    after do
      destroy_page("Update")
    end

    it 'returns commit sha' do
      expect(@page.last_commit_sha).to eq @page.commit.sha
    end

    it 'is changed after page updated' do
      last_commit_sha_before_update = @page.last_commit_sha

382
      @page.update(content: "new content")
H
Hiroyuki Sato 已提交
383 384 385 386 387 388
      @page = wiki.find_page("Update")

      expect(@page.last_commit_sha).not_to eq last_commit_sha_before_update
    end
  end

389 390 391 392 393 394 395
  private

  def remove_temp_repo(path)
    FileUtils.rm_rf path
  end

  def commit_details
396
    { name: user.name, email: user.email, message: "test commit" }
397 398 399 400 401 402 403 404 405 406
  end

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

  def destroy_page(title)
    page = wiki.wiki.paged(title)
    wiki.wiki.delete_page(page, commit_details)
  end
407 408 409 410 411 412 413 414

  def get_slugs(page_or_dir)
    if page_or_dir.is_a? WikiPage
      [page_or_dir.slug]
    else
      page_or_dir.pages.present? ? page_or_dir.pages.map(&:slug) : []
    end
  end
415
end