Skip to content

Commit

Permalink
Added Steam Deck support to app details parser and accompanying test.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bilge committed Mar 19, 2022
1 parent 323fe74 commit f803749
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/Scrape/AppDetailsParser.php
Expand Up @@ -91,6 +91,9 @@ private static function parseStorePage(string $html): array
$wmr = in_array('104', $vrPlatforms, true);
$valve_index = in_array('105', $vrPlatforms, true);

// Steam Deck.
$steam_deck = self::parseSteamDeckCompatibility($crawler);

return compact(
'name',
'type',
Expand Down Expand Up @@ -120,6 +123,7 @@ private static function parseStorePage(string $html): array
'occulus',
'wmr',
'valve_index',
'steam_deck',
'DEBUG_primary_sub_id',
);
}
Expand Down Expand Up @@ -435,4 +439,17 @@ private static function findPurchaseAreaBySubId(Crawler $crawler, int $subId): C
{
return $crawler->filter("#game_area_purchase_section_add_to_cart_$subId");
}

private static function parseSteamDeckCompatibility(Crawler $crawler): ?SteamDeckCompatibility
{
$config = $crawler->filter('#application_config');

if (count($config) && $deckCompatJson = $config->attr('data-deckcompatibility')) {
$deckCompat = \json_decode($deckCompatJson, true, 512, JSON_THROW_ON_ERROR);

return SteamDeckCompatibility::fromId($deckCompat['resolved_category']);
}

return null;
}
}
34 changes: 34 additions & 0 deletions src/Scrape/SteamDeckCompatibility.php
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);

namespace ScriptFUSION\Porter\Provider\Steam\Scrape;

use Eloquent\Enumeration\AbstractEnumeration;

/**
* @method static self UNSUPPORTED
* @method static self VERIFIED
* @method static self PLAYABLE
*/
final class SteamDeckCompatibility extends AbstractEnumeration
{
public const UNSUPPORTED = 'UNSUPPORTED';
public const VERIFIED = 'VERIFIED';
public const PLAYABLE = 'PLAYABLE';

private const ID_MAP = [
1 => self::UNSUPPORTED,
2 => self::PLAYABLE,
3 => self::VERIFIED,
];

public static function fromId(int $id): self
{
return self::memberByKey(self::ID_MAP[$id]);
}

public function toId(): int
{
return array_search($this->key(), self::ID_MAP, true);
}
}
49 changes: 49 additions & 0 deletions test/Functional/ScrapeAppDetailsTest.php
Expand Up @@ -9,6 +9,7 @@
use ScriptFUSION\Porter\Provider\Steam\Resource\InvalidAppIdException;
use ScriptFUSION\Porter\Provider\Steam\Resource\ScrapeAppDetails;
use ScriptFUSION\Porter\Provider\Steam\Scrape\InvalidMarkupException;
use ScriptFUSION\Porter\Provider\Steam\Scrape\SteamDeckCompatibility;
use ScriptFUSION\Porter\Provider\Steam\Scrape\SteamStoreException;
use ScriptFUSION\Porter\Specification\AsyncImportSpecification;
use ScriptFUSION\Porter\Specification\ImportSpecification;
Expand Down Expand Up @@ -753,6 +754,54 @@ public function testPackage(): void
self::assertGreaterThan(0, $app['price']);
}

/**
* Tests that a game with no Steam Deck information presents Steam Deck compatibility as "null".
*
* @see https://store.steampowered.com/app/1572920/SuperTux/
*/
public function testSteamDeckAbsent(): void
{
$app = $this->porter->importOne(new ImportSpecification(new ScrapeAppDetails(1572920)));

self::assertNull($app['steam_deck']);
}

/**
* Tests that a game with Steam Deck "unsupported" compatibility is parsed correctly.
*
* @see https://store.steampowered.com/app/546560/HalfLife_Alyx/
*/
public function testSteamDeckUnsupported(): void
{
$app = $this->porter->importOne(new ImportSpecification(new ScrapeAppDetails(546560)));

self::assertSame(SteamDeckCompatibility::UNSUPPORTED(), $app['steam_deck']);
}

/**
* Tests that a game with Steam Deck "verified" compatibility is parsed correctly.
*
* @see https://store.steampowered.com/app/620/Portal_2/
*/
public function testSteamDeckVerified(): void
{
$app = $this->porter->importOne(new ImportSpecification(new ScrapeAppDetails(620)));

self::assertSame(SteamDeckCompatibility::VERIFIED(), $app['steam_deck']);
}

/**
* Tests that a game with Steam Deck "playable" compatibility is parsed correctly.
*
* @see https://store.steampowered.com/app/427520/Factorio/
*/
public function testSteamDeckPlayable(): void
{
$app = $this->porter->importOne(new ImportSpecification(new ScrapeAppDetails(427520)));

self::assertSame(SteamDeckCompatibility::PLAYABLE(), $app['steam_deck']);
}

/**
* Tests that an EA Play subscription game with an additional regular purchase area is parsed correctly.
*
Expand Down
27 changes: 27 additions & 0 deletions test/Unit/SteamDeckCompatibilityTest.php
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);

namespace ScriptFUSIONTest\Porter\Provider\Steam\Unit;

use ScriptFUSION\Porter\Provider\Steam\Scrape\SteamDeckCompatibility;
use PHPUnit\Framework\TestCase;

/**
* @see SteamDeckCompatibility
*/
final class SteamDeckCompatibilityTest extends TestCase
{
/**
* @dataProvider provideIds
*/
public function testIdRoundTrip(int $id): void
{
self::assertInstanceOf(SteamDeckCompatibility::class, $compat = SteamDeckCompatibility::fromId($id));
self::assertSame($id, $compat->toId());
}

public function provideIds(): iterable
{
yield from \iter\chunk(range(1, 3), 1);
}
}

0 comments on commit f803749

Please sign in to comment.