Commit 4314a975 authored by Mark Harding's avatar Mark Harding

(wip): move visualisation to metric

1 merge request!343WIP: Entity Centric Metrics & Dashboard
Pipeline #84652715 passed with stages
in 10 minutes and 8 seconds
<?php
namespace Minds\Controllers\api\v2\analytics;
use Minds\Api\Factory;
use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Common\Cookie;
use Minds\Entities;
use Minds\Helpers\Counters;
use Minds\Interfaces;
class pageview implements Interfaces\Api, Interfaces\ApiIgnorePam
{
public function get($pages)
{
$dashboardsManager = Di::_()->get('Analytics\Dashboards\Manager');
$id = $pages[0] ?? 'unknown';
$dashboard = $dashboardsManager->getDashboardById($id);
if (isset($_GET['timespan'])) {
$dashboard->setTimespanId($_GET['timespan']);
}
if (isset($_GET['filters'])) {
$filterIds = explode(',', $_GET['filters']);
$dashboard->setFilterIds($filterIds);
}
if (isset($_GET['metric'])) {
$dashboard->setMetricId($_GET['metric']);
}
return Factory::response([
'dashboard' => $dashboard->export(),
]);
}
public function post($pages)
{
return Factory::response([]);
}
public function put($pages)
{
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
......@@ -3,7 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Filters;
use Minds\Traits\MagicAttributes;
abstract class FilterAbstract
abstract class AbstractFilter
{
use MagicAttributes;
......
......@@ -5,7 +5,7 @@ use Minds\Core\Analytics\Dashboards\DashboardCollectionInterface;
class FiltersCollection implements DashboardCollectionInterface
{
/** @var FilterAbstract[] */
/** @var AbstractFilter[] */
private $filters = [];
/** @var string[] */
......@@ -41,10 +41,10 @@ class FiltersCollection implements DashboardCollectionInterface
/**
* Set the filters
* @param FilterAbstract[] $filters
* @param AbstractFilter[] $filters
* @return self
*/
public function addFilters(FilterAbstract ...$filters): self
public function addFilters(AbstractFilter ...$filters): self
{
foreach ($filters as $filter) {
$this->filters[$filter->getId()] = $filter;
......@@ -54,7 +54,7 @@ class FiltersCollection implements DashboardCollectionInterface
/**
* Return the set metrics
* @return FilterAbstract[]
* @return AbstractFilter[]
*/
public function getFilters(): array
{
......
<?php
namespace Minds\Core\Analytics\Dashboards\Filters;
class PlatformFilter extends AbstractFilter
{
/** @var string */
protected $id = "platform";
/** @var string */
protected $label = "Platform types";
public function __construct()
{
$this->options = (new FilterOptions())
->setOptions(
(new FilterOptionsOption())
->setId("all")
->setLabel("All"),
(new FilterOptionsOption())
->setId("browser")
->setLabel("Browser"),
(new FilterOptionsOption())
->setId("mobile")
->setLabel("Mobile")
);
}
}
<?php
namespace Minds\Core\Analytics\Dashboards\Filters;
class ViewsFilter extends FilterAbstract
class ViewTypeFilter extends AbstractFilter
{
/** @var string */
protected $id = "views";
protected $id = "view_type";
/** @var string */
protected $label = "View types";
......
......@@ -6,11 +6,12 @@ use Minds\Core\Di\Di;
use Minds\Traits\MagicAttributes;
/**
* @method MetricAbstract setTimespansCollection(TimespansCollection $timespansCollection)
* @method AbstractMetric setTimespansCollection(TimespansCollection $timespansCollection)
* @method AbstractMetric setFiltersCollection(FiltersCollection $filtersCollection)
* @method string getId()
* @method string getLabel()
*/
abstract class MetricAbstract
abstract class AbstractMetric
{
use MagicAttributes;
......@@ -23,8 +24,11 @@ abstract class MetricAbstract
/** @var string[] */
protected $permissions;
/** @var MetricValues */
protected $values;
/** @var MetricSummary */
protected $summary;
/** @var VisualisationInterface */
protected $visualisation;
/** @var TimespansCollection */
protected $timespansCollection;
......@@ -43,7 +47,8 @@ abstract class MetricAbstract
'id' => (string) $this->id,
'label' => (string) $this->label,
'permissions' => (array) $this->permissions,
'values' => $this->values ? (array) $this->values->export() : null,
'summary' => $this->summary ? (array) $this->summary->export() : null,
'visualisation' => $this->visualisation ? (array) $this->visualisation->export : null,
];
}
}
......@@ -2,8 +2,9 @@
namespace Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Core\Di\Di;
use Minds\Core\Data\Elasticsearch;
class ActiveUsersMetric extends MetricAbstract
class ActiveUsersMetric extends AbstractMetric
{
/** @var string */
protected $id = 'active_users';
......@@ -14,32 +15,29 @@ class ActiveUsersMetric extends MetricAbstract
/** @var array */
protected $permissions = [ 'admin' ];
/** @var MetricValues */
protected $values;
public function __construct($entityCentricManager = null)
public function __construct($es = null)
{
$this->entityCentricManager = $entityCentricManager ?? Di::_()->get('Analytics\EntityCentric\Manager');
$this->es = $es ?? Di::_()->get('Database\ElasticSearch');
}
/**
* Build the metrics
* Build the metric summary
* @return self
*/
public function build(): self
public function buildSummary(): self
{
$timespan = $this->timespansCollection->getSelected();
$filters = $this->filtersCollection->getSelected();
$previousTs = strtotime('-1 ' . $timespan->getAggInterval(), $timespan->getFromTsMs() / 1000) * 1000;
$currentTs = $timespan->getFromTsMs();
$comparisonTsMs = strtotime("-{$timespan->getComparisonInterval()} days", $timespan->getFromTsMs() / 1000) * 1000;
$currentTsMs = $timespan->getFromTsMs();
$must = [];
// Range must be from previous period
$must[]['range'] = [
'@timestamp' => [
'gte' => $previousTs,
'gte' => $comparisonTsMs,
],
];
......@@ -76,34 +74,124 @@ class ActiveUsersMetric extends MetricAbstract
],
];
$response = $this->entityCentricManager->getAggregateByQuery([
'query' => [
'bool' => [
'must' => $must,
$query = [
'index' => 'minds-entitycentric-*',
'size' => 0,
'body' => [
'query' => [
'bool' => [
'must' => $must,
],
],
'aggs' => [
'1' => [
'date_histogram' => [
'field' => '@timestamp',
'fixed_interval' => $timespan->getComparisonInterval(),
'min_doc_count' => 1,
],
'aggs' => [
'2' => [
$aggType => [
'field' => $aggField,
],
],
],
],
],
],
];
$prepared = new ElasticSearch\Prepared\Search();
$prepared->query($query);
$response = $this->es->request($prepared);
$this->values = new MetricSummary();
$this->values->setValue($response['aggregations']['1']['buckets'][1]['2']['value'])
->setComparisonValue($response['aggregations']['1']['buckets'][0]['2']['value'])
->setComparisonInterval($timespan->getComparisonInterval());
return $this;
}
/**
* Build a visualisation for the metric
* @return self
*/
public function buildVisualisation(): self
{
$timespan = $this->timespansCollection->getSelected();
$xValues = [];
$yValues = [];
$must = [];
// Range must be from previous period
$must[]['range'] = [
'@timestamp' => [
'gte' => $timespan->getFromTsMs(),
],
];
// Use our global metrics
$must[]['term'] = [
'entity_urn' => 'urn:metric:global'
];
// Specify the resolution to avoid duplicates
$must[] = [
'term' => [
'resolution' => $timespan->getInterval(),
],
];
// Do the query
$query = [
'index' => 'minds-entitycentric-*',
'size' => 0,
'aggs' => [
'1' => [
'date_histogram' => [
'field' => '@timestamp',
'interval' => $timespan->getAggInterval(),
'min_doc_count' => 1,
'body' => [
'query' => [
'bool' => [
'must' => $must,
],
'aggs' => [
'2' => [
$aggType => [
'field' => $aggField,
],
'aggs' => [
'1' => [
'date_histogram' => [
'field' => '@timestamp',
'interval' => $timespan->getInterval(),
'min_doc_count' => 1,
],
'aggs' => [
'2' => [
'sum' => [
'field' => 'active::total',
],
],
],
],
],
],
]);
];
$prepared = new ElasticSearch\Prepared\Search();
$prepared->query($query);
$response = $this->es->request($prepared);
foreach ($response['aggregations']['1']['buckets'] as $bucket) {
$date = date(Visualisations\ChartVisualisation::DATE_FORMAT, $bucket['key'] / 1000);
$xValues[] = $date;
$yValues[] = $bucket['2']['value'];
}
$this->visualisation = (new Visualisations\ChartVisualisation())
->setXValues($xValues)
->setYValues($yValues)
->setXLabel('Date')
->setYLabel('Count');
$this->values = new MetricsValues();
$this->values->setCurrent($response[0]['1']['2']['value'])
->setPrevious($response[1]['1']['2']['value']);
return $this;
}
}
<?php
namespace Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Traits\MagicAttributes;
/**
* @method MetricSummary setValue(int $value)
* @method MetricSummary setComparisonValue(int $value)
* @method MetricSummary setComparisonInterval(int $interval)
*/
class MetricSummary
{
use MagicAttributes;
/** @var int */
private $value = 0;
/** @var int */
private $comparisonValue = 0;
/** @var int */
private $comparisonInterval = 1;
/**
* Export
* @param array $extras
* @return array
*/
public function export(array $extras = []): array
{
return [
'current_value' => (int) $this->value,
'comparison_value' => (int) $this->comparisonValue,
'comparison_interval' => (int) $this->comparisonInterval,
];
}
}
......@@ -3,13 +3,10 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Traits\MagicAttributes;
class MetricValues
class MetricTimeseries
{
/** @var int */
private $current = 0;
/** @var int */
private $previous = 0;
/** @var array */
private $dateHistogram = [];
/**
* Export
......@@ -19,8 +16,7 @@ class MetricValues
public function export(array $extras = []): array
{
return [
'current' => (int) $current,
'previous' => (int) $previous,
'date_histogram' => (array) $this->dateHistogram,
];
}
}
......@@ -3,11 +3,12 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Core\Di\Di;
use Minds\Core\Analytics\Dashboards\Timespans\TimespansCollection;
use Minds\Core\Analytics\Dashboards\Filters\FiltersCollection;
use Minds\Core\Analytics\Dashboards\DashboardCollectionInterface;
class MetricsCollection implements DashboardCollectionInterface
{
/** @var MetricsAbstract[] */
/** @var AbstractMetric[] */
private $metrics = [];
/** @var string */
......@@ -52,10 +53,10 @@ class MetricsCollection implements DashboardCollectionInterface
/**
* Set the metrics
* @param MetricAbstract[] $metric
* @param AbstractMetric[] $metric
* @return self
*/
public function addMetrics(MetricAbstract ...$metrics): self
public function addMetrics(AbstractMetric ...$metrics): self
{
foreach ($metrics as $metric) {
$this->metrics[$metric->getId()] = $metric;
......@@ -63,21 +64,44 @@ class MetricsCollection implements DashboardCollectionInterface
return $this;
}
/**
* Return the selected metric
* @return AbstractMetric
*/
public function getSelected(): AbstractMetric
{
return $this->metrics[$this->selectedId];
}
/**
* Return the set metrics
* @return MetricAbstract[]
* @return AbstractMetric[]
*/
public function getMetrics(): array
{
return $this->metrics;
}
/**
* Build the metrics
* @return self
*/
public function build(): self
{
// Build all summaries
$this->buildSummaries();
// Build current visualisation
$this->getSelected()->buildVisualisation();
}
public function buildSummaries(): self
{
foreach ($this->metrics as $metric) {
$metric
->setTimespansCollection($this->timespansCollection)
->build();
->setFiltersCollection($this->filtersCollection)
->buildSummary();
}
return $this;
}
......
......@@ -3,7 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Core\Di\Di;
class SignupsMetric extends MetricAbstract
class SignupsMetric extends AbstractMetric
{
/** @var string */
protected $id = 'signups';
......@@ -29,15 +29,15 @@ class SignupsMetric extends MetricAbstract
public function build(): self
{
$timespan = $this->timespansCollection->getSelected();
$previousTs = strtotime('-1 ' . $timespan->getAggInterval(), $timespan->getFromTsMs() / 1000) * 1000;
$currentTs = $timespan->getFromTsMs();
$comparisonTsMs = strtotime("-{$timespan->getComparisonInterval()} days", $timespan->getFromTsMs() / 1000) * 1000;
$currentTsMs = $timespan->getFromTsMs();
$must = [];
// Range must be from previous period
$must[]['range'] = [
'@timestamp' => [
'gte' => $previousTs,
'gte' => $comparisonTsMs,
],
];
......@@ -83,8 +83,10 @@ class SignupsMetric extends MetricAbstract
]);
$this->values = new MetricsValues();
$this->values->setCurrent($response[0]['1']['2']['value'])
->setPrevious($response[1]['1']['2']['value']);
$this->values
->setValue($response[0]['1']['2']['value'])
->setComparisonValue($response[1]['1']['2']['value'])
->setComparisonInterval($this->getComparisonInterval());
return $this;
}
}
......@@ -3,7 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Core\Di\Di;
class ViewsMetric extends MetricAbstract
class ViewsMetric extends AbstractMetric
{
/** @var string */
protected $id = 'views';
......@@ -14,8 +14,8 @@ class ViewsMetric extends MetricAbstract
/** @var array */
protected $permissions = [ 'admin' ];
/** @var MetricValues */
protected $values;
/** @var MetricSummary */
protected $summary;
public function __construct($entityCentricManager = null)
{
......@@ -29,13 +29,13 @@ class ViewsMetric extends MetricAbstract
public function build(): self
{
$timespan = $this->timespansCollection->getSelected();
$previousTs = strtotime('-1 ' . $timespan->getAggInterval(), $timespan->getFromTsMs() / 1000) * 1000;
$currentTs = $timespan->getFromTsMs();
$comparisonTsMs = strtotime("-{$timespan->getComparisonInterval()} days", $timespan->getFromTsMs() / 1000) * 1000;
$currentTsMs = $timespan->getFromTsMs();
$must = [];
$must[]['range'] = [
'@timestamp' => [
'gte' => $previousTs,
'gte' => $comparisonTsMs,
],
];
......@@ -76,9 +76,11 @@ class ViewsMetric extends MetricAbstract
],
]);
$this->values = new MetricsValues();
$this->values->setCurrent($response[0]['1']['2']['value'])
->setPrevious($response[1]['1']['2']['value']);
$this->summary = new MetricSummary();
$this->summary
->setValue($response[0]['1']['2']['value'])
->setComparisonValue($response[1]['1']['2']['value'])
->setComparisonInterval($this->getComparisonInterval());
return $this;
}
}
<?php
namespace Minds\Core\Analytics\Dashboards\Metrics\Visualisations;
use Minds\Traits\MagicAttributes;
abstract class AbstractVisualisation implements VisualisationInterface
{
use MagicAttributes;
/** @var string */
private $type;
public function export(array $extras = []): array
{
return [
];
}
}
<?php
namespace Minds\Core\Analytics\Dashboards\Metrics\Visualisations;
use Minds\Traits\MagicAttributes;
class ChartVisualisation extends AbstractVisualisation
{
use MagicAttributes;
const DATE_FORMAT = "d-m-Y";
/** @var string */
private $type = 'chart';
/** @var string */
private $xLabel = 'Date';
/** @var array */
private $xValues;
/** @var string */
private $yLabel = 'count';
/** @var array */
private $yValues;
/**
* Export
* @param array $extras
* @return array
*/
public function export(array $extras = []): array
{
return [
'type' => $this->type,
'x' => [
'values' => (array) $this->xValues,
'label' => $this->xLabel,
],
'y' => [
'values' => (array) $this->yValues,
'label' => $this->yLabel,
],
];
}
}
<?php
namespace Minds\Core\Analytics\Dashboards\Metrics\Visualisations;
use Minds\Traits\MagicAttributes;
class TableVisualisation extends AbstractVisualisation
{
use MagicAttributes;
const DATE_FORMAT = "d-m-Y";
/** @var string */
private $type = 'table';
/** @var array */
private $rows;
/**
* Export
* @param array $extras
* @return array
*/
public function export(array $extras = []): array
{
return [
'type' => $this->type,
'rows' => (array) $this->rows,
];
}
}
<?php
namespace Minds\Core\Analytics\Dashboards\Metrics\Visualisations;
interface VisualisationInterface
{
}
......@@ -7,8 +7,10 @@ use Minds\Traits\MagicAttributes;
* @method string getId()
* @method string getLabel()
* @method string getInterval()
* @method int getComparisonInterval()
* @method int getFromTsMs()
*/
abstract class TimespanAbstract
abstract class AbstractTimespan
{
use MagicAttributes;
......@@ -24,11 +26,8 @@ abstract class TimespanAbstract
/** @var int */
protected $fromTsMs;
/** @var int */
protected $previousFromTsMs;
/** @var string */
protected $aggInterval = 'day';
protected $comparisonInterval = 'day';
/**
* Export
......@@ -41,7 +40,7 @@ abstract class TimespanAbstract
'id' => (string) $this->id,
'label' => (string) $this->label,
'interval' => (string) $this->interval,
'agg_interval' => (string) $this->aggInterval,
'comparison_interval' => (string) $this->comparisonInterval,
'from_ts_ms' => (int) $this->fromTsMs,
];
}
......
<?php
namespace Minds\Core\Analytics\Dashboards\Timespans;
class MtdTimespan extends TimespanAbstract
class MtdTimespan extends AbstractTimespan
{
/** @var string */
protected $id = 'mtd';
......@@ -16,7 +16,7 @@ class MtdTimespan extends TimespanAbstract
protected $fromTsMs;
/** @var string */
protected $aggInterval = 'month';
protected $comparisonInterval = 'month';
public function __construct()
{
......
......@@ -5,7 +5,7 @@ use Minds\Core\Analytics\Dashboards\DashboardCollectionInterface;
class TimespansCollection implements DashboardCollectionInterface
{
/** @var TimespanAbstract[] */
/** @var AbstractTimespan[] */
private $timespans = [];
/** @var string */
......@@ -24,19 +24,19 @@ class TimespansCollection implements DashboardCollectionInterface
/**
* Return the selected timespan
* @return TimespanAbstract
* @return AbstractTimespan
*/
public function getSelected(): TimespanAbstract
public function getSelected(): AbstractTimespan
{
return $this->timespans[$this->selectedId];
}
/**
* Set the timespans
* @param TimespanAbstract[] $timespans
* @param AbstractTimespan[] $timespans
* @return self
*/
public function addTimespans(TimespanAbstract ...$timespans): self
public function addTimespans(AbstractTimespan ...$timespans): self
{
foreach ($timespans as $timespan) {
$this->timespans[$timespan->getId()] = $timespan;
......
......@@ -6,7 +6,7 @@ namespace Minds\Core\Analytics\Dashboards\Timespans;
* @method string getLabel()
* @method string getInterval()
*/
class TodayTimespan extends TimespanAbstract
class TodayTimespan extends AbstractTimespan
{
/** @var string */
protected $id = 'today';
......@@ -21,7 +21,7 @@ class TodayTimespan extends TimespanAbstract
protected $fromTsMs;
/** @var string */
protected $aggInterval = 'day';
protected $comparisonInterval = 'day';
public function __construct()
{
......
<?php
namespace Minds\Core\Analytics\Dashboards\Timespans;
class YtdTimespan extends TimespanAbstract
class YtdTimespan extends AbstractTimespan
{
/** @var string */
protected $id = 'ytd';
......@@ -16,7 +16,7 @@ class YtdTimespan extends TimespanAbstract
protected $fromTsMs;
/** @var string */
protected $aggInterval = 'year';
protected $comparisonInterval = 'year';
public function __construct()
{
......
......@@ -15,13 +15,13 @@ class TrafficDashboard implements DashboardInterface
use MagicAttributes;
/** @var string */
private $timespanId;
private $timespanId = 'mtd';
/** @var string[] */
private $filterIds;
private $filterIds = [ 'platform::browser' ];
/** @var string */
private $metricId;
private $metricId = 'active_users';
/** @var Timespans\TimespansCollection */
private $timespansCollection;
......@@ -32,19 +32,17 @@ class TrafficDashboard implements DashboardInterface
/** @var Filters\FiltersCollection */
private $filtersCollection;
/** @var Visualisations\Charts\ChartsCollection */
private $chartsCollection;
/** @var Visualisations\Chart\ChartSegmentsCollection */
private $chartCollection;
public function __construct(
$timespansCollection = null,
$metricsCollection = null,
$filtersCollection = null,
$chartsCollection = null
$filtersCollection = null
) {
$this->timespansCollection = $timespansCollection ?? new Timespans\TimespansCollection();
$this->metricsCollection = $metricsCollection ?? new Metrics\MetricsCollection();
$this->filtersCollection = $filtersCollection ?? new Filters\FiltersCollection();
$this->chartsCollection = $chartsCollection ?? new Visualisations\Charts\ChartsCollection();
}
/**
......@@ -55,7 +53,7 @@ class TrafficDashboard implements DashboardInterface
{
$this->timespansCollection
->setSelectedId($this->timespanId)
->addTimespan(
->addTimespans(
new Timespans\TodayTimespan(),
new Timespans\MtdTimespan(),
new Timespans\YtdTimespan()
......@@ -76,9 +74,6 @@ class TrafficDashboard implements DashboardInterface
new Metrics\ViewsMetric()
)
->build();
$this->chartsCollection
->setTimespansCollection($this->timespansCollection)
->setMetricsCollection($this->metricsCollection);
return $this;
}
......@@ -92,11 +87,10 @@ class TrafficDashboard implements DashboardInterface
{
return [
'category' => 'traffic',
'timespan' => $this->timespansCollection->getSelected->getId(),
'timespan' => $this->timespansCollection->getSelected()->getId(),
'timespans' => $this->timespansCollection->export(),
'metrics' => $this->metricsCollection->export(),
'charts' => $this->chartCollection->export(),
'filter' => $this->filtersCollection->getSelected->getId(),
'filter' => $this->filtersCollection->getSelected()->getId(),
'filters' => $this->filtersCollection->export(),
];
}
......
<?php
namespace Minds\Core\Analytics\Dashboards\Visualisations\Charts;
class ChartsCollection
{
}
......@@ -3,7 +3,7 @@
namespace Spec\Minds\Core\Analytics\Dashboards\Filters;
use Minds\Core\Analytics\Dashboards\Filters\FiltersCollection;
use Minds\Core\Analytics\Dashboards\Filters\ViewsFilter;
use Minds\Core\Analytics\Dashboards\Filters\ViewTypeFilter;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
......@@ -16,18 +16,18 @@ class FiltersCollectionSpec extends ObjectBehavior
public function it_should_add_filters_to_collection()
{
$this->addFilters(new ViewsFilter);
$this->addFilters(new ViewTypeFilter);
$filters = $this->getFilters();
$filters['views']->getId()
->shouldBe('views');
$filters['view_type']->getId()
->shouldBe('view_type');
}
public function it_should_export_filters()
{
$this->addFilters(new ViewsFilter);
$this->addFilters(new ViewTypeFilter);
$export = $this->export();
$export[0]['id']
->shouldBe('views');
->shouldBe('view_type');
$export[0]['options']
->shouldHaveCount(4);
}
......
<?php
namespace Spec\Minds\Core\Analytics\Dashboards\Metrics;
use Minds\Core\Analytics\Dashboards\Metrics\ActiveUsersMetric;
use Minds\Core\Analytics\Dashboards\Timespans\TimespansCollection;
use Minds\Core\Analytics\Dashboards\Timespans\AbstractTimespan;
use Minds\Core\Analytics\Dashboards\Filters\FiltersCollection;
use Minds\Core\Analytics\Dashboards\Filters\AbstractFilter;
use Minds\Core\Data\Elasticsearch\Client;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ActiveUsersMetricSpec extends ObjectBehavior
{
private $es;
private $timespansCollection;
private $filtersCollection;
public function let(Client $es, TimespansCollection $timespansCollection, FiltersCollection $filtersCollection)
{
$this->beConstructedWith($es);
$this->es = $es;
$this->setTimespansCollection($timespansCollection);
$this->setFiltersCollection($filtersCollection);
$this->timespansCollection = $timespansCollection;
$this->filtersCollection = $filtersCollection;
}
public function it_is_initializable()
{
$this->shouldHaveType(ActiveUsersMetric::class);
}
public function it_should_build_summary(AbstractTimespan $mockTimespan, AbstractFilter $mockFilter)
{
$this->timespansCollection->getSelected()
->willReturn($mockTimespan);
$this->filtersCollection->getSelected()
->willReturn([$mockFilter]);
$this->es->request(Argument::any())
->willReturn([
'aggregations' => [
'1' => [
'buckets' => [
[
'key' => strtotime('Midnight 1st December 2018') * 1000,
'2' => [
'value' => 256,
],
],
[
'key' => strtotime('Midnight 1st December 2019') * 1000,
'2' => [
'value' => 128,
],
],
],
],
]
]);
$this->buildSummary();
$this->values->getValue()
->shouldBe(128);
$this->values->getComparisonValue()
->shouldBe(256);
}
public function it_should_build_visualisation(AbstractTimespan $mockTimespan, AbstractFilter $mockFilter)
{
$this->timespansCollection->getSelected()
->willReturn($mockTimespan);
$this->filtersCollection->getSelected()
->willReturn([$mockFilter]);
$this->es->request(Argument::any())
->willReturn([
'aggregations' => [
'1' => [
'buckets' => [
[
'key' => strtotime('Midnight 1st December 2018') * 1000,
'2' => [
'value' => 256,
],
],
[
'key' => strtotime('Midnight 1st January 2019') * 1000,
'2' => [
'value' => 128,
],
],
[
'key' => strtotime('Midnight 1st February 2019') * 1000,
'2' => [
'value' => 4,
],
],
[
'key' => strtotime('Midnight 1st March 2019') * 1000,
'2' => [
'value' => 685,
],
],
],
],
]
]);
$this->buildVisualisation();
$xValues = $this->getVisualisation()->getXValues();
$xValues[0]->shouldBe('01-12-2018');
$xValues[1]->shouldBe('01-01-2019');
$xValues[2]->shouldBe('01-02-2019');
$xValues[3]->shouldBe('01-03-2019');
$yValues = $this->getVisualisation()->getYValues();
$yValues[0]->shouldBe(256);
$yValues[1]->shouldBe(128);
$yValues[2]->shouldBe(4);
$yValues[3]->shouldBe(685);
}
}
......@@ -7,6 +7,7 @@ use Minds\Core\Analytics\Dashboards\Metrics\ActiveUsersMetric;
use Minds\Core\Analytics\Dashboards\Metrics\SignupsMetric;
use Minds\Core\Analytics\Dashboards\Metrics\ViewsMetric;
use Minds\Core\Analytics\Dashboards\Timespans\TimespansCollection;
use Minds\Core\Analytics\Dashboards\Filters\FiltersCollection;
use Minds\Core\Analytics\Dashboards\Timespans\TodayTimespan;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
......@@ -21,6 +22,7 @@ class MetricsCollectionSpec extends ObjectBehavior
$this->timespansCollection = $timespansCollection;
$this->todayTimespan = $todayTimespan;
$this->setTimespansCollection($timespansCollection);
$this->setFiltersCollection(new FiltersCollection());
$this->timespansCollection->setSelectedId('today');
}
......@@ -61,9 +63,12 @@ class MetricsCollectionSpec extends ObjectBehavior
$activeUsersMetric->setTimespansCollection($this->timespansCollection)
->shouldBeCalled()
->willReturn($activeUsersMetric);
$activeUsersMetric->build()
$activeUsersMetric->setFiltersCollection(Argument::type(FiltersCollection::class))
->shouldBeCalled()
->willReturn($activeUsersMetric);
$activeUsersMetric->buildSummary()
->shouldBeCalled();
$this->addMetrics($activeUsersMetric);
$this->build();
$this->buildSummaries();
}
}
......@@ -3,13 +3,60 @@
namespace Spec\Minds\Core\Analytics\Dashboards;
use Minds\Core\Analytics\Dashboards\TrafficDashboard;
use Minds\Core\Analytics\Dashboards\Timespans\TimespansCollection;
use Minds\Core\Analytics\Dashboards\Metrics\MetricsCollection;
use Minds\Core\Analytics\Dashboards\Metrics\AbstractMetric;
use Minds\Core\Analytics\Dashboards\Filters\FiltersCollection;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class TrafficDashboardSpec extends ObjectBehavior
{
function it_is_initializable()
private $timespansCollection;
private $metricsCollection;
private $filtersCollection;
public function let(TimespansCollection $timespansCollection, MetricsCollection $metricsCollection, FiltersCollection $filtersCollection)
{
$this->beConstructedWith(null, $metricsCollection, null);
$this->timespansCollection = $timespansCollection;
$this->metricsCollection = $metricsCollection;
$this->filtersCollection = $filtersCollection;
}
public function it_is_initializable()
{
$this->shouldHaveType(TrafficDashboard::class);
}
public function it_should_build_dashboard(AbstractMetric $mockMetric)
{
$this->setTimespanId('today');
$this->setFilterIds([
'platform::browser'
]);
// Metrics
$this->metricsCollection->setTimespansCollection(Argument::type(TimespansCollection::class))
->willReturn($this->metricsCollection);
$this->metricsCollection->setFiltersCollection(Argument::type(FiltersCollection::class))
->willReturn($this->metricsCollection);
$this->metricsCollection->setSelectedId('active_users')
->willReturn($this->metricsCollection);
$this->metricsCollection->addMetrics(Argument::any(), Argument::any(), Argument::any())
->shouldBeCalled()
->willReturn($this->metricsCollection);
$this->metricsCollection->build()
->shouldBeCalled()
->willReturn($this->metricsCollection);
$this->metricsCollection->getSelected()
->willReturn($mockMetric);
$this->build();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment