Metrics: Added configured locales and themes, refactoring/formatting
This commit is contained in:
parent
4d8e568ff8
commit
e2e2ac0c68
|
@ -70,17 +70,17 @@ return [
|
|||
'available_themes' => [
|
||||
'12' => 'Engelsystem 36c3 (2019)',
|
||||
'10' => 'Engelsystem cccamp19 green (2019)',
|
||||
'9' => 'Engelsystem cccamp19 yellow (2019)',
|
||||
'8' => 'Engelsystem cccamp19 blue (2019)',
|
||||
'7' => 'Engelsystem 35c3 dark (2018)',
|
||||
'6' => 'Engelsystem 34c3 dark (2017)',
|
||||
'5' => 'Engelsystem 34c3 light (2017)',
|
||||
'4' => 'Engelsystem 33c3 (2016)',
|
||||
'3' => 'Engelsystem 32c3 (2015)',
|
||||
'2' => 'Engelsystem cccamp15',
|
||||
'9' => 'Engelsystem cccamp19 yellow (2019)',
|
||||
'8' => 'Engelsystem cccamp19 blue (2019)',
|
||||
'7' => 'Engelsystem 35c3 dark (2018)',
|
||||
'6' => 'Engelsystem 34c3 dark (2017)',
|
||||
'5' => 'Engelsystem 34c3 light (2017)',
|
||||
'4' => 'Engelsystem 33c3 (2016)',
|
||||
'3' => 'Engelsystem 32c3 (2015)',
|
||||
'2' => 'Engelsystem cccamp15',
|
||||
'11' => 'Engelsystem high contrast',
|
||||
'0' => 'Engelsystem light',
|
||||
'1' => 'Engelsystem dark',
|
||||
'0' => 'Engelsystem light',
|
||||
'1' => 'Engelsystem dark',
|
||||
],
|
||||
|
||||
// Redirect to this site after logging in or when pressing the top-left button
|
||||
|
@ -152,7 +152,7 @@ return [
|
|||
'voucher_start' => null,
|
||||
],
|
||||
|
||||
// Available locales in /locale/
|
||||
// Available locales in /resources/lang/
|
||||
'locales' => [
|
||||
'de_DE' => 'Deutsch',
|
||||
'en_US' => 'English',
|
||||
|
|
|
@ -8,6 +8,7 @@ use Engelsystem\Helpers\Version;
|
|||
use Engelsystem\Http\Exceptions\HttpForbidden;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Illuminate\Support\Collection;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class Controller extends BaseController
|
||||
|
@ -62,16 +63,9 @@ class Controller extends BaseController
|
|||
$now = microtime(true);
|
||||
$this->checkAuth();
|
||||
|
||||
$tshirtSizes = [];
|
||||
$userSizes = $this->stats->tshirtSizes();
|
||||
|
||||
foreach ($this->config->get('tshirt_sizes') as $name => $description) {
|
||||
$size = $userSizes->where('shirt_size', '=', $name)->sum('count');
|
||||
$tshirtSizes[] = [
|
||||
'labels' => ['size' => $name],
|
||||
$size,
|
||||
];
|
||||
}
|
||||
$userTshirtSizes = $this->formatStats($this->stats->tshirtSizes(), 'tshirt_sizes', 'shirt_size', 'size');
|
||||
$userLocales = $this->formatStats($this->stats->languages(), 'locales', 'language', 'locale');
|
||||
$userThemes = $this->formatStats($this->stats->themes(), 'available_themes', 'theme');
|
||||
|
||||
$data = [
|
||||
$this->config->get('app_name') . ' stats',
|
||||
|
@ -117,7 +111,12 @@ class Controller extends BaseController
|
|||
'worklog_seconds' => ['type' => 'gauge', $this->stats->worklogSeconds()],
|
||||
'vouchers' => ['type' => 'counter', $this->stats->vouchers()],
|
||||
'tshirts_issued' => ['type' => 'counter', 'help' => 'Issued T-Shirts', $this->stats->tshirts()],
|
||||
'tshirt_sizes' => ['type' => 'gauge', 'help' => 'The sizes users have configured'] + $tshirtSizes,
|
||||
'tshirt_sizes' => [
|
||||
'type' => 'gauge',
|
||||
'help' => 'The sizes users have configured'
|
||||
] + $userTshirtSizes,
|
||||
'locales' => ['type' => 'gauge', 'help' => 'The locales users have configured'] + $userLocales,
|
||||
'themes' => ['type' => 'gauge', 'help' => 'The themes users have configured'] + $userThemes,
|
||||
'shifts' => ['type' => 'gauge', $this->stats->shifts()],
|
||||
'announcements' => [
|
||||
'type' => 'gauge',
|
||||
|
@ -212,4 +211,27 @@ class Controller extends BaseController
|
|||
|
||||
throw new HttpForbidden($message, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the stats collection as stats data
|
||||
*
|
||||
* @param Collection $data
|
||||
* @param string $config
|
||||
* @param string $dataField
|
||||
* @param string|null $label
|
||||
* @return array
|
||||
*/
|
||||
protected function formatStats(Collection $data, string $config, string $dataField, ?string $label = null): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($this->config->get($config) as $name => $description) {
|
||||
$count = $data->where($dataField, '=', $name)->sum('count');
|
||||
$return[] = [
|
||||
'labels' => [($label ?: $dataField) => $name],
|
||||
$count,
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,10 @@ use Engelsystem\Models\Message;
|
|||
use Engelsystem\Models\News;
|
||||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\User\PasswordReset;
|
||||
use Engelsystem\Models\User\PersonalData;
|
||||
use Engelsystem\Models\User\Settings;
|
||||
use Engelsystem\Models\User\State;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use Illuminate\Database\Query\Expression as QueryExpression;
|
||||
use Illuminate\Support\Collection;
|
||||
|
@ -94,8 +97,7 @@ class Stats
|
|||
*/
|
||||
public function currentlyWorkingUsers(bool $freeloaded = null): int
|
||||
{
|
||||
$query = $this
|
||||
->getQuery('users')
|
||||
$query = User::query()
|
||||
->join('ShiftEntry', 'ShiftEntry.UID', '=', 'users.id')
|
||||
->join('Shifts', 'Shifts.SID', '=', 'ShiftEntry.SID')
|
||||
->where('Shifts.start', '<=', time())
|
||||
|
@ -129,11 +131,32 @@ class Stats
|
|||
*/
|
||||
public function tshirtSizes(): Collection
|
||||
{
|
||||
return $this
|
||||
->getQuery('users_personal_data')
|
||||
return PersonalData::query()
|
||||
->select(['shirt_size', $this->raw('COUNT(shirt_size) AS count')])
|
||||
->whereNotNull('shirt_size')
|
||||
->groupBy('shirt_size')
|
||||
->groupBy(['shirt_size'])
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function languages(): Collection
|
||||
{
|
||||
return Settings::query()
|
||||
->select(['language', $this->raw('COUNT(language) AS count')])
|
||||
->groupBy(['language'])
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function themes(): Collection
|
||||
{
|
||||
return Settings::query()
|
||||
->select(['theme', $this->raw('COUNT(theme) AS count')])
|
||||
->groupBy(['theme'])
|
||||
->get();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Engelsystem\Test\Unit\Controllers\Metrics;
|
||||
|
||||
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Controllers\Metrics\Controller;
|
||||
use Engelsystem\Controllers\Metrics\MetricsEngine;
|
||||
|
@ -18,9 +19,12 @@ use Symfony\Component\HttpFoundation\ServerBag;
|
|||
|
||||
class ControllerTest extends TestCase
|
||||
{
|
||||
use ArraySubsetAsserts;
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Controller::__construct
|
||||
* @covers \Engelsystem\Controllers\Metrics\Controller::metrics
|
||||
* @covers \Engelsystem\Controllers\Metrics\Controller::formatStats
|
||||
*/
|
||||
public function testMetrics()
|
||||
{
|
||||
|
@ -48,6 +52,8 @@ class ControllerTest extends TestCase
|
|||
$this->assertArrayHasKey('vouchers', $data);
|
||||
$this->assertArrayHasKey('tshirts_issued', $data);
|
||||
$this->assertArrayHasKey('tshirt_sizes', $data);
|
||||
$this->assertArrayHasKey('locales', $data);
|
||||
$this->assertArrayHasKey('themes', $data);
|
||||
$this->assertArrayHasKey('shifts', $data);
|
||||
$this->assertArrayHasKey('announcements', $data);
|
||||
$this->assertArrayHasKey('questions', $data);
|
||||
|
@ -59,6 +65,12 @@ class ControllerTest extends TestCase
|
|||
$this->assertArrayHasKey('log_entries', $data);
|
||||
$this->assertArrayHasKey('scrape_duration_seconds', $data);
|
||||
|
||||
$this->assertArraySubset(['tshirt_sizes' => [
|
||||
'type' => 'gauge',
|
||||
['labels' => ['size' => 'L'], 2],
|
||||
['labels' => ['size' => 'XL'], 0]
|
||||
]], $data);
|
||||
|
||||
return 'metrics return';
|
||||
});
|
||||
|
||||
|
@ -113,7 +125,13 @@ class ControllerTest extends TestCase
|
|||
$this->setExpects($stats, 'vouchers', null, 17);
|
||||
$this->setExpects($stats, 'tshirts', null, 3);
|
||||
$this->setExpects($stats, 'tshirtSizes', null, new Collection([
|
||||
(object)['shirt_size' => 'L', 'count' => 2],
|
||||
['shirt_size' => 'L', 'count' => 2],
|
||||
]));
|
||||
$this->setExpects($stats, 'languages', null, new Collection([
|
||||
['language' => 'en_US', 'count' => 5],
|
||||
]));
|
||||
$this->setExpects($stats, 'themes', null, new Collection([
|
||||
['theme' => '1', 'count' => 3],
|
||||
]));
|
||||
$this->setExpects($stats, 'shifts', null, 142);
|
||||
$this->setExpects($stats, 'messages', null, 3);
|
||||
|
@ -125,6 +143,14 @@ class ControllerTest extends TestCase
|
|||
'L' => 'Large',
|
||||
'XL' => 'X Large',
|
||||
]);
|
||||
$config->set('locales', [
|
||||
'de_DE' => 'German',
|
||||
'en_US' => 'US English',
|
||||
]);
|
||||
$config->set('available_themes', [
|
||||
'0' => 'Nothing',
|
||||
'1' => 'Testing',
|
||||
]);
|
||||
|
||||
$this->setExpects($version, 'getVersion', [], '0.42.42');
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use Engelsystem\Models\News;
|
|||
use Engelsystem\Models\Question;
|
||||
use Engelsystem\Models\User\PasswordReset;
|
||||
use Engelsystem\Models\User\PersonalData;
|
||||
use Engelsystem\Models\User\Settings;
|
||||
use Engelsystem\Models\User\State;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\HasDatabase;
|
||||
|
@ -58,7 +59,6 @@ class StatsTest extends TestCase
|
|||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::tshirtSizes
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::raw
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::getQuery
|
||||
*/
|
||||
public function testTshirtSizes()
|
||||
{
|
||||
|
@ -68,11 +68,44 @@ class StatsTest extends TestCase
|
|||
$sizes = $stats->tshirtSizes();
|
||||
$this->assertCount(2, $sizes);
|
||||
$this->assertEquals([
|
||||
(object)['shirt_size' => 'L', 'count' => 2],
|
||||
(object)['shirt_size' => 'XXL', 'count' => 1],
|
||||
['shirt_size' => 'L', 'count' => 2],
|
||||
['shirt_size' => 'XXL', 'count' => 1],
|
||||
], $sizes->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::languages
|
||||
*/
|
||||
public function testLanguages()
|
||||
{
|
||||
$this->addUsers();
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$languages = $stats->languages();
|
||||
$this->assertCount(2, $languages);
|
||||
$this->assertEquals([
|
||||
['language' => 'lo_RM', 'count' => 2],
|
||||
['language' => 'te_ST', 'count' => 7],
|
||||
], $languages->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::themes
|
||||
*/
|
||||
public function testThemes()
|
||||
{
|
||||
$this->addUsers();
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$themes = $stats->themes();
|
||||
$this->assertCount(3, $themes);
|
||||
$this->assertEquals([
|
||||
['theme' => 0, 'count' => 7],
|
||||
['theme' => 1, 'count' => 1],
|
||||
['theme' => 4, 'count' => 1],
|
||||
], $themes->toArray());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::announcements
|
||||
|
@ -118,7 +151,7 @@ class StatsTest extends TestCase
|
|||
$this->addUsers();
|
||||
|
||||
$stats = new Stats($this->database);
|
||||
$this->assertEquals(6, $stats->arrivedUsers());
|
||||
$this->assertEquals(7, $stats->arrivedUsers());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,6 +182,7 @@ class StatsTest extends TestCase
|
|||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::sessions
|
||||
* @covers \Engelsystem\Controllers\Metrics\Stats::getQuery
|
||||
*/
|
||||
public function testSessions()
|
||||
{
|
||||
|
@ -223,18 +257,20 @@ class StatsTest extends TestCase
|
|||
$this->addUser();
|
||||
$this->addUser([], ['shirt_size' => 'L']);
|
||||
$this->addUser(['arrived' => 1]);
|
||||
$this->addUser(['arrived' => 1, 'got_voucher' => 2], ['shirt_size' => 'XXL']);
|
||||
$this->addUser(['arrived' => 1, 'got_voucher' => 9]);
|
||||
$this->addUser(['arrived' => 1, 'got_voucher' => 3, 'force_active' => true]);
|
||||
$this->addUser(['arrived' => 1], [], ['language' => 'lo_RM']);
|
||||
$this->addUser(['arrived' => 1, 'got_voucher' => 2], ['shirt_size' => 'XXL'], ['language' => 'lo_RM']);
|
||||
$this->addUser(['arrived' => 1, 'got_voucher' => 9, 'force_active' => true], [], ['theme' => 1]);
|
||||
$this->addUser(['arrived' => 1, 'got_voucher' => 3], ['theme' => 10]);
|
||||
$this->addUser(['arrived' => 1, 'active' => 1, 'got_shirt' => true, 'force_active' => true]);
|
||||
$this->addUser(['arrived' => 1, 'active' => 1, 'got_shirt' => true], ['shirt_size' => 'L']);
|
||||
$this->addUser(['arrived' => 1, 'active' => 1, 'got_shirt' => true], ['shirt_size' => 'L'], ['theme' => 4]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $state
|
||||
* @param array $personalData
|
||||
* @param array $settings
|
||||
*/
|
||||
protected function addUser(array $state = [], $personalData = [])
|
||||
protected function addUser(array $state = [], $personalData = [], $settings = [])
|
||||
{
|
||||
$name = 'user_' . Str::random(5);
|
||||
|
||||
|
@ -255,6 +291,16 @@ class StatsTest extends TestCase
|
|||
$personalData->user()
|
||||
->associate($user)
|
||||
->save();
|
||||
|
||||
$settings = new Settings(array_merge([
|
||||
'language' => 'te_ST',
|
||||
'theme' => 0,
|
||||
'email_human' => '',
|
||||
'email_shiftinfo' => '',
|
||||
], $settings));
|
||||
$settings->user()
|
||||
->associate($user)
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue