Skip to content

Commit 66ca7af

Browse files
authored
Merge branch 'dev' into feature/better-pagination-handling
2 parents bc8a3e6 + 461b1dd commit 66ca7af

File tree

8 files changed

+343
-18
lines changed

8 files changed

+343
-18
lines changed

src/Entities/Page.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,19 @@ public function setDate(string $propertyTitle, DateTime $start, ?DateTime $end =
344344
return $this;
345345
}
346346

347+
/**
348+
* @param $propertyTitle
349+
* @param $start
350+
* @param $end
351+
* @return Page
352+
*/
353+
public function setDateTime(string $propertyTitle, DateTime $start, ?DateTime $end = null): Page
354+
{
355+
$this->set($propertyTitle, Date::valueWithTime($start, $end));
356+
357+
return $this;
358+
}
359+
347360
/**
348361
* @param $propertyTitle
349362
* @param $relationIds

src/Entities/Properties/Date.php

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use FiveamCode\LaravelNotionApi\Entities\Contracts\Modifiable;
77
use FiveamCode\LaravelNotionApi\Entities\PropertyItems\RichDate;
88
use FiveamCode\LaravelNotionApi\Exceptions\HandlingException;
9+
use Illuminate\Support\Arr;
910

1011
/**
1112
* Class Date.
@@ -26,6 +27,39 @@ public static function value(?DateTime $start, ?DateTime $end = null): Date
2627
$dateProperty = new Date();
2728
$dateProperty->content = $richDate;
2829

30+
if ($richDate->isRange()) {
31+
$dateProperty->rawContent = [
32+
'date' => [
33+
'start' => $start->format('Y-m-d'),
34+
'end' => $end->format('Y-m-d'),
35+
],
36+
];
37+
} else {
38+
$dateProperty->rawContent = [
39+
'date' => [
40+
'start' => $start->format('Y-m-d'),
41+
],
42+
];
43+
}
44+
45+
return $dateProperty;
46+
}
47+
48+
/**
49+
* @param $start
50+
* @param $end
51+
* @return Date
52+
*/
53+
public static function valueWithTime(?DateTime $start, ?DateTime $end = null): Date
54+
{
55+
$richDate = new RichDate();
56+
$richDate->setStart($start);
57+
$richDate->setEnd($end);
58+
$richDate->setHasTime(true);
59+
60+
$dateProperty = new Date();
61+
$dateProperty->content = $richDate;
62+
2963
if ($richDate->isRange()) {
3064
$dateProperty->rawContent = [
3165
'date' => [
@@ -57,19 +91,26 @@ protected function fillDate(): void
5791
{
5892
$richDate = new RichDate();
5993

60-
if (isset($this->rawContent['start'])) {
94+
if (Arr::exists($this->rawContent, 'start')) {
6195
$startAsIsoString = $this->rawContent['start'];
6296
$richDate->setStart(new DateTime($startAsIsoString));
97+
$richDate->setHasTime($this->isIsoTimeString($startAsIsoString));
6398
}
6499

65-
if (isset($this->rawContent['end'])) {
100+
if (Arr::exists($this->rawContent, 'end')) {
66101
$endAsIsoString = $this->rawContent['end'];
67102
$richDate->setEnd(new DateTime($endAsIsoString));
68103
}
69104

70105
$this->content = $richDate;
71106
}
72107

108+
// function for checking if ISO datetime string includes time or not
109+
private function isIsoTimeString(string $isoTimeDateString): bool
110+
{
111+
return strpos($isoTimeDateString, 'T') !== false;
112+
}
113+
73114
/**
74115
* @return RichDate
75116
*/
@@ -95,10 +136,18 @@ public function getStart(): DateTime
95136
}
96137

97138
/**
98-
* @return DateTime
139+
* @return ?DateTime
99140
*/
100-
public function getEnd(): DateTime
141+
public function getEnd(): ?DateTime
101142
{
102143
return $this->getContent()->getEnd();
103144
}
145+
146+
/**
147+
* @return bool
148+
*/
149+
public function hasTime(): bool
150+
{
151+
return $this->getContent()->hasTime();
152+
}
104153
}

src/Entities/Properties/Rollup.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protected function fillFromRaw(): void
3737
break;
3838
default:
3939
throw new HandlingException("Unexpected rollupType {$this->rollupType}");
40-
}
40+
}
4141
}
4242
}
4343

