Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8c9f1c0
Update README.md
Kii4ka Apr 18, 2025
28caaa5
Created StudentReviewService and removed MetareviewResponseMap from c…
smithackr Apr 21, 2025
a306ad8
Merge pull request #9 from Kii4ka/smit_dev
smithackr Apr 21, 2025
935d291
simplify ( action_allowed? )
Kenil2211 Apr 21, 2025
d83462f
Add set_locale before_action for I18n locale resolution and tests
Kenil2211 Apr 21, 2025
18ce518
update
Kenil2211 Apr 21, 2025
136d24f
Merge pull request #10 from Kii4ka/kenil_dev
smithackr Apr 21, 2025
3513553
Add tests
Kii4ka Apr 22, 2025
dd5a89a
Merge pull request #11 from Kii4ka/Katerina_tests
Kii4ka Apr 22, 2025
ab4625b
student_review_service.rb (82.14%)
Kii4ka Apr 22, 2025
17f4fcf
student_review_service.rb (85.71%)
Kii4ka Apr 22, 2025
a21b88e
student_review_controller.rb (86.67%)
Kii4ka Apr 22, 2025
03522a7
modify SimpleCov configuration in rails_helper.rb to ensure proper c…
Kii4ka Apr 22, 2025
9f6003d
modify SimpleCov configuration in rails_helper.rb to ensure proper c…
Kii4ka Apr 22, 2025
2ffeffc
modify SimpleCov configuration in rails_helper.rb to ensure proper c…
Kii4ka Apr 22, 2025
75cc297
Database Connectivity in CI
Kii4ka Apr 22, 2025
08b3ad9
Update main.yml
Kii4ka Apr 22, 2025
98dccc8
changed formater approach
Kii4ka Apr 22, 2025
50c0b70
Merge branch 'Katerina_tests' of https://github.com/Kii4ka/reimplemen…
Kii4ka Apr 22, 2025
dba774b
changed format of coverage file
Kii4ka Apr 22, 2025
c4a472d
another change to the format of coverage file
Kii4ka Apr 22, 2025
b815313
Changed formater, updated workflow
Kii4ka Apr 22, 2025
3383ff5
Changed formater again, updated workflow
Kii4ka Apr 22, 2025
7e8a47a
Merge pull request #12 from Kii4ka/Katerina_tests
Kii4ka Apr 22, 2025
7d3977e
"Code structure fixes"
smithackr Apr 22, 2025
d95fb94
Update main.yml
Kii4ka Apr 22, 2025
75fd408
Update main.yml
Kii4ka Apr 22, 2025
af78fce
Update README.md
Kii4ka Apr 22, 2025
6f51cf0
Update main.yml
Kii4ka Apr 22, 2025
1b8f322
Update main.yml
Kii4ka Apr 22, 2025
90129e2
Merge branch 'main' into smit_dev
smithackr Apr 22, 2025
af93949
Update main.yml
Kii4ka Apr 22, 2025
7a1096c
Merge pull request #13 from Kii4ka/smit_dev
smithackr Apr 22, 2025
f96290e
Update main.yml
Kii4ka Apr 26, 2025
6fd5669
Change folder
Kii4ka Apr 26, 2025
40c8ad7
fix check_bidding_redirect
Kii4ka Apr 26, 2025
2091b8f
check if review tests influence others
Kii4ka Apr 26, 2025
769ec0a
fixed issue with the routes crash
Kii4ka Apr 26, 2025
48ac10e
moved service tests
Kii4ka Apr 26, 2025
44e09a9
fix service error
Kii4ka Apr 26, 2025
c2a52f0
moved application controller spec
Kii4ka Apr 26, 2025
7bdb632
add extra comments to test files
Kii4ka Apr 26, 2025
ca42193
Merge pull request #15 from Kii4ka/check_tests
Kii4ka Apr 26, 2025
340e140
"Comments added"
smithackr Apr 26, 2025
86597a1
Revert ""Comments added""
smithackr Apr 26, 2025
74192d8
Merge branch 'main' into main
vihar2712 May 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
44 changes: 36 additions & 8 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI/CD

on:
push:
branches: [ main ]
branches: [ main, check_tests ]
pull_request:
branches: [ main ]

Expand Down Expand Up @@ -49,6 +49,14 @@ jobs:
gem install bundler:2.4.7
bundle install

- name: Wait for MySQL to be ready
run: |
while ! nc -z localhost 3306; do
echo "Waiting for MySQL..."
sleep 3
done
echo "MySQL is ready."

- name: Setup database
run: |
bundle exec rails db:create RAILS_ENV=test
Expand All @@ -67,7 +75,19 @@ jobs:
run: bundle exec rspec spec/requests/

- name: Format code coverage report
run: ./cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.models.json" --debug
run: |
mkdir -p coverage
if [ -f "coverage/codeclimate.json" ]; then
./cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.models.json" coverage/codeclimate.json
else
echo "coverage.json not found, looking for .resultset.json"
if [ -f "coverage/.resultset.json" ]; then
./cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.models.json"
else
echo "No coverage files found!"
find coverage -type f
fi
fi

- name: Upload coverage artifacts
uses: actions/upload-artifact@v4
Expand All @@ -77,24 +97,32 @@ jobs:


publish_code_coverage:
needs: test # Ensures this job runs after the test job
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main' # Only run when there's a push to main branch

if: github.event_name == 'push' && github.ref == 'refs/heads/main' # No secret check here!
steps:
- uses: actions/checkout@v3

