From f091b939e35551bfc46f20c5a70f44532b735697 Mon Sep 17 00:00:00 2001
From: Thijs Kinkhorst <thijs@kinkhorst.com>
Date: Mon, 5 Sep 2022 12:51:07 +0000
Subject: [PATCH] Add more coverage for MetadataStorageHandling.

Also do not restrict coverage calculation to this class since
the metada functions to test the various configured subclasses.
---
 .../Metadata/MetaDataStorageHandlerTest.php   | 120 ++++++++++++++++--
 .../Metadata/MetaDataStorageSourceTest.php    |   5 -
 .../source1/saml20-sp-remote.php              |  20 +++
 3 files changed, 131 insertions(+), 14 deletions(-)

diff --git a/tests/src/SimpleSAML/Metadata/MetaDataStorageHandlerTest.php b/tests/src/SimpleSAML/Metadata/MetaDataStorageHandlerTest.php
index dd881ab09..efc5b39ac 100644
--- a/tests/src/SimpleSAML/Metadata/MetaDataStorageHandlerTest.php
+++ b/tests/src/SimpleSAML/Metadata/MetaDataStorageHandlerTest.php
@@ -4,19 +4,17 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Test\Metadata;
 
+use Exception;
 use SimpleSAML\Configuration;
+use SimpleSAML\Error\MetadataNotFound;
 use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\TestUtils\ClearStateTestCase;
 
