<?php 
 
namespace ParagonIE\CSPBuilderTest; 
 
use ParagonIE\CSPBuilder\CSPBuilder; 
use PHPUnit\Framework\TestCase; 
 
/** 
 * Class BasicTest 
 * @package ParagonIE\CSPBuilderTest 
 */ 
class BasicTest extends TestCase 
{ 
    /** 
     * @throws \Exception 
     */ 
    public function testBasicFromFile() 
    { 
        $basic = CSPBuilder::fromFile(__DIR__.'/vectors/basic-csp.json'); 
        $basic->addSource('img-src', 'ytimg.com'); 
        $this->assertEquals( 
            file_get_contents(__DIR__.'/vectors/basic-csp.out'), 
            $basic->getCompiledHeader() 
        ); 
 
        $noOld = file_get_contents(__DIR__.'/vectors/basic-csp-no-old.out'); 
        // We expect different output for ytimg.com when we disable legacy 
        // browser support (i.e. Safari): 
        $this->assertEquals( 
            $noOld, 
            $basic 
                ->disableOldBrowserSupport() 
                ->getCompiledHeader() 
        ); 
 
        $array = $basic->getHeaderArray(); 
        $this->assertEquals( 
            $array, 
            [ 
                'Content-Security-Policy' => $noOld, 
                'X-Content-Security-Policy' => $noOld, 
                'X-Webkit-CSP' => $noOld 
            ] 
        ); 
 
 
        $array2 = $basic->getHeaderArray(false); 
        $this->assertEquals( 
            $array2, 
            [ 
                'Content-Security-Policy' => $noOld 
            ] 
        ); 
    } 
 
    /** 
     * @throws \Exception 
     */ 
    public function testBasicFromData() 
    { 
        $data = file_get_contents(__DIR__.'/vectors/basic-csp.json'); 
 
        $basic = CSPBuilder::fromData($data); 
        $basic->addSource('img-src', 'ytimg.com'); 
 
        $this->assertEquals( 
            file_get_contents(__DIR__.'/vectors/basic-csp.out'), 
            $basic->getCompiledHeader() 
        ); 
    } 
 
    /** 
     * @throws \Exception 
     */ 
    public function testHash() 
    { 
        $basic = CSPBuilder::fromFile(__DIR__.'/vectors/basic-csp.json'); 
        $basic->hash('script-src', 'Yellow Submarine', 'sha384'); 
        $this->assertEquals( 
            file_get_contents(__DIR__.'/vectors/basic-csp-hash.out'), 
            $basic->getCompiledHeader() 
        ); 
    } 
 
    /** 
     * @throws \Exception 
     */ 
    public function testPreHash() 
    { 
        $basic = CSPBuilder::fromFile(__DIR__.'/vectors/basic-csp.json'); 
        $hashed = \base64_encode( 
            \hash('sha384', 'Yellow Submarine', true) 
        ); 
        $basic->preHash('script-src', $hashed, 'sha384'); 
        $this->assertEquals( 
            file_get_contents(__DIR__.'/vectors/basic-csp-hash.out'), 
            $basic->getCompiledHeader() 
        ); 
    } 
 
