Skip to content

Commit 0a89540

Browse files
vid-2
1 parent 2ef790d commit 0a89540

16 files changed

+196
-31
lines changed

app/config/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ imports:
33
- { resource: security.yml }
44
- { resource: services.yml }
55
- { resource: services/doctrine_entity_repository.yml }
6+
- { resource: services/listener.yml }
67
- { resource: services/repository.yml }
78

89
# Put parameters here that don't need to change on each machine where the app is deployed

app/config/config_acceptance.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
imports:
22
- { resource: config.yml }
3+
- { resource: services/clock_acceptance.yml }
34

45
monolog:
56
handlers:

app/config/config_dev.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
imports:
22
- { resource: config.yml }
3+
- { resource: services/clock_prod.yml }
34

45
framework:
56
router:

app/config/config_prod.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
imports:
22
- { resource: config.yml }
3+
- { resource: services/clock_prod.yml }
34

45
#doctrine:
56
# orm:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
services:
2+
3+
crv.clock:
4+
class: AppBundle\Model\TestClock
5+
arguments:
6+
- "@filesystem"

app/config/services/clock_prod.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
3+
crv.clock:
4+
class: AppBundle\Model\SystemClock

app/config/services/listener.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
3+
crv.listener.timestamp:
4+
class: AppBundle\Listener\TimestampListener
5+
arguments:
6+
- "@crv.clock"
7+
tags:
8+
- { name: doctrine.event_listener, event: prePersist }
9+
- { name: doctrine.event_listener, event: preUpdate }

behat.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ default:
1515
client: "@guzzle.client.local_test_api"
1616
- AppBundle\Features\Context\WidgetSetupContext:
1717
em: "@doctrine.orm.entity_manager"
18+
clock: "@crv.clock"
19+
- AppBundle\Features\Context\TimeContext:
20+
clock: "@crv.clock"
1821

1922
extensions:
2023
Behat\Symfony2Extension:

src/AppBundle/Entity/Traits/TimestampableTrait.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,6 @@ public function setCreatedAt(\DateTimeImmutable $dateTime = null)
5858
return $this;
5959
}
6060

61-
/**
62-
* @ORM\PrePersist()
63-
* @return $this
64-
*/
65-
public function setCreatedAtViaPrePersist()
66-
{
67-
return $this->setCreatedAt();
68-
}
69-
7061
/**
7162
* Get updated at
7263
*
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace AppBundle\Features\Context;
4+
5+
use AppBundle\Model\Clock;
6+
use AppBundle\Model\TestClock;
7+
use Behat\Behat\Context\Context;
8+
9+
class TimeContext implements Context
10+
{
11+
/**
12+
* @var TestClock
13+
*/
14+
private $clock;
15+
16+
public function __construct(
17+
TestClock $clock
18+
)
19+
{
20+
$this->clock = $clock;
21+
}
22+
23+
/**
24+
* @Given the system time at the start of this test is :strDate
25+
*/
26+
public function theSystemTimeAtTheStartOfThisTestIs($strDate)
27+
{
28+
$this->clock->setTime(
29+
$strDate
30+
);
31+
}
32+
}

src/AppBundle/Features/Context/WidgetSetupContext.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace AppBundle\Features\Context;
44

55
use AppBundle\Entity\Widget;
6+
use AppBundle\Model\Clock;
67
use Behat\Behat\Context\Context;
78
use Behat\Gherkin\Node\TableNode;
89
use Doctrine\Common\Collections\ArrayCollection;
@@ -14,17 +15,24 @@ class WidgetSetupContext implements Context
1415
* @var EntityManagerInterface
1516
*/
1617
protected $em;
18+
/**
19+
* @var Clock
20+
*/
21+
private $clock;
1722

1823
/**
1924
* WidgetSetupContext constructor.
2025
*
2126
* @param EntityManagerInterface $em
27+
* @param Clock $clock
2228
*/
2329
public function __construct(
24-
EntityManagerInterface $em
30+
EntityManagerInterface $em,
31+
Clock $clock
2532
)
2633
{
2734
$this->em = $em;
35+
$this->clock = $clock;
2836
}
2937

