FEATURE: `/code-review/redirect/:sha1` to jump to a topic by SHA1

FEATURE: /code-review/redirect/:sha1 to jump to a topic by SHA1

This is a useful shortcut for jumping right to a topic if you know the sha1 of a commit that’s inside it.

I also added tests to make sure that the code-review URL requires a logged in staff user.

diff --git a/app/controllers/discourse_code_review/code_review_controller.rb b/app/controllers/discourse_code_review/code_review_controller.rb
index 9138550..5881589 100644
--- a/app/controllers/discourse_code_review/code_review_controller.rb
+++ b/app/controllers/discourse_code_review/code_review_controller.rb
@@ -9,7 +9,7 @@ module DiscourseCodeReview
     skip_before_action :ensure_logged_in, only: :webhook
     skip_before_action :ensure_staff, only: :webhook
     skip_before_action :redirect_to_login_if_required, only: :webhook
-    skip_before_action :check_xhr, only: :webhook
+    skip_before_action :check_xhr, only: [:webhook, :redirect]
 
     def webhook
 
@@ -106,6 +106,24 @@ module DiscourseCodeReview
       render_next_topic(topic.category_id)
     end
 
+    def redirect
+      sha1 = params[:sha1]
+
+      if sha1.present? && sha1.size >= 7
+        tcf = TopicCustomField
+          .where(name: DiscourseCodeReview::COMMIT_HASH)
+          .where("LEFT(LOWER(value), :len) = LOWER(:sha1)", len: sha1.size, sha1: sha1)
+          .order("created_at DESC")
+          .includes(:topic)
+          .first
+      end
+
+      raise Discourse::NotFound.new if tcf.blank?
+      guardian.ensure_can_see!(tcf.topic)
+
+      redirect_to tcf.topic.url
+    end
+
     protected
 
     def render_next_topic(category_id)
diff --git a/plugin.rb b/plugin.rb
index 7626ad2..c43b406 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -201,6 +201,7 @@ after_initialize do
       post '/followup' => 'code_review#followup'
       post '/skip' => 'code_review#skip'
       post '/webhook' => 'code_review#webhook'
+      get "/redirect/:sha1" => 'code_review#redirect', constraints: { sha1: /[0-9a-fA-F]+/ }
     end
 
     scope '/admin/plugins/code-review', as: 'admin_code_review', constraints: StaffConstraint.new do
diff --git a/spec/requests/discourse_code_review/code_review_controller_spec.rb b/spec/requests/discourse_code_review/code_review_controller_spec.rb
index 7a2d00a..165fa78 100644
--- a/spec/requests/discourse_code_review/code_review_controller_spec.rb
+++ b/spec/requests/discourse_code_review/code_review_controller_spec.rb
@@ -3,290 +3,338 @@
 require 'rails_helper'
 
 describe DiscourseCodeReview::CodeReviewController do
-  fab!(:signed_in_user) { Fabricate(:admin) }
-  fab!(:another_admin) { Fabricate(:admin) }
 
-  before do
-    SiteSetting.code_review_enabled = true
-    SiteSetting.tagging_enabled = true
-
-    sign_in signed_in_user
-  end
-
-  context '.skip' do
-    it "allows users to skip commits" do
-      commit1 = create_post(
-        raw: "this is a fake commit",
-        tags: ["hi", SiteSetting.code_review_pending_tag],
-        user: another_admin
-      )
-
-      commit2 = create_post(
-        raw: "this is a fake commit",
-        tags: ["hi", SiteSetting.code_review_pending_tag],
-        user: another_admin
-      )
-
-      commit3 = create_post(
-        raw: "this is a fake commit",
-        tags: ["hi", SiteSetting.code_review_pending_tag],
-        user: another_admin
-      )
-
-      post '/code-review/skip.json', params: { topic_id: commit3.topic_id }
-      expect(response.status).to eq(200)
+  context "when not staff" do
+    fab!(:topic) { Fabricate(:topic) }
+    before do
+      topic.upsert_custom_fields(DiscourseCodeReview::COMMIT_HASH => '6a5aecee1234')
+    end
 
-      post '/code-review/skip.json', params: { topic_id: commit2.topic_id }
-      expect(response.status).to eq(200)
+    it "returns 404 for anonymous users" do
+      get '/code-review/redirect/6a5aecee'
+      expect(response.status).to eq(404)
+    end
 
-      json = JSON.parse(response.body)
-      expect(json["next_topic_url"]).to eq(commit1.topic.relative_url)
+    it "returns 403 for a non-staff user" do
+      sign_in(Fabricate(:user))
+      get '/code-review/redirect/6a5aecee'
+      expect(response.status).to eq(403)
     end
   end
 
-  context '.approve' do
-    it 'doesn\'t allow you to approve your own commit if disabled' do
+  context "signed in as an admin" do
+    fab!(:signed_in_user) { Fabricate(:admin) }
+    fab!(:another_admin) { Fabricate(:admin) }
 
-      SiteSetting.code_review_allow_self_approval = false
+    before do
+      SiteSetting.code_review_enabled = true
+      SiteSetting.tagging_enabled = true
 
-      commit = create_post(raw: "this is a fake commit", user: signed_in_user, tags: ["hi", SiteSetting.code_review_pending_tag])
+      sign_in signed_in_user
+    end
 
-      post '/code-review/approve.json', params: { topic_id: commit.topic_id }
-      expect(response.status).to eq(403)
+    context ".redirect" do
+      it "will return 404 if that sha1 doesn't exist" do
+        get '/code-review/redirect/6a5aecee'
+        expect(response.status).to eq(404)
+      end
+
+      context "with a sha1 that exists" do
+        fab!(:topic) { Fabricate(:topic) }
+        before do
+          topic.upsert_custom_fields(DiscourseCodeReview::COMMIT_HASH => '6a5aecee1234')
+        end
+
+        it "will return 404 for a short sha1" do
+          get '/code-review/redirect/6a5aec'
+          expect(response.status).to eq(404)
+        end
+
+        it "will return 302 to the topic if the sha1 or partial sha1 exists" do
+          get '/code-review/redirect/6a5aecee1234'
+          expect(response.status).to redirect_to(topic.url)
+
+          get '/code-review/redirect/6a5aece'
+          expect(response.status).to redirect_to(topic.url)
+        end
+      end
     end
 
-    it 'skips commits from muted categories' do
-      admin2 = Fabricate(:admin)
+    context '.skip' do
+      it "allows users to skip commits" do
+        commit1 = create_post(
+          raw: "this is a fake commit",
+          tags: ["hi", SiteSetting.code_review_pending_tag],
+          user: another_admin
+        )
 
-      muted_category = Fabricate(:category)
+        commit2 = create_post(
+          raw: "this is a fake commit",
+          tags: ["hi", SiteSetting.code_review_pending_tag],
+          user: another_admin
+        )
 
-      CategoryUser.create!(
-        user_id: signed_in_user.id,
-        category_id: muted_category.id,
-        notification_level: CategoryUser.notification_levels[:muted]
-      )
+        commit3 = create_post(
+          raw: "this is a fake commit",
+          tags: ["hi", SiteSetting.code_review_pending_tag],
+          user: another_admin
+        )
 
-      commit = create_post(
-        raw: "this is a fake commit",
-        tags: [SiteSetting.code_review_pending_tag],
-        user: admin2
-      )
+        post '/code-review/skip.json', params: { topic_id: commit3.topic_id }
+        expect(response.status).to eq(200)
 
-      _muted_commit = create_post(
-        raw: "this is a fake commit 2",
-        tags: [SiteSetting.code_review_pending_tag],
-        category: muted_category.id,
-        user: admin2
-      )
+        post '/code-review/skip.json', params: { topic_id: commit2.topic_id }
+        expect(response.status).to eq(200)
 
-      post '/code-review/approve.json', params: { topic_id: commit.topic_id }
-      expect(response.status).to eq(200)
-
-      json = JSON.parse(response.body)
-      expect(json["next_topic_url"]).to eq(nil)
+        json = JSON.parse(response.body)
+        expect(json["next_topic_url"]).to eq(commit1.topic.relative_url)
+      end
     end
 
-    it 'allows you to approve your own commit if enabled' do
+    context '.approve' do
+      it 'doesn\'t allow you to approve your own commit if disabled' do
 
-      SiteSetting.code_review_allow_self_approval = true
+        SiteSetting.code_review_allow_self_approval = false
 
-      another_commit = create_post(
-        raw: "this is an old commit",
-        tags: [SiteSetting.code_review_pending_tag],
-        user: Fabricate(:admin)
-      )
+        commit = create_post(raw: "this is a fake commit", user: signed_in_user, tags: ["hi", SiteSetting.code_review_pending_tag])
 

[... diff too long, it was truncated ...]

GitHub sha: e5b30f23

1 Like