graphql: assignment override types

closes RECNVS-27

Test plan:
  * create different types of overrides for assignment(s)
  * make sure you can view the overrides with graphql

Change-Id: I557e1e8b26f8ead6c26bbddb5e09fd5ac425d421
Reviewed-on: https://gerrit.instructure.com/138381
Tested-by: Jenkins
Reviewed-by: Michael Jasper <mjasper@instructure.com>
QA-Review: Collin Parrish <cparrish@instructure.com>
Product-Review: Cameron Matheson <cameron@instructure.com>
This commit is contained in:
Cameron Matheson 2018-01-11 12:03:13 -07:00
parent d7643ad2dd
commit 713ccad7b0
4 changed files with 194 additions and 0 deletions

View File

@ -0,0 +1,67 @@
module Types
AssignmentOverrideType = GraphQL::ObjectType.define do
name "AssignmentOverride"
interfaces [Interfaces::TimestampInterface]
field :_id, !types.ID, "legacy canvas id", property: :id
field :assignment, AssignmentType, resolve: ->(override, _, _) {
Loaders::AssociationLoader.for(AssignmentOverride, :assignment)
.load(override)
.then { override.assignment }
}
field :title, types.String
field :set, AssignmentOverrideSetUnion do
description "This object specifies what students this override applies to"
resolve ->(override, _, _) {
if override.set_type == "ADHOC"
# AdhocStudentsType will load the actual students
override
else
Loaders::AssociationLoader.for(AssignmentOverride, :set)
.load(override)
.then { override.set }
end
}
end
field :dueAt, TimeType, property: :due_at
field :lockAt, TimeType, property: :lock_at
field :unlockAt, TimeType, property: :unlock_at
field :allDay, types.Boolean, property: :all_day
end
AssignmentOverrideSetUnion = GraphQL::UnionType.define do
name "AssignmentOverrideSet"
description "Objects that can be assigned overridden dates"
possible_types [SectionType, GroupType, AdhocStudentsType]
resolve_type ->(obj, _) {
case obj
when CourseSection then SectionType
when Group then GroupType
when AssignmentOverride then AdhocStudentsType
end
}
end
AdhocStudentsType = GraphQL::ObjectType.define do
name "AdhocStudents"
description "A list of students that an `AssignmentOverride` applies to"
field :students, types[UserType], resolve: ->(override, _, _) {
Loaders::AssociationLoader.for(AssignmentOverride,
assignment_override_students: :user)
.load(override)
.then { override.assignment_override_students.map(&:user) }
}
end
end

View File

@ -90,6 +90,15 @@ module Types
`AssignmentOverride` applies.",
property: :only_visible_to_overrides
connection :assignmentOverrides, AssignmentOverrideType.connection_type, resolve:
->(assignment, _, ctx) {
# this is the assignment overrides index method of loading
# overrides... there's also the totally different method found in
# assignment_overrides_json. they may not return the same results?
# ¯\_(ツ)_/¯
AssignmentOverrideApplicator.overrides_for_assignment_and_user(assignment, ctx[:current_user])
}
connection :submissionsConnection, SubmissionType.connection_type do
description "submissions for this assignment"
resolve ->(assignment, _, ctx) {

View File

@ -1,7 +1,25 @@
# A list of students that an `AssignmentOverride` applies to
type AdhocStudents {
students: [User]
}
type Assignment implements Node, Timestamped {
# legacy canvas id
_id: ID!
assignmentGroup: AssignmentGroup
assignmentOverrides(
# Returns the elements in the list that come after the specified global ID.
after: String
# Returns the elements in the list that come before the specified global ID.
before: String
# Returns the first _n_ elements from the list.
first: Int
# Returns the last _n_ elements from the list.
last: Int
): AssignmentOverrideConnection
course: Course
createdAt: Time
description: String
@ -126,6 +144,43 @@ input AssignmentInput {
name: String!
}
type AssignmentOverride implements Timestamped {
# legacy canvas id
_id: ID!
allDay: Boolean
assignment: Assignment
createdAt: Time
dueAt: Time
lockAt: Time
# This object specifies what students this override applies to
set: AssignmentOverrideSet
title: String
unlockAt: Time
updatedAt: Time
}
# The connection type for AssignmentOverride.
type AssignmentOverrideConnection {
# A list of edges.
edges: [AssignmentOverrideEdge]
# Information to aid in pagination.
pageInfo: PageInfo!
}
# An edge in a connection.
type AssignmentOverrideEdge {
# A cursor for use in pagination.
cursor: String!
# The item at the end of the edge.
node: AssignmentOverride
}
# Objects that can be assigned overridden dates
union AssignmentOverrideSet = AdhocStudents | Group | Section
# States that an Assignment can be in
enum AssignmentState {
deleted

View File

@ -0,0 +1,63 @@
#
# Copyright (C) 2017 - 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 File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require File.expand_path(File.dirname(__FILE__) + '/../../helpers/graphql_type_tester')
describe Types::AssignmentOverrideType do
let_once(:course) { course_factory(active_all: true) }
let_once(:teacher) { teacher_in_course(course: course).user }
let_once(:student) { student_in_course(course: course).user }
let_once(:section) { course.course_sections.create! name: "section" }
let_once(:group) {
gc = assignment.group_category = GroupCategory.create! name: "asdf", context: course
gc.groups.create! name: "group", context: course
}
let_once(:assignment) { course.assignments.create! name: "asdf" }
let_once(:adhoc_override) {
assignment.assignment_overrides.new(set_type: "ADHOC").tap { |override|
override.assignment_override_students.build(assignment: assignment, user: student, assignment_override: override)
override.save!
}
}
let_once(:group_override) { assignment.assignment_overrides.create!(set: group) }
let_once(:section_override) { assignment.assignment_overrides.create!(set: section) }
def assignment_override_type(override)
GraphQLTypeTester.new(Types::AssignmentOverrideType, override)
end
it "works" do
override_type = assignment_override_type(adhoc_override)
expect(override_type._id).to eq adhoc_override.id
expect(override_type.title).to eq adhoc_override.title
end
it "returns override sets" do
expect(assignment_override_type(section_override).set).to eq section
expect(assignment_override_type(group_override).set).to eq group
expect(assignment_override_type(adhoc_override).set).to eq adhoc_override
end
describe Types::AdhocStudentsType do
let(:adhoc_students_type) { GraphQLTypeTester.new(Types::AdhocStudentsType, adhoc_override) }
it "it returns students" do
expect(adhoc_students_type.students).to eq [student]
end
end
end