Skip to content

Commit c02dd6c

Browse files
qschmickroshangautam
authored andcommitted
refactor(stats) : task stats calculations
1 parent aa7aa0e commit c02dd6c

File tree

4 files changed

+125
-2
lines changed

4 files changed

+125
-2
lines changed

database/factories/ModelFactory.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,14 @@
3232
'expression' => '* * * * *',
3333
];
3434
});
35+
36+
$factory->define(Studio\Totem\Result::class, function (Faker\Generator $faker) {
37+
return [
38+
'task_id' => $faker->randomDigit,
39+
'ran_at' => $faker->dateTimeBetween('-1 hour'),
40+
'duration' => (string) $faker->randomFloat(11, 0, 8000000),
41+
'result' => $faker->sentence,
42+
'created_at' => $faker->dateTimeBetween('-1 year', '-6 months'),
43+
'updated_at' => $faker->dateTimeBetween('-6 months'),
44+
];
45+
});

resources/views/tasks/index.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
<span class="uk-float-right uk-hidden@s uk-text-muted">Command</span>
3737
</td>
3838
<td>
39-
{{ $task->results->count() > 0 ? number_format( $task->results->sum('duration') / (1000 * $task->results->count()) , 2) : '0' }} seconds
39+
{{ number_format( $task->averageRuntime / 1000 , 2 ) }} seconds
4040
<span class="uk-float-right uk-hidden@s uk-text-muted">Avg. Runtime</span>
4141
</td>
42-
@if($last = $task->results->last())
42+
@if($last = $task->lastResult)
4343
<td>
4444
{{$last->ran_at->toDateTimeString()}}
4545
<span class="uk-float-right uk-hidden@s uk-text-muted">Last Run</span>

src/Task.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,24 @@ public function results()
9595
return $this->hasMany(Result::class, 'task_id', 'id');
9696
}
9797

98+
/**
99+
* Returns the most recent result entry for this task.
100+
*
101+
* @return Model|null
102+
*/
103+
public function getLastResultAttribute()
104+
{
105+
return $this->results()->orderBy('id', 'desc')->first();
106+
}
107+
108+
/**
109+
* @return float
110+
*/
111+
public function getAverageRuntimeAttribute()
112+
{
113+
return $this->results()->avg('duration') ?? 0.00;
114+
}
115+
98116
/**
99117
* Route notifications for the mail channel.
100118
*
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Studio\Totem\Tests\Feature;
4+
5+
use Studio\Totem\Task;
6+
use Studio\Totem\Result;
7+
use Studio\Totem\Tests\TestCase;
8+
9+
class ViewDashboardTest extends TestCase
10+
{
11+
/** @test */
12+
public function user_can_view_dashboard()
13+
{
14+
$this->signIn();
15+
$response = $this->get(route('totem.dashboard'));
16+
$response->assertStatus(302);
17+
}
18+
19+
/** @test */
20+
public function guest_can_not_view_dashboard()
21+
{
22+
$response = $this->get(route('totem.dashboard'));
23+
$response->assertStatus(403);
24+
}
25+
26+
/** @test */
27+
public function view_dashboard_single_task_no_results()
28+
{
29+
$this->signIn();
30+
$task = factory(Task::class)->create();
31+
$response = $this->get(route('totem.tasks.all', $task));
32+
$response->assertStatus(200);
33+
$this->assertEmpty($task->results);
34+
$this->assertSame(0.0, $task->averageRuntime);
35+
$response->assertSee($task->description);
36+
}
37+
38+
/** @test */
39+
public function view_dashboard_single_task_with_results()
40+
{
41+
$this->signIn();
42+
$tasks = $this->_get_task_with_results();
43+
$response = $this->get(route('totem.tasks.all', $tasks[0]));
44+
$response->assertStatus(200);
45+
46+
$this->assertNotEmpty($tasks[0]->results);
47+
$this->assertGreaterThanOrEqual(0.0, $tasks[0]->averageRuntime);
48+
$response->assertSee($tasks[0]->description);
49+
}
50+
51+
/** @test */
52+
public function view_dashboard_single_task_with_multiple_results()
53+
{
54+
$this->signIn();
55+
$tasks = $this->_get_task_with_results(1, 9);
56+
$response = $this->get(route('totem.tasks.all', $tasks[0]));
57+
$response->assertStatus(200);
58+
59+
$this->assertNotEmpty($tasks[0]->results);
60+
$this->assertGreaterThanOrEqual(0.0, $tasks[0]->averageRuntime);
61+
$response->assertSee($tasks[0]->description);
62+
}
63+
64+
/** @test */
65+
public function view_dashboard_multiple_tasks_with_multiple_results()
66+
{
67+
$this->signIn();
68+
$tasks = $this->_get_task_with_results(4, 5);
69+
$response = $this->get(route('totem.tasks.all', $tasks[0]));
70+
$response->assertStatus(200);
71+
72+
foreach ($tasks as $task) {
73+
$this->assertNotEmpty($task->results);
74+
$this->assertGreaterThanOrEqual(0.0, $task->averageRuntime);
75+
$response->assertSee($task->description);
76+
}
77+
}
78+
79+
/**
80+
* @param int $task_count
81+
* @param int $result_count
82+
* @return mixed
83+
*/
84+
private function _get_task_with_results($task_count = 1, $result_count = 1)
85+
{
86+
return factory(Task::class, $task_count)
87+
->create()
88+
->each(function ($task) use ($result_count) {
89+
for ($i = 0; $i < $result_count; $i++) {
90+
$task->results()->save(factory(Result::class)->make());
91+
}
92+
});
93+
}
94+
}

0 commit comments

Comments
 (0)