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

Douwe Maan's avatar
Douwe Maan committed
3
describe WikiPage, models: true do
4
  let(:project) { create(:empty_project) }
5
  let(:user) { project.owner }
6
  let(:wiki) { ProjectWiki.new(project, user) }
7 8 9

  subject { WikiPage.new(wiki) }

10
  describe '.group_by_directory' do
11
    context 'when there are no pages' do
12 13 14
      it 'returns an empty array' do
        expect(WikiPage.group_by_directory(nil)).to eq([])
        expect(WikiPage.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 = WikiPage.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 = WikiPage.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

71 72 73 74 75 76 77 78
  describe '.unhyphenize' do
    it 'removes hyphens from a name' do
      name = 'a-name--with-hyphens'

      expect(WikiPage.unhyphenize(name)).to eq('a name with hyphens')
    end
  end

79 80 81 82 83 84 85 86 87
  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")
        @wiki_page = WikiPage.new(wiki, @page, true)
      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

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" }
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 181 182 183 184 185 186 187 188 189 190
    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
        @page.update("new content")
        @page = wiki.find_page(title)
      end

      it "returns true" do
        expect(@page.update("more content")).to be_truthy
      end
    end
  end

191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
  describe "#update" do
    before do
      create_page("Update", "content")
      @page = wiki.find_page("Update")
    end

    after do
      destroy_page("Update")
    end

    context "with valid attributes" do
      it "updates the content of the page" do
        @page.update("new content")
        @page = wiki.find_page("Update")
      end

      it "returns true" do
208
        expect(@page.update("more content")).to be_truthy
209 210 211 212 213 214 215 216 217 218
      end
    end
  end

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

219
    it "deletes the page" do
220
      @page.delete
221
      expect(wiki.pages).to be_empty
222 223
    end

224
    it "returns true" do
225
      expect(@page.delete).to eq(true)
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
    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
      3.times { |i| @page.update("content #{i}") }
241
      expect(@page.versions.count).to eq(4)
242 243 244
    end
  end

245 246 247 248 249 250 251 252 253 254
  describe "#title" do
    before do
      create_page("Title", "content")
      @page = wiki.find_page("Title")
    end

    after do
      destroy_page("Title")
    end

255
    it "replaces a hyphen to a space" do
256
      @page.title = "Import-existing-repositories-into-GitLab"
257
      expect(@page.title).to eq("Import existing repositories into GitLab")
258 259 260
    end
  end

261 262
  describe '#directory' do
    context 'when the page is at the root directory' do
263
      it 'returns an empty string' do
264 265 266
        create_page('file', 'content')
        page = wiki.find_page('file')

267
        expect(page.directory).to eq('')
268 269 270 271 272 273 274 275
      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')

276
        expect(page.directory).to eq('dir_1/dir_1_1')
277 278 279 280
      end
    end
  end

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
  describe '#historical?' do
    before do
      create_page('Update', 'content')
      @page = wiki.find_page('Update')
      3.times { |i| @page.update("content #{i}") }
    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

313 314 315 316 317 318 319 320
  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

321 322 323 324 325 326 327 328 329 330 331 332 333
  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
      updated_wiki_page = original_wiki_page.update("Updated content")
      expect(original_wiki_page).not_to eq(updated_wiki_page)
    end
  end

334 335 336 337 338 339 340
  private

  def remove_temp_repo(path)
    FileUtils.rm_rf path
  end

  def commit_details
341
    { name: user.name, email: user.email, message: "test commit" }
342 343 344 345 346 347 348 349 350 351
  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
352 353 354 355 356 357 358 359

  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
360
end