Skip to content

[ENHANCEMENT] Add PHPUnit tests for core business logic #57

@giovanny07

Description

@giovanny07

Plugin version: 3.2.6
GLPI version: 11.x
Priority: Low
Files: tests/ (to be created)

Summary

The plugin has no automated tests. The absence of tests allowed regressions like the wrong holiday count introduced in v3.1.5 (issue #31) to reach production undetected. Adding a basic PHPUnit suite for the most critical business logic would prevent regressions and make contributions safer to merge.

Recommended test coverage — priority order

1 — Report day-count calculation (highest value, issue #31)

This is the calculation that regressed between v3.1.2 and v3.1.5:

// tests/ReportTest.php
namespace GlpiPlugin\Activity\Tests;

use GlpiPlugin\Activity\Report;
use PHPUnit\Framework\TestCase;

class ReportTest extends TestCase
{
    /**
     * @dataProvider holidayDurationProvider
     */
    public function testHolidayDayCount(
        string $begin,
        string $end,
        string $beginSlot,  // 'am', 'pm', 'allday'
        string $endSlot,
        float $expectedDays
    ): void {
        $days = Report::calculateDays($begin, $end, $beginSlot, $endSlot);
        $this->assertEqualsWithDelta($expectedDays, $days, 0.01);
    }

    public static function holidayDurationProvider(): array
    {
        return [
            'same day allday'   => ['2025-01-06', '2025-01-06', 'allday', 'allday', 1.0],
            'same day morning'  => ['2025-01-06', '2025-01-06', 'am',     'allday', 0.5],
            'same day afternoon'=> ['2025-01-06', '2025-01-06', 'pm',     'allday', 0.5],
            '2 full days'       => ['2025-01-06', '2025-01-07', 'allday', 'allday', 2.0],
            '3 days with half'  => ['2025-01-06', '2025-01-08', 'pm',     'am',     2.0],
            'week skip weekend' => ['2025-01-06', '2025-01-10', 'allday', 'allday', 5.0], // Mon→Fri
            'span weekend'      => ['2025-01-06', '2025-01-13', 'allday', 'allday', 6.0], // Mon→Mon (skip weekend)
        ];
    }
}

2 — HolidayValidation state machine

// tests/HolidayValidationTest.php

class HolidayValidationTest extends TestCase
{
    public function testInitialStatusIsWaiting(): void
    {
        // New holidays should start in WAITING status
        $this->assertEquals(
            CommonValidation::WAITING,
            $this->createHoliday()->fields['status']
        );
    }

    public function testAcceptTransitionsToAccepted(): void
    {
        $validation = $this->createValidation();
        $validation->update(['id' => $validation->getID(), 'accept_holiday' => 1]);

        $this->assertEquals(CommonValidation::ACCEPTED, $this->getHolidayStatus());
    }

    public function testRefuseTransitionsToRefused(): void
    {
        $validation = $this->createValidation();
        $validation->update(['id' => $validation->getID(), 'refuse_holiday' => 1]);

        $this->assertEquals(CommonValidation::REFUSED, $this->getHolidayStatus());
    }
}

3 — Option::getInstance() fallback

// tests/OptionTest.php

class OptionTest extends TestCase
{
    public function testGetInstanceCreatesDefaultsIfMissing(): void
    {
        // Simulate missing options record
        global $DB;
        $DB->delete('glpi_plugin_activity_options', [true]);

        $opt = Option::getInstance();

        $this->assertIsArray($opt->fields);
        $this->assertArrayHasKey('use_timerepartition', $opt->fields);
    }
}

Setup

// composer.json — add to require-dev
{
    "require-dev": {
        "phpunit/phpunit": "^10.0"
    }
}
<!-- phpunit.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
         colors="true"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Activity Plugin">
            <directory>tests/</directory>
        </testsuite>
    </testsuites>
</phpunit>

Run tests:

composer install
./vendor/bin/phpunit

Notes

  • GLPI 11 provides a test bootstrap at tests/bootstrap.php that plugins can use to spin up a test GLPI instance. See [glpi-project/glpi](https://github.com/glpi-project/glpi/tree/main/tests) for reference.
  • Start with pure unit tests for calculation logic (no DB needed) before adding integration tests.
  • CI can be added via GitHub Actions using the existing GLPI plugin CI workflow template.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions