Skip to content

E2602 - Reimplement student task view#352

Open
bestinlalu wants to merge 4 commits into
expertiza:mainfrom
bestinlalu:main
Open

E2602 - Reimplement student task view#352
bestinlalu wants to merge 4 commits into
expertiza:mainfrom
bestinlalu:main

Conversation

@bestinlalu

@bestinlalu bestinlalu commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

This PR implements the StudentTask backend for the reimplementation, mirroring the functionality of the old Expertiza student_task_controller. It introduces student task listing, timeline data, teammate discovery, and revision tracking logic.

StudentTasksController

  • list - Returns all StudentTask objects for the logged-in user
  • show - Returns a single StudentTask object by participant ID with a unified event data (due dates + peer review responses + author feedback), with authorization checks
  • team - Returns teammates grouped by course name for the logged-in user

Grades Controller

  • get_team_scores - Embeds team_members hash (team name, grade, comment, submission links, member list) directly in the view_our_scores JSON response. Previously the frontend made 3+ sequential follow-up requests (/participants/user/:id → /teams_participants/:id/list_participants → /users/:id per member). Now a single request is sufficient.
  • get_reviews - Added else branch for single-round assignments. The original implementation only handled varying_rubrics_by_round? assignments; single-round assignments silently returned no scores. The new branch groups all submitted responses under a synthetic Round-1 key matching the same data shape as the varying-round branch.
  • ** insert_section_headers** (new private method) - After building each round's scores array, walks the questionnaire's items in seq order to locate SectionHeader items, counts the scored items preceding each header to determine insertion position, then inserts { type: "header", txt: "..." } sentinels into the array. Called for both varying-round and single-round branches. The frontend uses these sentinels to render labelled section dividers between rubric item rows.

StudentTask model

  • Added course, due_dates, revise, not_started attributes
  • create_from_participant - now computes current_stage and stage_deadline dynamically from due dates via DueDate.current_stage_for and DueDate.next_due_date, and resolves topic from SignedUpTeam → ProjectTopic
  • tasks - sorts tasks by course, then assignment, then deadline
  • all_teammates - mirrors old StudentTask.teamed_students; groups teammate names by course, sorted alphabetically, excludes calibrated assignments
  • get_events_for_assignment - builds a unified sorted timeline from due dates, submitted peer reviews and author feedback
  • submission_updated? - returns true if student has started work in the current stage (submitted content or given a review)
  • started? - returns true if assignment is in an active work stage but student hasn't started

DueDate model

  • Added DEADLINE_TYPE_NAMES constant in ExpertizaConstants::DeadlineTypes replacing the old DeadlineType DB table lookup
  • Added current_stage_for(assignment) - returns stage name from the next upcoming due date

AssignmentParticipant model

  • current_stage and stage_deadline are now computed dynamically from due dates, never from stored columns

AssignmentTeam model

  • Added submitted_files stub (file storage not yet implemented)
  • Restored has_submissions? to match old implementation

Response

  • Response#questionnaire - Fixed a NoMethodError crash on single-round assignments. The original one-liner called .questionnaire directly on the result of find_by(used_in_round: self.round), which returns nil for single-round assignments (their AssignmentQuestionnaire has used_in_round: nil but responses store round: 1). The fix falls back to .first when the round-specific lookup returns nil, and uses the safe navigator &. to handle the case where no AssignmentQuestionnaire exists at all.

ExpertizaConstants

  • Added DeadlineTypes submodule with named constants (SUBMISSION, REVIEW, etc.) and NAMES hash

Tests Added:

  • spec/models/student_task_spec.rb — revise?, not_started?, teamed_students, get_timeline_data
  • spec/models/due_date_spec.rb — current_stage_for
  • spec/requests/api/v1/student_tasks_controller_spec.rb — show/:id, team endpoints
  • spec/routing/student_tasks_routing_spec.rb — list, show/:id, team routes

Danger Policy and Code Review Quality Assessment

Pull Request Scope Issues

CRITICAL: Excessive PR Size & Multi-Concern Scope

  • This PR modifies 11+ files across 5 distinct concerns (StudentTask, GradesController, TeamsParticipantsController, Response, ExpertizaConstants), violating the principle of atomic, single-concern changes
  • GradesController alone: 498 lines (~110 lines net change) — this substantial refactor of heatgrid and score-view logic should be in a separate PR
  • StudentTask.rb: 206 lines (193 net new lines) — completely rewritten with 7 new public methods; combined with other changes, this creates high cognitive load for reviewers
  • Total affected production code: 743 lines across controllers and models — this is a large PR for a feature nominally about "reimplement student task view"

Test Coverage & Quality Patterns

Shallow RSpec Patterns

  • Heavy reliance on .allow().and_return() mocking without integration verification (31 RSpec examples with 5+ stub chains per spec)
  • StudentTask#get_timeline_data, #teamed_students, and #revise? are heavily mocked in tests rather than exercising real database queries and associations (e.g., allow(ReviewResponseMap).to receive(:where).and_return([]))
  • Mocks of DueDate, SignedUpTeam, ReviewResponseMap, and FeedbackResponseMap throughout student_task_spec.rb may hide integration issues
  • Test specs for timeline generation use stubbed timeline data rather than creating actual DueDate, Response, and FeedbackResponseMap records to verify real associations work

Inconsistent Test Depth

  • teamed_students test creates real AssignmentTeam and team members (better), but get_timeline_data and revise? are 100% mocked
  • GradesController tests expanded by 173 lines but largely assert response shape without verifying the underlying data aggregation logic

Authorization & Security

Positive: User ID Validation

  • StudentTasksController#show correctly checks participant.user_id != current_user.id and returns 403
  • TeamsParticipantsController#list_participants adds proper authorization guard for non-TA users

Concern: Authorization Added to Wrong Place

  • TeamsParticipantsController#action_allowed? now handles both update_duty and list_participants, but authorization logic for list_participants is scattered between action_allowed? and the action body; this mixes concerns and makes the logic harder to follow

Code Duplication & Coupling

Potential Duplication

  • StudentTask#get_timeline_data builds a timeline by merging due dates, peer reviews, and author feedback
  • GradesController#get_heatgrid_data_for also builds score-view timelines with similar logic (sorting, round grouping)
  • Response#questionnaire added fallback logic for single-round assignments, but this same logic may be needed elsewhere if get_heatgrid_data_for handles single-round assignments differently

Tight Coupling

  • StudentTask#create_from_participant depends on DueDate.current_stage_for, DueDate.next_due_date, SignedUpTeam, assignment.course, and timezone preference lookup — a many-dependency initializer makes testing and refactoring fragile
  • StudentTask#get_timeline_data directly queries ReviewResponseMap and FeedbackResponseMap; adding a new timeline source requires modifying this method

Testing Coverage Gaps

  • No integration tests verifying that StudentTasksController#show correctly populates due_dates from real DueDate and Response records
  • GradesController#inject_section_headers is a new private helper with no dedicated spec; tested only indirectly via get_heatgrid_data_for
  • AssignmentTeam#submitted_files added as a stub returning [] with no tests explaining its intended use or future implementation
  • Response#questionnaire fallback behavior tested, but no test covers the case where both lookups fail and nil is returned

Configuration & Schema Changes

  • No database migrations added despite schema.rb existing (19KB); PR reimplements without schema changes, which is acceptable, but should be documented
  • Route configuration change is appropriate (removing get :view, adding get 'show/:id' and get :team), but these changes are bundled with large logic changes

Code Quality Issues