@@ -89,12 +89,21 @@ private function setRollupContentArray()
8989
// TODO
9090
$rollupPropertyItem['id'] = 'undefined';
9191

92-
$this->content->add(
93-
Property::fromResponse('', $rollupPropertyItem)
94-
);
92+
if ($this->isRollupPropertyContentSet($rollupPropertyItem)) {
93+
$this->content->add(
94+
Property::fromResponse('', $rollupPropertyItem)
95+
);
96+
}
9597
}
9698
}
9799

100+
private function isRollupPropertyContentSet($rollupPropertyItem): bool
101+
{
102+
return Arr::exists($rollupPropertyItem, 'type')
103+
&& Arr::exists($rollupPropertyItem, $rollupPropertyItem['type'])
104+
&& ! is_null($rollupPropertyItem[$rollupPropertyItem['type']]);
105+
}
106+
98107
private function setRollupContentDate()
99108
{
100109
$this->content = new RichDate();

src/Entities/PropertyItems/RichDate.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
*/
1212
class RichDate extends Entity
1313
{
14-
/**
15-
* @var string
16-
*/
1714
protected DateTime $start;
1815
protected ?DateTime $end = null;
16+
protected bool $hasTime = false;
1917

2018
/**
2119
* @param array $responseData
@@ -63,13 +61,21 @@ public function getStart(): ?DateTime
6361
}
6462

6563
/**
66-
* @return DateTime
64+
* @return ?DateTime
6765
*/
6866
public function getEnd(): ?DateTime
6967
{
7068
return $this->end;
7169
}
7270

71+
/**
72+
* @return bool
73+
*/
74+
public function hasTime(): bool
75+
{
76+
return $this->hasTime;
77+
}
78+
7379
public function setStart($start): void
7480
{
7581
$this->start = $start;
@@ -79,4 +85,9 @@ public function setEnd($end): void
7985
{
8086
$this->end = $end;
8187
}
88+
89+
public function setHasTime($hasTime): void
90+
{
91+
$this->hasTime = $hasTime;
92+
}
8293
}

tests/EndpointDatabaseTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ public function it_throws_a_notion_exception_bad_request()
159159
Notion::database('8284f3ff77e24d4a939d19459e4d6bdc')->query();
160160
}
161161

162+
162163
/** @test */
163164
public function it_queries_a_database_with_and_without_offset_and_processes_result()
164165
{
@@ -215,4 +216,34 @@ public function it_queries_a_database_with_and_without_offset_and_processes_resu
215216
$page = $resultWithOffsetCollection->first();
216217
$this->assertEquals('Betty Holberton', $page->getTitle());
217218
}
219+
220+
221+
/**
222+
* @test
223+
* ! edge-case
224+
*/
225+
public function it_queries_a_database_with_a_rollup_property_with_empty_selects()
226+
{
227+
// success /v1/databases/DATABASE_DOES_EXIST/query
228+
Http::fake([
229+
'https://api.notion.com/v1/databases/11971214ce574df7a58389c1deda61d7/query*' => Http::response(
230+
json_decode(file_get_contents('tests/stubs/endpoints/databases/response_query_rollup_empty_select_200.json'), true),
231+
200,
232+
['Headers']
233+
),
234+
]);
235+
236+
$result = Notion::database('11971214ce574df7a58389c1deda61d7')->query();
237+
238+
$this->assertInstanceOf(PageCollection::class, $result);
239+
240+
$resultCollection = $result->asCollection();
241+
242+
$this->assertIsIterable($resultCollection);
243+
$this->assertContainsOnly(Page::class, $resultCollection);
244+
245+
// check page object
246+
$page = $resultCollection->first();
247+
$this->assertEquals(0, $page->getProperty('Rollup')->getContent()->count());
248+
}
218249
}

