Skip to content
Merged
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
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
help: ## Show this help message
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Streamlining changes to a make file instead of using composer for some of the changes.

@echo 'Usage:'
@echo ' make <target>'
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_\/-]+:.*?##/ { printf " %-20s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

dev/start-server: ## Start the Symfony server
symfony server:start

dev/install-deps: ## Install the dependencies
composer install

db/generate-migration: ## Generate a new migration
php bin/console make:migration

db/create: ## Create the database
php bin/console doctrine:database:create

db/migrate: ## Run the migrations
php bin/console doctrine:migrations:migrate --no-interaction --all-or-nothing

test: ## Run the tests
php bin/phpunit

lint: ## Run the linter
vendor/bin/php-cs-fixer fix

imports/import-themes: ## Import the themes
php bin/console ExtractService extractthemes

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ This project is a web-based visualization tool for exploring and analyzing open

3. Install Composer (PHP dependency manager):
- Follow installation steps at: https://getcomposer.org/download/
- Run `composer install` to install dependencies
- Run `make dev/install-deps` to install dependencies

4. Run migrations:
```
composer db:create
composer db:migrate
make db/create
make db/migrate
```

5. Set up local development server:
- Install Symfony CLI from: https://symfony.com/download
- Build database schema: `symfony console doctrine:schema:update --force`
- Start the server: `symfony server:start`
- Start the server: `make dev/start-server`

6. Access the application:
- Open your browser and navigate to: http://localhost:8000/

## Running tests

- Build database schema: `symfony console doctrine:schema:update --force --env=test`
- Run tests: `php bin/phpunit`
- Run tests: `make test`
6 changes: 1 addition & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,7 @@
],
"post-update-cmd": [
"@auto-scripts"
],
"fix-style": "php-cs-fixer fix",
"db:migrate": "php bin/console doctrine:migrations:migrate --no-interaction --all-or-nothing",
"db:create": "php bin/console doctrine:database:create",
"migration:create": "php bin/console make:migration"
]
},
"conflict": {
"symfony/symfony": "*"
Expand Down
32 changes: 9 additions & 23 deletions src/Controller/Api/ThemesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,24 @@

namespace App\Controller\Api;

use App\Repository\ThemeRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/api')]
final class ThemesController extends AbstractController
{
private $themeRepository;

public function __construct(ThemeRepository $themeRepository)
{
$this->themeRepository = $themeRepository;
}

#[Route('/themes', name: 'app_themes', methods: ['GET'])]
public function index(): JsonResponse
{
return $this->json([
'themes' => [
[
'code' => 'environment',
'id' => 1234,
'parentId' => null,
'children' => [
[
'code' => 'some_sub_theme',
'id' => 1024,
'parentId' => 1234,
'children' => [
[
'code' => 'yet_another_sub_theme',
'id' => 2048,
'parentId' => 1024,
],
],
],
],
],
],
]);
return $this->json(['themes' => $this->themeRepository->findAllHierarchical()]);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@magrigsdev there is probably a better way, but this will suffice for now I think.

}
}
15 changes: 13 additions & 2 deletions src/Repository/ThemeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@

class ThemeRepository extends ServiceEntityRepository
{
private $entityManager;

public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Theme::class);
}

public function findAllHierarchical(): array
{
$themes = $this->findAll();
$themesByParentId = [];
array_map(function (Theme $theme) use (&$themesByParentId) {
$children = $themesByParentId[$theme->getParentId()] ?? [];
$children[] = ['id' => $theme->getId(), 'name' => $theme->getName(), 'parentId' => $theme->getParentId(), 'externalId' => $theme->getExternalId()];
$themesByParentId[$theme->getParentId() ?? 'base'] = $children;
}, $themes);

return $themesByParentId;
}
}
42 changes: 36 additions & 6 deletions tests/Api/ThemesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,51 @@

namespace App\Tests;

use App\Entity\Theme;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class ThemesTest extends WebTestCase
{
// Ideally this should be replaced with a more comprehensive test
// once we have our data model in place
private $client;
private $themeRepository;
private $entityManager;

protected function setUp(): void
{
parent::setUp();
$this->client = static::createClient();

$container = static::getContainer();
$this->entityManager = $container->get('doctrine.orm.entity_manager');
$this->themeRepository = $this->entityManager->getRepository(Theme::class);

$parent = new Theme();
$parent->setName('Environment');
$parent->setIsSection(true);
$parent->setParentId(null);
$parent->setExternalId('external_id1');
$this->entityManager->persist($parent);
$this->entityManager->flush();
}

protected function tearDown(): void
{
$themes = $this->themeRepository->findAll();
foreach ($themes as $theme) {
$this->entityManager->remove($theme);
}
$this->entityManager->flush();
parent::tearDown();
}

public function testApiResponse(): void
{
$client = static::createClient();
$client->request('GET', '/api/themes');
$this->client->request('GET', '/api/themes');

$this->assertResponseIsSuccessful();
$content = $client->getResponse()->getContent();
$content = $this->client->getResponse()->getContent();

$results = json_decode($content, true);
$this->assertEquals('environment', $results['themes'][0]['code']);
$this->assertEquals('Environment', $results['themes']['base'][0]['name']);
}
}
38 changes: 38 additions & 0 deletions tests/Themes/ThemeRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,42 @@ public function testAddChildTheme(): void
$this->entityManager->flush();
$this->assertNotNull($child->getId());
}

public function testFindAllHierarchical(): void
{
$themes = $this->themeRepository->findAllHierarchical();
$this->assertEquals(0, count($themes));

$parent = new Theme();
$parent->setName('Environment');
$parent->setIsSection(true);
$parent->setParentId(null);
$parent->setExternalId('external_id1');
$this->entityManager->persist($parent);
$this->entityManager->flush();

$child = new Theme();
$child->setName('Climate Change');
$child->setIsSection(true);
$child->setParentId($parent->getId());
$child->setExternalId('external_id2');
$this->entityManager->persist($child);
$this->entityManager->flush();

$grandchild = new Theme();
$grandchild->setName('Sea Level Rise');
$grandchild->setIsSection(true);
$grandchild->setParentId($child->getId());
$grandchild->setExternalId('external_id3');
$this->entityManager->persist($grandchild);
$this->entityManager->flush();

$themes = $this->themeRepository->findAllHierarchical();
$this->assertEquals(3, count($themes));
$this->assertEquals('Environment', $themes['base'][0]['name']);
$topParentId = $themes['base'][0]['id'];
$this->assertEquals('Climate Change', $themes[$topParentId][0]['name']);
$midParentId = $themes[$topParentId][0]['id'];
$this->assertEquals('Sea Level Rise', $themes[$midParentId][0]['name']);
}
}