Complex Initialization Logic

  • StudentTask#initialize now accepts 10+ fields via a hash (assignment, course, current_stage, participant, stage_deadline, topic, permission_granted, due_dates, active_round, revise, not_started); large initializer signature is hard to maintain

Multi-Step Dependency Resolution

  • StudentTask.create_from_participant spans ~20 lines with inline calls to DueDate.next_due_date, SignedUpTeam.find_by, project_topic, timezone lookup, and then assignment of computed revise? and not_started? flags; this would benefit from smaller private helper methods

Private Method Inconsistency

  • StudentTask.parse_stage_deadline is a class method but defined in the private section; should clarify intent (used by class method, so could be public or moved outside private block)

Summary of Violations Against Danger Policy

Criterion Status Notes
PR Size ⚠️ VIOLATION 11+ files, 743 LOC across multiple concerns; should be split
Single Concern ⚠️ VIOLATION StudentTask, GradesController, Response, TeamsParticipants, ExpertizaConstants all modified; GradesController changes alone warrant separate PR
WIP Title ✅ PASS Title is clear: "E2602 - Reimplement student task view"
DEBUG/TODO ✅ PASS No debug statements or TODO/FIXME in modified code (unrelated puts found in other specs)
Test Coverage ⚠️ CONCERN Moderate: 31 examples added, but heavy mocking reduces integration verification; shallow RSpec patterns detected
Schema Changes ✅ PASS No schema changes without migrations (reimplementation has no schema impact)
Vendor/Factory ✅ PASS No vendor or factory changes
Authorization ✅ PASS User ID checks present in StudentTasksController#show and TeamsParticipantsController

Recommendations for Revision

  1. Split into smaller PRs: Separate StudentTask/StudentTasksController from GradesController refactor; separate authorization logic additions from model/controller logic
  2. Reduce mocking depth: Add integration tests with real database records for StudentTask#get_timeline_data, #teamed_students, #revise?, and #not_started?
  3. Clarify timeline duplication: Verify whether GradesController#get_heatgrid_data_for and StudentTask#get_timeline_data should share logic or remain independent
  4. Simplify StudentTask initialization: Break down create_from_participant into smaller methods for each responsibility (resolve topic, determine stage, compute deadline)
  5. Document AssignmentTeam#submitted_files: Add comment explaining the stub and its eventual implementation plan

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

StudentTask model gains rich state tracking and teammate/timeline lookup features; deadline-type constants enable stage resolution. Controllers add participant-driven show endpoint and team endpoint. Grades heatgrid adds section-header injection and response improvements. Tests comprehensively cover all new behavior.

Changes

Student Task Lifecycle and API Endpoint Refactoring

Layer / File(s) Summary
Deadline Type Constants and Due Date Stage Calculation
app/models/concerns/expertiza_constants.rb, app/models/due_date.rb, spec/models/due_date_spec.rb
ExpertizaConstants::DeadlineTypes defines deadline type IDs and a frozen NAMES hash mapping them to stage names. DueDate.current_stage_for(assignment) resolves the assignment's current stage from the next upcoming due date, returning 'Finished' when none exist and using the mapping with 'Unknown' fallback. Tests validate submission, review, finished, and unknown stage resolution.
StudentTask Model Expansion and Timeline/Teammate Features
app/models/student_task.rb
StudentTask adds attr_accessor for course, due_dates, revise, not_started, active_round. create_from_participant rewritten to derive stage from DueDate.current_stage_for, resolve topic via team signup, parse timezone-aware deadline with 'Finished' fallback, set active_round from next due date, and compute revise/not_started flags. New class methods: get_timeline_data(assignment, participant) merges due-dates, submitted peer reviews, and author feedback into sorted timeline; teamed_students(user) groups teammates by course, excluding calibrated assignments and the user. New instance predicates: revise? detects work in submission/review stages; not_started? detects active stages without work.
StudentTask Model Tests
spec/models/student_task_spec.rb
Shared setup enriched with course/assignment/participant doubles and stubbed dependency queries. .initialize test updated for "submission" stage. .from_participant expectations adjusted for stubbed topic and stage. .from_participant_id verifies AssignmentParticipant lookup. .from_user verifies composite sort key [course, assignment, stage_deadline]. New instance specs cover #revise? and #not_started? across stages using submitted response stubs. .teamed_students validates per-course grouping, user/calibration exclusion, and alphabetical sorting. .get_timeline_data validates due-date entries (id: nil), per-round submitted review inclusion, unsubmitted exclusion, and output ordering by date.
Supporting Model Changes
app/models/assignment_team.rb
AssignmentTeam.submitted_files stub returns [] to prevent has_submissions? errors. Whitespace normalization.
StudentTasksController Endpoints and Routes
app/controllers/student_tasks_controller.rb, config/routes.rb
New team endpoint renders StudentTask.teamed_students(current_user) as JSON. show rewritten to look up AssignmentParticipant by params[:id], return 404 when missing, 403 on user mismatch, build task with due_dates from StudentTask.get_timeline_data. view action removed. Routes updated: replaces get :view with get 'show/:id' and get :team.
StudentTasks API Request Tests
spec/requests/api/v1/student_tasks_controller_spec.rb
GET /student_tasks/list setup creates complete graph and generates participants with minimal fields. Response schema narrowed to assignment, current_stage, stage_deadline (strings), permission_granted (bool). Replaced view spec with GET /student_tasks/show/{id} asserting assignment, due_dates array, and 404 error. Added authorization: 403 for another user's participant, 401 for missing auth. Added GET /student_tasks/team asserting Hash response and 401 auth case.
StudentTasks Routing Tests
spec/routing/student_tasks_routing_spec.rb
Added routing specs for /student_tasks/list, /student_tasks/show/:id (with :id param), and /student_tasks/team.
Response#questionnaire Fallback and Tests
app/models/response.rb, spec/models/response_spec.rb
Response#questionnaire now falls back to first AssignmentQuestionnaire when round-specific lookup fails, returning nil when none exist. Tests cover round-matching, fallback to used_in_round: nil, and nil-safe nil return.
TeamsParticipants Authorization Guard
app/controllers/teams_participants_controller.rb
action_allowed? includes list_participants in student-privileges eligibility. list_participants adds non-TA guard: checks TeamsParticipant membership and returns 403 if user is not a member.
Participants Controller Serialization
app/controllers/participants_controller.rb
list_user_participants returns attribute hashes instead of ActiveRecord objects.
Grades Heatgrid Section Headers and N+1 Fix
app/controllers/grades_controller.rb
view_all_scores adds includes(:users) to reduce N+1. get_our_scores_data replaces team_details with team_members object containing team metadata and member list from team.users. get_heatgrid_data_for returns initialized hash when maps empty; sorts answers by reviewer/reviewee name (case-insensitive); discovers per-round grouping in non-varying path instead of single bucket; injects SectionHeader sentinels via new inject_section_headers helper using questionnaire Item records.
Grades API Request Tests
spec/requests/api/v1/grades_controller_spec.rb
instructor_review expanded to cover new/unsaved/submitted review states with HTTP request contract assertions. TA forbidden access test added for assign_grade. view_our_scores section-header test validates header sentinels in correct round positions with SectionHeader items, confirms absent after deletion. student_tasks/show constraint test verifies 404/403 for non-AssignmentParticipant ids.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes


Suggested labels

api, database, tests

🚥 Pre-merge checks | ✅ 7 | ❌ 7

