Skip to content

Commit

Permalink
Add multi select page property
Browse files Browse the repository at this point in the history
  • Loading branch information
mariosimao committed Oct 27, 2021
1 parent fa0d05f commit 3083365
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/Pages/Properties/Factory.php
Expand Up @@ -18,6 +18,7 @@ public static function fromArray(array $array): PropertyInterface
Property::TYPE_RICH_TEXT => RichTextProperty::fromArray($array),
Property::TYPE_NUMBER => Number::fromArray($array),
Property::TYPE_SELECT => Select::fromArray($array),
Property::TYPE_MULTI_SELECT => MultiSelect::fromArray($array),
default => throw new Exception("Invalid property type: '{$type}'"),
};
}
Expand Down
82 changes: 82 additions & 0 deletions src/Pages/Properties/MultiSelect.php
@@ -0,0 +1,82 @@
<?php

namespace Notion\Pages\Properties;

/**
* @psalm-import-type OptionJson from Option
*
* @psalm-type MultiSelectJson = array{
* id: string,
* type: "multi_select",
* multi_select: OptionJson[],
* }
*/
class MultiSelect implements PropertyInterface
{
private const TYPE = Property::TYPE_MULTI_SELECT;

private Property $property;

/** @var Option[] */
private array $options;

/** @param Option[] $options */
private function __construct(Property $property, array $options)
{
$this->property = $property;
$this->options = $options;
}

public static function fromIds(string ...$ids): self
{
$property = Property::create("", self::TYPE);
$options = array_map(fn(string $id) => Option::fromId($id), $ids);

return new self($property, $options);
}

public static function fromNames(string ...$names): self
{
$property = Property::create("", self::TYPE);
$options = array_map(fn(string $name) => Option::fromName($name), $names);

return new self($property, $options);
}

public static function fromArray(array $array): self
{
/** @psalm-var MultiSelectJson $array */
$property = Property::fromArray($array);

$options = array_map(fn(array $option) => Option::fromArray($option), $array[self::TYPE]);

return new self($property, $options);
}

public function toArray(): array
{
$array = $this->property->toArray();
$array[self::TYPE] = array_map(fn (Option $option) => $option->toArray(), $this->options);

return $array;
}

public function property(): Property
{
return $this->property;
}

/** @return Option[] */
public function options(): array
{
return $this->options;
}

public function addOption(Option $option): self
{
$options = $this->options;
$options[] = $option;

return new self($this->property, $options);
}
}
8 changes: 4 additions & 4 deletions src/Pages/Properties/Property.php
Expand Up @@ -86,10 +86,10 @@ public function isSelect(): bool
return $this->type === self::TYPE_SELECT;
}

// public function isMultiSelect(): bool
// {
// return $this->type === self::TYPE_MULTI_SELECT;
// }
public function isMultiSelect(): bool
{
return $this->type === self::TYPE_MULTI_SELECT;
}

// public function isDate(): bool
// {
Expand Down
61 changes: 61 additions & 0 deletions tests/Unit/Pages/Properties/MultiSelectTest.php
@@ -0,0 +1,61 @@
<?php

namespace Notion\Test\Unit\Pages\Properties;

use Notion\Pages\Properties\Factory;
use Notion\Pages\Properties\MultiSelect;
use Notion\Pages\Properties\Option;
use PHPUnit\Framework\TestCase;

class MultiSelectTest extends TestCase
{
public function test_create_from_ids(): void
{
$id1 = "d69f85ae-9425-4851-beeb-4b4831f5786c";
$id2 = "af65b5c5-8034-4ef9-91af-05b8bc01642e";

$multiSelect = MultiSelect::fromIds($id1, $id2);

$this->assertEquals($id1, $multiSelect->options()[0]->id());
$this->assertEquals($id2, $multiSelect->options()[1]->id());

$this->assertTrue($multiSelect->property()->isMultiSelect());
}

public function test_create_from_names(): void
{
$optionA = "Option A";
$optionC = "Option C";

$multiSelect = MultiSelect::fromNames($optionA, $optionC);

$this->assertEquals($optionA, $multiSelect->options()[0]->name());
$this->assertEquals($optionC, $multiSelect->options()[1]->name());
}

public function test_array_conversion(): void
{
$array = [
"id" => "931db25b-f8af-4fc0-b7bf-eb9c29de6b87",
"type" => "multi_select",
"multi_select" => [
[ "name" => "Option A", "color" => "red" ],
[ "name" => "Option C", "color" => "blue" ],
],
];

$multiSelect = MultiSelect::fromArray($array);
$fromFactory = Factory::fromArray($array);

$this->assertEquals($array, $multiSelect->toArray());
$this->assertEquals($array, $fromFactory->toArray());
}

public function test_add_option(): void
{
$multiSelect = MultiSelect::fromNames("Option A", "Option B")
->addOption(Option::fromName("Option C"));

$this->assertCount(3, $multiSelect->options());
}
}

0 comments on commit 3083365

Please sign in to comment.