tests/EndpointPagesTest.php

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ public function it_returns_page_entity_with_filled_properties()
6969
// check properties
7070
$this->assertSame('Notion Is Awesome', $pageResult->getTitle());
7171
$this->assertSame('page', $pageResult->getObjectType());
72-
$this->assertCount(7, $pageResult->getRawProperties());
73-
$this->assertCount(7, $pageResult->getProperties());
74-
$this->assertCount(7, $pageResult->getPropertyKeys());
72+
$this->assertCount(9, $pageResult->getRawProperties());
73+
$this->assertCount(9, $pageResult->getProperties());
74+
$this->assertCount(9, $pageResult->getPropertyKeys());
75+
76+
// check date and datetime properties
77+
$this->assertTrue($pageResult->getProperty('DateWithTime')->hasTime());
78+
$this->assertFalse($pageResult->getProperty('DateWithoutTime')->hasTime());
7579

7680
$this->assertInstanceOf(Carbon::class, $pageResult->getCreatedTime());
7781
$this->assertInstanceOf(Carbon::class, $pageResult->getLastEditedTime());
@@ -106,9 +110,11 @@ public function it_assembles_properties_for_a_new_page()
106110
$checkboxKey = 'CheckboxProperty';
107111
$checkboxValue = true;
108112
$dateRangeKey = 'DateRangeProperty';
113+
$dateTimeRangeKey = 'DateTimeRangeProperty';
109114
$dateRangeStartValue = Carbon::now()->toDateTime();
110115
$dateRangeEndValue = Carbon::tomorrow()->toDateTime();
111116
$dateKey = 'DateProperty';
117+
$dateTimeKey = 'DateTimeProperty';
112118
$dateValue = Carbon::yesterday()->toDateTime();
113119
$emailKey = 'EmailProperty';
114120
$emailValue = 'notion-is-awesome@example.org';
@@ -135,7 +141,9 @@ public function it_assembles_properties_for_a_new_page()
135141
$page->setTitle('Name', $pageTitle);
136142
$page->setCheckbox($checkboxKey, $checkboxValue);
137143
$page->setDate($dateRangeKey, $dateRangeStartValue, $dateRangeEndValue);
144+
$page->setDateTime($dateTimeRangeKey, $dateRangeStartValue, $dateRangeEndValue);
138145
$page->setDate($dateKey, $dateValue);
146+
$page->setDateTime($dateTimeKey, $dateValue);
139147
$page->setEmail($emailKey, $emailValue);
140148
$page->setMultiSelect($multiSelectKey, $multiSelectValues);
141149
$page->setNumber($numberKey, $numberValue);
@@ -175,27 +183,65 @@ public function it_assembles_properties_for_a_new_page()
175183
$this->assertTrue($dateRangeProp->isRange());
176184
$this->assertEquals($dateRangeStartValue, $dateRangeProp->getStart());
177185
$this->assertEquals($dateRangeEndValue, $dateRangeProp->getEnd());
186+
$this->assertFalse($dateRangeProp->hasTime());
178187
$this->assertJson($dateRangeProp->asText());
179188
$this->assertStringContainsString($dateRangeStartValue->format('Y-m-d H:i:s'), $dateRangeProp->asText());
180189
$this->assertStringContainsString($dateRangeEndValue->format('Y-m-d H:i:s'), $dateRangeProp->asText());
181190
$dateRangeContent = $dateRangeProp->getRawContent();
182191
$this->assertArrayHasKey('date', $dateRangeContent);
183192
$this->assertCount(2, $dateRangeContent['date']);
184193
$this->assertArrayHasKey('start', $dateRangeContent['date']);
185-
$this->assertEquals($dateRangeStartValue->format('c'), $dateRangeContent['date']['start']);
194+
$this->assertEquals($dateRangeStartValue->format('Y-m-d'), $dateRangeContent['date']['start']);
186195
$this->assertArrayHasKey('end', $dateRangeContent['date']);
187-
$this->assertEquals($dateRangeEndValue->format('c'), $dateRangeContent['date']['end']);
196+
$this->assertEquals($dateRangeEndValue->format('Y-m-d'), $dateRangeContent['date']['end']);
197+
198+
// date range (with time)
199+
$this->assertTrue(
200+
$this->assertContainsInstanceOf(Date::class, $properties)
201+
);
202+
$dateTimeRangeProp = $page->getProperty($dateTimeRangeKey);
203+
$this->assertInstanceOf(RichDate::class, $dateTimeRangeProp->getContent());
204+
$dateTimeRangeContent = $dateTimeRangeProp->getContent();
205+
$this->assertTrue($dateTimeRangeProp->isRange());
206+
$this->assertEquals($dateRangeStartValue, $dateTimeRangeProp->getStart());
207+
$this->assertEquals($dateRangeEndValue, $dateTimeRangeProp->getEnd());
208+
$this->assertTrue($dateTimeRangeProp->hasTime());
209+
$this->assertJson($dateTimeRangeProp->asText());
210+
$this->assertStringContainsString($dateRangeStartValue->format('Y-m-d H:i:s'), $dateTimeRangeProp->asText());
211+
$this->assertStringContainsString($dateRangeEndValue->format('Y-m-d H:i:s'), $dateTimeRangeProp->asText());
212+
$dateTimeRangeContent = $dateTimeRangeProp->getRawContent();
213+
$this->assertArrayHasKey('date', $dateTimeRangeContent);
214+
$this->assertCount(2, $dateTimeRangeContent['date']);
215+
$this->assertArrayHasKey('start', $dateTimeRangeContent['date']);
216+
$this->assertEquals($dateRangeStartValue->format('c'), $dateTimeRangeContent['date']['start']);
217+
$this->assertArrayHasKey('end', $dateTimeRangeContent['date']);
218+
$this->assertEquals($dateRangeEndValue->format('c'), $dateTimeRangeContent['date']['end']);
188219