❌ Failed checks (6 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Workflow-Security ⚠️ Warning .github/workflows/danger_target.yml uses pull_request_target and actions/checkout of PR head (ref/repository) with token: ${{ secrets.GITHUB_TOKEN }} and DANGER_GITHUB_API_TOKEN from secrets. Use pull_request (not pull_request_target) or avoid checkout of PR head; remove secrets-based tokens/env and set explicit minimal GITHUB_TOKEN permissions (read-only).
Todo-Temp-Debug-Artifacts ⚠️ Warning PR commit introduces generated local-state files results.txt (SimpleCov/Coveralls output) and safe.log (mysqld_safe log), found in git show HEAD. Delete committed generated artifacts (results.txt, safe.log) and add matching patterns to .gitignore so CI/coverage/log output isn’t committed again.
Legacy-Pr-Scope-And-Title ⚠️ Warning Per PR summary, changed files list shows ~16 files with ~1,168 added LOC in those files, exceeding the 500 LOC warning threshold. Split the change into smaller PRs (e.g., model-only, controller/routes, and spec updates) to keep each under ~500 LOC and reduce touched surface area.
Legacy-Config-File-Guardrails ⚠️ Warning Evidence from git show --name-only HEAD lists changes to Gemfile/Gemfile.lock, .gitignore/.rspec, Dangerfile, Rakefile, config.ru, setup.sh, plus many YAML/Markdown and spec/factories/** files—no... Provide a clear justification for each guarded-file change (or revert them), since PR description only discusses student_tasks/grades and related model logic/tests.
Legacy-Rspec-Hygiene ⚠️ Warning PR’s spec/models/student_task_spec.rb includes shallow/non-real-value assertions like expect(...).to be_nil and expect(...).to be_empty (e.g., lines 59, 282, 317). Replace shallow nil/empty checks with meaningful assertions on returned data (specific fields/structure) or stronger expectations (e.g., eq expected IDs/names) instead of be_nil/be_empty placeholders.
Config-And-Setup-Scrutiny ❓ Inconclusive Could not verify whether those files changed: local git diff is empty, and gh pr view for PR#352 fails with 401 auth required. Share the PR’s changed-file list/diff for config/database.yml, config/storage.yml, config/credentials.yml.enc, config.ru, setup.sh, and workflow files (or provide GitHub auth) so we can confirm.
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: reimplementing the student task view endpoint with a subsystem-focused prefix (E2602) and concise imperative phrasing that accurately reflects the core functionality.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Schema-Without-Migration ✅ Passed In the PR commit, db/schema.rb is changed and many files under db/migrate/ are also changed (e.g., listing includes db/migrate/* and db/schema.rb).
Behavior-Change-Needs-Tests ✅ Passed Controller/model/routes changes in commit 841b3b3 are accompanied by spec updates in spec/models and spec/requests (due_date_spec, student_task_spec, response_spec, request/routing specs).
Legacy-Global-Debug-Code ✅ Passed Searched PR-related files for uncommented puts/print, binding.pry, debugger, console.log, and global/class vars; only a commented “# puts” appears in app/models/response.rb.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
2 Warnings
⚠️ Your pull request is more than 500 LoC.
Please make sure you did not commit unnecessary changes, such as schema.rb, node_modules, or changelog noise.
⚠️ One or more of your test expectations only focus on the return value not being nil, empty, or 0 without testing the real value.
To avoid shallow tests, please write expectations that verify the real value.
You are including debug code in your pull request, please remove it.
1 Message
📖 Thanks for the pull request, and welcome! The Expertiza team is excited to review your changes, and you should hear from us soon.

Please make sure the PR passes all checks and you have run rubocop -a to autocorrect issues before requesting a review.

This repository is being automatically checked for code-quality issues using CodeRabbit, Danger, and CI workflows. Please address newly introduced issues before marking the PR ready for review.

Also, please spend some time looking at the instructions at the top of your course project writeup.
If you have any questions, please send email to expertiza-support@lists.ncsu.edu.

Thanks for the pull request, and welcome! The Expertiza team is excited to review your changes, and you should hear from us soon.

Please make sure the PR passes all checks and you have run rubocop -a to autocorrect issues before requesting a review.

This repository is being automatically checked for code-quality issues using CodeRabbit, Danger, and CI workflows. Please address newly introduced issues before marking the PR ready for review.

Also, please spend some time looking at the instructions at the top of your course project writeup.
If you have any questions, please send email to expertiza-support@lists.ncsu.edu.

Your pull request is more than 500 LoC.
Please make sure you did not commit unnecessary changes, such as schema.rb, node_modules, or changelog noise.

One or more of your test expectations only focus on the return value not being nil, empty, or 0 without testing the real value.
To avoid shallow tests, please write expectations that verify the real value.

Generated by 🚫 Danger

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

🚨 RSpec Tests Report

Failing Controller Test Cases:
rspec ./spec/requests/api/v1/student_tasks_controller_spec.rb:49 # StudentTasks API /student_tasks/list get authorized request has proper JSON schema returns a 200 response
rspec ./spec/requests/api/v1/student_tasks_controller_spec.rb:109 # StudentTasks API /student_tasks/show/{id} get successful retrieval with due dates returns a 200 response

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/models/assignment_team.rb (1)

160-213: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Duplicate method block overrides earlier team-cleanup behavior.

Line 183 redefines remove_participant and overrides the earlier implementation (Line 145), dropping destroy if participants.empty?. Because Ruby uses the last definition, empty teams are no longer auto-destroyed.

🧹 Nitpick comments (3)
spec/models/student_task_spec.rb (1)

242-298: ⚡ Quick win

Add regression specs for ordering and submitted-only timeline behavior.

The new suite doesn’t lock two changed contracts: .from_user multi-key ordering and exclusion of unsubmitted Response records from .get_timeline_data. Please add explicit examples for both to prevent silent regressions.

As per coding guidelines, "Check that model specs cover validations, associations, callbacks, and important edge cases with meaningful assertions instead of shallow examples."

Source: Coding guidelines

config/routes.rb (1)

52-53: ⚡ Quick win

Avoid duplicate show paths; keep one canonical show route

resources :student_tasks already provides GET /student_tasks/:id. Adding GET /student_tasks/show/:id creates duplicate endpoint contracts for the same action and increases routing/spec/swagger drift risk.

Suggested fix
       resources :student_tasks do
         collection do
           get :list, action: :list
-          get 'show/:id', action: :show
           get :team, action: :team
         end
       end

As per coding guidelines, config/routes.rb should flag duplicate or shadowed routes and surprising non-RESTful patterns.

Source: Coding guidelines

spec/requests/api/v1/student_tasks_controller_spec.rb (1)

179-183: ⚡ Quick win

Strengthen /student_tasks/team success assertions beyond type-checking

Asserting only Hash will pass even if grouping/output semantics regress. Add fixture data and assert at least one expected course key and teammate name list to lock the API contract.

As per coding guidelines, spec/requests/**/*.rb tests should include meaningful expectations and avoid shallow assertions that only prove superficial structure.

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a154aa7-bbca-405c-a95a-fac228b63523

📥 Commits

Reviewing files that changed from the base of the PR and between 3eabaf9 and 946fffc.

📒 Files selected for processing (10)
  • app/controllers/student_tasks_controller.rb
  • app/models/assignment_team.rb
  • app/models/concerns/expertiza_constants.rb
  • app/models/due_date.rb
  • app/models/student_task.rb
  • config/routes.rb
  • spec/models/due_date_spec.rb
  • spec/models/student_task_spec.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • spec/routing/student_tasks_routing_spec.rb
📜 Review details
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: test
🧰 Additional context used
📓 Path-based instructions (6)
spec/models/**/*.rb

⚙️ CodeRabbit configuration file

spec/models/**/*.rb: Check that model specs cover validations, associations, callbacks, and important edge cases
with meaningful assertions instead of shallow examples.
Also apply the legacy Danger policy: discourage create( in unit tests when build or doubles are enough,
reject .should, skipped/focused specs, wildcard matcher overuse, missing expectations, matcher-less expectations,
and expectations that only prove values are not nil, empty, or zero.

Files:

  • spec/models/due_date_spec.rb
  • spec/models/student_task_spec.rb
**

⚙️ CodeRabbit configuration file

**: # CodeRabbit Setup For This Repository

This repository uses CodeRabbit as an AI pull request reviewer for the Expertiza backend reimplementation. The goal is to improve review quality and preserve project-specific policy without replacing the existing CI runners.

What CodeRabbit Should Do Here

  • Review pull requests automatically and re-review on new commits.
  • Leave useful inline comments on Rails, API, database, workflow, and test changes.
  • Summarize the impact of a pull request clearly for human reviewers.
  • Surface policy issues that used to live in Danger-like rules, but start in warning mode instead of blocking merges.
  • Read GitHub check results and use them as context when tests or workflows fail.

What CodeRabbit Should Not Replace Here

  • GitHub Actions still runs the real work.
  • main.yml and TestPR.yml still execute RSpec, database setup, coverage generation, and Docker-related jobs.
  • lint.yml still remains the source of truth for runnable spellcheck and lint workflows unless those checks are intentionally retired.
  • CodeRabbit is a reviewer and explainer, not the test runner or deployment engine.

Repository Context

  • Language and framework: Ruby 3.4.5 with Rails 8.
  • Test stack: RSpec, mainly under spec/models and spec/requests.
  • API surface: controllers plus request specs, with Swagger documentation checked into swagger/v1/swagger.yaml.
  • Database: MySQL-backed Rails app with a large migration history and db/schema.rb committed.
  • Automation: GitHub Actions workflows in .github/workflows, including CI, PR test reporting, linting, and Danger.

Review Standards For This Codebase

Controllers

  • Verify authorization behavior and strong parameters.
  • Check HTTP status codes and response payload consistency.
  • Flag N+1 queries or heavy database work in request paths.
  • Expect request-spec coverage for behavior changes.
  • If an endpoint contract changes, expect Swagger documentation to stay in sync.

Models

...

Files:

  • spec/models/due_date_spec.rb
  • app/models/concerns/expertiza_constants.rb
  • config/routes.rb
  • app/models/due_date.rb
  • spec/routing/student_tasks_routing_spec.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • app/controllers/student_tasks_controller.rb
  • app/models/assignment_team.rb
  • spec/models/student_task_spec.rb
  • app/models/student_task.rb
app/models/**/*.rb

⚙️ CodeRabbit configuration file

app/models/**/*.rb: Focus on associations, validations, callbacks, transactions, STI and polymorphic behavior,
foreign keys, data integrity, and query efficiency.

Files:

  • app/models/concerns/expertiza_constants.rb
  • app/models/due_date.rb
  • app/models/assignment_team.rb
  • app/models/student_task.rb
config/routes.rb

⚙️ CodeRabbit configuration file

config/routes.rb: Flag duplicate or shadowed routes, surprising non-RESTful patterns, and route changes without matching request specs.

Files:

  • config/routes.rb
spec/requests/**/*.rb

⚙️ CodeRabbit configuration file

spec/requests/**/*.rb: Check authentication, authorization, invalid input, response payload assertions, and failure cases.
When endpoints change, expect Swagger docs to stay aligned.
Apply the legacy shallow-test rules: each new test should have a meaningful expectation,
avoid commented-out expectations, and do not rely only on page content or non-nil checks.

Files:

  • spec/requests/api/v1/student_tasks_controller_spec.rb
app/controllers/**/*.rb

⚙️ CodeRabbit configuration file

app/controllers/**/*.rb: Review authorization, strong parameters, HTTP status codes, and response shape consistency.
Flag N+1 queries, missing request-spec coverage, and behavior changes not reflected in Swagger docs.

Files:

  • app/controllers/student_tasks_controller.rb
🪛 RuboCop (1.87.0)
spec/requests/api/v1/student_tasks_controller_spec.rb

[convention] 163-163: Do not use strings for word-like symbol literals.

(Style/SymbolLiteral)


[convention] 187-187: Do not use strings for word-like symbol literals.

(Style/SymbolLiteral)

spec/models/student_task_spec.rb

[convention] 14-14: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 15-15: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 16-16: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 18-18: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 19-19: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 20-20: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 32-32: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 33-33: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 34-34: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 35-35: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 36-36: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 37-37: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 183-183: Line is too long. [192/120]

(Layout/LineLength)


[convention] 184-184: Line is too long. [138/120]

(Layout/LineLength)


[convention] 185-185: Line is too long. [134/120]

(Layout/LineLength)


[convention] 186-186: Line is too long. [192/120]

(Layout/LineLength)


[convention] 187-187: Line is too long. [192/120]

(Layout/LineLength)


[convention] 231-231: Line is too long. [175/120]

(Layout/LineLength)


[convention] 245-245: Line is too long. [178/120]

(Layout/LineLength)

app/models/student_task.rb

[convention] 4-4: Line is too long. [147/120]

(Layout/LineLength)


[convention] 19-37: Assignment Branch Condition size for create_from_participant is too high. [<7, 22, 5> 23.62/20]

(Metrics/AbcSize)


[convention] 26-26: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 27-27: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 28-28: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 29-29: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 30-30: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 30-30: Line is too long. [147/120]

(Layout/LineLength)


[convention] 32-32: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 39-40: Extra blank line detected.

(Layout/EmptyLines)


[convention] 41-41: Expected 1 empty line between method definitions; found 2.

(Layout/EmptyLineBetweenDefs)


[convention] 56-99: Assignment Branch Condition size for get_timeline_data is too high. [<7, 39, 7> 40.24/20]

(Metrics/AbcSize)


[convention] 56-99: Method has too many lines. [33/20]

(Metrics/MethodLength)


[convention] 62-62: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 63-63: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 63-63: Line is too long. [160/120]

(Layout/LineLength)


[convention] 64-64: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 65-65: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 76-76: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 77-77: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 78-78: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 79-79: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 90-90: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 91-91: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 92-92: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 93-93: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 103-118: Assignment Branch Condition size for teamed_students is too high. [<7, 20, 10> 23.43/20]

(Metrics/AbcSize)


[convention] 103-118: Cyclomatic complexity for teamed_students is too high. [11/7]

(Metrics/CyclomaticComplexity)


[convention] 103-118: Perceived complexity for teamed_students is too high. [11/8]

(Metrics/PerceivedComplexity)


[convention] 106-106: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 139-139: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 141-141: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 146-146: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[warning] 154-154: private (on line 131) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.

(Lint/IneffectiveAccessModifier)


[convention] 155-155: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)

Comment thread app/controllers/student_tasks_controller.rb Outdated
Comment thread app/models/student_task.rb Outdated
Comment thread app/models/student_task.rb Outdated
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@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: 10

🧹 Nitpick comments (2)
app/models/student_task.rb (1)

44-47: 🚀 Performance & Scalability | 🏗️ Heavy lift

Preload the list endpoint's participant graph.

from_user maps over a bare AssignmentParticipant.where(user_id: user.id), then create_from_participant dereferences assignment, assignment.course, team, user, due dates, and review state for each row. On /student_tasks/list, that becomes an N+1 query pattern per task.

As per coding guidelines, "Flag N+1 queries or heavy database work in request paths."

Source: Coding guidelines

spec/requests/api/v1/student_tasks_controller_spec.rb (1)

106-152: 🗄️ Data Integrity & Integration | ⚡ Quick win

Merge the duplicate RSwag declaration for GET /student_tasks/show/{id}.

Lines 106-221 define the same path and verb twice. Depending on how rswag collapses duplicate metadata, one block's responses can overwrite the other in generated Swagger output, which makes the published contract unstable. Keep a single path '/student_tasks/show/{id}' block and fold the 200/401/403/404 cases into it.

As per coding guidelines, "When endpoints change, expect Swagger docs to stay aligned."

Also applies to: 157-221

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9643f2af-7b3d-4fe4-8ad7-565ce5e53463

📥 Commits

Reviewing files that changed from the base of the PR and between 946fffc and 6a64f65.

📒 Files selected for processing (17)
  • app/controllers/concerns/authorization.rb
  • app/controllers/grades_controller.rb
  • app/controllers/participants_controller.rb
  • app/controllers/student_tasks_controller.rb
  • app/controllers/teams_participants_controller.rb
  • app/models/assignment_team.rb
  • app/models/concerns/expertiza_constants.rb
  • app/models/due_date.rb
  • app/models/response.rb
  • app/models/student_task.rb
  • config/routes.rb
  • spec/models/due_date_spec.rb
  • spec/models/response_spec.rb
  • spec/models/student_task_spec.rb
  • spec/requests/api/v1/grades_controller_spec.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • spec/routing/student_tasks_routing_spec.rb
🚧 Files skipped from review as they are similar to previous changes (6)
  • spec/routing/student_tasks_routing_spec.rb
  • app/models/due_date.rb
  • app/models/assignment_team.rb
  • config/routes.rb
  • spec/models/due_date_spec.rb
  • app/models/concerns/expertiza_constants.rb
📜 Review details
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: test
🧰 Additional context used
📓 Path-based instructions (5)
app/controllers/**/*.rb

⚙️ CodeRabbit configuration file

app/controllers/**/*.rb: Review authorization, strong parameters, HTTP status codes, and response shape consistency.
Flag N+1 queries, missing request-spec coverage, and behavior changes not reflected in Swagger docs.

Files:

  • app/controllers/participants_controller.rb
  • app/controllers/teams_participants_controller.rb
  • app/controllers/concerns/authorization.rb
  • app/controllers/student_tasks_controller.rb
  • app/controllers/grades_controller.rb
**

⚙️ CodeRabbit configuration file

**: # CodeRabbit Setup For This Repository

This repository uses CodeRabbit as an AI pull request reviewer for the Expertiza backend reimplementation. The goal is to improve review quality and preserve project-specific policy without replacing the existing CI runners.

What CodeRabbit Should Do Here

  • Review pull requests automatically and re-review on new commits.
  • Leave useful inline comments on Rails, API, database, workflow, and test changes.
  • Summarize the impact of a pull request clearly for human reviewers.
  • Surface policy issues that used to live in Danger-like rules, but start in warning mode instead of blocking merges.
  • Read GitHub check results and use them as context when tests or workflows fail.

What CodeRabbit Should Not Replace Here

  • GitHub Actions still runs the real work.
  • main.yml and TestPR.yml still execute RSpec, database setup, coverage generation, and Docker-related jobs.
  • lint.yml still remains the source of truth for runnable spellcheck and lint workflows unless those checks are intentionally retired.
  • CodeRabbit is a reviewer and explainer, not the test runner or deployment engine.

Repository Context

  • Language and framework: Ruby 3.4.5 with Rails 8.
  • Test stack: RSpec, mainly under spec/models and spec/requests.
  • API surface: controllers plus request specs, with Swagger documentation checked into swagger/v1/swagger.yaml.
  • Database: MySQL-backed Rails app with a large migration history and db/schema.rb committed.
  • Automation: GitHub Actions workflows in .github/workflows, including CI, PR test reporting, linting, and Danger.

Review Standards For This Codebase

Controllers

  • Verify authorization behavior and strong parameters.
  • Check HTTP status codes and response payload consistency.
  • Flag N+1 queries or heavy database work in request paths.
  • Expect request-spec coverage for behavior changes.
  • If an endpoint contract changes, expect Swagger documentation to stay in sync.

Models

...

Files:

  • app/controllers/participants_controller.rb
  • app/models/response.rb
  • spec/models/response_spec.rb
  • app/controllers/teams_participants_controller.rb
  • app/controllers/concerns/authorization.rb
  • spec/requests/api/v1/grades_controller_spec.rb
  • app/controllers/student_tasks_controller.rb
  • app/controllers/grades_controller.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • spec/models/student_task_spec.rb
  • app/models/student_task.rb
app/models/**/*.rb

⚙️ CodeRabbit configuration file

app/models/**/*.rb: Focus on associations, validations, callbacks, transactions, STI and polymorphic behavior,
foreign keys, data integrity, and query efficiency.

Files:

  • app/models/response.rb
  • app/models/student_task.rb
spec/models/**/*.rb

⚙️ CodeRabbit configuration file

spec/models/**/*.rb: Check that model specs cover validations, associations, callbacks, and important edge cases
with meaningful assertions instead of shallow examples.
Also apply the legacy Danger policy: discourage create( in unit tests when build or doubles are enough,
reject .should, skipped/focused specs, wildcard matcher overuse, missing expectations, matcher-less expectations,
and expectations that only prove values are not nil, empty, or zero.

Files:

  • spec/models/response_spec.rb
  • spec/models/student_task_spec.rb
spec/requests/**/*.rb

⚙️ CodeRabbit configuration file

spec/requests/**/*.rb: Check authentication, authorization, invalid input, response payload assertions, and failure cases.
When endpoints change, expect Swagger docs to stay aligned.
Apply the legacy shallow-test rules: each new test should have a meaningful expectation,
avoid commented-out expectations, and do not rely only on page content or non-nil checks.

Files:

  • spec/requests/api/v1/grades_controller_spec.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
🪛 ast-grep (0.43.0)
spec/models/student_task_spec.rb

[warning] 136-136: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(courses).to eq(courses.sort), "tasks should be sorted by course first"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures

(hardcoded-secret-rsa-passphrase-ruby)


[warning] 140-140: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(assignments).to eq(assignments.sort), "tasks within same course should be sorted by assignment name"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures

(hardcoded-secret-rsa-passphrase-ruby)

🪛 RuboCop (1.87.0)
app/models/response.rb

[convention] 19-19: Redundant self detected.

(Style/RedundantSelf)

spec/requests/api/v1/grades_controller_spec.rb

[convention] 366-366: Line is too long. [125/120]

(Layout/LineLength)


[convention] 388-388: Line is too long. [125/120]

(Layout/LineLength)


[convention] 4-573: Block has too many lines. [448/120]

(Metrics/BlockLength)

app/controllers/grades_controller.rb

[convention] 284-284: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.

(Layout/FirstHashElementIndentation)


[convention] 284-284: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 285-285: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 286-286: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 288-288: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 292-292: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.

(Layout/FirstHashElementIndentation)


[convention] 292-292: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 293-293: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 294-294: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 380-380: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 380-380: Line is too long. [158/120]

(Layout/LineLength)


[convention] 380-380: Space found before comma.

(Layout/SpaceBeforeComma)


[convention] 394-394: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 394-394: Don't use parentheses around a literal.

(Style/RedundantParentheses)


[convention] 398-398: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 402-402: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 408-408: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 408-408: Line is too long. [153/120]

(Layout/LineLength)


[convention] 417-417: Redundant return detected.

(Style/RedundantReturn)


[convention] 425-425: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 426-426: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 430-430: Unnecessary spacing detected.

(Layout/ExtraSpacing)


[convention] 433-433: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 434-434: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 436-436: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 442-442: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)

spec/requests/api/v1/student_tasks_controller_spec.rb

[convention] 117-117: Line is too long. [136/120]

(Layout/LineLength)


[convention] 119-119: Line is too long. [168/120]

(Layout/LineLength)


[convention] 120-120: Line is too long. [136/120]

(Layout/LineLength)


[convention] 167-167: Line is too long. [136/120]

(Layout/LineLength)


[convention] 169-169: Line is too long. [168/120]

(Layout/LineLength)


[convention] 170-170: Line is too long. [136/120]

(Layout/LineLength)


[convention] 216-216: Do not use strings for word-like symbol literals.

(Style/SymbolLiteral)


[convention] 240-240: Do not use strings for word-like symbol literals.

(Style/SymbolLiteral)

spec/models/student_task_spec.rb

[convention] 14-14: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 15-15: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 16-16: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 18-18: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 19-19: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 20-20: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 32-32: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 33-33: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 34-34: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 35-35: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 36-36: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 37-37: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[warning] 119-119: Useless assignment to variable - deadline_near. Did you mean deadline_far?

(Lint/UselessAssignment)


[warning] 120-120: Useless assignment to variable - deadline_far. Did you mean deadline_near?

(Lint/UselessAssignment)


[convention] 136-136: Unnecessary spacing detected.

(Layout/ExtraSpacing)


[convention] 232-232: Line is too long. [192/120]

(Layout/LineLength)


[convention] 233-233: Line is too long. [138/120]

(Layout/LineLength)


[convention] 234-234: Line is too long. [134/120]

(Layout/LineLength)


[convention] 235-235: Line is too long. [192/120]

(Layout/LineLength)


[convention] 236-236: Line is too long. [192/120]

(Layout/LineLength)


[convention] 280-280: Line is too long. [175/120]

(Layout/LineLength)


[convention] 294-294: Line is too long. [178/120]

(Layout/LineLength)


[warning] 341-341: Useless assignment to variable - draft_response.

(Lint/UselessAssignment)

app/models/student_task.rb

[convention] 4-4: Line is too long. [147/120]

(Layout/LineLength)


[convention] 19-37: Assignment Branch Condition size for create_from_participant is too high. [<7, 22, 5> 23.62/20]

(Metrics/AbcSize)


[convention] 26-26: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 27-27: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 28-28: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 29-29: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 30-30: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 30-30: Line is too long. [147/120]

(Layout/LineLength)


[convention] 32-32: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 39-40: Extra blank line detected.

(Layout/EmptyLines)


[convention] 44-44: Expected 1 empty line between method definitions; found 2.

(Layout/EmptyLineBetweenDefs)


[convention] 59-110: Assignment Branch Condition size for get_timeline_data is too high. [<7, 40, 7> 41.21/20]

(Metrics/AbcSize)


[convention] 59-110: Method has too many lines. [33/20]

(Metrics/MethodLength)


[convention] 65-65: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 66-66: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 66-66: Line is too long. [160/120]

(Layout/LineLength)


[convention] 67-67: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 68-68: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 86-86: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 87-87: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 88-88: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 89-89: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 101-101: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 102-102: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 103-103: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 104-104: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 114-129: Assignment Branch Condition size for teamed_students is too high. [<7, 20, 10> 23.43/20]

(Metrics/AbcSize)


[convention] 114-129: Cyclomatic complexity for teamed_students is too high. [11/7]

(Metrics/CyclomaticComplexity)


[convention] 114-129: Perceived complexity for teamed_students is too high. [11/8]

(Metrics/PerceivedComplexity)


[convention] 117-117: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 150-150: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 152-152: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 157-157: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[warning] 165-165: private (on line 142) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.

(Lint/IneffectiveAccessModifier)


[convention] 166-166: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)

