Browse Source

testing initial .. with examples in test.rb

Klumpp, Paul-Dieter 7 years ago
commit
0047e36e57
4 changed files with 513 additions and 0 deletions
  1. 226 0
      rub/http_response_test.rb
  2. 18 0
      rub/resource_path.rb
  3. 162 0
      rub/response_check.rb
  4. 107 0
      rub/test.rb

+ 226 - 0
rub/http_response_test.rb

@@ -0,0 +1,226 @@
+require './resource_path'
+require './response_check'
+
+require 'test/unit'
+require 'digest'
+
+class HTTPResponseTest < Test::Unit::TestCase
+
+  def default_test; end  # placeholder to stop Test::Unit from complaining
+
+  def self.useragent=(useragent)
+    ResponseCheck.useragent = useragent
+  end
+  def self.reset_useragent
+    ResponseCheck.useragent = nil
+  end
+  def self.ssl_no_verify=(verify)
+    ResponseCheck.ssl_no_verify = verify
+  end
+
+  # no accessors needed, as every class that is derived from this one can be adjusted featurewise by just setting:
+  # @useragent
+  # @ssl_no_verify
+
+  def self.uri_be_code(options)
+    @get_uri    = options[:uri].to_s
+    @http_code  = options[:code].to_s
+    @last_uri = @get_uri
+    @last_code = @http_code
+
+    id = Digest::SHA1.hexdigest "#{@get_uri}#{@http_code}#{@ssl_no_verify}#{@useragent}"
+    id = id[0..7]
+
+    #puts "uri to be code ssl_no_verify: " + @ssl_no_verify.to_s
+    class_eval <<-CODE
+      def test_#{name_for(@get_uri)}_response_code_should_be_#{@http_code}_#{id}
+        check = ResponseCheck.new(:get_uri => '#{@get_uri}')
+        if #{@ssl_no_verify} 
+          check.ssl_no_verify = #{@ssl_no_verify}
+        end
+        if '#{@useragent}'.size > 0
+          check.useragent = '#{@useragent}'
+        end
+
+        assert_equal('#{@http_code}', check.response.code, 
+                     "'" + check.get_uri + "' says '" + check.response.code + "' instead of '#{@http_code}'.")
+      end
+    CODE
+  end
+
+  def self.uri_be_success(options)
+    @get_uri  = options.fetch(:uri)
+    @last_uri = @get_uri
+
+    id = Digest::SHA1.hexdigest "#{@get_uri}#{@ssl_no_verify}"
+    id = id[0..7]
+
+    class_eval (
+      <<-CODE
+      def test_#{name_for(@get_uri)}_response_should_be_success_#{id}
+        check = ResponseCheck.new(:get_uri => '#{@get_uri}')
+        if #{@ssl_no_verify} 
+          check.ssl_no_verify = #{@ssl_no_verify}
+        end
+        if '#{@useragent}'.size > 0
+          check.useragent = '#{@useragent}'
+        end
+
+        assert_equal(true, check.success?, 
+                     "'" + check.get_uri + "' says '" + check.response.code + "' instead of '2xx'-something.")
+      end
+      CODE
+    )
+  end
+
+  def self.uri_body_contains(options)
+    @get_uri      = options.fetch(:uri, @last_to)
+    contains          = nil
+    contains_trueness = false
+    if (options[:strings] != nil) and (options[:strings].is_a?(Array))
+      contains          = options[:strings]
+      contains_trueness = true
+    else
+      abort "'uri_body_contains :strings => ['abc']' is missing. Remember, must be array."
+    end
+    @last_uri = @get_uri
+
+    contains.each do |string|
+      id = Digest::SHA1.hexdigest "#{@get_uri}#{string}#{@ssl_no_verify}"
+      id = id[0..7]
+      #puts string
+      class_eval <<-CODE
+        def test_#{name_for(@get_uri)}_response_contains_a_string_#{id}
+          check = ResponseCheck.new(:get_uri => '#{@get_uri}')
+          if #{@ssl_no_verify} 
+            check.ssl_no_verify = #{@ssl_no_verify}
+          end
+          if '#{@useragent}'.size > 0
+            check.useragent = '#{@useragent}'
+          end
+
+          to_match = '#{string}'
+          matched = check.body_contains?(to_match)          
+          assert_equal(true, matched,
+                       "'" + check.get_uri + "' does not contain '" + to_match + "' inside response body.")
+        end
+      CODE
+    end
+  end
+
+
+  def self.uri_should_redirect(options = {})
+    begin
+      @get_uri         = options.fetch(:from, @last_to)
+      wanted_dst_uri   = options.fetch(:to)
+    rescue
+      abort "Usage: uri_should_redirect [:from => '',] :to => ''\n       :from defaults to @last_to"
+    end
+
+    if @get_uri == wanted_dst_uri
+      abort "uri_should_redirect: :to must be different than :from. Both were '#{wanted_dst_uri}'."
+    end
+    by_code          = nil
+    by_code_trueness = false
+    if options[:by] != nil
+      if options[:by].to_i >= 300 and options[:by].to_i < 400
+        by_code          = options[:by].to_i
+        @last_code = by_code
+        by_code_trueness = true
+      else
+        abort "uri_should_redirect: :by must be in 300 to 399 range. Not '#{options[:by]}'."
+      end
+    end
+    @last_to = wanted_dst_uri
+    @last_from = @get_uri
+
+    id = Digest::SHA1.hexdigest "#{@get_uri}#{wanted_dst_uri}#{by_code}#{@ssl_no_verify}#{@useragent}"
+    id = id[0..7]
+
+    class_eval <<-CODE
+      def test_#{name_for(@get_uri)}_should_redirect_to_#{name_for(wanted_dst_uri)}_#{id}
+        check = ResponseCheck.new(:get_uri => '#{@get_uri}')
+        check.wanted_dst_uri = '#{wanted_dst_uri}'
+        if #{@ssl_no_verify} 
+          check.ssl_no_verify = #{@ssl_no_verify}
+        end
+        if '#{@useragent}'.size > 0
+          check.useragent = '#{@useragent}'
+        end
+
+        assert_equal(true, check.redirect?, 
+                     "'" + check.get_uri + "' is not redirecting at all (" + check.response.code + "), but we expected a redirection to '" + check.wanted_dst_uri + "'.")
+
+        assert_equal(check.wanted_dst_uri, check.redirected_uri, 
+                     "'" + check.get_uri + "' is not redirecting to '" + check.wanted_dst_uri + "'.")
+
+        @response = check.response
+        
+        if #{by_code_trueness}
+          assert_equal('#{by_code}', check.response.code,
+                       "The redirection is not the wanted '#{by_code}' redirect. It's a '" + check.response.code + "'." + 
+                       "From '" + check.get_uri + "' to '" + check.wanted_dst_uri + "'")
+        end
+      end
+    CODE
+  end
+
+  def self.path_should_redirect(source, options)
+    source_path      = ResourcePath.new(source, :param => 'subdir').to_s
+    destination_path = ResourcePath.new(options[:to], :param => 'subdir').to_s
+    
+    permanent        = options.fetch(:permanent, true)
+    
+    class_eval <<-CODE
+      def test_#{name_for(source_path)}_should_redirect_to_#{name_for(destination_path)}
+        check = ResponseCheck.new(:src_path => '#{source_path}', :dst_path => '#{destination_path}')
+        if #{@ssl_no_verify}
+          check.ssl_no_verify = #{@ssl_no_verify}
+        end
+        if '#{@useragent}'.size > 0
+          check.useragent = '#{@useragent}'
+        end
+        
+        assert_equal true, check.redirect?, "'#{source_path}' is not redirecting"
+        assert_equal '#{destination_path}', check.redirected_path, 
+                     "'#{source_path}' is not redirecting to '#{destination_path}'"
+        
+        if #{permanent}
+          assert_equal true, check.permanent_redirect?, 
+                       "The redirection from '#{source_path}' to '#{destination_path}' doesn't appear to be a permanent redirect"
+        end
+      end
+    CODE
+
+  end
+
+  def self.path_should_not_redirect(path)
+    class_eval <<-CODE
+      def test_#{name_for(path)}_should_not_redirect
+        check = ResponseCheck.new(:src_path => '#{path}')
+        if #{@ssl_no_verify}
+          check.ssl_no_verify = #{@ssl_no_verify}
+        end
+        if '#{@useragent}'.size > 0
+          check.useragent = '#{@useragent}'
+        end
+        
+        assert_equal false, check.redirect?, "#{path} is redirecting"
+        assert_equal true,  check.success?, "#{path} is not a success response"
+      end
+    CODE
+  end
+
+  private
+
+  def self.name_for(path)
+    name = path.gsub(/\W+/, '_')
+    name.gsub!(/^_+/, '')
+    name.gsub!(/_+$/, '')
+
+    name = 'root' if name == ''
+
+    name
+  end
+
+end

