From f92d8c654df654538096efff05e9b1a989d01490 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Wed, 3 Jan 2024 10:08:08 -0500
Subject: [PATCH] Standardize on Thor methods in CLI classes (#28566)

---
 lib/mastodon/cli/federation.rb     | 36 ++++++----------
 lib/mastodon/cli/preview_cards.rb  |  1 -
 spec/lib/mastodon/cli/main_spec.rb | 68 ++++++++++++++++++++++++------
 3 files changed, 70 insertions(+), 35 deletions(-)

diff --git a/lib/mastodon/cli/federation.rb b/lib/mastodon/cli/federation.rb
index 1b4cb467a5..4a4dde3686 100644
--- a/lib/mastodon/cli/federation.rb
+++ b/lib/mastodon/cli/federation.rb
@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-require 'tty-prompt'
-
 module Mastodon::CLI
   module Federation
     extend ActiveSupport::Concern
@@ -30,45 +28,39 @@ module Mastodon::CLI
       LONG_DESC
       def self_destruct
         if SelfDestructHelper.self_destruct?
-          prompt.ok('Self-destruct mode is already enabled for this Mastodon server')
+          say('Self-destruct mode is already enabled for this Mastodon server', :green)
 
           pending_accounts = Account.local.without_suspended.count + Account.local.suspended.joins(:deletion_request).count
           sidekiq_stats = Sidekiq::Stats.new
 
           if pending_accounts.positive?
-            prompt.warn("#{pending_accounts} accounts are still pending deletion.")
+            say("#{pending_accounts} accounts are still pending deletion.", :yellow)
           elsif sidekiq_stats.enqueued.positive?
-            prompt.warn('Deletion notices are still being processed')
+            say('Deletion notices are still being processed', :yellow)
           elsif sidekiq_stats.retry_size.positive?
-            prompt.warn('At least one delivery attempt for each deletion notice has been made, but some have failed and are scheduled for retry')
+            say('At least one delivery attempt for each deletion notice has been made, but some have failed and are scheduled for retry', :yellow)
           else
-            prompt.ok('Every deletion notice has been sent! You can safely delete all data and decomission your servers!')
+            say('Every deletion notice has been sent! You can safely delete all data and decomission your servers!', :green)
           end
 
           exit(0)
         end
 
-        exit(1) unless prompt.ask('Type in the domain of the server to confirm:', required: true) == Rails.configuration.x.local_domain
+        exit(1) unless ask('Type in the domain of the server to confirm:') == Rails.configuration.x.local_domain
 
-        prompt.warn('This operation WILL NOT be reversible.')
-        prompt.warn('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.')
-        prompt.warn('The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).')
+        say('This operation WILL NOT be reversible.', :yellow)
+        say('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.', :yellow)
+        say('The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).', :yellow)
 
-        exit(1) if prompt.no?('Are you sure you want to proceed?')
+        exit(1) if no?('Are you sure you want to proceed?')
 
         self_destruct_value = Rails.application.message_verifier('self-destruct').generate(Rails.configuration.x.local_domain)
-        prompt.ok('To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:')
-        prompt.ok("  SELF_DESTRUCT=#{self_destruct_value}")
-        prompt.ok("\nYou can re-run this command to see the state of the self-destruct process.")
-      rescue TTY::Reader::InputInterrupt
+        say('To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:', :green)
+        say("  SELF_DESTRUCT=#{self_destruct_value}", :green)
+        say("\nYou can re-run this command to see the state of the self-destruct process.", :green)
+      rescue Interrupt
         exit(1)
       end
-
-      private
-
-      def prompt
-        @prompt ||= TTY::Prompt.new
-      end
     end
   end
 end
diff --git a/lib/mastodon/cli/preview_cards.rb b/lib/mastodon/cli/preview_cards.rb
index 2df3d095da..9b20a0cbb8 100644
--- a/lib/mastodon/cli/preview_cards.rb
+++ b/lib/mastodon/cli/preview_cards.rb
@@ -1,6 +1,5 @@
 # frozen_string_literal: true
 
-require 'tty-prompt'
 require_relative 'base'
 
 module Mastodon::CLI
diff --git a/spec/lib/mastodon/cli/main_spec.rb b/spec/lib/mastodon/cli/main_spec.rb
index 931ca57c30..081cd2dd47 100644
--- a/spec/lib/mastodon/cli/main_spec.rb
+++ b/spec/lib/mastodon/cli/main_spec.rb
@@ -100,33 +100,77 @@ describe Mastodon::CLI::Main do
       end
 
       context 'with an incorrect response to hostname' do
-        let(:prompt_double) { instance_double(TTY::Prompt, ask: 'wrong') }
-
         before do
-          allow(TTY::Prompt).to receive(:new).and_return(prompt_double)
+          answer_hostname_incorrectly
         end
 
-        it 'reports failed answer' do
+        it 'exits silently' do
           expect { subject }
             .to raise_error(SystemExit)
         end
       end
 
-      context 'with a correct response to hostname' do
-        # TODO: Update after tty-prompt replace with Thor methods
-        let(:prompt_double) { instance_double(TTY::Prompt, ask: Rails.configuration.x.local_domain, warn: nil, no?: false, ok: nil) }
-
+      context 'with a correct response to hostname but no to proceed' do
         before do
-          allow(TTY::Prompt).to receive(:new).and_return(prompt_double)
+          answer_hostname_correctly
+          decline_proceed
+        end
+
+        it 'passes first step but stops before instructions' do
+          expect { subject }
+            .to output_results('operation WILL NOT')
+            .and raise_error(SystemExit)
+        end
+      end
+
+      context 'with a correct response to hostname and yes to proceed' do
+        before do
+          answer_hostname_correctly
+          accept_proceed
         end
 
         it 'instructs to set the appropriate environment variable' do
           expect { subject }
-            .to_not raise_error
-          # TODO: Update after tty-prompt replace with Thor methods
-          expect(prompt_double).to have_received(:ok).with(/add the following variable/)
+            .to output_results(
+              'operation WILL NOT',
+              'the following variable'
+            )
         end
       end
+
+      private
+
+      def answer_hostname_incorrectly
+        allow(cli.shell)
+          .to receive(:ask)
+          .with('Type in the domain of the server to confirm:')
+          .and_return('wrong.host')
+          .once
+      end
+
+      def answer_hostname_correctly
+        allow(cli.shell)
+          .to receive(:ask)
+          .with('Type in the domain of the server to confirm:')
+          .and_return(Rails.configuration.x.local_domain)
+          .once
+      end
+
+      def decline_proceed
+        allow(cli.shell)
+          .to receive(:no?)
+          .with('Are you sure you want to proceed?')
+          .and_return(true)
+          .once
+      end
+
+      def accept_proceed
+        allow(cli.shell)
+          .to receive(:no?)
+          .with('Are you sure you want to proceed?')
+          .and_return(false)
+          .once
+      end
     end
   end
 end