|
# HVAC Multi-Role Scenario Testing Plan

This document outlines the structure and guidance for implementing comprehensive multi-role scenario tests for the HVAC Role Manager Testing Framework, building upon existing components like `HVAC_Test_User_Factory` and `HVAC_Test_Data_Manager`.

## Plan Overview

The multi-role scenario tests will leverage the existing test framework components and transaction management to ensure isolated and reliable testing of complex role interactions.

**1. Test Structure and Organization**

*   **Dedicated Test Class:** Create a new test class, e.g., `HVAC_Multi_Role_Test`, extending `WP_UnitTestCase`. This class will house all tests specifically related to multi-role scenarios.
*   **Scenario-Based Methods:** Organize tests into methods that represent specific multi-role scenarios (e.g., `test_user_with_editor_and_trainer_roles_can_publish_events`, `test_role_conflict_resolution_for_event_editing`).
*   **Setup Method:** Utilize the `setUp` method to initialize `HVAC_Test_User_Factory` and `HVAC_Test_Data_Manager` and potentially start a transaction if not handled by a base class.
*   **Teardown Method:** Ensure the `tearDown` method rolls back the transaction and cleans up any created users or data using `HVAC_Test_Data_Manager`.

```mermaid
graph TD
    A[HVAC_Multi_Role_Test] --> B[setUp()]
    A --> C[test_scenario_X()]
    A --> D[test_scenario_Y()]
    A --> E[tearDown()]

    B --> F[Initialize Factories/Managers]
    B --> G[Start Transaction (if needed)]

    C --> H[Create User with Roles (HVAC_Test_User_Factory)]
    C --> I[Perform Actions/Checks]
    C --> J[Assert Expected Outcomes]

    E --> K[Rollback Transaction]
    E --> L[Cleanup Data/Users (HVAC_Test_Data_Manager)]
```

**2. Strategies for Testing Permission Inheritance and Conflict Resolution**

*   **Define Expected Capabilities:** For each multi-role combination, clearly define the expected set of capabilities based on the HVAC Role Manager's inheritance and conflict resolution logic.
*   **Create Users with Combinations:** Use `HVAC_Test_User_Factory` to create users with the specific role combinations being tested. The factory should handle assigning multiple roles.
*   **Verify Capabilities Directly:** After assigning roles, directly check the user's capabilities using WordPress functions like `user_can()` or `current_user_can()`.
*   **Test Actions Requiring Capabilities:** Beyond direct capability checks, test if the user can actually perform actions that require those capabilities (e.g., publishing an event, editing a specific post type).

*   **Pseudocode Example (Inheritance):**
    ```php
    // Assuming 'hvac_manager' inherits from 'editor'
    public function test_hvac_manager_inherits_editor_caps() {
        $user = HVAC_Test_User_Factory::get_instance()->create_test_user(['hvac_manager']);
        $this->assertTrue(user_can($user, 'edit_posts'), 'HVAC Manager should inherit edit_posts capability from Editor.');
        $this->assertTrue(user_can($user, 'publish_posts'), 'HVAC Manager should inherit publish_posts capability from Editor.');
        // Add more inherited capability checks
    }
    ```

*   **Pseudocode Example (Conflict Resolution):**
    ```php
    // Assuming 'role_A' grants 'cap_X' and 'role_B' denies 'cap_X', and 'role_A' has higher priority
    public function test_role_conflict_resolution_priority() {
        $user = HVAC_Test_User_Factory::get_instance()->create_test_user(['role_A', 'role_B']);
        $this->assertTrue(user_can($user, 'cap_X'), 'User with Role A and Role B should have cap_X due to Role A priority.');

        // Test the opposite priority if applicable
        // $user_b_a = HVAC_Test_User_Factory::get_instance()->create_test_user(['role_B', 'role_A']);
        // $this->assertFalse(user_can($user_b_a, 'cap_X'), 'User with Role B and Role A should NOT have cap_X due to Role B priority.');
    }
    ```

**3. Approaches for Verifying Capability Checks Across Role Combinations**

*   **Matrix Approach:** Consider creating a matrix of relevant capabilities vs. role combinations. Each cell in the matrix represents an assertion that needs to be tested.
*   **Iterate Through Combinations:** Programmatically generate or define the key role combinations to test.
*   **Contextual Checks:** Test capabilities within the context they are used (e.g., can a user with roles X and Y edit *this specific* event?). This might involve creating test data using `HVAC_Test_Data_Manager`.

*   **Pseudocode Example (Capability Matrix Idea):**
    ```php
    public function test_capability_matrix() {
        $role_combinations = [
            ['editor', 'hvac_trainer'],
            ['administrator', 'hvac_viewer'],
            // Add all relevant combinations
        ];

        $capabilities_to_check = [
            'publish_tribe_events' => [
                'editor,hvac_trainer' => true,
                'administrator,hvac_viewer' => true, // Example expected outcome
            ],
            'view_hvac_reports' => [
                'editor,hvac_trainer' => false,
                'administrator,hvac_viewer' => true,
            ],
            // Add all relevant capabilities
        ];

        foreach ($role_combinations as $roles) {
            $user = HVAC_Test_User_Factory::get_instance()->create_test_user($roles);
            $combination_key = implode(',', $roles);

            foreach ($capabilities_to_check as $capability => $expected_outcomes) {
                if (isset($expected_outcomes[$combination_key])) {
                    $expected = $expected_outcomes[$combination_key];
                    $message = "User with roles {$combination_key} should " . ($expected ? "have" : "not have") . " capability {$capability}.";
                    $this->assertEquals($expected, user_can($user, $capability), $message);
                }
            }
        }
    }
    ```

**4. Best Practices for Testing Role Addition and Removal**

*   **Test Sequential Changes:** Test adding a role to an existing user and then removing it, verifying capabilities at each step.
*   **Edge Cases:**
    *   Adding a role the user already has.
    *   Removing a role the user doesn't have.
    *   Removing the user's last role (should they revert to a default?).
    *   Adding/removing roles that are part of an inheritance chain.
*   **Verify Persistence:** Ensure role changes persist after the operation (within the test's transaction).

*   **Pseudocode Example (Role Addition/Removal):**
    ```php
    public function test_role_addition_and_removal() {
        $user = HVAC_Test_User_Factory::get_instance()->create_test_user(['subscriber']);
        $this->assertFalse(user_can($user, 'publish_posts'), 'Subscriber should not publish posts initially.');

        // Add editor role
        $user->add_role('editor');
        $user = new WP_User($user->ID); // Reload user object to refresh capabilities
        $this->assertTrue(user_can($user, 'publish_posts'), 'User should publish posts after adding editor role.');

        // Remove editor role
        $user->remove_role('editor');
        $user = new WP_User($user->ID); // Reload user object
        $this->assertFalse(user_can($user, 'publish_posts'), 'User should not publish posts after removing editor role.');
    }
    ```

**Compatibility with WordPress Testing and Architecture:**

*   The proposed structure uses `WP_UnitTestCase`, which is the standard for WordPress plugin unit testing.
*   Leveraging `HVAC_Test_User_Factory` and `HVAC_Test_Data_Manager` ensures integration with the existing framework components.
*   Using WordPress core functions like `user_can()`, `add_role()`, and `remove_role()` aligns with WordPress best practices.
*   Transaction management by `HVAC_Test_Data_Manager` provides necessary test isolation.