Skip to content

Commit b2720bc

Browse files
feat(install): add InstallationCompletedEvent for post-installation hooks
Add InstallationCompletedEvent class in public API (OCP namespace) that provides installation details: data directory, admin username, and admin email. Event will be dispatched after successful installation. Include comprehensive unit tests covering all event scenarios. Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
1 parent 49d8957 commit b2720bc

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
namespace OCP\Install\Events;
10+
11+
use OCP\EventDispatcher\Event;
12+
13+
/**
14+
* Emitted when the Nextcloud installation has been completed successfully.
15+
*
16+
* This event is dispatched after:
17+
* - The database has been configured and migrations have run
18+
* - The admin user has been created (if applicable)
19+
* - Default apps have been installed
20+
* - Background jobs have been configured
21+
* - The system has been marked as installed
22+
*
23+
* Apps can listen to this event to perform additional actions after installation,
24+
* such as:
25+
* - Sending notification emails
26+
* - Triggering external APIs
27+
* - Initializing app-specific data
28+
* - Setting up integrations
29+
*
30+
* @since 33.0.0
31+
*/
32+
class InstallationCompletedEvent extends Event {
33+
/**
34+
* @since 33.0.0
35+
*/
36+
public function __construct(
37+
private string $dataDirectory,
38+
private ?string $adminUsername = null,
39+
private ?string $adminEmail = null,
40+
) {
41+
parent::__construct();
42+
}
43+
44+
/**
45+
* Get the configured data directory path
46+
*
47+
* @since 33.0.0
48+
*/
49+
public function getDataDirectory(): string {
50+
return $this->dataDirectory;
51+
}
52+
53+
/**
54+
* Get the admin username if an admin user was created
55+
*
56+
* @since 33.0.0
57+
*/
58+
public function getAdminUsername(): ?string {
59+
return $this->adminUsername;
60+
}
61+
62+
/**
63+
* Get the admin email if configured
64+
*
65+
* @since 33.0.0
66+
*/
67+
public function getAdminEmail(): ?string {
68+
return $this->adminEmail;
69+
}
70+
71+
/**
72+
* Check if an admin user was created during installation
73+
*
74+
* @since 33.0.0
75+
*/
76+
public function hasAdminUser(): bool {
77+
return $this->adminUsername !== null;
78+
}
79+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace Test\Install\Events;
11+
12+
use OCP\Install\Events\InstallationCompletedEvent;
13+
14+
class InstallationCompletedEventTest extends \Test\TestCase {
15+
public function testConstructorWithAllParameters(): void {
16+
$dataDir = '/path/to/data';
17+
$adminUsername = 'admin';
18+
$adminEmail = 'admin@example.com';
19+
20+
$event = new InstallationCompletedEvent($dataDir, $adminUsername, $adminEmail);
21+
22+
$this->assertEquals($dataDir, $event->getDataDirectory());
23+
$this->assertEquals($adminUsername, $event->getAdminUsername());
24+
$this->assertEquals($adminEmail, $event->getAdminEmail());
25+
$this->assertTrue($event->hasAdminUser());
26+
}
27+
28+
public function testConstructorWithMinimalParameters(): void {
29+
$dataDir = '/path/to/data';
30+
31+
$event = new InstallationCompletedEvent($dataDir);
32+
33+
$this->assertEquals($dataDir, $event->getDataDirectory());
34+
$this->assertNull($event->getAdminUsername());
35+
$this->assertNull($event->getAdminEmail());
36+
$this->assertFalse($event->hasAdminUser());
37+
}
38+
39+
public function testConstructorWithUsernameOnly(): void {
40+
$dataDir = '/path/to/data';
41+
$adminUsername = 'admin';
42+
43+
$event = new InstallationCompletedEvent($dataDir, $adminUsername);
44+
45+
$this->assertEquals($dataDir, $event->getDataDirectory());
46+
$this->assertEquals($adminUsername, $event->getAdminUsername());
47+
$this->assertNull($event->getAdminEmail());
48+
$this->assertTrue($event->hasAdminUser());
49+
}
50+
51+
public function testConstructorWithUsernameAndEmail(): void {
52+
$dataDir = '/path/to/data';
53+
$adminUsername = 'admin';
54+
$adminEmail = 'admin@example.com';
55+
56+
$event = new InstallationCompletedEvent($dataDir, $adminUsername, $adminEmail);
57+
58+
$this->assertEquals($dataDir, $event->getDataDirectory());
59+
$this->assertEquals($adminUsername, $event->getAdminUsername());
60+
$this->assertEquals($adminEmail, $event->getAdminEmail());
61+
$this->assertTrue($event->hasAdminUser());
62+
}
63+
64+
public function testHasAdminUserReturnsFalseWhenUsernameIsNull(): void {
65+
$event = new InstallationCompletedEvent('/path/to/data', null, 'admin@example.com');
66+
67+
$this->assertFalse($event->hasAdminUser());
68+
$this->assertNull($event->getAdminUsername());
69+
$this->assertEquals('admin@example.com', $event->getAdminEmail());
70+
}
71+
72+
public function testDataDirectoryCanBeAnyString(): void {
73+
$customPath = '/custom/data/directory';
74+
$event = new InstallationCompletedEvent($customPath);
75+
76+
$this->assertEquals($customPath, $event->getDataDirectory());
77+
}
78+
79+
public function testEmailCanBeSetWithoutUsername(): void {
80+
$dataDir = '/path/to/data';
81+
$email = 'admin@example.com';
82+
83+
$event = new InstallationCompletedEvent($dataDir, null, $email);
84+
85+
$this->assertNull($event->getAdminUsername());
86+
$this->assertEquals($email, $event->getAdminEmail());
87+
$this->assertFalse($event->hasAdminUser());
88+
}
89+
}

0 commit comments

Comments
 (0)