diff --git a/Gemfile b/Gemfile index 020dbe491..d3d733e54 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ ruby '3.4.5' gem 'mysql2', '~> 0.5.7' gem 'sqlite3', '~> 1.4' # Alternative for development -gem 'puma', '~> 5.0' +gem 'puma', '~> 6.0' gem 'rails', '~> 8.0', '>= 8.0.1' gem 'mini_portile2', '~> 2.8' # Helps with native gem compilation gem 'observer' # Required for Ruby 3.4.5 compatibility with Rails 8.0 diff --git a/Gemfile.lock b/Gemfile.lock index 5e7341cb0..fb240f4ef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,6 +106,7 @@ GEM term-ansicolor thor crass (1.0.6) + csv (3.3.5) danger (9.5.3) base64 (~> 0.2) claide (~> 1.0) @@ -128,6 +129,7 @@ GEM debug (1.11.0) irb (~> 1.10) reline (>= 0.3.8) + delegate (0.4.0) diff-lcs (1.6.2) docile (1.4.1) domain_name (0.6.20240107) @@ -149,8 +151,11 @@ GEM faraday (>= 0.8) faraday-net_http (3.4.1) net-http (>= 0.5.0) + faraday-retry (2.3.2) + faraday (~> 2.0) find_with_order (1.3.1) activerecord (>= 3) + forwardable (1.3.3) git (2.3.3) activesupport (>= 5.0) addressable (~> 2.8) @@ -197,10 +202,13 @@ GEM mime-types-data (~> 3.2025, >= 3.2025.0507) mime-types-data (3.2025.0924) mini_mime (1.1.5) + mini_portile2 (2.8.9) minitest (5.25.5) mize (0.6.1) + monitor (0.2.0) msgpack (1.8.0) multi_json (1.17.0) + mutex_m (0.3.0) mysql2 (0.5.7) bigdecimal nap (1.1.0) @@ -217,7 +225,7 @@ GEM net-protocol netrc (0.11.0) nio4r (2.5.9) - nokogiri (1.15.2-aarch64-linux) + nokogiri (1.18.10-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.18.10-arm64-darwin) racc (~> 1.4) @@ -230,6 +238,7 @@ GEM faraday (>= 1, < 3) sawyer (~> 0.9) open4 (1.3.4) + ostruct (0.6.3) parallel (1.27.0) parser (3.3.9.0) ast (~> 2.4.1) @@ -350,6 +359,7 @@ GEM addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) securerandom (0.4.1) + set (1.1.2) shoulda-matchers (6.5.0) activesupport (>= 5.2.0) simplecov (0.22.0) @@ -358,7 +368,10 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) + singleton (0.3.0) spring (4.4.0) + sqlite3 (1.7.3) + mini_portile2 (~> 2.8.0) stringio (3.1.7) sync (0.5.0) term-ansicolor (1.11.3) @@ -392,24 +405,37 @@ PLATFORMS arm64-darwin-22 arm64-darwin-23 arm64-darwin-24 + arm64-darwin-25 x64-mingw-ucrt x86_64-linux DEPENDENCIES active_model_serializers (~> 0.10.0) bcrypt (~> 3.1.7) + bigdecimal bootsnap (>= 1.18.4) coveralls + csv danger database_cleaner-active_record + date debug + delegate factory_bot_rails faker + faraday-retry find_with_order + forwardable jwt (~> 2.7, >= 2.7.1) lingua - mysql2 (~> 0.5.5) + logger + mini_portile2 (~> 2.8) + monitor + mutex_m + mysql2 (~> 0.5.7) observer + ostruct + psych (~> 5.2) puma (~> 6.0) rack-cors rails (~> 8.0, >= 8.0.1) @@ -418,14 +444,19 @@ DEPENDENCIES rswag-specs rswag-ui rubocop + set shoulda-matchers simplecov simplecov_json_formatter + singleton spring + sqlite3 (~> 1.4) + timeout tzinfo-data + uri RUBY VERSION - ruby 3.2.7p253 + ruby 3.4.5p51 BUNDLED WITH 2.4.14 diff --git a/app/controllers/participants_controller.rb b/app/controllers/participants_controller.rb index 97f3241b0..878209621 100644 --- a/app/controllers/participants_controller.rb +++ b/app/controllers/participants_controller.rb @@ -29,7 +29,7 @@ def list_assignment_participants if participants.nil? render json: participants.errors, status: :unprocessable_entity else - render json: participants, status: :ok + render json: participants.as_json(include: { user: { include: %i[role parent] } }), status: :ok end end @@ -103,7 +103,7 @@ def update_authorization # DELETE /participants/:id def destroy participant = Participant.find_by(id: params[:id]) - + if participant.nil? render json: { error: 'Not Found' }, status: :not_found elsif participant.destroy @@ -139,8 +139,7 @@ def filter_user_participants(user) # Filters participants based on the provided assignment # Returns participants ordered by their IDs def filter_assignment_participants(assignment) - participants = Participant.all - participants = participants.where(parent_id: assignment.id, type: 'AssignmentParticipant') if assignment + participants = Participant.where(parent_id: assignment.id, type: 'AssignmentParticipant') if assignment participants.order(:id) end diff --git a/db/seeds.rb b/db/seeds.rb index 9828977ea..7a6c5edfc 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,130 +1,129 @@ # frozen_string_literal: true begin - #Create an instritution - inst_id = Institution.create!( - name: 'North Carolina State University', + # Create an instritution + inst_id = Institution.create!( + name: 'North Carolina State University' + ).id + + Role.create!(id: 1, name: 'Super Administrator') + Role.create!(id: 2, name: 'Administrator') + Role.create!(id: 3, name: 'Instructor') + Role.create!(id: 4, name: 'Teaching Assistant') + Role.create!(id: 5, name: 'Student') + + # Create an admin user + User.create!( + name: 'admin', + email: 'admin2@example.com', + password: 'password123', + full_name: 'admin admin', + institution_id: 1, + role_id: 1 + ) + + # Generate Random Users + num_students = 48 + num_assignments = 8 + num_teams = 16 + num_courses = 2 + num_instructors = 2 + + puts "creating instructors" + instructor_user_ids = [] + num_instructors.times do + instructor_user_ids << User.create( + name: Faker::Internet.unique.username, + email: Faker::Internet.unique.email, + password: "password", + full_name: Faker::Name.name, + institution_id: 1, + role_id: 3 + ).id + end + + puts "creating courses" + course_ids = [] + num_courses.times do |i| + course_ids << Course.create( + instructor_id: instructor_user_ids[i], + institution_id: inst_id, + directory_path: Faker::File.dir(segment_count: 2), + name: Faker::Company.industry, + info: "A fake class", + private: false + ).id + end + + puts "creating assignments" + assignment_ids = [] + num_assignments.times do |i| + assignment_ids << Assignment.create( + name: Faker::Verb.base, + instructor_id: instructor_user_ids[i % num_instructors], + course_id: course_ids[i % num_courses], + has_teams: true, + private: false + ).id + end + + puts "creating teams" + team_ids = [] + num_teams.times do |i| + team_ids << AssignmentTeam.create( + name: "Team #{i + 1}", + parent_id: assignment_ids[i % num_assignments] ).id - - # Create an admin user - User.create!( - name: 'admin', - email: 'admin2@example.com', - password: 'password123', - full_name: 'admin admin', + end + + puts "creating students" + student_user_ids = [] + num_students.times do + student_user_ids << User.create( + name: Faker::Internet.unique.username, + email: Faker::Internet.unique.email, + password: "password", + full_name: Faker::Name.name, institution_id: 1, - role_id: 1 + role_id: 5, + parent_id: [nil, *instructor_user_ids].sample + ).id + end + + puts "assigning students to teams" + teams_users_ids = [] + # num_students.times do |i| + # teams_users_ids << TeamsUser.create( + # team_id: team_ids[i%num_teams], + # user_id: student_user_ids[i] + # ).id + # end + + num_students.times do |i| + puts "Creating TeamsUser with team_id: #{team_ids[i % num_teams]}, user_id: #{student_user_ids[i]}" + teams_user = TeamsUser.create( + team_id: team_ids[i % num_teams], + user_id: student_user_ids[i] ) - - - #Generate Random Users - num_students = 48 - num_assignments = 8 - num_teams = 16 - num_courses = 2 - num_instructors = 2 - - puts "creating instructors" - instructor_user_ids = [] - num_instructors.times do - instructor_user_ids << User.create( - name: Faker::Internet.unique.username, - email: Faker::Internet.unique.email, - password: "password", - full_name: Faker::Name.name, - institution_id: 1, - role_id: 3, - ).id - end - - puts "creating courses" - course_ids = [] - num_courses.times do |i| - course_ids << Course.create( - instructor_id: instructor_user_ids[i], - institution_id: inst_id, - directory_path: Faker::File.dir(segment_count: 2), - name: Faker::Company.industry, - info: "A fake class", - private: false - ).id - end - - puts "creating assignments" - assignment_ids = [] - num_assignments.times do |i| - assignment_ids << Assignment.create( - name: Faker::Verb.base, - instructor_id: instructor_user_ids[i%num_instructors], - course_id: course_ids[i%num_courses], - has_teams: true, - private: false - ).id - end - - - puts "creating teams" - team_ids = [] - num_teams.times do |i| - team_ids << AssignmentTeam.create( - name: "Team #{i + 1}", - parent_id: assignment_ids[i%num_assignments] - ).id - end - - puts "creating students" - student_user_ids = [] - num_students.times do - student_user_ids << User.create( - name: Faker::Internet.unique.username, - email: Faker::Internet.unique.email, - password: "password", - full_name: Faker::Name.name, - institution_id: 1, - role_id: 5, - ).id + if teams_user.persisted? + teams_users_ids << teams_user.id + puts "Created TeamsUser with ID: #{teams_user.id}" + else + puts "Failed to create TeamsUser: #{teams_user.errors.full_messages.join(', ')}" end - - puts "assigning students to teams" - teams_users_ids = [] - #num_students.times do |i| - # teams_users_ids << TeamsUser.create( - # team_id: team_ids[i%num_teams], - # user_id: student_user_ids[i] - # ).id - #end - - num_students.times do |i| - puts "Creating TeamsUser with team_id: #{team_ids[i % num_teams]}, user_id: #{student_user_ids[i]}" - teams_user = TeamsUser.create( - team_id: team_ids[i % num_teams], - user_id: student_user_ids[i] - ) - if teams_user.persisted? - teams_users_ids << teams_user.id - puts "Created TeamsUser with ID: #{teams_user.id}" - else - puts "Failed to create TeamsUser: #{teams_user.errors.full_messages.join(', ')}" - end - end - - puts "assigning participant to students, teams, courses, and assignments" - participant_ids = [] - num_students.times do |i| - participant_ids << AssignmentParticipant.create( - user_id: student_user_ids[i], - parent_id: assignment_ids[i%num_assignments], - team_id: team_ids[i%num_teams], - ).id - end - - - - - - - - + end + + puts "assigning participant to students, teams, courses, and assignments" + participant_ids = [] + num_students.times do |i| + puts "Creating AssignmentParticipant for user_id: #{student_user_ids[i]}, assignment_id: #{assignment_ids[i % num_assignments]}, team_id: #{team_ids[i % num_teams]}" + participant_ids << AssignmentParticipant.create( + user_id: student_user_ids[i], + parent_id: assignment_ids[i % num_assignments], + team_id: team_ids[i % num_teams], + handle: Faker::Internet.unique.username + ).id + end rescue ActiveRecord::RecordInvalid => e - puts 'The db has already been seeded' + puts e, 'The db has already been seeded' end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 9d528540b..018510749 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -76,13 +76,19 @@ abort e.to_s.strip end RSpec.configure do |config| - # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = Rails.root.join('spec/fixtures') - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = true + if config.respond_to?(:fixture_path=) + config.fixture_path = [Rails.root.join('spec/fixtures').to_s] + else + # fallback for older Rails / rspec versions + config.fixture_path = Rails.root.join('spec/fixtures') + end + + # Since we're using Factory Bot instead of fixtures, we don't need fixture_path + # config.fixture_path is deprecated in newer RSpec versions anyway + + # We're using DatabaseCleaner instead of transactional fixtures + # config.use_transactional_fixtures = false # You can uncomment this line to turn off ActiveRecord support entirely. # config.use_active_record = false