Skip to content

Commit 96c0ded

Browse files
committed
updates adding tests in and updating readme/composer file
1 parent b4cee0d commit 96c0ded

7 files changed

Lines changed: 1394 additions & 587 deletions

File tree

.github/workflows/tests.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
jobs:
10+
tests:
11+
name: PHP ${{ matrix.php-version }}
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
php-version: ['8.2', '8.3', '8.4']
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup PHP
24+
uses: shivammathur/setup-php@v2
25+
with:
26+
php-version: ${{ matrix.php-version }}
27+
extensions: soap, xml, curl, mbstring
28+
coverage: xdebug
29+
30+
- name: Install dependencies
31+
run: composer install --prefer-dist --no-progress --no-interaction
32+
33+
- name: Run tests
34+
run: vendor/bin/phpunit --colors=always
35+
36+
- name: Run tests with coverage
37+
if: matrix.php-version == '8.2'
38+
run: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.xml

README.md

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,45 @@
1-
# Plesk Webhosting Class
1+
# MyAdmin Plesk Webhosting Plugin
22

3-
Plesk Webhosting Class
3+
[![Tests](https://github.com/detain/myadmin-plesk-webhosting/actions/workflows/tests.yml/badge.svg)](https://github.com/detain/myadmin-plesk-webhosting/actions/workflows/tests.yml)
4+
[![Latest Stable Version](https://poser.pugx.org/detain/myadmin-plesk-webhosting/version)](https://packagist.org/packages/detain/myadmin-plesk-webhosting)
5+
[![Total Downloads](https://poser.pugx.org/detain/myadmin-plesk-webhosting/downloads)](https://packagist.org/packages/detain/myadmin-plesk-webhosting)
6+
[![License](https://poser.pugx.org/detain/myadmin-plesk-webhosting/license)](https://packagist.org/packages/detain/myadmin-plesk-webhosting)
47

5-
## Build Status and Code Analysis
8+
A MyAdmin plugin that provides Plesk control panel integration for automated webhosting provisioning and lifecycle management. It communicates with the Plesk XML API to handle account creation, suspension, reactivation, termination, and IP management operations.
69

7-
Site | Status
8-
--------------|---------------------------
9-
![Travis-CI](http://i.is.cc/storage/GYd75qN.png "Travis-CI") | [![Build Status](https://travis-ci.org/detain/myadmin-plesk-webhosting.svg?branch=master)](https://travis-ci.org/detain/myadmin-plesk-webhosting)
10-
![CodeClimate](http://i.is.cc/storage/GYlageh.png "CodeClimate") | [![Code Climate](https://codeclimate.com/github/detain/myadmin-plesk-webhosting/badges/gpa.svg)](https://codeclimate.com/github/detain/myadmin-plesk-webhosting) [![Test Coverage](https://codeclimate.com/github/detain/myadmin-plesk-webhosting/badges/coverage.svg)](https://codeclimate.com/github/detain/myadmin-plesk-webhosting/coverage) [![Issue Count](https://codeclimate.com/github/detain/myadmin-plesk-webhosting/badges/issue_count.svg)](https://codeclimate.com/github/detain/myadmin-plesk-webhosting)
11-
![Scrutinizer](http://i.is.cc/storage/GYeUnux.png "Scrutinizer") | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/myadmin-plugins/plesk-webhosting/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/myadmin-plugins/plesk-webhosting/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/myadmin-plugins/plesk-webhosting/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/myadmin-plugins/plesk-webhosting/?branch=master) [![Build Status](https://scrutinizer-ci.com/g/myadmin-plugins/plesk-webhosting/badges/build.png?b=master)](https://scrutinizer-ci.com/g/myadmin-plugins/plesk-webhosting/build-status/master)
12-
![Codacy](http://i.is.cc/storage/GYi66Cx.png "Codacy") | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/226251fc068f4fd5b4b4ef9a40011d06)](https://www.codacy.com/app/detain/myadmin-plesk-webhosting) [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/25fa74eb74c947bf969602fcfe87e349)](https://www.codacy.com/app/detain/myadmin-plesk-webhosting?utm_source=github.com&utm_medium=referral&utm_content=detain/myadmin-plesk-webhosting&utm_campaign=Badge_Coverage)
13-
![Coveralls](http://i.is.cc/storage/GYjNSim.png "Coveralls") | [![Coverage Status](https://coveralls.io/repos/github/detain/db_abstraction/badge.svg?branch=master)](https://coveralls.io/github/detain/myadmin-plesk-webhosting?branch=master)
14-
![Packagist](http://i.is.cc/storage/GYacBEX.png "Packagist") | [![Latest Stable Version](https://poser.pugx.org/detain/myadmin-plesk-webhosting/version)](https://packagist.org/packages/detain/myadmin-plesk-webhosting) [![Total Downloads](https://poser.pugx.org/detain/myadmin-plesk-webhosting/downloads)](https://packagist.org/packages/detain/myadmin-plesk-webhosting) [![Latest Unstable Version](https://poser.pugx.org/detain/myadmin-plesk-webhosting/v/unstable)](//packagist.org/packages/detain/myadmin-plesk-webhosting) [![Monthly Downloads](https://poser.pugx.org/detain/myadmin-plesk-webhosting/d/monthly)](https://packagist.org/packages/detain/myadmin-plesk-webhosting) [![Daily Downloads](https://poser.pugx.org/detain/myadmin-plesk-webhosting/d/daily)](https://packagist.org/packages/detain/myadmin-plesk-webhosting) [![License](https://poser.pugx.org/detain/myadmin-plesk-webhosting/license)](https://packagist.org/packages/detain/myadmin-plesk-webhosting)
10+
## Features
1511

12+
- Automated webhosting account provisioning via the Plesk XML API
13+
- Full service lifecycle management (activate, deactivate, reactivate, terminate)
14+
- Client and subscription CRUD operations
15+
- Site, database, email, and DNS management
16+
- Service plan listing and assignment
17+
- IP address management and migration
18+
- Event-driven architecture using Symfony EventDispatcher
19+
20+
## Requirements
21+
22+
- PHP >= 8.2
23+
- ext-soap
24+
- ext-curl
25+
- ext-xml
26+
- ext-mbstring
1627

1728
## Installation
1829

19-
Install with composer like
30+
Install with Composer:
2031

2132
```sh
2233
composer require detain/myadmin-plesk-webhosting
2334
```
2435

25-
## License
36+
## Testing
2637

27-
The Plesk Webhosting Class class is licensed under the LGPL-v2.1 license.
38+
```sh
39+
composer install
40+
vendor/bin/phpunit
41+
```
42+
43+
## License
2844

45+
This package is licensed under the LGPL-2.1-only license.

composer.json

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,50 @@
11
{
22
"name": "detain/myadmin-plesk-webhosting",
33
"type": "myadmin-plugin",
4-
"description": "Plesk Webhosting Class",
4+
"description": "MyAdmin Plesk Webhosting Plugin - Provides Plesk control panel integration for automated webhosting provisioning, management, and lifecycle operations including account creation, suspension, and termination via the Plesk XML API.",
55
"keywords": [
66
"plesk",
7-
"administration",
8-
"license"
7+
"webhosting",
8+
"myadmin",
9+
"control-panel",
10+
"provisioning",
11+
"api"
912
],
1013
"license": "LGPL-2.1-only",
1114
"authors": [
1215
{
1316
"name": "Joe Huss",
14-
"homepage": "https:\/\/my.interserver.net\/"
17+
"homepage": "https://my.interserver.net/"
1518
}
1619
],
1720
"config": {
18-
"bin-dir": "vendor\/bin",
19-
"minimum-stability": "dev"
21+
"bin-dir": "vendor/bin",
22+
"minimum-stability": "dev",
23+
"allow-plugins": {
24+
"detain/myadmin-plugin-installer": true
25+
}
2026
},
2127
"require": {
22-
"php": ">=5.0.0",
28+
"php": ">=8.2",
2329
"ext-soap": "*",
24-
"symfony/event-dispatcher": "^5.0@stable",
30+
"symfony/event-dispatcher": "^5.0 || ^6.0 || ^7.0",
2531
"detain/myadmin-plugin-installer": "dev-master"
26-
},
32+
},
2733
"require-dev": {
28-
"phpunit/phpunit": "*",
29-
"phpunit/phpunit-mock-objects": "*",
30-
"vlucas/phpdotenv": "*",
31-
"codeclimate/php-test-reporter": "dev-master",
32-
"satooshi/php-coveralls": "*",
33-
"codacy/coverage": "dev-master"
34+
"phpunit/phpunit": "^9.6"
3435
},
3536
"autoload": {
3637
"psr-4": {
3738
"Detain\\MyAdminPlesk\\": "src/"
3839
}
40+
},
41+
"autoload-dev": {
42+
"psr-4": {
43+
"Detain\\MyAdminPlesk\\Tests\\": "tests/"
44+
}
45+
},
46+
"scripts": {
47+
"test": "phpunit",
48+
"test-coverage": "phpunit --coverage-text"
3949
}
4050
}

phpunit.xml.dist

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
verbose="true"
7+
failOnRisky="true"
8+
failOnWarning="true"
9+
beStrictAboutOutputDuringTests="true"
10+
beStrictAboutTestsThatDoNotTestAnything="true">
11+
<testsuites>
12+
<testsuite name="Unit">
13+
<directory suffix="Test.php">tests</directory>
14+
</testsuite>
15+
</testsuites>
16+
<coverage processUncoveredFiles="true">
17+
<include>
18+
<directory suffix=".php">src</directory>
19+
</include>
20+
</coverage>
21+
</phpunit>

tests/ApiRequestExceptionTest.php

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Detain\MyAdminPlesk\Tests;
6+
7+
use Detain\MyAdminPlesk\ApiRequestException;
8+
use PHPUnit\Framework\TestCase;
9+
use ReflectionClass;
10+
11+
/**
12+
* Unit tests for the ApiRequestException class.
13+
*
14+
* Tests verify correct class hierarchy, instantiation, and
15+
* exception behavior.
16+
*/
17+
class ApiRequestExceptionTest extends TestCase
18+
{
19+
/**
20+
* @var ReflectionClass<ApiRequestException>
21+
*/
22+
private ReflectionClass $reflection;
23+
24+
/**
25+
* Set up reflection for each test.
26+
*
27+
* @return void
28+
*/
29+
protected function setUp(): void
30+
{
31+
parent::setUp();
32+
$this->reflection = new ReflectionClass(ApiRequestException::class);
33+
}
34+
35+
/**
36+
* Verify the ApiRequestException class exists.
37+
*
38+
* @return void
39+
*/
40+
public function testClassExists(): void
41+
{
42+
$this->assertTrue(class_exists(ApiRequestException::class));
43+
}
44+
45+
/**
46+
* Verify the class resides in the correct namespace.
47+
*
48+
* @return void
49+
*/
50+
public function testClassNamespace(): void
51+
{
52+
$this->assertSame('Detain\MyAdminPlesk', $this->reflection->getNamespaceName());
53+
}
54+
55+
/**
56+
* Verify ApiRequestException extends the base Exception class.
57+
*
58+
* @return void
59+
*/
60+
public function testExtendsException(): void
61+
{
62+
$this->assertTrue($this->reflection->isSubclassOf(\Exception::class));
63+
}
64+
65+
/**
66+
* Verify ApiRequestException implements Throwable.
67+
*
68+
* @return void
69+
*/
70+
public function testImplementsThrowable(): void
71+
{
72+
$this->assertTrue($this->reflection->implementsInterface(\Throwable::class));
73+
}
74+
75+
/**
76+
* Verify the exception can be instantiated with a message.
77+
*
78+
* @return void
79+
*/
80+
public function testCanBeInstantiatedWithMessage(): void
81+
{
82+
$exception = new ApiRequestException('Test error message');
83+
$this->assertSame('Test error message', $exception->getMessage());
84+
}
85+
86+
/**
87+
* Verify the exception can be instantiated with a message and code.
88+
*
89+
* @return void
90+
*/
91+
public function testCanBeInstantiatedWithMessageAndCode(): void
92+
{
93+
$exception = new ApiRequestException('Connection failed', 7);
94+
$this->assertSame('Connection failed', $exception->getMessage());
95+
$this->assertSame(7, $exception->getCode());
96+
}
97+
98+
/**
99+
* Verify the exception can be instantiated with no arguments.
100+
*
101+
* @return void
102+
*/
103+
public function testCanBeInstantiatedWithNoArguments(): void
104+
{
105+
$exception = new ApiRequestException();
106+
$this->assertSame('', $exception->getMessage());
107+
$this->assertSame(0, $exception->getCode());
108+
}
109+
110+
/**
111+
* Verify the exception can be thrown and caught.
112+
*
113+
* @return void
114+
*/
115+
public function testCanBeThrownAndCaught(): void
116+
{
117+
$this->expectException(ApiRequestException::class);
118+
$this->expectExceptionMessage('API request failed');
119+
throw new ApiRequestException('API request failed');
120+
}
121+
122+
/**
123+
* Verify the exception can be caught as a base Exception.
124+
*
125+
* @return void
126+
*/
127+
public function testCanBeCaughtAsBaseException(): void
128+
{
129+
$caught = false;
130+
try {
131+
throw new ApiRequestException('test');
132+
} catch (\Exception $e) {
133+
$caught = true;
134+
$this->assertInstanceOf(ApiRequestException::class, $e);
135+
}
136+
$this->assertTrue($caught);
137+
}
138+
139+
/**
140+
* Verify the exception supports a previous exception in the chain.
141+
*
142+
* @return void
143+
*/
144+
public function testSupportsPreviousException(): void
145+
{
146+
$previous = new \RuntimeException('Root cause');
147+
$exception = new ApiRequestException('Wrapper', 0, $previous);
148+
$this->assertSame($previous, $exception->getPrevious());
149+
}
150+
151+
/**
152+
* Verify the class is not abstract.
153+
*
154+
* @return void
155+
*/
156+
public function testClassIsNotAbstract(): void
157+
{
158+
$this->assertFalse($this->reflection->isAbstract());
159+
}
160+
161+
/**
162+
* Verify the class is not final.
163+
*
164+
* @return void
165+
*/
166+
public function testClassIsNotFinal(): void
167+
{
168+
$this->assertFalse($this->reflection->isFinal());
169+
}
170+
}

0 commit comments

Comments
 (0)