PHP Classes

File: tests/WorkflowHelpersTest.php

Recommend this page to a friend!
  Packages of A. B. M. Mahmudul Hasan   OTP   tests/WorkflowHelpersTest.php   Download  
File: tests/WorkflowHelpersTest.php
Role: Example script
Content type: text/plain
Description: Example script
Class: OTP
Generate token to be verified during a time window
Author: By
Last change:
Date: 20 days ago
Size: 3,194 bytes
 

Contents

Class file image Download
<?php

use Infocyph\OTP\HOTP;
use
Infocyph\OTP\OCRA;
use
Infocyph\OTP\Support\StepUp;
use
Infocyph\OTP\TOTP;
use
Infocyph\OTP\ValueObjects\DeviceEnrollment;

test('device enrollment tracks pending activation and revocation lifecycle', function () {
   
$enrollment = DeviceEnrollment::create('device-1', 'Alice phone', 'secret-ref-1');

   
$active = $enrollment->activate(new \DateTimeImmutable('2026-04-20 10:00:00'));
   
$renamed = $active->rename('Primary phone');
   
$rotated = $renamed->withSecretReference('secret-ref-2');
   
$revoked = $rotated->revoke(new \DateTimeImmutable('2026-04-20 11:00:00'));

   
expect($enrollment->isPendingActivation())->toBeTrue()
        ->
and($active->isActive())->toBeTrue()
        ->
and($renamed->label)->toBe('Primary phone')
        ->
and($rotated->secretReference)->toBe('secret-ref-2')
        ->
and($revoked->isRevoked())->toBeTrue()
        ->
and($revoked->isActive())->toBeFalse();
});

test('step-up helpers report age and freshness details', function () {
   
$verifiedAt = new \DateTimeImmutable('2026-04-20 10:00:00');
   
$now = new \DateTimeImmutable('2026-04-20 10:04:00');

   
$result = StepUp::assess($verifiedAt, 300, $now);

   
expect($result->hasVerification())->toBeTrue()
        ->
and($result->ageInSeconds)->toBe(240)
        ->
and($result->isFresh())->toBeTrue()
        ->
and($result->requiresFreshOtp)->toBeFalse()
        ->
and($result->expiresAt?->format('Y-m-d H:i:s'))->toBe('2026-04-20 10:05:00')
        ->
and(StepUp::requiresFreshOtp($verifiedAt, 120, $now))->toBeTrue();
});

test('totp secret rotation can prepare reprovisioning payloads', function () {
   
$totp = (new TOTP(TOTP::generateSecret()))->setAlgorithm('sha256');
   
$rotation = $totp->planSecretRotation(
       
TOTP::generateSecret(),
       
'alice@example.com',
       
'Example App',
       
gracePeriodInSeconds: 3600,
       
now: 1716532624,
       
withQrSvg: true,
    );

   
expect($rotation->hasGracePeriod())->toBeTrue()
        ->
and($rotation->isDualSecretActive(new \DateTimeImmutable('@1716533000')))->toBeTrue()
        ->
and($rotation->nextEnrollment?->issuer)->toBe('Example App')
        ->
and($rotation->nextEnrollment?->label)->toBe('alice@example.com')
        ->
and($rotation->nextEnrollment?->qrSvg)->toContain('<svg');
});

test('hotp and ocra secret rotation can prepare replacement enrollment payloads', function () {
   
$hotp = (new HOTP(HOTP::generateSecret()))->setAlgorithm('sha512')->setCounter(5);
   
$hotpRotation = $hotp->planSecretRotation(
       
HOTP::generateSecret(),
       
'alice@example.com',
       
'Example App',
    );

   
$ocra = new OCRA('OCRA-1:HOTP-SHA256-8:QN08-PSHA1', '12345678901234567890123456789012');
   
$ocraRotation = $ocra->planSecretRotation(
       
OCRA::generateSecret(),
       
'alice@example.com',
       
'Example App',
       
gracePeriodInSeconds: 900,
       
now: 1716532624,
    );

   
expect($hotpRotation->requiresImmediateCutover())->toBeTrue()
        ->
and($hotpRotation->nextEnrollment?->uri)->toContain('counter=5')
        ->
and($ocraRotation->hasGracePeriod())->toBeTrue()
        ->
and($ocraRotation->nextEnrollment?->uri)->toContain('ocraSuite=');
});