FIX: `UploadRecovery` should look through posts for image markdown

FIX: UploadRecovery should look through posts for image markdown

Downloaded onebox images only included in the cooked HTML content. So we have to check ‘post.cooked’ instead of ‘raw’. bfdd0fe64cc90707569a158b0dbdecedf3d03986

diff --git a/app/models/post.rb b/app/models/post.rb
index b26510c..f2a93c5 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -108,6 +108,13 @@ class Post < ActiveRecord::Base
     end
   }
 
+  scope :have_uploads, -> {
+    where(
+      "(posts.cooked LIKE '%<a %' OR posts.cooked LIKE '%<img %') AND posts.cooked LIKE ?",
+      "%/uploads/#{RailsMultisite::ConnectionManagement.current_db}/%"
+    )
+  }
+
   delegate :username, to: :user
 
   def self.hidden_reasons
diff --git a/lib/tasks/posts.rake b/lib/tasks/posts.rake
index 05757a6..083afc0 100644
--- a/lib/tasks/posts.rake
+++ b/lib/tasks/posts.rake
@@ -391,9 +391,8 @@ end
 desc 'Finds missing post upload records from cooked HTML content'
 task 'posts:missing_uploads' => :environment do
   name = "missing_uploads"
-  db_name = RailsMultisite::ConnectionManagement.current_db
   PostCustomField.where(name: name).destroy_all
-  posts = Post.where("(posts.cooked LIKE '%<a %' OR posts.cooked LIKE '%<img %') AND posts.cooked LIKE '%/uploads/#{db_name}/%'").select(:id, :cooked)
+  posts = Post.have_uploads.select(:id, :cooked)
   count = 0
 
   posts.find_each do |post|
@@ -401,7 +400,7 @@ task 'posts:missing_uploads' => :environment do
 
     Nokogiri::HTML::fragment(post.cooked).css("a/@href", "img/@src").each do |media|
       src = media.value
-      next if src.blank? || (src =~ /\/uploads\/#{db_name}\//).blank?
+      next if src.blank? || (src =~ /\/uploads\/#{RailsMultisite::ConnectionManagement.current_db}\//).blank?
 
       src = "#{SiteSetting.force_https ? "https" : "http"}:#{src}" if src.start_with?("//")
       next unless Discourse.store.has_been_uploaded?(src) || src =~ /\A\/[^\/]/i
diff --git a/lib/upload_recovery.rb b/lib/upload_recovery.rb
index 4e5bec5..eba9849 100644
--- a/lib/upload_recovery.rb
+++ b/lib/upload_recovery.rb
@@ -4,12 +4,7 @@ class UploadRecovery
   end
 
   def recover(posts = Post)
-    posts.where("
-      raw LIKE '%upload:\/\/%'
-      OR raw LIKE '%href=%'
-      OR raw LIKE '%src=%'
-      OR raw LIKE '%[img]%'
-    ").find_each do |post|
+    posts.have_uploads.find_each do |post|
 
       begin
         analyzer = PostAnalyzer.new(post.raw, post.topic_id)
diff --git a/spec/lib/upload_recovery_spec.rb b/spec/lib/upload_recovery_spec.rb
index fca10f5..79eccb2 100644
--- a/spec/lib/upload_recovery_spec.rb
+++ b/spec/lib/upload_recovery_spec.rb
@@ -141,6 +141,33 @@ RSpec.describe UploadRecovery do
       end
     end
 
+    describe 'image markdown' do
+      let(:post) do
+        Fabricate(:post,
+          raw: <<~SQL,
+          ![image](#{upload.url})
+          SQL
+          user: user
+        ).tap(&:link_post_uploads)
+      end
+
+      it 'should recover the upload' do
+        stub_request(:get, "http://test.localhost#{upload.url}")
+          .to_return(status: 200)
+
+        expect do
+          upload.destroy!
+        end.to change { post.reload.uploads.count }.from(1).to(0)
+
+        expect do
+          upload_recovery.recover
+        end.to change { post.reload.uploads.count }.from(0).to(1)
+
+        expect(File.read(Discourse.store.path_for(post.uploads.first)))
+          .to eq(File.read(file_from_fixtures("smallest.png")))
+      end
+    end
+
     describe 'bbcode' do
       let(:post) do
         Fabricate(:post,

GitHub sha: d0fe42e2