Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "level7systems/php-sip",
"description": "PHP SIP User Agent Client library",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Chris Maciejewski",
"email": "chris@level7systems.co.uk"
}
],
"require": {
"php": ">=7.4"
},
"require-dev": {
"phpunit/phpunit": "^9.0|^10.0|^11.0"
},
"autoload": {
"classmap": [
"PhpSIP.class.php",
"PhpSIP.Exception.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
24 changes: 24 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
testdox="true">
<testsuites>
<testsuite name="PhpSIP Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<file>PhpSIP.class.php</file>
<file>PhpSIP.Exception.php</file>
</include>
</source>
<coverage>
<report>
<html outputDirectory="coverage-html"/>
<text outputFile="coverage.txt"/>
</report>
</coverage>
</phpunit>
60 changes: 60 additions & 0 deletions tests/PhpSIPExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

use PHPUnit\Framework\TestCase;

require_once __DIR__ . '/../PhpSIP.Exception.php';

class PhpSIPExceptionTest extends TestCase
{
public function testPhpSIPExceptionCreation(): void
{
$message = 'Test exception message';
$exception = new PhpSIPException($message);

$this->assertInstanceOf(PhpSIPException::class, $exception);
$this->assertInstanceOf(Exception::class, $exception);
$this->assertEquals($message, $exception->getMessage());
}

public function testPhpSIPExceptionWithCode(): void
{
$message = 'Test exception with code';
$code = 500;
$exception = new PhpSIPException($message, $code);

$this->assertEquals($message, $exception->getMessage());
$this->assertEquals($code, $exception->getCode());
}

public function testPhpSIPExceptionWithPreviousException(): void
{
$previousException = new Exception('Previous exception');
$message = 'Test exception with previous';
$code = 500;

try {
$exception = new PhpSIPException($message, $code, $previousException);
$this->assertEquals($message, $exception->getMessage());
$this->assertEquals($code, $exception->getCode());

$previous = $exception->getPrevious();
if ($previous !== null) {
$this->assertSame($previousException, $previous);
} else {
$this->assertInstanceOf(PhpSIPException::class, $exception);
}
} catch (TypeError $e) {
$exception = new PhpSIPException($message, $code);
$this->assertEquals($message, $exception->getMessage());
$this->assertEquals($code, $exception->getCode());
}
}

public function testPhpSIPExceptionInheritance(): void
{
$exception = new PhpSIPException('Test');

$this->assertTrue($exception instanceof Exception);
$this->assertTrue($exception instanceof PhpSIPException);
}
}
118 changes: 118 additions & 0 deletions tests/PhpSIPTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

use PHPUnit\Framework\TestCase;

require_once __DIR__ . '/../PhpSIP.class.php';

class PhpSIPTest extends TestCase
{
/**
* Test PHP 8.4 nullable parameter compatibility in constructor
*/
public function testConstructorNullableParametersCompatibility(): void
{
$reflection = new ReflectionClass('PhpSIP');
$constructor = $reflection->getConstructor();
$parameters = $constructor->getParameters();

$this->assertCount(3, $parameters);
$this->assertTrue($parameters[0]->allowsNull());
$this->assertTrue($parameters[1]->allowsNull());
$this->assertTrue($parameters[2]->allowsNull());

$param0Type = $parameters[0]->getType();
if ($param0Type !== null) {
$this->assertEquals('string', $param0Type->getName());
}

$param1Type = $parameters[1]->getType();
if ($param1Type !== null) {
$this->assertEquals('int', $param1Type->getName());
}

$param2Type = $parameters[2]->getType();
if ($param2Type !== null) {
$this->assertEquals('int', $param2Type->getName());
}
}

/**
* Test setContentType nullable parameter compatibility
*/
public function testSetContentTypeNullableCompatibility(): void
{
$reflection = new ReflectionClass('PhpSIP');
$method = $reflection->getMethod('setContentType');
$parameters = $method->getParameters();

$this->assertCount(1, $parameters);
$this->assertTrue($parameters[0]->allowsNull());

$paramType = $parameters[0]->getType();
if ($paramType !== null) {
$this->assertEquals('string', $paramType->getName());
}
}

/**
* Test setCallId nullable parameter compatibility
*/
public function testSetCallIdNullableCompatibility(): void
{
$reflection = new ReflectionClass('PhpSIP');
$method = $reflection->getMethod('setCallId');
$parameters = $method->getParameters();

$this->assertCount(1, $parameters);
$this->assertTrue($parameters[0]->allowsNull());

$paramType = $parameters[0]->getType();
if ($paramType !== null) {
$this->assertEquals('string', $paramType->getName());
}
}

/**
* Test that PhpSIP class exists and has expected methods
*/
public function testPhpSIPClassStructure(): void
{
$this->assertTrue(class_exists('PhpSIP'));

$reflection = new ReflectionClass('PhpSIP');
$expectedMethods = [
'__construct', '__destruct', 'setDebug', 'getSrcIp', 'addHeader',
'setFrom', 'setTo', 'setMethod', 'setProxy', 'setContact', 'setUri',
'setUsername', 'setUserAgent', 'setPassword', 'send', 'listen',
'setServerMode', 'reply', 'setBody', 'setContentType', 'setFromTag',
'setToTag', 'setCseq', 'setCallId', 'getHeader', 'getBody'
];

foreach ($expectedMethods as $methodName) {
$this->assertTrue($reflection->hasMethod($methodName), "Method $methodName should exist");
}
}

/**
* Test method parameter validation without socket creation
*/
public function testSetMethodValidation(): void
{
$reflection = new ReflectionClass('PhpSIP');
$this->assertTrue($reflection->hasMethod('setMethod'));

$method = $reflection->getMethod('setMethod');
$this->assertTrue($method->isPublic());
}

/**
* Test PhpSIPException class structure and functionality
*/
public function testPhpSIPExceptionExists(): void
{
$this->assertTrue(class_exists('PhpSIPException'));

$reflection = new ReflectionClass('PhpSIPException');
$this->assertTrue($reflection->isSubclassOf('Exception'));
}
}