Skip to content

Feat/230/add endpoint getbyuserid#245

Merged
weazy12 merged 5 commits into
devfrom
feat/230/add-endpoint-getbyuserid
Sep 23, 2025
Merged

Feat/230/add endpoint getbyuserid#245
weazy12 merged 5 commits into
devfrom
feat/230/add-endpoint-getbyuserid

Conversation

@oleksandrhofner

@oleksandrhofner oleksandrhofner commented Sep 23, 2025

Copy link
Copy Markdown
Contributor

dev

JIRA

Code reviewers

  • @github_username

Second Level Review

  • @github_username

Summary of issue

ToDo

Summary of change

ToDo

Testing approach

ToDo

CHECK LIST

  • СI passed
  • Сode coverage >=95%
  • PR is reviewed manually again (to make sure you have 100% ready code)
  • All reviewers agreed to merge the PR
  • I've checked new feature as logged in and logged out user if needed
  • PR meets all conventions

Summary by CodeRabbit

  • New Features
    • Added an authorized API endpoint to retrieve a user’s favorite streetcodes by user ID.
    • Returns an empty list when no favorites are found and provides clear error responses on failure.
  • Tests
    • Introduced comprehensive unit tests covering successful retrieval, empty results, and null repository responses to ensure reliability and correctness of favorite streetcode fetching.

@coderabbitai

coderabbitai Bot commented Sep 23, 2025

Copy link
Copy Markdown

Walkthrough

Adds a MediatR query and handler to fetch a user’s favorite streetcodes, wires a new authorized Web API GET endpoint using the mediator, adjusts a repository using directive, and introduces unit tests covering success and empty/null repository scenarios.

Changes

Cohort / File(s) Summary of changes
FavouriteStreetcode: GetFavoritesByUserId feature
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs, Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdQuery.cs, Streetcode/Streetcode.WebApi/Controllers/FavouriteStreetcode/FavouriteStreetcodeController.cs
New MediatR query and handler to retrieve favorites by user ID; API controller adds authorized GET endpoint that invokes the query via mediator and returns result or errors.
Unit tests
Streetcode/Streetcode.XUnitTest/BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserIdQueryHandlerTests.cs
Adds tests for handler: user with favorites, no favorites, and null repository response; verifies mapping and result shapes.
Repository imports
Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs
Adjusts using directives to include Microsoft.EntityFrameworkCore; no functional changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant API as FavouriteStreetcodeController
  participant Med as Mediator
  participant H as GetFavoritesByUserIdHandler
  participant Repo as IRepositoryWrapper
  participant Map as IMapper

  Client->>API: GET /favourite-streetcodes/{userId}
  API->>Med: Send(GetFavoritesByUserIdQuery)
  Med->>H: Handle(query)
  H->>Repo: FavouriteStreetcode.GetAll( userId )
  alt Favorites found
    H->>Repo: Streetcode.GetAllByIds( streetcodeIds )
    H->>Map: Map(Streetcodes -> StreetcodeDTO[])
    Map-->>H: DTOs
    H-->>Med: Result.Success(DTOs)
  else None or null
    H-->>Med: Result.Success(empty)
  end
  Med-->>API: Result
  alt Success
    API-->>Client: 200 OK (DTOs)
  else Failure
    API-->>Client: 400 Bad Request (errors)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

enhancement

Suggested reviewers

  • denys-pavskyi
  • weazy12
  • Markian-Grybok

Poem

I thump with glee on cobblestone lanes,
A basket of favorites, gathered like grains.
Hop to the endpoint, queries take flight—
Handler maps memories, tidy and bright.
Tests nibble errors, all set to run,
Carrots for coverage—done, and done! 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description includes the repository template and a JIRA link but leaves mandatory sections "Summary of issue", "Summary of change", and "Testing approach" as "ToDo", and reviewer/checklist entries are placeholders, so required information is incomplete. Because those sections are expected to describe the problem, the implemented change, and how it was tested, the current description does not meet the template requirements. This makes the PR insufficiently documented for review and merging. Complete the template by filling "Summary of issue" with the problem being addressed, "Summary of change" with the concrete files/behavior modified and rationale, and "Testing approach" with test cases and steps (including CI and coverage results); assign actual reviewers, update or remove placeholders, and mark checklist items (CI, coverage, manual checks) accordingly before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Feat/230/add endpoint getbyuserid" directly references the primary change—adding an endpoint to retrieve a user's favorite streetcodes—and matches the new controller, query, and handler in the changeset. It is concise and related to the main change, though it uses ticket shorthand and a path-style phrase rather than an imperative sentence. This wording is acceptable for quick scanning of history but could be slightly clearer for changelog readability.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/230/add-endpoint-getbyuserid

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fbb5e5 and 6dd7298.

📒 Files selected for processing (3)
  • Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (1 hunks)
  • Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (1 hunks)
  • Streetcode/Streetcode.XUnitTest/BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserIdQueryHandlerTests.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs
  • Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs
  • Streetcode/Streetcode.XUnitTest/BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserIdQueryHandlerTests.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and analyze

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (5)
Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (1)

16-21: Guard null/empty IDs; add AsNoTracking + Distinct; consider CT support

Avoid NRE on null input, reduce duplicates, and skip change tracking for a read-only query. Also propagate CancellationToken from callers.

Apply:

