Revize ea92a5e5
Přidáno uživatelem Jakub Vašta před téměř 5 roky(ů)
.gitlab-ci.yml | ||
---|---|---|
2 | 2 |
# IMAGE_NAME: zcu-campus-life-app:$CI_COMMIT_REF_NAME |
3 | 3 |
|
4 | 4 |
stages: |
5 |
- test |
|
6 | 5 |
- linter |
7 | 6 |
- build |
7 |
- test |
|
8 | 8 |
- deploy |
9 |
|
|
10 |
unit_tests: |
|
11 |
stage: test |
|
12 |
tags: |
|
13 |
- test |
|
14 |
script: |
|
15 |
- cd website |
|
16 |
- composer require --dev symfony/phpunit-bridge |
|
17 |
- php bin/phpunit |
|
9 |
|
|
18 | 10 |
php_linter: |
19 | 11 |
stage: linter |
20 | 12 |
tags: |
... | ... | |
23 | 15 |
- cd website |
24 | 16 |
- composer require --dev squizlabs/php_codesniffer |
25 | 17 |
- ./vendor/bin/php-cs-fixer fix --dry-run --config .php_cs --stop-on-violation --using-cache=no |
18 |
|
|
26 | 19 |
build: |
27 | 20 |
stage: build |
28 | 21 |
tags: |
29 | 22 |
- build |
30 | 23 |
script: |
31 | 24 |
# Test whether container can be build or not |
32 |
- docker-compose build |
|
25 |
- ./scripts/build.sh |
|
26 |
- docker-compose stop crawler nginx |
|
33 | 27 |
# We could also push docker image to some registry or docker hub |
28 |
|
|
29 |
tests: |
|
30 |
stage: test |
|
31 |
tags: |
|
32 |
- test |
|
33 |
script: |
|
34 |
- cd website |
|
35 |
- composer require --dev symfony/phpunit-bridge |
|
36 |
- composer require --dev symfony/browser-kit symfony/css-selector |
|
37 |
- docker-compose exec -T php-fpm /bin/sh -c "export APP_ENV=test && cd ../symfony && php bin/phpunit" |
|
38 |
- docker stop $(docker ps -q) |
|
34 | 39 |
|
35 | 40 |
deploy_prod: |
36 | 41 |
stage: deploy |
scripts/dev/build.bat | ||
---|---|---|
2 | 2 |
docker-compose exec php-fpm composer config extra.symfony.allow-contrib true --no-interaction --working-dir=/var/www/symfony |
3 | 3 |
docker-compose exec php-fpm composer install --no-interaction --working-dir=/var/www/symfony |
4 | 4 |
docker-compose exec php-fpm composer update --no-interaction --working-dir=/var/www/symfony |
5 |
docker-compose exec php-fpm /bin/sh -c 'cd /var/www/symfony && npm install'
|
|
5 |
docker-compose exec php-fpm /bin/sh -c "cd /var/www/symfony && npm install"
|
|
6 | 6 |
docker-compose exec crawler /bin/sh -c "cd /src && python docker_prepare_structure.py && echo '-all' | python force_update_datasets.py" |
website/.gitignore | ||
---|---|---|
22 | 22 |
|
23 | 23 |
|
24 | 24 |
/.php_cs.dist |
25 |
node_modules |
|
25 |
node_modules |
|
26 |
###> symfony/phpunit-bridge ### |
|
27 |
.phpunit |
|
28 |
.phpunit.result.cache |
|
29 |
/phpunit.xml |
|
30 |
###< symfony/phpunit-bridge ### |
website/bin/phpunit | ||
---|---|---|
1 |
#!/usr/bin/env php |
|
2 |
<?php |
|
3 |
|
|
4 |
if (!file_exists(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) { |
|
5 |
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n"; |
|
6 |
exit(1); |
|
7 |
} |
|
8 |
|
|
9 |
if (false === getenv('SYMFONY_PHPUNIT_DIR')) { |
|
10 |
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit'); |
|
11 |
} |
|
12 |
|
|
13 |
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php'; |
website/composer.json | ||
---|---|---|
20 | 20 |
}, |
21 | 21 |
"require-dev": { |
22 | 22 |
"friendsofphp/php-cs-fixer": "^2.16", |
23 |
"squizlabs/php_codesniffer": "^3.5" |
|
23 |
"squizlabs/php_codesniffer": "^3.5", |
|
24 |
"symfony/browser-kit": "5.0.*", |
|
25 |
"symfony/css-selector": "5.0.*", |
|
26 |
"symfony/phpunit-bridge": "^5.0" |
|
24 | 27 |
}, |
25 | 28 |
"config": { |
26 | 29 |
"preferred-install": { |
website/config/services.yaml | ||
---|---|---|
29 | 29 |
# add more service definitions when explicit configuration is needed |
30 | 30 |
# please note that last definitions always *replace* previous ones |
31 | 31 |
|
32 |
App\OpenData\OpenDataManager: ~ |
|
33 |
App\OpenData\IOpenDataManager: '@App\OpenData\OpenDataManager' |
|
32 |
App\Repository\OpenDataManager: |
|
33 |
arguments: |
|
34 |
$connectionString: '%env(resolve:DATABASE_CONNECTION_STRING)%' |
|
35 |
App\Repository\IOpenDataManager: |
|
36 |
alias: 'App\Repository\OpenDataManager' |
|
37 |
public: true |
|
34 | 38 |
App\Form\Type\DataSetType: ~ |
website/phpunit.xml.dist | ||
---|---|---|
1 |
<phpunit bootstrap="vendor/autoload.php"> |
|
2 |
<testsuites> |
|
3 |
<testsuite name="Project Test Suite"> |
|
4 |
<directory>tests</directory> |
|
5 |
</testsuite> |
|
6 |
</testsuites> |
|
7 |
<php> |
|
8 |
<env name="APP_ENV" value="test" /> |
|
9 |
<env name="KERNEL_CLASS" value="App\Kernel" /> |
|
10 |
<env name="DATABASE_CONNECTION_STRING" value="mongodb://root:root@database" /> |
|
11 |
</php> |
|
12 |
</phpunit> |
website/src/Calculator.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App; |
|
4 |
|
|
5 |
class Calculator { |
|
6 |
public function add($a, $b) { |
|
7 |
return $a + $b; |
|
8 |
} |
|
9 |
} |
website/src/Controller/HeatmapController.php | ||
---|---|---|
4 | 4 |
|
5 | 5 |
use App\Entity\DataSet; |
6 | 6 |
use App\Form\Type\DataSetType; |
7 |
use App\OpenData\IOpenDataManager;
|
|
7 |
use App\Repository\IOpenDataManager;
|
|
8 | 8 |
use Symfony\Component\HttpFoundation\Request; |
9 | 9 |
use Symfony\Component\Routing\Annotation\Route; |
10 | 10 |
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
website/src/Form/DataSetType.php | ||
---|---|---|
4 | 4 |
|
5 | 5 |
use App\Utils\Utils; |
6 | 6 |
use App\Entity\DataSet; |
7 |
use App\OpenData\IOpenDataManager;
|
|
7 |
use App\Repository\IOpenDataManager;
|
|
8 | 8 |
use Symfony\Component\Form\FormView; |
9 | 9 |
use Symfony\Component\Form\AbstractType; |
10 | 10 |
use Symfony\Component\Form\FormInterface; |
website/src/IOpenDataManager.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\OpenData; |
|
4 |
|
|
5 |
interface IOpenDataManager { |
|
6 |
public function getCollectionDataByName($name, $date, $hour); |
|
7 |
|
|
8 |
public function getAvailableCollections(); |
|
9 |
|
|
10 |
public function getAvailableCollectionsByDay($date); |
|
11 |
|
|
12 |
public function isCollectionAvailable($name, $date); |
|
13 |
|
|
14 |
public function getDatesWithAvailableCollection(); |
|
15 |
|
|
16 |
public function getMaxCollectionNumberAtDay($name, $date); |
|
17 |
|
|
18 |
public function getDataSourcePositions($name); |
|
19 |
|
|
20 |
public function getLastAvailableCollections(); |
|
21 |
} |
website/src/OpenDataManager.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\OpenData; |
|
4 |
|
|
5 |
use MongoDB\Driver\Query; |
|
6 |
use MongoDB\Driver\Manager; |
|
7 |
|
|
8 |
class OpenDataManager implements IOpenDataManager { |
|
9 |
private $manager; |
|
10 |
|
|
11 |
public function __construct() { |
|
12 |
$this->manager = new Manager( |
|
13 |
$_ENV['DATABASE_CONNECTION_STRING'] |
|
14 |
); |
|
15 |
} |
|
16 |
|
|
17 |
public function getCollectionDataByName($name, $date, $hour) { |
|
18 |
$valh = $hour < 10 ? '0'.$hour : $hour; |
|
19 |
$openData = $this->manager->executeQuery('open-data-db.'.$name.$date, new Query(['date' => $date.'-'.$valh], [])); |
|
20 |
|
|
21 |
$openData->setTypeMap([ |
|
22 |
'array' => 'array', |
|
23 |
'document' => 'array', |
|
24 |
'root' => 'array', |
|
25 |
]); |
|
26 |
|
|
27 |
return $openData->toArray(); |
|
28 |
} |
|
29 |
|
|
30 |
public function getAvailableCollections() { |
|
31 |
$openData = $this->manager->executeQuery('open-data-db.DATASETS', new Query([], ['projection' => ['key-name' => 1, 'display-name' => 1, '_id' => 0]])); |
|
32 |
|
|
33 |
$openData->setTypeMap([ |
|
34 |
'array' => 'array', |
|
35 |
'document' => 'array', |
|
36 |
'root' => 'array', |
|
37 |
]); |
|
38 |
|
|
39 |
return $openData->toArray(); |
|
40 |
} |
|
41 |
|
|
42 |
public function getAvailableCollectionsByDay($date) { |
|
43 |
$availableInDate = []; |
|
44 |
$available = $this->getAvailableCollections(); |
|
45 |
$index = 0; |
|
46 |
foreach ($available as $key => $value) { |
|
47 |
if ($this->isCollectionAvailable($value['key-name'], $date) && false == array_key_exists($value['key-name'], $availableInDate)) { |
|
48 |
$availableInDate[$value['key-name']] = $value['display-name']; |
|
49 |
} |
|
50 |
} |
|
51 |
|
|
52 |
return $availableInDate; |
|
53 |
} |
|
54 |
|
|
55 |
public function isCollectionAvailable($name, $date) { |
|
56 |
$result = $this->manager->executeQuery('open-data-db.'.$name, new Query(['date' => $date], [])); |
|
57 |
|
|
58 |
return !empty($result->toArray()); |
|
59 |
} |
|
60 |
|
|
61 |
public function getDatesWithAvailableCollection() { |
|
62 |
$available = $this->getAvailableCollections(); |
|
63 |
$result = []; |
|
64 |
|
|
65 |
foreach ($available as $key => $value) { |
|
66 |
$dates = $this->manager->executeQuery('open-data-db.'.$value['key-name'], new Query([], ['projection' => ['date' => true, '_id' => false]])); |
|
67 |
$dates->setTypeMap(['root' => 'array']); |
|
68 |
$result = array_merge($result, array_map(function ($item) {return $item['date']; }, $dates->toArray())); |
|
69 |
} |
|
70 |
|
|
71 |
return array_values(array_unique($result)); |
|
72 |
} |
|
73 |
|
|
74 |
public function getLastAvailableCollections() { |
|
75 |
$available = $this->getAvailableCollections(); |
|
76 |
$result = []; |
|
77 |
|
|
78 |
foreach ($available as $key => $value) { |
|
79 |
$date = $this->manager->executeQuery('open-data-db.'.$value['key-name'], new Query([], ['sort' => ['date' => -1], 'limit' => 1, 'projection' => ['date' => true, '_id' => false]])); |
|
80 |
$date->setTypeMap(['root' => 'array']); |
|
81 |
|
|
82 |
$date_array = $date->toArray(); |
|
83 |
if (!empty($date_array)) { |
|
84 |
$result[$value['key-name']] = $date_array[0]['date']; |
|
85 |
} |
|
86 |
} |
|
87 |
|
|
88 |
return $result; |
|
89 |
} |
|
90 |
|
|
91 |
public function getMaxCollectionNumberAtDay($name, $date) { |
|
92 |
$max = $this->manager->executeQuery('open-data-db.'.$name.$date, new Query([], ['sort' => ['number' => -1], 'limit' => 1])); |
|
93 |
|
|
94 |
$max->setTypeMap([ |
|
95 |
'array' => 'array', |
|
96 |
'document' => 'array', |
|
97 |
'root' => 'array', |
|
98 |
]); |
|
99 |
|
|
100 |
$result = $max->toArray(); |
|
101 |
|
|
102 |
return empty($result) ? 1 : $result[0]['number']; |
|
103 |
} |
|
104 |
|
|
105 |
public function getDataSourcePositions($name = 'NONE') { |
|
106 |
$positions = $this->manager->executeQuery('open-data-db.'.$name.'DEVICES', new Query([], [])); |
|
107 |
|
|
108 |
$positions->setTypeMap([ |
|
109 |
'array' => 'array', |
|
110 |
'document' => 'array', |
|
111 |
'root' => 'array', |
|
112 |
]); |
|
113 |
|
|
114 |
return $positions->toArray(); |
|
115 |
} |
|
116 |
} |
website/src/Repository/IOpenDataManager.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\Repository; |
|
4 |
|
|
5 |
interface IOpenDataManager { |
|
6 |
public function getCollectionDataByName($name, $date, $hour); |
|
7 |
|
|
8 |
public function getAvailableCollections(); |
|
9 |
|
|
10 |
public function getAvailableCollectionsByDay($date); |
|
11 |
|
|
12 |
public function isCollectionAvailable($name, $date); |
|
13 |
|
|
14 |
public function getDatesWithAvailableCollection(); |
|
15 |
|
|
16 |
public function getMaxCollectionNumberAtDay($name, $date); |
|
17 |
|
|
18 |
public function getDataSourcePositions($name); |
|
19 |
|
|
20 |
public function getLastAvailableCollections(); |
|
21 |
} |
website/src/Repository/OpenDataManager.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\Repository; |
|
4 |
|
|
5 |
use MongoDB\Driver\Query; |
|
6 |
use MongoDB\Driver\Manager; |
|
7 |
|
|
8 |
class OpenDataManager implements IOpenDataManager { |
|
9 |
private $manager; |
|
10 |
|
|
11 |
public function __construct($connectionString) { |
|
12 |
$this->manager = new Manager( |
|
13 |
$connectionString |
|
14 |
// $_ENV['DATABASE_CONNECTION_STRING'] |
|
15 |
); |
|
16 |
} |
|
17 |
|
|
18 |
public function getCollectionDataByName($name, $date, $hour) { |
|
19 |
$valh = $hour < 10 ? '0'.$hour : $hour; |
|
20 |
$openData = $this->manager->executeQuery('open-data-db.'.$name.$date, new Query(['date' => $date.'-'.$valh], [])); |
|
21 |
|
|
22 |
$openData->setTypeMap([ |
|
23 |
'array' => 'array', |
|
24 |
'document' => 'array', |
|
25 |
'root' => 'array', |
|
26 |
]); |
|
27 |
|
|
28 |
return $openData->toArray(); |
|
29 |
} |
|
30 |
|
|
31 |
public function getAvailableCollections() { |
|
32 |
$openData = $this->manager->executeQuery('open-data-db.DATASETS', new Query([], ['projection' => ['key-name' => 1, 'display-name' => 1, '_id' => 0]])); |
|
33 |
|
|
34 |
$openData->setTypeMap([ |
|
35 |
'array' => 'array', |
|
36 |
'document' => 'array', |
|
37 |
'root' => 'array', |
|
38 |
]); |
|
39 |
|
|
40 |
return $openData->toArray(); |
|
41 |
} |
|
42 |
|
|
43 |
public function getAvailableCollectionsByDay($date) { |
|
44 |
$availableInDate = []; |
|
45 |
$available = $this->getAvailableCollections(); |
|
46 |
$index = 0; |
|
47 |
foreach ($available as $key => $value) { |
|
48 |
if ($this->isCollectionAvailable($value['key-name'], $date) && false == array_key_exists($value['key-name'], $availableInDate)) { |
|
49 |
$availableInDate[$value['key-name']] = $value['display-name']; |
|
50 |
} |
|
51 |
} |
|
52 |
|
|
53 |
return $availableInDate; |
|
54 |
} |
|
55 |
|
|
56 |
public function isCollectionAvailable($name, $date) { |
|
57 |
$result = $this->manager->executeQuery('open-data-db.'.$name, new Query(['date' => $date], [])); |
|
58 |
|
|
59 |
return !empty($result->toArray()); |
|
60 |
} |
|
61 |
|
|
62 |
public function getDatesWithAvailableCollection() { |
|
63 |
$available = $this->getAvailableCollections(); |
|
64 |
$result = []; |
|
65 |
|
|
66 |
foreach ($available as $key => $value) { |
|
67 |
$dates = $this->manager->executeQuery('open-data-db.'.$value['key-name'], new Query([], ['projection' => ['date' => true, '_id' => false]])); |
|
68 |
$dates->setTypeMap(['root' => 'array']); |
|
69 |
$result = array_merge($result, array_map(function ($item) {return $item['date']; }, $dates->toArray())); |
|
70 |
} |
|
71 |
|
|
72 |
return array_values(array_unique($result)); |
|
73 |
} |
|
74 |
|
|
75 |
public function getLastAvailableCollections() { |
|
76 |
$available = $this->getAvailableCollections(); |
|
77 |
$result = []; |
|
78 |
|
|
79 |
foreach ($available as $key => $value) { |
|
80 |
$date = $this->manager->executeQuery('open-data-db.'.$value['key-name'], new Query([], ['sort' => ['date' => -1], 'limit' => 1, 'projection' => ['date' => true, '_id' => false]])); |
|
81 |
$date->setTypeMap(['root' => 'array']); |
|
82 |
|
|
83 |
$date_array = $date->toArray(); |
|
84 |
if (!empty($date_array)) { |
|
85 |
$result[$value['key-name']] = $date_array[0]['date']; |
|
86 |
} |
|
87 |
} |
|
88 |
|
|
89 |
return $result; |
|
90 |
} |
|
91 |
|
|
92 |
public function getMaxCollectionNumberAtDay($name, $date) { |
|
93 |
$max = $this->manager->executeQuery('open-data-db.'.$name.$date, new Query([], ['sort' => ['number' => -1], 'limit' => 1])); |
|
94 |
|
|
95 |
$max->setTypeMap([ |
|
96 |
'array' => 'array', |
|
97 |
'document' => 'array', |
|
98 |
'root' => 'array', |
|
99 |
]); |
|
100 |
|
|
101 |
$result = $max->toArray(); |
|
102 |
|
|
103 |
return empty($result) ? 1 : $result[0]['number']; |
|
104 |
} |
|
105 |
|
|
106 |
public function getDataSourcePositions($name = 'NONE') { |
|
107 |
$positions = $this->manager->executeQuery('open-data-db.'.$name.'DEVICES', new Query([], [])); |
|
108 |
|
|
109 |
$positions->setTypeMap([ |
|
110 |
'array' => 'array', |
|
111 |
'document' => 'array', |
|
112 |
'root' => 'array', |
|
113 |
]); |
|
114 |
|
|
115 |
return $positions->toArray(); |
|
116 |
} |
|
117 |
} |
website/tests/CalculatorTest.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\tests; |
|
4 |
|
|
5 |
use App\Calculator; |
|
6 |
use PHPUnit\Framework\TestCase; |
|
7 |
|
|
8 |
class CalculatorTest extends TestCase |
|
9 |
{ |
|
10 |
public function testAdd() |
|
11 |
{ |
|
12 |
$calculator = new Calculator(); |
|
13 |
$result = $calculator->add(30, 12); |
|
14 |
|
|
15 |
// assert that your calculator added the numbers correctly! |
|
16 |
$this->assertEquals(42, $result); |
|
17 |
} |
|
18 |
} |
website/tests/Controller/HeatmapControllerTest.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\Tests\Controller; |
|
4 |
|
|
5 |
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; |
|
6 |
|
|
7 |
class HatmapControllerTest extends WebTestCase { |
|
8 |
|
|
9 |
public function testMainPage() { |
|
10 |
$client = static::createClient(); |
|
11 |
$client->request('GET', '/heatmap'); |
|
12 |
$this->assertEquals(200, $client->getResponse()->getStatusCode()); |
|
13 |
} |
|
14 |
} |
website/tests/Controller/HomeControllerTest.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\Tests\Controller; |
|
4 |
|
|
5 |
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; |
|
6 |
|
|
7 |
class HomeControllerTest extends WebTestCase { |
|
8 |
|
|
9 |
public function testMainPage() { |
|
10 |
$client = static::createClient(); |
|
11 |
$client->request('GET', '/'); |
|
12 |
$this->assertEquals(200, $client->getResponse()->getStatusCode()); |
|
13 |
} |
|
14 |
} |
website/tests/Repository/OpenDataManagerTest.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
namespace App\Test\Repository; |
|
4 |
|
|
5 |
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; |
|
6 |
use App\Repository\OpenDataManager; |
|
7 |
|
|
8 |
class OpenDataManagerTest extends KernelTestCase { |
|
9 |
|
|
10 |
private $manager; |
|
11 |
|
|
12 |
protected function setUp() : void { |
|
13 |
$kernel = self::bootKernel(); |
|
14 |
$this->manager = $kernel->getContainer()->get('App\Repository\IOpenDataManager'); |
|
15 |
} |
|
16 |
|
|
17 |
public function testAvailableCollections() { |
|
18 |
$this->assertCount(3, $this->manager->getAvailableCollections()); |
|
19 |
} |
|
20 |
} |
website/tests/bootstrap.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
use Symfony\Component\Dotenv\Dotenv; |
|
4 |
|
|
5 |
require dirname(__DIR__).'/vendor/autoload.php'; |
|
6 |
|
|
7 |
if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) { |
|
8 |
require dirname(__DIR__).'/config/bootstrap.php'; |
|
9 |
} elseif (method_exists(Dotenv::class, 'bootEnv')) { |
|
10 |
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env'); |
|
11 |
} |
Také k dispozici: Unified diff
+ Re #8081
+ tests environmnet prepared
+ fast fix in build script