Completed
Push — master ( c087ad...47fff7 )
by Benedikt
02:33
created

DatabaseTestCase   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 173
c 0
b 0
f 0
rs 10
wmc 19
lcom 2
cbo 5

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A clearDatabase() 0 13 2
A createPlayers() 0 8 2
A createTeams() 0 14 3
A createUser() 0 10 1
A newPassword() 0 4 1
B setUpTraits() 0 25 3
A workOnDatabaseDestroy() 0 4 1
A workOnDatabaseSetUp() 0 4 1
A resolveEntity() 0 14 4
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\UserInterface;
15
16
/**
17
 * Class DatabaseTestCase
18
 * @package Tfboe\FmLib\TestHelpers
19
 */
20
abstract class DatabaseTestCase extends LumenTestCase
21
{
22
//<editor-fold desc="Fields">
23
  /**
24
   * @var \Faker\Generator
25
   */
26
  protected $faker;
27
28
  /**
29
   * @var bool
30
   */
31
  private $clear;
32
//</editor-fold desc="Fields">
33
34
//<editor-fold desc="Constructor">
35
  /**
36
   * DatabaseTestCase constructor.
37
   * @param string|null $name test name
38
   * @param array $data test data
39
   * @param string $dataName test data name
40
   * @param bool $clear
41
   */
42
  public function __construct($name = null, array $data = [], $dataName = '', $clear = false)
43
  {
44
    parent::__construct($name, $data, $dataName);
45
    srand(3); //always use the same faker values to get reproducibility
46
    $this->faker = Factory::create();
47
    $this->clear = $clear;
48
  }
49
//</editor-fold desc="Constructor">
50
51
//<editor-fold desc="Protected Methods">
52
53
  /**
54
   * Clears the database by truncating all tables (very time consuming)
55
   * @throws \Doctrine\DBAL\DBALException
56
   */
57
  protected function clearDatabase()
58
  {
59
    /** @var \Doctrine\DBAL\Connection $connection */
60
    /** @noinspection PhpUndefinedMethodInspection */
61
    $connection = EntityManager::getConnection();
62
    $connection->query(sprintf('SET FOREIGN_KEY_CHECKS = 0;'));
63
    $tables = $connection->getSchemaManager()->listTables();
64
    foreach ($tables as $table) {
65
      $sql = sprintf('TRUNCATE TABLE %s', $table->getName());
66
      $connection->query($sql);
67
    }
68
    $connection->query(sprintf('SET FOREIGN_KEY_CHECKS = 1;'));
69
  }
70
71
  /**
72
   * Creates an array of players.
73
   * @param int $number the number of players
74
   * @return PlayerInterface[] the created player array
75
   */
76
  protected function createPlayers(int $number = 1): array
77
  {
78
    $result = [];
79
    for ($i = 0; $i < $number; $i++) {
80
      $result[] = entity($this->resolveEntity(PlayerInterface::class))->create();
81
    }
82
    return $result;
83
  }
84
85
  /**
86
   * Creates an array of teams with ranks and start numbers
87
   * @param int $number the number of teams to create
88
   * @param int $playerPerTeam the number of players per team
89
   * @return TeamInterface[] the created team array
90
   */
91
  protected function createTeams(int $number, $playerPerTeam = 1): array
92
  {
93
    $result = [];
94
    for ($i = 0; $i < $number; $i++) {
95
      /** @var TeamInterface $team */
96
      $team = entity($this->resolveEntity(TeamInterface::class))->create(
97
        ['startNumber' => $i + 1, 'rank' => $number - $i]);
98
      foreach ($this->createPlayers($playerPerTeam) as $player) {
99
        $team->getPlayers()->add($player);
100
      }
101
      $result[] = $team;
102
    }
103
    return $result;
104
  }
105
106
  /**
107
   * Creates a new user
108
   * @return array containing the password and the user object
109
   */
110
  protected function createUser()
111
  {
112
    $password = $this->newPassword();
113
    /** @var UserInterface $user */
114
    $user = entity($this->resolveEntity(UserInterface::class))->create(['originalPassword' => $password]);
115
    return [
116
      'password' => $password,
117
      'user' => $user
118
    ];
119
  }
120
121
  /**
122
   * Uses faker to generate a new password
123
   * @return string the new password
124
   */
125
  protected function newPassword()
126
  {
127
    return $this->faker->password(8, 30);
128
  }
129
130
  /**
131
   * Boot the testing helper traits.
132
   *
133
   * @return void
134
   * @throws \Doctrine\DBAL\DBALException
135
   */
136
  protected function setUpTraits()
137
  {
138
    srand(3); //always use the same faker values to get reproducibility
139
    $clear = $this->clear;
140
    parent::setUpTraits();
141
    if ($clear) {
142
      $this->clearDatabase();
143
      $this->workOnDatabaseSetUp();
144
    } else {
145
      $this->workOnDatabaseSetUp();
146
      /** @noinspection PhpUndefinedMethodInspection */
147
      EntityManager::beginTransaction();
148
    }
149
150
    $this->beforeApplicationDestroyed(function () use ($clear) {
151
      if ($clear) {
152
        $this->workOnDatabaseDestroy();
153
        $this->clearDatabase();
154
      } else {
155
        /** @noinspection PhpUndefinedMethodInspection */
156
        EntityManager::rollback();
157
        $this->workOnDatabaseDestroy();
158
      }
159
    });
160
  }
161
162
  protected function workOnDatabaseDestroy()
163
  {
164
165
  }
166
167
  protected function workOnDatabaseSetUp()
168
  {
169
170
  }
171
172
  /**
173
   * Resolve className according to fm-lib config
174
   * @param string $className
175
   * @return string
176
   */
177
  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...
178
  {
179
    //resolve class name according to fm-lib config
180
    if (config()->has('fm-lib')) {
181
      $config = config('fm-lib');
182
      if (array_key_exists('entityMaps', $config)) {
183
        $classMap = $config['entityMaps'];
184
        if (array_key_exists($className, $classMap)) {
185
          return $classMap[$className];
186
        }
187
      }
188
    }
189
    return $className;
190
  }
191
//</editor-fold desc="Protected Methods">
192
}