diff --git a/Gemfile b/Gemfile index fe90f4c7efa..bef0ed5beab 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ ruby '3.1.4' gem 'tzinfo-data', platforms: [:mswin, :mswin64] # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 7.1.4' +gem 'rails', '~> 7.2.1' # Use PostgreSQL for the backend gem 'pg' @@ -18,7 +18,8 @@ gem 'rack-cors' # Instance/Course settings gem 'settings_on_rails', git: 'https://github.com/Coursemology/settings_on_rails' # Manage read/unread status -gem 'unread' +# fix for https://github.com/ledermann/unread/issues/135 +gem 'unread', git: 'https://github.com/ledermann/unread', ref: '675b744' # Extension for validating hostnames and domain names gem 'validates_hostname' # A Ruby state machine library @@ -29,14 +30,14 @@ gem 'activerecord-userstamp', git: 'https://github.com/Coursemology/activerecord # Allow actions to be deferred until after a record is committed. gem 'after_commit_action' # Allow declaring the calculated attributes of a record -gem 'calculated_attributes', git: 'https://github.com/aha-app/calculated_attributes' +gem 'calculated_attributes', git: 'https://github.com/adi-herwana-nus/calculated_attributes.git' # For multiple table inheritance # TODO: Figure out breaking changes in v2 as polymorphism is not working correctly. gem 'active_record-acts_as', git: 'https://github.com/Coursemology/active_record-acts_as.git' # Organise ActiveRecord model into a tree structure gem 'edge' -# Upsert action for Postgres -gem 'active_record_upsert', '0.11.2' +# Upsert action for Postgres with validations +gem 'active_record_upsert', git: 'https://github.com/jesjos/active_record_upsert', ref: 'c3e07ae' # Create pretty URLs and work with human-friendly strings gem 'friendly_id' @@ -106,6 +107,8 @@ group :development, :test do gem 'rubocop', '~> 1.66' # Factory Bot for factories + # fix for https://github.com/thoughtbot/factory_bot/issues/1690 + gem 'factory_bot', '~> 6.5.0' gem 'factory_bot_rails' # Checks that all translations are used and defined @@ -181,7 +184,7 @@ gem 'jwt' gem 'cancancan' # Using CarrierWave for file uploads -gem 'carrierwave', '2.2.6' +gem 'carrierwave', '~> 3' # Generate sequential filenames gem 'filename' # Required by CarrierWave, for image resizing diff --git a/Gemfile.lock b/Gemfile.lock index 0a2f05c5583..8877f7439b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,94 +27,104 @@ GIT rails (>= 6) GIT - remote: https://github.com/aha-app/calculated_attributes - revision: d2f69a1acefd5646ce1908fed3785a63d8399374 + remote: https://github.com/adi-herwana-nus/calculated_attributes.git + revision: 3d9fe0c99070c61de634b7235044200d61b65a65 specs: - calculated_attributes (1.0.0) + calculated_attributes (1.0.1) activerecord (>= 6.0.0, < 8) +GIT + remote: https://github.com/jesjos/active_record_upsert + revision: c3e07aecf28d6a81a06fcada4710b103dfca823b + ref: c3e07ae + specs: + active_record_upsert (0.11.2) + activerecord (>= 5.2, < 8.0) + pg (>= 0.18, < 2.0) + +GIT + remote: https://github.com/ledermann/unread + revision: 675b7443af5ca23e44ffe3b70a443a5ec1d3952b + ref: 675b744 + specs: + unread (0.13.1) + activerecord (>= 6.1) + GEM remote: https://rubygems.org/ specs: - actioncable (7.1.4) - actionpack (= 7.1.4) - activesupport (= 7.1.4) + actioncable (7.2.1) + actionpack (= 7.2.1) + activesupport (= 7.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.4) - actionpack (= 7.1.4) - activejob (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.4) - actionpack (= 7.1.4) - actionview (= 7.1.4) - activejob (= 7.1.4) - activesupport (= 7.1.4) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (7.2.1) + actionpack (= 7.2.1) + activejob (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) + mail (>= 2.8.0) + actionmailer (7.2.1) + actionpack (= 7.2.1) + actionview (= 7.2.1) + activejob (= 7.2.1) + activesupport (= 7.2.1) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.4) - actionview (= 7.1.4) - activesupport (= 7.1.4) + actionpack (7.2.1) + actionview (= 7.2.1) + activesupport (= 7.2.1) nokogiri (>= 1.8.5) racc - rack (>= 2.2.4) + rack (>= 2.2.4, < 3.2) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.4) - actionpack (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) + useragent (~> 0.16) + actiontext (7.2.1) + actionpack (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.4) - activesupport (= 7.1.4) + actionview (7.2.1) + activesupport (= 7.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - active_record_upsert (0.11.2) - activerecord (>= 5.2, < 7.2) - pg (>= 0.18, < 2.0) - activejob (7.1.4) - activesupport (= 7.1.4) + activejob (7.2.1) + activesupport (= 7.2.1) globalid (>= 0.3.6) - activemodel (7.1.4) - activesupport (= 7.1.4) - activerecord (7.1.4) - activemodel (= 7.1.4) - activesupport (= 7.1.4) + activemodel (7.2.1) + activesupport (= 7.2.1) + activerecord (7.2.1) + activemodel (= 7.2.1) + activesupport (= 7.2.1) timeout (>= 0.4.0) activerecord-import (1.8.1) activerecord (>= 4.2) - activestorage (7.1.4) - actionpack (= 7.1.4) - activejob (= 7.1.4) - activerecord (= 7.1.4) - activesupport (= 7.1.4) + activestorage (7.2.1) + actionpack (= 7.2.1) + activejob (= 7.2.1) + activerecord (= 7.2.1) + activesupport (= 7.2.1) marcel (~> 1.0) - activesupport (7.1.4) + activesupport (7.2.1) base64 bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) acts_as_tenant (1.0.1) rails (>= 6.0) addressable (2.8.7) @@ -163,13 +173,12 @@ GEM capybara-selenium (0.0.6) capybara selenium-webdriver - carrierwave (2.2.6) - activemodel (>= 5.0.0) - activesupport (>= 5.0.0) + carrierwave (3.0.7) + activemodel (>= 6.0.0) + activesupport (>= 6.0.0) addressable (~> 2.6) image_processing (~> 1.1) marcel (~> 1.0.0) - mini_mime (>= 0.1.3) ssrf_filter (~> 1.0) childprocess (5.0.0) codecov (0.6.0) @@ -211,7 +220,7 @@ GEM tzinfo excon (0.111.0) exifr (1.4.0) - factory_bot (6.4.6) + factory_bot (6.5.0) activesupport (>= 5.0.0) factory_bot_rails (6.4.3) factory_bot (~> 6.4) @@ -275,7 +284,7 @@ GEM image_optim (~> 0.24) railties sprockets - image_processing (1.12.2) + image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) image_size (3.4.0) @@ -348,7 +357,6 @@ GEM mini_portile2 (2.8.7) minitest (5.25.1) multi_json (1.15.0) - mutex_m (0.2.0) net-imap (0.4.14) date net-protocol @@ -391,20 +399,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.4) - actioncable (= 7.1.4) - actionmailbox (= 7.1.4) - actionmailer (= 7.1.4) - actionpack (= 7.1.4) - actiontext (= 7.1.4) - actionview (= 7.1.4) - activejob (= 7.1.4) - activemodel (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) + rails (7.2.1) + actioncable (= 7.2.1) + actionmailbox (= 7.2.1) + actionmailer (= 7.2.1) + actionpack (= 7.2.1) + actiontext (= 7.2.1) + actionview (= 7.2.1) + activejob (= 7.2.1) + activemodel (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) bundler (>= 1.15.0) - railties (= 7.1.4) + railties (= 7.2.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -419,10 +427,10 @@ GEM rails-i18n (7.0.9) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.4) - actionpack (= 7.1.4) - activesupport (= 7.1.4) - irb + railties (7.2.1) + actionpack (= 7.2.1) + activesupport (= 7.2.1) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) @@ -489,7 +497,7 @@ GEM rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (6.1.4) + rspec-rails (6.1.5) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -521,12 +529,14 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-oembed (0.18.0) ruby-progressbar (1.13.0) - ruby-vips (2.2.1) + ruby-vips (2.2.2) ffi (~> 1.12) + logger rubyzip (2.3.2) sanitize (6.1.3) crass (~> 1.0.2) nokogiri (>= 1.12.0) + securerandom (0.3.1) selenium-webdriver (4.22.0) base64 (~> 0.2) logger (~> 1.4) @@ -578,8 +588,7 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) uniform_notifier (1.16.0) - unread (0.13.1) - activerecord (>= 6.1) + useragent (0.16.10) validates_hostname (1.0.13) activerecord (>= 3.0) activesupport (>= 3.0) @@ -604,7 +613,7 @@ PLATFORMS DEPENDENCIES active_record-acts_as! - active_record_upsert (= 0.11.2) + active_record_upsert! activerecord-import (>= 0.2.0) activerecord-userstamp! acts_as_tenant @@ -617,7 +626,7 @@ DEPENDENCIES capybara capybara-screenshot capybara-selenium - carrierwave (= 2.2.6) + carrierwave (~> 3) codecov consistency_fail coursemology-polyglot @@ -627,6 +636,7 @@ DEPENDENCIES dotenv-rails edge email_spec + factory_bot (~> 6.5.0) factory_bot_rails ffi (>= 1.14.2) filename @@ -655,7 +665,7 @@ DEPENDENCIES puma rack-cors rack-mini-profiler - rails (~> 7.1.4) + rails (~> 7.2.1) rails-controller-testing rails-html-sanitizer (>= 1.0.4) recaptcha @@ -686,7 +696,7 @@ DEPENDENCIES stackprof traceroute tzinfo-data - unread + unread! validates_hostname workflow workflow-activerecord (>= 4.1, < 7.0) diff --git a/app/models/concerns/course/assessment/submission/workflow_event_concern.rb b/app/models/concerns/course/assessment/submission/workflow_event_concern.rb index 44986893acc..51741c682ad 100644 --- a/app/models/concerns/course/assessment/submission/workflow_event_concern.rb +++ b/app/models/concerns/course/assessment/submission/workflow_event_concern.rb @@ -230,7 +230,7 @@ def publish_delayed_posts update_delayed_topics_and_posts(submission_question_topics) # Publish delayed annotations for each programming question of a submission - programming_answers = answers.where('actable_type = ?', Course::Assessment::Answer::Programming) + programming_answers = answers.where('actable_type = ?', Course::Assessment::Answer::Programming.name) annotation_topics = programming_answers.flat_map(&:specific). flat_map(&:files).flat_map(&:annotations).map(&:discussion_topic) update_delayed_topics_and_posts(annotation_topics) diff --git a/app/models/course.rb b/app/models/course.rb index 5e7bfdf7a5a..f4cc5c01b4b 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -27,7 +27,7 @@ class Course < ApplicationRecord validates :instance, presence: true validates :conditional_satisfiability_evaluation_time, presence: true - enum default_timeline_algorithm: CourseUser.timeline_algorithms + enum :default_timeline_algorithm, CourseUser.timeline_algorithms has_many :enrol_requests, inverse_of: :course, dependent: :destroy has_many :course_users, inverse_of: :course, dependent: :destroy diff --git a/app/models/course/assessment.rb b/app/models/course/assessment.rb index e3189aed0ae..d3f8b81c9bb 100644 --- a/app/models/course/assessment.rb +++ b/app/models/course/assessment.rb @@ -19,7 +19,7 @@ class Course::Assessment < ApplicationRecord after_commit :grade_with_new_test_cases, on: :update before_save :save_tab - enum randomization: { prepared: 0 } + enum :randomization, { prepared: 0 } validates :autograded, inclusion: { in: [true, false] } validates :session_password, length: { maximum: 255 }, allow_nil: true diff --git a/app/models/course/assessment/question/multiple_response.rb b/app/models/course/assessment/question/multiple_response.rb index f19a0656c7e..3f19d02e8c6 100644 --- a/app/models/course/assessment/question/multiple_response.rb +++ b/app/models/course/assessment/question/multiple_response.rb @@ -2,7 +2,7 @@ class Course::Assessment::Question::MultipleResponse < ApplicationRecord acts_as :question, class_name: 'Course::Assessment::Question' - enum grading_scheme: [:all_correct, :any_correct] + enum :grading_scheme, [:all_correct, :any_correct] validate :validate_has_option validate :validate_multiple_choice_has_correct_solution, if: :multiple_choice? diff --git a/app/models/course/assessment/question/programming.rb b/app/models/course/assessment/question/programming.rb index b9037a10f63..256ac5f1424 100644 --- a/app/models/course/assessment/question/programming.rb +++ b/app/models/course/assessment/question/programming.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Course::Assessment::Question::Programming < ApplicationRecord # rubocop:disable Metrics/ClassLength - enum package_type: { zip_upload: 0, online_editor: 1 } + enum :package_type, { zip_upload: 0, online_editor: 1 } # The table name for this model is singular. self.table_name = table_name.singularize diff --git a/app/models/course/assessment/question/programming_test_case.rb b/app/models/course/assessment/question/programming_test_case.rb index a6b1a2fc24a..b388017f8ac 100644 --- a/app/models/course/assessment/question/programming_test_case.rb +++ b/app/models/course/assessment/question/programming_test_case.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Course::Assessment::Question::ProgrammingTestCase < ApplicationRecord - enum test_case_type: { private_test: 0, public_test: 1, evaluation_test: 2 } + enum :test_case_type, { private_test: 0, public_test: 1, evaluation_test: 2 } validates :identifier, length: { maximum: 255 }, presence: true validates :test_case_type, presence: true diff --git a/app/models/course/assessment/question/text_response_comprehension_solution.rb b/app/models/course/assessment/question/text_response_comprehension_solution.rb index 7d4128755f7..1e3a9f6e9bf 100644 --- a/app/models/course/assessment/question/text_response_comprehension_solution.rb +++ b/app/models/course/assessment/question/text_response_comprehension_solution.rb @@ -2,7 +2,7 @@ class Course::Assessment::Question::TextResponseComprehensionSolution < ApplicationRecord self.table_name = 'course_assessment_question_text_response_compre_solutions' - enum solution_type: [:compre_keyword, :compre_lifted_word] + enum :solution_type, [:compre_keyword, :compre_lifted_word] before_validation :sanitise_solution_and_derive_lemma diff --git a/app/models/course/assessment/question/text_response_solution.rb b/app/models/course/assessment/question/text_response_solution.rb index c95df844731..74767c14314 100644 --- a/app/models/course/assessment/question/text_response_solution.rb +++ b/app/models/course/assessment/question/text_response_solution.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Course::Assessment::Question::TextResponseSolution < ApplicationRecord - enum solution_type: [:exact_match, :keyword] + enum :solution_type, [:exact_match, :keyword] before_validation :strip_whitespace before_save :sanitize_explanation diff --git a/app/models/course/discussion/post/codaveri_feedback.rb b/app/models/course/discussion/post/codaveri_feedback.rb index a53cd4fcffe..ce48d56640b 100644 --- a/app/models/course/discussion/post/codaveri_feedback.rb +++ b/app/models/course/discussion/post/codaveri_feedback.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Course::Discussion::Post::CodaveriFeedback < ApplicationRecord - enum status: { pending_review: 0, accepted: 1, rejected: 2 } + enum :status, { pending_review: 0, accepted: 1, rejected: 2 } validates :codaveri_feedback_id, presence: true validates :original_feedback, presence: true diff --git a/app/models/course/forum/topic.rb b/app/models/course/forum/topic.rb index df16a3e58f0..31441660d18 100644 --- a/app/models/course/forum/topic.rb +++ b/app/models/course/forum/topic.rb @@ -15,7 +15,7 @@ class Course::Forum::Topic < ApplicationRecord after_create :mark_as_read_for_creator after_update :mark_as_read_for_updater - enum topic_type: { normal: 0, question: 1, sticky: 2, announcement: 3 } + enum :topic_type, { normal: 0, question: 1, sticky: 2, announcement: 3 } validates :title, length: { maximum: 255 }, presence: true validates :slug, length: { maximum: 255 }, allow_nil: true diff --git a/app/models/course/group_user.rb b/app/models/course/group_user.rb index 1357cade7a0..34a92f1df2b 100644 --- a/app/models/course/group_user.rb +++ b/app/models/course/group_user.rb @@ -2,7 +2,7 @@ class Course::GroupUser < ApplicationRecord after_initialize :set_defaults, if: :new_record? - enum role: { normal: 0, manager: 1 } + enum :role, { normal: 0, manager: 1 } validate :course_user_and_group_in_same_course validates :role, presence: true diff --git a/app/models/course/monitoring/session.rb b/app/models/course/monitoring/session.rb index 41a1eb5caa3..0e228fb11b3 100644 --- a/app/models/course/monitoring/session.rb +++ b/app/models/course/monitoring/session.rb @@ -2,7 +2,7 @@ class Course::Monitoring::Session < ApplicationRecord DEFAULT_MAX_SESSION_DURATION = 1.day - enum status: { stopped: 0, listening: 1 } + enum :status, { stopped: 0, listening: 1 } belongs_to :monitor, class_name: 'Course::Monitoring::Monitor', inverse_of: :sessions diff --git a/app/models/course/notification.rb b/app/models/course/notification.rb index da846b94c6f..0e292e604e5 100644 --- a/app/models/course/notification.rb +++ b/app/models/course/notification.rb @@ -3,7 +3,7 @@ # # @api notifications class Course::Notification < ApplicationRecord - enum notification_type: { feed: 0, email: 1 } + enum :notification_type, { feed: 0, email: 1 } validates :activity, presence: true validates :course, presence: true diff --git a/app/models/course/settings/email.rb b/app/models/course/settings/email.rb index bd3a198b3ff..d7b2a322496 100644 --- a/app/models/course/settings/email.rb +++ b/app/models/course/settings/email.rb @@ -10,8 +10,8 @@ class Course::Settings::Email < ApplicationRecord Course::Settings::Email.send(:after_assessment_category_initialize, self) end - enum component: { announcements: 0, assessments: 1, forums: 2, surveys: 3, users: 4, videos: 5 } - enum setting: { new_announcement: 0, + enum :component, { announcements: 0, assessments: 1, forums: 2, surveys: 3, users: 4, videos: 5 } + enum :setting, { new_announcement: 0, opening_reminder: 1, closing_reminder: 2, closing_reminder_summary: 3, diff --git a/app/models/course/survey.rb b/app/models/course/survey.rb index 86365f2e979..a94945fecae 100644 --- a/app/models/course/survey.rb +++ b/app/models/course/survey.rb @@ -5,9 +5,6 @@ class Course::Survey < ApplicationRecord include Course::ClosingReminderConcern - attribute :question_type, :integer - enum question_type: { text_response: 0, multiple_choice: 1, multiple_response: 2 } - validates :end_at, presence: true, if: :allow_response_after_end validates :anonymous, inclusion: { in: [true, false] } validates :allow_modify_after_submit, inclusion: { in: [true, false] } diff --git a/app/models/course/survey/question.rb b/app/models/course/survey/question.rb index 50c391bf06c..f2721778887 100644 --- a/app/models/course/survey/question.rb +++ b/app/models/course/survey/question.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class Course::Survey::Question < ApplicationRecord - attribute :question_type, :integer - enum question_type: { text: 0, multiple_choice: 1, multiple_response: 2 } + enum :question_type, { text: 0, multiple_choice: 1, multiple_response: 2 } validates :description, presence: true validates :required, inclusion: { in: [true, false] } diff --git a/app/models/course/user_invitation.rb b/app/models/course/user_invitation.rb index 3a1897449aa..07aac1f371f 100644 --- a/app/models/course/user_invitation.rb +++ b/app/models/course/user_invitation.rb @@ -10,8 +10,8 @@ class Course::UserInvitation < ApplicationRecord validates :phantom, inclusion: [true, false] validate :no_existing_unconfirmed_invitation - enum role: CourseUser.roles - enum timeline_algorithm: CourseUser.timeline_algorithms + enum :role, CourseUser.roles + enum :timeline_algorithm, CourseUser.timeline_algorithms belongs_to :course, inverse_of: :invitations belongs_to :confirmer, class_name: 'User', inverse_of: nil, optional: true diff --git a/app/models/course/video/event.rb b/app/models/course/video/event.rb index 92841ed9094..e5ba9447c2b 100644 --- a/app/models/course/video/event.rb +++ b/app/models/course/video/event.rb @@ -16,5 +16,5 @@ class Course::Video::Event < ApplicationRecord upsert_keys [:session_id, :sequence_num] - enum event_type: [:play, :pause, :speed_change, :seek_start, :seek_end, :buffer, :end] + enum :event_type, [:play, :pause, :speed_change, :seek_start, :seek_end, :buffer, :end] end diff --git a/app/models/course_user.rb b/app/models/course_user.rb index a0e521545df..2f27ad966ab 100644 --- a/app/models/course_user.rb +++ b/app/models/course_user.rb @@ -7,8 +7,8 @@ class CourseUser < ApplicationRecord after_initialize :set_defaults, if: :new_record? before_validation :set_defaults, if: :new_record? - enum role: { student: 0, teaching_assistant: 1, manager: 2, owner: 3, observer: 4 } - enum timeline_algorithm: { fixed: 0, fomo: 1, stragglers: 2, otot: 3 } + enum :role, { student: 0, teaching_assistant: 1, manager: 2, owner: 3, observer: 4 } + enum :timeline_algorithm, { fixed: 0, fomo: 1, stragglers: 2, otot: 3 } # A set of roles which comprise the staff of a course, including the observer. STAFF_ROLES_SYM = Set[:teaching_assistant, :manager, :owner, :observer] diff --git a/app/models/instance/user_invitation.rb b/app/models/instance/user_invitation.rb index 545af0f2b2e..c8263eca7e1 100644 --- a/app/models/instance/user_invitation.rb +++ b/app/models/instance/user_invitation.rb @@ -11,7 +11,7 @@ class Instance::UserInvitation < ApplicationRecord validates :generate_invitation_key, presence: true validate :no_existing_unconfirmed_invitation - enum role: InstanceUser.roles + enum :role, InstanceUser.roles belongs_to :confirmer, class_name: 'User', inverse_of: nil, optional: true diff --git a/app/models/instance/user_role_request.rb b/app/models/instance/user_role_request.rb index 47b45e2df87..c6751979d18 100644 --- a/app/models/instance/user_role_request.rb +++ b/app/models/instance/user_role_request.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Instance::UserRoleRequest < ApplicationRecord include Workflow - enum role: InstanceUser.roles.except(:normal) + enum :role, InstanceUser.roles.except(:normal) after_initialize :set_default_role, if: :new_record? diff --git a/app/models/instance_user.rb b/app/models/instance_user.rb index f7f6cd1ab4d..c134665c059 100644 --- a/app/models/instance_user.rb +++ b/app/models/instance_user.rb @@ -5,7 +5,7 @@ class InstanceUser < ApplicationRecord acts_as_tenant :instance, inverse_of: :instance_users after_initialize :set_defaults, if: :new_record? - enum role: { normal: 0, instructor: 1, administrator: 2 } + enum :role, { normal: 0, instructor: 1, administrator: 2 } validates :role, presence: true validates :instance, presence: true diff --git a/app/models/user.rb b/app/models/user.rb index ced0fa89ffb..0fdd47c8020 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -11,7 +11,7 @@ class User < ApplicationRecord acts_as_reader mount_uploader :profile_photo, ImageUploader - enum role: { normal: 0, administrator: 1 } + enum :role, { normal: 0, administrator: 1 } AVAILABLE_LOCALES = I18n.available_locales.map(&:to_s) diff --git a/app/models/user_notification.rb b/app/models/user_notification.rb index 37107888911..cec66fb92bf 100644 --- a/app/models/user_notification.rb +++ b/app/models/user_notification.rb @@ -5,7 +5,7 @@ class UserNotification < ApplicationRecord acts_as_readable on: :created_at - enum notification_type: { popup: 0, email: 1 } + enum :notification_type, { popup: 0, email: 1 } validates :notification_type, presence: true validates :activity, presence: true diff --git a/config/application.rb b/config/application.rb index 2e62bce8895..790487d891c 100644 --- a/config/application.rb +++ b/config/application.rb @@ -13,7 +13,7 @@ module Application # rubocop:disable Style/ClassAndModuleChildren class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 + config.load_defaults 7.2 # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers diff --git a/config/credentials/development.key b/config/credentials/development.key new file mode 100644 index 00000000000..9a9a1030d0e --- /dev/null +++ b/config/credentials/development.key @@ -0,0 +1 @@ +921054b69df2e11efe48fcc33e5e6c3b \ No newline at end of file diff --git a/config/credentials/development.yml.enc b/config/credentials/development.yml.enc new file mode 100644 index 00000000000..21eb8ca51ae --- /dev/null +++ b/config/credentials/development.yml.enc @@ -0,0 +1 @@ +cpFVpuK16dpiu5+pMhjCp2acLOuK/s3flbhMx6vRG+wXLfoGt+RyNkdO1wXI8s/S9MPWpz0OYDLKOx+WlYfp/11z4pl59DbO4dMGVvpHOJxvRRGmcIvmNgAOFUUDOESFzBYu+WIdbGQqUthuJXzBb7CiNtOxhFiXu6uvnH3qfVZBXjFBpqjO/5Us2irVG7NJNOpMp9Dkh4PEye4d4kS1BjppcVe9wwMI1qZBZggW0VOBATisrAQGwJnoQY4eH7dNw6NfkoEKC4LpVH74xhrtL/tNYmNRmiQ2gvb/y0P0MGDBsdP+vakhGmS1ZDbAxwnMXUMhPQhEmFAphUuX2t9imSty/G2pKiaQA5ltAgpxwJbhT8MFyH8ZlBN+07NrJClYxLZMcujMToJjbyNNl3E2FRZRcLRIYCydVXCyyO0+oBSGIxJDbl7gYlbVd0U+6r4NtxNCmHU8m68IlESmXoomtFqAO+BYO4Xuutj/QavX1s7wDR7HBTpRK8vBDIDV1953kWoAj4Ck/3fgQjAAu7px47rlIN8S38ZoJXb8j5ShRLAwwQ46ZoIngzM=--De0M4cyIsF6pIvXU--2DxvDZDez7Q9AZcNkJFCzQ== \ No newline at end of file diff --git a/config/credentials/test.key b/config/credentials/test.key new file mode 100644 index 00000000000..c364b9b83ad --- /dev/null +++ b/config/credentials/test.key @@ -0,0 +1 @@ +00bcc95e1b3a44b1ba9766807383d3cb \ No newline at end of file diff --git a/config/credentials/test.yml.enc b/config/credentials/test.yml.enc new file mode 100644 index 00000000000..57c68291fcc --- /dev/null +++ b/config/credentials/test.yml.enc @@ -0,0 +1 @@ +Os8x0dJeIe65MOnAk0gFzYpdoRmLUPm5FtE3EyWuf1HZuOXqEGvSSvRmGyHkSynTBJ1dcR1zOKr0WY0lCJr++Q23Vrx1mqTnoA+p3aqdjE26x+vdvyAYAJ2OAgPARSeiO4I8h0rbTVkSpJMTjiBoHMj3ehKTkexr3sYnnjM/5CST6ytwSJhV4uWMuc1JPkTFlBI2FCO8EQ==--VLikj22h5LPwB5hI--lo1VepV16EWRIhkByrtyhw== \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 3e1dbe33f1a..e339d2166b3 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -9,8 +9,11 @@ # since you don't have to restart the web server when you make code changes. config.cache_classes = false - # Do not eager load code on boot. - config.eager_load = false + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true # Show full error reports. config.consider_all_requests_local = true @@ -34,6 +37,8 @@ # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local + config.log_level = :debug + # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false diff --git a/config/environments/test.rb b/config/environments/test.rb index fa9a971a1d3..56beca8296c 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -12,10 +12,11 @@ config.cache_classes = true - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true diff --git a/config/secrets.yml b/config/secrets.yml deleted file mode 100644 index a0158636b12..00000000000 --- a/config/secrets.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key is used for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! - -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -# You can use `rails secret` to generate a secure secret key. - -# Make sure the secrets in this file are kept private -# if you're sharing your code publicly. - -development: - secret_key_base: e38b6588c625976a7b79de42b6916cb32d4d349e90c8911a9dd5dda88de0675c9bc632ba90b2092e2690b5426bfc952463bf03e7ab3168172f5ee4e494f55ec9 - -test: - secret_key_base: fce273299448c1ea3ce9c2fd0138eaf745cd6498edb512cb1e9bba1faae527bd6803b88d8592953854c18ff41679e3ba8e629e45622f2332cecfab66aa0f91bd - -# Do not keep production secrets in the repository, -# instead read values from the environment. -production: - secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/db/schema.rb b/db/schema.rb index 2288f605e12..3976f46bb14 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_08_30_090759) do +ActiveRecord::Schema[7.2].define(version: 2024_08_30_090759) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "uuid-ossp" diff --git a/lib/autoload/trackable_job.rb b/lib/autoload/trackable_job.rb index 03a594d997f..f2144dcdb7f 100644 --- a/lib/autoload/trackable_job.rb +++ b/lib/autoload/trackable_job.rb @@ -14,7 +14,7 @@ module TrackableJob extend ActiveSupport::Concern class Job < ApplicationRecord - enum status: [:submitted, :completed, :errored] + enum :status, [:submitted, :completed, :errored] after_save :signal_finished, unless: :submitted? diff --git a/lib/extensions/conditional/active_record/base.rb b/lib/extensions/conditional/active_record/base.rb index 940b7f2a078..8498fc0ac82 100644 --- a/lib/extensions/conditional/active_record/base.rb +++ b/lib/extensions/conditional/active_record/base.rb @@ -4,7 +4,7 @@ module ClassMethods # Functions from conditional-and-condition framework. # Declare this function in the conditional model that requires conditions. def acts_as_conditional - enum satisfiability_type: [:all_conditions, :at_least_one_condition] + enum :satisfiability_type, [:all_conditions, :at_least_one_condition] has_many :conditions, -> { includes :actable }, class_name: 'Course::Condition', as: :conditional, dependent: :destroy, diff --git a/spec/libraries/acts_as_condition_spec.rb b/spec/libraries/acts_as_condition_spec.rb index ea7a0546479..6429258d3ac 100644 --- a/spec/libraries/acts_as_condition_spec.rb +++ b/spec/libraries/acts_as_condition_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_condition end diff --git a/spec/libraries/acts_as_conditional_spec.rb b/spec/libraries/acts_as_conditional_spec.rb index 59d4a0edf20..33b58fc5167 100644 --- a/spec/libraries/acts_as_conditional_spec.rb +++ b/spec/libraries/acts_as_conditional_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + attr_accessor :satisfiability_type acts_as_conditional @@ -21,6 +25,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_condition end diff --git a/spec/libraries/acts_as_duplication_traceable.rb b/spec/libraries/acts_as_duplication_traceable.rb index 2f8c926aa2f..a5f49ffeb4c 100644 --- a/spec/libraries/acts_as_duplication_traceable.rb +++ b/spec/libraries/acts_as_duplication_traceable.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_duplication_traceable end @@ -33,6 +37,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_duplication_traceable def self.dependent_class diff --git a/spec/libraries/acts_as_exp_record_spec.rb b/spec/libraries/acts_as_exp_record_spec.rb index 0d13f38547e..6337c5dfacb 100644 --- a/spec/libraries/acts_as_exp_record_spec.rb +++ b/spec/libraries/acts_as_exp_record_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_experience_points_record end diff --git a/spec/libraries/acts_as_lesson_plan_item_spec.rb b/spec/libraries/acts_as_lesson_plan_item_spec.rb index 79387b65dce..ea3755533ea 100644 --- a/spec/libraries/acts_as_lesson_plan_item_spec.rb +++ b/spec/libraries/acts_as_lesson_plan_item_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_lesson_plan_item end @@ -19,6 +23,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + acts_as_lesson_plan_item has_todo: true end diff --git a/spec/libraries/course/conditional/user_satisfiability_graph_spec.rb b/spec/libraries/course/conditional/user_satisfiability_graph_spec.rb index 93f231a8fca..f721d5faf71 100644 --- a/spec/libraries/course/conditional/user_satisfiability_graph_spec.rb +++ b/spec/libraries/course/conditional/user_satisfiability_graph_spec.rb @@ -41,6 +41,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + def self.build(conditions, id) dummy = new dummy.conditions = conditions diff --git a/spec/libraries/filename_validator_spec.rb b/spec/libraries/filename_validator_spec.rb index 6b9eb9f4dae..ec96dea7fe4 100644 --- a/spec/libraries/filename_validator_spec.rb +++ b/spec/libraries/filename_validator_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + attr_accessor :name validates_with FilenameValidator diff --git a/spec/libraries/has_one_many_attachments_spec.rb b/spec/libraries/has_one_many_attachments_spec.rb index 95f49bdd93d..454a07f0f29 100644 --- a/spec/libraries/has_one_many_attachments_spec.rb +++ b/spec/libraries/has_one_many_attachments_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + has_many_attachments end @@ -19,6 +23,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + has_one_attachment def clear_attribute_changes(attributes = changed_attributes.keys) diff --git a/spec/libraries/materials_spec.rb b/spec/libraries/materials_spec.rb index 6d3903f4815..e45fab01f13 100644 --- a/spec/libraries/materials_spec.rb +++ b/spec/libraries/materials_spec.rb @@ -9,6 +9,10 @@ def self.columns def self.load_schema!; end + def self._default_attributes + ActiveModel::AttributeSet.new({}) + end + has_one_folder end diff --git a/spec/services/course/duplication/course_duplication_service_spec.rb b/spec/services/course/duplication/course_duplication_service_spec.rb index 487bd92e43a..43121956a48 100644 --- a/spec/services/course/duplication/course_duplication_service_spec.rb +++ b/spec/services/course/duplication/course_duplication_service_spec.rb @@ -21,7 +21,7 @@ describe '#duplicate_course' do it 'duplicates the logo' do - expect(File.exist?(File.join(Rails.root, 'public', new_course.logo.url))).to be true + expect(File.exist?(File.join(Rails.root, 'public', new_course.logo.store_path))).to be true end context 'when saving fails' do