diff --git a/app/models/assignment.rb b/app/models/assignment.rb
old mode 100644
new mode 100755
index efa0c457329..0dd2dbd1e61
--- a/app/models/assignment.rb
+++ b/app/models/assignment.rb
@@ -11,6 +11,7 @@ class Assignment < ApplicationRecord
include ReviewAssignment
include QuizAssignment
include AssignmentHelper
+ include DueDateMixIn
has_paper_trail
# When an assignment is created, it needs to
# be created as an instance of a subclass of the Assignment (model) class;
@@ -186,38 +187,6 @@ def path
path_text
end
- # Check whether review, metareview, etc.. is allowed
- # The permissions of TopicDueDate is the same as AssignmentDueDate.
- # Here, column is usually something like 'review_allowed_id'
- def check_condition(column, topic_id = nil)
- next_due_date = DueDate.get_next_due_date(id, topic_id)
- return false if next_due_date.nil?
-
- right_id = next_due_date.send column
- right = DeadlineRight.find(right_id)
- right && (right.name == 'OK' || right.name == 'Late')
- end
-
- # Determine if the next due date from now allows for submissions
- def submission_allowed(topic_id = nil)
- check_condition('submission_allowed_id', topic_id)
- end
-
- # Determine if the next due date from now allows to take the quizzes
- def quiz_allowed(topic_id = nil)
- check_condition('quiz_allowed_id', topic_id)
- end
-
- # Determine if the next due date from now allows for reviews
- def can_review(topic_id = nil)
- check_condition('review_allowed_id', topic_id)
- end
-
- # Determine if the next due date from now allows for metareviews
- def metareview_allowed(topic_id = nil)
- check_condition('review_of_review_allowed_id', topic_id)
- end
-
# Deletes all instances created as part of assignment and finally destroys itself.
def delete(force = nil)
begin
@@ -294,15 +263,6 @@ def create_node
node.save
end
- # if current stage is submission or review, find the round number
- # otherwise, return 0
- def number_of_current_round(topic_id)
- next_due_date = DueDate.get_next_due_date(id, topic_id)
- return 0 if next_due_date.nil?
-
- next_due_date.round ||= 0
- end
-
# For varying rubric feature
def current_stage_name(topic_id = nil)
if staggered_deadline?
@@ -323,17 +283,6 @@ def varying_rubrics_by_round?
AssignmentQuestionnaire.where(assignment_id: id, used_in_round: 2).size > 1
end
- def link_for_current_stage(topic_id = nil)
- return nil if staggered_and_no_topic?(topic_id)
-
- due_date = find_current_stage(topic_id)
- if due_date.nil? || (due_date == 'Finished') || due_date.is_a?(TopicDueDate)
- return nil
- end
-
- due_date.description_url
- end
-
def stage_deadline(topic_id = nil)
return 'Unknown' if staggered_and_no_topic?(topic_id)
@@ -341,22 +290,6 @@ def stage_deadline(topic_id = nil)
due_date.nil? || due_date == 'Finished' ? due_date : due_date.due_at.to_s
end
- def num_review_rounds
- due_dates = AssignmentDueDate.where(parent_id: id)
- rounds = 0
- due_dates.each do |due_date|
- rounds = due_date.round if due_date.round > rounds
- end
- rounds
- end
-
- def find_current_stage(topic_id = nil)
- next_due_date = DueDate.get_next_due_date(id, topic_id)
- return 'Finished' if next_due_date.nil?
-
- next_due_date
- end
-
# Zhewei: this method is almost the same as 'stage_deadline'
def current_stage(topic_id = nil)
return 'Unknown' if staggered_and_no_topic?(topic_id)
@@ -566,39 +499,6 @@ def self.export_fields(options)
fields
end
- def find_due_dates(type)
- due_dates.select { |due_date| due_date.deadline_type_id == DeadlineType.find_by(name: type).id }
- end
-
- # Method find_review_period is used in answer_helper.rb to get the start and end dates of a round
- def find_review_period(round)
- # If round is nil, it means the same questionnaire is used for every round. Thus, we return all periods.
- # If round is not nil, we return only the period of that round.
-
- submission_type = DeadlineType.find_by(name: 'submission').id
- review_type = DeadlineType.find_by(name: 'review').id
-
- due_dates = []
- due_dates += find_due_dates('submission')
- due_dates += find_due_dates('review')
- due_dates.sort_by!(&:id)
-
- start_dates = []
- end_dates = []
-
- if round.nil?
- round = 1
- while self.due_dates.exists?(round: round)
- start_dates << due_dates.select { |due_date| due_date.deadline_type_id == submission_type && due_date.round == round }.last
- end_dates << due_dates.select { |due_date| due_date.deadline_type_id == review_type && due_date.round == round }.last
- round += 1
- end
- else
- start_dates << due_dates.select { |due_date| due_date.deadline_type_id == submission_type && due_date.round == round }.last
- end_dates << due_dates.select { |due_date| due_date.deadline_type_id == review_type && due_date.round == round }.last
- end
- [start_dates, end_dates]
- end
# for program 1 like assignment, if same rubric is used in both rounds,
# the 'used_in_round' field in 'assignment_questionnaires' will be null,
diff --git a/app/views/sign_up_sheet/review_bids_others_work.html.erb b/app/views/sign_up_sheet/review_bids_others_work.html.erb
index bb6d95c3cfa..539406b588a 100644
--- a/app/views/sign_up_sheet/review_bids_others_work.html.erb
+++ b/app/views/sign_up_sheet/review_bids_others_work.html.erb
@@ -67,7 +67,7 @@
<% last_response_round = @latest_response.round %>
<%end%>
- <% current_round = @assignment.number_of_current_round(topic_id) %>
+ <% current_round = @assignment.number_of_current_round(@participant.user_id) %>
<%= link_to "View", {:controller => 'response', :action => 'view', :id => @latest_response.id} %>
diff --git a/app/views/student_review/list.html.erb b/app/views/student_review/list.html.erb
index ccd4a49c43c..28fa08f45f8 100755
--- a/app/views/student_review/list.html.erb
+++ b/app/views/student_review/list.html.erb
@@ -21,7 +21,7 @@
<%= render :partial => 'responses', :locals => {:mappings => @review_mappings, :title => 'Review'} %>
- <% if @assignment.staggered_deadline? or @assignment.number_of_current_round(@topic_id) == 1 or (@assignment.number_of_current_round(@topic_id) > 1 and @assignment.allow_selecting_additional_reviews_after_1st_round) %>
+ <% if @assignment.staggered_deadline? or @assignment.number_of_current_round(@participant.user_id) == 1 or (@assignment.number_of_current_round(@participant.user_id) > 1 and @assignment.allow_selecting_additional_reviews_after_1st_round) %>
<% if @assignment.dynamic_reviewer_assignment? %>
<% if @num_reviews_in_progress >= Assignment.max_outstanding_reviews %>
diff --git a/app/views/student_task/view.html.erb b/app/views/student_task/view.html.erb
index 06407fcd03f..396a671ff6e 100644
--- a/app/views/student_task/view.html.erb
+++ b/app/views/student_task/view.html.erb
@@ -27,7 +27,7 @@
<% if @use_bookmark %>
- <% if @topic_id and @assignment.submission_allowed(@topic_id) %>
+ <% if @topic_id and @assignment.submission_allowed(@participant.user_id) %>
<%= link_to "View bookmarks", :controller=>'bookmarks', :action=> 'list', :id => @topic_id %> <%=t ".view_bookmarks_lengthy" %>
<% else %>
<%=t ".view_bookmarks" %><%=t ".choose_topic" %>
@@ -53,14 +53,14 @@ to display the label "Your team" in the student assignment tasks-->
<% if @team %>
<% if @topics.size > 0 %>
- <% if @topic_id && @assignment.submission_allowed(@topic_id) %>
+ <% if @topic_id && @assignment.submission_allowed(@participant.user_id) %>
<%= link_to t(".your_work"), :controller => 'submitted_content', :action => 'edit', :id => @participant.id %> <%=t ".submit_work" %>
<% else %>
<%=t ".your_work" %> <%=t ".choose_topic" %>
<% end %>
<% else %>
- <% if @assignment.submission_allowed(@topic_id) %>
+ <% if @assignment.submission_allowed(@participant.user_id) %>
<%= link_to t(".your_work"), :controller => 'submitted_content', :action => 'edit', :id => @participant.id %> <%=t ".submit_work" %>
<% else %>
<%=t ".your_work" %> <%=t ".not_allowed" %>
@@ -105,7 +105,7 @@ to display the label "Your team" in the student assignment tasks-->
<%if @assignment.require_quiz%>
<% if @authorization == 'participant' or @can_take_quiz == true %>
- <% if @assignment.require_quiz and (@assignment.quiz_allowed(@topic_id) or @assignment.current_stage(@topic_id) == "Finished") %>
+ <% if @assignment.require_quiz and (@assignment.quiz_allowed(@participant.user_id) or @assignment.current_stage(@topic_id) == "Finished") %>
<%= link_to t(".take_quizzes"), student_quizzes_path(:id => @participant.id) %>
<% else %>
<%=t ".take_quizzes" %>
diff --git a/app/views/submitted_content/_self_review.html.erb b/app/views/submitted_content/_self_review.html.erb
index 32073e13423..9e05c654a4b 100644
--- a/app/views/submitted_content/_self_review.html.erb
+++ b/app/views/submitted_content/_self_review.html.erb
@@ -36,7 +36,7 @@
<% last_response_round = @latest_response.round %>
<% end %>
- <% current_round = @assignment.number_of_current_round(@topic_id) %>
+ <% current_round = @assignment.number_of_current_round(@participant.user_id) %>
|
<%= link_to 'View', {:controller => 'response', :action => 'view', :id => @latest_response.id} %> |
diff --git a/lib/due_date_mix_in.rb b/lib/due_date_mix_in.rb
new file mode 100755
index 00000000000..3edeec31b7f
--- /dev/null
+++ b/lib/due_date_mix_in.rb
@@ -0,0 +1,143 @@
+# frozen_String_literal: true
+
+# lib/due_date_mix_in.rb
+module DueDateMixIn
+ # finds the topic_id given the participant user_id
+ def find_topic_id(participant_id)
+ topic_id = if participant_id.nil?
+ nil
+ else
+ SignedUpTeam.topic_id(id, participant_id)
+ end
+ end
+
+ # Determine if the next due date from now allows for submissions
+ def submission_allowed(participant_id = nil)
+ # Find topic id for given participant for selected assignment
+ # Return nil if no participant is given
+ topic_id = find_topic_id(participant_id)
+ # only need to pass @participiant to search, can this be done locally
+ next_due_date = DueDate.get_next_due_date(id, topic_id)
+ return false if next_due_date.nil?
+
+ # find the quiz allowed id, then check if that deadline is passed
+ right_id = next_due_date.submission_allowed_id
+ right = DeadlineRight.find(right_id)
+ # check is assignment action deadline is ok or late (i.e. not no)
+ right && (right.name != 'No')
+ end
+
+ # Determine if the next due date from now allows for reviews
+ # Should be renamed to review_allowed from can_review
+ def can_review(participant_id = nil)
+ topic_id = find_topic_id(participant_id)
+ next_due_date = DueDate.get_next_due_date(id, topic_id)
+ return false if next_due_date.nil?
+
+ # find the quiz allowed id, then check if that deadline is passed
+ right_id = next_due_date.review_allowed_id
+ right = DeadlineRight.find(right_id)
+ # check is assignment action deadline is ok or late (i.e. not no)
+ right && (right.name != 'No')
+ end
+
+ # Determine if the next due date from now allows for metareviews
+ def metareview_allowed(participant_id = nil)
+ topic_id = find_topic_id(participant_id)
+ next_due_date = DueDate.get_next_due_date(id, topic_id)
+ return false if next_due_date.nil?
+
+ # find the quiz allowed id, then check if that deadline is passed
+ right_id = next_due_date.review_of_review_allowed_id # meta-review id
+ right = DeadlineRight.find(right_id)
+ # check is assignment action deadline is ok or late (i.e. not no)
+ right && (right.name != 'No')
+ end
+
+ # Determine if the next due date from now allows to take the quizzes
+ def quiz_allowed(participant_id = nil)
+ topic_id = find_topic_id(participant_id)
+ next_due_date = DueDate.get_next_due_date(id, topic_id)
+ return false if next_due_date.nil?
+
+ # find the quiz allowed id, then check if that deadline is passed
+ right_id = next_due_date.quiz_allowed_id
+ right = DeadlineRight.find(right_id)
+ # check is assignment action deadline is ok or late (i.e. not no)
+ right && (right.name != 'No')
+ end
+
+ # if current stage is submission or review, find the round number
+ # otherwise, return 0
+ def number_of_current_round(participant_id = nil)
+ topic_id = find_topic_id(participant_id)
+ next_due_date = DueDate.get_next_due_date(id, topic_id)
+ return 0 if next_due_date.nil?
+
+ next_due_date.round ||= 0
+ end
+
+ def link_for_current_stage(topic_id = nil)
+ return nil if staggered_and_no_topic?(topic_id)
+
+ due_date = find_current_stage(topic_id)
+ if due_date.nil? || (due_date == 'Finished') || due_date.is_a?(TopicDueDate)
+ return nil
+ end
+
+ due_date.description_url
+ end
+
+ def num_review_rounds
+ due_dates = AssignmentDueDate.where(parent_id: id)
+ rounds = 0
+ due_dates.each do |due_date|
+ rounds = due_date.round if due_date.round > rounds
+ end
+ rounds
+ end
+
+ def find_current_stage(participant_id = nil)
+ topic_id = find_topic_id(participant_id)
+ next_due_date = DueDate.get_next_due_date(id, topic_id)
+ return 'Finished' if next_due_date.nil?
+
+ next_due_date
+ end
+
+ def find_due_dates(type)
+ due_dates.select { |due_date| due_date.deadline_type_id == DeadlineType.find_by(name: type).id }
+ end
+
+ # Method find_review_period is used in answer_helper.rb to get the start and end dates of a round
+ def find_review_period(round)
+ # If round is nil, it means the same questionnaire is used for every round. Thus, we return all periods.
+ # If round is not nil, we return only the period of that round.
+
+ submission_type = DeadlineType.find_by(name: 'submission').id
+ review_type = DeadlineType.find_by(name: 'review').id
+
+ due_dates = []
+ due_dates += find_due_dates('submission')
+ due_dates += find_due_dates('review')
+ due_dates.sort_by!(&:id)
+
+ start_dates = []
+ end_dates = []
+
+ if round.nil?
+ round = 1
+ while self.due_dates.exists?(round: round)
+ start_dates << due_dates.select { |due_date| due_date.deadline_type_id == submission_type && due_date.round == round }.last
+ end_dates << due_dates.select { |due_date| due_date.deadline_type_id == review_type && due_date.round == round }.last
+ round += 1
+ end
+ else
+ start_dates << due_dates.select { |due_date| due_date.deadline_type_id == submission_type && due_date.round == round }.last
+ end_dates << due_dates.select { |due_date| due_date.deadline_type_id == review_type && due_date.round == round }.last
+ end
+ [start_dates, end_dates]
+ end
+
+ # END OF MODULE #
+end
diff --git a/spec/lib/due_date_mix_in_test.rb b/spec/lib/due_date_mix_in_test.rb
new file mode 100644
index 00000000000..444bb60a67b
--- /dev/null
+++ b/spec/lib/due_date_mix_in_test.rb
@@ -0,0 +1,73 @@
+describe Assignment do
+ let(:assignment) { build(:assignment, id: 1, name: 'no assignment', participants: [participant], teams: [team], max_team_size: 2) }
+ let(:instructor) { build(:instructor, id: 6) }
+ let(:student) { build(:student, id: 3, name: 'no one') }
+ let(:review_response_map) { build(:review_response_map, response: [response], reviewer: build(:participant), reviewee: build(:assignment_team)) }
+ let(:teammate_review_response_map) { build(:review_response_map, type: 'TeammateReviewResponseMap') }
+ let(:participant) { build(:participant, id: 1) }
+ let(:question) { double('Question') }
+ let(:team) { build(:assignment_team, id: 1, name: 'no team') }
+ let(:response) { build(:response) }
+ let(:course) { build(:course) }
+ let(:assignment_due_date) do
+ build(:assignment_due_date, due_at: '2011-11-11 11:11:11', deadline_name: 'Review',
+ description_url: 'https://expertiza.ncsu.edu/', round: 1)
+ end
+ let(:topic_due_date) { build(:topic_due_date, deadline_name: 'Submission', description_url: 'https://github.com/expertiza/expertiza') }
+ let(:deadline_type) { build(:deadline_type, id: 1) }
+ let(:assignment_questionnaire1) { build(:assignment_questionnaire, id: 1, assignment_id: 1, questionnaire_id: 1) }
+ let(:assignment_questionnaire2) { build(:assignment_questionnaire, id: 2, assignment_id: 1, questionnaire_id: 2) }
+ let(:questionnaire1) { build(:questionnaire, id: 1, type: 'ReviewQuestionnaire') }
+ let(:questionnaire2) { build(:questionnaire, id: 2, type: 'MetareviewQuestionnaire') }
+
+ describe '#submission_allowed' do
+ it 'returns true when the next topic due date is allowed to submit sth' do
+ #allow(assignment).to receive(:check_condition).with('submission_allowed_id', 123).and_return(true)
+ #expect(assignment.submission_allowed(123)).to be true
+ assignment_due_date = double('AssignmentDueDate')
+ assignment_topic_id = double('AssignmentTopicId')
+ allow(SignedUpTeam).to receive(:topic_id).with(1, 1).and_return(assignment_topic_id) # 1,1
+ allow(DueDate).to receive(:get_next_due_date).with(1, assignment_topic_id).and_return(assignment_due_date)
+ allow(assignment_due_date).to receive(:submission_allowed_id).and_return(1)
+ allow(DeadlineRight).to receive(:find).with(1).and_return(double('DeadlineRight', name: 'OK'))
+ expect(assignment.submission_allowed(1)).to be true
+ end
+ end
+
+ describe '#quiz_allowed' do
+ it 'returns false when the next topic due date is not allowed to do quiz' do
+ assignment_due_date = double('AssignmentDueDate')
+ assignment_topic_id = double('AssignmentTopicId')
+ allow(SignedUpTeam).to receive(:topic_id).with(1, 1).and_return(assignment_topic_id) # 1,1
+ allow(DueDate).to receive(:get_next_due_date).with(1, assignment_topic_id).and_return(assignment_due_date)
+ allow(assignment_due_date).to receive(:quiz_allowed_id).and_return(1)
+ allow(DeadlineRight).to receive(:find).with(1).and_return(double('DeadlineRight', name: 'OK'))
+ expect(assignment.quiz_allowed(1)).to be true
+ end
+ end
+
+ describe '#metareview_allowed' do
+ it 'returns true when the next assignment due date is not allowed to do metareview' do
+ assignment_due_date = double('AssignmentDueDate')
+ assignment_topic_id = double('AssignmentTopicId')
+ allow(SignedUpTeam).to receive(:topic_id).with(1, 1).and_return(assignment_topic_id) # 1,1
+ allow(DueDate).to receive(:get_next_due_date).with(1, assignment_topic_id).and_return(assignment_due_date)
+ allow(assignment_due_date).to receive(:review_of_review_allowed_id).and_return(1)
+ allow(DeadlineRight).to receive(:find).with(1).and_return(double('DeadlineRight', name: 'OK'))
+ expect(assignment.metareview_allowed(1)).to be true
+ end
+ end
+
+ describe '#can_review' do
+ it 'returns true when the next assignment due date is not allowed to do metareview' do
+ assignment_due_date = double('AssignmentDueDate')
+ assignment_topic_id = double('AssignmentTopicId')
+ allow(SignedUpTeam).to receive(:topic_id).with(1, 1).and_return(assignment_topic_id) # 1,1
+ allow(DueDate).to receive(:get_next_due_date).with(1, assignment_topic_id).and_return(assignment_due_date)
+ allow(assignment_due_date).to receive(:review_allowed_id).and_return(1)
+ allow(DeadlineRight).to receive(:find).with(1).and_return(double('DeadlineRight', name: 'OK'))
+ expect(assignment.can_review(1)).to be true
+ end
+ end
+
+end
diff --git a/spec/models/assignment_spec.rb b/spec/models/assignment_spec.rb
index 0bb5f50fb12..0c27ac1947e 100644
--- a/spec/models/assignment_spec.rb
+++ b/spec/models/assignment_spec.rb
@@ -245,53 +245,6 @@
end
end
- describe '#check_condition' do
- context 'when the next due date is nil' do
- it 'returns false ' do
- allow(DueDate).to receive(:get_next_due_date).with(1, nil).and_return(nil)
- expect(assignment.check_condition('review_allowed_id')).to be false
- end
- end
-
- context 'when the next due date is allowed to review submissions' do
- it 'returns true' do
- assignment_due_date = double('AssignmentDueDate')
- allow(DueDate).to receive(:get_next_due_date).with(1, nil).and_return(assignment_due_date)
- allow(assignment_due_date).to receive(:send).with('review_allowed_id').and_return(1)
- allow(DeadlineRight).to receive(:find).with(1).and_return(double('DeadlineRight', name: 'OK'))
- expect(assignment.check_condition('review_allowed_id')).to be true
- end
- end
- end
-
- describe '#submission_allowed' do
- it 'returns true when the next topic due date is allowed to submit sth' do
- allow(assignment).to receive(:check_condition).with('submission_allowed_id', 123).and_return(true)
- expect(assignment.submission_allowed(123)).to be true
- end
- end
-
- describe '#quiz_allowed' do
- it 'returns false when the next topic due date is not allowed to do quiz' do
- allow(assignment).to receive(:check_condition).with('quiz_allowed_id', 456).and_return(false)
- expect(assignment.quiz_allowed(456)).to be false
- end
- end
-
- describe '#can_review' do
- it "returns false when the next assignment due date is not allowed to review other's work" do
- allow(assignment).to receive(:check_condition).with('review_allowed_id', nil).and_return(true)
- expect(assignment.can_review).to be true
- end
- end
-
- describe '#metareview_allowed' do
- it 'returns true when the next assignment due date is not allowed to do metareview' do
- allow(assignment).to receive(:check_condition).with(any_args).and_return(false)
- expect(assignment.metareview_allowed).to be false
- end
- end
-
describe '#delete' do
before(:each) do
allow(ReviewResponseMap).to receive(:where).with(reviewed_object_id: 1).and_return([review_response_map])
|