Comment thread app/controllers/concerns/authorization.rb
Comment thread app/controllers/grades_controller.rb
Comment thread app/controllers/grades_controller.rb Outdated
Comment thread app/controllers/grades_controller.rb
Comment thread app/controllers/teams_participants_controller.rb
Comment thread app/models/response.rb Outdated
Comment thread app/models/student_task.rb
Comment thread app/models/student_task.rb Outdated
Comment thread spec/requests/api/v1/grades_controller_spec.rb
Comment thread spec/requests/api/v1/grades_controller_spec.rb Outdated
@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/response_spec.rb:151 # Response#questionnaire single-round assignment (used_in_round is nil but response.round is 1) falls back to the first AssignmentQuestionnaire and returns its questionnaire
rspec ./spec/models/response_spec.rb:166 # Response#questionnaire single-round assignment (used_in_round is nil but response.round is 1) does not raise NoMethodError when find_by returns nil
rspec ./spec/models/response_spec.rb:181 # Response#questionnaire when no AssignmentQuestionnaire exists at all returns nil safely via the safe-navigator (&.)
rspec ./spec/models/student_task_spec.rb:109 # StudentTask.from_user sorts by a single composite key [course, assignment, stage_deadline]

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/student_task_spec.rb:109 # StudentTask.from_user sorts by a single composite key [course, assignment, stage_deadline]

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@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: 3

