Skip to content

Commit 14e0087

Browse files
committed
(qa): add more tests and some cleanup
Signed-off-by: Benjamin Fahl <[email protected]>
1 parent fbb1c5c commit 14e0087

File tree

10 files changed

+239
-17
lines changed

10 files changed

+239
-17
lines changed

src/Collection/LightBulbs.php

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use IKEA\Tradfri\Device\LightBulb;
1818
use IKEA\Tradfri\Device\SwitchableInterface;
1919

20-
2120
/**
2221
* @method self createFrom(array $elements)
2322
*

src/Device/Helper/Type.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public function buildFrom(string $typeAttribute, int $deviceId, bool $buildUnkno
164164
$modelClass = \str_replace('is', '', $method);
165165

166166
if ('isUnknownDeviceType' === $method && $buildUnknownDevice) {
167-
$modelClass = 'Unknown';
167+
$modelClass = 'UnknownDevice';
168168
}
169169

170170
$fqdnClassName = '\\IKEA\\Tradfri\\Device\\' . $modelClass;

src/Device/RollerBlind.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public function open(): bool
4646
*/
4747
public function setToPosition(int $level): bool
4848
{
49-
return $this->getService()->setRollerBlindPosition($this, $level);
49+
$wasSet = $this->getService()->setRollerBlindPosition($this, $level);
50+
if ($wasSet) {
51+
$this->setDarkenedState($level);
52+
}
53+
54+
return $wasSet;
5055
}
5156
}

src/Device/Unknown.php src/Device/UnknownDevice.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
namespace IKEA\Tradfri\Device;
1515