189220
// date
190221
$dateProp = $page->getProperty($dateKey);
191222
$this->assertInstanceOf(RichDate::class, $dateProp->getContent());
192223
$this->assertFalse($dateProp->isRange());
193224
$this->assertEquals($dateValue, $dateProp->getStart());
225+
$this->assertNull($dateProp->getEnd());
226+
$this->assertFalse($dateProp->hasTime());
194227
$dateContent = $dateProp->getRawContent();
195228
$this->assertArrayHasKey('date', $dateContent);
196229
$this->assertCount(1, $dateContent['date']);
197230
$this->assertArrayHasKey('start', $dateContent['date']);
198-
$this->assertEquals($dateValue->format('c'), $dateContent['date']['start']);
231+
$this->assertEquals($dateValue->format('Y-m-d'), $dateContent['date']['start']);
232+
233+
// date (with time)
234+
$dateTimeProp = $page->getProperty($dateTimeKey);
235+
$this->assertInstanceOf(RichDate::class, $dateTimeProp->getContent());
236+
$this->assertFalse($dateTimeProp->isRange());
237+
$this->assertEquals($dateValue, $dateTimeProp->getStart());
238+
$this->assertNull($dateTimeProp->getEnd());
239+
$this->assertTrue($dateTimeProp->hasTime());
240+
$dateTimeContent = $dateTimeProp->getRawContent();
241+
$this->assertArrayHasKey('date', $dateTimeContent);
242+
$this->assertCount(1, $dateTimeContent['date']);
243+
$this->assertArrayHasKey('start', $dateTimeContent['date']);
244+
$this->assertEquals($dateValue->format('c'), $dateTimeContent['date']['start']);
199245

200246
// email
201247
$this->assertTrue($this->assertContainsInstanceOf(Email::class, $properties));

0 commit comments

Comments
 (0)