🧹 Nitpick comments (4)
app/models/student_task.rb (1)

197-204: 📐 Maintainability & Code Quality | 💤 Low value

parse_stage_deadline is not actually private.

The private keyword on line 167 only affects instance methods. Class methods like self.parse_stage_deadline remain public. Use private_class_method to restrict access as intended.

♻️ Proposed fix
 end

+private_class_method :parse_stage_deadline
 end

Or move into a class << self block with private inside it.

Source: Linters/SAST tools

spec/requests/api/v1/student_tasks_controller_spec.rb (2)

106-152: 📐 Maintainability & Code Quality | ⚡ Quick win

Consolidate GET /student_tasks/show/{id} into a single path block.

This endpoint is declared twice with overlapping responses, which makes the contract easy to drift and harder to maintain. Keep one path '/student_tasks/show/{id}' block and group all 200/401/403/404 responses there.

Also applies to: 157-221


232-236: 📐 Maintainability & Code Quality | ⚡ Quick win

Strengthen the /student_tasks/team success assertion beyond Hash type.

The current 200 check can still pass for an empty or structurally wrong payload. Add fixture data and assert expected course-key grouping and teammate values to validate contract behavior.

As per coding guidelines, "spec/requests/**/*.rb: each new test should have a meaningful expectation ... and should not rely only on shallow checks."