+ 18 - 0
rub/resource_path.rb

@@ -0,0 +1,18 @@
+class ResourcePath
+  
+  attr_writer :param
+  
+  def initialize(path, options = {})
+    @path  = path
+    @param = options[:param]
+  end
+  
+  def param
+    @param ||= (0...8).map{65.+(rand(25)).chr}.join
+  end
+  
+  def to_s
+    @path.gsub('*', param)
+  end
+  
+end

+ 162 - 0
rub/response_check.rb

@@ -0,0 +1,162 @@
+require 'uri'
+require 'net/http'
+require 'openssl'
+
+DEFAULT_USERAGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
+DEFAULT_SSL_NO_VERIFY = false
+
+class ResponseCheck
+
+  ## Class Methods with class variables.
+  def self.useragent=(useragent)
+    case useragent
+      when nil
+        @@useragent = DEFAULT_USERAGENT
+      else
+        @@useragent = useragent
+    end
+  end
+  def self.useragent
+    @@useragent
+  end
+
+  # a class accessor
+  def self.ssl_no_verify=(verify)
+    @@ssl_no_verify = verify
+  end
+  def self.ssl_no_verify
+    @@ssl_no_verify
+  end
+
+
+  ## Instance Methods following:
+  attr_reader :get_uri, :parsed_uri
+  attr_accessor :ssl_no_verify, :useragent, :wanted_dst_uri
+
+  def initialize(options)
+    # required at init
+    @get_uri        = options[:get_uri] || abort("#{self.class.name}: no get_uri given")
+
+    # optional at init. can be set by accessor.
+    @wanted_dst_uri = options[:wanted_dst_uri] ||= nil
+    @ssl_no_verify  = options[:ssl_no_verify]  ||= @@ssl_no_verify ||= DEFAULT_SSL_NO_VERIFY
+    @useragent      = options[:useragent]      ||= @@useragent     ||= DEFAULT_USERAGENT
+
+    # those are just reader
+    @parsed_uri  ||= uri(@get_uri)
+  end
+
+  ### response code mappings following here.
+  ### also see: https://en.wikipedia.org/wiki/URL_redirection
+
+  def http2xx?
+    response.is_a?(Net::HTTPSuccess) # any http 2xx code
+  end
+  def success?
+    http2xx?
+  end
+
+  def http200?
+    response.is_a?(Net::HTTPOK)
+  end
+  def ok?
+    http200?
+  end
+
+  def http3xx?
+    response.is_a?(Net::HTTPRedirection) # any http 3xx code
+  end
+  def redirect? # an alias for 'http3xx?'
+    http3xx?
+  end
+
+  def http301?
+    http3xx? && response.is_a?(Net::HTTPMovedPermanently) # 301
+  end
+  def permanent_redirect? # an alias for 'http301?'
+    http301?
+  end
+
+  def http302?
+    http3xx? && response.is_a?(Net::HTTPFound) # 302
+  end
+
+  def http303?
+    http3xx? && response.is_a?(Net::HTTPMovedTemporarily) # 303
+  end
+  def see_other_temp_redirect? # an alias for 'http303?'
+    http303?
+  end
+
+  def http304?
+    http3xx? && response.is_a?(Net::HTTPNotModified) # 304
+  end
+
+  def http305?
+    http3xx? && response.is_a?(Net::HTTPUseProxy) # 305
+  end
+
+  def http307?
+    http3xx? && response.is_a?(Net::HTTPTemporaryRedirect) # 307
+  end
+  def strict_temp_redirect? # an alias for 'http307?'
+    http307?
+  end
+
+  def body
+    response.body
+  end
+
+  def body_contains?(contains)
+    begin
+      if body.to_s.match(contains)
+        true
+      else
+        false
+      end
+    rescue
+      false
+    end
+  end
+
+  def redirected_path
+    response['location'].sub(/#{Regexp.escape("#{uri.scheme}://#{uri.host}")}/, '') if redirect?
+  end
+
+  def redirected_uri
+    response['location'] if redirect?
+  end
+
+  def response
+    if @useragent.to_s.size < 5
+      abort "#{self.class.name}: useragent '" + @useragent + "' is very short. Thus, just wrong."
+    #else
+    #  puts "Using UA: " + @useragent
+    end
+
+    @verify_mode ||= OpenSSL::SSL::VERIFY_NONE if @ssl_no_verify
+
+    @response ||= Net::HTTP.start(@parsed_uri.host,
+                                  @parsed_uri.port,
+                                  :use_ssl     => @parsed_uri.scheme == 'https',
+                                  :verify_mode => @verify_mode
+    ) {|http|
+      http.request(Net::HTTP::Get.new(@parsed_uri.path, {'User-Agent' => @useragent}) )
+    }
+    return @response
+  end
+
+  private
+
+  def uri(uri)
+    check_uri = URI.parse(uri.to_s)
+    if not check_uri.path.to_s.size > 0
+      check_uri.path = '/'
+    end
+    if not check_uri.scheme =~ /http[s]?/
+      abort "Must be either http or https"
+    end
+    URI.parse(check_uri.to_s)
+  end
+
+end

+ 107 - 0
rub/test.rb

@@ -0,0 +1,107 @@
+
+require './http_response_test'
+
+UA_MOBILE = 'Mozilla/5.0 (Android; Linux armv7l; rv:9.0) Gecko/20111216 Firefox/9.0 Fennec/9.0'
+UA_DEFAULT = nil
+
+class ResponseTest < HTTPResponseTest
+
+  ### Setting Defaults for all subsequent class calls - except when overridden.
+  self.ssl_no_verify = false # setting as default, except when overridden by @ssl_no_verify
+  #self.useragent = 'My Own User Agent for all calls' # setting as default, except when overridden by @useragent
+
+  ### Netdome Sites
+
+  # Rainloop Mailer
+  @ssl_no_verify = true
+  uri_should_redirect :from => 'http://mail.netdome.biz',  :to => 'https://mail.netdome.biz/', :by => '302'
+  uri_be_success      :uri => 'https://mail.netdome.biz/'
+
+  # Grafana
+  uri_should_redirect :from => 'http://grafana.netdome.biz',      :to => 'https://grafana.netdome.biz/'
+  uri_should_redirect :from => 'https://grafana.netdome.biz',      :to => '/login'
+  uri_be_code         :uri => 'https://grafana.netdome.biz/login', :code => '200' # 200 = OK
+
+  # Confluence
+  uri_should_redirect :from => 'https://netdome.biz',     :to => 'https://www.netdome.biz/', :by => '301'
+  uri_should_redirect :from => 'https://www.netdome.biz', :to => 'http://www.netdome.biz/homepage.action', :by => '302'
+  uri_should_redirect :from => 'https://netdome.biz/display/ndpub/Home',
+                      :to => 'https://www.netdome.biz/display/ndpub/Home',
+                      :by => '301'
+  #uri_be_success      :uri => 'http://www.netdome.biz/display/ndpub' # leitet leider per Post 302 auf JSESSIONID weiter
+  uri_be_code         :uri => 'https://www.netdome.biz/display/ndpub', :code => '302'
+
+  #### User Agent testing
+  @ssl_no_verify = false
+  @useragent = UA_MOBILE
+  uri_should_redirect :from => 'https://youtube.com/',
+                      :to => 'https://www.youtube.com/'
+  uri_should_redirect :to => 'https://m.youtube.com/'   # :from is being defaulted to @last_to
+  @useragent = UA_DEFAULT
+
+
+  #### DM Sites
+
+  @ssl_no_verify = false
+  ### DM Germany (.de)
+  uri_should_redirect :from => 'http://dm.de',      :to => 'https://www.dm.de/'
+  uri_should_redirect :from => 'https://dm.de',     :to => @last_to
+  uri_should_redirect :from => 'http://www.dm.de',  :to => @last_to
+  uri_be_success      :uri => @last_to # any of 2xx http response codes
+
+
+  uri_should_redirect :from => 'http://helferherzen.de/',  :to => 'http://www.helferherzen.de/'
+  uri_be_success      :uri => @last_to
+  uri_should_redirect :from => 'https://helferherzen.de/',  :to => 'https://www.helferherzen.de/'
+  uri_be_success      :uri => 'https://www.helferherzen.de/'
+
+  ### DM Austria (.at)
+  uri_should_redirect :from => 'http://dm.at',       :to => 'https://www.meindm.at/mein-dm/'
+  uri_should_redirect :from => 'https://dm.at',      :to => @last_to
+  uri_should_redirect :from => 'http://www.dm.at',   :to => @last_to
+  uri_should_redirect :from => 'https://www.dm.at',  :to => @last_to
+  uri_be_success      :uri => @last_to
+
+  uri_should_redirect :from => 'http://dm-drogeriemarkt.at/',  :to => 'http://www.dm-drogeriemarkt.at/'
+  uri_be_success      :uri => @last_to
+  uri_should_redirect :from => 'https://dm-drogeriemarkt.at/',  :to => 'https://www.dm-drogeriemarkt.at/'
+  uri_be_success      :uri => 'https://www.dm-drogeriemarkt.at'
+
+  ### DM Czech Republic (.cz)
+  uri_should_redirect :from => 'http://dm.cz',  :to => 'http://www.dm-drogeriemarkt.cz/'
+  uri_should_redirect :from => 'https://dm.cz', :to => 'https://www.dm-drogeriemarkt.cz/'
+  uri_should_redirect :from => 'http://www.dm.cz',  :to => 'http://www.dm-drogeriemarkt.cz/'
+  uri_should_redirect :from => 'https://www.dm.cz', :to => 'https://www.dm-drogeriemarkt.cz/'
+  uri_should_redirect :from => 'http://dm-drogeriemarkt.cz',  :to => 'http://www.dm-drogeriemarkt.cz/'
+  uri_be_success      :uri => @last_to
+  uri_should_redirect :from => 'https://dm-drogeriemarkt.cz',  :to => 'https://www.dm-drogeriemarkt.cz/'
+  uri_be_success      :uri => @last_to
+
+  ### DM Hungary (.hu)
+  uri_should_redirect :from => 'http://dm.hu',  :to => 'http://www.dm-drogeriemarkt.hu/', :by => 301
+  uri_should_redirect :from => 'https://dm.hu', :to => 'https://www.dm-drogeriemarkt.hu/'
+  uri_should_redirect :from => 'http://www.dm.hu',  :to => 'http://www.dm-drogeriemarkt.hu/'
+  uri_should_redirect :from => 'https://www.dm.hu', :to => 'https://www.dm-drogeriemarkt.hu/'
+  uri_should_redirect :from => 'http://dm-drogeriemarkt.hu',   :to => 'http://www.dm-drogeriemarkt.hu/'
+  uri_be_success      :uri => 'http://www.dm-drogeriemarkt.hu'
+  uri_should_redirect :from => 'https://dm-drogeriemarkt.hu',  :to => 'https://www.dm-drogeriemarkt.hu/'
+  uri_be_success      :uri => 'https://www.dm-drogeriemarkt.hu'
+
+  ### DM Slovakia (.sk)
+  uri_should_redirect :from => 'http://dm-drogeriemarkt.sk',  :to => 'http://www.dm-drogeriemarkt.sk/'
+  uri_should_redirect :from => 'https://dm-drogeriemarkt.sk', :to => 'https://www.dm-drogeriemarkt.sk/'
+
+  uri_be_success      :uri => 'http://www.dm-drogeriemarkt.sk'
+  uri_body_contains   :uri => 'http://www.dm-drogeriemarkt.sk',
+                      :strings => [
+                          '<title>dm drogerie markt Slovensko</title>'
+                      ]
+
+  uri_be_success      :uri => 'https://www.dm-drogeriemarkt.sk'
+  uri_body_contains   :uri => 'https://www.dm-drogeriemarkt.sk',
+                      :strings => [
+                          '<title>dm drogerie markt Slovensko</title>',
+                      ]
+
+end
+