-    public async Task<IEnumerable<StreetcodeContent>> GetStreetcodesByIdsAsync(IEnumerable<int> streetcodeIds)
+    public async Task<IEnumerable<StreetcodeContent>> GetStreetcodesByIdsAsync(IEnumerable<int> streetcodeIds, CancellationToken cancellationToken = default)
     {
-        return await FindAll()
-            .Where(s => streetcodeIds.Contains(s.Id))
-            .ToListAsync();
+        if (streetcodeIds is null || !streetcodeIds.Any())
+        {
+            return Enumerable.Empty<StreetcodeContent>();
+        }
+
+        var ids = streetcodeIds.Distinct().ToList();
+        return await FindAll()
+            .AsNoTracking()
+            .Where(s => ids.Contains(s.Id))
+            .ToListAsync(cancellationToken);
     }

If not globally enabled, add:

// at file top
using System.Linq;
using System.Threading;
Streetcode/Streetcode.DAL/Repositories/Interfaces/Streetcode/IStreetcodeRepository.cs (1)

8-8: Propagate cancellation tokens from top to data layer

Add an optional CancellationToken to support request aborts/timeouts.

Apply:

-    Task<IEnumerable<StreetcodeContent>> GetStreetcodesByIdsAsync(IEnumerable<int> streetcodeIds);
+    Task<IEnumerable<StreetcodeContent>> GetStreetcodesByIdsAsync(IEnumerable<int> streetcodeIds, CancellationToken cancellationToken = default);

If not present, add:

using System.Threading;
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdQuery.cs (1)

7-8: LGTM

Query shape is clear and minimal.

Consider aligning naming with the project’s “Favourite” convention for consistency (e.g., GetFavouriteStreetcodesByUserIdQuery).

Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (2)

1-10: Missing System.Linq import

Ensure Linq is available for Any/Select/Distinct if implicit usings are off.

Apply:

 using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;

28-42: Deduplicate IDs and pass CancellationToken downstream

Avoid redundant DB filter terms and propagate CT to the repository call.

Apply:

-            var streetcodeIds = favoriteStreetcodes.Select(fs => fs.StreetcodeId).ToList();
+            var streetcodeIds = favoriteStreetcodes.Select(fs => fs.StreetcodeId).Distinct().ToList();
             var streetcodes = await _repositoryWrapper.StreetcodeRepository
-                .GetStreetcodesByIdsAsync(streetcodeIds);
+                .GetStreetcodesByIdsAsync(streetcodeIds, cancellationToken);

Optional: log when favorites are empty to aid diagnostics.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 014f987 and fbe46d1.

📒 Files selected for processing (6)
  • Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (1 hunks)
  • Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdQuery.cs (1 hunks)
  • Streetcode/Streetcode.DAL/Repositories/Interfaces/Streetcode/IStreetcodeRepository.cs (1 hunks)
  • Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (2 hunks)
  • Streetcode/Streetcode.WebApi/Controllers/FavouriteStreetcode/FavouriteStreetcodeController.cs (2 hunks)
  • Streetcode/Streetcode.XUnitTest/BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserIdQueryHandlerTests.cs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdQuery.cs (1)
Streetcode/Streetcode.XUnitTest/BLL/MediatR/StreetCode/Streetcode/Create/StreetcodeCreateHandlerTest.cs (1)
  • StreetcodeDTO (550-559)
Streetcode/Streetcode.WebApi/Controllers/FavouriteStreetcode/FavouriteStreetcodeController.cs (3)
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (1)
  • Task (28-42)
Streetcode/Streetcode.DAL/Repositories/Interfaces/Streetcode/IStreetcodeRepository.cs (1)
  • Task (8-8)
Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (1)
  • Task (16-21)
Streetcode/Streetcode.XUnitTest/BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserIdQueryHandlerTests.cs (3)
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (3)
  • GetFavoritesByUserIdHandler (13-43)
  • GetFavoritesByUserIdHandler (18-26)
  • Task (28-42)
Streetcode/Streetcode.DAL/Repositories/Interfaces/Streetcode/IStreetcodeRepository.cs (1)
  • Task (8-8)
Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (3)
  • Task (16-21)
  • StreetcodeRepository (9-22)
  • StreetcodeRepository (11-14)
Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (2)
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (1)
  • Task (28-42)
Streetcode/Streetcode.DAL/Repositories/Interfaces/Streetcode/IStreetcodeRepository.cs (1)
  • Task (8-8)
Streetcode/Streetcode.BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserId/GetFavoritesByUserIdHandler.cs (2)
Streetcode/Streetcode.DAL/Repositories/Interfaces/Streetcode/IStreetcodeRepository.cs (1)
  • Task (8-8)
Streetcode/Streetcode.DAL/Repositories/Realizations/Streetcode/StreetcodeRepository.cs (3)
  • Task (16-21)
  • StreetcodeRepository (9-22)
  • StreetcodeRepository (11-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and analyze
🔇 Additional comments (3)
Streetcode/Streetcode.XUnitTest/BLL/MediatR/FavouriteStreetcode/GetFavoritesByUserIdQueryHandlerTests.cs (3)

40-89: Happy-path coverage looks solid

Mocks and assertions validate mapping and counts correctly.


91-116: Good negative path tests

Verifies no downstream calls when there are no favorites.


118-142: Null path handled

Appropriate assertion and verifications.

@Skiper29 Skiper29 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Perhaps it is not necessary to create the GetStreetcodesByIdsAsync method in StreetcodeRepository. It is redundant because it is used in only one place. Instead, you should use the existing GetAllAsync or FindAll methods, using the predicate parameter for filtering.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
71.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@weazy12 weazy12 merged commit 3271a88 into dev Sep 23, 2025
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task][User/Favorite] Add endpoint GetByUserId

4 participants