<?php

declare(strict_types=1);

/*
 * eduVPN - End-user friendly VPN.
 *
 * Copyright: 2014-2023, The Commons Conservancy eduVPN Programme
 * SPDX-License-Identifier: AGPL-3.0+
 */

namespace Vpn\Portal\Tests;

use PHPUnit\Framework\TestCase;
use Vpn\Portal\Http\UserInfo;

/**
 * @covers \Vpn\Portal\Http\UserInfo
 */
final class UserInfoTest extends TestCase
{
    public function testNoExpiry(): void
    {
        $userInfo = new UserInfo(
            'foo',
            []
        );
        $this->assertCount(0, $userInfo->sessionExpiry());
    }

    public function testOneExpiry(): void
    {
        $userInfo = new UserInfo(
            'foo',
            [
                'https://eduvpn.org/expiry#P1Y',
            ]
        );
        $this->assertSame(
            [
                'P1Y',
            ],
            $userInfo->sessionExpiry()
        );
    }

    public function testExpiryFromCapability(): void
    {
        $userInfo = new UserInfo(
            'foo',
            [
                'urn:example.org:res:eduvpn.org:session-expiry:P99D#idp.example.org',
            ]
        );
        $this->assertSame(
            [
                'P99D',
            ],
            $userInfo->sessionExpiry()
        );
    }

    public function testMultipleExpiries(): void
    {
        $userInfo = new UserInfo(
            'foo',
            [
                'https://eduvpn.org/expiry#P1Y',
                'eduPersonEntitlement!https://eduvpn.org/expiry#PT12H',
            ]
        );
        $this->assertSame(
            [
                'P1Y',
                'PT12H',
            ],
            $userInfo->sessionExpiry()
        );
    }

    public function testHasAnyLegacyPermission(): void
    {
        $u = new UserInfo(
            'foo',
            [
                'one',
                'two',
            ]
        );

        $this->assertTrue($u->hasAnyPermission(['one']));
        $this->assertTrue($u->hasAnyPermission(['two']));
        $this->assertTrue($u->hasAnyPermission(['three', 'one']));
        $this->assertFalse($u->hasAnyPermission([]));
        $this->assertFalse($u->hasAnyPermission(['three']));
        $this->assertFalse($u->hasAnyPermission(['three', 'four']));
    }

    public function testHasAnyAttributePermission(): void
    {
        $u = new UserInfo(
            'foo',
            [
                'foo',
                'isMember!one',
                'isMember!two',
                'foo!bar!baz',  // attribute=foo, value=bar!baz
            ]
        );

        $this->assertTrue($u->hasAnyPermission(['foo']));
        $this->assertTrue($u->hasAnyPermission(['one']));
        $this->assertTrue($u->hasAnyPermission(['two']));
        $this->assertTrue($u->hasAnyPermission(['isMember!one']));
        $this->assertTrue($u->hasAnyPermission(['isMember!two']));
        $this->assertTrue($u->hasAnyPermission(['isMember!three', 'isMember!one']));
        $this->assertFalse($u->hasAnyPermission(['bar']));
        $this->assertFalse($u->hasAnyPermission(['isMember!foo']));
        $this->assertFalse($u->hasAnyPermission([]));
        $this->assertFalse($u->hasAnyPermission(['isMember!three']));
        $this->assertFalse($u->hasAnyPermission(['isMember!three', 'isMember!four']));
        $this->assertTrue($u->hasAnyPermission(['foo!bar!baz']));
        $this->assertTrue($u->hasAnyPermission(['bar!baz']));
    }
}