3038
/**
@@ -48,13 +56,13 @@ public function thereAreWidgetsWithTheFollowingDetails(TableNode $widgets)
4856
->set(
4957
'w.createdAt',
5058
$qb->expr()->literal(
51-
(new \DateTimeImmutable($val['created_at']))->format('c')
59+
$this->clock->now()->modify($val['created_at'])->format('c')
5260
)
5361
)
5462
->set(
5563
'w.updatedAt',
5664
$qb->expr()->literal(
57-
(new \DateTimeImmutable($val['updated_at']))->format('c')
65+
$this->clock->now()->modify($val['updated_at'])->format('c')
5866
)
5967
)
6068
->where('w.id = :id')

src/AppBundle/Features/widget.feature

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ Feature: Manage Widget data via a JSON API
66

77

88
Background:
9-
Given there are Widgets with the following details:
9+
Given the system time at the start of this test is "1 January 2020 00:00:00"
10+
And there are Widgets with the following details:
1011
| id | name | created_at | updated_at |
11-
| 1 | Widget A | -4 days | -5 minutes |
12+
| 1 | Widget A | -7 days | -5 minutes |
1213
| 2 | Widget B | -1 day | -1 day |
1314
| 3 | Widget C | -6 months | -3 weeks |
1415
And I set header "Content-Type" with value "application/json"
@@ -22,21 +23,7 @@ Feature: Manage Widget data via a JSON API
2223
{
2324
"id": 1,
2425
"name": "Widget A",
25-
features: [
26-
{
27-
"id": 1,
28-
"name": "some feature",
29-
"created_at": "2015-01-01T00:00:00+0000",
30-
"updated_at": "2015-01-01T00:00:00+0000",
31-
},
32-
{
33-
"id": 1,
34-
"name": "another feature",
35-
"created_at": "2016-01-01T00:00:00+0000",
36-
"updated_at": "2016-01-01T00:00:00+0000",
37-
}
38-
]
26+
"created_at": "2019-12-25T00:00:00+0000",
27+
"updated_at": "2019-12-31T23:55:00+0000"
3928
}
40-
"""
41-
And the "created_at" date should be approximately "-4 days"
42-
And the "updated_at" date should be approximately "-5 minutes"
29+
"""
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace AppBundle\Listener;
4+
5+
use AppBundle\Model\Clock;
6+
use Doctrine\ORM\Event\LifecycleEventArgs;
7+
use Doctrine\ORM\Event\PreUpdateEventArgs;
8+
9+
class TimestampListener
10+
{
11+
/**
12+
* @var Clock
13+
*/
14+
private $clock;
15+
16+
public function __construct(Clock $clock)
17+
{
18+
$this->clock = $clock;
19+
}
20+
21+
public function prePersist(LifecycleEventArgs $lifecycleEventArgs)
22+
{
23+
$entity = $lifecycleEventArgs->getEntity();
24+
25+
if (method_exists($entity, 'setCreatedAt')) {
26+
$entity->setCreatedAt(
27+
$this->clock->now()
28+
);
29+
}
30+
}
31+
32+
public function preUpdate(PreUpdateEventArgs $preUpdateEventArgs)
33+
{
34+
$entity = $preUpdateEventArgs->getEntity();
35+
36+
if (method_exists($entity, 'setUpdatedAt')) {
37+
$entity->setCreatedAt(
38+
$this->clock->now()
39+
);
40+
}
41+
}
42+
}

src/AppBundle/Model/Clock.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace AppBundle\Model;
4+
5+
interface Clock
6+
{
7+
public function now() : \DateTimeImmutable;
8+
}

src/AppBundle/Model/SystemClock.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace AppBundle\Model;
4+
5+
class SystemClock implements Clock
6+
{
7+
public function now(): \DateTimeImmutable
8+
{
9+
return new \DateTimeImmutable('now');
10+
}
11+
}

src/AppBundle/Model/TestClock.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace AppBundle\Model;
4+
5+
use Symfony\Component\Filesystem\Filesystem;
6+
7+
class TestClock implements Clock
8+
{
9+
/**
10+
* @var Filesystem
11+
*/
12+
private $filesystem;
13+
14+
/**
15+
* @var string
16+
*/
17+
private $dir;
18+
19+
/**
20+
* @var string
21+
*/
22+
private $file;
23+
24+
public function __construct(Filesystem $filesystem)
25+
{
26+
$this->filesystem = $filesystem;
27+
28+
$this->dir = sys_get_temp_dir() . '/time';
29+
$this->file = $this->dir . '/timefile';
30+
}
31+
32+
public function setTime(string $time)
33+
{
34+
$this->filesystem->mkdir($this->dir);
35+
36+
if ($this->filesystem->exists($this->file)) {
37+
$this->filesystem->remove($this->file);
38+
}
39+
40+
$isoDateTime = (new \DateTimeImmutable($time))
41+
->format('c')
42+
;
43+
44+
$this->filesystem->dumpFile(
45+
$this->file,
46+
$isoDateTime
47+
);
48+
}
49+
50+
public function now(): \DateTimeImmutable
51+
{
52+
if (false === $this->filesystem->exists($this->file)) {
53+
throw new \RuntimeException('Must set the time file before doing this.');
54+
}
55+
56+
return new \DateTimeImmutable(
57+
file_get_contents($this->file)
58+
);
59+
}
60+
}

0 commit comments

Comments
 (0)