text: # -*- coding: utf-8 -*-
  #
  # This file is part of Invenio.
  # Copyright (C) 2017-2018 CERN.
  #
  # Invenio is free software; you can redistribute it and/or modify it
  # under the terms of the MIT License; see LICENSE file for more details.
  
  """Module tests."""
  
  from __future__ import absolute_import, print_function
  
  from flask import Flask
  from werkzeug.http import parse_options_header
  
  from invenio_app import InvenioApp
  
  
  def test_rate_secure_headers(app):
      """Test Rate Limiter extension."""
      app.config['APP_ENABLE_SECURE_HEADERS'] = False
      # Initialize the app
      InvenioApp(app)
      assert 'talisman' not in app.extensions
  
  
  def test_headers(app):
      """Test headers."""
      app.config['RATELIMIT_DEFAULT'] = '1/day'
      app.config['RATELIMIT_STORAGE_URL'] = 'memory://'
      ext = InvenioApp(app)
  
      for handler in app.logger.handlers:
          ext.limiter.logger.addHandler(handler)
  
      @app.route('/jessica_jones')
      def jessica_jones():
          return 'jessica jones'
  
      @app.route('/avengers')
      def avengers():
          return 'infinity war'
  
      with app.test_client() as client:
          res = client.get('/jessica_jones')
          assert res.status_code == 200
          assert res.headers['X-RateLimit-Limit'] == '1'
          assert res.headers['X-RateLimit-Remaining'] == '0'
          assert res.headers['X-RateLimit-Reset']
  
          res = client.get('/jessica_jones')
          assert res.status_code == 429
          assert res.headers['X-RateLimit-Limit']
          assert res.headers['X-RateLimit-Remaining']
          assert res.headers['X-RateLimit-Reset']
  
          res = client.get('/avengers')
          assert res.status_code == 200
          assert res.headers['X-Content-Security-Policy']
          assert res.headers['X-Content-Type-Options']
          assert res.headers['X-Frame-Options']
          assert res.headers['X-XSS-Protection']
          assert res.headers['X-RateLimit-Limit']
          assert res.headers['X-RateLimit-Remaining']
          assert res.headers['X-RateLimit-Reset']
  
  
  def _normalize_csp_header(header):
      """Normalize a CSP header for consistent comparisons."""
      return {p.strip() for p in (header or '').split(';')}
  
  
  def _test_csp_default_src(app, expect):
      """Assert that the Content-Security-Policy header is the expect param."""
      ext = InvenioApp(app)
  
      @app.route('/captain_america')
      def captain_america():
          return 'captain america'
  
      with app.test_client() as client:
          res = client.get('/captain_america')
          assert res.status_code == 200
          assert _normalize_csp_header(
              res.headers.get('Content-Security-Policy')
          ) == _normalize_csp_header(expect)
          assert _normalize_csp_header(
              res.headers.get('X-Content-Security-Policy')
          ) == _normalize_csp_header(expect)
  
  
  def test_csp_default_src_when_debug_false(app):
      """Test the Content-Security-Policy header when app debug is False."""
      expect = "default-src 'self'; object-src 'none'"
      _test_csp_default_src(app, expect)
  
  
  def test_csp_default_src_when_debug_true(app):
      """Test the Content-Security-Policy header when app debug is True."""
      app.config['DEBUG'] = True
      expect = "default-src 'self' 'unsafe-inline'; object-src 'none'"
      _test_csp_default_src(app, expect)
  
  
  def test_empty_csp_when_set_empty(app):
      """Test empty Content-Security-Policy header when set emtpy."""
      app.config['DEBUG'] = True
      app.config['APP_DEFAULT_SECURE_HEADERS']['content_security_policy'] = {}
      expect = None
      _test_csp_default_src(app, expect)
  
  
  def test_default_health_blueprint(app):
      app.config['APP_HEALTH_BLUEPRINT_ENABLED'] = True
      # Initialize the app
      InvenioApp(app)
      with app.test_client() as client:
          res = client.get('/ping')
          assert res.status_code == 200
  
  
  def test_requestid(base_app):
      """Test extraction of header id."""
      InvenioApp(base_app)
      with base_app.test_client() as client:
          assert '1234' == client.get(
              '/requestid',  headers={'X-Request-ID': '1234'}
          ).get_data(as_text=True)
  
  
  def test_requestid_different_header(base_app):
      """Test changing header name."""
      base_app.config['APP_REQUESTID_HEADER'] = 'Request-ID'
      InvenioApp(base_app)
      with base_app.test_client() as client:
          # Extracted
          assert '1234' == client.get(
              '/requestid',  headers={'Request-ID': '1234'}
          ).get_data(as_text=True)
          # Not extracted
          assert '' == client.get(
              '/requestid',  headers={'X-Request-ID': '1234'}
          ).get_data(as_text=True)
  
  
  def test_requestid_cap_200(base_app):
      """Test cap at 200 chars of request id."""
      InvenioApp(base_app)
      with base_app.test_client() as client:
          assert '1'*200 == client.get(
              '/requestid',  headers={'X-Request-ID': '1'*500}
          ).get_data(as_text=True)
  
  
  def test_requestid_no_extraction(base_app):
      """Test no extraction of header id."""
      base_app.config['APP_REQUESTID_HEADER'] = None
      InvenioApp(base_app)
      with base_app.test_client() as client:
          assert '' == client.get(
              '/requestid',  headers={'X-Request-ID': '1234'}
          ).get_data(as_text=True)
  