Source: Coding guidelines

app/controllers/teams_participants_controller.rb (1)

50-53: 🩺 Stability & Availability

TeamsParticipant.user_id is present/non-null, so the 500-risk concern is unfounded; consider replacing pluck/include? with exists? for efficiency.

  • db/schema.rb defines teams_participants.user_id as null: false (with an index), TeamsParticipant validates user_id presence, and migration 20250427014225_add_user_id_to_teams_participants.rb adds the column.
  • Current TeamsParticipant.where(team_id: ...).pluck(:user_id).include?(current_user.id) works but loads all participant ids; TeamsParticipant.exists?(team_id: current_team.id, user_id: current_user.id) avoids materializing the list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 33e0b854-0dc9-4fe7-a116-70c8d11088bb

📥 Commits

Reviewing files that changed from the base of the PR and between 6a64f65 and 841b3b3.

📒 Files selected for processing (16)
  • app/controllers/grades_controller.rb
  • app/controllers/participants_controller.rb
  • app/controllers/student_tasks_controller.rb
  • app/controllers/teams_participants_controller.rb
  • app/models/assignment_team.rb
  • app/models/concerns/expertiza_constants.rb
  • app/models/due_date.rb
  • app/models/response.rb
  • app/models/student_task.rb
  • config/routes.rb
  • spec/models/due_date_spec.rb
  • spec/models/response_spec.rb
  • spec/models/student_task_spec.rb
  • spec/requests/api/v1/grades_controller_spec.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • spec/routing/student_tasks_routing_spec.rb
