Problemas al agregar una prueba unitaria simple para Youtube oneboxing

Hola!

Quiero añadir soporte para enlaces de Youtube /shorts/.

Mi modificación de la clase YoutubeOnebox funciona, pero es necesario que añada una prueba en youtube_onebox.rb y mi prueba no funciona.

Similar a la prueba "puede analizar resultados de incrustaciones de youtube", añadí este código:

it "puede analizar resultados de shorts de youtube" do
  preview = expect(Onebox.preview('https://www.youtube.com/watch?v=wi2jAtpBl0Y').placeholder_html)
  preview.to match(/From which sound/)
  preview.to match(/hqdefault/)
end

También añadí esto al principio del archivo, en before do:

stub_request(:get, "https://www.youtube.com/shorts/wi2jAtpBl0Y").to_return(status: 200, body: onebox_response("youtube-shorts"))

Nunca antes había hecho pruebas unitarias, así que no entiendo muy bien todo esto.

Mi fallo de prueba:

Failures:

  1) Onebox::Engine::YoutubeOnebox puede analizar resultados de shorts de youtube
     Failure/Error:
               http.request(request) do |response|

                 if cookie = response.get_fields('set-cookie')
                   # HACK: Si esto vuelve a fallar en el futuro, usa HTTP::CookieJar del gem 'http-cookie'
                   # Ver prueba: it "no envía cookies al dominio incorrecto"
                   redir_header = { 'Cookie' => cookie.join('; ') }
                 end

                 redir_header = nil unless redir_header.is_a? Hash

     WebMock::NetConnectNotAllowedError:
       Las conexiones HTTP reales están deshabilitadas. Solicitud no registrada: GET https://www.youtube.com/embed/wi2jAtpBl0Y con encabezados {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Discourse Forum Onebox v2.9.0.beta12'}

       Puedes simular esta solicitud con el siguiente fragmento:

       stub_request(:get, "https://www.youtube.com/embed/wi2jAtpBl0Y").
         with(
           headers: {
          'Accept' => '*/*',
          'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
          'User-Agent' => 'Discourse Forum Onebox v2.9.0.beta12'
           }).
         to_return(status: 200, body: "", headers: {})

       solicitudes registradas:

       stub_request(:get, "https://www.youtube.com/shorts/wi2jAtpBl0Y")
       stub_request(:get, "https://www.youtube.com/embed/KCyIfcevExE")
       stub_request(:get, "https://www.youtube.com/playlist?list=PL5308B2E5749D1696")
       stub_request(:get, "http://www.youtube.com/user/googlechrome")
       stub_request(:get, "https://www.youtube.com/channel/UCL8ZULXASCc1I_oaOT0NaOQ")
       stub_request(:get, "https://www.youtube.com/watch?v=21Lk4YiASMo")
       stub_request(:get, "http://www.youtube.com/watch?v=21Lk4YiASMo")
       stub_request(:get, "https://www.youtube.com/embed/21Lk4YiASMo")
       stub_request(:get, "https://youtu.be/21Lk4YiASMo")
       stub_request(:get, "https://www.youtube.com/watch?feature=player_embedded&v=21Lk4YiASMo")

       ============================================================
     # ./lib/onebox/helpers.rb:83:in `block in fetch_response'
     # ./lib/onebox/helpers.rb:69:in `fetch_response'
     # ./lib/onebox/helpers.rb:28:in `fetch_html_doc'
     # ./lib/onebox/engine/youtube_onebox.rb:21:in `parse_embed_response'
     # ./lib/onebox/engine/youtube_onebox.rb:42:in `placeholder_html'
     # ./lib/onebox/preview.rb:28:in `placeholder_html'
     # ./spec/lib/onebox/engine/youtube_onebox_spec.rb:110:in `block (2 levels) in <main>'
     # ./spec/rails_helper.rb:328:in `block (2 levels) in <top (required)>'

Finished in 0.89418 seconds (files took 5.04 seconds to load)
17 examples, 1 failure

Failed examples:

rspec ./spec/lib/onebox/engine/youtube_onebox_spec.rb:109 # Onebox::Engine::YoutubeOnebox puede analizar resultados de shorts de youtube

¿Tienes alguna idea de por qué falla?

Además, ¿qué hacen estas partes en before do?

onebox_response("youtube-embed")

La cadena “youtube-embed” no parece usarse en ningún lugar del código de Discourse excepto aquí. ¿Cuál es su propósito?

¿Por qué hay enlaces /embed/ dos veces y por qué onebox_response tiene un parámetro de cadena diferente?

stub_request(:get, "https://www.youtube.com/embed/21Lk4YiASMo")
.to_return(status: 200, body: onebox_response("youtube"))
stub_request(:get, "https://www.youtube.com/embed/KCyIfcevExE")
.to_return(status: 200, body: onebox_response("youtube-embed"))

Yo tampoco soy muy bueno en esto, pero necesitas que ese stub tenga exactamente lo mismo que devolvería YouTube. Así que necesita tener un subconjunto de lo que devuelve wget https://www.youtube.com/embed/wi2jAtpBl0Y. Esa es la entrada que necesita tu especificación.

wc wi2jAtpBl0Y 
    6   251 65245 wi2jAtpBl0Y

Es mucho texto para darle sentido y ponerlo en tu stub.

¿Puedes abrir un PR de borrador con tus cambios actuales? Será más fácil de seguir y ayudar. Con la información actual, parece que necesitas crear los archivos stub y el stub, y las solicitudes salientes.

¡Claro, aquí está!

Lo arreglé en un nuevo PR que te atribuye correctamente como Coautor:

Para que nuestro conjunto de pruebas no dependa de una conexión a Internet que funcione (y de un Youtube que funcione), simulamos todas las solicitudes de Internet haciendo que esas llamadas devuelvan una respuesta en caché. La función onebox_response llamará al archivo con un nombre coincidente como parámetro pasado desde la carpeta discourse/spec/fixtures/onebox at main · discourse/discourse · GitHub.

Añadí un nuevo archivo .response para shorts para tener una buena prueba, pero eso fue todo lo que fue necesario para esto. ¡Gracias por el PR!

Probando onebox de shorts:

https://youtube.com/shorts/VvoFuaLAslw

Video no disponible
El uploader no ha hecho que este video esté disponible en tu país

Aparte de esto, debería funcionar :smile:

¿Qué pasa con

?

Me funciona.

Pregunta rápida. Aquí está la notificación por correo electrónico que recibí:

La URL aquí es /embed/ y no /shorts/, pero supongo que esto es normal.