summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/wiki_page.rb29
-rw-r--r--spec/models/wiki_page_spec.rb30
2 files changed, 54 insertions, 5 deletions
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index a563b0b7a72..a84f84c67cd 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -12,10 +12,17 @@ class WikiPage
ActiveModel::Name.new(self, nil, 'wiki')
end
+ # Sorts and groups pages by directory.
+ #
+ # pages - an array of WikiPage objects.
+ #
+ # Returns a hash whose keys are directories and whose values are WikiPage
+ # arrays. See WikiPage.sort_by_directory for more info about the ordering.
def self.group_by_directory(pages)
return {} if pages.blank?
- directories = { '/' => [] }
+ pages = sort_by_directory(pages)
+ directories = {}
pages.each do |page|
directories[page.directory] ||= []
directories[page.directory] << page
@@ -199,6 +206,26 @@ class WikiPage
private
+ # Sorts an array of pages by directory and file alphabetical order.
+ # Pages at the root directory will come first. The next pages will be
+ # sorted by their directories. Within directories, pages are sorted by
+ # filename alphabetical order. Pages are sorted in such a fashion that
+ # nested directories will always follow their parents (e.g. pages in
+ # dir_1/nested_dir_1 will follow pages inside dir_1).
+ #
+ # pages - an array of WikiPage objects.
+ #
+ # Returns a sorted array of WikiPage objects.
+ def self.sort_by_directory(pages)
+ pages.sort do |page, next_page|
+ if page.directory == next_page.directory
+ page.slug <=> next_page.slug
+ else
+ page.directory <=> next_page.directory
+ end
+ end
+ end
+
def set_attributes
attributes[:slug] = @page.url_path
attributes[:title] = @page.title
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 91d5fccce60..374849e1932 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -17,17 +17,22 @@ describe WikiPage, models: true do
context 'when there are pages' do
before do
- create_page('page_1', 'content')
+ create_page('dir_1/dir_1_1/page_3', 'content')
create_page('dir_1/page_2', 'content')
- create_page('dir_1/dir_2/page_3', 'content')
+ create_page('dir_2/page_5', 'content')
+ create_page('dir_2/page_4', 'content')
+ create_page('page_1', 'content')
end
it 'returns a hash in which keys are directories and values are their pages' do
page_1 = wiki.find_page('page_1')
page_2 = wiki.find_page('dir_1/page_2')
- page_3 = wiki.find_page('dir_1/dir_2/page_3')
+ page_3 = wiki.find_page('dir_1/dir_1_1/page_3')
+ page_4 = wiki.find_page('dir_2/page_4')
+ page_5 = wiki.find_page('dir_2/page_5')
expected_grouped_pages = {
- '/' => [page_1], '/dir_1' => [page_2], '/dir_1/dir_2' => [page_3]
+ '/' => [page_1], '/dir_1' => [page_2], '/dir_1/dir_1_1' => [page_3],
+ '/dir_2' => [page_4, page_5]
}
grouped_pages = WikiPage.group_by_directory(wiki.pages)
@@ -39,6 +44,23 @@ describe WikiPage, models: true do
expect(slugs).to match_array(expected_slugs)
end
end
+
+ it 'returns a hash in which keys (directories) are sorted by alphabetical position' do
+ expected_ordered_directories = ['/', '/dir_1', '/dir_1/dir_1_1', '/dir_2']
+
+ grouped_pages = WikiPage.group_by_directory(wiki.pages)
+
+ expect(grouped_pages.keys).to eq(expected_ordered_directories)
+ end
+
+ it 'returns a hash in which values (pages) are sorted by alphabetical position' do
+ expected_ordered_page_slugs = ['dir_2/page_4', 'dir_2/page_5']
+
+ grouped_pages = WikiPage.group_by_directory(wiki.pages)
+
+ dir_2_page_slugs = grouped_pages.fetch('/dir_2').map(&:slug)
+ expect(dir_2_page_slugs).to eq(expected_ordered_page_slugs)
+ end
end
end