🚧 Files skipped from review as they are similar to previous changes (9)
  • config/routes.rb
  • app/models/concerns/expertiza_constants.rb
  • app/models/due_date.rb
  • spec/models/response_spec.rb
  • spec/models/due_date_spec.rb
  • app/controllers/participants_controller.rb
  • app/models/assignment_team.rb
  • app/models/response.rb
  • app/controllers/student_tasks_controller.rb
📜 Review details
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: test
🧰 Additional context used
📓 Path-based instructions (5)
**

⚙️ CodeRabbit configuration file

**: # CodeRabbit Setup For This Repository

This repository uses CodeRabbit as an AI pull request reviewer for the Expertiza backend reimplementation. The goal is to improve review quality and preserve project-specific policy without replacing the existing CI runners.

What CodeRabbit Should Do Here

  • Review pull requests automatically and re-review on new commits.
  • Leave useful inline comments on Rails, API, database, workflow, and test changes.
  • Summarize the impact of a pull request clearly for human reviewers.
  • Surface policy issues that used to live in Danger-like rules, but start in warning mode instead of blocking merges.
  • Read GitHub check results and use them as context when tests or workflows fail.

What CodeRabbit Should Not Replace Here

  • GitHub Actions still runs the real work.
  • main.yml and TestPR.yml still execute RSpec, database setup, coverage generation, and Docker-related jobs.
  • lint.yml still remains the source of truth for runnable spellcheck and lint workflows unless those checks are intentionally retired.
  • CodeRabbit is a reviewer and explainer, not the test runner or deployment engine.

Repository Context

  • Language and framework: Ruby 3.4.5 with Rails 8.
  • Test stack: RSpec, mainly under spec/models and spec/requests.
  • API surface: controllers plus request specs, with Swagger documentation checked into swagger/v1/swagger.yaml.
  • Database: MySQL-backed Rails app with a large migration history and db/schema.rb committed.
  • Automation: GitHub Actions workflows in .github/workflows, including CI, PR test reporting, linting, and Danger.

Review Standards For This Codebase

Controllers

  • Verify authorization behavior and strong parameters.
  • Check HTTP status codes and response payload consistency.
  • Flag N+1 queries or heavy database work in request paths.
  • Expect request-spec coverage for behavior changes.
  • If an endpoint contract changes, expect Swagger documentation to stay in sync.

Models

...

Files:

  • spec/routing/student_tasks_routing_spec.rb
  • app/controllers/teams_participants_controller.rb
  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • app/controllers/grades_controller.rb
  • app/models/student_task.rb
  • spec/models/student_task_spec.rb
  • spec/requests/api/v1/grades_controller_spec.rb
app/controllers/**/*.rb

⚙️ CodeRabbit configuration file

app/controllers/**/*.rb: Review authorization, strong parameters, HTTP status codes, and response shape consistency.
Flag N+1 queries, missing request-spec coverage, and behavior changes not reflected in Swagger docs.

Files:

  • app/controllers/teams_participants_controller.rb
  • app/controllers/grades_controller.rb
spec/requests/**/*.rb

⚙️ CodeRabbit configuration file

spec/requests/**/*.rb: Check authentication, authorization, invalid input, response payload assertions, and failure cases.
When endpoints change, expect Swagger docs to stay aligned.
Apply the legacy shallow-test rules: each new test should have a meaningful expectation,
avoid commented-out expectations, and do not rely only on page content or non-nil checks.

Files:

  • spec/requests/api/v1/student_tasks_controller_spec.rb
  • spec/requests/api/v1/grades_controller_spec.rb
app/models/**/*.rb

⚙️ CodeRabbit configuration file

app/models/**/*.rb: Focus on associations, validations, callbacks, transactions, STI and polymorphic behavior,
foreign keys, data integrity, and query efficiency.

Files:

  • app/models/student_task.rb
spec/models/**/*.rb

⚙️ CodeRabbit configuration file

spec/models/**/*.rb: Check that model specs cover validations, associations, callbacks, and important edge cases
with meaningful assertions instead of shallow examples.
Also apply the legacy Danger policy: discourage create( in unit tests when build or doubles are enough,
reject .should, skipped/focused specs, wildcard matcher overuse, missing expectations, matcher-less expectations,
and expectations that only prove values are not nil, empty, or zero.

Files:

  • spec/models/student_task_spec.rb
🪛 ast-grep (0.43.0)
spec/models/student_task_spec.rb

[warning] 142-142: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(courses).to eq(courses.sort), "tasks should be sorted by course first"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures

(hardcoded-secret-rsa-passphrase-ruby)


[warning] 146-146: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file.
Context: expect(assignments).to eq(assignments.sort), "tasks within same course should be sorted by assignment name"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures

(hardcoded-secret-rsa-passphrase-ruby)

🪛 RuboCop (1.87.0)
spec/requests/api/v1/student_tasks_controller_spec.rb

[convention] 117-117: Line is too long. [136/120]

(Layout/LineLength)


[convention] 119-119: Line is too long. [168/120]

(Layout/LineLength)


[convention] 120-120: Line is too long. [136/120]

(Layout/LineLength)


[convention] 167-167: Line is too long. [136/120]

(Layout/LineLength)


[convention] 169-169: Line is too long. [168/120]

(Layout/LineLength)


[convention] 170-170: Line is too long. [136/120]

(Layout/LineLength)


[convention] 216-216: Do not use strings for word-like symbol literals.

(Style/SymbolLiteral)


[convention] 240-240: Do not use strings for word-like symbol literals.

(Style/SymbolLiteral)

app/controllers/grades_controller.rb

[convention] 21-21: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 22-22: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 27-27: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 34-34: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 287-287: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.

(Layout/FirstHashElementIndentation)


[convention] 287-287: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 288-288: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 289-289: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 291-291: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 295-295: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.

(Layout/FirstHashElementIndentation)


[convention] 295-295: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 296-296: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 297-297: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 383-383: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 383-383: Line is too long. [158/120]

(Layout/LineLength)


[convention] 383-383: Space found before comma.

(Layout/SpaceBeforeComma)


[convention] 392-392: Align .joins with AssignmentQuestionnaire on line 391.

(Layout/MultilineMethodCallIndentation)


[convention] 393-393: Align .where with AssignmentQuestionnaire on line 391.

(Layout/MultilineMethodCallIndentation)


[convention] 394-394: Align .where with AssignmentQuestionnaire on line 391.

(Layout/MultilineMethodCallIndentation)


[convention] 395-395: Align .first with AssignmentQuestionnaire on line 391.

(Layout/MultilineMethodCallIndentation)


[convention] 405-405: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 405-405: Avoid using {...} for multi-line blocks.

(Style/BlockDelimiters)


[convention] 406-406: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 413-413: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 413-413: Don't use parentheses around a literal.

(Style/RedundantParentheses)


[convention] 417-417: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 417-417: Avoid using {...} for multi-line blocks.

(Style/BlockDelimiters)


[convention] 418-418: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 423-423: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 429-429: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 429-429: Avoid using {...} for multi-line blocks.

(Style/BlockDelimiters)


[convention] 430-430: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 443-443: Redundant return detected.

(Style/RedundantReturn)


[convention] 451-451: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 452-452: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 456-456: Unnecessary spacing detected.

(Layout/ExtraSpacing)


[convention] 459-459: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 460-460: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 462-462: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)