- uses: actions/download-artifact@v4
with:
name: code-coverage-artifacts
path: coverage/

- name: Upload code-coverage report to code-climate
- name: Upload code-coverage report to Code Climate
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
run: |
if [ -z "$CC_TEST_REPORTER_ID" ]; then
echo "Secret CC_TEST_REPORTER_ID not set. Skipping code coverage upload."
exit 0
fi

export GIT_BRANCH="${GITHUB_REF/refs\/heads\//}"
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter sum-coverage coverage/codeclimate.*.json
./cc-test-reporter after-build -t simplecov -r ${{ secrets.CC_TEST_REPORTER_ID }}
./cc-test-reporter sum-coverage coverage/codeclimate.*.json
./cc-test-reporter after-build -t simplecov -r "$CC_TEST_REPORTER_ID"


docker:
needs: test
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@
/config/master.key
coverage/
rsa_keys.yml

/config/credentials/test.key
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-3.2.7
3.2.7
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ PLATFORMS
aarch64-linux
arm64-darwin-22
arm64-darwin-23
arm64-darwin-24
x64-mingw-ucrt
x86_64-linux

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ application up and running.

Things you may want to cover:

* Ruby version - 3.2.1
* Ruby version - 3.2.

## Development Environment

Expand Down
125 changes: 125 additions & 0 deletions app/controllers/api/v1/student_review_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
class Api::V1::StudentReviewController < ApplicationController
# Constants for action names and roles to avoid magic strings
LIST_ACTION = 'list'.freeze
SUBMITTER_ROLE = 'submitter'.freeze


# Ensure proper authorization and service initialization before actions
before_action :authorize_user, only: [LIST_ACTION.to_sym]
before_action :load_service, only: [:list]
# Handle service-specific errors gracefully
rescue_from 'StudentReviewService::Error', with: :handle_service_error

# GET /api/v1/student_review/list
# Returns a list of reviews for the authenticated student participant
def list
return unless authorized_participant?

render json: build_review_response
end

protected

def check_bidding_redirect
if @service&.bidding_enabled?
redirect_to controller: 'review_bids', action: 'index', assignment_id: params[:assignment_id], id: params[:id]
end
end

private

# Ensures the user has proper authorization to access the endpoint
def authorize_user
unless action_allowed?
render json: { error: 'Unauthorized' }, status: :unauthorized
return
end
end

# Add this method to handle locale
def controller_locale
# Use the user's locale preference if available
if current_user && current_user.locale.present?
I18n.locale = current_user.locale
else
# Fall back to default locale
I18n.locale = I18n.default_locale
end
end

# Quick-exit unless they're a student.
# Then, only allow the LIST_ACTION for users who also have the SUBMITTER_ROLE on this resource.
def action_allowed?
# guard clause: must be a student at all
return false unless current_user_has_student_privileges? # early return

# only permit “list” for submitters
action_name == LIST_ACTION &&
are_needed_authorizations_present?(params[:id], SUBMITTER_ROLE)
end

# Initializes the StudentReviewService with the participant ID
# Handles any errors that occur during service initialization
def load_service
@service = StudentReviewService.new(params[:id])
rescue StandardError => e
render_error(e.message)
end

# Verifies that the current user matches the participant's user ID
# Returns false and renders unauthorized error if verification fails
def authorized_participant?
if current_user_id?(@service.participant.user_id)
check_bidding_redirect
true
else
render json: { error: 'Unauthorized participant' }, status: :unauthorized
false
end
end

# Builds the complete review response JSON structure
# Includes participant details, assignment info, and review statistics
def build_review_response
{
participant: @service.participant,
assignment: @service.assignment,
topic_id: @service.topic_id,
review_phase: @service.review_phase,
review_mappings: @service.review_mappings,
reviews: build_reviews_summary,
response_ids: @service.response_ids
}
end

# Constructs a summary of review statistics including:
# - Total number of reviews
# - Number of completed reviews
# - Number of reviews in progress
def build_reviews_summary
{
total: @service.num_reviews_total,
completed: @service.num_reviews_completed,
in_progress: @service.num_reviews_in_progress
}
end

# Renders error messages with unprocessable entity status
def render_error(message)
render json: { error: message }, status: :unprocessable_entity
end

# TODO- implementation for review_bids has not been done yet
# Handles redirection for review bidding functionality
# Will be implemented in future iterations
# def check_bidding_redirect
# if @service.bidding_enabled?
# redirect_to(
# controller: 'review_bids',
# action: 'index',
# assignment_id: params[:assignment_id],
# id: params[:id]
# ) and return
# end
# end
end
27 changes: 26 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
class ApplicationController < ActionController::API
include Authorization
include JwtToken


# 1) Set locale for every request
before_action :set_locale
# 2) Perform authorization
before_action :authorize

private

# Sets I18n.locale based on params, Accept-Language header, or default
def set_locale
I18n.locale = extract_locale || I18n.default_locale
end

# Returns a valid locale symbol or nil
def extract_locale
# 1) Param override
if params[:locale].present?
sym = params[:locale].to_sym
return sym if I18n.available_locales.include?(sym)
end

# 2) Accept-Language header fallback
header = request.env['HTTP_ACCEPT_LANGUAGE'].to_s
header
.split(',')
.map { |l| l[0..1].downcase.to_sym }
.find { |loc| I18n.available_locales.include?(loc) }
end
end
Loading
Loading