refactor(dashboard,history): replace ViewModels with Pinia stores and improve backend

This commit is contained in:
2026-08-05 09:23:18 +02:00
parent a0387126de
commit 90930cd223
29 changed files with 1372 additions and 237 deletions
+156
View File
@@ -0,0 +1,156 @@
<?php
namespace Tests\Feature\Api;
use App\Contracts\PriceClient;
use App\Data\ElectricityData;
use App\Data\GasData;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Mockery;
use Tests\TestCase;
class DashboardApiTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config(['cache_prices.ttl' => 60]);
config(['cache_prices.prefix' => 'test:']);
}
protected function tearDown(): void
{
Mockery::close();
\Illuminate\Support\Facades\Cache::flush();
parent::tearDown();
}
public function test_dashboard_endpoint_returns_electricity_and_gas_data(): void
{
$now = Carbon::now();
$electricityResponse = collect([
$this->createElectricityArray($now->copy()->subMinutes(30), 15.0, 80),
$this->createElectricityArray($now->copy()->addHour(), 12.0, 90),
$this->createElectricityArray($now->copy()->addHours(2), 20.0, 60),
$this->createElectricityArray($now->copy()->addHours(3), 10.0, 95),
]);
$gasResponse = collect([
$this->createGasArray($now->copy()->startOfDay(), 5.0),
$this->createGasArray($now->copy()->addDay(), 4.0),
$this->createGasArray($now->copy()->addDays(2), 6.0),
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPrices')->once()->andReturn($electricityResponse);
$client->shouldReceive('getGasPrices')->once()->andReturn($gasResponse);
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/energy-prices');
$response->assertOk()
->assertJsonStructure([
'electricity' => [
'startDate',
'endDate',
'period',
'totalPriceTaxIncluded',
],
'electricityCheapest',
'electricityDurable',
'electricityPriciest',
'gas' => [
'startDate',
'endDate',
'period',
'totalPriceTaxIncluded',
],
'gasCheapest',
'gasPriciest',
]);
}
public function test_dashboard_endpoint_returns_correct_prices(): void
{
$now = Carbon::now();
$electricityResponse = collect([
$this->createElectricityArray($now->copy()->subMinutes(30), 15.0, 80),
$this->createElectricityArray($now->copy()->addHour(), 12.0, 90),
$this->createElectricityArray($now->copy()->addHours(2), 20.0, 60),
]);
$gasResponse = collect([
$this->createGasArray($now->copy()->startOfDay(), 5.0),
$this->createGasArray($now->copy()->addDay(), 4.0),
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPrices')->once()->andReturn($electricityResponse);
$client->shouldReceive('getGasPrices')->once()->andReturn($gasResponse);
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/energy-prices');
$response->assertOk();
$data = $response->json();
$this->assertEquals(15.0, $data['electricity']['totalPriceTaxIncluded']);
$this->assertEquals(12.0, $data['electricityCheapest']['totalPriceTaxIncluded']);
$this->assertEquals(20.0, $data['electricityPriciest']['totalPriceTaxIncluded']);
$this->assertEquals(5.0, $data['gas']['totalPriceTaxIncluded']);
$this->assertEquals(4.0, $data['gasCheapest']['totalPriceTaxIncluded']);
}
public function test_dashboard_endpoint_handles_empty_data(): void
{
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPrices')->once()->andReturn(collect());
$client->shouldReceive('getGasPrices')->once()->andReturn(collect());
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/energy-prices');
$response->assertOk();
$data = $response->json();
$this->assertNull($data['electricity'] ?? null);
$this->assertNull($data['gas'] ?? null);
}
private function createElectricityArray(Carbon $startDate, float $price, int $sustainabilityScore): array
{
return [
'start_date' => $startDate->format('Y-m-d H:i:s'),
'end_date' => $startDate->copy()->addHour()->format('Y-m-d H:i:s'),
'period' => 'elec_hour',
'market_price' => (int) ($price * 100),
'total_price_tax_included' => $price,
'price_incl_handling_vat' => (int) ($price * 100),
'price_tax_with_vat' => (int) ($price * 20),
'pricing_profile' => 'dynamic',
'carbon_footprint_in_gram' => 500,
'sustainability_score' => $sustainabilityScore,
'start_date_datetime' => $startDate->format('Y-m-d H:i:s'),
];
}
private function createGasArray(Carbon $startDate, float $price): array
{
return [
'start_date' => $startDate->format('Y-m-d H:i:s'),
'end_date' => $startDate->copy()->addDay()->format('Y-m-d H:i:s'),
'period' => 'gas_day',
'market_price' => (int) ($price * 100),
'total_price_tax_included' => $price,
'price_incl_handling_vat' => (int) ($price * 100),
'price_tax_with_vat' => (int) ($price * 20),
'start_date_datetime' => $startDate->format('Y-m-d H:i:s'),
];
}
}
+179
View File
@@ -0,0 +1,179 @@
<?php
namespace Tests\Feature\Api;
use App\Contracts\PriceClient;
use App\Data\ElectricityData;
use App\Data\GasData;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Mockery;
use Tests\TestCase;
class HistoryApiTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config(['cache_prices.ttl' => 60]);
config(['cache_prices.prefix' => 'test:']);
}
protected function tearDown(): void
{
Mockery::close();
\Illuminate\Support\Facades\Cache::flush();
parent::tearDown();
}
public function test_history_endpoint_returns_electricity_and_gas_data(): void
{
$date = Carbon::today();
$electricityResponse = collect([
$this->createElectricityArray($date->copy()->setHour(0), 15.0),
$this->createElectricityArray($date->copy()->setHour(1), 16.0),
]);
$gasResponse = collect([
$this->createGasArray($date, 5.0),
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPricesForDate')
->once()
->andReturn($electricityResponse);
$client->shouldReceive('getGasPricesForDate')
->once()
->andReturn($gasResponse);
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/history?date=' . $date->format('Y-m-d'));
$response->assertOk()
->assertJsonStructure([
'electricity' => [
'*' => [
'startDate',
'endDate',
'period',
'totalPriceTaxIncluded',
],
],
'gas' => [
'*' => [
'startDate',
'endDate',
'period',
'totalPriceTaxIncluded',
],
],
]);
}
public function test_history_endpoint_returns_correct_data(): void
{
$date = Carbon::today();
$electricityResponse = collect([
$this->createElectricityArray($date->copy()->setHour(0), 15.0),
$this->createElectricityArray($date->copy()->setHour(1), 16.0),
]);
$gasResponse = collect([
$this->createGasArray($date, 5.0),
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPricesForDate')
->once()
->andReturn($electricityResponse);
$client->shouldReceive('getGasPricesForDate')
->once()
->andReturn($gasResponse);
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/history?date=' . $date->format('Y-m-d'));
$response->assertOk();
$data = $response->json();
$this->assertCount(2, $data['electricity']);
$this->assertCount(1, $data['gas']);
$this->assertEquals(15.0, $data['electricity'][0]['totalPriceTaxIncluded']);
$this->assertEquals(5.0, $data['gas'][0]['totalPriceTaxIncluded']);
}
public function test_history_endpoint_defaults_to_today(): void
{
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPricesForDate')
->once()
->andReturn(collect());
$client->shouldReceive('getGasPricesForDate')
->once()
->andReturn(collect());
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/history');
$response->assertOk();
}
public function test_history_endpoint_handles_empty_data(): void
{
$date = Carbon::today();
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPricesForDate')
->once()
->andReturn(collect());
$client->shouldReceive('getGasPricesForDate')
->once()
->andReturn(collect());
$this->app->bind(PriceClient::class, fn () => $client);
$response = $this->getJson('/api/history?date=' . $date->format('Y-m-d'));
$response->assertOk();
$data = $response->json();
$this->assertEmpty($data['electricity']);
$this->assertEmpty($data['gas']);
}
private function createElectricityArray(Carbon $startDate, float $price): array
{
return [
'start_date' => $startDate->format('Y-m-d H:i:s'),
'end_date' => $startDate->copy()->addHour()->format('Y-m-d H:i:s'),
'period' => 'elec_hour',
'market_price' => (int) ($price * 100),
'total_price_tax_included' => $price,
'price_incl_handling_vat' => (int) ($price * 100),
'price_tax_with_vat' => (int) ($price * 20),
'pricing_profile' => 'dynamic',
'carbon_footprint_in_gram' => 500,
'sustainability_score' => 80,
'start_date_datetime' => $startDate->format('Y-m-d H:i:s'),
];
}
private function createGasArray(Carbon $startDate, float $price): array
{
return [
'start_date' => $startDate->format('Y-m-d H:i:s'),
'end_date' => $startDate->copy()->addDay()->format('Y-m-d H:i:s'),
'period' => 'gas_day',
'market_price' => (int) ($price * 100),
'total_price_tax_included' => $price,
'price_incl_handling_vat' => (int) ($price * 100),
'price_tax_with_vat' => (int) ($price * 20),
'start_date_datetime' => $startDate->format('Y-m-d H:i:s'),
];
}
}
@@ -0,0 +1,143 @@
<?php
namespace Tests\Unit\Clients;
use App\Clients\ZonneplanPriceClient;
use Carbon\Carbon;
use Illuminate\Http\Client\Factory;
use Illuminate\Http\Client\RequestException;
use Illuminate\Http\Response;
use Mockery;
use Tests\TestCase;
class ZonneplanPriceClientTest extends TestCase
{
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
public function test_get_electricity_prices_returns_collection(): void
{
$response = Mockery::mock();
$response->shouldReceive('throw')->once();
$response->shouldReceive('json')
->once()
->with('data', [])
->andReturn([
['start_date' => Carbon::now()->format('Y-m-d H:i:s'), 'total_price_tax_included' => 15.0],
]);
$response->shouldReceive('status')->once()->andReturn(200);
$http = Mockery::mock(Factory::class);
$http->shouldReceive('baseUrl')->once()->andReturnSelf();
$http->shouldReceive('withQueryParameters')->once()->andReturnSelf();
$http->shouldReceive('timeout')->once()->andReturnSelf();
$http->shouldReceive('retry')->once()->andReturnSelf();
$http->shouldReceive('get')->once()->andReturn($response);
$client = new ZonneplanPriceClient($http);
$result = $client->getElectricityPrices();
$this->assertCount(1, $result);
}
public function test_get_gas_prices_returns_collection(): void
{
$response = Mockery::mock();
$response->shouldReceive('throw')->once();
$response->shouldReceive('json')
->once()
->with('data', [])
->andReturn([
['start_date' => Carbon::now()->format('Y-m-d H:i:s'), 'total_price_tax_included' => 5.0],
]);
$response->shouldReceive('status')->once()->andReturn(200);
$http = Mockery::mock(Factory::class);
$http->shouldReceive('baseUrl')->once()->andReturnSelf();
$http->shouldReceive('withQueryParameters')->once()->andReturnSelf();
$http->shouldReceive('timeout')->once()->andReturnSelf();
$http->shouldReceive('retry')->once()->andReturnSelf();
$http->shouldReceive('get')->once()->andReturn($response);
$client = new ZonneplanPriceClient($http);
$result = $client->getGasPrices();
$this->assertCount(1, $result);
}
public function test_get_electricity_prices_for_date_returns_collection(): void
{
$date = Carbon::today();
$response = Mockery::mock();
$response->shouldReceive('throw')->once();
$response->shouldReceive('json')
->once()
->with('data', [])
->andReturn([
['start_date' => $date->format('Y-m-d H:i:s'), 'total_price_tax_included' => 15.0],
]);
$response->shouldReceive('status')->once()->andReturn(200);
$http = Mockery::mock(Factory::class);
$http->shouldReceive('baseUrl')->once()->andReturnSelf();
$http->shouldReceive('withQueryParameters')->once()->andReturnSelf();
$http->shouldReceive('timeout')->once()->andReturnSelf();
$http->shouldReceive('retry')->once()->andReturnSelf();
$http->shouldReceive('get')->once()->andReturn($response);
$client = new ZonneplanPriceClient($http);
$result = $client->getElectricityPricesForDate($date);
$this->assertCount(1, $result);
}
public function test_get_gas_prices_for_date_returns_collection(): void
{
$date = Carbon::today();
$response = Mockery::mock();
$response->shouldReceive('throw')->once();
$response->shouldReceive('json')
->once()
->with('data', [])
->andReturn([
['start_date' => $date->format('Y-m-d H:i:s'), 'total_price_tax_included' => 5.0],
]);
$response->shouldReceive('status')->once()->andReturn(200);
$http = Mockery::mock(Factory::class);
$http->shouldReceive('baseUrl')->once()->andReturnSelf();
$http->shouldReceive('withQueryParameters')->once()->andReturnSelf();
$http->shouldReceive('timeout')->once()->andReturnSelf();
$http->shouldReceive('retry')->once()->andReturnSelf();
$http->shouldReceive('get')->once()->andReturn($response);
$client = new ZonneplanPriceClient($http);
$result = $client->getGasPricesForDate($date);
$this->assertCount(1, $result);
}
public function test_client_throws_exception_on_api_failure(): void
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Kon energieprijzen niet ophalen');
$response = Mockery::mock();
$response->shouldReceive('throw')->once()->andThrow(
new \Illuminate\Http\Client\ConnectionException('API Error')
);
$http = Mockery::mock(Factory::class);
$http->shouldReceive('baseUrl')->once()->andReturnSelf();
$http->shouldReceive('withQueryParameters')->once()->andReturnSelf();
$http->shouldReceive('timeout')->once()->andReturnSelf();
$http->shouldReceive('retry')->once()->andReturnSelf();
$http->shouldReceive('get')->once()->andReturn($response);
$client = new ZonneplanPriceClient($http);
$client->getElectricityPrices();
}
}
@@ -0,0 +1,189 @@
<?php
namespace Tests\Unit\Repositories;
use App\Contracts\PriceClient;
use App\Data\ElectricityData;
use App\Data\GasData;
use App\Repositories\ZonneplanPriceRepository;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Mockery;
use Tests\TestCase;
class ZonneplanPriceRepositoryTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config(['cache_prices.ttl' => 60]);
config(['cache_prices.prefix' => 'test:']);
}
protected function tearDown(): void
{
Mockery::close();
Cache::flush();
parent::tearDown();
}
public function test_retrieve_electricity_returns_collection_of_electricity_data(): void
{
$now = Carbon::now();
$electricityResponse = collect([
[
'start_date' => $now->format('Y-m-d H:i:s'),
'end_date' => $now->copy()->addHour()->format('Y-m-d H:i:s'),
'period' => 'elec_hour',
'market_price' => 1500,
'total_price_tax_included' => 15.50,
'price_incl_handling_vat' => 1550,
'price_tax_with_vat' => 300,
'pricing_profile' => 'dynamic',
'carbon_footprint_in_gram' => 500,
'sustainability_score' => 80,
'start_date_datetime' => $now->format('Y-m-d H:i:s'),
],
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPrices')
->once()
->andReturn($electricityResponse);
$repository = new ZonneplanPriceRepository($client);
$result = $repository->retrieveElectricity();
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(1, $result);
$this->assertInstanceOf(ElectricityData::class, $result->first());
}
public function test_retrieve_gas_returns_collection_of_gas_data(): void
{
$now = Carbon::now();
$gasResponse = collect([
[
'start_date' => $now->format('Y-m-d H:i:s'),
'end_date' => $now->copy()->addDay()->format('Y-m-d H:i:s'),
'period' => 'gas_day',
'market_price' => 500,
'total_price_tax_included' => 5.50,
'price_incl_handling_vat' => 550,
'price_tax_with_vat' => 100,
'start_date_datetime' => $now->format('Y-m-d H:i:s'),
],
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getGasPrices')
->once()
->andReturn($gasResponse);
$repository = new ZonneplanPriceRepository($client);
$result = $repository->retrieveGas();
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(1, $result);
$this->assertInstanceOf(GasData::class, $result->first());
}
public function test_retrieve_electricity_for_date_returns_collection(): void
{
$date = Carbon::today();
$electricityResponse = collect([
[
'start_date' => $date->copy()->setHour(0)->format('Y-m-d H:i:s'),
'end_date' => $date->copy()->setHour(1)->format('Y-m-d H:i:s'),
'period' => 'elec_hour',
'market_price' => 1500,
'total_price_tax_included' => 15.50,
'price_incl_handling_vat' => 1550,
'price_tax_with_vat' => 300,
'pricing_profile' => 'dynamic',
'carbon_footprint_in_gram' => 500,
'sustainability_score' => 80,
'start_date_datetime' => $date->copy()->setHour(0)->format('Y-m-d H:i:s'),
],
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPricesForDate')
->once()
->with($date)
->andReturn($electricityResponse);
$repository = new ZonneplanPriceRepository($client);
$result = $repository->retrieveElectricityForDate($date);
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(1, $result);
$this->assertInstanceOf(ElectricityData::class, $result->first());
}
public function test_retrieve_gas_for_date_returns_collection(): void
{
$date = Carbon::today();
$gasResponse = collect([
[
'start_date' => $date->format('Y-m-d H:i:s'),
'end_date' => $date->copy()->addDay()->format('Y-m-d H:i:s'),
'period' => 'gas_day',
'market_price' => 500,
'total_price_tax_included' => 5.50,
'price_incl_handling_vat' => 550,
'price_tax_with_vat' => 100,
'start_date_datetime' => $date->format('Y-m-d H:i:s'),
],
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getGasPricesForDate')
->once()
->with($date)
->andReturn($gasResponse);
$repository = new ZonneplanPriceRepository($client);
$result = $repository->retrieveGasForDate($date);
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(1, $result);
$this->assertInstanceOf(GasData::class, $result->first());
}
public function test_retrieve_electricity_caches_result(): void
{
$now = Carbon::now();
$electricityResponse = collect([
[
'start_date' => $now->format('Y-m-d H:i:s'),
'end_date' => $now->copy()->addHour()->format('Y-m-d H:i:s'),
'period' => 'elec_hour',
'market_price' => 1500,
'total_price_tax_included' => 15.50,
'price_incl_handling_vat' => 1550,
'price_tax_with_vat' => 300,
'pricing_profile' => 'dynamic',
'carbon_footprint_in_gram' => 500,
'sustainability_score' => 80,
'start_date_datetime' => $now->format('Y-m-d H:i:s'),
],
]);
$client = Mockery::mock(PriceClient::class);
$client->shouldReceive('getElectricityPrices')
->once()
->andReturn($electricityResponse);
$repository = new ZonneplanPriceRepository($client);
$result1 = $repository->retrieveElectricity();
$result2 = $repository->retrieveElectricity();
$this->assertEquals(
$result1->first()->totalPriceTaxIncluded,
$result2->first()->totalPriceTaxIncluded
);
}
}
@@ -0,0 +1,129 @@
<?php
namespace Tests\Unit\Services;
use App\Contracts\PriceRepository;
use App\Data\ElectricityData;
use App\Data\GasData;
use App\Features\Dashboard\Services\DashboardService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Mockery;
use Tests\TestCase;
class DashboardServiceTest extends TestCase
{
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
public function test_get_dashboard_data_returns_current_cheapest_sustainable_and_expensive_prices(): void
{
$now = Carbon::now();
$electricityData = collect([
$this->createElectricityData($now->copy()->subMinutes(30), 15.0, 80),
$this->createElectricityData($now->copy()->addHour(), 12.0, 90),
$this->createElectricityData($now->copy()->addHours(2), 20.0, 60),
$this->createElectricityData($now->copy()->addHours(3), 10.0, 95),
]);
$gasData = collect([
$this->createGasData($now->copy()->startOfDay(), 5.0),
$this->createGasData($now->copy()->addDay(), 4.0),
$this->createGasData($now->copy()->addDays(2), 6.0),
]);
$repository = Mockery::mock(PriceRepository::class);
$repository->shouldReceive('retrieveElectricity')->once()->andReturn($electricityData);
$repository->shouldReceive('retrieveGas')->once()->andReturn($gasData);
$service = new DashboardService($repository);
$result = $service->getDashboardData();
$this->assertEquals(15.0, $result->electricity->totalPriceTaxIncluded);
$this->assertEquals(10.0, $result->electricityCheapest->totalPriceTaxIncluded);
$this->assertEquals(95, $result->electricityDurable->sustainabilityScore);
$this->assertEquals(20.0, $result->electricityPriciest->totalPriceTaxIncluded);
$this->assertEquals(5.0, $result->gas->totalPriceTaxIncluded);
$this->assertEquals(4.0, $result->gasCheapest->totalPriceTaxIncluded);
$this->assertEquals(6.0, $result->gasPriciest->totalPriceTaxIncluded);
}
public function test_get_dashboard_data_returns_null_for_missing_current_price(): void
{
$now = Carbon::now();
$electricityData = collect([
$this->createElectricityData($now->copy()->addHours(5), 15.0, 80),
]);
$gasData = collect([
$this->createGasData($now->copy()->addDays(5), 5.0),
]);
$repository = Mockery::mock(PriceRepository::class);
$repository->shouldReceive('retrieveElectricity')->once()->andReturn($electricityData);
$repository->shouldReceive('retrieveGas')->once()->andReturn($gasData);
$service = new DashboardService($repository);
$result = $service->getDashboardData();
$this->assertNull($result->electricity);
$this->assertNull($result->gas);
$this->assertNotNull($result->electricityCheapest);
$this->assertNotNull($result->gasCheapest);
}
public function test_get_dashboard_data_with_empty_collections(): void
{
$repository = Mockery::mock(PriceRepository::class);
$repository->shouldReceive('retrieveElectricity')->once()->andReturn(collect());
$repository->shouldReceive('retrieveGas')->once()->andReturn(collect());
$service = new DashboardService($repository);
$result = $service->getDashboardData();
$this->assertNull($result->electricity);
$this->assertNull($result->electricityCheapest);
$this->assertNull($result->electricityDurable);
$this->assertNull($result->electricityPriciest);
$this->assertNull($result->gas);
$this->assertNull($result->gasCheapest);
$this->assertNull($result->gasPriciest);
}
private function createElectricityData(Carbon $startDate, float $price, int $sustainabilityScore): ElectricityData
{
return new ElectricityData(
startDate: $startDate,
endDate: $startDate->copy()->addHour(),
period: 'elec_hour',
marketPrice: (int) ($price * 100),
totalPriceTaxIncluded: $price,
priceInclHandlingVat: (int) ($price * 100),
priceTaxWithVat: (int) ($price * 20),
pricingProfile: 'dynamic',
carbonFootprintInGram: 500,
sustainabilityScore: $sustainabilityScore,
startDateDatetime: $startDate,
);
}
private function createGasData(Carbon $startDate, float $price): GasData
{
return new GasData(
startDate: $startDate,
endDate: $startDate->copy()->addDay(),
period: 'gas_day',
marketPrice: (int) ($price * 100),
totalPriceTaxIncluded: $price,
priceInclHandlingVat: (int) ($price * 100),
priceTaxWithVat: (int) ($price * 20),
startDateDatetime: $startDate,
);
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
namespace Tests\Unit\Services;
use App\Contracts\PriceRepository;
use App\Data\ElectricityData;
use App\Data\GasData;
use App\Features\History\Services\HistoryService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Mockery;
use Tests\TestCase;
class HistoryServiceTest extends TestCase
{
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
public function test_get_history_data_returns_electricity_and_gas_for_date(): void
{
$date = Carbon::today();
$electricityData = collect([
$this->createElectricityData($date->copy()->setHour(0), 15.0),
$this->createElectricityData($date->copy()->setHour(1), 16.0),
]);
$gasData = collect([
$this->createGasData($date, 5.0),
]);
$repository = Mockery::mock(PriceRepository::class);
$repository->shouldReceive('retrieveElectricityForDate')
->once()
->with($date)
->andReturn($electricityData);
$repository->shouldReceive('retrieveGasForDate')
->once()
->with($date)
->andReturn($gasData);
$service = new HistoryService($repository);
$result = $service->getHistoryData($date);
$this->assertCount(2, $result->electricity);
$this->assertCount(1, $result->gas);
$this->assertEquals(15.0, $result->electricity->first()->totalPriceTaxIncluded);
$this->assertEquals(5.0, $result->gas->first()->totalPriceTaxIncluded);
}
public function test_get_history_data_with_empty_collections(): void
{
$date = Carbon::today();
$repository = Mockery::mock(PriceRepository::class);
$repository->shouldReceive('retrieveElectricityForDate')
->once()
->andReturn(collect());
$repository->shouldReceive('retrieveGasForDate')
->once()
->andReturn(collect());
$service = new HistoryService($repository);
$result = $service->getHistoryData($date);
$this->assertCount(0, $result->electricity);
$this->assertCount(0, $result->gas);
}
private function createElectricityData(Carbon $startDate, float $price): ElectricityData
{
return new ElectricityData(
startDate: $startDate,
endDate: $startDate->copy()->addHour(),
period: 'elec_hour',
marketPrice: (int) ($price * 100),
totalPriceTaxIncluded: $price,
priceInclHandlingVat: (int) ($price * 100),
priceTaxWithVat: (int) ($price * 20),
pricingProfile: 'dynamic',
carbonFootprintInGram: 500,
sustainabilityScore: 80,
startDateDatetime: $startDate,
);
}
private function createGasData(Carbon $startDate, float $price): GasData
{
return new GasData(
startDate: $startDate,
endDate: $startDate->copy()->addDay(),
period: 'gas_day',
marketPrice: (int) ($price * 100),
totalPriceTaxIncluded: $price,
priceInclHandlingVat: (int) ($price * 100),
priceTaxWithVat: (int) ($price * 20),
startDateDatetime: $startDate,
);
}
}