    /** 
     * @covers \ParagonIE\CSPBuilder\CSPBuilder 
     */ 
    public function testSourceHttpsConversion() 
    { 
        /** @var CSPBuilder|\PHPUnit_Framework_MockObject_MockObject $cspHttp */ 
        $cspHttp = $this->getMockBuilder(CSPBuilder::class)->setMethods(['isHTTPSConnection']) 
            ->disableOriginalConstructor()->getMock(); 
        $cspHttp->method('isHTTPSConnection')->willReturn(false); 
 
        $cspHttp->addSource('form', 'http://example.com'); 
        $cspHttp->addSource('form', 'another.com'); 
        $cspHttp->enableHttpsTransformOnHttpsConnections(); // enabled by default 
        $compiledCspHttp = $cspHttp->compile(); 
        $this->assertContains('http://example.com', $compiledCspHttp); 
        $this->assertContains('http://another.com', $compiledCspHttp); 
 
        /** @var CSPBuilder|\PHPUnit_Framework_MockObject_MockObject $cspHttps */ 
        $cspHttps = $this->getMockBuilder(CSPBuilder::class)->setMethods(['isHTTPSConnection']) 
            ->disableOriginalConstructor()->getMock(); 
        $cspHttps->method('isHTTPSConnection')->willReturn(true); 
 
        $cspHttps->addSource('form', 'http://example.com'); 
        $cspHttps->addSource('form', 'another.com'); 
 
        $compiledCspHttpsWithConvertEnabled = $cspHttps->compile(); 
        $this->assertContains('https://example.com', $compiledCspHttpsWithConvertEnabled); 
        $this->assertContains('https://another.com', $compiledCspHttpsWithConvertEnabled); 
        $this->assertNotContains('http://example.com', $compiledCspHttpsWithConvertEnabled); 
        $this->assertNotContains('http://another.com', $compiledCspHttpsWithConvertEnabled); 
 
        $cspHttps->disableHttpsTransformOnHttpsConnections(); 
        $compiledCspHttpsWithConvertDisabled = $cspHttps->compile(); 
        $this->assertContains('http://example.com', $compiledCspHttpsWithConvertDisabled); 
        $this->assertContains('http://another.com', $compiledCspHttpsWithConvertDisabled); 
    } 
 
    /** 
     * @covers CSPBuilder::disableHttpsTransformOnHttpsConnections() 
     */ 
    public function testUpgradeInsecureBeatsDisableHttpsConversionFlag() 
    { 
        $csp = new CSPBuilder(); 
        $csp->addSource('form', 'http://example.com'); 
        $csp->disableHttpsTransformOnHttpsConnections(); 
        $csp->addDirective('upgrade-insecure-requests'); 
        $compiled = $csp->compile(); 
        $this->assertContains('https://example.com', $compiled); 
        $this->assertNotContains('http://example.com', $compiled); 
    } 
 
    /** 
     * @covers CSPBuilder::setDataAllowed() 
     * @throws \Exception 
     */ 
    public function testAllowDataUris() 
    { 
        $csp = new CSPBuilder(); 
        $csp->setDataAllowed('img-src', true); 
        $compiled = $csp->compile(); 
 
        $this->assertContains("data:", $compiled); 
    } 
    /** 
     * @covers CSPBuilder::setSelfAllowed() 
     * @throws \Exception 
     */ 
    public function testRequireSRI() 
    { 
        $csp = new CSPBuilder(); 
        $csp->setSelfAllowed('script-src', true) 
            ->addSource('script-src', 'self') 
            ->requireSRIFor('script'); 
        $require = \json_encode($csp->getRequireHeaders()); 
        $this->assertEquals( 
            '[["Content-Security-Policy","require-sri-for script"]]', 
            $require 
        ); 
    } 
 
    /** 
     * @covers CSPBuilder::setSelfAllowed() 
     * @throws \Exception 
     */ 
    public function testAllowSelfUris() 
    { 
        $csp = new CSPBuilder(); 
        $csp->setSelfAllowed('img-src', true); 
        $compiled = $csp->compile(); 
 
        $this->assertContains("'self'", $compiled); 
    } 
 
    /** 
     * @covers CSPBuilder::setAllowUnsafeEval() 
     * @throws \Exception 
     */ 
    public function testAllowUnsafeEval() 
    { 
        $csp = new CSPBuilder(); 
        $csp->setAllowUnsafeEval('script-src', true); 
        $compiled = $csp->compile(); 
 
        $this->assertContains("'unsafe-eval'", $compiled); 
    } 
 
    /** 
     * @covers CSPBuilder::setAllowUnsafeInline() 
     * @throws \Exception 
     */ 
    public function testAllowUnsafeInline() 
    { 
        $csp = new CSPBuilder(); 
        $csp->setAllowUnsafeInline('script-src', true); 
        $compiled = $csp->compile(); 
 
        $this->assertContains("'unsafe-inline'", $compiled); 
    } 
} 
 
 |