[convention] 468-468: Use 2 (not 4) spaces for indentation.

(Layout/IndentationWidth)

app/models/student_task.rb

[convention] 4-4: Line is too long. [162/120]

(Layout/LineLength)


[convention] 20-47: Assignment Branch Condition size for create_from_participant is too high. [<9, 23, 8> 25.96/20]

(Metrics/AbcSize)


[convention] 20-47: Cyclomatic complexity for create_from_participant is too high. [9/7]

(Metrics/CyclomaticComplexity)


[convention] 20-47: Perceived complexity for create_from_participant is too high. [9/8]

(Metrics/PerceivedComplexity)


[convention] 35-35: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 36-36: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 37-37: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 38-38: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 39-39: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 39-39: Line is too long. [147/120]

(Layout/LineLength)


[convention] 41-41: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 42-42: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 49-50: Extra blank line detected.

(Layout/EmptyLines)


[convention] 54-54: Expected 1 empty line between method definitions; found 2.

(Layout/EmptyLineBetweenDefs)


[convention] 84-135: Assignment Branch Condition size for get_timeline_data is too high. [<7, 40, 7> 41.21/20]

(Metrics/AbcSize)


[convention] 84-135: Method has too many lines. [33/20]

(Metrics/MethodLength)


[convention] 90-90: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 91-91: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 91-91: Line is too long. [160/120]

(Layout/LineLength)


[convention] 92-92: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 93-93: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 111-111: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 112-112: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 113-113: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 114-114: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 126-126: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 127-127: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 128-128: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 129-129: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 139-154: Assignment Branch Condition size for teamed_students is too high. [<7, 20, 10> 23.43/20]

(Metrics/AbcSize)


[convention] 139-154: Cyclomatic complexity for teamed_students is too high. [11/7]

(Metrics/CyclomaticComplexity)


[convention] 139-154: Perceived complexity for teamed_students is too high. [11/8]

(Metrics/PerceivedComplexity)


[convention] 142-142: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 175-175: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 177-177: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 183-183: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)


[convention] 191-191: Favor modifier if usage when having a single-line body. Another good alternative is the usage of control flow &&/||.

(Style/IfUnlessModifier)


[warning] 198-198: private (on line 167) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.

(Lint/IneffectiveAccessModifier)


[convention] 199-199: Add empty line after guard clause.

(Layout/EmptyLineAfterGuardClause)

spec/models/student_task_spec.rb

[convention] 14-14: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 15-15: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 16-16: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 18-18: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 19-19: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 20-20: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 32-32: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 33-33: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 34-34: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 35-35: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 36-36: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[convention] 37-37: Align the keys of a hash literal if they span more than one line.

(Layout/HashAlignment)


[warning] 119-119: Useless assignment to variable - deadline_near. Did you mean deadline_far?

(Lint/UselessAssignment)


[warning] 120-120: Useless assignment to variable - deadline_far. Did you mean deadline_near?

(Lint/UselessAssignment)


[convention] 142-142: Unnecessary spacing detected.

(Layout/ExtraSpacing)


[convention] 238-238: Line is too long. [192/120]

(Layout/LineLength)


[convention] 239-239: Line is too long. [138/120]

(Layout/LineLength)


[convention] 240-240: Line is too long. [134/120]

(Layout/LineLength)


[convention] 241-241: Line is too long. [192/120]

(Layout/LineLength)


[convention] 242-242: Line is too long. [192/120]

(Layout/LineLength)


[convention] 286-286: Line is too long. [175/120]

(Layout/LineLength)


[convention] 300-300: Line is too long. [178/120]

(Layout/LineLength)


[warning] 347-347: Useless assignment to variable - draft_response.

(Lint/UselessAssignment)

spec/requests/api/v1/grades_controller_spec.rb

[convention] 366-366: Line is too long. [125/120]

(Layout/LineLength)


[convention] 388-388: Line is too long. [125/120]

(Layout/LineLength)


[convention] 4-573: Block has too many lines. [448/120]

(Metrics/BlockLength)

🔇 Additional comments (18)
app/models/student_task.rb (4)

4-47: LGTM!


54-73: LGTM!


104-135: LGTM!


137-195: LGTM!

spec/models/student_task_spec.rb (5)

7-27: LGTM!

Also applies to: 29-64, 66-106


108-149: LGTM!


151-232: LGTM!


234-295: LGTM!


297-427: LGTM!

spec/routing/student_tasks_routing_spec.rb (1)

31-41: LGTM!

spec/requests/api/v1/grades_controller_spec.rb (4)

564-571: Pin the expected status to 404 rather than accepting both.

This is a Grades API spec file, but the test exercises student_tasks/show. The controller returns 404 when the participant is not found (id 999999) and 403 only when a participant exists but belongs to a different user. Using be_in([404, 403]) masks regressions if the controller behavior changes. As per coding guidelines, request specs should have meaningful expectations and avoid shallow assertions.

Source: Coding guidelines


348-404: LGTM!


454-460: LGTM!


462-558: LGTM!

app/controllers/grades_controller.rb (4)

21-36: LGTM!


279-298: LGTM!


344-397: LGTM!


446-473: LGTM!

Comment thread app/controllers/grades_controller.rb Outdated
Comment thread app/models/student_task.rb
Comment thread app/models/student_task.rb
@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

Failing Controller Test Cases:
rspec ./spec/requests/api/v1/grades_controller_spec.rb:514 # Grades API section headers in view_our_scores injects a section header sentinel at position 0 in the round array
rspec ./spec/requests/api/v1/grades_controller_spec.rb:533 # Grades API section headers in view_our_scores places the header sentinel before the scored items, not after
rspec ./spec/requests/api/v1/grades_controller_spec.rb:545 # Grades API section headers in view_our_scores does not inject headers when the questionnaire has none

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

Failing Model Test Cases:
rspec ./spec/models/student_task_spec.rb:86 # StudentTask.from_participant_id uses AssignmentParticipant (not Participant) to look up by id

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

1 similar comment
@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

Failing Controller Test Cases:
rspec ./spec/requests/api/v1/grades_controller_spec.rb:514 # Grades API section headers in view_our_scores injects a section header sentinel at position 0 in the round array
rspec ./spec/requests/api/v1/grades_controller_spec.rb:533 # Grades API section headers in view_our_scores places the header sentinel before the scored items, not after
rspec ./spec/requests/api/v1/grades_controller_spec.rb:545 # Grades API section headers in view_our_scores does not inject headers when the questionnaire has none

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests passed.

@github-actions

Copy link
Copy Markdown

🚨 RSpec Tests Report

All tests 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.

1 participant