Completed
Push — master ( ae2b86...3f2a96 )
by Benedikt
02:57
created

DatabaseTestCase::addAdditionalNewUserAttributes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * Class DatabaseTestCase
6
 */
7
8
namespace Tfboe\FmLib\TestHelpers;
9
10
use Faker\Factory;
11
use LaravelDoctrine\ORM\Facades\EntityManager;
12
use Tfboe\FmLib\Entity\PlayerInterface;
13
use Tfboe\FmLib\Entity\TeamInterface;
14
use Tfboe\FmLib\Entity\TeamMembershipInterface;
15
use Tfboe\FmLib\Entity\UserInterface;
16
17
/**
18
 * Class DatabaseTestCase
19
 * @package Tfboe\FmLib\TestHelpers
20
 */
21
abstract class DatabaseTestCase extends LumenTestCase
22
{
23
//<editor-fold desc="Fields">
24
  /**
25
   * @var \Faker\Generator
26
   */
27
  protected $faker;
28
29
  /**
30
   * @var bool
31
   */
32
  private $clear;
33
//</editor-fold desc="Fields">
34
35
//<editor-fold desc="Constructor">
36
  /**
37
   * DatabaseTestCase constructor.
38
   * @param string|null $name test name
39
   * @param array $data test data
40
   * @param string $dataName test data name
41
   * @param bool $clear
42
   */
43
  public function __construct($name = null, array $data = [], $dataName = '', $clear = false)
44
  {
45
    parent::__construct($name, $data, $dataName);
46
    srand(3); //always use the same faker values to get reproducibility
47
    $this->faker = Factory::create();
48
    $this->clear = $clear;
49
  }
50
//</editor-fold desc="Constructor">
51
52
//<editor-fold desc="Protected Methods">
53
54
  /**
55
   * Clears the database by truncating all tables (very time consuming)
56
   * @throws \Doctrine\DBAL\DBALException
57
   */
58
  protected function clearDatabase()
59
  {
60
    /** @var \Doctrine\DBAL\Connection $connection */
61
    /** @noinspection PhpUndefinedMethodInspection */
62
    $connection = EntityManager::getConnection();
63
    $connection->query(sprintf('SET FOREIGN_KEY_CHECKS = 0;'));
64
    $tables = $connection->getSchemaManager()->listTables();
65
    foreach ($tables as $table) {
66
      $sql = sprintf('TRUNCATE TABLE %s', $table->getName());
67
      $connection->query($sql);
68
    }
69
    $connection->query(sprintf('SET FOREIGN_KEY_CHECKS = 1;'));
70
  }
71
72
  /**
73
   * Creates an array of players.
74
   * @param int $number the number of players
75
   * @return PlayerInterface[] the created player array
76
   */
77
  protected function createPlayers(int $number = 1): array
78
  {
79
    $result = [];
80
    for ($i = 0; $i < $number; $i++) {
81
      $result[] = entity($this->resolveEntity(PlayerInterface::class))->create();
82
    }
83
    return $result;
84
  }
85
86
  /**
87
   * Creates an array of teams with ranks and start numbers
88
   * @param int $number the number of teams to create
89
   * @param int $playerPerTeam the number of players per team
90
   * @return TeamInterface[] the created team array
91
   */
92
  protected function createTeams(int $number, $playerPerTeam = 1): array
93
  {
94
    $result = [];
95
    for ($i = 0; $i < $number; $i++) {
96
      /** @var TeamInterface $team */
97
      $team = entity($this->resolveEntity(TeamInterface::class))->create(
98
        ['startNumber' => $i + 1, 'rank' => $number - $i]);
99
      foreach ($this->createPlayers($playerPerTeam) as $player) {
100
        /** @var TeamMembershipInterface $teamMembership */
101
        $teamMembership = entity($this->resolveEntity(TeamMembershipInterface::class))->create(
102
          ['team' => $team, 'player' => $player]);
103
        $team->getMemberships()->set($teamMembership->getId(), $teamMembership);
104
      }
105
      $result[] = $team;
106
    }
107
    return $result;
108
  }
109
110
  /**
111
   * Creates a new user
112
   * @return array containing the password and the user object
113
   */
114
  protected function createUser()
115
  {
116
    $password = $this->newPassword();
117
    /** @var UserInterface $user */
118
    $attributes = ['originalPassword' => $password];
119
    $this->addAdditionalNewUserAttributes($attributes);
120
    $user = entity($this->resolveEntity(UserInterface::class))->create($attributes);
121
    return [
122
      'password' => $password,
123
      'user' => $user
124
    ];
125
  }
126
127
  /**
128
   * Adds additional attributes given to the create entity method
129
   * @param mixed[] $attributes
130
   */
131
  protected function addAdditionalNewUserAttributes(array &$attributes)
0 ignored issues
show
Unused Code introduced by
The parameter $attributes is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
132
  {
133
  }
134
135
  /**
136
   * Uses faker to generate a new password
137
   * @return string the new password
138
   */
139
  protected function newPassword()
140
  {
141
    return $this->faker->password(8, 30);
142
  }
143
144
  /**
145
   * Boot the testing helper traits.
146
   *
147
   * @return void
148
   * @throws \Doctrine\DBAL\DBALException
149
   */
150
  protected function setUpTraits()
151
  {
152
    srand(3); //always use the same faker values to get reproducibility
153
    $clear = $this->clear;
154
    parent::setUpTraits();
155
    if ($clear) {
156
      $this->clearDatabase();
157
      $this->workOnDatabaseSetUp();
158
    } else {
159
      $this->workOnDatabaseSetUp();
160
      /** @noinspection PhpUndefinedMethodInspection */
161
      EntityManager::beginTransaction();
162
    }
163
164
    $this->beforeApplicationDestroyed(function () use ($clear) {
165
      if ($clear) {
166
        $this->workOnDatabaseDestroy();
167
        $this->clearDatabase();
168
      } else {
169
        /** @noinspection PhpUndefinedMethodInspection */
170
        EntityManager::rollback();
171
        $this->workOnDatabaseDestroy();
172
      }
173
    });
174
  }
175
176
  protected function workOnDatabaseDestroy()
177
  {
178
179
  }
180
181
  protected function workOnDatabaseSetUp()
182
  {
183
184
  }
185
186
  /**
187
   * Resolve className according to fm-lib config
188
   * @param string $className
189
   * @return string
190
   */
191
  protected final function resolveEntity(string $className): string
0 ignored issues
show
Coding Style introduced by
As per PSR2, final should precede the visibility keyword.
Loading history...
192
  {
193
    //resolve class name according to fm-lib config
194
    if (config()->has('fm-lib')) {
195
      $config = config('fm-lib');
196
      if (array_key_exists('entityMaps', $config)) {
197
        $classMap = $config['entityMaps'];
198
        if (array_key_exists($className, $classMap)) {
199
          return $classMap[$className];
200
        }
201
      }
202
    }
203
    return $className;
204
  }
205
//</editor-fold desc="Protected Methods">
206
}