Skip to content
Merged
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
118 changes: 118 additions & 0 deletions includes/Services/KnowledgeBaseService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

namespace Escalated\Services;

use Escalated\Models\Setting;

class KnowledgeBaseService
{
/**
* Check if the knowledge base is enabled.
*/
public static function is_enabled(): bool
{
return Setting::get_bool('knowledge_base_enabled', true);
}

/**
* Check if the knowledge base is publicly accessible (no auth required).
*/
public static function is_public(): bool
{
return Setting::get_bool('knowledge_base_public', true);
}

/**
* Check if article feedback (helpful/not helpful) is enabled.
*/
public static function is_feedback_enabled(): bool
{
return Setting::get_bool('knowledge_base_feedback_enabled', true);
}

/**
* Get all KB settings as an array.
*
* @return array<string, bool>
*/
public static function get_settings(): array
{
return [
'knowledge_base_enabled' => self::is_enabled(),
'knowledge_base_public' => self::is_public(),
'knowledge_base_feedback_enabled' => self::is_feedback_enabled(),
];
}

/**
* Update KB settings.
*
* @param array $settings Settings to update.
*/
public static function update_settings(array $settings): void
{
$allowed = [
'knowledge_base_enabled',
'knowledge_base_public',
'knowledge_base_feedback_enabled',
];

foreach ($allowed as $key) {
if (isset($settings[$key])) {
Setting::set($key, $settings[$key] ? '1' : '0');
}
}
}

/**
* Guard check: should KB routes be accessible?
*
* Returns true if the KB is enabled. For public access, also checks
* knowledge_base_public or if user is authenticated.
*
* @param bool $require_auth Whether authentication is required.
*/
public static function can_access(bool $require_auth = false): bool
{
if (! self::is_enabled()) {
return false;
}

if ($require_auth) {
return is_user_logged_in();
}

// If KB is not public, require authentication.
if (! self::is_public()) {
return is_user_logged_in();
}

return true;
}

/**
* Permission callback for KB REST API routes.
*
* @return bool|\WP_Error
*/
public static function permission_check()
{
if (! self::is_enabled()) {
return new \WP_Error(
'escalated_kb_disabled',
__('Knowledge base is disabled.', 'escalated'),
['status' => 403]
);
}

if (! self::is_public() && ! is_user_logged_in()) {
return new \WP_Error(
'escalated_kb_private',
__('Knowledge base requires authentication.', 'escalated'),
['status' => 401]
);
}

return true;
}
}
216 changes: 216 additions & 0 deletions tests/Test_Knowledge_Base_Settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php

/**
* Tests for the KnowledgeBaseService toggle settings.
*
* Covers enabled/disabled checks, public/private access,
* feedback toggle, settings CRUD, and permission callbacks.
*/

use Escalated\Models\Setting;
use Escalated\Services\KnowledgeBaseService;

