Ajout de nouvelles classes de tests

This commit is contained in:
Jérémy Lecour 2016-04-28 22:51:52 +02:00
parent fe0e5804a3
commit bb10b39b60
4 changed files with 321 additions and 11 deletions

View file

@ -1,6 +1,6 @@
Il s'agit d'un ensemble de scripts, de type "tests unitaires" permettant de valider le comportement d'un service web, du point de vue d'un client web. Il s'agit d'un ensemble de scripts, de type "tests unitaires" permettant de valider le comportement d'un service web, du point de vue d'un client web.
## Installation # Installation
Au minimum il faut Ruby pour l'exécution des scripts. Au minimum il faut Ruby pour l'exécution des scripts.
@ -17,9 +17,9 @@ Une fois Ruby installé, depuis le dossier du projet :
Ça va installer localement des paquets Ruby nécessaires. Ça va installer localement des paquets Ruby nécessaires.
## Exécution # Exécution
### Partie "sécurité" : ## Partie "sécurité" :
bundle exec ruby -Itest test/secrity_test.rb bundle exec ruby -Itest test/secrity_test.rb
@ -27,34 +27,94 @@ Il est possible d'utiliser un certificat SSL racine stocké en local (`test/cert
Il est possible d'utiliser un binaire `open_ssl` personnalisé, géré dans la méthode `openssl_path`. Il est possible d'utiliser un binaire `open_ssl` personnalisé, géré dans la méthode `openssl_path`.
#### `test_certificate_level` ### `test_certificate_level`
Permet de vérifier la conformité avec un des niveaux normalisés proposés par Mozilla (https://wiki.mozilla.org/Security/Server_Side_TLS) Permet de vérifier la conformité avec un des niveaux normalisés proposés par Mozilla (https://wiki.mozilla.org/Security/Server_Side_TLS)
#### `test_certificate` ### `test_certificate`
Vérifie la validité du certificat Vérifie la validité du certificat
#### `test_accepts_tls_v1` ### `test_accepts_tls_v1`
Vérifie que le serveur accepte bien des connexions TLS v1 Vérifie que le serveur accepte bien des connexions TLS v1
#### `test_refuse_ssl_v3` ### `test_refuse_ssl_v3`
Vérifie que le serveur refuse bien des connexions SSL v3 Vérifie que le serveur refuse bien des connexions SSL v3
#### `test_hsts_header` ### `test_hsts_header`
Vérifie la présence de l'en-tête HTTP `HTTP-Strict-Transport-Security`. Vérifie la présence de l'en-tête HTTP `HTTP-Strict-Transport-Security`.
### Partie "redirections" : ## Partie "redirections" :
bundle exec ruby -Itest test/domain_redirects_test.rb bundle exec ruby -Itest test/domain_redirects_test.rb
#### `test_redirections` ### `test_redirections`
Vérifie que les redirections attendues aient bien lieu. Vérifie que les redirections attendues aient bien lieu.
#### `test_http_codes` ### `test_http_codes`
Vérifie que les codes HTTP attendus soient bien reçus. Vérifie que les codes HTTP attendus soient bien reçus.
## Partie "assets accessibility"
bundle exec ruby -Itest test/assets_accessibility_test.rb
### `test_rss_feeds`
Vérifie la présence de flux RSS sur la page et leur fonctionnement.
### `test_head_stylelsheets`
Vérifie la présence de CSS, qu'elles sont bien accessibles, et que leurs en-têtes HTTP les rendent cachables.
### `test_head_scripts`
Vérifie la présence de JS, qu'ils sont bien accessibles, et que leurs en-têtes HTTP les rendent cachables.
### `test_images`
Vérifie que toutes images de la page sont bien accessibles et cachables.
### `test_https_src`
Vérifie que toutes les balises avec attribut `src` sont bien en HTTPS.
### `test_cors`
Vérifie les en-têtes CORS sur la feuille de style et toutes les polices web qu'elle référence.
## Partie "cookies"
bundle exec ruby -Itest test/cookies_test.rb
`test_no_session_on_pages`
Vérifie que certaines pages ne poussent pas de cookies.
`test_session_on_pages`
Vérifie que certaines pages poussent bien un cookie.
## Partie "cache HTTP"
bundle exec ruby -Itest test/http_cache_test.rb
`test_varnish_hit`
Vérifie que certaines pages sont bien servies puis mises en cache par Varnish.
`test_homepage_first_visit`
Vérifie que certaines pages ont des en-têtes corrects pour le cache public.
`test_homepage_second_visit`
Vérifie que certaines pages rechargées en transmettant les infos de cache reçoivent une réponse "304".
`test_login_first_visit`
Vérifie que certaines pages ne soient pas mises en cache.

View file

@ -0,0 +1,110 @@
require 'test_helper'
require "mechanize"
require "nokogiri"
class AssetsAccessibilityTest < Minitest::Test
include WebserverHelper
def test_rss_feeds
on_home_page do |page, doc|
feeds = doc.search("//head/link[@type='application/rss+xml']")
# Il y a au moins 1 flux RSS
assert feeds.size >= 1, "Expected to find an RSS feed"
feeds.each do |feed|
url = feed["href"]
assert_status_ok agent.get(url), "for #{url}"
end
end
end
def test_head_stylelsheets
on_home_page do |page, doc|
stylesheets = doc.search("//head/link[@rel='stylesheet']")
# Il y a au moins 1 CSS "application"
assert stylesheets.any? { |stylesheet|
path = URI.parse(stylesheet["href"]).path
%r(\A/assets/application-\w+\.css\Z) =~ path
}, "Expected to find the application CSS"
# Tous les CSS sont accessibles et correctement configurés
stylesheets.each do |stylesheet|
url = stylesheet["href"]
if internal_url?(url)
assert_cachable_asset agent.get(url), "for #{url}"
end
end
end
end
def test_head_scripts
on_home_page do |page, doc|
scripts = doc.search("//head/script[@src]")
# Il y a au moins 1 JS "application"
assert scripts.any? { |script|
path = URI.parse(script["src"]).path
%r|\A/assets/application-\w+\.js\Z| =~ path
}, "Expected to find the application JS"
# Tous les scripts externes sont accessibles
scripts.each do |script|
url = script["src"]
if internal_url?(url)
assert_cachable_asset agent.get(url), "for #{url}"
end
end
end
end
def test_images
on_home_page do |page, doc|
doc.search("body img").each do |image|
url = image["src"]
if internal_url?(url)
assert_cachable_asset agent.get(url), "for #{url}"
end
end
end
end
def test_https_src
on_home_page do |page, doc|
doc.search("[src]").each do |element|
assert_scheme "https", element["src"], "on page #{page.uri}"
end
end
end
def test_cors
on_home_page do |page, doc|
stylesheets = doc.search("//head/link[@rel='stylesheet']")
# On récupère la feuille de style qui contient les appels aux polices web
vendor_stylesheet = stylesheets.detect { |stylesheet|
path = URI.parse(stylesheet["href"]).path
%r(\A/assets/vendor_bootstrap-\w+\.css\Z) =~ path
}
refute_nil vendor_stylesheet, "Expected to find a \"vendor_bootstrap\" CSS file"
# On extrait toutes les URL de polices web
css_url = vendor_stylesheet["href"]
pattern = /url\((?:"|')?([^\)"']+)(?:"|')?\)/
font_urls = agent.get(css_url).body.scan(pattern).flatten
refute font_urls.empty?, "Expected to find webfonts in #{css_url}"
# On vérifie que les en-têtes sont présents
origin = "https://www.example.com/"
font_urls.each do |font_url|
page = agent.get(font_url, [], nil, { "Origin" => origin })
actual = header(page, "access-control-allow-origin")
assert_equal origin, actual, "Expected CORS header to match the request origin for #{font_url}"
end
end
end
end

47
test/cookies_test.rb Normal file
View file

@ -0,0 +1,47 @@
require 'test_helper'
require 'mechanize'
class CookiesTest < Minitest::Test
include WebserverHelper
def setup
@agent = Mechanize.new { |a|
a.follow_redirect = false
}
end
def test_no_session_on_pages
[
"/",
"/faq",
].each do |path|
url = "https://#{domain}#{path}"
page = @agent.get(url)
refute_has_session_cookie @agent, "_example_session", "for #{url}"
end
end
def test_session_on_pages
[
"/login",
"/store",
].each do |path|
url = "https://#{domain}#{path}"
page = @agent.get(url)
assert_has_session_cookie @agent, "_example_session", "for #{url}"
end
end
def assert_has_session_cookie(agent, cookie_name, context = nil)
message = message_with_context("Expected to find a session cookie named '#{cookie_name}'", context)
assert_includes agent.cookie_jar.map(&:name), cookie_name, message
end
def refute_has_session_cookie(agent, cookie_name, context = nil)
message = message_with_context("Expected to not find a session cookie named '#{cookie_name}'", context)
refute_includes agent.cookie_jar.map(&:name), cookie_name, message
end
end

93
test/http_cache_test.rb Normal file
View file

@ -0,0 +1,93 @@
require 'test_helper'
require "mechanize"
class HTTPCacheTest < Minitest::Test
include WebserverHelper
def setup
@agent = Mechanize.new { |a|
a.follow_redirect = false
}
end
def test_varnish_hit
skip("Pas de test avec Varnish") if ENV["VARNISH"] == "0"
[
"https://#{domain}/",
].each do |url|
# Pour assurer la mise en cache par Varnish
page = @agent.get(url)
assert_has_header "x-varnish", page, "for #{url}"
assert_has_header "x-cache", page, "for #{url}"
# On laisse un peu de temps au cache pour se réchauffer
sleep(0.1)
# On refait la requête en espérant avoir un HIT
@agent.reset
page = @agent.get(url)
assert_x_cache_hit page, "for #{url}"
end
end
def test_homepage_first_visit
[
"https://#{domain}/",
].each do |url|
page = @agent.get(url)
assert_status_ok page, "for #{url}"
assert_has_etag page, "for #{url}"
assert_has_last_modified page, "for #{url}"
# assert_max_age "300", page, "for #{url}"
# refute_must_revalidate page, "for #{url}"
assert_public page, "for #{url}"
end
end
def test_homepage_second_visit
[
"https://#{domain}/",
].each do |url|
page1 = @agent.get(url)
assert_status_ok page1, "for #{url} on 1st visit"
if last_modified = last_modified_header(page1)
# il faut reinitialiser l'agent pour vider le cache et l'historique
@agent.reset
page2a = @agent.get(url, [], nil, {
"If-Modified-Since" => last_modified
})
assert_status_not_modified page2a, "for #{url} on 2nd visit with Last-Modified"
else
flunk "Expected to find a Last-Modified header for #{url} on 1st visit"
end
if etag = etag_header(page1)
# il faut reinitialiser l'agent pour vider le cache et l'historique
@agent.reset
page2b = @agent.get(url, [], nil, {
"If-None-Match" => etag_header(page1)
})
assert_status_not_modified page2b, "for #{url} on 2nd visit with ETag"
else
flunk "Expected to fin an ETag header for #{url} on 1st visit"
end
end
end
def test_login_first_visit
[
"https://#{domain}/login",
].each do |url|
page = @agent.get(url)
assert_max_age "0", page, "for #{url}"
assert_must_revalidate page, "for #{url}"
assert_private page, "for #{url}"
end
end
end