Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

* [PR-10](https://github.com/itk-dev/enter/pull/10)
Added test data setup
* [PR-9](https://github.com/itk-dev/enter/pull/9)
Refactored source import
* [PR-7](https://github.com/itk-dev/enter/pull/7)
Expand Down
12 changes: 12 additions & 0 deletions docs/Testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Testing

For local testing and development we use a test controller that's only enabled in the `dev` and `test` environments.

Load some local test data from a test data source (only available in the `dev` and `test` environments):

```shell
docker compose exec phpfpm php bin/console app:source:import test:mtm_spatialmaps-handicap-parking
curl 'http://enter.local.itkdev.dk/data/ngsi-ld/v1/entities?type=https://smartdatamodels.org/dataModel.Parking/OnStreetParking'
```

See the result on <https://enter.local.itkdev.dk/test>.
9 changes: 0 additions & 9 deletions src/Controller/DataController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Yaml\Yaml;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final class DataController extends AbstractController
Expand Down Expand Up @@ -54,12 +53,4 @@ public function index(Request $request, string $path, string $_format,
json: true,
);
}

#[Route('/test', name: 'data_test')]
public function test(): JsonResponse
{
$data = Yaml::parseFile(__DIR__.'/data.yaml');

return new JsonResponse($data);
}
}
2 changes: 1 addition & 1 deletion src/Controller/DefaultController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

final class DefaultController extends AbstractController
{
#[Route('/{path}', name: 'app_default', requirements: ['path' => Requirement::CATCH_ALL], methods: [Request::METHOD_GET])]
#[Route('/{path}', name: 'app_default', requirements: ['path' => Requirement::CATCH_ALL], methods: [Request::METHOD_GET], priority: -9999)]
public function index(?string $path = null): Response
{
return $this->render(null === $path ? 'default/index.html.twig' : sprintf('default/%s.html.twig', $path));
Expand Down
94 changes: 94 additions & 0 deletions src/Source/Test/TestHandicapParking.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace App\Source\Test;

use App\Geo\Wgs84Transformer;
use App\Ngsi\NgsiEntity;
use App\Source\AbstractSource;
use Symfony\Component\DependencyInjection\Attribute\When;

/**
* Disabled parking bays in Aarhus Municipality.
*/
#[When('dev')]
#[When('test')]
final readonly class TestHandicapParking extends AbstractSource
{
public function __construct(
private Wgs84Transformer $transformer,
) {
parent::__construct(
id: 'test:mtm_spatialmaps-handicap-parking',
title: 'Test: Handicapparkering, Aarhus Kommune',
description: 'Disabled parking bays in Aarhus Municipality, with the number of reserved bays per location.',
publisher: 'Aarhus Kommune',
contact: 'ppg@aarhus.dk',
landingPage: 'https://www.opendata.dk/city-of-aarhus/parkering-i-aarhus-kommune',
accessUrl: 'http://nginx:8080/test/data/webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=invap',
mediaType: 'application/geo+json',
crs: 'EPSG:25832',
model: 'OnStreetParking',
contextUrl: 'https://raw.githubusercontent.com/smart-data-models/dataModel.Parking/master/context.jsonld',
updateFrequency: 'continuous',

omittedFields: [
'ident' => 'Single-letter code; its meaning is not documented and not confirmed by the data owner.',
'oprettet_af' => 'Directory username of the municipal employee who created the record.',
'rettet_af' => 'Directory username of the municipal employee who last edited the record.',
'oprettet_dato' => 'Describes the register record.',
'rettet_dato' => 'Describes the register record.',
'mi_style' => 'MapInfo rendering style, empty throughout the export.',
],
);
}

/**
* Maps one feed record onto an NgsiEntity.
*
* @param array<string, mixed> $data GeoJSON Feature
*/
public function createNgsiEntity(array $data): ?NgsiEntity
{
$row = $data['properties'] ?? null;
$geometry = $data['geometry'] ?? null;

if (!\is_array($row) || !\is_array($geometry)) {
return null;
}

// mi_prinx is the feed's stable primary key. Without it there is no
// way to address the same bay again on the next import, and an upsert
// would create duplicates instead of updating.
$key = $row['mi_prinx'] ?? null;
if (null === $key || '' === $key) {
return null;
}

$entity = new NgsiEntity(
\sprintf('urn:ngsi-ld:%s:aarhus-handicap-%s', $this->model, $key),
$this->model
);

return $entity
->setProperty('name', $this->address($row))
->setProperty('description', trim((string) ($row['bemrk'] ?? '')))
->setProperty('category', ['forDisabled'])
->setProperty('totalSpotNumber', (int) ($row['invalidepladser'] ?? 0))
->setProperty('source', $this->accessUrl)
->geoProperty('location', $this->transformer->transformGeometry($this->crs, $geometry));
}

/**
* @param array<string, mixed> $row
*/
private function address(array $row): string
{
return trim(\sprintf(
'%s %s',
trim((string) ($row['vejnavn'] ?? '')),
trim((string) ($row['husnnr'] ?? ''))
));
}
}
12 changes: 12 additions & 0 deletions templates/test/index.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends 'base.html.twig' %}

{% block content %}
{% set type = 'https://smartdatamodels.org/dataModel.Parking/OnStreetParking' %}

<h2>{{ type }}</h2>

<div data-widget-url="{{ path('test_config', {type: type}) }}"></div>
{# <script src="https://widget.cdn.septima.dk/3.23.0/widgetconfig.js"></script> #}
{# https://github.com/Septima/widget-issues/issues/24#issuecomment-5478400091 #}
<script src="https://widget.cdn.septima.dk/3.19.0/widgetconfig.js"></script>
{% endblock %}
9 changes: 9 additions & 0 deletions tests/resources/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Test data resources

Run

```shell
./data/fetch-resources
```

to update the data resources.
25 changes: 25 additions & 0 deletions tests/resources/config/Parking/OnStreetParking.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
debug: true
map:
# "srs": "EPSG:4326",

view:
zoomLevel: 6
# Dokk1
x: 575436.27797098
y: 6223832.5677597
# x: 10.214391917362704,
# y: 56.153720859591054

layer:
- namedlayer: "#septima_standard"

- features_host: "/data/ngsi-ld/v1/entities.geojson?type=https://smartdatamodels.org/dataModel.Parking/OnStreetParking"

# THe undocumented property src is needed to display GeoJSON!
srs: "EPSG:4326"

visible: true
features: true

features_style:
- namedstyle: "#001"
17 changes: 17 additions & 0 deletions tests/resources/data/fetch-resources
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -o errexit -o errtrace -o noclobber -o nounset -o pipefail
IFS=$'\n\t'

script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)

cd "$script_dir"

urls=(
"https://webkort.aarhuskommune.dk/spatialmap?page=get_geojson_opendata&datasource=invap"
)
for url in "${urls[@]}"; do
target_file_name="${url##https://}"
mkdir -p "$(dirname "$target_file_name")"
curl --silent "$url" >| "$target_file_name"
echo "$url → $target_file_name"
done

Large diffs are not rendered by default.