Test Failed
Push — main ( 99efcd...df6632 )
by Alex
14:53
created

HandleTakeTest::testProcessActionTakeItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 30
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 45
rs 9.44
1
<?php
2
3
namespace App\Tests\Adventure;
4
5
use App\Adventure\Game;
6
use App\Adventure\Location;
7
use App\Adventure\Inventory;
8
use App\Adventure\Item;
9
use App\Adventure\InputActions\TakeAction;
10
use PHPUnit\Framework\TestCase;
11
12
/**
13
 * Unit tests for Game class. Specifically testing 'take' action.
14
 */
15
class HandleTakeTest extends TestCase
16
{
17
    /**
18
     * @var Game
19
     */
20
    private $game;
21
22
    protected function setUp(): void
23
    {
24
        $this->game = new Game();
25
    }
26
27
    /**
28
     * Test case for processAction method with input action 'take'.
29
     */
30
    public function testProcessActionTakeItem(): void
31
    {
32
        // Create and configure take action mock
33
        $action = $this->createMock(TakeAction::class);
34
        $action->method('getTextResponse')->willReturn('You take the key.');
35
36
        // Create and configure item mock
37
        $item = $this->createMock(Item::class);
38
        $item->method('hasAction')->with('take')->willReturn(true);
39
        $item->method('getAction')->with('take')->willReturn($action);
40
        $item->method('getName')->willReturn('key');
41
42
        // Configure location mock to find the item
43
        $location = $this->createMock(Location::class);
44
        $location->expects($this->once())
45
            ->method('hasItem')
46
            ->with('key')
47
            ->willReturn(true);
48
49
        $location->expects($this->once())
50
            ->method('getItem')
51
            ->with('key')
52
            ->willReturn($item);
53
54
        $location->expects($this->once())
55
            ->method('removeItem')
56
            ->with($item);
57
58
        $inventory = $this->createMock(Inventory::class);
59
        $inventory->expects($this->once())
60
            ->method('hasItem')
61
            ->with('key')
62
            ->willReturn(false); // Item NOT in inventory
63
64
        // Expect item to be added exactly once
65
        $inventory->expects($this->once())
66
            ->method('addItem')
67
            ->with($item);
68
69
        $this->game->setInventory($inventory);
70
        $this->game->setCurrentLocation($location);
71
72
        // Assert that the same take message is returned
73
        $response = $this->game->processAction('take', 'key');
74
        $this->assertSame("You take the key.", $response);
75
    }
76
77
    /**
78
     * Test case for processAction method with 'take' with item already in inventory.
79
     */
80
    public function testProcessActionTakeItemAlreadyInInventory(): void
81
    {
82
        // Create and configure take action mock
83
        $action = $this->createMock(TakeAction::class);
84
        $action->method('getTextResponse')->willReturn('You take the key.');
85
86
        // Create and configure item mock
87
        $item = $this->createMock(Item::class);
88
        $item->method('hasAction')->with('take')->willReturn(true);
89
        $item->method('getAction')->with('take')->willReturn($action);
90
        $item->method('getName')->willReturn('key');
91
92
        // Configure location mock to find the item
93
        $location = $this->createMock(Location::class);
94
        $location->method('hasItem')
95
            ->with('key')
96
            ->willReturn(true);
97
98
        $location->method('getItem')
99
            ->with('key')
100
            ->willReturn($item);
101
102
        // Configure inventory mock to already have the item
103
        $inventory = $this->createMock(Inventory::class);
104
        $inventory->expects($this->once())
105
            ->method('hasItem')
106
            ->with('key')
107
            ->willReturn(true);
108
109
        // Expect item to NOT get removed/added
110
        $location->expects($this->never())
111
            ->method('removeItem');
112
113
        $inventory->expects($this->never())
114
            ->method('addItem');
115
116
        // Perform action
117
        $this->game->setCurrentLocation($location);
118
        $this->game->setInventory($inventory);
119
        $response = $this->game->processAction('take', 'key');
120
121
        // Assert error message is returned
122
        $this->assertSame('The key has already been added to your inventory.', $response);
123
    }
124
}
125