-/**
- * @covers \SimpleSAML\Metadata\MetadataStorageHandler
- */
 class MetaDataStorageHandlerTest extends ClearStateTestCase
 {
-    /**
-     * Test that loading specific entities works, and that metadata source precedence is followed
-     */
-    public function testLoadEntities(): void
+    protected $handler;
+
+    public function setUp(): void
     {
         $c = [
             'metadata.sources' => [
@@ -25,9 +23,15 @@ class MetaDataStorageHandlerTest extends ClearStateTestCase
             ],
         ];
         Configuration::loadFromArray($c, '', 'simplesaml');
-        $handler = MetaDataStorageHandler::getMetadataHandler();
+        $this->handler = MetaDataStorageHandler::getMetadataHandler();
+    }
 
-        $entities = $handler->getMetaDataForEntities([
+    /**
+     * Test that loading specific entities works, and that metadata source precedence is followed
+     */
+    public function testLoadEntities(): void
+    {
+        $entities = $this->handler->getMetaDataForEntities([
             'entityA',
             'entityB',
             'nosuchEntity',
@@ -47,5 +51,103 @@ class MetaDataStorageHandlerTest extends ClearStateTestCase
             $entities['expiredInSrc1InSrc2']['name']['en'],
             "Entity is in both sources, expired in src1 and available from src2"
         );
+        // Did not ask for this one, which is in source1
+        $this->assertArrayNotHasKey('http://localhost/simplesaml', $entities);
+    }
+
+    /**
+     * Test that retrieving a full metadataSet from a source works and precedence works
+     */
+    public function testLoadMetadataSet(): void
+    {
+        $entities = $this->handler->getList('saml20-sp-remote');
+
+        $this->assertCount(5, $entities);
+        $this->assertEquals('entityA SP from source1', $entities['entityA']['name']['en']);
+        $this->assertEquals('entityB SP from source2', $entities['entityB']['name']['en']);
+        $this->assertEquals(
+            'entityInBoth SP from source1',
+            $entities['entityInBoth']['name']['en'],
+            "Entity is in both sources, but should get loaded from the first"
+        );
+        $this->assertEquals(
+            'expiredInSrc1InSrc2 SP from source2',
+            $entities['expiredInSrc1InSrc2']['name']['en'],
+            "Entity is in both sources, expired in src1 and available from src2"
+        );
+        $this->assertEquals('entityA SP from source1', $entities['entityA']['name']['en']);
+        $this->assertEquals('hostname SP from source1', $entities['http://localhost/simplesaml']['name']['en']);
+    }
+
+    /**
+     * Query from a metadata set for which we have no entities should be empty
+     */
+    public function testLoadMetadataSetEmpty(): void
+    {
+        $entities = $this->handler->getList('saml20-idp-remote');
+
+        $this->assertCount(0, $entities);
+    }
+
+    /**
+     * Test the current metadata entity selection
+     */
+    public function testGetMetadataCurrent(): void
+    {
+        $entity = $this->handler->getMetaDataCurrent('saml20-sp-remote');
+
+        $this->assertEquals('http://localhost/simplesaml', $entity['entityid']);
+    }
+
+    /**
+     * Test the helper that returns the metadata as a Configuration object
+     */
+    public function testGetMetadataConfig(): void
+    {
+        $entity = $this->handler->getMetaDataConfig('entityA', 'saml20-sp-remote');
+
+        $this->assertInstanceOf(Configuration::class, $entity);
+        $this->assertEquals('entityA', $entity->getValue('entityid'));
+    }
+
+    /**
+     * Test the helper that searches metadata by sha1 hash
+     */
+    public function testGetMetadataConfigForSha1(): void
+    {
+        $hash = sha1('entityB');
+        $entity = $this->handler->getMetaDataConfigForSha1($hash, 'saml20-sp-remote');
+
+        $this->assertInstanceOf(Configuration::class, $entity);
+        $this->assertEquals('entityB', $entity->getValue('entityid'));
+    }
+
+    /**
+     * Test the helper that searches metadata by sha1 hash
+     */
+    public function testGetMetadataConfigForSha1NotFoundReturnsNull(): void
+    {
+        $hash = sha1('entitynotexist');
+        $entity = $this->handler->getMetaDataConfigForSha1($hash, 'saml20-sp-remote');
+
+        $this->assertNull($entity);
+    }
+
+    /**
+     * Test the current metadata entity selection, empty set
+     */
+    public function testGetMetadataCurrentEmptySet(): void
+    {
+        $this->expectException(Exception::class, 'Could not find any default metadata');
+        $this->handler->getMetaDataCurrent('saml20-idp-remote');
+    }
+
+    /**
+     * Test that trying to fetch a non-existent entity throws Exception
+     */
+    public function testGetMetaDataNonExistentEntity(): void
+    {
+        $this->expectException(MetadataNotFound::class, "METADATANOTFOUND('%ENTITYID%' => 'doesnotexist')");
+        $this->handler->getMetaData('doesnotexist', 'saml20-sp-remote');
     }
 }
diff --git a/tests/src/SimpleSAML/Metadata/MetaDataStorageSourceTest.php b/tests/src/SimpleSAML/Metadata/MetaDataStorageSourceTest.php
index 655c67858..44d0fb606 100644
--- a/tests/src/SimpleSAML/Metadata/MetaDataStorageSourceTest.php
+++ b/tests/src/SimpleSAML/Metadata/MetaDataStorageSourceTest.php
@@ -9,11 +9,6 @@ use PHPUnit\Framework\TestCase;
 use SimpleSAML\Configuration;
 use SimpleSAML\Metadata\MetaDataStorageSource;
 
-/**
- * Class MetaDataStorageSourceTest
- *
- * @covers \SimpleSAML\Metadata\MetadataStorageSource
- */
 class MetaDataStorageSourceTest extends TestCase
 {
     /**
diff --git a/tests/src/SimpleSAML/Metadata/test-metadata/source1/saml20-sp-remote.php b/tests/src/SimpleSAML/Metadata/test-metadata/source1/saml20-sp-remote.php
index b137a00b9..ce5a287d7 100644
--- a/tests/src/SimpleSAML/Metadata/test-metadata/source1/saml20-sp-remote.php
+++ b/tests/src/SimpleSAML/Metadata/test-metadata/source1/saml20-sp-remote.php
@@ -62,3 +62,23 @@ $metadata['expiredInSrc1InSrc2'] = [
                 ],
         ]
 ];
+
+$metadata['http://localhost/simplesaml'] = [
+    'entityid' => 'http://localhost/simplesaml',
+    'host' => 'localhost',
+    'name' =>
+        [
+            'en' => 'hostname SP from source1',
+        ],
+    'metadata-set' => 'saml20-sp-remote',
+    'AssertionConsumerService' =>
+        [
+            0 =>
+                [
+                    'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
+                    'Location' => 'https://hostname.example.org/Shibboleth.sso/SAML2/POST',
+                    'index' => 1,
+                    'isDefault' => true,
+                ],
+        ]
+];
-- 
GitLab