diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..46a0b74 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,24 @@ +# Copilot instructions for this repository + +Preferred behavior for running backend tests and quality checks: + +- Always run backend tests and QA inside the docker-compose "app" service so environment, PHP extensions and dependencies match the container. +- Prefer using the Makefile targets which already invoke the app service. Examples: + - make test # runs phpunit inside the app container + - make quality # runs composer qa inside the app container + +If running commands directly inside the container, run non-interactively (no -it) to avoid TTY allocation issues: + +- docker compose exec -T app bin/phpunit +- docker compose exec -T app composer qa +- docker compose exec -T app vendor/bin/phpstan analyse --memory-limit=1G +- docker compose exec -T app vendor/bin/php-cs-fixer fix +- docker compose exec -T app vendor/bin/deptrac analyse --report-uncovered + +Guidelines for Copilot CLI usage in this repo: + +- When asked to run tests or QA, prefer the Makefile targets (make test, make quality) executed in the repository root. +- If running inside a container is required, always target the "app" service and use `-T` for exec to run non-interactively. +- When proposing automation or CI commands, include explicit container commands using the "app" service so they work in the project's docker-compose setup. + +These instructions ensure consistent, reproducible test and QA runs by using the project's containerized environment. diff --git a/backend/tests/Unit/SplitFairly/ExpenseTrackerTest.php b/backend/tests/Unit/SplitFairly/ExpenseTrackerTest.php new file mode 100644 index 0000000..9ee6ebe --- /dev/null +++ b/backend/tests/Unit/SplitFairly/ExpenseTrackerTest.php @@ -0,0 +1,46 @@ +createMock(CurrentUserInterface::class); + $currentUser->method('getUuid')->willReturn('user-123'); + + $normalizedPayload = ['price' => (string) $price, 'what' => 'Coffee', 'type' => 'Groceries', 'location' => 'Starbucks']; + $normalizer = $this->createMock(NormalizerInterface::class); + $normalizer->expects($this->once())->method('toArray')->with($expense, ['id'])->willReturn($normalizedPayload); + + $eventStore = $this->createMock(EventStoreInterface::class); + $eventStore->expects($this->once())->method('persist')->with( + $this->callback(function (Event $event) use ($expense, $normalizedPayload): bool { + return 'user-123' === $event->createdBy + && 'Expense' === $event->subjectType + && $event->subjectId === $expense->getId()->toRfc4122() + && 'tracked' === $event->eventType + && $event->payload === $normalizedPayload; + }), + false + ); + + $tracker = new ExpenseTracker($eventStore, $normalizer, $currentUser); + + $tracker->track($expense); + } +} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..c56d6ac --- /dev/null +++ b/codecov.yml @@ -0,0 +1,14 @@ +# Limit Codecov reports to the SplitFairly namespace +coverage: + status: + project: + default: + target: 0 + precision: 2 + round: down +reports: + - name: SplitFairly + paths: + - backend/src/SplitFairly + # Only show this report on the Codecov UI + # see https://docs.codecov.com/docs/codecov-yaml#section-reports diff --git a/dashboard/assets/config.yml b/dashboard/assets/config.yml index 4f31dfe..fec8b10 100644 --- a/dashboard/assets/config.yml +++ b/dashboard/assets/config.yml @@ -49,3 +49,8 @@ services: icon: "fa-brands fa-github" url: "https://github.com/makomweb/split-fairly" target: "_blank" + - name: "Code coverage" + subtitle: "PHPUnit coverage" + icon: "fa-solid fa-clipboard-check" + url: "http://localhost:8000/coverage/index.html" + target: "_blank" diff --git a/docker-compose.yaml b/docker-compose.yaml index 19dd6ea..b797067 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -79,7 +79,7 @@ services: volumes: - ./dashboard/assets:/www/assets - ./backend/report:/www/public/report - - ./backend/coverage:/www/public/coverage + - ./backend/coverage:/www/coverage ports: - "8000:8080" user: "1000:1001"