Assignment and Grade Service Data Model
Closes PLAT-3006, PLAT-3003 Test Plan Specs pass Change-Id: I77a9cf5f35f5c5397cc40a38127d49e34a0935ee Reviewed-on: https://gerrit.instructure.com/138450 Reviewed-by: Marc Alan Phillips <mphillips@instructure.com> Tested-by: Jenkins QA-Review: August Thornton <august@instructure.com> Reviewed-by: Cody Cutrer <cody@instructure.com> Product-Review: Weston Dransfield <wdransfield@instructure.com>
This commit is contained in:
parent
46eb7560a3
commit
433997655c
|
@ -74,6 +74,7 @@ class Assignment < ActiveRecord::Base
|
|||
|
||||
has_many :assignment_configuration_tool_lookups, dependent: :delete_all
|
||||
has_many :tool_settings_context_external_tools, through: :assignment_configuration_tool_lookups, source: :tool, source_type: 'ContextExternalTool'
|
||||
has_many :line_items, inverse_of: :assignment, class_name: 'Lti::LineItem'
|
||||
|
||||
has_one :external_tool_tag, :class_name => 'ContentTag', :as => :context, :inverse_of => :context, :dependent => :destroy
|
||||
validates_associated :external_tool_tag, :if => :external_tool?
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class Lti::LineItem < ApplicationRecord
|
||||
validates :score_maximum, :label, :assignment, presence: true
|
||||
validates :score_maximum, numericality: true
|
||||
|
||||
belongs_to :resource_link,
|
||||
inverse_of: :line_items,
|
||||
foreign_key: :lti_resource_link_id,
|
||||
class_name: 'Lti::ResourceLink'
|
||||
belongs_to :assignment, inverse_of: :line_items
|
||||
has_many :results,
|
||||
inverse_of: :line_item,
|
||||
class_name: 'Lti::Result',
|
||||
foreign_key: :lti_line_item_id,
|
||||
dependent: :destroy
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class Lti::ResourceLink < ApplicationRecord
|
||||
validates :resource_link_id, presence: true
|
||||
|
||||
has_many :line_items,
|
||||
inverse_of: :resource_link,
|
||||
class_name: 'Lti::LineItem',
|
||||
dependent: :destroy,
|
||||
foreign_key: :lti_resource_link_id
|
||||
|
||||
before_validation :generate_resource_link_id, on: :create
|
||||
|
||||
private
|
||||
|
||||
def generate_resource_link_id
|
||||
self.resource_link_id ||= SecureRandom.uuid
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class Lti::Result < ApplicationRecord
|
||||
validates :line_item, :user, presence: true
|
||||
validates :result_maximum, presence: true, unless: proc { |r| r.result_score.blank? }
|
||||
validates :result_maximum, :result_score, numericality: true, allow_nil: true
|
||||
validates :activity_progress,
|
||||
inclusion: { in: ['Initialized', 'Started', 'InProgress', 'Submitted', 'Completed'] },
|
||||
allow_nil: true
|
||||
validates :grading_progress,
|
||||
inclusion: { in: ['FullyGraded', 'Pending', 'PendingManual', 'Failed', 'NotReady'] },
|
||||
allow_nil: true
|
||||
|
||||
belongs_to :submission, inverse_of: :lti_result
|
||||
belongs_to :user, inverse_of: :lti_results
|
||||
belongs_to :line_item, inverse_of: :results, foreign_key: :lti_line_item_id, class_name: 'Lti::LineItem'
|
||||
end
|
|
@ -81,6 +81,7 @@ class Submission < ActiveRecord::Base
|
|||
has_many :provisional_grades, class_name: 'ModeratedGrading::ProvisionalGrade'
|
||||
has_many :originality_reports
|
||||
has_one :rubric_assessment, -> { where(assessment_type: 'grading') }, as: :artifact, inverse_of: :artifact
|
||||
has_one :lti_result, inverse_of: :submission, class_name: 'Lti::Result'
|
||||
|
||||
# we no longer link submission comments and conversations, but we haven't fixed up existing
|
||||
# linked conversations so this relation might be useful
|
||||
|
|
|
@ -81,6 +81,7 @@ class User < ActiveRecord::Base
|
|||
has_many :access_tokens, -> { preload(:developer_key) }
|
||||
has_many :notification_endpoints, :through => :access_tokens
|
||||
has_many :context_external_tools, -> { order(:name) }, as: :context, inverse_of: :context, dependent: :destroy
|
||||
has_many :lti_results, inverse_of: :user, class_name: 'Lti::Result'
|
||||
|
||||
has_many :student_enrollments
|
||||
has_many :ta_enrollments
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class CreateLtiResourceLinks < ActiveRecord::Migration[5.0]
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
create_table :lti_resource_links do |t|
|
||||
t.string :resource_link_id, null: false
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :lti_resource_links, :resource_link_id, unique: true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class CreateLtiLineItems < ActiveRecord::Migration[5.0]
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
create_table :lti_line_items do |t|
|
||||
t.float :score_maximum, null: false
|
||||
t.string :label, null: false
|
||||
t.string :resource_id, null: true
|
||||
t.string :tag, null: true
|
||||
t.references :lti_resource_link, foreign_key: true, null: true, limit: 8
|
||||
t.references :assignment, foreign_key: true, null: false, limit: 8
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :lti_line_items, :tag
|
||||
add_index :lti_line_items, :resource_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class CreateLtiResults < ActiveRecord::Migration[5.0]
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
create_table :lti_results do |t|
|
||||
t.float :result_score
|
||||
t.float :result_maximum
|
||||
t.text :comment
|
||||
t.string :activity_progress
|
||||
t.string :grading_progress
|
||||
t.references :lti_line_item, foreign_key: true, null: false, limit: 8
|
||||
t.references :submission, foreign_key: true, limit: 8
|
||||
t.references :user, foreign_key: true, null: false, limit: 8
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :lti_results, %i(lti_line_item_id user_id), unique: true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
module Factories
|
||||
def line_item_model(overrides: {})
|
||||
options = {
|
||||
score_maximum: 1,
|
||||
label: 'Test Line Item',
|
||||
assignment: assignment_model
|
||||
}
|
||||
Lti::LineItem.create!(options.merge(overrides))
|
||||
end
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
module Factories
|
||||
def lti_result_model(overrides: {})
|
||||
submission = submission_model
|
||||
options = {
|
||||
activity_progress: 'Completed',
|
||||
grading_progress: 'FullyGraded',
|
||||
submission: submission,
|
||||
line_item: overrides[:line_item] || line_item_model(overrides: {assignment: @assignment}),
|
||||
user: @user
|
||||
}
|
||||
Lti::Result.create!(options.merge(overrides))
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
RSpec.describe Lti::LineItem, type: :model do
|
||||
context 'when validating' do
|
||||
let(:line_item) { line_item_model }
|
||||
|
||||
it 'requires "score_maximum"' do
|
||||
expect do
|
||||
line_item.update_attributes!(score_maximum: nil)
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
"Validation failed: Score maximum can't be blank, Score maximum is not a number"
|
||||
)
|
||||
end
|
||||
|
||||
it 'requires "label"' do
|
||||
expect do
|
||||
line_item.update_attributes!(label: nil)
|
||||
end.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Label can't be blank")
|
||||
end
|
||||
|
||||
it 'requires "assignment"' do
|
||||
expect do
|
||||
line_item.update_attributes!(assignment: nil)
|
||||
end.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Assignment can't be blank")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
RSpec.describe Lti::ResourceLink, type: :model do
|
||||
context 'when validating' do
|
||||
let(:resource_link) { Lti::ResourceLink.create! }
|
||||
|
||||
it 'sets the "resource_link_id" if it is not specified' do
|
||||
expect(resource_link.resource_link_id).not_to be_blank
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
RSpec.describe Lti::Result, type: :model do
|
||||
context 'when validating' do
|
||||
let(:result) { lti_result_model }
|
||||
|
||||
it 'requires "line_item"' do
|
||||
expect do
|
||||
result.update_attributes!(line_item: nil)
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
"Validation failed: Line item can't be blank"
|
||||
)
|
||||
end
|
||||
|
||||
it 'requires "user"' do
|
||||
expect do
|
||||
result.update_attributes!(user: nil)
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
"Validation failed: User can't be blank"
|
||||
)
|
||||
end
|
||||
|
||||
it 'requires the "activity_progress" be valid' do
|
||||
expect do
|
||||
result.update_attributes!(activity_progress: 'Banana')
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
"Validation failed: Activity progress is not included in the list"
|
||||
)
|
||||
end
|
||||
|
||||
it 'requires the "grading_progress" be valid' do
|
||||
expect do
|
||||
result.update_attributes!(grading_progress: 'Banana')
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
"Validation failed: Grading progress is not included in the list"
|
||||
)
|
||||
end
|
||||
|
||||
it 'requires "score_maximum" if "result_score" is present' do
|
||||
expect do
|
||||
result.update_attributes!(result_score: 12.2)
|
||||
end.to raise_error(
|
||||
ActiveRecord::RecordInvalid,
|
||||
"Validation failed: Result maximum can't be blank"
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not require "score_maximum" if "result_score" is blank' do
|
||||
expect do
|
||||
result.update_attributes!(result_score: nil)
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue