diff --git a/app/controllers/account_requests_controller.rb b/app/controllers/account_requests_controller.rb index c4b79e065..04cb1fd6c 100644 --- a/app/controllers/account_requests_controller.rb +++ b/app/controllers/account_requests_controller.rb @@ -16,6 +16,11 @@ def processed_requests def create @account_request = AccountRequest.new(account_request_params) if @account_request.save + # Check if username already exists in Users table + if User.exists?(username: @account_request.username) + render json: { error: 'Username already exists in the system' }, status: :unprocessable_entity + return + end response = { account_request: @account_request } if User.find_by(email: @account_request.email) response[:warnings] = 'WARNING: User with this email already exists!' @@ -81,11 +86,16 @@ def account_request_params # Create a new user if account request is approved def create_approved_user + # Check for BOTH email and username duplicates in the Users table if User.exists?(email: @account_request.email) - render json: { error: 'A user with this email already exists. Cannot approve the account request.' }, status: :unprocessable_entity + render json: { error: 'A user with this email already exists.' }, status: :unprocessable_entity + return + end + if User.exists?(username: @account_request.username) + render json: { error: 'A user with this username already exists.' }, status: :unprocessable_entity return end - @new_user = User.new(name: @account_request.username, role_id: @account_request.role_id, institution_id: @account_request.institution_id, full_name: @account_request.full_name, email: @account_request.email, password: 'password') + @new_user = User.new(username: @account_request.username, role_id: @account_request.role_id, institution_id: @account_request.institution_id, full_name: @account_request.full_name, email: @account_request.email, password: 'password') if @new_user.save render json: { success: 'Account Request Approved and User successfully created.', user: @new_user}, status: :ok else diff --git a/app/controllers/authentication_controller.rb b/app/controllers/authentication_controller.rb index 696c4ab21..3db0f1e8b 100644 --- a/app/controllers/authentication_controller.rb +++ b/app/controllers/authentication_controller.rb @@ -6,7 +6,7 @@ class AuthenticationController < ApplicationController # POST /login def login - user = User.find_by(name: params[:user_name]) || User.find_by(email: params[:user_name]) + user = User.find_by(username: params[:user_name]) || User.find_by(email: params[:user_name]) if user&.authenticate(params[:password]) payload = { id: user.id, name: user.name, full_name: user.full_name, role: user.role.name, institution_id: user.institution.id } diff --git a/app/controllers/bookmarks_controller.rb b/app/controllers/bookmarks_controller.rb index 59fa3efda..51555d125 100644 --- a/app/controllers/bookmarks_controller.rb +++ b/app/controllers/bookmarks_controller.rb @@ -68,7 +68,7 @@ def destroy def get_bookmark_rating_score begin @bookmark = Bookmark.find(params[:id]) - @bookmark_rating = BookmarkRating.where(bookmark_id: @bookmark.id, user_id: @current_user.id).first + @bookmark_rating = BookmarkRating.where(artifact_id: @bookmark.id, rater_id: @current_user.id).first render json: @bookmark_rating, status: :ok and return rescue ActiveRecord::RecordNotFound render json: $ERROR_INFO.to_s, status: :not_found and return @@ -79,11 +79,11 @@ def get_bookmark_rating_score # POST on /bookmarks/:id/bookmarkratings def save_bookmark_rating_score @bookmark = Bookmark.find(params[:id]) - @bookmark_rating = BookmarkRating.where(bookmark_id: @bookmark.id, user_id: @current_user.id).first + @bookmark_rating = BookmarkRating.where(artifact_id: @bookmark.id, rater_id: @current_user.id).first if @bookmark_rating.blank? - @bookmark_rating = BookmarkRating.create(bookmark_id: @bookmark.id, user_id: @current_user.id, rating: params[:rating]) + @bookmark_rating = BookmarkRating.create(artifact_id: @bookmark.id, rater_id: @current_user.id, ratings: params[:rating]) else - @bookmark_rating.update({'rating': params[:rating].to_i}) + @bookmark_rating.update(ratings: params[:rating].to_i) end render json: {"bookmark": @bookmark, "rating": @bookmark_rating}, status: :ok end diff --git a/app/controllers/grades_controller.rb b/app/controllers/grades_controller.rb index 2687d23a6..44d771a13 100644 --- a/app/controllers/grades_controller.rb +++ b/app/controllers/grades_controller.rb @@ -77,7 +77,7 @@ def get_review_tableau_data response_mapping_condition = "reviewed_object_id = " + params[:assignment_id] + " AND reviewer_id = " + params[:participant_id] ReviewResponseMap.where(response_mapping_condition).find_each do |mapping| - Response.where("map_id = " + mapping[:id].to_s).find_each do |response| + Response.where("response_map_id = " + mapping[:id].to_s).find_each do |response| # response = Response.find_by(map_id: mapping[:id]) @@ -203,11 +203,11 @@ def instructor_review reviewee_id: @team.id ) - existing_response = Response.find_by(map_id: mapping.id) + existing_response = Response.find_by(response_map_id: mapping.id) action = existing_response.present? ? 'edit' : 'new' render json: { - map_id: mapping.id, + response_map_id: mapping.id, response_id: existing_response&.id, redirect_to: "/response/#{action}/#{mapping.id}" } @@ -323,7 +323,7 @@ def get_heatgrid_data_for(maps) maps.each_with_index do |map, index| # Find the most recent submitted response for the current round submitted_round_response = map.responses.select do |r| - r.round == round && r.is_submitted && r.map_id == map.id + r.round == round && r.is_submitted && r.response_map_id == map.id end.last # Skip if no valid response was submitted diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index 69bb0c167..39073eb37 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -146,7 +146,7 @@ def inviter_team end def invitee_participant - invitee_user = User.find_by(name: params[:username])|| User.find_by(email: params[:username]) + invitee_user = User.find_by(username: params[:username])|| User.find_by(email: params[:username]) unless invitee_user render json: { error: "Participant with username #{params[:username]} not found" }, status: :not_found return diff --git a/app/controllers/participants_controller.rb b/app/controllers/participants_controller.rb index 607faa015..fd17411df 100644 --- a/app/controllers/participants_controller.rb +++ b/app/controllers/participants_controller.rb @@ -122,8 +122,8 @@ def destroy def participant_params params.require(:participant).permit(:user_id, :assignment_id, :authorization, :can_submit, :can_review, :can_take_quiz, :can_mentor, :handle, - :team_id, :join_team_request_id, :permission_granted, - :topic, :current_stage, :stage_deadline) + :team_id, :join_team_request_id, :topic, + :current_stage, :stage_deadline) end private diff --git a/app/controllers/submitted_content_controller.rb b/app/controllers/submitted_content_controller.rb index a84dd6812..b0f855d87 100644 --- a/app/controllers/submitted_content_controller.rb +++ b/app/controllers/submitted_content_controller.rb @@ -39,7 +39,7 @@ def create if record.save render json: record, status: :created else - render json: record.errors, status: :unprocessable_content + render json: record.errors, status: :unprocessable_entity end end @@ -331,7 +331,7 @@ def ensure_participant_team # Strong parameters for submission record creation def submitted_content_params # Permit only specified attributes for security - params.require(:submitted_content).permit(:id, :content, :operation, :team_id, :user, :assignment_id, :record_type) + params.require(:submitted_content).permit(:id, :content, :operation, :team_id, :submitted_by, :record_type) end # Returns the participant's team (local method, no instance variable caching) @@ -342,7 +342,7 @@ def participant_team end # Renders an error response with the given message and HTTP status - def render_error(message, status = :unprocessable_content) + def render_error(message, status = :unprocessable_entity) # Render JSON error response with specified status code render json: { error: message }, status: status end @@ -371,9 +371,8 @@ def create_submission_record_for(record_type, content, operation) SubmissionRecord.create!( record_type: record_type, # 'file' or 'hyperlink' content: content, # File path or URL - user: @participant.user_name, # Username from participant + submitted_by: @participant.user_name, # Username from participant team_id: @participant.team_id, # Team ID from participant - assignment_id: @participant.assignment_id, # Assignment ID from participant operation: operation # Operation description (e.g., 'Submit File') ) end diff --git a/app/controllers/teams_participants_controller.rb b/app/controllers/teams_participants_controller.rb index c34e3f34d..898a50e6d 100644 --- a/app/controllers/teams_participants_controller.rb +++ b/app/controllers/teams_participants_controller.rb @@ -64,8 +64,8 @@ def list_participants # Adds Participant to a team def add_participant # First Check if Participant exists - # Look up the User record based on the provided name parameter. - user = User.find_by(name: params[:name].strip) || (render(json: { error: "User not found" }, status: :not_found) and return) + # Look up the User record based on the provided username parameter. + user = User.find_by(username: params[:name].strip) || (render(json: { error: "User not found" }, status: :not_found) and return) # Find the Participant associated with the user, or return not found error participant = Participant.find_by(user_id: user.id) || (render(json: { error: "Couldn't find Participant" }, status: :not_found) and return) diff --git a/app/models/assignment.rb b/app/models/assignment.rb index 130fa6837..6a7736214 100644 --- a/app/models/assignment.rb +++ b/app/models/assignment.rb @@ -11,7 +11,7 @@ class Assignment < ApplicationRecord has_many :response_maps, foreign_key: 'reviewed_object_id', dependent: :destroy, inverse_of: :assignment has_many :review_mappings, class_name: 'ReviewResponseMap', foreign_key: 'reviewed_object_id', dependent: :destroy, inverse_of: :assignment has_many :project_topics , class_name: 'ProjectTopic', foreign_key: 'assignment_id', dependent: :destroy - has_many :due_dates,as: :parent, class_name: 'DueDate', dependent: :destroy + has_many :due_dates, class_name: 'DueDate', foreign_key: 'assignment_id', dependent: :destroy has_many :assignments_duties, dependent: :destroy has_many :duties, through: :assignments_duties belongs_to :course, optional: true diff --git a/app/models/bookmark_rating.rb b/app/models/bookmark_rating.rb index 6eb8aafa3..0772a4f02 100644 --- a/app/models/bookmark_rating.rb +++ b/app/models/bookmark_rating.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class BookmarkRating < ApplicationRecord - belongs_to :bookmark - belongs_to :user + belongs_to :bookmark, foreign_key: 'artifact_id' + belongs_to :user, foreign_key: 'rater_id' end diff --git a/app/models/dropdown.rb b/app/models/dropdown.rb index 4769e7d84..a31ab6cb7 100644 --- a/app/models/dropdown.rb +++ b/app/models/dropdown.rb @@ -2,7 +2,7 @@ class Dropdown < UnscoredItem include QuestionHelper - + self.inheritance_column = nil attr_accessor :txt, :type, :count, :weight def edit(count) edit_common("Item #{count}:", txt , weight, type).to_json diff --git a/app/models/due_date.rb b/app/models/due_date.rb index 7a2a5a883..b9f982e5a 100644 --- a/app/models/due_date.rb +++ b/app/models/due_date.rb @@ -9,7 +9,8 @@ class DueDate < ApplicationRecord LATE_ALLOWED = 2 NOT_ALLOWED = 1 - belongs_to :parent, polymorphic: true + belongs_to :parent, polymorphic: true, foreign_key: 'assignment_id' + belongs_to :assignment, foreign_key: 'assignment_id', optional: true validate :due_at_is_valid_datetime validates :due_at, presence: true @@ -30,8 +31,8 @@ def self.sort_due_dates(due_dates) end # Fetches all due dates for the parent Assignment or Topic - def self.fetch_due_dates(parent_id) - due_dates = where('parent_id = ?', parent_id) + def self.fetch_due_dates(assignment_id) + due_dates = where(assignment_id: assignment_id) sort_due_dates(due_dates) end @@ -42,21 +43,25 @@ def self.any_future_due_dates?(due_dates) def set(deadline, assignment_id, max_round) self.deadline_type_id = deadline - self.parent_id = assignment_id + self.assignment_id = assignment_id self.round = max_round save end # Fetches due dates from parent then selects the next upcoming due date - def self.next_due_date(parent_id) - due_dates = fetch_due_dates(parent_id) + def self.next_due_date(assignment_id) + due_dates = fetch_due_dates(assignment_id) due_dates.find { |due_date| due_date.due_at > Time.zone.now } end # Creates duplicate due dates and assigns them to a new assignment def copy(new_assignment_id) new_due_date = dup - new_due_date.parent_id = new_assignment_id + new_due_date.assignment_id = new_assignment_id new_due_date.save end + + def parent_id + assignment_id + end end diff --git a/app/models/question_advice.rb b/app/models/question_advice.rb index 76b54c56d..b53ea14f7 100644 --- a/app/models/question_advice.rb +++ b/app/models/question_advice.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class QuestionAdvice < ApplicationRecord + self.table_name = 'question_advice' belongs_to :item def self.export_fields(_options) QuestionAdvice.columns.map(&:name) diff --git a/app/models/quiz_question_choice.rb b/app/models/quiz_question_choice.rb index abfbdd47d..cbbe015cd 100644 --- a/app/models/quiz_question_choice.rb +++ b/app/models/quiz_question_choice.rb @@ -2,4 +2,5 @@ class QuizQuestionChoice < ApplicationRecord belongs_to :item, dependent: :destroy + alias_attribute :iscorrect, :is_correct end \ No newline at end of file diff --git a/app/models/response.rb b/app/models/response.rb index f99db770f..d6853d25a 100644 --- a/app/models/response.rb +++ b/app/models/response.rb @@ -4,7 +4,7 @@ class Response < ApplicationRecord include ScorableHelper include MetricHelper - belongs_to :response_map, class_name: 'ResponseMap', foreign_key: 'map_id', inverse_of: false + belongs_to :response_map, class_name: 'ResponseMap', foreign_key: 'response_map_id', inverse_of: false has_many :scores, class_name: 'Answer', foreign_key: 'response_id', dependent: :destroy, inverse_of: false alias map response_map @@ -43,7 +43,7 @@ def reportable_difference? assignment_questionnaire = AssignmentQuestionnaire.find_by(assignment_id: assignment.id, questionnaire_id: questionnaire.id) # notification_limit can be specified on 'Rubrics' tab on assignment edit page. - allowed_difference_percentage = assignment_questionnaire.notification_limit.to_f + allowed_difference_percentage = assignment_questionnaire.notification_threshold.to_f # the range of average_score_on_same_artifact_from_others and score is [0,1] # the range of allowed_difference_percentage is [0, 100] diff --git a/app/models/scale.rb b/app/models/scale.rb index 2517f7cf7..488ddf1b1 100644 --- a/app/models/scale.rb +++ b/app/models/scale.rb @@ -3,14 +3,14 @@ class Scale < ScoredItem include QuestionHelper - attr_accessor :txt, :type, :weight, :min_label, :max_label, :answer, :min_question_score, :max_question_score + attr_accessor :txt, :question_type, :weight, :min_label, :max_label, :answer, :min_question_score, :max_question_score def edit - edit_common('Item:', min_question_score, max_question_score , txt, weight, type).to_json + edit_common('Item:', min_question_score, max_question_score , txt, weight, question_type).to_json end def view_item_text - view_item_text_common(txt, type, weight, score_range).to_json + view_item_text_common(txt, question_type, weight, score_range).to_json end def complete diff --git a/app/models/student_task.rb b/app/models/student_task.rb index c5bb9332b..c93aa5e79 100644 --- a/app/models/student_task.rb +++ b/app/models/student_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class StudentTask - attr_accessor :assignment, :current_stage, :participant, :stage_deadline, :topic, :permission_granted + attr_accessor :assignment, :current_stage, :participant, :stage_deadline, :topic # Initializes a new instance of the StudentTask class def initialize(args) @@ -10,7 +10,6 @@ def initialize(args) @participant = args[:participant] @stage_deadline = args[:stage_deadline] @topic = args[:topic] - @permission_granted = args[:permission_granted] end # create a new StudentTask instance from a Participant object.cccccccc @@ -20,7 +19,6 @@ def self.create_from_participant(participant) topic: participant.topic, # Current stage of the assignment process current_stage: participant.current_stage, # Participant object stage_deadline: parse_stage_deadline(participant.stage_deadline), # Deadline for the current stage of the assignment - permission_granted: participant.permission_granted, # Topic of the assignment participant: participant # Boolean indicating if Publishing Rights is enabled ) end diff --git a/app/models/submission_record.rb b/app/models/submission_record.rb index 415a965be..58328b3e7 100644 --- a/app/models/submission_record.rb +++ b/app/models/submission_record.rb @@ -5,8 +5,7 @@ class SubmissionRecord < ApplicationRecord validates :content, presence: true validates :operation, presence: true validates :team_id, presence: true - validates :user, presence: true - validates :assignment_id, presence: true + validates :submitted_by, presence: true scope :files, -> { where(record_type: 'file') } scope :hyperlinks, -> { where(record_type: 'hyperlink') } diff --git a/app/models/user.rb b/app/models/user.rb index 0e77e25dc..cfdb438c7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,7 +3,17 @@ class User < ApplicationRecord has_secure_password after_initialize :set_defaults + alias_attribute :full_name, :name + # 2. Instead of alias_attribute for 'name', use explicit methods + # This prevents 'full_name' from accidentally following the 'name' alias + def name + self[:username] + end + + def name=(value) + self[:username] = value + end # name must be lowercase and unique validates :name, presence: true, uniqueness: true, allow_blank: false # format: { with: /\A[a-z]+\z/, message: 'must be in lowercase' } @@ -126,16 +136,15 @@ def self.from_params(params) # that only the id, name, and email attributes should be included when a User object is serialized. def as_json(options = {}) super(options.merge({ - only: %i[id name email full_name email_on_review email_on_submission - email_on_review_of_review], + only: %i[id username email full_name], include: { role: { only: %i[id name] }, - parent: { only: %i[id name] }, + parent: { only: %i[id username] }, institution: { only: %i[id name] } } })).tap do |hash| - hash['parent'] ||= { id: nil, name: nil } + hash['parent'] ||= { id: nil, username: nil } hash['institution'] ||= { id: nil, name: nil } end end @@ -143,9 +152,6 @@ def as_json(options = {}) def set_defaults self.is_new_user = true self.copy_of_emails ||= false - self.email_on_review ||= false - self.email_on_submission ||= false - self.email_on_review_of_review ||= false self.etc_icons_on_homepage ||= true end diff --git a/config/application.rb b/config/application.rb index 798f8702b..f78d01563 100644 --- a/config/application.rb +++ b/config/application.rb @@ -17,7 +17,7 @@ def self.preview_path=(_) module Reimplementation class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.0 + config.load_defaults 8.0 config.active_record.schema_format = :ruby # Configuration for the application, engines, and railties goes here. diff --git a/db/migrate/20260320005757_init_full_schema.rb b/db/migrate/20260320005757_init_full_schema.rb new file mode 100644 index 000000000..6cce510a8 --- /dev/null +++ b/db/migrate/20260320005757_init_full_schema.rb @@ -0,0 +1,204 @@ +class InitFullSchema < ActiveRecord::Migration[8.0] + def change + + # ---------------------------- + # CORE TABLES + # ---------------------------- + create_table :tag_prompts do |t| + t.string :prompt + t.string :desc + t.string :control_type + t.timestamps + end unless table_exists?(:tag_prompts) + + create_table :tag_prompt_deployments do |t| + t.bigint :tag_prompt_id + t.bigint :assignment_id + t.bigint :questionnaire_id + t.string :question_type + t.integer :answer_length_threshold + t.timestamps + end unless table_exists?(:tag_prompt_deployments) + + create_table :answer_tags do |t| + t.bigint :answer_id + t.bigint :tag_prompt_deployment_id + t.bigint :user_id + t.string :value + t.decimal :confidence_level, precision: 10, scale: 5 + t.timestamps + end unless table_exists?(:answer_tags) + + create_table :topic_bids do |t| + t.integer :topic_id + t.integer :team_id + t.integer :priority + t.timestamps + end unless table_exists?(:topic_bids) + + create_table :deadline_rights do |t| + t.string :name + end unless table_exists?(:deadline_rights) + + create_table :deadline_types do |t| + t.string :name + end unless table_exists?(:deadline_types) + + create_table :languages do |t| + t.string :name + end unless table_exists?(:languages) + + create_table :permissions do |t| + t.string :name + end unless table_exists?(:permissions) + + create_table :password_resets do |t| + t.string :user_email + t.string :token + t.datetime :updated_at + end unless table_exists?(:password_resets) + + create_table :sample_reviews do |t| + t.integer :assignment_id + t.integer :response_id + t.timestamps + end unless table_exists?(:sample_reviews) + + create_table :submission_records do |t| + t.text :record_type # FIXED (no STI) + t.string :content + t.string :operation + t.integer :team_id + t.string :submitted_by + t.timestamps + end unless table_exists?(:submission_records) + + create_table :suggestions do |t| + t.integer :assignment_id + t.string :title + t.text :description + t.string :status + t.string :username + t.string :signup_preference + end unless table_exists?(:suggestions) + + create_table :suggestion_comments do |t| + t.text :comments + t.string :commenter + t.string :vote + t.integer :suggestion_id + t.boolean :visible_to_student, default: false + t.timestamps + end unless table_exists?(:suggestion_comments) + + create_table :tree_folders do |t| + t.string :name + t.string :child_type + t.integer :parent_id + end unless table_exists?(:tree_folders) + + create_table :user_pastebins do |t| + t.integer :user_id + t.string :short_form + t.text :long_form + t.timestamps + end unless table_exists?(:user_pastebins) + + create_table :duties do |t| + t.string :name + t.integer :max_members_for_duty + t.bigint :assignment_id + t.timestamps + end unless table_exists?(:duties) + + create_table :late_policies do |t| + t.float :penalty_per_unit + t.integer :max_penalty, default: 0, null: false + t.string :penalty_unit, null: false + t.integer :times_used, default: 0, null: false + t.bigint :instructor_id + t.string :policy_name + t.boolean :private, default: true + end unless table_exists?(:late_policies) + + create_table :resubmission_times do |t| + t.bigint :participant_id + t.datetime :resubmitted_at + end unless table_exists?(:resubmission_times) + + create_table :review_bids do |t| + t.integer :priority + t.bigint :project_topic_id + t.bigint :participant_id + t.bigint :user_id + t.bigint :assignment_id + t.timestamps + end unless table_exists?(:review_bids) + + create_table :review_grades do |t| + t.bigint :participant_id + t.integer :grade_for_reviewer + t.text :comment_for_reviewer + t.datetime :review_graded_at + t.integer :reviewer_id + end unless table_exists?(:review_grades) + + create_table :review_comment_paste_bins do |t| + t.bigint :review_grade_id + t.string :title + t.text :review_comment + t.timestamps + end unless table_exists?(:review_comment_paste_bins) + + create_table :roles_permissions do |t| + t.integer :role_id + t.integer :permission_id + end unless table_exists?(:roles_permissions) + + create_table :survey_deployments do |t| + t.bigint :questionnaire_id + t.datetime :start_date + t.datetime :end_date + t.datetime :last_reminder + t.integer :parent_id, default: 0 + t.integer :global_survey_id + t.string :deployment_type # FIXED + end unless table_exists?(:survey_deployments) + + create_table :track_notifications do |t| + t.integer :user_id + t.integer :notification_id + t.timestamps + end unless table_exists?(:track_notifications) + + create_table :questionnaire_types do |t| + t.string :display_type, null: false + end unless table_exists?(:questionnaire_types) + + # ---------------------------- + # FOREIGN KEYS + # ---------------------------- + add_foreign_key :tag_prompt_deployments, :tag_prompts if table_exists?(:tag_prompt_deployments) + add_foreign_key :tag_prompt_deployments, :assignments if table_exists?(:assignments) + add_foreign_key :tag_prompt_deployments, :questionnaires if table_exists?(:questionnaires) + + add_foreign_key :answer_tags, :answers if table_exists?(:answers) + add_foreign_key :answer_tags, :users if table_exists?(:users) + add_foreign_key :answer_tags, :tag_prompt_deployments if table_exists?(:tag_prompt_deployments) + + add_foreign_key :late_policies, :users, column: :instructor_id if table_exists?(:users) + + add_foreign_key :resubmission_times, :participants if table_exists?(:participants) + + add_foreign_key :review_bids, :participants if table_exists?(:participants) + add_foreign_key :review_bids, :users if table_exists?(:users) + add_foreign_key :review_bids, :assignments if table_exists?(:assignments) + + add_foreign_key :review_grades, :participants if table_exists?(:participants) + + add_foreign_key :review_comment_paste_bins, :review_grades if table_exists?(:review_grades) + + add_foreign_key :survey_deployments, :questionnaires if table_exists?(:questionnaires) + + end +end \ No newline at end of file diff --git a/db/migrate/20260320011304_cleanup_and_transformations.rb b/db/migrate/20260320011304_cleanup_and_transformations.rb new file mode 100644 index 000000000..dff5589c0 --- /dev/null +++ b/db/migrate/20260320011304_cleanup_and_transformations.rb @@ -0,0 +1,223 @@ +class CleanupAndTransformations < ActiveRecord::Migration[8.0] + def up + # ------------------------- + # USERS TABLE + # ------------------------- + rename_column :users, :name, :username if column_exists?(:users, :name) + rename_column :users, :full_name, :name if column_exists?(:users, :full_name) + if column_exists?(:users, "timeZonePref") + rename_column :users, "timeZonePref", :time_zone_pref + else + # This will print in your terminal during migrate so you know what happened + say "WARNING: timeZonePref not found in users table!", true + end + remove_column :users, :mru_directory_path if column_exists?(:users, :mru_directory_path) + remove_column :users, :email_on_review if column_exists?(:users, :email_on_review) + remove_column :users, :email_on_review_of_review if column_exists?(:users, :email_on_review_of_review) + remove_column :users, :master_permission_granted if column_exists?(:users, :master_permission_granted) + remove_column :users, :digital_certificate if column_exists?(:users, :digital_certificate) + remove_column :users, :persistence_token if column_exists?(:users, :persistence_token) + add_column :users, :public_key, :text unless column_exists?(:users, :public_key) + add_column :users, :private_by_default, :boolean unless column_exists?(:users, :private_by_default) + add_column :users, :password_salt, :text unless column_exists?(:users, :password_salt) + # ------------------------- + # ASSIGNMENTS TABLE + # ------------------------- + rename_column :assignments, :spec_location, :URL if column_exists?(:assignments, :spec_location) + rename_column :assignments, :is_intelligent, :topics_assigned_by_bidding if column_exists?(:assignments, :is_intelligent) + rename_column :assignments, :availability_flag, :available_to_students if column_exists?(:assignments, :availability_flag) + rename_column :assignments, :use_bookmark, :can_bookmark_topics if column_exists?(:assignments, :use_bookmark) + + remove_column :assignments, :max_bids if column_exists?(:assignments, :max_bids) + remove_column :assignments, :reputation_algorithm if column_exists?(:assignments, :reputation_algorithm) + remove_column :assignments, :simicheck if column_exists?(:assignments, :simicheck) + remove_column :assignments, :simicheck_threshold if column_exists?(:assignments, :simicheck_threshold) + remove_column :assignments, :has_badge if column_exists?(:assignments, :has_badge) + remove_column :assignments, :is_conference_assignment if column_exists?(:assignments, :is_conference_assignment) + add_column :assignments, :vary_by_topic?, :boolean unless column_exists?(:assignments, :vary_by_topic?) + add_column :assignments, :vary_by_round?, :boolean unless column_exists?(:assignments, :vary_by_round?) + add_column :assignments, :team_reviewing_enabled, :boolean unless column_exists?(:assignments, :team_reviewing_enabled) + add_column :assignments, :bidding_for_reviews_enabled, :boolean unless column_exists?(:assignments, :bidding_for_reviews_enabled) + add_column :assignments, :auto_assign_mentor, :boolean unless column_exists?(:assignments, :auto_assign_mentor) + add_column :assignments, :team_members_have_duty, :boolean unless column_exists?(:assignments, :team_members_have_duty) + add_column :assignments, :vary_by_duty?, :boolean unless column_exists?(:assignments, :vary_by_duty?) + + # ------------------------- + # PARTICIPANTS TABLE + # ------------------------- + change_column :participants, :user_id, :bigint if column_exists?(:participants, :user_id) + + remove_column :participants, :submitted_at if column_exists?(:participants, :submitted_at) + remove_column :participants, :penalty_accumulated if column_exists?(:participants, :penalty_accumulated) + remove_column :participants, :time_stamp if column_exists?(:participants, :time_stamp) + remove_column :participants, :digital_signature if column_exists?(:participants, :digital_signature) + remove_column :participants, :duty if column_exists?(:participants, :duty) + remove_column :participants, :duty_id if column_exists?(:participants, :duty_id) + + rename_column :participants, :permission_granted, :OK_to_show if column_exists?(:participants, :permission_granted) + + add_column :participants, :can_mentor, :boolean unless column_exists?(:participants, :can_mentor) + + # ------------------------- + # SUBMISSION RECORDS + # ------------------------- + rename_column :submission_records, :type, :record_type if column_exists?(:submission_records, :type) + rename_column :submission_records, :user, :submitted_by if column_exists?(:submission_records, :user) + + remove_column :submission_records, :assignment_id if column_exists?(:submission_records, :assignment_id) + + # ------------------------- + # SUGGESTIONS + # ------------------------- + rename_column :suggestions, :unityID, :username if column_exists?(:suggestions, :unityID) + + # ------------------------- + # REVIEW BIDS + # ------------------------- + rename_column :review_bids, :signuptopic_id, :project_topic_id if column_exists?(:review_bids, :signuptopic_id) + + # ------------------------- + # BOOKMARK RATINGS + # ------------------------- + rename_column :bookmark_ratings, :bookmark_id, :artifact_id if column_exists?(:bookmark_ratings, :bookmark_id) + rename_column :bookmark_ratings, :user_id, :rater_id if column_exists?(:bookmark_ratings, :user_id) + rename_column :bookmark_ratings, :rating, :ratings if column_exists?(:bookmark_ratings, :rating) + + # ------------------------- + # COURSES + # ------------------------- + rename_column :courses, :private, :is_private if column_exists?(:courses, :private) + rename_column :courses, :institutions_id, :institution_id if column_exists?(:courses, :institutions_id) + add_column :courses, :language, :text unless column_exists?(:courses, :language) + + # ------------------------- + # DUE DATES + # ------------------------- + rename_column :due_dates, :parent_id, :assignment_id if column_exists?(:due_dates, :parent_id) + + # ------------------------- + # RESPONSES + # ------------------------- + rename_column :responses, :map_id, :response_map_id if column_exists?(:responses, :map_id) + + # ------------------------- + # QUIZ_QUESTION_CHOICES + # ------------------------- + rename_column :quiz_question_choices, :iscorrect, :is_correct if column_exists?(:quiz_question_choices, :iscorrect) + + # ------------------------- + # ASSIGNMENT_QUESTIONNAIRES + # ------------------------- + rename_column :assignment_questionnaires, :notification_limit, :notification_threshold if column_exists?(:assignment_questionnaires, :notification_limit) + add_column :assignment_questionnaires, :dropdown, :boolean unless column_exists?(:survey_deployments, :dropdown) + add_column :assignment_questionnaires, :topic_id, :bigint unless column_exists?(:survey_deployments, :topic_id) + add_column :assignment_questionnaires, :duty_id, :bigint unless column_exists?(:survey_deployments, :duty_id) + + # ------------------------- + # SURVEY_DEPLOYMENTS + # ------------------------- + add_column :survey_deployments, :type, :text unless column_exists?(:survey_deployments, :type) + + # ------------------------- + # ROLES + # ------------------------- + add_column :roles, :description, :text unless column_exists?(:roles, :description) + + # ------------------------- + # RESPONSES + # ------------------------- + add_column :responses, :visibility, :text unless column_exists?(:responses, :visibility) + + # ------------------------- + # RESPONSES + # ------------------------- + add_column :response_maps, :for_calibration, :boolean unless column_exists?(:response_maps, :for_calibration) + + # ------------------------- + # ITEMS + # ------------------------- + add_column :items, :type, :text unless column_exists?(:items, :type) + + # ------------------------- + # QUESTIONNAIRES + # ------------------------- + add_column :questionnaires, :type, :text unless column_exists?(:questionnaires, :type) + + # ------------------------- + # QUESTION_TYPES + # ------------------------- + add_column :question_types, :type, :text unless column_exists?(:question_types, :type) + + # ------------------------- + # JOIN_TEAM_REQUESTS + # ------------------------- + add_column :join_team_requests, :status, :text unless column_exists?(:join_team_requests, :status) + + # ------------------------- + # DUTIES + # ------------------------- + add_column :duties, :assignment_id, :bigint unless column_exists?(:duties, :assignment_id) + + + # ------------------------- + # TABLE RENAMES + # ------------------------- + if table_exists?(:teams_users) && !table_exists?(:teams_participants) + rename_table :teams_users, :teams_participants + end + if table_exists?(:question_advices) && !table_exists?(:question_advice) + rename_table :question_advices, :question_advice + end + + if table_exists?(:bids) && !table_exists?(:topic_bids) + rename_table :bids, :topic_bids + end + + # ------------------------- + # DATA MIGRATION (IMPORTANT) + # ------------------------- + if column_exists?(:signed_up_teams, :advertise_for_partner) && + column_exists?(:teams, :advertise_for_partner) + + execute <<-SQL + UPDATE signed_up_teams sut + JOIN teams t ON sut.team_id = t.id + SET + sut.comments_for_advertisement = t.comments_for_advertisement, + sut.advertise_for_partner = t.advertise_for_partner + SQL + + end + + # ------------------------- + # CLEANUP TABLES + # ------------------------- + drop_table :awarded_badges, if_exists: true + drop_table :badges, if_exists: true + drop_table :calculated_penalties, if_exists: true + drop_table :delayed_jobs, if_exists: true + drop_table :locks, if_exists: true + drop_table :menu_items, if_exists: true + drop_table :plagiarism_checker_assignment_submissions, if_exists: true + drop_table :plagiarism_checker_comparisons, if_exists: true + drop_table :sections, if_exists: true + drop_table :system_settings, if_exists: true + drop_table :content_pages, if_exists: true + drop_table :controller_actions, if_exists: true + drop_table :markup_styles, if_exists: true + drop_table :notifications, if_exists: true + drop_table :ar_internal_metadata, if_exists: true + drop_table :site_controllers, if_exists: true + + # ------------------------- + # NEW TABLE + # ------------------------- + create_table :questionnaire_types do |t| + t.string :display_type, null: false + end unless table_exists?(:questionnaire_types) + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index cddbe12c6..70d81771c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,27 +10,40 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2026_03_13_064334) do +ActiveRecord::Schema[8.0].define(version: 2026_03_20_011304) do create_table "account_requests", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "username" - t.string "full_name" + t.datetime "created_at", null: false t.string "email" - t.string "status" + t.string "full_name" + t.bigint "institution_id", null: false t.text "introduction" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.bigint "role_id", null: false - t.bigint "institution_id", null: false + t.string "status" + t.datetime "updated_at", null: false + t.string "username" t.index ["institution_id"], name: "index_account_requests_on_institution_id" t.index ["role_id"], name: "index_account_requests_on_role_id" end + create_table "answer_tags", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.bigint "answer_id" + t.decimal "confidence_level", precision: 10, scale: 5 + t.datetime "created_at", null: false + t.bigint "tag_prompt_deployment_id" + t.datetime "updated_at", null: false + t.bigint "user_id" + t.string "value" + t.index ["answer_id"], name: "fk_rails_6c5d47c4e2" + t.index ["tag_prompt_deployment_id"], name: "fk_rails_ec0fee5d79" + t.index ["user_id"], name: "fk_rails_36ff09eab9" + end + create_table "answers", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.integer "item_id", default: 0, null: false - t.integer "response_id" t.integer "answer" t.text "comments" t.datetime "created_at", null: false + t.integer "item_id", default: 0, null: false + t.integer "response_id" t.datetime "updated_at", null: false t.index ["item_id"], name: "fk_score_items" t.index ["response_id"], name: "fk_score_response" @@ -38,101 +51,106 @@ create_table "assignment_questionnaires", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.integer "assignment_id" - t.integer "questionnaire_id" - t.integer "notification_limit", default: 15, null: false t.datetime "created_at", null: false + t.boolean "dropdown" + t.bigint "duty_id" + t.integer "notification_threshold", default: 15, null: false + t.integer "questionnaire_id" + t.integer "questionnaire_weight" + t.bigint "topic_id" t.datetime "updated_at", null: false t.integer "used_in_round" - t.integer "questionnaire_weight" t.index ["assignment_id"], name: "fk_aq_assignments_id" t.index ["questionnaire_id"], name: "fk_aq_questionnaire_id" end create_table "assignments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "name" - t.string "directory_path" - t.integer "submitter_count" - t.boolean "private" - t.integer "num_reviews" - t.integer "num_review_of_reviews" - t.integer "num_review_of_reviewers" - t.boolean "reviews_visible_to_all" - t.integer "num_reviewers" - t.text "spec_location" - t.integer "max_team_size" - t.boolean "staggered_deadline" + t.text "URL" + t.boolean "allow_selecting_additional_reviews_after_1st_round" t.boolean "allow_suggestions" - t.integer "days_between_submissions" - t.string "review_assignment_strategy" - t.integer "max_reviews_per_submission" - t.integer "review_topic_threshold" - t.boolean "copy_flag" - t.integer "rounds_of_reviews" - t.boolean "microtask" - t.boolean "require_quiz" - t.integer "num_quiz_questions" - t.boolean "is_coding_assignment" - t.boolean "is_intelligent" + t.boolean "auto_assign_mentor" + t.boolean "available_to_students" + t.boolean "bidding_for_reviews_enabled" t.boolean "calculate_penalty" - t.integer "late_policy_id" - t.boolean "is_penalty_calculated" - t.integer "max_bids" - t.boolean "show_teammate_reviews" - t.boolean "availability_flag" - t.boolean "use_bookmark" - t.boolean "can_review_same_topic" + t.boolean "can_bookmark_topics" t.boolean "can_choose_topic_to_review" + t.boolean "can_review_same_topic" + t.boolean "copy_flag" + t.bigint "course_id" + t.datetime "created_at", null: false + t.integer "days_between_submissions" + t.string "directory_path" + t.boolean "enable_pair_programming", default: false + t.boolean "has_teams", default: false + t.boolean "has_topics", default: false + t.bigint "instructor_id", null: false + t.boolean "is_anonymous" + t.boolean "is_answer_tagging_allowed" t.boolean "is_calibrated" + t.boolean "is_coding_assignment" + t.boolean "is_penalty_calculated" t.boolean "is_selfreview_enabled" - t.string "reputation_algorithm" - t.boolean "is_anonymous" - t.integer "num_reviews_required" - t.integer "num_metareviews_required" + t.integer "late_policy_id" + t.integer "max_reviews_per_submission" + t.integer "max_team_size" + t.boolean "microtask" + t.string "name" t.integer "num_metareviews_allowed" + t.integer "num_metareviews_required" + t.integer "num_quiz_questions" + t.integer "num_review_of_reviewers" + t.integer "num_review_of_reviews" + t.integer "num_reviewers" + t.integer "num_reviews" t.integer "num_reviews_allowed" - t.integer "simicheck" - t.integer "simicheck_threshold" - t.boolean "is_answer_tagging_allowed" - t.boolean "has_badge" - t.boolean "allow_selecting_additional_reviews_after_1st_round" + t.integer "num_reviews_required" + t.boolean "private" + t.boolean "require_quiz" + t.string "review_assignment_strategy" + t.integer "review_topic_threshold" + t.boolean "reviews_visible_to_all" + t.integer "rounds_of_reviews" t.integer "sample_assignment_id" - t.datetime "created_at", null: false + t.boolean "show_teammate_reviews" + t.boolean "staggered_deadline" + t.integer "submitter_count" + t.boolean "team_members_have_duty" + t.boolean "team_reviewing_enabled" + t.boolean "topics_assigned_by_bidding" t.datetime "updated_at", null: false - t.bigint "instructor_id", null: false - t.bigint "course_id" - t.boolean "enable_pair_programming", default: false - t.boolean "has_teams", default: false - t.boolean "has_topics", default: false + t.boolean "vary_by_duty?" t.boolean "vary_by_round", default: false, null: false + t.boolean "vary_by_round?" + t.boolean "vary_by_topic?" t.index ["course_id"], name: "index_assignments_on_course_id" t.index ["instructor_id"], name: "index_assignments_on_instructor_id" end create_table "assignments_duties", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "assignment_id", null: false - t.bigint "duty_id", null: false t.datetime "created_at", null: false + t.bigint "duty_id", null: false t.datetime "updated_at", null: false t.index ["assignment_id"], name: "index_assignments_duties_on_assignment_id" t.index ["duty_id"], name: "index_assignments_duties_on_duty_id" end create_table "bookmark_ratings", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.integer "bookmark_id" - t.integer "user_id" - t.integer "rating" + t.integer "artifact_id" t.datetime "created_at", null: false + t.integer "rater_id" + t.integer "ratings" t.datetime "updated_at", null: false end create_table "bookmarks", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.text "url" - t.text "title" + t.datetime "created_at", null: false t.text "description" - t.integer "user_id" + t.text "title" t.integer "topic_id" - t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.text "url" + t.integer "user_id" end create_table "cakes", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| @@ -141,271 +159,411 @@ end create_table "courses", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "name" + t.datetime "created_at", null: false t.string "directory_path" t.text "info" - t.boolean "private", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.bigint "instructor_id", null: false t.bigint "institution_id", null: false + t.bigint "instructor_id", null: false + t.boolean "is_private", default: false + t.text "language" + t.string "name" + t.datetime "updated_at", null: false t.index ["institution_id"], name: "index_courses_on_institution_id" t.index ["instructor_id"], name: "fk_course_users" t.index ["instructor_id"], name: "index_courses_on_instructor_id" end + create_table "deadline_rights", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "name" + end + + create_table "deadline_types", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "name" + end + create_table "due_dates", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.datetime "due_at", null: false + t.bigint "assignment_id", null: false + t.datetime "created_at", null: false + t.string "deadline_name" t.integer "deadline_type_id", null: false - t.string "parent_type", null: false - t.bigint "parent_id", null: false - t.integer "submission_allowed_id", null: false - t.integer "review_allowed_id", null: false - t.integer "round" - t.boolean "flag", default: false - t.integer "threshold", default: 1 t.string "delayed_job_id" - t.string "deadline_name" t.string "description_url" + t.datetime "due_at", null: false + t.boolean "flag", default: false + t.string "parent_type", null: false t.integer "quiz_allowed_id", default: 1 - t.integer "teammate_review_allowed_id", default: 3 - t.string "type", default: "AssignmentDueDate" - t.integer "resubmission_allowed_id" t.integer "rereview_allowed_id" + t.integer "resubmission_allowed_id" + t.integer "review_allowed_id", null: false t.integer "review_of_review_allowed_id" - t.datetime "created_at", null: false + t.integer "round" + t.integer "submission_allowed_id", null: false + t.integer "teammate_review_allowed_id", default: 3 + t.integer "threshold", default: 1 + t.string "type", default: "AssignmentDueDate" t.datetime "updated_at", null: false - t.index ["parent_type", "parent_id"], name: "index_due_dates_on_parent" + t.index ["parent_type", "assignment_id"], name: "index_due_dates_on_parent" end create_table "duties", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.bigint "assignment_id" + t.datetime "created_at", null: false + t.bigint "instructor_id", null: false + t.integer "max_members_for_duty" t.string "name" t.boolean "private", default: false - t.bigint "instructor_id", null: false - t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "max_members_for_duty" t.index ["instructor_id"], name: "index_duties_on_instructor_id" end create_table "institutions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "name" t.datetime "created_at", null: false + t.string "name" t.datetime "updated_at", null: false end create_table "invitations", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.integer "assignment_id" - t.string "reply_status", limit: 1 t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.bigint "from_id", null: false + t.string "reply_status", limit: 1 t.bigint "to_id", null: false + t.datetime "updated_at", null: false t.index ["assignment_id"], name: "fk_invitation_assignments" t.index ["from_id"], name: "index_invitations_on_from_id" t.index ["to_id"], name: "index_invitations_on_to_id" end create_table "items", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.text "txt" - t.integer "weight" - t.decimal "seq", precision: 10 - t.string "question_type" - t.string "size" t.string "alternatives" t.boolean "break_before" + t.datetime "created_at", null: false t.string "max_label" t.string "min_label" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "question_type" t.bigint "questionnaire_id", null: false + t.decimal "seq", precision: 10 + t.string "size" + t.text "txt" + t.text "type" + t.datetime "updated_at", null: false + t.integer "weight" t.index ["questionnaire_id"], name: "fk_question_questionnaires" t.index ["questionnaire_id"], name: "index_items_on_questionnaire_id" end create_table "join_team_requests", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.text "comments" t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.integer "participant_id" - t.integer "team_id" - t.text "comments" t.string "reply_status" + t.text "status" + t.integer "team_id" + t.datetime "updated_at", null: false + end + + create_table "languages", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "name" + end + + create_table "late_policies", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.bigint "instructor_id" + t.integer "max_penalty", default: 0, null: false + t.float "penalty_per_unit" + t.string "penalty_unit", null: false + t.string "policy_name" + t.boolean "private", default: true + t.integer "times_used", default: 0, null: false + t.index ["instructor_id"], name: "fk_rails_c0d822b6f4" end create_table "nodes", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.integer "parent_id" + t.datetime "created_at", null: false t.integer "node_object_id" + t.integer "parent_id" t.string "type" - t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "participants", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.bigint "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "can_submit", default: true + t.boolean "OK_to_show", default: false + t.string "authorization" + t.boolean "can_mentor" t.boolean "can_review", default: true + t.boolean "can_submit", default: true + t.boolean "can_take_quiz" + t.datetime "created_at", null: false + t.string "current_stage" + t.float "grade" t.string "handle" - t.boolean "permission_granted", default: false t.bigint "join_team_request_id" + t.integer "parent_id", null: false + t.datetime "stage_deadline" t.bigint "team_id" t.string "topic" - t.string "current_stage" - t.datetime "stage_deadline" - t.boolean "can_take_quiz" - t.boolean "can_mentor" - t.string "authorization" - t.integer "parent_id", null: false t.string "type", null: false - t.float "grade" - t.bigint "duty_id" - t.index ["duty_id"], name: "index_participants_on_duty_id" + t.datetime "updated_at", null: false + t.bigint "user_id" t.index ["join_team_request_id"], name: "index_participants_on_join_team_request_id" t.index ["team_id"], name: "index_participants_on_team_id" t.index ["user_id"], name: "fk_participant_users" t.index ["user_id"], name: "index_participants_on_user_id" end + create_table "password_resets", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "token" + t.datetime "updated_at" + t.string "user_email" + end + + create_table "permissions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "name" + end + create_table "project_topics", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.text "topic_name", null: false t.bigint "assignment_id", null: false - t.integer "max_choosers", default: 0, null: false t.text "category" - t.string "topic_identifier", limit: 10 - t.integer "micropayment", default: 0 - t.integer "private_to" + t.datetime "created_at", null: false t.text "description" t.string "link" - t.datetime "created_at", null: false + t.integer "max_choosers", default: 0, null: false + t.integer "micropayment", default: 0 + t.integer "private_to" + t.string "topic_identifier", limit: 10 + t.text "topic_name", null: false t.datetime "updated_at", null: false t.index ["assignment_id"], name: "index_project_topics_on_assignment_id" end - create_table "question_advices", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.bigint "question_id", null: false - t.integer "score" + create_table "question_advice", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.text "advice" t.datetime "created_at", null: false + t.bigint "question_id", null: false + t.integer "score" t.datetime "updated_at", null: false - t.index ["question_id"], name: "index_question_advices_on_question_id" + t.index ["question_id"], name: "index_question_advice_on_question_id" end create_table "question_types", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "name" t.datetime "created_at", null: false + t.string "name" + t.text "type" t.datetime "updated_at", null: false end create_table "questionnaire_types", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "name" t.datetime "created_at", null: false + t.string "name" t.datetime "updated_at", null: false end create_table "questionnaires", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.string "name" + t.datetime "created_at", null: false + t.string "display_type" + t.text "instruction_loc" t.integer "instructor_id" - t.boolean "private" - t.integer "min_question_score" t.integer "max_question_score" + t.integer "min_question_score" + t.string "name" + t.boolean "private" t.string "questionnaire_type" - t.string "display_type" - t.text "instruction_loc" - t.datetime "created_at", null: false + t.text "type" t.datetime "updated_at", null: false end create_table "quiz_question_choices", id: :integer, charset: "latin1", force: :cascade do |t| + t.datetime "created_at", null: false + t.boolean "is_correct", default: false t.integer "question_id" t.text "txt" - t.boolean "iscorrect", default: false - t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "response_maps", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.datetime "created_at", null: false + t.boolean "for_calibration" t.integer "reviewed_object_id", default: 0, null: false - t.integer "reviewer_id", default: 0, null: false t.integer "reviewee_id", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "reviewer_id", default: 0, null: false t.string "type" + t.datetime "updated_at", null: false t.index ["reviewer_id"], name: "fk_response_map_reviewer" end create_table "responses", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.integer "map_id", default: 0, null: false t.text "additional_comment" - t.boolean "is_submitted", default: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.boolean "is_submitted", default: false + t.integer "response_map_id", default: 0, null: false t.integer "round" + t.datetime "updated_at", null: false t.integer "version_num" - t.index ["map_id"], name: "fk_response_response_map" + t.text "visibility" + t.index ["response_map_id"], name: "fk_response_response_map" + end + + create_table "resubmission_times", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.bigint "participant_id" + t.datetime "resubmitted_at" + t.index ["participant_id"], name: "fk_rails_8a569f5ab6" + end + + create_table "review_bids", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.bigint "assignment_id" + t.datetime "created_at", null: false + t.bigint "participant_id" + t.integer "priority" + t.bigint "project_topic_id" + t.datetime "updated_at", null: false + t.bigint "user_id" + t.index ["assignment_id"], name: "fk_rails_549e23ae08" + t.index ["participant_id"], name: "fk_rails_ab93feeb35" + t.index ["user_id"], name: "fk_rails_6041e1cdb9" + end + + create_table "review_comment_paste_bins", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.datetime "created_at", null: false + t.text "review_comment" + t.bigint "review_grade_id" + t.string "title" + t.datetime "updated_at", null: false + t.index ["review_grade_id"], name: "fk_rails_0a539bcc81" + end + + create_table "review_grades", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.text "comment_for_reviewer" + t.integer "grade_for_reviewer" + t.bigint "participant_id" + t.datetime "review_graded_at" + t.integer "reviewer_id" + t.index ["participant_id"], name: "fk_rails_29587cf6a9" end create_table "roles", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.datetime "created_at", null: false + t.integer "default_page_id" + t.text "description" t.string "name" t.bigint "parent_id" - t.integer "default_page_id" - t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["parent_id"], name: "fk_rails_4404228d2f" end + create_table "roles_permissions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.integer "permission_id" + t.integer "role_id" + end + + create_table "sample_reviews", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.integer "assignment_id" + t.datetime "created_at", null: false + t.integer "response_id" + t.datetime "updated_at", null: false + end + create_table "signed_up_teams", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.bigint "project_topic_id", null: false - t.bigint "team_id", null: false + t.boolean "advertise_for_partner" + t.text "comments_for_advertisement" + t.datetime "created_at", null: false t.boolean "is_waitlisted" t.integer "preference_priority_number" - t.datetime "created_at", null: false + t.bigint "project_topic_id", null: false + t.bigint "team_id", null: false t.datetime "updated_at", null: false - t.text "comments_for_advertisement" - t.boolean "advertise_for_partner" t.index ["project_topic_id"], name: "index_signed_up_teams_on_project_topic_id" t.index ["team_id"], name: "index_signed_up_teams_on_team_id" end create_table "submission_records", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.text "record_type" t.text "content" + t.datetime "created_at", null: false t.string "operation" + t.text "record_type" + t.string "submitted_by" t.integer "team_id" - t.string "user" - t.integer "assignment_id" + t.datetime "updated_at", null: false + end + + create_table "suggestion_comments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "commenter" + t.text "comments" t.datetime "created_at", null: false + t.integer "suggestion_id" t.datetime "updated_at", null: false + t.boolean "visible_to_student", default: false + t.string "vote" + end + + create_table "suggestions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.integer "assignment_id" + t.text "description" + t.string "signup_preference" + t.string "status" + t.string "title" + t.string "username" + end + + create_table "survey_deployments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "deployment_type" + t.datetime "end_date" + t.integer "global_survey_id" + t.datetime "last_reminder" + t.integer "parent_id", default: 0 + t.bigint "questionnaire_id" + t.datetime "start_date" + t.text "type" + t.index ["questionnaire_id"], name: "fk_rails_7c62b6ef2b" end create_table "ta_mappings", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "course_id", null: false - t.bigint "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.bigint "user_id", null: false t.index ["course_id"], name: "index_ta_mappings_on_course_id" t.index ["user_id"], name: "fk_ta_mapping_users" t.index ["user_id"], name: "index_ta_mappings_on_user_id" end - create_table "teams", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "tag_prompt_deployments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.integer "answer_length_threshold" + t.bigint "assignment_id" + t.datetime "created_at", null: false + t.string "question_type" + t.bigint "questionnaire_id" + t.bigint "tag_prompt_id" + t.datetime "updated_at", null: false + t.index ["assignment_id"], name: "fk_rails_7a44de7225" + t.index ["questionnaire_id"], name: "fk_rails_c3b5a3cf6f" + t.index ["tag_prompt_id"], name: "fk_rails_fbf75bc17c" + end + + create_table "tag_prompts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "control_type" t.datetime "created_at", null: false + t.string "desc" + t.string "prompt" t.datetime "updated_at", null: false + end + + create_table "teams", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "comment_for_submission" + t.datetime "created_at", null: false + t.integer "directory_num" + t.integer "grade_for_submission" t.string "name", null: false - t.string "type", null: false t.integer "parent_id", null: false - t.integer "grade_for_submission" - t.string "comment_for_submission" t.text "submitted_hyperlinks" - t.integer "directory_num" + t.string "type", null: false + t.datetime "updated_at", null: false end create_table "teams_participants", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.bigint "team_id", null: false - t.integer "duty_id" t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "duty_id" t.bigint "participant_id", null: false + t.bigint "team_id", null: false + t.datetime "updated_at", null: false t.integer "user_id", null: false t.index ["participant_id"], name: "index_teams_participants_on_participant_id" t.index ["team_id"], name: "index_teams_participants_on_team_id" @@ -413,36 +571,63 @@ end create_table "teams_users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| - t.bigint "team_id", null: false - t.bigint "user_id", null: false t.datetime "created_at", null: false + t.bigint "team_id", null: false t.datetime "updated_at", null: false + t.bigint "user_id", null: false t.index ["team_id"], name: "index_teams_users_on_team_id" t.index ["user_id"], name: "index_teams_users_on_user_id" end - create_table "users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + create_table "topic_bids", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.datetime "created_at", null: false + t.integer "priority" + t.integer "team_id" + t.integer "topic_id" + t.datetime "updated_at", null: false + end + + create_table "track_notifications", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.datetime "created_at", null: false + t.integer "notification_id" + t.datetime "updated_at", null: false + t.integer "user_id" + end + + create_table "tree_folders", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.string "child_type" t.string "name" - t.string "password_digest" - t.string "full_name" + t.integer "parent_id" + end + + create_table "user_pastebins", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.datetime "created_at", null: false + t.text "long_form" + t.string "short_form" + t.datetime "updated_at", null: false + t.integer "user_id" + end + + create_table "users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| + t.boolean "copy_of_emails", default: false + t.datetime "created_at", null: false t.string "email" - t.string "mru_directory_path" - t.boolean "email_on_review", default: false t.boolean "email_on_submission", default: false - t.boolean "email_on_review_of_review", default: false - t.boolean "is_new_user", default: true - t.boolean "master_permission_granted", default: false - t.string "handle" - t.string "persistence_token" - t.string "timeZonePref" - t.boolean "copy_of_emails", default: false t.boolean "etc_icons_on_homepage", default: false - t.integer "locale" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "handle" t.bigint "institution_id" - t.bigint "role_id", null: false + t.boolean "is_new_user", default: true + t.integer "locale" + t.string "name" t.bigint "parent_id" + t.string "password_digest" + t.text "password_salt" + t.boolean "private_by_default" + t.text "public_key" + t.bigint "role_id", null: false + t.string "time_zone_pref" + t.datetime "updated_at", null: false + t.string "username" t.index ["institution_id"], name: "index_users_on_institution_id" t.index ["parent_id"], name: "index_users_on_parent_id" t.index ["role_id"], name: "index_users_on_role_id" @@ -450,27 +635,40 @@ add_foreign_key "account_requests", "institutions" add_foreign_key "account_requests", "roles" + add_foreign_key "answer_tags", "answers" + add_foreign_key "answer_tags", "tag_prompt_deployments" + add_foreign_key "answer_tags", "users" add_foreign_key "assignments", "courses" add_foreign_key "assignments", "users", column: "instructor_id" add_foreign_key "assignments_duties", "assignments" add_foreign_key "assignments_duties", "duties" add_foreign_key "courses", "institutions" add_foreign_key "courses", "users", column: "instructor_id" + add_foreign_key "duties", "users", column: "instructor_id" add_foreign_key "invitations", "participants", column: "from_id" add_foreign_key "invitations", "participants", column: "to_id" - add_foreign_key "duties", "users", column: "instructor_id" add_foreign_key "items", "questionnaires" - add_foreign_key "participants", "duties" + add_foreign_key "late_policies", "users", column: "instructor_id" add_foreign_key "participants", "join_team_requests" add_foreign_key "participants", "teams" add_foreign_key "participants", "users" add_foreign_key "project_topics", "assignments" - add_foreign_key "question_advices", "items", column: "question_id" + add_foreign_key "question_advice", "items", column: "question_id" + add_foreign_key "resubmission_times", "participants" + add_foreign_key "review_bids", "assignments" + add_foreign_key "review_bids", "participants" + add_foreign_key "review_bids", "users" + add_foreign_key "review_comment_paste_bins", "review_grades" + add_foreign_key "review_grades", "participants" add_foreign_key "roles", "roles", column: "parent_id", on_delete: :cascade add_foreign_key "signed_up_teams", "project_topics" add_foreign_key "signed_up_teams", "teams" + add_foreign_key "survey_deployments", "questionnaires" add_foreign_key "ta_mappings", "courses" add_foreign_key "ta_mappings", "users" + add_foreign_key "tag_prompt_deployments", "assignments" + add_foreign_key "tag_prompt_deployments", "questionnaires" + add_foreign_key "tag_prompt_deployments", "tag_prompts" add_foreign_key "teams_participants", "participants" add_foreign_key "teams_participants", "teams" add_foreign_key "teams_users", "teams" diff --git a/db/seeds.rb b/db/seeds.rb index d49c80f33..2b19e2187 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -14,7 +14,7 @@ # Create an admin user User.create!( - name: 'admin', + username: 'admin', email: 'admin2@example.com', password: 'password123', full_name: 'admin admin', @@ -33,7 +33,7 @@ instructor_user_ids = [] num_instructors.times do instructor_user_ids << User.create( - name: Faker::Internet.unique.username, + username: Faker::Internet.unique.username, email: Faker::Internet.unique.email, password: "password", full_name: Faker::Name.name, @@ -51,7 +51,7 @@ directory_path: Faker::File.dir(segment_count: 2), name: Faker::Company.industry, info: "A fake class", - private: false + is_private: false ).id end @@ -80,7 +80,7 @@ student_user_ids = [] num_students.times do student_user_ids << User.create( - name: Faker::Internet.unique.username, + username: Faker::Internet.unique.username, email: Faker::Internet.unique.email, password: "password", full_name: Faker::Name.name, diff --git a/docker-compose.yml b/docker-compose.yml index f22dc27ef..2413a65fd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: command: tail -f /dev/null environment: RAILS_ENV: development - DATABASE_URL: mysql2://root:expertiza@db:3306/reimplementation? + DATABASE_URL: mysql2://root:expertiza@db:3306/reimplementation CACHE_STORE: redis://redis:6380/0 ports: - "3002:3002" diff --git a/spec/factories/courses.rb b/spec/factories/courses.rb index f51991f02..87a48ff40 100644 --- a/spec/factories/courses.rb +++ b/spec/factories/courses.rb @@ -4,7 +4,7 @@ factory :course do name { Faker::Educator.course_name } info { Faker::Lorem.paragraph } - private { false } + is_private { false } directory_path { Faker::File.dir } association :institution, factory: :institution association :instructor, factory: :user diff --git a/spec/models/assignment_spec.rb b/spec/models/assignment_spec.rb index 93badf826..81aed71e2 100644 --- a/spec/models/assignment_spec.rb +++ b/spec/models/assignment_spec.rb @@ -12,16 +12,18 @@ include RolesHelper before(:all) { @roles = create_roles_hierarchy } # Create the full roles hierarchy once for creating the instructor role later let(:institution) { Institution.create!(name: "NC State") } # All users belong to the same institution to satisfy foreign key constraints. - let(:instructor) { User.create!(name: "instructor", full_name: "Instructor User", email: "instructor@example.com", password_digest: "password", role_id: @roles[:instructor].id, institution_id: institution.id) } + let(:instructor) { User.create!(name: "instructor", full_name: "Instructor User", email: "instructor@example.com", password: "password", role_id: @roles[:instructor].id, institution_id: institution.id) } describe '#num_review_rounds' do it 'counts review due dates to determine the number of rounds' do assignment = Assignment.create!(name: 'Round Count', instructor: instructor, vary_by_round: true) - AssignmentDueDate.create!(parent: assignment, due_at: 1.day.from_now, + AssignmentDueDate.create!(assignment: assignment, due_at: 1.day.from_now, deadline_type_id: DueDate::REVIEW_DEADLINE_TYPE_ID, + parent_type: 'Assignment', submission_allowed_id: 3, review_allowed_id: 3) - AssignmentDueDate.create!(parent: assignment, due_at: 2.days.from_now, + AssignmentDueDate.create!(assignment: assignment, due_at: 2.days.from_now, deadline_type_id: DueDate::REVIEW_DEADLINE_TYPE_ID, + parent_type: 'Assignment', submission_allowed_id: 3, review_allowed_id: 3) expect(assignment.num_review_rounds).to eq(2) @@ -29,10 +31,10 @@ it 'ignores non-review deadlines when counting rounds' do assignment = Assignment.create!(name: 'Mixed Deadlines', instructor: instructor, vary_by_round: true) - AssignmentDueDate.create!(parent: assignment, due_at: 1.day.from_now, - deadline_type_id: 99, + AssignmentDueDate.create!(assignment: assignment, due_at: 1.day.from_now, + deadline_type_id: 99, parent_type: 'Assignment', submission_allowed_id: 3, review_allowed_id: 3) - AssignmentDueDate.create!(parent: assignment, due_at: 2.days.from_now, + AssignmentDueDate.create!(assignment: assignment, due_at: 2.days.from_now, parent_type: 'Assignment', deadline_type_id: DueDate::REVIEW_DEADLINE_TYPE_ID, submission_allowed_id: 3, review_allowed_id: 3) diff --git a/spec/models/assignment_team_spec.rb b/spec/models/assignment_team_spec.rb index 50e03616f..d14453cdb 100644 --- a/spec/models/assignment_team_spec.rb +++ b/spec/models/assignment_team_spec.rb @@ -21,7 +21,7 @@ def create_student(suffix) name: suffix, email: "#{suffix}@example.com", full_name: suffix.split('_').map(&:capitalize).join(' '), - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -41,7 +41,7 @@ def create_student(suffix) name: "instructor", full_name: "Instructor User", email: "instructor@example.com", - password_digest: "password", + password: "password", role_id: @roles[:instructor].id, institution_id: institution.id ) @@ -52,7 +52,7 @@ def create_student(suffix) name: "team_owner", full_name: "Team Owner", email: "team_owner@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) diff --git a/spec/models/course_spec.rb b/spec/models/course_spec.rb index d80d8bd40..a194e5f24 100644 --- a/spec/models/course_spec.rb +++ b/spec/models/course_spec.rb @@ -4,10 +4,10 @@ describe Course, type: :model do let(:role) {Role.create(name: 'Instructor', parent_id: nil, id: 2, default_page_id: nil)} - let(:instructor) { Instructor.create(name: 'testinstructor', email: 'test@test.com', full_name: 'Test Instructor', password: '123456', role_id: role.id) } + let(:instructor) { Instructor.create(username: 'testinstructor', email: 'test@test.com', full_name: 'Test Instructor', password: '123456', role_id: role.id) } let(:institution) { create(:institution, id: 1) } let(:course) { create(:course, id: 1, name: 'ECE517', instructor: instructor, institution: institution) } - let(:user1) { create(:user, name: 'abcdef', full_name:'abc bbc', email: 'abcbbc@gmail.com', password: '123456789', password_confirmation: '123456789', role: role) } + let(:user1) { create(:user, username: 'abcdef', full_name: 'abc bbc', email: 'abcbbc@gmail.com', password: '123456789', password_confirmation: '123456789', role: role) } describe 'validations' do it 'validates presence of name' do diff --git a/spec/models/course_team_spec.rb b/spec/models/course_team_spec.rb index 2eda015ac..987a5e9d1 100644 --- a/spec/models/course_team_spec.rb +++ b/spec/models/course_team_spec.rb @@ -21,7 +21,7 @@ def create_student(suffix) name: suffix, email: "#{suffix}@example.com", full_name: suffix.split('_').map(&:capitalize).join(' '), - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -41,7 +41,7 @@ def create_student(suffix) name: "instructor", full_name: "Instructor User", email: "instructor@example.com", - password_digest: "password", + password: "password", role_id: @roles[:instructor].id, institution_id: institution.id ) @@ -52,7 +52,7 @@ def create_student(suffix) name: "team_owner", full_name: "Team Owner", email: "team_owner@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) diff --git a/spec/models/due_date_spec.rb b/spec/models/due_date_spec.rb index 039fc881c..1cc343f05 100644 --- a/spec/models/due_date_spec.rb +++ b/spec/models/due_date_spec.rb @@ -11,18 +11,18 @@ let(:assignment) { Assignment.create(id: 1, name: 'Test Assignment', instructor:) } it 'fetches all the due_dates from a due_date\'s parent' do - due_date1 = DueDate.create(parent: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date2 = DueDate.create(parent: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date3 = DueDate.create(parent: assignment, due_at: 4.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date4 = DueDate.create(parent: assignment, due_at: 2.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date5 = DueDate.create(parent: assignment, due_at: 3.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) + due_date1 = DueDate.create(assignment: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date2 = DueDate.create(assignment: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date3 = DueDate.create(assignment: assignment, due_at: 4.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date4 = DueDate.create(assignment: assignment, due_at: 2.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date5 = DueDate.create(assignment: assignment, due_at: 3.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') due_dates = [due_date1, due_date2, due_date3, due_date4, due_date5] - fetched_due_dates = DueDate.fetch_due_dates(due_date3.parent_id) + fetched_due_dates = DueDate.fetch_due_dates(due_date3.assignment_id) fetched_due_dates.each { |due_date| expect(due_dates).to include(due_date) } end @@ -31,16 +31,16 @@ describe '.sort_due_dates' do let(:assignment) { Assignment.create(id: 1, name: 'Test Assignment', instructor:) } it 'sorts a list of due dates from earliest to latest' do - due_date1 = DueDate.create(parent: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date2 = DueDate.create(parent: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date3 = DueDate.create(parent: assignment, due_at: 4.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date4 = DueDate.create(parent: assignment, due_at: 2.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date5 = DueDate.create(parent: assignment, due_at: 3.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) + due_date1 = DueDate.create(assignment: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date2 = DueDate.create(assignment: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date3 = DueDate.create(assignment: assignment, due_at: 4.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date4 = DueDate.create(assignment: assignment, due_at: 2.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date5 = DueDate.create(assignment: assignment, due_at: 3.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') sorted_dates = DueDate.sort_due_dates([due_date1, due_date2, due_date3, due_date4, due_date5]) expect(sorted_dates).to eq([due_date5, due_date4, due_date1, due_date2, due_date3]) @@ -50,23 +50,23 @@ describe '.any_future_due_dates?' do let(:assignment) { Assignment.create(id: 1, name: 'Test Assignment', instructor:) } it 'returns true when a future due date exists' do - due_date1 = DueDate.create(parent: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date2 = DueDate.create(parent: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date3 = DueDate.create(parent: assignment, due_at: 4.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) + due_date1 = DueDate.create(assignment: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date2 = DueDate.create(assignment: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date3 = DueDate.create(assignment: assignment, due_at: 4.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') due_dates = [due_date1, due_date2, due_date3] expect(DueDate.any_future_due_dates?(due_dates)).to(be true) end it 'returns true when a no future due dates exist' do - due_date1 = DueDate.create(parent: assignment, due_at: 2.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date2 = DueDate.create(parent: assignment, due_at: 3.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date3 = DueDate.create(parent: assignment, due_at: 4.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) + due_date1 = DueDate.create(assignment: assignment, due_at: 2.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date2 = DueDate.create(assignment: assignment, due_at: 3.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date3 = DueDate.create(assignment: assignment, due_at: 4.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') due_dates = [due_date1, due_date2, due_date3] expect(DueDate.any_future_due_dates?(due_dates)).to(be false) end @@ -76,16 +76,16 @@ let(:assignment) { Assignment.create(id: 1, name: 'Test Assignment', instructor:) } let(:assignment2) { Assignment.create(id: 2, name: 'Test Assignment2', instructor:) } it 'returns true when a future due date exists' do - due_date = DueDate.create(parent: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) + due_date = DueDate.create(assignment: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') expect(due_date.deadline_type_id).to(be 3) - expect(due_date.parent).to(be assignment) + expect(due_date.parent).to eq(assignment) expect(due_date.round).to(be nil) due_date.set(1, assignment2.id, 1) expect(due_date.deadline_type_id).to(be 1) - expect(due_date.parent).to eq(assignment2) + expect(due_date.assignment).to eq(assignment2) expect(due_date.round).to(be 1) end end @@ -94,18 +94,19 @@ let(:assignment) { Assignment.create(id: 1, name: 'Test Assignment', instructor:) } let(:assignment2) { Assignment.create(id: 2, name: 'Test Assignment2', instructor:) } it 'copies the due dates from one assignment to another' do - due_date1 = DueDate.create(parent: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date2 = DueDate.create(parent: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) - due_date3 = DueDate.create(parent: assignment, due_at: 3.days.ago, submission_allowed_id: 3, - review_allowed_id: 3, deadline_type_id: 3) + due_date1 = DueDate.create(assignment: assignment, due_at: 2.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date2 = DueDate.create(assignment: assignment, due_at: 3.days.from_now, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') + due_date3 = DueDate.create(assignment: assignment, due_at: 3.days.ago, submission_allowed_id: 3, + review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') assign1_due_dates = DueDate.fetch_due_dates(assignment.id) assign1_due_dates.each { |due_date| due_date.copy(assignment2.id) } assign2_due_dates = DueDate.fetch_due_dates(assignment2.id) - excluded_attributes = %w[id created_at updated_at parent parent_id] + # Add 'assignment_id' to the list of ignored keys + excluded_attributes = %w[id created_at updated_at parent parent_id assignment_id] assign1_due_dates.zip(assign2_due_dates).each do |original, copy| original_attributes = original.attributes.except(*excluded_attributes) @@ -120,16 +121,16 @@ context 'when parent_type is Assignment' do let(:assignment) { Assignment.create(id: 1, name: 'Test Assignment', instructor:) } let!(:assignment_due_date1) do - DueDate.create(parent: assignment, due_at: 2.days.from_now, - submission_allowed_id: 3, review_allowed_id: 3, deadline_type_id: 3) + DueDate.create(assignment: assignment, due_at: 2.days.from_now, + submission_allowed_id: 3, review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') end let!(:assignment_due_date2) do - DueDate.create(parent: assignment, due_at: 3.days.from_now, - submission_allowed_id: 3, review_allowed_id: 3, deadline_type_id: 3) + DueDate.create(assignment: assignment, due_at: 3.days.from_now, + submission_allowed_id: 3, review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') end let!(:assignment_past_due_date) do - DueDate.create(parent: assignment, due_at: 1.day.ago, - submission_allowed_id: 3, review_allowed_id: 3, deadline_type_id: 3) + DueDate.create(assignment: assignment, due_at: 1.day.ago, + submission_allowed_id: 3, review_allowed_id: 3, deadline_type_id: 3, parent_type: 'Assignment') end it 'returns the next upcoming due date' do @@ -146,23 +147,23 @@ let!(:topic3) { ProjectTopic.create(id: 5, topic_name: 'Test Topic2', assignment: assignment2) } let!(:topic_due_date1) do DueDate.create(parent: topic1, due_at: 2.days.from_now, submission_allowed_id: 3, review_allowed_id: 3, - deadline_type_id: 3, type: 'TopicDueDate') + deadline_type_id: 3, parent_type: 'ProjectTopic') end let!(:topic_due_date2) do DueDate.create(parent: topic1, due_at: 3.days.from_now, submission_allowed_id: 3, review_allowed_id: 3, - deadline_type_id: 3, type: 'TopicDueDate') + deadline_type_id: 3, parent_type: 'ProjectTopic') end let!(:past_topic_due_date) do DueDate.create(parent: topic1, due_at: 1.day.ago, submission_allowed_id: 3, review_allowed_id: 3, - deadline_type_id: 3, type: 'TopicDueDate') + deadline_type_id: 3, parent_type: 'ProjectTopic') end let!(:past_topic_due_date2) do DueDate.create(parent: topic2, due_at: 2.day.ago, submission_allowed_id: 3, review_allowed_id: 3, - deadline_type_id: 3, type: 'TopicDueDate') + deadline_type_id: 3, parent_type: 'ProjectTopic') end let!(:assignment_due_date) do - DueDate.create(parent: assignment2, due_at: 2.days.from_now, submission_allowed_id: 3, review_allowed_id: 3, - deadline_type_id: 3, type: 'AssignmentDueDate') + DueDate.create(assignment: assignment2, due_at: 2.days.from_now, submission_allowed_id: 3, review_allowed_id: 3, + deadline_type_id: 3, parent_type: 'Assignment') end it 'calls TopicDueDate.next_due_date' do diff --git a/spec/models/invitation_spec.rb b/spec/models/invitation_spec.rb index 20521fe3b..1c7a25faf 100644 --- a/spec/models/invitation_spec.rb +++ b/spec/models/invitation_spec.rb @@ -9,12 +9,12 @@ let(:instructor) { create(:user, role_id: @roles[:instructor].id, name: "profa", full_name: "Prof A", email: "profa@example.com")} let(:user1) do - User.create!( name: "student", password_digest: "password",role_id: @roles[:student].id, full_name: "Student Name",email: "student@example.com") + User.create!( name: "student", password: "password",role_id: @roles[:student].id, full_name: "Student Name",email: "student@example.com") end let(:user2) do User.create!( - name: "student2", password_digest: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com") + name: "student2", password: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com") end let(:assignment) { Assignment.create!(name: "Test Assignment", instructor_id: instructor.id, max_team_size: 4) } let(:team1) { AssignmentTeam.create!(name: "Team1", parent_id: assignment.id) } diff --git a/spec/models/mentored_team_spec.rb b/spec/models/mentored_team_spec.rb index 5d95b50c3..c68335b64 100644 --- a/spec/models/mentored_team_spec.rb +++ b/spec/models/mentored_team_spec.rb @@ -19,7 +19,7 @@ # name: suffix, # email: "#{suffix}@example.com", # full_name: suffix.split('_').map(&:capitalize).join(' '), -# password_digest: "password", +# password: "password", # role_id: roles[:student].id, # institution_id: institution.id # ) @@ -39,7 +39,7 @@ # name: "instructor", # full_name: "Instructor User", # email: "instructor@example.com", -# password_digest: "password", +# password: "password", # role_id: roles[:instructor].id, # institution_id: institution.id # ) @@ -50,7 +50,7 @@ # name: "team_owner", # full_name: "Team Owner", # email: "team_owner@example.com", -# password_digest: "password", +# password: "password", # role_id: roles[:student].id, # institution_id: institution.id # ) @@ -66,7 +66,7 @@ # name: "mentor_user", # full_name: "Mentor User", # email: "mentor@example.com", -# password_digest: "password", +# password: "password", # role_id: mentor_role.id, # institution_id: institution.id # ) @@ -85,7 +85,7 @@ # name: "student_user", # full_name: "Student User", # email: "student@example.com", -# password_digest: "password", +# password: "password", # role_id: roles[:student].id, # institution_id: institution.id # ) diff --git a/spec/models/response_spec.rb b/spec/models/response_spec.rb index 976128828..13eb8e2bf 100644 --- a/spec/models/response_spec.rb +++ b/spec/models/response_spec.rb @@ -13,10 +13,10 @@ let(:item) { ScoredItem.new(weight: 2) } let(:answer) { Answer.new(answer: 1, comments: 'Answer text', item:item) } let(:questionnaire) { Questionnaire.new(items: [item], min_question_score: 0, max_question_score: 5) } - let(:assignment_questionnaire) { AssignmentQuestionnaire.create!(assignment: assignment, questionnaire: questionnaire, used_in_round: 1, notification_limit: 5.0)} + let(:assignment_questionnaire) { AssignmentQuestionnaire.create!(assignment: assignment, questionnaire: questionnaire, used_in_round: 1, notification_threshold: 5.0)} let(:review_response_map) { ReviewResponseMap.new(assignment: assignment, reviewee: team, reviewer: participant2) } let(:response_map) { ResponseMap.new(assignment: assignment, reviewee: participant, reviewer: participant2) } - let(:response) { Response.new(map_id: review_response_map.id, response_map: review_response_map, round:1, scores: [answer]) } + let(:response) { Response.new(response_map_id: review_response_map.id, response_map: review_response_map, round:1, scores: [answer]) } # Compare the current response score with other scores on the same artifact, and test if the difference is significant enough to notify # instructor. @@ -38,7 +38,7 @@ allow(response).to receive(:maximum_score).and_return(100) allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire) allow(AssignmentQuestionnaire).to receive(:find_by).with(assignment_id: assignment.id, questionnaire_id: questionnaire.id) - .and_return(double('AssignmentQuestionnaire', notification_limit: 5.0)) + .and_return(double('AssignmentQuestionnaire', notification_threshold: 5.0)) expect(response.reportable_difference?).to be true end end diff --git a/spec/models/scale_spec.rb b/spec/models/scale_spec.rb index 0b382452c..440656e7b 100644 --- a/spec/models/scale_spec.rb +++ b/spec/models/scale_spec.rb @@ -8,7 +8,7 @@ before do subject.txt = "Rate your experience" - subject.type = "Scale" + subject.question_type = "Scale" subject.weight = 1 subject.min_label = "Poor" subject.max_label = "Excellent" @@ -20,7 +20,7 @@ describe "#edit" do it 'returns a JSON object with item text, type, weight, and score range' do - scale = Scale.new(txt: 'Scale Item', type: 'scale', weight: 2, min_question_score: 0, max_question_score: 10) + scale = Scale.new(txt: 'Scale Item', question_type: 'scale', weight: 2, min_question_score: 0, max_question_score: 10) json_result = scale.edit diff --git a/spec/models/student_task_spec.rb b/spec/models/student_task_spec.rb index 94b9e7ffc..95fc39cad 100644 --- a/spec/models/student_task_spec.rb +++ b/spec/models/student_task_spec.rb @@ -10,8 +10,7 @@ assignment: @assignment, topic: "E2442", current_stage: "finished", - stage_deadline: "2024-04-23", - permission_granted: true + stage_deadline: "2024-04-23" ) end @@ -23,8 +22,7 @@ current_stage: "finished", participant: @participant, stage_deadline: "2024-04-23", - topic: "E2442", - permission_granted: false + topic: "E2442" } student_task = StudentTask.new(args) @@ -34,7 +32,6 @@ expect(student_task.participant).to eq(@participant) expect(student_task.stage_deadline).to eq("2024-04-23") expect(student_task.topic).to eq("E2442") - expect(student_task.permission_granted).to be false end end @@ -47,7 +44,6 @@ expect(student_task.topic).to eq(@participant.topic) expect(student_task.current_stage).to eq(@participant.current_stage) expect(student_task.stage_deadline).to eq(Time.parse(@participant.stage_deadline)) - expect(student_task.permission_granted).to be @participant.permission_granted expect(student_task.participant).to be @participant end end diff --git a/spec/models/team_spec.rb b/spec/models/team_spec.rb index fe55ac3c1..6f91ec767 100644 --- a/spec/models/team_spec.rb +++ b/spec/models/team_spec.rb @@ -25,7 +25,7 @@ def create_student(suffix) name: suffix, email: "#{suffix}@example.com", full_name: suffix.split('_').map(&:capitalize).join(' '), - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -45,7 +45,7 @@ def create_student(suffix) name: "instructor", full_name: "Instructor User", email: "instructor@example.com", - password_digest: "password", + password: "password", role_id: @roles[:instructor].id, institution_id: institution.id ) @@ -56,7 +56,7 @@ def create_student(suffix) name: "team_owner", full_name: "Team Owner", email: "team_owner@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) diff --git a/spec/models/teams_participant_spec.rb b/spec/models/teams_participant_spec.rb index c9a711e4d..bec643410 100644 --- a/spec/models/teams_participant_spec.rb +++ b/spec/models/teams_participant_spec.rb @@ -18,7 +18,7 @@ def create_student(suffix) name: suffix, email: "#{suffix}@example.com", full_name: suffix.split('_').map(&:capitalize).join(' '), - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -36,7 +36,7 @@ def create_student(suffix) name: "instructor", full_name: "Instructor User", email: "instructor@example.com", - password_digest: "password", + password: "password", role_id: @roles[:instructor].id, institution_id: institution.id ) diff --git a/spec/requests/api/v1/account_requests_spec.rb b/spec/requests/api/v1/account_requests_spec.rb index ee355a685..e5f370364 100644 --- a/spec/requests/api/v1/account_requests_spec.rb +++ b/spec/requests/api/v1/account_requests_spec.rb @@ -10,12 +10,11 @@ let(:prof) { User.create( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } diff --git a/spec/requests/api/v1/assignment_controller_spec.rb b/spec/requests/api/v1/assignment_controller_spec.rb index 6b64f4270..2bd228c03 100644 --- a/spec/requests/api/v1/assignment_controller_spec.rb +++ b/spec/requests/api/v1/assignment_controller_spec.rb @@ -26,7 +26,7 @@ name: "admin", full_name: "admin", email: "admin@gmail.com", - password_digest: "admin", + password: "password", role_id: 2, # Must exist in DB institution_id: institution.id ) @@ -34,12 +34,11 @@ let!(:prof) do User.create!( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser" ) end diff --git a/spec/requests/api/v1/bookmarks_controller_spec.rb b/spec/requests/api/v1/bookmarks_controller_spec.rb index 861891aee..f4900fa43 100644 --- a/spec/requests/api/v1/bookmarks_controller_spec.rb +++ b/spec/requests/api/v1/bookmarks_controller_spec.rb @@ -9,19 +9,18 @@ @roles = create_roles_hierarchy end - let(:student) { + let!(:student) { User.create( - name: "studenta", - password_digest: "password", + username: "studenta", + password: "password", role_id: @roles[:student].id, full_name: "student A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } - let(:token) { JsonWebToken.encode({ id: student.id }) } - let(:Authorization) { "Bearer #{token}" } + let!(:token) { JsonWebToken.encode({ id: student.id }) } + let!(:Authorization) { "Bearer #{token}" } path '/bookmarks' do # Creation of dummy objects for the test with the help of let statements @@ -220,7 +219,7 @@ path '/bookmarks/{id}/bookmarkratings' do parameter name: 'id', in: :path, type: :integer - let(:bookmark) do + let!(:bookmark) do student Bookmark.create( url: 'http://example.com', @@ -249,7 +248,7 @@ response(200, 'successful') do let(:rating) { { rating: 4 } } run_test! do - expect(response.body).to include('"rating":4') + expect(response.body).to include('"ratings":4') end end end @@ -260,10 +259,10 @@ response(200, 'successful') do before do - BookmarkRating.create(bookmark_id: bookmark.id, user_id: student.id, rating: 5) + BookmarkRating.create!(artifact_id: bookmark.id, rater_id: student.id, ratings: 5) end run_test! do - expect(response.body).to include('"rating":5') + expect(response.body).to include('"ratings":5') end end diff --git a/spec/requests/api/v1/courses_spec.rb b/spec/requests/api/v1/courses_spec.rb index 241231b43..ae2ad9d2d 100644 --- a/spec/requests/api/v1/courses_spec.rb +++ b/spec/requests/api/v1/courses_spec.rb @@ -10,12 +10,11 @@ let(:prof) { User.create( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } @@ -29,12 +28,11 @@ let(:institution) { Institution.create(name: "NC State") } let(:ta) { User.create( - name: "taa", - password_digest: "password", + username: "taa", + password: "password", role_id: @roles[:ta].id, full_name: "TA A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } let(:course) { @@ -109,12 +107,11 @@ let(:id) { course.id } let(:ta) { User.create( - name: "taa", - password_digest: "password", + username: "taa", + password: "password", role_id: @roles[:ta].id, full_name: "TA A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } let(:ta_id) { ta.id } diff --git a/spec/requests/api/v1/grades_controller_get_review_tableau_data_spec.rb b/spec/requests/api/v1/grades_controller_get_review_tableau_data_spec.rb index f96e86a1e..e7eb2d883 100644 --- a/spec/requests/api/v1/grades_controller_get_review_tableau_data_spec.rb +++ b/spec/requests/api/v1/grades_controller_get_review_tableau_data_spec.rb @@ -82,7 +82,7 @@ fake_response_relation = double("ActiveRecord::Relation") allow(fake_response_relation).to receive(:find_each).and_yield(fake_response) allow(Response).to receive(:where) - .with("map_id = #{fake_response_map[:id]}") + .with("response_map_id = #{fake_response_map[:id]}") .and_return(fake_response_relation) # Stub Answer.find_by(...) diff --git a/spec/requests/api/v1/grades_controller_spec.rb b/spec/requests/api/v1/grades_controller_spec.rb index e78a3ffdf..6fa07ef03 100644 --- a/spec/requests/api/v1/grades_controller_spec.rb +++ b/spec/requests/api/v1/grades_controller_spec.rb @@ -8,8 +8,8 @@ let(:instructor) do User.create!( - name: "instructor", - password_digest: "password", + username: "instructor", + password: "password", role_id: @roles[:instructor].id, full_name: "Instructor Name", email: "instructor@example.com" @@ -18,8 +18,8 @@ let(:ta) do User.create!( - name: "ta", - password_digest: "password", + username: "ta", + password: "password", role_id: @roles[:ta].id, full_name: "Teaching Assistant", email: "ta@example.com" @@ -28,8 +28,8 @@ let(:student) do User.create!( - name: "student", - password_digest: "password", + username: "student", + password: "password", role_id: @roles[:student].id, full_name: "Student Name", email: "student@example.com" @@ -38,8 +38,8 @@ let(:student2) do User.create!( - name: "student2", - password_digest: "password", + username: "student2", + password: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com" @@ -350,7 +350,7 @@ run_test! do |response| data = JSON.parse(response.body) - expect(data).to have_key('map_id') + expect(data).to have_key('response_map_id') expect(data).to have_key('response_id') expect(data).to have_key('redirect_to') expect(data['redirect_to']).to include('/response/new/') if data['response_id'].nil? @@ -367,7 +367,7 @@ reviewer_id: reviewer.id, reviewee_id: team.id ) - Response.create!(map_id: mapping.id) + Response.create!(response_map_id: mapping.id) end run_test! do |response| diff --git a/spec/requests/api/v1/institution_spec.rb b/spec/requests/api/v1/institution_spec.rb index 6a3712c2a..0ed1daf05 100644 --- a/spec/requests/api/v1/institution_spec.rb +++ b/spec/requests/api/v1/institution_spec.rb @@ -8,12 +8,11 @@ end let(:prof) { User.create( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } let(:token) { JsonWebToken.encode({id: prof.id}) } diff --git a/spec/requests/api/v1/invitation_controller_spec.rb b/spec/requests/api/v1/invitation_controller_spec.rb index 3c532ac56..cd43b68f2 100644 --- a/spec/requests/api/v1/invitation_controller_spec.rb +++ b/spec/requests/api/v1/invitation_controller_spec.rb @@ -13,28 +13,28 @@ let(:ta) do User.create!( - name: "ta", - password_digest: "password", + username: "ta", + password: "password", role_id: @roles[:ta].id, full_name: "Teaching Assistant", email: "ta@example.com" ) end - let(:user1) do + let!(:user1) do User.create!( - name: "student", - password_digest: "password", + username: "student", + password: "password", role_id: @roles[:student].id, full_name: "Student Name", email: "student@example.com" ) end - let(:user2) do + let!(:user2) do User.create!( - name: "student2", - password_digest: "password", + username: "student2", + password: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com" @@ -44,7 +44,7 @@ let(:prof) { create(:user, role_id: @roles[:instructor].id, - name: "profa", + username: "profa", full_name: "Prof A", email: "profa@example.com") } @@ -133,7 +133,7 @@ let(:invitation) { { assignment_id: assignment.id, - username: user2.name + username: user2.username } } @@ -163,7 +163,7 @@ let(:invitation) { { assignment_id: assignment.id, - username: non_participant_user.name + username: non_participant_user.username } } diff --git a/spec/requests/api/v1/participants_controller_spec.rb b/spec/requests/api/v1/participants_controller_spec.rb index 835a444c6..67a3d9e7c 100644 --- a/spec/requests/api/v1/participants_controller_spec.rb +++ b/spec/requests/api/v1/participants_controller_spec.rb @@ -10,8 +10,8 @@ let(:studenta) do User.create!( - name: "studenta", - password_digest: "password", + username: "studenta", + password: "password", role_id: @roles[:student].id, full_name: "Student A", email: "testuser@example.com" @@ -20,8 +20,8 @@ let(:studentb) do User.create!( - name: "studentb", - password_digest: "password", + username: "studentb", + password: "password", role_id: @roles[:student].id, full_name: "Student B", email: "testuser@example.com" @@ -30,8 +30,8 @@ let!(:instructor) do User.create!( - name: "Instructor", - password_digest: "password", + username: "Instructor", + password: "password", role_id: @roles[:instructor].id, full_name: "Instructor Name", email: "instructor@example.com" diff --git a/spec/requests/api/v1/project_topic_controller_spec.rb b/spec/requests/api/v1/project_topic_controller_spec.rb index a0948789a..58f569053 100644 --- a/spec/requests/api/v1/project_topic_controller_spec.rb +++ b/spec/requests/api/v1/project_topic_controller_spec.rb @@ -9,7 +9,7 @@ let!(:instructor) do User.create!( name: "Instructor", - password_digest: "password", + password: "password", role_id: @roles[:instructor].id, full_name: "Instructor Name", email: "instructor@example.com" diff --git a/spec/requests/api/v1/questionnaires_controller_spec.rb b/spec/requests/api/v1/questionnaires_controller_spec.rb index 046efd83e..f3707824a 100644 --- a/spec/requests/api/v1/questionnaires_controller_spec.rb +++ b/spec/requests/api/v1/questionnaires_controller_spec.rb @@ -12,12 +12,11 @@ let(:prof) { User.create!( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } diff --git a/spec/requests/api/v1/questions_spec.rb b/spec/requests/api/v1/questions_spec.rb index 7137d1e08..f8912f899 100644 --- a/spec/requests/api/v1/questions_spec.rb +++ b/spec/requests/api/v1/questions_spec.rb @@ -9,12 +9,11 @@ end let(:instructor) { User.create( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } let!(:questionnaire) do diff --git a/spec/requests/api/v1/roles_spec.rb b/spec/requests/api/v1/roles_spec.rb index 434de6a41..424166b0f 100644 --- a/spec/requests/api/v1/roles_spec.rb +++ b/spec/requests/api/v1/roles_spec.rb @@ -10,12 +10,11 @@ let(:adm) { User.create( - name: "adma", - password_digest: "password", + username: "adma", + password: "password", role_id: @roles[:admin].id, full_name: "Admin A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", ) } @@ -70,9 +69,6 @@ let(:role) { { name: '' } } after do |example| - puts "Response status: #{response.status}" if response - puts "Response body: #{response.body}" if response&.body - example.metadata[:response][:content] = { 'application/json' => { example: JSON.parse(response.body, symbolize_names: true) @@ -175,8 +171,6 @@ let(:id) { Role.create(name: 'Test Role').id } after do |example| - puts "Response status: #{response.status}" if response - puts "Response body: #{response.body}" if response&.body example.metadata[:response][:content] = { 'application/json' => { example: JSON.parse(response.body, symbolize_names: true) diff --git a/spec/requests/api/v1/student_tasks_controller_spec.rb b/spec/requests/api/v1/student_tasks_controller_spec.rb index 481f7b5d1..5d53d91ca 100644 --- a/spec/requests/api/v1/student_tasks_controller_spec.rb +++ b/spec/requests/api/v1/student_tasks_controller_spec.rb @@ -10,8 +10,8 @@ let!(:instructor) do User.create!( - name: "Instructor", - password_digest: "password", + username: "Instructor", + password: "password", role_id: @roles[:instructor].id, full_name: "Instructor Name", email: "instructor@example.com" @@ -20,8 +20,8 @@ let(:studenta) do User.create!( - name: "studenta", - password_digest: "password", + username: "studenta", + password: "password", role_id: @roles[:student].id, full_name: "Student A", email: "testuser@example.com" @@ -60,7 +60,6 @@ user_id: studenta.id, parent_id: assignment.id, handle: studenta.name, - permission_granted: [true, false].sample, # store “stage” and “deadline” fields as your Participant model expects # e.g. might be: topic: "Topic #{i}", @@ -83,7 +82,6 @@ expect(task['current_stage']).to be_a(String) expect(task['stage_deadline']).to be_a(String) expect(task['topic']).to be_a(String) - expect(task['permission_granted']).to be_in([true, false]) end end end @@ -121,7 +119,6 @@ current_stage: "Review", stage_deadline: (Time.now + 7.days).to_s, topic: "Topic XYZ", - permission_granted: true ) end @@ -134,7 +131,6 @@ expect(data['current_stage']).to eq("Review") expect(data['stage_deadline']).to be_a(String) # e.g. "YYYY-MM-DD..." expect(data['topic']).to eq("Topic XYZ") - expect(data['permission_granted']).to be true end end diff --git a/spec/requests/api/v1/student_teams_controller_spec.rb b/spec/requests/api/v1/student_teams_controller_spec.rb index 185cfa8d7..b85fe1bd7 100644 --- a/spec/requests/api/v1/student_teams_controller_spec.rb +++ b/spec/requests/api/v1/student_teams_controller_spec.rb @@ -12,8 +12,8 @@ # let(:student_user) { User.create!( - name: "student1", - password_digest: "password", + username: "student1", + password: "password", role_id: @roles[:student].id, full_name: "Student One", email: "student1@example.com" @@ -22,8 +22,8 @@ let(:student_user2) { User.create!( - name: "student2", - password_digest: "password", + username: "student2", + password: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com" @@ -32,8 +32,8 @@ let(:ta_user) { User.create!( - name: "ta123", - password_digest: "password", + username: "ta123", + password: "password", role_id: @roles[:ta].id, full_name: "Teaching Assistant", email: "ta@example.com" diff --git a/spec/requests/api/v1/submitted_content_spec.rb b/spec/requests/api/v1/submitted_content_spec.rb index bba7141f5..a18a07f22 100644 --- a/spec/requests/api/v1/submitted_content_spec.rb +++ b/spec/requests/api/v1/submitted_content_spec.rb @@ -63,12 +63,11 @@ def assignment_class let(:instructor) do User.create!( - name: 'profa', - password_digest: 'password', + username: 'profa', + password: 'password', role_id: @roles[:instructor].id, full_name: 'Prof A', email: 'testuser@example.com', - mru_directory_path: '/home/testuser', institution_id: institution.id ) end @@ -76,9 +75,9 @@ def assignment_class let(:student) do User.create!( full_name: 'Student Member', - name: 'student_member', + username: 'student_member', email: 'studentmember@example.com', - password_digest: 'password', + password: 'password', role_id: @roles[:student].id, institution_id: institution.id ) @@ -124,8 +123,7 @@ def create_submission_record(attrs = {}) content: '/path/to/file.txt', operation: 'Submit File', team_id: team.id, - user: student.name, - assignment_id: assignment.id + submitted_by: student.name }.merge(attrs)) end @@ -169,10 +167,9 @@ def create_submission_record(attrs = {}) content: { type: :string }, operation: { type: :string }, team_id: { type: :integer }, - user: { type: :string }, - assignment_id: { type: :integer } + submitted_by: { type: :string }, }, - required: %w[content team_id user assignment_id] + required: %w[content team_id submitted_by] } } } @@ -184,8 +181,7 @@ def create_submission_record(attrs = {}) content: 'http://example.com', operation: 'Submit Hyperlink', team_id: team.id, - user: student.name, - assignment_id: assignment.id + submitted_by: student.name, } } end @@ -217,7 +213,7 @@ def create_submission_record(attrs = {}) end run_test! do - expect(response).to have_http_status(:unprocessable_content) + expect(response).to have_http_status(:unprocessable_entity) end end end @@ -637,7 +633,6 @@ def create_submission_record(attrs = {}) send(method, '/submitted_content/submit_file', params: { id: id, uploaded_file: uploaded_file, unzip: true, current_folder: { name: '/' } }, headers: auth_headers_student.merge({ 'CONTENT_TYPE' => 'multipart/form-data' })) - puts "RESPONSE BODY: #{response.body}" expect(response).to have_http_status(:created) end end diff --git a/spec/requests/api/v1/teams_controller_spec.rb b/spec/requests/api/v1/teams_controller_spec.rb index 9c4e660d9..2d166c2ef 100644 --- a/spec/requests/api/v1/teams_controller_spec.rb +++ b/spec/requests/api/v1/teams_controller_spec.rb @@ -18,12 +18,11 @@ # An instructor user who will own assignments and courses. let(:instructor) do User.create!( - name: "profa", - password_digest: "password", + username: "profa", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", institution_id: institution.id ) end @@ -32,9 +31,9 @@ let(:user) do User.create!( full_name: "New Participant", - name: "NewParticipant", + username: "NewParticipant", email: "newparticipant@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -44,9 +43,9 @@ let(:other_user) do User.create!( full_name: "Student Member", - name: "student_member", + username: "student_member", email: "studentmember@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -69,10 +68,10 @@ let(:team_owner) do User.create!( - name: "team_owner", + username: "team_owner", full_name: "Team Owner", email: "team_owner@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) diff --git a/spec/requests/api/v1/teams_participants_controller_spec.rb b/spec/requests/api/v1/teams_participants_controller_spec.rb index 2b973f3a3..e40ca50f2 100644 --- a/spec/requests/api/v1/teams_participants_controller_spec.rb +++ b/spec/requests/api/v1/teams_participants_controller_spec.rb @@ -22,11 +22,10 @@ let(:instructor) do User.create!( name: "profa", - password_digest: "password", + password: "password", role_id: @roles[:instructor].id, full_name: "Prof A", email: "testuser@example.com", - mru_directory_path: "/home/testuser", institution_id: institution.id ) end @@ -37,7 +36,7 @@ full_name: "New Participant", name: "NewParticipant", email: "newparticipant@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -49,7 +48,7 @@ full_name: "Student Member", name: "student_member", email: "studentmember@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -77,7 +76,7 @@ name: "team_owner", full_name: "Team Owner", email: "team_owner@example.com", - password_digest: "password", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -190,7 +189,7 @@ full_name: "Other", name: "other", email: "other@example.com", - password_digest: "pw", + password: "password", role_id: @roles[:student].id, institution_id: institution.id ) @@ -324,7 +323,7 @@ # -- NOT FOUND: Participant record missing for given name -- response(404, 'participant not found') do let(:id) { team_with_assignment.id } - let!(:user_without_participant) { User.create!(full_name: "User Without Participant", name: "no_part", email: "no@example.com", password_digest: "pw", role_id: @roles[:student].id, institution_id: institution.id) } + let!(:user_without_participant) { User.create!(full_name: "User Without Participant", name: "no_part", email: "no@example.com", password: "password", role_id: @roles[:student].id, institution_id: institution.id) } let(:payload) { { name: user_without_participant.name } } run_test! do diff --git a/spec/validators/invitation_validator_spec.rb b/spec/validators/invitation_validator_spec.rb index 1ed2700e3..d7f35a791 100644 --- a/spec/validators/invitation_validator_spec.rb +++ b/spec/validators/invitation_validator_spec.rb @@ -8,11 +8,11 @@ let(:instructor) { create(:user, role_id: @roles[:instructor].id, name: "profa", full_name: "Prof A", email: "profa@example.com")} let(:user1) do - User.create!( name: "student", password_digest: "password",role_id: @roles[:student].id, full_name: "Student Name",email: "student@example.com") + User.create!( name: "student", password: "password",role_id: @roles[:student].id, full_name: "Student Name",email: "student@example.com") end let(:user2) do - User.create!( name: "student2", password_digest: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com") + User.create!( name: "student2", password: "password", role_id: @roles[:student].id, full_name: "Student Two", email: "student2@example.com") end let(:assignment) { Assignment.create!(name: "Test Assignment", instructor_id: instructor.id) } let(:team1) { AssignmentTeam.create!(name: "Team1", parent_id: assignment.id) }