Browse Source

Maintenance: Port UserAgent minitest to RSpec.

Florian Liebe 2 years ago
parent
commit
ffc755c7dc

+ 0 - 4
.gitlab/ci/test/integration/other.yml

@@ -12,7 +12,3 @@
     - bundle exec rails test test/integration/clearbit_test.rb
     - echo "Slack test..."
     - bundle exec rails test test/integration/slack_test.rb
-    - echo "UserAgent tests..."
-    - bundle exec rails test test/integration/user_agent_test.rb
-    - export ZAMMAD_PROXY_TEST=true
-    - bundle exec rails test test/integration/user_agent_test.rb

+ 542 - 0
spec/lib/user_agent_spec.rb

@@ -0,0 +1,542 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+require 'rails_helper'
+
+# rubocop:disable RSpec/MultipleExpectations
+# this cop is disabled to speed up testing by avoiding the overhead of multiple requests
+
+RSpec.describe UserAgent, integration: true, use_vcr: true do
+  include ZammadSpecSupportRequest
+
+  let(:has_proxy) { false }
+
+  shared_context 'when doing user agent tests' do
+    let(:host) { 'https://web-test.dc.zammad.com' }
+
+    shared_examples 'successful request' do
+      it 'returns a response' do
+        expect(response).to be_success
+        expect(response.code).to eq(code)
+      end
+    end
+
+    shared_examples 'successful request with json body' do
+      it 'returns a response' do # rubocop:disable RSpec/ExampleLength
+        expect(response).to be_success
+        expect(response.code).to eq(code)
+
+        if has_proxy
+          expect(json_response).to include(expected_body)
+            .and include(
+              'remote_ip' => ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK'],
+            )
+        else
+          expect(json_response).to include(expected_body)
+        end
+      end
+    end
+
+    shared_examples 'successful get request' do
+      it 'returns a response' do
+        expect(response).to be_success
+        expect(response.code).to eq(code)
+        expect(response.header).to include('content-type' => content_type)
+        expect(json_response).to include(expected_body)
+      end
+    end
+
+    shared_examples 'successful post/put request' do
+      include_examples 'successful request with json body'
+    end
+
+    shared_examples 'successful delete request' do
+      include_examples 'successful request with json body'
+    end
+
+    shared_examples 'successful redirect request' do
+      include_examples 'successful request with json body'
+    end
+
+    shared_examples 'unsuccessful request' do
+      it 'returns a response' do
+        expect(response).not_to be_success
+        expect(response.code).to eq(code)
+      end
+    end
+
+    shared_examples 'unsuccessful request without body' do
+      it 'returns a response' do
+        expect(response).not_to be_success
+        expect(response.code).to eq(code)
+        expect(response.body).to be_nil
+      end
+    end
+
+    shared_examples 'unsuccessful get/post/put/delete request' do
+      it 'returns a response' do
+        expect(response).not_to be_success
+        expect(response.code).to eq(code)
+        expect(response.body).to eq(expected_body)
+      end
+    end
+
+    shared_examples 'ftp requests' do
+      it 'returns a response' do
+        expect(response).to be_success
+        expect(response.code).to eq(code)
+        expect(response.body).to match(expected_body)
+      end
+    end
+
+    describe '#get' do
+      context 'without http basic auth' do
+        subject(:response) { described_class.get(request_url) }
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:content_type)  { 'application/json; charset=utf-8' }
+          let(:request_url)   { "#{host}/test/get/1?submitted=123" }
+          let(:expected_body) do
+            {
+              'method'                 => 'get',
+              'submitted'              => '123',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful get request'
+        end
+
+        context 'with code 202' do
+          let(:code)         { '202' }
+          let(:content_type) { 'application/json; charset=utf-8' }
+          let(:request_url)  { "#{host}/test/get_accepted/1?submitted=123" }
+          let(:expected_body) do
+            {
+              'method'                 => 'get',
+              'submitted'              => '123',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful get request'
+        end
+
+        context 'with code 404' do
+          let(:code)        { '404' }
+          let(:request_url) { "#{host}/test/not_existing" }
+
+          include_examples 'unsuccessful request'
+        end
+      end
+
+      context 'with http basic auth' do
+        subject(:response) do
+          described_class.get(request_url, {}, {
+                                user:     'basic_auth_user',
+                                password: password,
+                              })
+        end
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:content_type)  { 'application/json; charset=utf-8' }
+          let(:request_url)   { "#{host}/test_basic_auth/get/1?submitted=123" }
+          let(:password)      { 'test123' }
+          let(:expected_body) do
+            {
+              'method'                 => 'get',
+              'submitted'              => '123',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful get request'
+        end
+
+        context 'with code 401' do
+          let(:code)          { '401' }
+          let(:request_url)   { "#{host}/test_basic_auth/get/1?submitted=123" }
+          let(:password)      { 'test<>123' }
+          let(:expected_body) { "HTTP Basic: Access denied.\n" }
+
+          include_examples 'unsuccessful get/post/put/delete request'
+        end
+      end
+
+      context 'when timeouts are raised' do
+        subject(:response) do
+          described_class.get(request_url, {}, {
+                                open_timeout: 0.25,
+                                read_timeout: 0.25,
+                              })
+        end
+
+        let(:request_url) { "#{host}/test/get/3?submitted=123" }
+        let(:code)        { 0 }
+
+        include_examples 'unsuccessful request without body'
+      end
+
+      context 'with content type set to json' do
+        subject(:response) { described_class.get(request_url, request_params, request_options) }
+
+        context 'with code 200' do
+          let(:code)            { '200' }
+          let(:content_type)    { 'application/json; charset=utf-8' }
+          let(:request_url)     { "#{host}/test/get/1" }
+          let(:request_params)  { { submitted: { key: 'some value' } } }
+          let(:request_options) { { json: true } }
+          let(:expected_body) do
+            {
+              'method'                 => 'get',
+              'content_type_requested' => 'application/json',
+              'submitted'              => {
+                'key' => 'some value',
+              },
+            }
+          end
+
+          include_examples 'successful get request'
+        end
+
+        context 'with code 404' do
+          let(:code)            { '404' }
+          let(:request_url)     { "#{host}/test/not_existing" }
+          let(:request_params)  { { submitted: { key: 'some value' } } }
+          let(:request_options) { { json: true } }
+
+          include_examples 'unsuccessful request'
+        end
+      end
+    end
+
+    describe '#post' do
+      context 'without http basic auth' do
+        subject(:response) { described_class.post(request_url, request_params) }
+
+        context 'with code 201' do
+          let(:code)           { '201' }
+          let(:request_url)    { "#{host}/test/post/1" }
+          let(:request_params) { { submitted: 'some value' } }
+          let(:expected_body) do
+            {
+              'method'                 => 'post',
+              'submitted'              => 'some value',
+              'content_type_requested' => 'application/x-www-form-urlencoded',
+            }
+          end
+
+          include_examples 'successful post/put request'
+        end
+
+        context 'with code 404' do
+          let(:code)           { '404' }
+          let(:request_url)    { "#{host}/test/not_existing" }
+          let(:request_params) { { submitted: 'some value' } }
+
+          include_examples 'unsuccessful request without body'
+        end
+      end
+
+      context 'with http basic auth' do
+        subject(:response) do
+          described_class.post(request_url, request_params, {
+                                 user:     'basic_auth_user',
+                                 password: password,
+                               })
+        end
+
+        context 'with code 201' do
+          let(:code)           { '201' }
+          let(:request_url)    { "#{host}/test_basic_auth/post/1" }
+          let(:request_params) { { submitted: 'some value' } }
+          let(:password)       { 'test123' }
+          let(:expected_body) do
+            {
+              'method'                 => 'post',
+              'submitted'              => 'some value',
+              'content_type_requested' => 'application/x-www-form-urlencoded',
+            }
+          end
+
+          include_examples 'successful post/put request'
+        end
+
+        context 'with code 401' do
+          let(:code)           { '401' }
+          let(:request_url)    { "#{host}/test_basic_auth/post/1" }
+          let(:request_params) { { submitted: 'some value' } }
+          let(:password)       { 'test<>123' }
+          let(:expected_body)  { "HTTP Basic: Access denied.\n" }
+
+          include_examples 'unsuccessful get/post/put/delete request'
+        end
+      end
+
+      context 'when timeouts are raised' do
+        subject(:response) do
+          described_class.post(request_url, request_params, {
+                                 open_timeout: 0.25,
+                                 read_timeout: 0.25,
+                               })
+        end
+
+        let(:request_url) { "#{host}/test/post/3" }
+        let(:request_params) { { submitted: 'timeout' } }
+        let(:code)           { 0 }
+
+        include_examples 'unsuccessful request without body'
+      end
+
+      context 'with content type set to json' do
+        subject(:response) { described_class.post(request_url, request_params, request_options) }
+
+        context 'with code 201' do
+          let(:code)            { '201' }
+          let(:content_type)    { 'application/json; charset=utf-8' }
+          let(:request_url)     { "#{host}/test/post/1" }
+          let(:request_params)  { { submitted: { key: 'some value' } } }
+          let(:request_options) { { json: true } }
+          let(:expected_body) do
+            {
+              'method'                 => 'post',
+              'content_type_requested' => 'application/json',
+              'submitted'              => {
+                'key' => 'some value',
+              },
+            }
+          end
+
+          include_examples 'successful post/put request'
+        end
+      end
+    end
+
+    describe '#put' do
+      subject(:response) { described_class.put(request_url, request_params) }
+
+      context 'without http basic auth' do
+        context 'with code 200' do
+          let(:code)           { '200' }
+          let(:request_url)    { "#{host}/test/put/1" }
+          let(:request_params) { { submitted: 'some value' } }
+
+          let(:expected_body) do
+            {
+              'method'                 => 'put',
+              'submitted'              => 'some value',
+              'content_type_requested' => 'application/x-www-form-urlencoded',
+            }
+          end
+
+          include_examples 'successful post/put request'
+        end
+
+        context 'with code 404' do
+          let(:code)           { '404' }
+          let(:request_url)    { "#{host}/test/not_existing" }
+          let(:request_params) { { submitted: 'some value' } }
+
+          include_examples 'unsuccessful request without body'
+        end
+      end
+
+      context 'with http basic auth' do
+        subject(:response) do
+          described_class.put(request_url, request_params, {
+                                user:     'basic_auth_user',
+                                password: password,
+                              })
+        end
+
+        let(:password)     { 'test123' }
+        let(:submit_value) { 'some value' }
+
+        context 'with code 200' do
+          let(:code)           { '200' }
+          let(:request_url)    { "#{host}/test_basic_auth/put/1" }
+          let(:request_params) { { submitted: 'some value' } }
+          let(:expected_body) do
+            {
+              'method'                 => 'put',
+              'submitted'              => 'some value',
+              'content_type_requested' => 'application/x-www-form-urlencoded',
+            }
+          end
+
+          include_examples 'successful post/put request'
+        end
+
+        context 'with code 401' do
+          let(:code)           { '401' }
+          let(:request_url)    { "#{host}/test_basic_auth/put/1" }
+          let(:request_params) { { submitted: 'some value' } }
+          let(:password)       { 'test<>123' }
+          let(:expected_body)  { "HTTP Basic: Access denied.\n" }
+
+          include_examples 'unsuccessful get/post/put/delete request'
+        end
+      end
+    end
+
+    describe '#delete' do
+      context 'without http basic auth' do
+        subject(:response) { described_class.delete(request_url) }
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:request_url)   { "#{host}/test/delete/1" }
+          let(:expected_body) do
+            {
+              'method'                 => 'delete',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful delete request'
+        end
+
+        context 'with code 404' do
+          let(:code)        { '404' }
+          let(:request_url) { "#{host}/test/not_existing" }
+
+          include_examples 'unsuccessful request without body'
+        end
+      end
+
+      context 'with http basic auth' do
+        subject(:response) do
+          described_class.delete(request_url, {}, {
+                                   user:     'basic_auth_user',
+                                   password: password,
+                                 })
+        end
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:content_type)  { 'application/json; charset=utf-8' }
+          let(:request_url)   { "#{host}/test_basic_auth/delete/1" }
+          let(:password)      { 'test123' }
+          let(:expected_body) do
+            {
+              'method'                 => 'delete',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful delete request'
+        end
+
+        context 'with code 401' do
+          let(:code)          { '401' }
+          let(:request_url)   { "#{host}/test_basic_auth/delete/1" }
+          let(:password)      { 'test<>123' }
+          let(:expected_body) { "HTTP Basic: Access denied.\n" }
+
+          include_examples 'unsuccessful get/post/put/delete request'
+        end
+      end
+    end
+
+    describe '#request' do
+      context 'without http basic auth' do
+        subject(:response) { described_class.request(request_url) }
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:content_type)  { 'application/json; charset=utf-8' }
+          let(:request_url)   { "#{host}/test/redirect" }
+          let(:expected_body) do
+            {
+              'method'                 => 'get',
+              'submitted'              => 'abc',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful redirect request'
+        end
+      end
+
+      context 'with http basic auth' do
+        subject(:response) do
+          described_class.request(request_url, {
+                                    user:     'basic_auth_user',
+                                    password: password,
+                                  })
+        end
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:request_url)   { "#{host}/test_basic_auth/redirect" }
+          let(:password)      { 'test123' }
+          let(:expected_body) do
+            {
+              'method'                 => 'get',
+              'submitted'              => 'abc',
+              'content_type_requested' => nil,
+            }
+          end
+
+          include_examples 'successful redirect request'
+        end
+
+        context 'with code 401' do
+          let(:code)          { '401' }
+          let(:request_url)   { "#{host}/test_basic_auth/redirect" }
+          let(:password)      { 'test<>123' }
+          let(:expected_body) { "HTTP Basic: Access denied.\n" }
+
+          include_examples 'unsuccessful get/post/put/delete request'
+        end
+      end
+
+      context 'when ftp' do
+        subject(:response) do
+          described_class.request(request_url)
+        end
+
+        context 'with code 200' do
+          let(:code)          { '200' }
+          let(:request_url)   { 'ftp://ftp.gwdg.de/pub/rfc/rfc-index.txt' }
+          let(:expected_body) { %r{instructions}i }
+
+          include_examples 'ftp requests'
+        end
+
+        context 'with code 550' do
+          let(:code)          { '550' }
+          let(:request_url)   { 'ftp://ftp.gwdg.de/pub/rfc/not_existing.txt' }
+
+          include_examples 'unsuccessful request without body'
+        end
+
+        context 'with a not existing URL' do
+          let(:code)          { 0 }
+          let(:request_url)   { 'http://not.existing.host.tld/test.php' }
+
+          include_examples 'unsuccessful request without body'
+        end
+      end
+    end
+  end
+
+  describe 'testing without proxy' do
+    include_context 'when doing user agent tests'
+  end
+
+  describe 'testing with proxy', required_envs: %w[ZAMMAD_PROXY ZAMMAD_PROXY_USERNAME ZAMMAD_PROXY_PASSWORD ZAMMAD_PROXY_REMOTE_IP_CHECK] do
+    let(:has_proxy) { true }
+
+    before do
+      Setting.set('proxy', ENV['ZAMMAD_PROXY'])
+      Setting.set('proxy_username', ENV['ZAMMAD_PROXY_USERNAME'])
+      Setting.set('proxy_password', ENV['ZAMMAD_PROXY_PASSWORD'])
+    end
+
+    include_context 'when doing user agent tests'
+  end
+end
+
+# rubocop:enable RSpec/MultipleExpectations

+ 4 - 2
spec/support/vcr.rb

@@ -4,6 +4,7 @@ require 'vcr'
 
 VCR_IGNORE_MATCHING_HOSTS = %w[elasticsearch selenium zammad.org zammad.com znuny.com google.com login.microsoftonline.com github.com].freeze
 VCR_IGNORE_MATCHING_REGEXPS = [%r{^192\.168\.\d+\.\d+$}].freeze
+VCR_MATCHING_HOSTS_WHITELIST = %w[web-test.dc.zammad.com].freeze
 
 VCR.configure do |config|
   config.cassette_library_dir = 'test/data/vcr_cassettes'
@@ -13,8 +14,9 @@ VCR.configure do |config|
   config.ignore_request do |request|
     uri = URI(request.uri)
 
-    next true if VCR_IGNORE_MATCHING_HOSTS.any?   { |elem| uri.host.include? elem }
-    next true if VCR_IGNORE_MATCHING_REGEXPS.any? { |elem| uri.host.match? elem }
+    next false if VCR_MATCHING_HOSTS_WHITELIST.any? { |elem| uri.host.include?(elem) }
+    next true if VCR_IGNORE_MATCHING_HOSTS.any?     { |elem| uri.host.include? elem }
+    next true if VCR_IGNORE_MATCHING_REGEXPS.any?   { |elem| uri.host.match? elem }
   end
 
   config.register_request_matcher(:oauth_headers) do |r1, r2|

+ 63 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_delete_with_http_basic_auth_with_code_200_returns_a_response.yml

@@ -0,0 +1,63 @@
+---
+http_interactions:
+- request:
+    method: delete
+    uri: https://web-test.dc.zammad.com/test_basic_auth/delete/1
+    body:
+      encoding: US-ASCII
+      string: ''
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+      Authorization:
+      - Basic YmFzaWNfYXV0aF91c2VyOnRlc3QxMjM=
+  response:
+    status:
+      code: 200
+      message: OK
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:42 GMT
+      Content-Type:
+      - application/json; charset=utf-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Frame-Options:
+      - DENY
+      - SAMEORIGIN
+      X-Xss-Protection:
+      - 1; mode=block
+      X-Content-Type-Options:
+      - nosniff
+      - nosniff
+      X-Download-Options:
+      - noopen
+      X-Permitted-Cross-Domain-Policies:
+      - none
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Etag:
+      - W/"c371fbc4501157a24013c6404893c28d"
+      Cache-Control:
+      - max-age=0, private, must-revalidate
+      X-Request-Id:
+      - 24324644-d54f-41e8-b588-202bbb969519
+      X-Runtime:
+      - '1.001533'
+      Strict-Transport-Security:
+      - max-age=63072000
+    body:
+      encoding: ASCII-8BIT
+      string: '{"remote_ip":"<ZAMMAD_PROXY_REMOTE_IP_CHECK>","content_type_requested":null,"method":"delete","submitted":null}'
+  recorded_at: Tue, 05 Jul 2022 08:53:42 GMT
+recorded_with: VCR 6.1.0

+ 61 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_delete_with_http_basic_auth_with_code_401_returns_a_response.yml

@@ -0,0 +1,61 @@
+---
+http_interactions:
+- request:
+    method: delete
+    uri: https://web-test.dc.zammad.com/test_basic_auth/delete/1
+    body:
+      encoding: US-ASCII
+      string: ''
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+      Authorization:
+      - Basic YmFzaWNfYXV0aF91c2VyOnRlc3Q8PjEyMw==
+  response:
+    status:
+      code: 401
+      message: Unauthorized
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:42 GMT
+      Content-Type:
+      - text/html; charset=utf-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Xss-Protection:
+      - 1; mode=block
+      X-Content-Type-Options:
+      - nosniff
+      X-Download-Options:
+      - noopen
+      X-Permitted-Cross-Domain-Policies:
+      - none
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Www-Authenticate:
+      - Basic realm="Application"
+      Cache-Control:
+      - no-cache
+      X-Request-Id:
+      - fb639518-4f4f-4ab5-9554-c04f4e5031a3
+      X-Runtime:
+      - '0.001002'
+    body:
+      encoding: UTF-8
+      string: 'HTTP Basic: Access denied.
+
+        '
+  recorded_at: Tue, 05 Jul 2022 08:53:42 GMT
+recorded_with: VCR 6.1.0

+ 61 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_delete_without_http_basic_auth_with_code_200_returns_a_response.yml

@@ -0,0 +1,61 @@
+---
+http_interactions:
+- request:
+    method: delete
+    uri: https://web-test.dc.zammad.com/test/delete/1
+    body:
+      encoding: US-ASCII
+      string: ''
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+  response:
+    status:
+      code: 200
+      message: OK
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:41 GMT
+      Content-Type:
+      - application/json; charset=utf-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Frame-Options:
+      - DENY
+      - SAMEORIGIN
+      X-Xss-Protection:
+      - 1; mode=block
+      X-Content-Type-Options:
+      - nosniff
+      - nosniff
+      X-Download-Options:
+      - noopen
+      X-Permitted-Cross-Domain-Policies:
+      - none
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Etag:
+      - W/"c371fbc4501157a24013c6404893c28d"
+      Cache-Control:
+      - max-age=0, private, must-revalidate
+      X-Request-Id:
+      - 97ec0646-2dad-4e05-83e3-d7670af6d2db
+      X-Runtime:
+      - '1.001441'
+      Strict-Transport-Security:
+      - max-age=63072000
+    body:
+      encoding: ASCII-8BIT
+      string: '{"remote_ip":"<ZAMMAD_PROXY_REMOTE_IP_CHECK>","content_type_requested":null,"method":"delete","submitted":null}'
+  recorded_at: Tue, 05 Jul 2022 08:53:40 GMT
+recorded_with: VCR 6.1.0

+ 108 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_delete_without_http_basic_auth_with_code_404_returns_a_response.yml

@@ -0,0 +1,108 @@
+---
+http_interactions:
+- request:
+    method: delete
+    uri: https://web-test.dc.zammad.com/test/not_existing
+    body:
+      encoding: US-ASCII
+      string: ''
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+  response:
+    status:
+      code: 404
+      message: Not Found
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:41 GMT
+      Content-Type:
+      - text/html; charset=UTF-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Request-Id:
+      - cdd6d9f7-2447-4208-842c-70965aaf00c1
+      X-Runtime:
+      - '0.000643'
+    body:
+      encoding: ASCII-8BIT
+      string: |
+        <!DOCTYPE html>
+        <html>
+        <head>
+          <title>The page you were looking for doesn't exist (404)</title>
+          <meta name="viewport" content="width=device-width,initial-scale=1">
+          <style>
+          .rails-default-error-page {
+            background-color: #EFEFEF;
+            color: #2E2F30;
+            text-align: center;
+            font-family: arial, sans-serif;
+            margin: 0;
+          }
+
+          .rails-default-error-page div.dialog {
+            width: 95%;
+            max-width: 33em;
+            margin: 4em auto 0;
+          }
+
+          .rails-default-error-page div.dialog > div {
+            border: 1px solid #CCC;
+            border-right-color: #999;
+            border-left-color: #999;
+            border-bottom-color: #BBB;
+            border-top: #B00100 solid 4px;
+            border-top-left-radius: 9px;
+            border-top-right-radius: 9px;
+            background-color: white;
+            padding: 7px 12% 0;
+            box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+          }
+
+          .rails-default-error-page h1 {
+            font-size: 100%;
+            color: #730E15;
+            line-height: 1.5em;
+          }
+
+          .rails-default-error-page div.dialog > p {
+            margin: 0 0 1em;
+            padding: 1em;
+            background-color: #F7F7F7;
+            border: 1px solid #CCC;
+            border-right-color: #999;
+            border-left-color: #999;
+            border-bottom-color: #999;
+            border-bottom-left-radius: 4px;
+            border-bottom-right-radius: 4px;
+            border-top-color: #DADADA;
+            color: #666;
+            box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+          }
+          </style>
+        </head>
+
+        <body class="rails-default-error-page">
+          <!-- This file lives in public/404.html -->
+          <div class="dialog">
+            <div>
+              <h1>The page you were looking for doesn't exist.</h1>
+              <p>You may have mistyped the address or the page may have moved.</p>
+            </div>
+            <p>If you are the application owner check the logs for more information.</p>
+          </div>
+        </body>
+        </html>
+  recorded_at: Tue, 05 Jul 2022 08:53:41 GMT
+recorded_with: VCR 6.1.0

+ 64 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_get_with_content_type_set_to_json_with_code_200_returns_a_response.yml

@@ -0,0 +1,64 @@
+---
+http_interactions:
+- request:
+    method: get
+    uri: https://web-test.dc.zammad.com/test/get/1
+    body:
+      encoding: UTF-8
+      string: '{"submitted":{"key":"some value"}}'
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+      Content-Type:
+      - application/json
+  response:
+    status:
+      code: 200
+      message: OK
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:30 GMT
+      Content-Type:
+      - application/json; charset=utf-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Frame-Options:
+      - DENY
+      - SAMEORIGIN
+      X-Xss-Protection:
+      - 1; mode=block
+      X-Content-Type-Options:
+      - nosniff
+      - nosniff
+      X-Download-Options:
+      - noopen
+      X-Permitted-Cross-Domain-Policies:
+      - none
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Etag:
+      - W/"22c6aa00a1bf42bd731adc0edcefa610"
+      Cache-Control:
+      - max-age=0, private, must-revalidate
+      X-Request-Id:
+      - b1cbe761-54b8-43e7-8bab-5f6b4e2eccef
+      X-Runtime:
+      - '1.001454'
+      Strict-Transport-Security:
+      - max-age=63072000
+    body:
+      encoding: ASCII-8BIT
+      string: '{"remote_ip":"<ZAMMAD_PROXY_REMOTE_IP_CHECK>","content_type_requested":"application/json","method":"get","submitted":{"key":"some
+        value"}}'
+  recorded_at: Tue, 05 Jul 2022 08:53:30 GMT
+recorded_with: VCR 6.1.0

+ 110 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_get_with_content_type_set_to_json_with_code_404_returns_a_response.yml

@@ -0,0 +1,110 @@
+---
+http_interactions:
+- request:
+    method: get
+    uri: https://web-test.dc.zammad.com/test/not_existing
+    body:
+      encoding: UTF-8
+      string: '{"submitted":{"key":"some value"}}'
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+      Content-Type:
+      - application/json
+  response:
+    status:
+      code: 404
+      message: Not Found
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:31 GMT
+      Content-Type:
+      - text/html; charset=UTF-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Request-Id:
+      - f50b959a-93f8-406a-8f46-b6e9eb0e2d3d
+      X-Runtime:
+      - '0.000654'
+    body:
+      encoding: ASCII-8BIT
+      string: |
+        <!DOCTYPE html>
+        <html>
+        <head>
+          <title>The page you were looking for doesn't exist (404)</title>
+          <meta name="viewport" content="width=device-width,initial-scale=1">
+          <style>
+          .rails-default-error-page {
+            background-color: #EFEFEF;
+            color: #2E2F30;
+            text-align: center;
+            font-family: arial, sans-serif;
+            margin: 0;
+          }
+
+          .rails-default-error-page div.dialog {
+            width: 95%;
+            max-width: 33em;
+            margin: 4em auto 0;
+          }
+
+          .rails-default-error-page div.dialog > div {
+            border: 1px solid #CCC;
+            border-right-color: #999;
+            border-left-color: #999;
+            border-bottom-color: #BBB;
+            border-top: #B00100 solid 4px;
+            border-top-left-radius: 9px;
+            border-top-right-radius: 9px;
+            background-color: white;
+            padding: 7px 12% 0;
+            box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+          }
+
+          .rails-default-error-page h1 {
+            font-size: 100%;
+            color: #730E15;
+            line-height: 1.5em;
+          }
+
+          .rails-default-error-page div.dialog > p {
+            margin: 0 0 1em;
+            padding: 1em;
+            background-color: #F7F7F7;
+            border: 1px solid #CCC;
+            border-right-color: #999;
+            border-left-color: #999;
+            border-bottom-color: #999;
+            border-bottom-left-radius: 4px;
+            border-bottom-right-radius: 4px;
+            border-top-color: #DADADA;
+            color: #666;
+            box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
+          }
+          </style>
+        </head>
+
+        <body class="rails-default-error-page">
+          <!-- This file lives in public/404.html -->
+          <div class="dialog">
+            <div>
+              <h1>The page you were looking for doesn't exist.</h1>
+              <p>You may have mistyped the address or the page may have moved.</p>
+            </div>
+            <p>If you are the application owner check the logs for more information.</p>
+          </div>
+        </body>
+        </html>
+  recorded_at: Tue, 05 Jul 2022 08:53:31 GMT
+recorded_with: VCR 6.1.0

+ 63 - 0
test/data/vcr_cassettes/lib/user_agent/useragent_testing_with_proxy_get_with_http_basic_auth_with_code_200_returns_a_response.yml

@@ -0,0 +1,63 @@
+---
+http_interactions:
+- request:
+    method: get
+    uri: https://web-test.dc.zammad.com/test_basic_auth/get/1?submitted=123
+    body:
+      encoding: US-ASCII
+      string: ''
+    headers:
+      Accept-Encoding:
+      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+      Accept:
+      - "*/*"
+      User-Agent:
+      - Zammad User Agent
+      Host:
+      - web-test.dc.zammad.com
+      Authorization:
+      - Basic YmFzaWNfYXV0aF91c2VyOnRlc3QxMjM=
+  response:
+    status:
+      code: 200
+      message: OK
+    headers:
+      Server:
+      - nginx
+      Date:
+      - Tue, 05 Jul 2022 08:53:28 GMT
+      Content-Type:
+      - application/json; charset=utf-8
+      Transfer-Encoding:
+      - chunked
+      Connection:
+      - keep-alive
+      X-Frame-Options:
+      - DENY
+      - SAMEORIGIN
+      X-Xss-Protection:
+      - 1; mode=block
+      X-Content-Type-Options:
+      - nosniff
+      - nosniff
+      X-Download-Options:
+      - noopen
+      X-Permitted-Cross-Domain-Policies:
+      - none
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Etag:
+      - W/"5237445bbd1b27ff683f301b3edc61e1"
+      Cache-Control:
+      - max-age=0, private, must-revalidate
+      X-Request-Id:
+      - 9eed4470-7f17-4ccb-bc93-cd1187766ae2
+      X-Runtime:
+      - '1.001545'
+      Strict-Transport-Security:
+      - max-age=63072000
+    body:
+      encoding: ASCII-8BIT
+      string: '{"remote_ip":"<ZAMMAD_PROXY_REMOTE_IP_CHECK>","content_type_requested":null,"method":"get","submitted":"123"}'
+  recorded_at: Tue, 05 Jul 2022 08:53:28 GMT
+recorded_with: VCR 6.1.0

Some files were not shown because too many files changed in this diff