16-
final class Unknown extends Device
16+
final class UnknownDevice extends Device
1717
{
1818
/**
1919
* @throws \IKEA\Tradfri\Exception\RuntimeException
@@ -22,7 +22,7 @@ public function __construct(int $deviceId, string $type)
2222
{
2323
parent::__construct(
2424
$deviceId,
25-
'TRADFRI unknown' . $type,
25+
'unknown' . $type,
2626
);
2727
}
2828
}

src/Dto/CoapGatewayRequestPayloadDto.php

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public function __construct(
3434
private string $target,
3535
private string $endpoint,
3636
private float|int|string $value,
37-
3837
) {
3938
}
4039

src/Factory/GatewayServiceFactory.php

+11-8
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ public function __construct(
2727

2828
public function __invoke(): ServiceInterface
2929
{
30-
$deviceMapper = new \IKEA\Tradfri\Mapper\DeviceData();
31-
$groupMapper = new \IKEA\Tradfri\Mapper\GroupData();
32-
$commands = new GatewayHelperCommands(
33-
$this->authConfig,
30+
return new \IKEA\Tradfri\Service\GatewayApiService(
31+
client: new \IKEA\Tradfri\Client\Client(
32+
adapter: new Adapter(
33+
authConfig: $this->authConfig,
34+
commands: new GatewayHelperCommands(
35+
authConfig: $this->authConfig,
36+
),
37+
deviceDataMapper: new \IKEA\Tradfri\Mapper\DeviceData(),
38+
groupDataMapper: new \IKEA\Tradfri\Mapper\GroupData(),
39+
),
40+
),
3441
);
35-
$adapter = new Adapter(authConfig: $this->authConfig, commands: $commands, deviceDataMapper: $deviceMapper, groupDataMapper: $groupMapper);
36-
$client = new \IKEA\Tradfri\Client\Client($adapter);
37-
38-
return new \IKEA\Tradfri\Service\GatewayApiService($client);
3942
}
4043
}

src/Traits/ProvidesDarkenedState.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ trait ProvidesDarkenedState
1919

2020
public function setDarkenedState(int $state): self
2121
{
22-
$this->darkenedState = $state;
22+
$this->darkenedState = \max(0, $state);
2323

2424
return $this;
2525
}

tests/Unit/Tradfri/Adapter/CoapTest.php

+54
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515

1616
use IKEA\Tradfri\Adapter\CoapAdapter;
1717
use IKEA\Tradfri\Device\MotionSensor;
18+
use IKEA\Tradfri\Device\UnknownDevice;
1819
use IKEA\Tradfri\Dto\CoapGatewayAuthConfigDto;
1920
use IKEA\Tradfri\Dto\CoapResponse\DeviceDto;
2021
use IKEA\Tradfri\Dto\CoapResponse\DeviceInfoDto;
2122
use IKEA\Tradfri\Dto\CoapResponse\LightControlDto;
2223
use IKEA\Tradfri\Helper\CommandRunnerInterface as Runner;
2324
use IKEA\Tradfri\Mapper\DeviceData;
2425
use IKEA\Tradfri\Mapper\GroupData;
26+
use IKEA\Tradfri\Service\ServiceInterface;
2527
use PHPUnit\Framework\TestCase;
2628
use WMDE\PsrLogTestDoubles\LoggerSpy;
2729

@@ -247,6 +249,58 @@ public function testGetDevicesDataWithRawJsonMixedResponse(): void
247249
$this->assertSame($blubDeviceDto->getLightControl()->getColorHex(), $lightDevice->getLightControl()->getColorHex());
248250
}
249251

252+
public function testGetDevicesCollectionWithValidJson(): void
253+
{
254+
// Arrange
255+
$deviceJson = /** @lang JSON */ <<<'DEVICE_JSON'
256+
{
257+
"ATTR_ID": 12,
258+
"ATTR_NAME": "name",
259+
"ATTR_DEVICE_INFO": {
260+
"ATTR_DEVICE_MANUFACTURER": "manufacturer",
261+
"ATTR_DEVICE_FIRMWARE_VERSION": "version",
262+
"ATTR_DEVICE_MODEL_NUMBER": "type"
263+
}
264+
}
265+
DEVICE_JSON;
266+
267+
$runner = mock(Runner::class);
268+
$runner
269+
->expects('execWithTimeout')
270+
->with('coap-client -m get -u "mocked-user" -k "mocked-api-key" "coaps://127.0.0.1:5684/15001"', 1, true)
271+
->andReturn(['[5000]']);
272+
273+
$runner
274+
->expects('execWithTimeout')
275+
->with('coap-client -m get -u "mocked-user" -k "mocked-api-key" "coaps://127.0.0.1:5684/15001/5000"', 1, true)
276+
->andReturn([$deviceJson]);
277+
278+
$adapter = new CoapAdapter(
279+
$this->getGatewayAuthConfigDto(),
280+
$this->buildCoapsCommandsWrapper(),
281+
new DeviceData(),
282+
new GroupData(),
283+
$runner,
284+
);
285+
286+
$deviceData = new DeviceInfoDto('manufacturer', 'unknowntype', 'version');
287+
$deviceDto = new DeviceDto(12, 'name', $deviceData, null);
288+
289+
$service = mock(ServiceInterface::class);
290+
// Act
291+
$deviceCollection = $adapter->getDeviceCollection($service);
292+
// Assert
293+
$this->assertCount(1, $deviceCollection);
294+
$device = $deviceCollection->first();
295+
296+
$this->assertInstanceOf(UnknownDevice::class, $device);
297+
$this->assertSame($deviceDto->getId(), $device->getId());
298+
$this->assertSame($deviceDto->getName(), $device->getName());
299+
$this->assertSame($deviceDto->getDeviceInfo()->getManufacturer(), $device->getManufacturer());
300+
$this->assertSame($deviceDto->getDeviceInfo()->getType(), $device->getType());
301+
$this->assertSame($deviceDto->getDeviceInfo()->getVersion(), $device->getVersion());
302+
}
303+
250304
public function testGetType(): void
251305
{
252306
// Arrange

tests/Unit/Tradfri/Device/Helper/TypeTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
use IKEA\Tradfri\Command\Coap\Keys;
1717
use IKEA\Tradfri\Device\Helper\Type;
18-
use IKEA\Tradfri\Device\Unknown;
18+
use IKEA\Tradfri\Device\UnknownDevice;
1919

2020
/**
2121
* Class TypeTest.
@@ -244,7 +244,7 @@ public function testBuildFromUnknownClass(): void
244244

245245
// Assert
246246
$this->assertNotNull($model);
247-
$this->assertInstanceOf(Unknown::class, $model);
247+
$this->assertInstanceOf(UnknownDevice::class, $model);
248248
}
249249

250250
public function testBuildFromNoUnknownClassAndSeeError(): void
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* Copyright (c) 2024 Benjamin Fahl
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE.md file that was distributed with this source code.
10+
*
11+
* @see https://github.com/WebProject-xyz/ikea-tradfri-php
12+
*/
13+
14+
namespace IKEA\Tests\Unit\Tradfri\Device;
15+
16+
use IKEA\Tradfri\Command\Coap\Keys;
17+
use IKEA\Tradfri\Device\RollerBlind;
18+
use IKEA\Tradfri\Exception\RuntimeException;
19+
use IKEA\Tradfri\Service\ServiceInterface as Api;
20+
21+
final class RollerBlindTest extends DeviceTester
22+
{
23+
public function testGetAnInstance(): void
24+
{
25+
// Arrange
26+
// Act
27+
$lamp = $this->getModel();
28+
// Assert
29+
$this->assertInstanceOf(RollerBlind::class, $lamp);
30+
}
31+
32+
public function testSetType(): void
33+
{
34+
// Arrange
35+
$lamp = $this->getModel();
36+
$lamp->setType(Keys::ATTR_DEVICE_INFO_TYPE_ROLLER_BLIND);
37+
// Act
38+
$result = $lamp->getType();
39+
40+
// Assert
41+
$this->assertSame(Keys::ATTR_DEVICE_INFO_TYPE_ROLLER_BLIND, $result);
42+
}
43+
44+
public function testGetBrightnessButNotSet(): void
45+
{
46+
// Arrange
47+
$rollerBlind = $this->getModel();
48+
49+
// Act
50+
$result = $rollerBlind->getDarkenedState();
51+
52+
// Assert
53+
$this->assertSame(0, $result);
54+
}
55+
56+
public function testGetBrightness(): void
57+
{
58+
// Arrange
59+
$rollerBlind = $this->getModel();
60+
$rollerBlind->setDarkenedState((int) 30);
61+
// Act
62+
$result = $rollerBlind->getDarkenedState();
63+
64+
// Assert
65+
$this->assertSame(30, $result);
66+
}
67+
68+
public function testSetBrightnessToLow(): void
69+
{
70+
// Arrange
71+
$rollerBlind = $this->getModel();
72+
$rollerBlind->setDarkenedState(-12);
73+
// Act
74+
$result = $rollerBlind->getDarkenedState();
75+
76+
// Assert
77+
$this->assertSame(0, $result);
78+
}
79+
80+
public function testStates(): void
81+
{
82+
// Arrange
83+
$rollerBlind = $this->getModel();
84+
$this->assertTrue($rollerBlind->isFullyOpened());
85+
86+
$service = \mock(Api::class);
87+
$service->expects()->setRollerBlindPosition($rollerBlind, 0)->once()->andReturn(true);
88+
$rollerBlind->setService($service);
89+
90+
// Act
91+
$rollerBlind->setToPosition(0);
92+
93+
// Assert
94+
$this->assertTrue($rollerBlind->isFullyOpened());
95+
}
96+
97+
public function testICanSetPositions(): void
98+
{
99+
// Arrange
100+
$rollerBlind = $this->getModel();
101+
102+
$service = \mock(Api::class);
103+
$service->expects('setRollerBlindPosition')->with($rollerBlind, 100)->once()->andReturnUsing(static function (): bool {
104+
$model = \func_get_arg(0);
105+
\assert($model instanceof RollerBlind);
106+
$model->setDarkenedState(\func_get_arg(1));
107+
108+
return true;
109+
});
110+
$service->expects('setRollerBlindPosition')->with($rollerBlind, 75)->once()->andReturnUsing(static function (): bool {
111+
$model = \func_get_arg(0);
112+
\assert($model instanceof RollerBlind);
113+
$model->setDarkenedState(\func_get_arg(1));
114+
115+
return true;
116+
});
117+
118+
$rollerBlind->setService($service);
119+
$this->assertFalse($rollerBlind->isFullyClosed());
120+
121+
// Act
122+
$result = $rollerBlind->setToPosition(100);
123+
124+
// Assert
125+
$this->assertTrue($result);
126+
$this->assertTrue($rollerBlind->isFullyClosed());
127+
$this->assertFalse($rollerBlind->isFullyOpened());
128+
129+
// Act
130+
$result = $rollerBlind->setToPosition(75);
131+
// Assert
132+
$this->assertTrue($result);
133+
$this->assertFalse($rollerBlind->isFullyOpened());
134+
$this->assertFalse($rollerBlind->isFullyClosed());
135+
136+
$this->assertSame(75, $rollerBlind->getDarkenedState());
137+
}
138+
139+
public function testICanSetPositionFails(): void
140+
{
141+
$this->expectException(RuntimeException::class);
142+
$this->expectExceptionMessage('set postion failed');
143+
// Arrange
144+
$lamp = $this->getModel();
145+
146+
$service = \mock(Api::class);
147+
$service->expects('setRollerBlindPosition')->andThrow(new RuntimeException('set postion failed'));
148+
149+
$lamp->setService($service);
150+
$this->assertTrue($lamp->isFullyOpened());
151+
152+
// Act
153+
$result = $lamp->setToPosition(100);
154+
155+
// Assert
156+
}
157+
158+
protected function getModel(): RollerBlind
159+
{
160+
return new RollerBlind($this->_id, Keys::ATTR_DEVICE_INFO_TYPE_ROLLER_BLIND);
161+
}
162+
}

0 commit comments

Comments
 (0)