From 7a223331d1bffc0405dd5d345721c5721d08142e Mon Sep 17 00:00:00 2001
From: Johannes Faigle <jo-f@gmx.at>
Date: Wed, 1 Jun 2022 14:54:23 +0200
Subject: [PATCH] FIX: Show suspended by user (#16927)

- Show "suspended by" user
- Add specs for silence user
---
 app/controllers/admin/users_controller.rb     |  3 +-
 spec/requests/admin/users_controller_spec.rb  |  2 +
 .../schemas/json/user_silence_request.json    | 20 +++++++
 .../schemas/json/user_silence_response.json   | 52 +++++++++++++++++++
 .../schemas/json/user_suspend_response.json   | 22 +++++++-
 spec/requests/api/users_spec.rb               | 27 ++++++++++
 6 files changed, 124 insertions(+), 2 deletions(-)
 create mode 100644 spec/requests/api/schemas/json/user_silence_request.json
 create mode 100644 spec/requests/api/schemas/json/user_silence_response.json

diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 04b1dcceb44..9586f0ef6f7 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -150,7 +150,8 @@ class Admin::UsersController < Admin::AdminController
         suspend_reason: params[:reason],
         full_suspend_reason: user_history.try(:details),
         suspended_till: @user.suspended_till,
-        suspended_at: @user.suspended_at
+        suspended_at: @user.suspended_at,
+        suspended_by: BasicUserSerializer.new(current_user, root: false).as_json
       }
     )
   end
diff --git a/spec/requests/admin/users_controller_spec.rb b/spec/requests/admin/users_controller_spec.rb
index d5f467d6915..dd110d41085 100644
--- a/spec/requests/admin/users_controller_spec.rb
+++ b/spec/requests/admin/users_controller_spec.rb
@@ -162,6 +162,7 @@ RSpec.describe Admin::UsersController do
       expect(user).to be_suspended
       expect(user.suspended_at).to be_present
       expect(user.suspended_till).to be_present
+      expect(user.suspend_record).to be_present
 
       log = UserHistory.where(target_user_id: user.id).order('id desc').first
       expect(log.details).to match(/because I said so/)
@@ -896,6 +897,7 @@ RSpec.describe Admin::UsersController do
       expect(response.status).to eq(200)
       reg_user.reload
       expect(reg_user).to be_silenced
+      expect(reg_user.silenced_record).to be_present
     end
 
     it "can have an associated post" do
diff --git a/spec/requests/api/schemas/json/user_silence_request.json b/spec/requests/api/schemas/json/user_silence_request.json
new file mode 100644
index 00000000000..a751c640089
--- /dev/null
+++ b/spec/requests/api/schemas/json/user_silence_request.json
@@ -0,0 +1,20 @@
+{
+  "additionalProperties": false,
+  "properties": {
+    "silenced_till": {
+      "type": "string",
+      "example": "2022-06-01T08:00:00.000Z"
+    },
+    "reason": {
+      "type": "string"
+    },
+    "message": {
+      "type": "string",
+      "description": "Will send an email with this message when present"
+    },
+    "post_action": {
+      "type": "string",
+      "example": "delete"
+    }
+  }
+}
diff --git a/spec/requests/api/schemas/json/user_silence_response.json b/spec/requests/api/schemas/json/user_silence_response.json
new file mode 100644
index 00000000000..13ae10ab6f8
--- /dev/null
+++ b/spec/requests/api/schemas/json/user_silence_response.json
@@ -0,0 +1,52 @@
+{
+  "additionalProperties": false,
+  "properties": {
+    "silence": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "silenced": {
+          "type": "boolean"
+        },
+        "silence_reason": {
+          "type": "string"
+        },
+        "silenced_till": {
+          "type": "string"
+        },
+        "silenced_at": {
+          "type": "string"
+        },
+        "silenced_by": {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "id": {
+              "type": "integer"
+            },
+            "username": {
+              "type": "string"
+            },
+            "name": {
+              "type": "string"
+            },
+            "avatar_template": {
+              "type": "string"
+            }
+          },
+          "required": ["id", "username", "name", "avatar_template"]
+        }
+      },
+      "required": [
+        "silenced",
+        "silence_reason",
+        "silenced_till",
+        "silenced_at",
+        "silenced_by"
+      ]
+    }
+  },
+  "required": [
+    "silence"
+  ]
+}
diff --git a/spec/requests/api/schemas/json/user_suspend_response.json b/spec/requests/api/schemas/json/user_suspend_response.json
index d6d091283be..f2bf59b8f56 100644
--- a/spec/requests/api/schemas/json/user_suspend_response.json
+++ b/spec/requests/api/schemas/json/user_suspend_response.json
@@ -16,13 +16,33 @@
         },
         "suspended_at": {
           "type": "string"
+        },
+        "suspended_by": {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "id": {
+              "type": "integer"
+            },
+            "username": {
+              "type": "string"
+            },
+            "name": {
+              "type": "string"
+            },
+            "avatar_template": {
+              "type": "string"
+            }
+          },
+          "required": ["id", "username", "name", "avatar_template"]
         }
       },
       "required": [
         "suspend_reason",
         "full_suspend_reason",
         "suspended_till",
-        "suspended_at"
+        "suspended_at",
+        "suspended_by"
       ]
     }
   },
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 4353b1364d8..229ec5935e3 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -400,6 +400,33 @@ describe 'users' do
     end
   end
 
+  path '/admin/users/{id}/silence.json' do
+    put 'Silence a user' do
+      tags 'Users', 'Admin'
+      operationId 'silenceUser'
+      consumes 'application/json'
+      expected_request_schema = load_spec_schema('user_silence_request')
+
+      parameter name: :id, in: :path, type: :integer, required: true
+      parameter name: :params, in: :body, schema: expected_request_schema
+
+      produces 'application/json'
+      response '200', 'response' do
+
+        let(:id) { Fabricate(:user).id }
+        let(:params) {}
+
+        expected_response_schema = load_spec_schema('user_silence_response')
+        schema(expected_response_schema)
+
+        it_behaves_like "a JSON endpoint", 200 do
+          let(:expected_response_schema) { expected_response_schema }
+          let(:expected_request_schema) { expected_request_schema }
+        end
+      end
+    end
+  end
+
   path '/admin/users/{id}/anonymize.json' do
     put 'Anonymize a user' do
       tags 'Users', 'Admin'