FIX: Don’t use `user_generated` images as avatar images in Oneboxed Twitter content (#13712)

FIX: Don’t use user_generated images as avatar images in Oneboxed Twitter content (#13712)

By default, Twitter will return the URL for the avatar image of the tweet poster as the og:image value.

However, if the user_generated attribute is true, we should not use this as the avatar URL as this will be an URL of an image in the tweet itself (e.g., an image belonging to a tweeted news story).

diff --git a/lib/onebox/engine/twitter_status_onebox.rb b/lib/onebox/engine/twitter_status_onebox.rb
index a0f4cb3..a973184 100644
--- a/lib/onebox/engine/twitter_status_onebox.rb
+++ b/lib/onebox/engine/twitter_status_onebox.rb
@@ -23,7 +23,7 @@ module Onebox
         html.css('meta').each do |m|
           if m.attribute('property') && m.attribute('property').to_s.match(/^og:/i)
             m_content = m.attribute('content').to_s.strip
-            m_property = m.attribute('property').to_s.gsub('og:', '')
+            m_property = m.attribute('property').to_s.gsub('og:', '').gsub(':', '_')
             twitter_data[m_property.to_sym] = m_content
           end
         end
@@ -100,7 +100,7 @@ module Onebox
         if twitter_api_credentials_present?
           access(:user, :profile_image_url_https).sub('normal', '400x400')
         elsif twitter_data[:image]
-          twitter_data[:image]
+          twitter_data[:image] unless twitter_data[:image_user_generated]
         end
       end
 
diff --git a/spec/fixtures/onebox/twitterstatus_featured_image.response b/spec/fixtures/onebox/twitterstatus_featured_image.response
new file mode 100644
index 0000000..0f865fe
--- /dev/null
+++ b/spec/fixtures/onebox/twitterstatus_featured_image.response
@@ -0,0 +1,4149 @@
+<!DOCTYPE html>
+<html lang="en" data-scribe-reduced-action-queue="true">
+  <head>
+    
+    
+    
+    
+    
+    
+    
+    <meta charset="utf-8">
+      <script  nonce="PumNFXfgvYvkQzJpN49/1g==">
+        !function(){window.initErrorstack||(window.initErrorstack=[]),window.onerror=function(r,i,n,o,t){r.indexOf("Script error.")>-1||window.initErrorstack.push({errorMsg:r,url:i,lineNumber:n,column:o,errorObj:t})}}();
+      </script>
+    
+    
+  
+  <script id="bouncer_terminate_iframe" nonce="PumNFXfgvYvkQzJpN49/1g==">
+    if (window.top != window) {
+  window.top.postMessage({'bouncer': true, 'event': 'complete'}, '*');
+}
+  </script>
+  <script id="swift_action_queue" nonce="PumNFXfgvYvkQzJpN49/1g==">
+    !function(){function e(e){if(e||(e=window.event),!e)return!1;if(e.timestamp=(new Date).getTime(),!e.target&&e.srcElement&&(e.target=e.srcElement),document.documentElement.getAttribute("data-scribe-reduced-action-queue"))for(var t=e.target;t&&t!=document.body;){if("A"==t.tagName)return;t=t.parentNode}return i("all",o(e)),a(e)?(document.addEventListener||(e=o(e)),e.preventDefault=e.stopPropagation=e.stopImmediatePropagation=function(){},y?(v.push(e),i("captured",e)):i("ignored",e),!1):(i("direct",e),!0)}function t(e){n();for(var t,r=0;t=v[r];r++){var a=e(t.target),i=a.closest("a")[0];if("click"==t.type&&i){var o=e.data(i,"events"),u=o&&o.click,c=!i.hostname.match(g)||!i.href.match(/#$/);if(!u&&c){window.location=i.href;continue}}a.trigger(e.event.fix(t))}window.swiftActionQueue.wasFlushed=!0}function r(){for(var e in b)if("all"!=e)for(var t=b[e],r=0;r<t.length;r++)console.log("actionQueue",c(t[r]))}function n(){clearTimeout(w);for(var e,t=0;e=h[t];t++)document["on"+e]=null}function a(e){if(!e.target)return!1;var t=e.target,r=(t.tagName||"").toLowerCase();if(e.metaKey)return!1;if(e.shiftKey&&"a"==r)return!1;if(t.hostname&&!t.hostname.match(g))return!1;if(e.type.match(p)&&s(t))return!1;if("label"==r){var n=t.getAttribute("for");if(n){var a=document.getElementById(n);if(a&&f(a))return!1}else for(var i,o=0;i=t.childNodes[o];o++)if(f(i))return!1}return!0}function i(e,t){t.bucket=e,b[e].push(t)}function o(e){var t={};for(var r in e)t[r]=e[r];return t}function u(e){for(;e&&e!=document.body;){if("A"==e.tagName)return e;e=e.parentNode}}function c(e){var t=[];e.bucket&&t.push("["+e.bucket+"]"),t.push(e.type);var r,n,a=e.target,i=u(a),o="",c=e.timestamp&&e.timestamp-d;return"click"===e.type&&i?(r=i.className.trim().replace(/\s+/g,"."),n=i.id.trim(),o=/[^#]$/.test(i.href)?" ("+i.href+")":"",a='"'+i.innerText.replace(/\n+/g," ").trim()+'"'):(r=a.className.trim().replace(/\s+/g,"."),n=a.id.trim(),a=a.tagName.toLowerCase(),e.keyCode&&(a=String.fromCharCode(e.keyCode)+" : "+a)),t.push(a+o+(n&&"#"+n)+(!n&&r?"."+r:"")),c&&t.push(c),t.join(" ")}function f(e){var t=(e.tagName||"").toLowerCase();return"input"==t&&"checkbox"==e.getAttribute("type")}function s(e){var t=(e.tagName||"").toLowerCase();return"textarea"==t||"input"==t&&"text"==e.getAttribute("type")||"true"==e.getAttribute("contenteditable")}for(var m,d=(new Date).getTime(),l=1e4,g=/^([^\.]+\.)*twitter\.com$/,p=/^key/,h=["click","keydown","keypress","keyup"],v=[],w=null,y=!0,b={captured:[],ignored:[],direct:[],all:[]},k=0;m=h[k];k++)document["on"+m]=e;w=setTimeout(function(){y=!1},l),window.swiftActionQueue={buckets:b,flush:t,logActions:r,wasFlushed:!1}}();
+  </script>
+  <script id="composition_state" nonce="PumNFXfgvYvkQzJpN49/1g==">
+    !function(){function t(t){t.target.setAttribute("data-in-composition","true")}function n(t){t.target.removeAttribute("data-in-composition")}document.addEventListener&&(document.addEventListener("compositionstart",t,!1),document.addEventListener("compositionend",n,!1))}();
+  </script>
+
+    <link rel="stylesheet" href="https://abs.twimg.com/a/1625696336/css/t1/twitter_core.bundle.css" class="coreCSSBundles">
+  <link rel="stylesheet" class="moreCSSBundles" href="https://abs.twimg.com/a/1625696336/css/t1/twitter_more_1.bundle.css">
+  <link rel="stylesheet" class="moreCSSBundles" href="https://abs.twimg.com/a/1625696336/css/t1/twitter_more_2.bundle.css">
+
+    <link rel="dns-prefetch" href="https://pbs.twimg.com">
+    <link rel="dns-prefetch" href="https://t.co">
+      <link rel="preload" href="https://abs.twimg.com/k/en/init.en.d28d8449d76b990b62bf.js" as="script">
+      <link rel="preload" href="https://abs.twimg.com/k/en/0.commons.en.2d6be4aa18878a5eb7fc.js" as="script">
+      <link rel="preload" href="https://abs.twimg.com/k/en/5.pages_permalink.en.d01701ba3cce1f0d3917.js" as="script">
+
+      <title>Jeff Atwood on Twitter: &quot;My first text message from my child! A moment that shall live on in infamy!… &quot;</title>
+      <meta name="robots" content="NOODP">
+  
+
+
+
+<meta name="msapplication-TileImage" content="//abs.twimg.com/favicons/win8-tile-144.png"/>
+<meta name="msapplication-TileColor" content="#00aced"/>
+
+
+
+<meta name="facebook-domain-verification" content="moho2ug7zs57jijiywrewd8wb5a08h" />
+
+
+
+<link rel="mask-icon" sizes="any" href="https://abs.twimg.com/a/1625696336/icons/favicon.svg" color="#1da1f2">
+
+<link rel="shortcut icon" href="//abs.twimg.com/favicons/favicon.ico" type="image/x-icon">
+<link rel="apple-touch-icon" href="https://abs.twimg.com/icons/apple-touch-icon-192x192.png" sizes="192x192">
+
+<link rel="manifest" href="/manifest.json">
+
+
+  <meta name="swift-page-name" id="swift-page-name" content="permalink">
+  <meta name="swift-page-section" id="swift-section-name" content="permalink">
+
+    <link rel="canonical" href="https://twitter.com/codinghorror/status/1409351083177046020">
+  <link rel="alternate" hreflang="x-default" href="https://twitter.com/codinghorror/status/1409351083177046020">

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

GitHub sha: a64aea38b795d51724512740f4158014fe182eeb

This commit appears in #13712 which was approved by eviltrout and ZogStriP. It was merged by jbrw.