From 09ed7c02744f0c1c1e7fa65f41adaa55a170d464 Mon Sep 17 00:00:00 2001
From: ArtOfCode- <hello@artofcode.co.uk>
Date: Wed, 1 Jul 2020 00:26:56 +0100
Subject: [PATCH] Tests

---
 app/controllers/tags_controller.rb       |  11 ++-
 app/models/tag.rb                        |   2 +-
 test/controllers/tags_controller_test.rb | 119 +++++++++++++++++++++++
 test/fixtures/tags.yml                   |  11 +++
 4 files changed, 139 insertions(+), 4 deletions(-)

diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index dd8504599..f055fc9b2 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -47,13 +47,18 @@ class TagsController < ApplicationController
     end
   end
 
-  def edit; end
+  def edit
+    check_your_privilege('EditTag', nil, true)
+  end
 
   def update
-    if @tag.update(tag_params.merge(wiki: helpers.render_markdown(params[:tag][:wiki_markdown])))
+    return unless check_your_privilege('EditTag', nil, true)
+
+    wiki_md = params[:tag][:wiki_markdown]
+    if @tag.update(tag_params.merge(wiki: wiki_md.present? ? helpers.render_markdown(wiki_md) : nil))
       redirect_to tag_path(id: @category.id, tag_id: @tag.id)
     else
-      render :edit
+      render :edit, status: 400
     end
   end
 
diff --git a/app/models/tag.rb b/app/models/tag.rb
index d9daa475d..5ee4ccc71 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -13,7 +13,7 @@ class Tag < ApplicationRecord
 
   def self.search(term)
     where('name LIKE ?', "%#{sanitize_sql_like(term)}%")
-      .order(sanitize_sql_array(['name LIKE ? DESC, name', "#{sanitize_sql_like(term)}%"]))
+      .order(Arel.sql(sanitize_sql_array(['name LIKE ? DESC, name', "#{sanitize_sql_like(term)}%"])))
   end
 
   def all_children
diff --git a/test/controllers/tags_controller_test.rb b/test/controllers/tags_controller_test.rb
index c27607337..171dce5a0 100644
--- a/test/controllers/tags_controller_test.rb
+++ b/test/controllers/tags_controller_test.rb
@@ -23,4 +23,123 @@ class TagsControllerTest < ActionController::TestCase
       assert_equal true, tag['name'].start_with?('dis')
     end
   end
+
+  test 'should get category tags list' do
+    get :category, params: { id: categories(:main).id }
+    assert_response 200
+    assert_not_nil assigns(:tags)
+    assert_not_nil assigns(:category)
+
+    sign_in users(:standard_user)
+    get :category, params: { id: categories(:main).id }
+    assert_response 200
+    assert_not_nil assigns(:tags)
+    assert_not_nil assigns(:category)
+  end
+
+  test 'should get children list' do
+    get :children, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 200
+    assert_not_nil assigns(:tags)
+    assert_not_nil assigns(:category)
+
+    sign_in users(:standard_user)
+    get :children, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 200
+    assert_not_nil assigns(:tags)
+    assert_not_nil assigns(:category)
+  end
+
+  test 'should get tag page and RSS' do
+    get :show, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 200
+    assert_not_nil assigns(:tag)
+    assert_not_nil assigns(:category)
+    assert_not_nil assigns(:posts)
+
+    sign_in users(:standard_user)
+    get :show, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 200
+    assert_not_nil assigns(:tag)
+    assert_not_nil assigns(:category)
+    assert_not_nil assigns(:posts)
+  end
+
+  test 'should get tag RSS feed' do
+    get :show, params: { id: categories(:main).id, tag_id: tags(:topic).id, format: :rss }
+    assert_response 200
+    assert_not_nil assigns(:tag)
+    assert_not_nil assigns(:category)
+    assert_not_nil assigns(:posts)
+
+    sign_in users(:standard_user)
+    get :show, params: { id: categories(:main).id, tag_id: tags(:topic).id, format: :rss }
+    assert_response 200
+    assert_not_nil assigns(:tag)
+    assert_not_nil assigns(:category)
+    assert_not_nil assigns(:posts)
+  end
+
+  test 'should deny edit to anonymous user' do
+    get :edit, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 302
+    assert_redirected_to new_user_session_path
+  end
+
+  test 'should deny edit to unprivileged user' do
+    sign_in users(:standard_user)
+    get :edit, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 401
+  end
+
+  test 'should get edit' do
+    sign_in users(:deleter)
+    get :edit, params: { id: categories(:main).id, tag_id: tags(:topic).id }
+    assert_response 200
+    assert_not_nil assigns(:tag)
+    assert_not_nil assigns(:category)
+  end
+
+  test 'should deny update to anonymous user' do
+    patch :update, params: { id: categories(:main).id, tag_id: tags(:topic).id,
+                             tag: { parent_id: tags(:discussion).id, excerpt: 'things' } }
+    assert_response 302
+    assert_redirected_to new_user_session_path
+  end
+
+  test 'should deny update to unprivileged user' do
+    sign_in users(:standard_user)
+    patch :update, params: { id: categories(:main).id, tag_id: tags(:topic).id,
+                             tag: { parent_id: tags(:discussion).id, excerpt: 'things' } }
+    assert_response 401
+  end
+
+  test 'should update tag' do
+    sign_in users(:deleter)
+    patch :update, params: { id: categories(:main).id, tag_id: tags(:topic).id,
+                             tag: { parent_id: tags(:discussion).id, excerpt: 'things' } }
+    assert_response 302
+    assert_redirected_to tag_path(id: categories(:main).id, tag_id: tags(:topic).id)
+    assert_not_nil assigns(:tag)
+    assert_equal tags(:discussion).id, assigns(:tag).parent_id
+    assert_equal 'things', assigns(:tag).excerpt
+  end
+
+  test 'should prevent a tag being its own parent' do
+    sign_in users(:deleter)
+    patch :update, params: { id: categories(:main).id, tag_id: tags(:topic).id,
+                             tag: { parent_id: tags(:topic).id, excerpt: 'things' } }
+    assert_response 400
+    assert_not_nil assigns(:tag)
+    assert_equal ['A tag cannot be its own parent.'], assigns(:tag).errors.full_messages
+  end
+
+  test 'should prevent hierarchical loops' do
+    sign_in users(:deleter)
+    patch :update, params: { id: categories(:main).id, tag_id: tags(:topic).id,
+                             tag: { parent_id: tags(:child).id, excerpt: 'things' } }
+    assert_response 400
+    assert_not_nil assigns(:tag)
+    assert_equal ["The #{tags(:child).name} tag is already a child of this tag."], assigns(:tag).errors.full_messages
+  end
 end
diff --git a/test/fixtures/tags.yml b/test/fixtures/tags.yml
index d35e8f1c0..de28397ed 100644
--- a/test/fixtures/tags.yml
+++ b/test/fixtures/tags.yml
@@ -27,3 +27,14 @@ status-completed:
   name: status-completed
   community: sample
   tag_set: meta
+
+topic:
+  name: topic-tag
+  community: sample
+  tag_set: main
+
+child:
+  name: child-tag
+  community: sample
+  tag_set: main
+  parent: topic
-- 
GitLab