class Test_Knowledge_Base_Settings extends WP_UnitTestCase
{
public function set_up(): void
{
parent::set_up();

\Escalated\Activator::activate();
}

// =========================================================================
// Default Settings Tests
// =========================================================================

public function test_kb_enabled_by_default(): void
{
$this->assertTrue(KnowledgeBaseService::is_enabled());
}

public function test_kb_public_by_default(): void
{
$this->assertTrue(KnowledgeBaseService::is_public());
}

public function test_kb_feedback_enabled_by_default(): void
{
$this->assertTrue(KnowledgeBaseService::is_feedback_enabled());
}

// =========================================================================
// Toggle Tests
// =========================================================================

public function test_disable_knowledge_base(): void
{
Setting::set('knowledge_base_enabled', '0');

$this->assertFalse(KnowledgeBaseService::is_enabled());
}

public function test_enable_knowledge_base(): void
{
Setting::set('knowledge_base_enabled', '0');
Setting::set('knowledge_base_enabled', '1');

$this->assertTrue(KnowledgeBaseService::is_enabled());
}

public function test_make_kb_private(): void
{
Setting::set('knowledge_base_public', '0');

$this->assertFalse(KnowledgeBaseService::is_public());
}

public function test_disable_feedback(): void
{
Setting::set('knowledge_base_feedback_enabled', '0');

$this->assertFalse(KnowledgeBaseService::is_feedback_enabled());
}

// =========================================================================
// Get Settings Tests
// =========================================================================

public function test_get_settings_returns_all_keys(): void
{
$settings = KnowledgeBaseService::get_settings();

$this->assertArrayHasKey('knowledge_base_enabled', $settings);
$this->assertArrayHasKey('knowledge_base_public', $settings);
$this->assertArrayHasKey('knowledge_base_feedback_enabled', $settings);
}

public function test_get_settings_reflects_changes(): void
{
Setting::set('knowledge_base_enabled', '0');
Setting::set('knowledge_base_public', '0');
Setting::set('knowledge_base_feedback_enabled', '0');

$settings = KnowledgeBaseService::get_settings();

$this->assertFalse($settings['knowledge_base_enabled']);
$this->assertFalse($settings['knowledge_base_public']);
$this->assertFalse($settings['knowledge_base_feedback_enabled']);
}

// =========================================================================
// Update Settings Tests
// =========================================================================

public function test_update_settings(): void
{
KnowledgeBaseService::update_settings([
'knowledge_base_enabled' => false,
'knowledge_base_public' => false,
'knowledge_base_feedback_enabled' => false,
]);

$this->assertFalse(KnowledgeBaseService::is_enabled());
$this->assertFalse(KnowledgeBaseService::is_public());
$this->assertFalse(KnowledgeBaseService::is_feedback_enabled());
}

public function test_update_settings_ignores_unknown_keys(): void
{
KnowledgeBaseService::update_settings([
'unknown_setting' => 'value',
]);

// Should not throw or affect anything.
$this->assertTrue(KnowledgeBaseService::is_enabled());
}

// =========================================================================
// Access Guard Tests
// =========================================================================

public function test_can_access_when_enabled_and_public(): void
{
Setting::set('knowledge_base_enabled', '1');
Setting::set('knowledge_base_public', '1');

$this->assertTrue(KnowledgeBaseService::can_access());
}

public function test_cannot_access_when_disabled(): void
{
Setting::set('knowledge_base_enabled', '0');

$this->assertFalse(KnowledgeBaseService::can_access());
}

public function test_cannot_access_private_kb_without_auth(): void
{
Setting::set('knowledge_base_enabled', '1');
Setting::set('knowledge_base_public', '0');

// Not logged in.
wp_set_current_user(0);

$this->assertFalse(KnowledgeBaseService::can_access());
}

public function test_can_access_private_kb_with_auth(): void
{
Setting::set('knowledge_base_enabled', '1');
Setting::set('knowledge_base_public', '0');

$user_id = $this->factory->user->create(['role' => 'subscriber']);
wp_set_current_user($user_id);

$this->assertTrue(KnowledgeBaseService::can_access());
}

// =========================================================================
// Permission Callback Tests
// =========================================================================

public function test_permission_check_returns_error_when_disabled(): void
{
Setting::set('knowledge_base_enabled', '0');

$result = KnowledgeBaseService::permission_check();

$this->assertInstanceOf(\WP_Error::class, $result);
$this->assertEquals('escalated_kb_disabled', $result->get_error_code());
}

public function test_permission_check_returns_error_when_private_and_not_logged_in(): void
{
Setting::set('knowledge_base_enabled', '1');
Setting::set('knowledge_base_public', '0');
wp_set_current_user(0);

$result = KnowledgeBaseService::permission_check();

$this->assertInstanceOf(\WP_Error::class, $result);
$this->assertEquals('escalated_kb_private', $result->get_error_code());
}

public function test_permission_check_returns_true_when_enabled_and_public(): void
{
Setting::set('knowledge_base_enabled', '1');
Setting::set('knowledge_base_public', '1');

$result = KnowledgeBaseService::permission_check();

$this->assertTrue($result);
}

public function test_permission_check_returns_true_when_private_and_logged_in(): void
{
Setting::set('knowledge_base_enabled', '1');
Setting::set('knowledge_base_public', '0');

$user_id = $this->factory->user->create(['role' => 'subscriber']);
wp_set_current_user($user_id);

$result = KnowledgeBaseService::permission_check();

$this->assertTrue($result);
}
}
Loading