multiple contexts per appointment group
closes #7561 Test plan: - create some appointment groups: - make one with multiple courses - make one with a course, and then add more courses after saving - make one restricted to some (not all) sections in a course [1] - make one that has students sign up in groups [1] - make sure that only students that match the above criteria are able to see/reserve those appointment groups [1] you can only choose the group-signup option or restrict appointment groups to certain sections on creation (these options won't be availabe when editing later) Change-Id: I1cff5fb4ed233882c2061f8fd8a7ba6f2d4959b0 Reviewed-on: https://gerrit.instructure.com/9407 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Jon Jensen <jon@instructure.com>
This commit is contained in:
parent
81593a3680
commit
a2a6579c10
|
@ -0,0 +1,162 @@
|
|||
define [
|
||||
'jquery'
|
||||
'underscore'
|
||||
'jst/calendar/contextSelector'
|
||||
'jst/calendar/contextSelectorItem'
|
||||
'compiled/fn/preventDefault'
|
||||
], ($, _, contextSelectorTemplate, contextSelectorItemTemplate, preventDefault) ->
|
||||
|
||||
class ContextSelectorItem
|
||||
constructor: (@context) ->
|
||||
@state = 'off'
|
||||
@locked = false
|
||||
@sectionsLocked = false
|
||||
|
||||
pubsubHelper = (fn) =>
|
||||
(sender) =>
|
||||
return if sender is this
|
||||
fn.apply(this)
|
||||
|
||||
$.subscribe '/contextSelector/disable', pubsubHelper(@disable)
|
||||
$.subscribe '/contextSelector/enable', pubsubHelper(@enable)
|
||||
$.subscribe '/contextSelector/uncheck', pubsubHelper(=> @setState('off'))
|
||||
|
||||
$.subscribe '/contextSelector/lockSections', @lockSections
|
||||
|
||||
render: ($list) ->
|
||||
@$listItem = $(contextSelectorItemTemplate(@context))
|
||||
@$listItem.appendTo($list)
|
||||
@$sectionsList = @$listItem.find('.ag_sections')
|
||||
|
||||
@$listItem.find('.ag_sections_toggle').click preventDefault @toggleSections
|
||||
@$contentCheckbox = @$listItem.find('[name="context_codes[]"]')
|
||||
@$contentCheckbox.change preventDefault @change
|
||||
@$sectionCheckboxes = @$listItem.find('[name="sections[]"]')
|
||||
@$sectionCheckboxes.change @sectionChange
|
||||
|
||||
toggleSections: (jsEvent) =>
|
||||
$(jsEvent.target).toggleClass('ag-sections-expanded')
|
||||
@$sectionsList.toggleClass('hidden')
|
||||
|
||||
change: =>
|
||||
newState = switch @state
|
||||
when 'off' then 'on'
|
||||
when 'on' then 'off'
|
||||
when 'partial' then 'on'
|
||||
@setState(newState)
|
||||
|
||||
setState: (state) =>
|
||||
return if @locked
|
||||
|
||||
@state = state
|
||||
switch @state
|
||||
when 'on', 'off'
|
||||
checked = @state == 'on'
|
||||
@$contentCheckbox.prop('checked', checked)
|
||||
@$contentCheckbox.prop('indeterminate', false)
|
||||
@$sectionCheckboxes.prop('checked', checked)
|
||||
$.publish("/contextSelector/enable", [this])
|
||||
when 'partial'
|
||||
@$contentCheckbox.prop('checked', true)
|
||||
@$contentCheckbox.prop('indeterminate', true)
|
||||
$.publish('/contextSelector/disable', [this])
|
||||
$.publish('/contextSelector/uncheck', [this])
|
||||
|
||||
$.publish('/contextSelector/changed')
|
||||
|
||||
sectionChange: =>
|
||||
switch @$sectionCheckboxes.filter(':checked').length
|
||||
when 0
|
||||
@setState('off')
|
||||
when @$sectionCheckboxes.length
|
||||
@setState('on')
|
||||
else
|
||||
@setState('partial')
|
||||
|
||||
disable: ->
|
||||
@$contentCheckbox.prop('disabled', true)
|
||||
@disableSections()
|
||||
|
||||
disableSections: ->
|
||||
@$sectionCheckboxes.prop('disabled', true)
|
||||
|
||||
enable: ->
|
||||
unless @locked
|
||||
@$contentCheckbox.prop('disabled', false)
|
||||
@enableSections()
|
||||
|
||||
enableSections: ->
|
||||
unless @lockedSections
|
||||
@$sectionCheckboxes.prop('disabled', false)
|
||||
|
||||
lock: ->
|
||||
@locked = true
|
||||
@disable()
|
||||
$.publish('/contextSelector/lockSections')
|
||||
|
||||
lockSections: =>
|
||||
@lockedSections = true
|
||||
@disableSections()
|
||||
|
||||
isChecked: -> @state != 'off'
|
||||
|
||||
sections: ->
|
||||
checked = @$sectionCheckboxes.filter(':checked')
|
||||
if checked.length == @$sectionCheckboxes.length
|
||||
[]
|
||||
else
|
||||
_.map(checked, (cb) -> cb.value)
|
||||
|
||||
class ContextSelector
|
||||
constructor: (selector, @apptGroup, @contexts, contextsChangedCB, closeCB) ->
|
||||
@$menu = $(selector).html contextSelectorTemplate()
|
||||
$contextsList = @$menu.find('.ag-contexts')
|
||||
|
||||
$.subscribe('/contextSelector/changed', => contextsChangedCB @selectedContexts(), @selectedSections())
|
||||
|
||||
@contextSelectorItems = {}
|
||||
for c in @contexts
|
||||
item = new ContextSelectorItem(c)
|
||||
item.render($contextsList)
|
||||
@contextSelectorItems[item.context.asset_string] = item
|
||||
|
||||
if @apptGroup.sub_context_codes.length > 0
|
||||
# if you choose sub_contexts when creating an appointment
|
||||
# group, the appointment group is locked down
|
||||
# TODO: be smarter about this
|
||||
for subContextCode in @apptGroup.sub_context_codes
|
||||
$("[value='#{subContextCode}']").prop('checked', true)
|
||||
for c, item of @contextSelectorItems
|
||||
item.sectionChange()
|
||||
item.lock()
|
||||
else
|
||||
for contextCode in @apptGroup.context_codes
|
||||
@contextSelectorItems[contextCode].setState('on')
|
||||
@contextSelectorItems[contextCode].lock()
|
||||
|
||||
$('.ag_contexts_done').click preventDefault closeCB
|
||||
|
||||
contextsChangedCB(@selectedContexts(), @selectedSections())
|
||||
|
||||
selectedContexts: ->
|
||||
contexts = _.chain(@contextSelectorItems)
|
||||
.values()
|
||||
.filter( (c) -> c.state != 'off')
|
||||
.map( (c) -> c.context.asset_string)
|
||||
.value()
|
||||
|
||||
numPartials = _.filter(contexts, (c) -> c.state == 'partial')
|
||||
if numPartials > 1 or numPartials == 1 and contexts.length > 1
|
||||
throw "invalid state"
|
||||
|
||||
contexts
|
||||
|
||||
selectedSections: ->
|
||||
sections = _.chain(@contextSelectorItems)
|
||||
.values()
|
||||
.map( (c) -> c.sections())
|
||||
.reject((ss) -> ss.length == 0)
|
||||
.value()
|
||||
|
||||
throw "invalid state" if sections.length > 1
|
||||
sections[0]
|
|
@ -1,26 +1,34 @@
|
|||
define [
|
||||
'jquery'
|
||||
'underscore'
|
||||
'i18n!EditAppointmentGroupDetails'
|
||||
'compiled/calendar/TimeBlockList'
|
||||
'jst/calendar/editAppointmentGroup'
|
||||
'jst/calendar/genericSelect'
|
||||
'jst/calendar/sectionCheckboxes'
|
||||
'compiled/calendar/ContextSelector'
|
||||
'compiled/fn/preventDefault'
|
||||
'jquery.ajaxJSON'
|
||||
'jquery.disableWhileLoading'
|
||||
'jquery.instructure_forms'
|
||||
], ($, I18n, TimeBlockList, editAppointmentGroupTemplate, genericSelectTemplate, sectionCheckboxesTemplate) ->
|
||||
], ($, _, I18n, TimeBlockList, editAppointmentGroupTemplate, genericSelectTemplate, sectionCheckboxesTemplate, ContextSelector, preventDefault) ->
|
||||
|
||||
class EditAppointmentGroupDetails
|
||||
constructor: (selector, @apptGroup, @contextChangeCB, @closeCB) ->
|
||||
constructor: (selector, @apptGroup, @contexts, @closeCB) ->
|
||||
@currentContextInfo = null
|
||||
|
||||
$(selector).html editAppointmentGroupTemplate({
|
||||
title: @apptGroup.title
|
||||
contexts: @apptGroup.contexts
|
||||
contexts: @contexts
|
||||
appointment_group: @apptGroup
|
||||
})
|
||||
|
||||
@contextsHash = {}
|
||||
@contextsHash[c.asset_string] = c for c in @contexts
|
||||
|
||||
@form = $(selector).find("form")
|
||||
|
||||
@form.find("select.context_id").change(@contextChange).change()
|
||||
@contextSelector = new ContextSelector('.ag-menu-container', @apptGroup, @contexts, @contextsChanged, @toggleContextsMenu)
|
||||
|
||||
if @apptGroup.id
|
||||
@form.attr('action', @apptGroup.url)
|
||||
|
@ -29,16 +37,17 @@ define [
|
|||
@form.find(".context_id").val(@apptGroup.context_code).attr('disabled', true)
|
||||
@form.find("select.context_id").change()
|
||||
|
||||
@form.find(".group_category").attr('disabled', true)
|
||||
@form.find('input[name="section_ids[]"]').attr('disabled', true)
|
||||
@form.find(".group-signup-checkbox").attr('disabled', true)
|
||||
@disableGroups()
|
||||
if @apptGroup.participant_type == 'Group'
|
||||
@form.find(".group-signup-checkbox").prop('checked', true)
|
||||
@form.find(".group_category").val(@apptGroup.sub_context_codes[0])
|
||||
else
|
||||
@form.find(".group-signup-checkbox").prop('checked', false)
|
||||
else
|
||||
@form.attr('action', @currentContextInfo.create_appointment_group_url)
|
||||
# FIXME: put this url in ENV json or something
|
||||
@form.attr('action', '/api/v1/appointment_groups')
|
||||
|
||||
@form.find('.ag_contexts_selector').click preventDefault @toggleContextsMenu
|
||||
|
||||
timeBlocks = ([appt.start, appt.end, true] for appt in @apptGroup.appointmentEvents || [] )
|
||||
@timeBlockList = new TimeBlockList(@form.find(".time-block-list-body"), @form.find(".splitter"), timeBlocks)
|
||||
|
@ -54,7 +63,6 @@ define [
|
|||
checked = !!jsEvent.target.checked
|
||||
@form.find('.per_appointment_groups_label').toggle(checked)
|
||||
@form.find('.per_appointment_users_label').toggle(!checked)
|
||||
@form.find(".section-signup").toggle(!checked)
|
||||
@form.find(".group-signup").toggle(checked)
|
||||
@form.find(".group-signup-checkbox").change()
|
||||
|
||||
|
@ -86,12 +94,6 @@ define [
|
|||
if @apptGroup.workflow_state == 'active'
|
||||
@form.find("#appointment-blocks-active-button").attr('disabled', true).prop('checked', true)
|
||||
|
||||
contextInfoForCode: (code) ->
|
||||
for context in @apptGroup.contexts
|
||||
if context.asset_string == code
|
||||
return context
|
||||
return null
|
||||
|
||||
saveWithoutPublishingClick: (jsEvent) =>
|
||||
jsEvent.preventDefault()
|
||||
@save(false)
|
||||
|
@ -136,13 +138,23 @@ define [
|
|||
|
||||
params['appointment_group[participant_visibility]'] = if data.participant_visibility == '1' then 'protected' else 'private'
|
||||
|
||||
if create
|
||||
params['appointment_group[context_code]'] = data.context_code
|
||||
# get the context/section info from @contextSelector instead
|
||||
delete data['context_codes[]']
|
||||
delete data['sections[]']
|
||||
|
||||
contextCodes = @contextSelector.selectedContexts()
|
||||
if contextCodes.length == 0
|
||||
$('.ag_contexts_selector').errorBox(I18n.t 'context_required', 'You need to select a calendar')
|
||||
return
|
||||
else
|
||||
params['appointment_group[context_codes]'] = contextCodes
|
||||
|
||||
if create
|
||||
if data.use_group_signup == '1' && data.group_category_id
|
||||
params['appointment_group[sub_context_codes]'] = [data.group_category_id]
|
||||
else if data['section_ids[]']?.length > 0
|
||||
params['appointment_group[sub_context_codes]'] = data['section_ids[]']
|
||||
else
|
||||
sections = @contextSelector.selectedSections()
|
||||
params['appointment_group[sub_context_codes]'] = sections if sections
|
||||
|
||||
# TODO: Provide UI for specifying this
|
||||
params['appointment_group[min_appointments_per_participant]'] = 1
|
||||
|
@ -155,31 +167,47 @@ define [
|
|||
deferred = $.ajaxJSON @form.attr('action'), method, params, onSuccess, onError
|
||||
@form.disableWhileLoading(deferred)
|
||||
|
||||
contextChange: (jsEvent) =>
|
||||
context = $(jsEvent.target).val()
|
||||
@currentContextInfo = @contextInfoForCode(context)
|
||||
@apptGroup.contextInfo = @currentContextInfo
|
||||
if @currentContextInfo == null then return
|
||||
contextsChanged: (contextCodes, sectionCodes) =>
|
||||
# dropdown text
|
||||
if sectionCodes
|
||||
sectionCode = sectionCodes[0]
|
||||
section = _.chain(@contexts)
|
||||
.pluck('course_sections')
|
||||
.flatten()
|
||||
.find((s) -> s.asset_string == sectionCode)
|
||||
.value()
|
||||
text = section.name
|
||||
if sectionCodes.length > 1
|
||||
text += I18n.t('and_n_sectionCodes', ' and %{n} others', n: sectionCodes.length - 1)
|
||||
@form.find('.ag_contexts_selector').text(text)
|
||||
else if contextCodes.length > 0
|
||||
contextCode = contextCodes[0]
|
||||
text = @contextsHash[contextCode].name
|
||||
if contextCodes.length > 1
|
||||
text += I18n.t('and_n_contexts', ' and %{n} others', n: contextCodes.length - 1)
|
||||
@form.find('.ag_contexts_selector').text(text)
|
||||
else
|
||||
@form.find('.ag_contexts_selector').text(I18n.t 'select_calendars', 'Select Calendars')
|
||||
|
||||
# Update the sections and groups lists in the scheduler
|
||||
if @currentContextInfo.course_sections
|
||||
for courseSection in @currentContextInfo.course_sections
|
||||
courseSection.selected = courseSection.asset_string in this.apptGroup.sub_context_codes
|
||||
sectionsInfo = { sections: @currentContextInfo.course_sections }
|
||||
@form.find('.section_select').html(sectionCheckboxesTemplate(sectionsInfo))
|
||||
# group selector
|
||||
context = @contextsHash[contextCodes[0]]
|
||||
if contextCodes.length == 1 and not sectionCodes and context.group_categories?.length > 0
|
||||
@enableGroups(context)
|
||||
else
|
||||
@disableGroups()
|
||||
|
||||
if !@currentContextInfo.group_categories || @currentContextInfo.group_categories.length == 0
|
||||
@form.find(".group-signup-checkbox").attr('disabled', true).prop('checked', false).change()
|
||||
else if @currentContextInfo.group_categories
|
||||
disableGroups: ->
|
||||
@form.find(".group-signup-checkbox").attr('disabled', true)
|
||||
@form.find("group-signup").hide()
|
||||
|
||||
enableGroups: (contextInfo) ->
|
||||
@form.find(".group-signup-checkbox").attr('disabled', false)
|
||||
groupsInfo =
|
||||
cssClass: 'group_category'
|
||||
name: 'group_category_id'
|
||||
collection: @currentContextInfo.group_categories
|
||||
collection: contextInfo.group_categories
|
||||
@form.find(".group_select").html(genericSelectTemplate(groupsInfo))
|
||||
@form.find("group-signup").show()
|
||||
|
||||
@contextChangeCB(context)
|
||||
|
||||
# Update the edit and more options links with the new context, if this is a new group
|
||||
if !@apptGroup.id
|
||||
@form.attr('action', @currentContextInfo.create_appointment_group_url)
|
||||
toggleContextsMenu: (jsEvent) =>
|
||||
$('.ag_contexts_menu').toggleClass('hidden')
|
||||
|
|
|
@ -11,20 +11,20 @@ define [
|
|||
width: 'auto'
|
||||
resizable: false
|
||||
title: I18n.t('titles.edit_appointment_group', "Edit Appointment Group")
|
||||
# this is dumb, but it prevents the columns from wrapping when
|
||||
# the context selector drop down gets too long
|
||||
dialog.dialog('widget').find('#edit_event').css('overflow', 'visible')
|
||||
|
||||
class EditAppointmentGroupDialog
|
||||
constructor: (@apptGroup, @parentCloseCB) ->
|
||||
constructor: (@apptGroup, @contexts, @parentCloseCB) ->
|
||||
@currentContextInfo = null
|
||||
|
||||
contextChange: (newContext) =>
|
||||
# TODO: update the color?
|
||||
|
||||
closeCB: (saved) =>
|
||||
dialog.dialog('close')
|
||||
@parentCloseCB(saved)
|
||||
|
||||
show: =>
|
||||
@appointmentGroupsForm = new EditAppointmentGroupDetails(dialog.find(".wrapper"), @apptGroup, @contextChange, @closeCB)
|
||||
@appointmentGroupsForm = new EditAppointmentGroupDetails(dialog.find(".wrapper"), @apptGroup, @contexts, @closeCB)
|
||||
|
||||
buttons = if @apptGroup.workflow_state == 'active'
|
||||
[
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
define [
|
||||
'jquery',
|
||||
'underscore'
|
||||
'i18n!calendar'
|
||||
'jst/calendar/appointmentGroupList'
|
||||
'jst/calendar/schedulerRightSideAdminSection'
|
||||
|
@ -11,7 +12,7 @@ define [
|
|||
'jquery.instructure_misc_plugins'
|
||||
'vendor/jquery.ba-tinypubsub'
|
||||
'vendor/jquery.spin'
|
||||
], ($, I18n, appointmentGroupListTemplate, schedulerRightSideAdminSectionTemplate, EditAppointmentGroupDialog, MessageParticipantsDialog, deleteItemTemplate) ->
|
||||
], ($, _, I18n, appointmentGroupListTemplate, schedulerRightSideAdminSectionTemplate, EditAppointmentGroupDialog, MessageParticipantsDialog, deleteItemTemplate) ->
|
||||
|
||||
class Scheduler
|
||||
constructor: (selector, @calendar) ->
|
||||
|
@ -33,6 +34,9 @@ define [
|
|||
@rightSideAdminSection = $(schedulerRightSideAdminSectionTemplate())
|
||||
@rightSideAdminSection.find(".create_link").click @createClick
|
||||
|
||||
@appointmentGroupContexts = _.filter @contexts, (c) ->
|
||||
c.can_create_appointment_groups
|
||||
|
||||
$.subscribe "CommonEvent/eventSaved", @eventSaved
|
||||
$.subscribe "CommonEvent/eventDeleted", @eventDeleted
|
||||
|
||||
|
@ -40,11 +44,11 @@ define [
|
|||
jsEvent.preventDefault()
|
||||
|
||||
group = {
|
||||
contexts: @calendar.contexts
|
||||
context_codes: []
|
||||
sub_context_codes: []
|
||||
}
|
||||
|
||||
@createDialog = new EditAppointmentGroupDialog(group, @dialogCloseCB)
|
||||
@createDialog = new EditAppointmentGroupDialog(group, @appointmentGroupContexts, @dialogCloseCB)
|
||||
@createDialog.show()
|
||||
|
||||
dialogCloseCB: (saved) =>
|
||||
|
@ -138,9 +142,8 @@ define [
|
|||
for appointmentEvent in group.appointmentEvents
|
||||
group.signed_up += appointmentEvent.childEvents.length if appointmentEvent.childEvents
|
||||
|
||||
# look up the context name for the group
|
||||
for contextInfo in @contexts when contextInfo.asset_string == group.context_code
|
||||
group.context = contextInfo
|
||||
# look up the context names for the group
|
||||
group.contexts = _.filter(@contexts, (c) -> c.asset_string in group.context_codes)
|
||||
|
||||
group.published = group.workflow_state == "active"
|
||||
|
||||
|
@ -224,8 +227,7 @@ define [
|
|||
group = @groups?[$(jsEvent.target).closest(".appointment-group-item").data('appointment-group-id')]
|
||||
return unless group
|
||||
|
||||
group.contexts = @calendar.contexts
|
||||
@createDialog = new EditAppointmentGroupDialog(group, @dialogCloseCB)
|
||||
@createDialog = new EditAppointmentGroupDialog(group, @appointmentGroupContexts, @dialogCloseCB)
|
||||
@createDialog.show()
|
||||
|
||||
deleteLinkClick: (jsEvent) =>
|
||||
|
|
|
@ -2,12 +2,13 @@ define [
|
|||
'vendor/handlebars.vm'
|
||||
'i18nObj'
|
||||
'jquery'
|
||||
'underscore'
|
||||
'str/htmlEscape'
|
||||
'compiled/util/semanticDateRange'
|
||||
'jquery.instructure_date_and_time'
|
||||
'jquery.instructure_misc_helpers'
|
||||
'jquery.instructure_misc_plugins'
|
||||
], (Handlebars, I18n, $, htmlEscape, semanticDateRange) ->
|
||||
], (Handlebars, I18n, $, _, htmlEscape, semanticDateRange) ->
|
||||
|
||||
Handlebars.registerHelper name, fn for name, fn of {
|
||||
t : (key, defaultValue, options) ->
|
||||
|
@ -129,5 +130,10 @@ define [
|
|||
#
|
||||
eachProp: (context, options) ->
|
||||
(options.fn(property: prop, value: context[prop]) for prop of context).join ''
|
||||
|
||||
# evaluates the block for each item in context and passes the result to $.toSentence
|
||||
toSentence: (context, options) ->
|
||||
results = _.map(context, (c) -> options.fn(c))
|
||||
$.toSentence(results)
|
||||
}
|
||||
return Handlebars
|
||||
|
|
|
@ -20,7 +20,6 @@ class AppointmentGroupsController < ApplicationController
|
|||
include Api::V1::CalendarEvent
|
||||
|
||||
before_filter :require_user
|
||||
before_filter :get_context, :only => :create
|
||||
before_filter :get_appointment_group, :only => [:show, :update, :destroy, :users, :groups]
|
||||
|
||||
def calendar_fragment(opts)
|
||||
|
@ -51,8 +50,12 @@ class AppointmentGroupsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
contexts = get_contexts
|
||||
raise ActiveRecord::RecordNotFound unless contexts.present?
|
||||
|
||||
publish = params[:appointment_group].delete(:publish) == '1'
|
||||
@group = @context.appointment_groups.build(params[:appointment_group])
|
||||
params[:appointment_group][:contexts] = contexts
|
||||
@group = AppointmentGroup.new(params[:appointment_group])
|
||||
if authorized_action(@group, @current_user, :manage)
|
||||
if @group.save
|
||||
@group.publish! if publish
|
||||
|
@ -75,6 +78,8 @@ class AppointmentGroupsController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
contexts = get_contexts
|
||||
@group.contexts = contexts if contexts
|
||||
if authorized_action(@group, @current_user, :update)
|
||||
publish = params[:appointment_group].delete(:publish) == "1"
|
||||
if @group.update_attributes(params[:appointment_group])
|
||||
|
@ -119,13 +124,18 @@ class AppointmentGroupsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def get_context
|
||||
@context = Context.find_by_asset_string(params[:appointment_group].delete(:context_code)) if params[:appointment_group] && params[:appointment_group][:context_code]
|
||||
raise ActiveRecord::RecordNotFound unless @context
|
||||
def get_contexts
|
||||
if params[:appointment_group] && params[:appointment_group][:context_codes]
|
||||
context_codes = params[:appointment_group].delete(:context_codes)
|
||||
contexts = context_codes.map do |code|
|
||||
Context.find_by_asset_string(code)
|
||||
end
|
||||
end
|
||||
contexts
|
||||
end
|
||||
|
||||
def get_appointment_group
|
||||
@group = AppointmentGroup.find(params[:id].to_i)
|
||||
@context = @group.context
|
||||
@context = @group.contexts_for_user(@current_user).first # FIXME?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -82,7 +82,7 @@ class CalendarsController < ApplicationController
|
|||
:can_create_calendar_events => context.respond_to?("calendar_events") && context.calendar_events.new.grants_right?(@current_user, session, :create),
|
||||
:can_create_assignments => context.respond_to?("assignments") && context.assignments.new.grants_right?(@current_user, session, :create),
|
||||
:assignment_groups => context.respond_to?("assignments") ? context.assignment_groups.active.scoped(:select => "id, name").map {|g| { :id => g.id, :name => g.name } } : [],
|
||||
:can_create_appointment_groups => context.respond_to?("appointment_groups") && context.appointment_groups.new.grants_right?(@current_user, session, :create),
|
||||
:can_create_appointment_groups => context.respond_to?("appointment_groups") && AppointmentGroup.new(:contexts => [context]).grants_right?(@current_user, session, :create),
|
||||
}
|
||||
if context.respond_to?("course_sections")
|
||||
info[:course_sections] = context.course_sections.active.scoped(:select => "id, name").map {|cs| { :id => cs.id, :asset_string => cs.asset_string, :name => cs.name } }
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<% courses = asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %>
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Reservation canceled for "%{appointment_name}" (%{course})', :appointment_name => asset.title, :course => asset.appointment_group.context.name) %>
|
||||
<%= t('subject', 'Reservation canceled for "%{appointment_name}" (%{course})', :appointment_name => asset.title, :course => courses) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} canceled his/her reservation for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %>
|
||||
|
@ -16,7 +19,7 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %>
|
||||
<%= before_label :course, "Course" %> <%= courses %>
|
||||
<% if asset.appointment_group.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.appointment_group.available_slots %>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} canceled his/her reservation for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %>
|
||||
|
@ -12,7 +12,9 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %><br>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<% if asset.appointment_group.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.appointment_group.available_slots %><br>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, '%{user} canceled his/her reservation for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.contexts.first) %>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<% courses = asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %>
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Your time slot for "%{appointment_name}" has been canceled (%{course})', :appointment_name => asset.title, :course => asset.appointment_group.context.name) %>
|
||||
<%= t('subject', 'Your time slot for "%{appointment_name}" has been canceled (%{course})', :appointment_name => asset.title, :course => courses) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} canceled your time slot for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %>
|
||||
|
@ -16,7 +19,7 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %>
|
||||
<%= before_label :course, "Course" %> <%= courses %>
|
||||
|
||||
<%= before_label :cancel_reason, "Reason for canceling" %>
|
||||
<%= asset.cancel_reason || t(:no_reason_given, "none given") %>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} canceled your time slot for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %><br>
|
||||
|
@ -12,7 +12,9 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %><br>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<br>
|
||||
<b><%= before_label :cancel_reason, "Reason for canceling" %></b><br>
|
||||
<%= asset.cancel_reason || t(:no_reason_given, "none given") %><br>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, 'Your time slot for "%{appointment_name} was canceled".', :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.contexts.first) %>
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Appointments for "%{appointment_name}" have been canceled (%{course})', :appointment_name => asset.title, :course => asset.context.name) %>
|
||||
<%= t('subject', 'Appointments for "%{appointment_name}" have been canceled (%{course})', :appointment_name => asset.title, :course => asset.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'All appointments for "%{appointment_name}" have been canceled.', :appointment_name => asset.title %>
|
||||
|
||||
<%= before_label :details, "Appointment details" %>
|
||||
<%= before_label :dates, "Date(s)" %> <%= date_string(asset.start_at, asset.end_at, :no_words) %>
|
||||
<%= before_label :course, "Course" %> <%= asset.context.name %>
|
||||
<%= before_label :course, "Course" %> <%=
|
||||
asset.participant_type == 'Group' ?
|
||||
asset.contexts.first.name :
|
||||
asset.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
|
||||
<%= before_label :cancel_reason, "Reason for canceling" %>
|
||||
<%= asset.cancel_reason || t(:no_reason_given, "none given") %>
|
|
@ -2,7 +2,10 @@
|
|||
<br>
|
||||
<b><%= before_label :details, "Appointment details" %></b><br>
|
||||
<%= before_label :dates, "Date(s)" %> <%= date_string(asset.start_at, asset.end_at, :no_words) %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%=
|
||||
asset.participant_type == 'Group' ?
|
||||
asset.contexts.first.name :
|
||||
asset.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<br>
|
||||
<b><%= before_label :cancel_reason, "Reason for canceling" %></b><br>
|
||||
<%= asset.cancel_reason || t(:no_reason_given, "none given") %>
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, 'All appointments for "%{appointment_name} have been canceled".', :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.contexts.first) %>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups/<%= asset.id %>
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups/<%= asset.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" is available for signup (%{course})', :appointment_name => asset.title, :course => asset.context.name) %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" is available for signup (%{course})', :appointment_name => asset.title,
|
||||
:course => asset.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'Time slots for "%{appointment_name}" are now available for signup.', :appointment_name => asset.title %>
|
||||
|
@ -14,7 +15,10 @@
|
|||
asset.participant_type == 'Group' ?
|
||||
t(:group_signup, "Group (%{group_category})", :group_category => asset.sub_contexts.first.name) :
|
||||
t(:individual_signup, "Individual") %>
|
||||
<%= before_label :course, "Course" %> <%= asset.context.name %>
|
||||
<%= before_label :course, "Course" %> <%=
|
||||
asset.participant_type == 'Group' ?
|
||||
asset.contexts.first.name :
|
||||
asset.contexts_for_user(user).map(&:name).join(", ") %>
|
||||
<% if asset.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.available_slots %>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups/<%= asset.id %>
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups/<%= asset.id %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'Time slots for "%{appointment_name}" are now available for signup.', :appointment_name => asset.title %><br>
|
||||
|
@ -10,7 +10,10 @@
|
|||
asset.participant_type == 'Group' ?
|
||||
t(:group_signup, "Group (%{group_category})", :group_category => asset.sub_contexts.first.name) :
|
||||
t(:individual_signup, "Individual") %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%=
|
||||
asset.participant_type == 'Group' ?
|
||||
asset.contexts.first.name :
|
||||
asset.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<% if asset.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.available_slots %><br>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, 'Signups are open for "%{appointment_name}".', :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.contexts.first) %>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups/<%= asset.id %>
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups/<%= asset.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" is available for signup (%{course})', :appointment_name => asset.title, :course => asset.context.name) %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" is available for signup (%{course})', :appointment_name => asset.title, :course => asset.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'Time slots for "%{appointment_name}" are now available for signup (%{dates}).', :appointment_name => asset.title, :dates => date_string(asset.start_at, asset.end_at, :no_words) %>
|
|
@ -1,9 +1,9 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups/<%= asset.id %>
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups/<%= asset.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" has been updated (%{course})', :appointment_name => asset.title, :course => asset.context.name) %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" has been updated (%{course})', :appointment_name => asset.title, :course => asset.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'Time slots have been added to "%{appointment_name}" and are available for signup.', :appointment_name => asset.title %>
|
||||
|
@ -14,7 +14,10 @@
|
|||
asset.participant_type == 'Group' ?
|
||||
t(:group_signup, "Group (%{group_category})", :group_category => asset.sub_contexts.first.name) :
|
||||
t(:individual_signup, "Individual") %>
|
||||
<%= before_label :course, "Course" %> <%= asset.context.name %>
|
||||
<%= before_label :course, "Course" %> <%=
|
||||
asset.participant_type == 'Group' ?
|
||||
asset.contexts.first.name :
|
||||
asset.contexts_for_user(user).map(&:name).join(", ") %>
|
||||
<% if asset.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.available_slots %>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups/<%= asset.id %>
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups/<%= asset.id %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'Time slots have been added to "%{appointment_name}" and are available for signup.', :appointment_name => asset.title %><br>
|
||||
|
@ -10,7 +10,10 @@
|
|||
asset.participant_type == 'Group' ?
|
||||
t(:group_signup, "Group (%{group_category})", :group_category => asset.sub_contexts.first.name) :
|
||||
t(:individual_signup, "Individual") %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%=
|
||||
asset.participant_type == 'Group' ?
|
||||
asset.contexts.first.name :
|
||||
asset.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<% if asset.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.available_slots %><br>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, 'New time slots are available for "%{appointment_name}".', :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.contexts.first) %>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.context) %>/appointment_groups/<%= asset.id %>
|
||||
http://<%= HostUrl.context_host(asset.contexts.first) %>/appointment_groups/<%= asset.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" has been updated (%{course})', :appointment_name => asset.title, :course => asset.context.name) %>
|
||||
<%= t('subject', 'Appointment "%{appointment_name}" has been updated (%{course})', :appointment_name => asset.title, :course => asset.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, 'Time slots have been added to "%{appointment_name}" and are available for signup (%{dates}).', :appointment_name => asset.title, :dates => date_string(asset.start_at, asset.end_at, :no_words) %>
|
|
@ -1,9 +1,9 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'User signed up for "%{appointment_name}" (%{course})', :appointment_name => asset.title, :course => asset.appointment_group.context.name) %>
|
||||
<%= t('subject', 'User signed up for "%{appointment_name}" (%{course})', :appointment_name => asset.title, :course => asset.appointment_group.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} has signed up for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %>
|
||||
|
@ -16,7 +16,9 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %>
|
||||
<%= before_label :course, "Course" %> <%= courses = asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %>
|
||||
<% if asset.appointment_group.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.appointment_group.available_slots %>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} has signed up for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %><br>
|
||||
|
@ -12,7 +12,9 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %><br>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<% if asset.appointment_group.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.appointment_group.available_slots %><br>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, '%{user} has signed up for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.contexts.first) %>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
|
@ -16,7 +16,9 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %>
|
||||
<% if asset.appointment_group.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.appointment_group.available_slots %>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} has signed you up for "%{appointment_name}".', :user => asset.updating_user.name, :appointment_name => asset.title %><br>
|
||||
|
@ -12,7 +12,9 @@
|
|||
<% else -%>
|
||||
<%= before_label :attendee, "Attendee" %> <%= asset.context.name %><br>
|
||||
<% end -%>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.context.name %><br>
|
||||
<%= before_label :course, "Course" %> <%= asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ") %><br>
|
||||
<% if asset.appointment_group.available_slots -%>
|
||||
<%= before_label :slots_remaining, "Available time slots" %> <%= asset.appointment_group.available_slots %><br>
|
||||
<% end -%>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= t :message, 'You have been signed up for "%{appointment_name}".', :appointment_name => asset.title %>
|
||||
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.context) %>
|
||||
<%= t :more_info, "More info at %{url}", :url => HostUrl.context_host(asset.appointment_group.contexts.first) %>
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<% define_content :link do %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.context) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
http://<%= HostUrl.context_host(asset.appointment_group.contexts.first) %>/appointment_groups/<%= asset.appointment_group.id %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t('subject', 'You have been signed up for "%{appointment_name}" (%{course})', :appointment_name => asset.title, :course => asset.appointment_group.context.name) %>
|
||||
<%= t('subject', 'You have been signed up for "%{appointment_name}" (%{course})',
|
||||
:appointment_name => asset.title,
|
||||
:course => asset.appointment_group.participant_type == 'Group' ?
|
||||
asset.appointment_group.contexts.first.name :
|
||||
asset.appointment_group.contexts_for_user(user).map(&:name).join(", ")) %>
|
||||
<% end %>
|
||||
|
||||
<%= t :message, '%{user} has signed you up for "%{appointment_name}" (%{date_and_time}).', :user => asset.updating_user.name, :appointment_name => asset.title, :date_and_time => datetime_string(asset.start_at, asset.end_at) %>
|
|
@ -26,10 +26,13 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
# appointments_participants conditions have the correct table alias
|
||||
has_many :_appointments, opts.merge(:conditions => opts[:conditions].gsub(/calendar_events\./, 'calendar_events_join.'))
|
||||
has_many :appointments_participants, :through => :_appointments, :source => :child_events, :conditions => "calendar_events.workflow_state <> 'deleted'", :order => :start_at
|
||||
belongs_to :context, :polymorphic => true
|
||||
alias_method :effective_context, :context
|
||||
has_many :appointment_group_contexts
|
||||
has_many :appointment_group_sub_contexts, :include => :sub_context
|
||||
|
||||
def contexts
|
||||
appointment_group_contexts.map &:context
|
||||
end
|
||||
|
||||
def sub_contexts
|
||||
appointment_group_sub_contexts.map &:sub_context
|
||||
end
|
||||
|
@ -40,7 +43,6 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
|
||||
validates_length_of :title, :maximum => maximum_string_length
|
||||
validates_length_of :description, :maximum => maximum_long_text_length, :allow_nil => true, :allow_blank => true
|
||||
validates_presence_of :context
|
||||
validates_inclusion_of :participant_visibility, :in => ['private', 'protected'] # presumably we might add public if we decide to show appointments on the public calendar feed
|
||||
validates_each :appointments do |record, attr, value|
|
||||
next unless record.new_appointments.present? || record.validation_event_override
|
||||
|
@ -55,8 +57,14 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
attr_accessible :title, :description, :location_name, :location_address, :context, :sub_context_codes, :participants_per_appointment, :min_appointments_per_participant, :max_appointments_per_participant, :new_appointments, :participant_visibility, :cancel_reason
|
||||
attr_readonly :context_id, :context_type, :context_code
|
||||
def validate
|
||||
if appointment_group_contexts.empty?
|
||||
errors.add(:appointment_group_contexts,
|
||||
t('errors.needs_contexts', 'Must have at least one context'))
|
||||
end
|
||||
end
|
||||
|
||||
attr_accessible :title, :description, :location_name, :location_address, :contexts, :sub_context_codes, :participants_per_appointment, :min_appointments_per_participant, :max_appointments_per_participant, :new_appointments, :participant_visibility, :cancel_reason
|
||||
|
||||
# when creating/updating an appointment, you can give it a list of (new)
|
||||
# appointment times. these will be added to the existing appointment times
|
||||
|
@ -73,12 +81,22 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
end
|
||||
attr_accessor :validation_event_override
|
||||
attr_accessor :cancel_reason
|
||||
attr_accessor :context
|
||||
|
||||
def reload
|
||||
remove_instance_variable :@new_appointments if @new_appointments
|
||||
super
|
||||
end
|
||||
|
||||
def contexts=(new_contexts)
|
||||
new_contexts -= self.contexts
|
||||
self.appointment_group_contexts += new_contexts.map do |context|
|
||||
AppointmentGroupContext.create! :appointment_group => self,
|
||||
:context => context
|
||||
end
|
||||
appointments.update_all :effective_context_code => contexts.map(&:asset_string).join(",")
|
||||
end
|
||||
|
||||
def sub_context_codes=(codes)
|
||||
if new_record?
|
||||
sub_contexts = codes.map do |code|
|
||||
|
@ -104,11 +122,13 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
codes = user.appointment_context_codes
|
||||
{
|
||||
:select => "DISTINCT appointment_groups.*",
|
||||
:joins => "LEFT JOIN appointment_group_sub_contexts sc " \
|
||||
:joins => "JOIN appointment_group_contexts agc " \
|
||||
"ON appointment_groups.id = agc.appointment_group_id " \
|
||||
"LEFT JOIN appointment_group_sub_contexts sc " \
|
||||
"ON appointment_groups.id = sc.appointment_group_id",
|
||||
:conditions => [<<-COND, codes[:primary], codes[:secondary]]
|
||||
workflow_state = 'active'
|
||||
AND context_code IN (?)
|
||||
AND agc.context_code IN (?)
|
||||
AND (
|
||||
sc.sub_context_code IS NULL
|
||||
OR sc.sub_context_code IN (?)
|
||||
|
@ -128,13 +148,15 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
end
|
||||
{
|
||||
:select => "DISTINCT appointment_groups.*",
|
||||
:joins => "LEFT JOIN appointment_group_sub_contexts sc " \
|
||||
:joins => "JOIN appointment_group_contexts agc " \
|
||||
"ON appointment_groups.id = agc.appointment_group_id " \
|
||||
"LEFT JOIN appointment_group_sub_contexts sc " \
|
||||
"ON appointment_groups.id = sc.appointment_group_id",
|
||||
:conditions => [<<-COND, codes[:full] + codes[:limited], codes[:full], codes[:secondary]]
|
||||
workflow_state <> 'deleted'
|
||||
AND context_code IN (?)
|
||||
AND agc.context_code IN (?)
|
||||
AND (
|
||||
context_code IN (?)
|
||||
agc.context_code IN (?)
|
||||
OR sc.sub_context_code IN (?)
|
||||
)
|
||||
COND
|
||||
|
@ -153,9 +175,13 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
set_policy do
|
||||
given { |user, session|
|
||||
next false if deleted?
|
||||
next false unless cached_context_grants_right?(user, nil, :manage_calendar)
|
||||
next false unless contexts.all? { |c| c.grants_right? user, nil, :manage_calendar }
|
||||
if appointment_group_sub_contexts.present?
|
||||
raise "you can't have multiple contexts and sub_contexts" if appointment_group_contexts.size > 1
|
||||
context = contexts.first
|
||||
next true if appointment_group_sub_contexts.any? { |sc| sc.sub_context_type == 'CourseSection' && context.section_visibilities_for(user).any?{ |v| sc.sub_context_id == v[:course_section_id] } }
|
||||
!context.visibility_limited_to_course_sections?(user)
|
||||
end
|
||||
!contexts.all? { |c| c.visibility_limited_to_course_sections?(user) }
|
||||
}
|
||||
can :manage and can :manage_calendar and can :read and can :read_appointment_participants and
|
||||
can :create and can :update and can :delete
|
||||
|
@ -177,15 +203,15 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
set_broadcast_policy do
|
||||
dispatch :appointment_group_published
|
||||
to { possible_users }
|
||||
whenever { context.available? && active? && workflow_state_changed? }
|
||||
whenever { contexts.any?(&:available?) && active? && workflow_state_changed? }
|
||||
|
||||
dispatch :appointment_group_updated
|
||||
to { possible_users }
|
||||
whenever { context.available? && active? && new_appointments && !workflow_state_changed? }
|
||||
whenever { contexts.any?(&:available?) && active? && new_appointments && !workflow_state_changed? }
|
||||
|
||||
dispatch :appointment_group_deleted
|
||||
to { possible_users }
|
||||
whenever { context.available? && deleted? && workflow_state_changed? }
|
||||
whenever { contexts.any?(&:available?) && deleted? && workflow_state_changed? }
|
||||
end
|
||||
|
||||
def possible_users
|
||||
|
@ -195,17 +221,20 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def instructors
|
||||
sub_context_type == 'CourseSection' ?
|
||||
context.participating_instructors.restrict_to_sections(sub_context_id).uniq :
|
||||
context.participating_instructors.uniq
|
||||
if sub_context_type == "CourseSection"
|
||||
contexts.map { |c| c.participating_instructors.restrict_to_sections(sub_context_id) }.flatten.uniq
|
||||
else
|
||||
contexts.map(&:participating_instructors).flatten.uniq
|
||||
end
|
||||
end
|
||||
|
||||
def possible_participants(registration_status=nil)
|
||||
participants = if participant_type == 'User'
|
||||
sub_contexts.empty? ?
|
||||
context.participating_students :
|
||||
contexts.map(&:participating_students).flatten :
|
||||
sub_contexts.map(&:participating_students).flatten
|
||||
else
|
||||
# FIXME?
|
||||
sub_contexts.map(&:groups).flatten
|
||||
end
|
||||
participant_ids = self.participant_ids
|
||||
|
@ -242,7 +271,7 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
def eligible_participant?(participant)
|
||||
return false unless participant && participant.class.base_ar_class.name == participant_type
|
||||
codes = participant.appointment_context_codes
|
||||
return false unless codes[:primary].include?(context_code)
|
||||
return false unless (codes[:primary]. & appointment_group_contexts.map(&:context_code)).present?
|
||||
return false unless sub_context_codes.empty? || (codes[:secondary] & sub_context_codes).present?
|
||||
true
|
||||
end
|
||||
|
@ -337,7 +366,6 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def default_values
|
||||
self.context_code ||= context_string
|
||||
self.participant_visibility ||= 'private'
|
||||
end
|
||||
|
||||
|
@ -357,4 +385,21 @@ class AppointmentGroup < ActiveRecord::Base
|
|||
self.appointments.map{ |a| a.destroy(false) }
|
||||
end
|
||||
end
|
||||
|
||||
def contexts_for_user(user)
|
||||
context_codes = context_codes_for_user(user)
|
||||
course_ids = appointment_group_contexts.all(:conditions => {:context_code => context_codes}).map(&:context_id)
|
||||
Course.all(:conditions => {:id => course_ids})
|
||||
end
|
||||
|
||||
def context_codes_for_user(user)
|
||||
manageable_codes = user.manageable_appointment_context_codes
|
||||
user_codes = user.appointment_context_codes[:primary] |
|
||||
manageable_codes[:full] | manageable_codes[:limited]
|
||||
context_codes & user_codes
|
||||
end
|
||||
|
||||
def context_codes
|
||||
appointment_group_contexts.map(&:context_code)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Copyright (C) 2012 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 AppointmentGroupContext < ActiveRecord::Base
|
||||
belongs_to :appointment_group
|
||||
belongs_to :context, :polymorphic => true
|
||||
|
||||
attr_accessible :appointment_group, :context
|
||||
|
||||
before_validation :default_values
|
||||
|
||||
def default_values
|
||||
self.context_code ||= context_string
|
||||
end
|
||||
end
|
|
@ -24,10 +24,10 @@ class AppointmentGroupSubContext < ActiveRecord::Base
|
|||
|
||||
validates_each :sub_context do |record, attr, value|
|
||||
if record.participant_type == 'User'
|
||||
record.errors.add(attr, t('errors.invalid_course_section', 'Invalid course section')) unless value.blank? || value.is_a?(CourseSection) && value.course == record.appointment_group.context
|
||||
record.errors.add(attr, t('errors.invalid_course_section', 'Invalid course section')) unless value.blank? || value.is_a?(CourseSection) && record.appointment_group.contexts.any? { |c| c == value.course }
|
||||
else
|
||||
record.errors.add(attr, t('errors.missing_group_category', 'Group appointments must have a group category')) unless value.present? && value.is_a?(GroupCategory)
|
||||
record.errors.add(attr, t('errors.invalid_group_category', 'Invalid group category')) unless value && value.context == record.appointment_group.context
|
||||
record.errors.add(attr, t('errors.invalid_group_category', 'Invalid group category')) unless value && record.appointment_group.contexts.any? { |c| c == value.context }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ class Assignment < ActiveRecord::Base
|
|||
has_one :rubric, :through => :rubric_association
|
||||
has_one :teacher_enrollment, :class_name => 'TeacherEnrollment', :foreign_key => 'course_id', :primary_key => 'context_id', :include => :user, :conditions => ['enrollments.workflow_state = ?', 'active']
|
||||
belongs_to :context, :polymorphic => true
|
||||
alias_method :effective_context, :context
|
||||
belongs_to :cloned_item
|
||||
belongs_to :grading_standard
|
||||
belongs_to :group_category
|
||||
|
|
|
@ -125,7 +125,13 @@ class CalendarEvent < ActiveRecord::Base
|
|||
all_codes = codes | effectively_courses_codes
|
||||
group_codes = codes.grep(/\Aappointment_group_\d+\z/)
|
||||
codes -= group_codes
|
||||
{:conditions => [<<-SQL, all_codes, codes, group_codes, effectively_courses_codes, codes]}
|
||||
|
||||
codes_conditions = codes.map { |code|
|
||||
wildcard(quoted_table_name + '.effective_context_code', code, :delimiter => ',')
|
||||
}.join(" OR ")
|
||||
codes_conditions = self.connection.quote(false) if codes_conditions.blank?
|
||||
|
||||
{:conditions => [<<-SQL, all_codes, codes, group_codes, effectively_courses_codes]}
|
||||
calendar_events.context_code IN (?)
|
||||
AND (
|
||||
( -- explicit contexts (e.g. course_123)
|
||||
|
@ -137,7 +143,7 @@ class CalendarEvent < ActiveRecord::Base
|
|||
)
|
||||
OR ( -- own appointment_participants, or section events in the course
|
||||
calendar_events.context_code IN (?)
|
||||
AND calendar_events.effective_context_code IN (?)
|
||||
AND (#{codes_conditions})
|
||||
)
|
||||
)
|
||||
SQL
|
||||
|
@ -186,13 +192,13 @@ class CalendarEvent < ActiveRecord::Base
|
|||
|
||||
if parent_event
|
||||
self.effective_context_code = if appointment_group # appointment participant
|
||||
appointment_group.context_code if appointment_group.participant_type == 'User'
|
||||
appointment_group.appointment_group_contexts.map(&:context_code).join(',') if appointment_group.participant_type == 'User'
|
||||
else # e.g. section-level event
|
||||
parent_event.context_code
|
||||
end
|
||||
(locked? ? LOCKED_ATTRIBUTES : CASCADED_ATTRIBUTES).each{ |attr| send("#{attr}=", parent_event.send(attr)) }
|
||||
elsif context.is_a?(AppointmentGroup)
|
||||
self.effective_context_code = context.context_code
|
||||
self.effective_context_code = context.appointment_group_contexts.map(&:context_code).join(",")
|
||||
if new_record?
|
||||
AppointmentGroup::EVENT_ATTRIBUTES.each { |attr| send("#{attr}=", attr == :description ? context.description_html : context.send(attr)) }
|
||||
if locked?
|
||||
|
|
|
@ -162,7 +162,8 @@ class Course < ActiveRecord::Base
|
|||
has_many :content_exports
|
||||
has_many :course_imports
|
||||
has_many :alerts, :as => :context, :include => :criteria
|
||||
has_many :appointment_groups, :as => :context
|
||||
has_many :appointment_group_contexts, :as => :context
|
||||
has_many :appointment_groups, :through => :appointment_group_contexts
|
||||
has_many :appointment_participants, :class_name => 'CalendarEvent', :foreign_key => :effective_context_code, :primary_key => :asset_string, :conditions => "workflow_state = 'locked' AND parent_calendar_event_id IS NOT NULL"
|
||||
attr_accessor :import_source
|
||||
has_many :zip_file_imports, :as => :context
|
||||
|
|
|
@ -1680,7 +1680,9 @@ class User < ActiveRecord::Base
|
|||
|
||||
events = CalendarEvent.active.for_user_and_context_codes(self, context_codes).between(Time.now.utc, opts[:end_at]).scoped(:limit => opts[:limit]).reject(&:hidden?)
|
||||
events += Assignment.active.for_context_codes(context_codes).due_between(Time.now.utc, opts[:end_at]).scoped(:limit => opts[:limit]).include_submitted_count
|
||||
events += AppointmentGroup.manageable_by(self, context_codes).intersecting(Time.now.utc, opts[:end_at]).scoped(:limit => opts[:limit])
|
||||
appointment_groups = AppointmentGroup.manageable_by(self, context_codes).intersecting(Time.now.utc, opts[:end_at]).scoped(:limit => opts[:limit])
|
||||
appointment_groups.each { |ag| ag.context = ag.contexts_for_user(self).first }
|
||||
events += appointment_groups
|
||||
events.sort_by{|e| [e.start_at, e.title] }.uniq.first(opts[:limit])
|
||||
end
|
||||
|
||||
|
|
|
@ -41,10 +41,11 @@ button.single_item_done_button
|
|||
margin: 10px
|
||||
.unpublished-ag
|
||||
background-color: #f2f2f2
|
||||
.ag-context
|
||||
margin-bottom: 10px
|
||||
color: #666
|
||||
.ag-context a
|
||||
color: #666
|
||||
margin-bottom: 10px
|
||||
display: block
|
||||
.ag-x-of-x-signed-up
|
||||
font-size: 11px
|
||||
|
||||
|
@ -120,6 +121,40 @@ button.single_item_done_button
|
|||
margin: 0
|
||||
padding: 0
|
||||
|
||||
.ag_contexts_selector
|
||||
width: 225px
|
||||
.ag-menu-container
|
||||
position: relative
|
||||
.ag_contexts_menu
|
||||
position: absolute
|
||||
width: 223px
|
||||
background: white
|
||||
border: 1px solid #b6b6b6
|
||||
margin-top: -3px
|
||||
padding-bottom: 5px
|
||||
.ag-contexts
|
||||
+reset_list
|
||||
max-height: 150px
|
||||
overflow-y: auto
|
||||
.ag_sections
|
||||
+reset_list
|
||||
padding-left: 35px
|
||||
.ag_sections_toggle
|
||||
display: block
|
||||
width: 16px
|
||||
height: 16px
|
||||
float: left
|
||||
background-image: url(/images/jqueryui/icon_sprite.png)
|
||||
background-position: -16px -80px
|
||||
.ag-sections-expanded
|
||||
background-position: 0px -64px
|
||||
|
||||
.ag_contexts_done
|
||||
float: right
|
||||
|
||||
.hidden
|
||||
display: none
|
||||
|
||||
.delete-block-link
|
||||
+accessible_text_replacement
|
||||
display: block
|
||||
|
@ -154,6 +189,12 @@ button.single_item_done_button
|
|||
.context_id
|
||||
max-width: 200px
|
||||
|
||||
.select-calendar-container
|
||||
margin: 0 0 1.5em
|
||||
|
||||
.group-signup
|
||||
margin: 0 0 1.5em
|
||||
|
||||
#message_participants_form
|
||||
padding: 10px
|
||||
textarea
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
<span style="display: block;"><%= datetime_string(recent_event.start_at, :event, recent_event.end_at) %></span>
|
||||
<% end %>
|
||||
<% if show_context %>
|
||||
<span style="display: block; font-size: 0.8em;"><%= recent_event.effective_context.short_name %></span>
|
||||
<span style="display: block; font-size: 0.8em;">
|
||||
<%= recent_event.is_a?(CalendarEvent) ? recent_event.effective_context.short_name : recent_event.context.short_name %>
|
||||
</span>
|
||||
<% end %>
|
||||
</span>
|
||||
</span>
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
{{/if}}
|
||||
|
||||
<h3><a class="view_calendar_link" href="#">{{title}}</a></h3>
|
||||
{{#if context}}
|
||||
<div class='ag-context'><a href="{{context.url}}">{{context.name}}</a></div>
|
||||
{{/if}}
|
||||
<div class='ag-context'>
|
||||
{{#toSentence contexts}}<a href="{{url}}">{{name}}</a>{{/toSentence}}
|
||||
</div>
|
||||
{{#if location_name}}
|
||||
<div class="ag-location">
|
||||
<strong>{{#t "location"}}Location:{{/t}}</strong>
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<div class="ag_contexts_menu hidden">
|
||||
<ul class="ag-contexts"></ul>
|
||||
<button class="button small-button ag_contexts_done">{{#t "done"}}Done{{/t}}</button>
|
||||
</div>
|
|
@ -0,0 +1,13 @@
|
|||
<li>
|
||||
<a class="ag_sections_toggle"></a>
|
||||
<input type="checkbox" name="context_codes[]" value="{{asset_string}}" id="option_{{asset_string}}">
|
||||
<label for="option_{{asset_string}}">{{name}}</label>
|
||||
<ul class="ag_sections hidden">
|
||||
{{#each course_sections}}
|
||||
<li>
|
||||
<input type="checkbox" name="sections[]" value="{{asset_string}}" id="option_{{asset_string}}">
|
||||
<label for="option_{{asset_string}}">{{name}}</label>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
|
@ -8,33 +8,21 @@
|
|||
<b>{{#t "location"}}Location{{/t}}</b><br />
|
||||
<input type="text" name="location" style="width: 190px" value="{{appointment_group.location_name}}">
|
||||
</p>
|
||||
<p>
|
||||
<div class="select-calendar-container">
|
||||
<b>{{#t "calendar"}}Calendar{{/t}}</b><br />
|
||||
<select name="context_code" class="context_id">
|
||||
{{#each contexts}}
|
||||
{{#if can_create_appointment_groups}}
|
||||
<option value="{{asset_string}}">{{name}}</option>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</select>
|
||||
</p>
|
||||
<button class="button ag_contexts_selector"></button>
|
||||
<div class="ag-menu-container"></div>
|
||||
</div>
|
||||
<p>
|
||||
<input type="checkbox" class="group-signup-checkbox" id="group-signup-checkbox" name="use_group_signup" value="1" {{#ifEqual participant_type "Group"}}checked{{/ifEqual}}>
|
||||
<label for="group-signup-checkbox">Have students sign up in groups.</label>
|
||||
</p>
|
||||
<p>
|
||||
<div class="section-signup">
|
||||
<b>{{#t "course_section"}}Limit Signups to{{/t}}</b><br />
|
||||
<div class="section_select">
|
||||
</div>
|
||||
</div>
|
||||
<div class="group-signup" style="display: none">
|
||||
<b>{{#t "group_category"}}Group Category{{/t}}</b><br />
|
||||
<div class="group_select">
|
||||
<select name="group_category_id"></select>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="right-column-wrapper">
|
||||
<div class="time-block-list-wrapper">
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
class CreateAppointmentGroupContexts < ActiveRecord::Migration
|
||||
tag :predeploy
|
||||
|
||||
def self.up
|
||||
create_table :appointment_group_contexts do |t|
|
||||
t.references :appointment_group, :limit => 8
|
||||
t.string :context_code
|
||||
t.integer :context_id, :limit => 8
|
||||
t.string :context_type
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :appointment_group_contexts
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
class MigrateAppointmentGroupContexts < ActiveRecord::Migration
|
||||
tag :postdeploy
|
||||
|
||||
def self.up
|
||||
records = AppointmentGroup.all.map { |ag|
|
||||
{
|
||||
:appointment_group_id => ag.id,
|
||||
:context_code => ag.context_code,
|
||||
:context_type => ag.context_type,
|
||||
:context_id => ag.context_id,
|
||||
:updated_at => ag.updated_at,
|
||||
:created_at => ag.created_at
|
||||
}
|
||||
}
|
||||
|
||||
bulk_insert :appointment_group_contexts, records
|
||||
end
|
||||
|
||||
def self.down
|
||||
end
|
||||
end
|
|
@ -37,8 +37,20 @@ module Api::V1::CalendarEvent
|
|||
participant = nil
|
||||
|
||||
hash = api_json(event, user, session, :only => %w(id created_at updated_at start_at end_at all_day all_day_date title description location_address location_name workflow_state))
|
||||
hash['context_code'] = event.context_code
|
||||
hash['effective_context_code'] = event.effective_context_code if event.effective_context_code
|
||||
|
||||
appointment_group_id = (options[:appointment_group_id] || event.appointment_group.try(:id))
|
||||
|
||||
if event.effective_context_code
|
||||
if appointment_group_id
|
||||
codes_for_user = AppointmentGroup.find(appointment_group_id).contexts_for_user(user).map(&:asset_string)
|
||||
hash['context_code'] = (event.effective_context_code.split(',') & codes_for_user).first
|
||||
hash['effective_context_code'] = hash['context_code']
|
||||
else
|
||||
hash['effective_context_code'] = event.effective_context_code
|
||||
end
|
||||
end
|
||||
hash['context_code'] ||= event.context_code
|
||||
|
||||
hash["child_events_count"] = event.child_events.size
|
||||
hash['parent_event_id'] = event.parent_calendar_event_id
|
||||
hash['hidden'] = event.hidden?
|
||||
|
@ -50,7 +62,7 @@ module Api::V1::CalendarEvent
|
|||
hash['group'] = group_json(event.context, user, session, :include => ['users'])
|
||||
end
|
||||
end
|
||||
if appointment_group_id = (options[:appointment_group_id] || event.appointment_group.try(:id))
|
||||
if appointment_group_id
|
||||
hash['appointment_group_id'] = appointment_group_id
|
||||
hash['appointment_group_url'] = api_v1_appointment_group_url(appointment_group_id)
|
||||
if options[:current_participant] && event.has_asset?(options[:current_participant])
|
||||
|
@ -99,11 +111,12 @@ module Api::V1::CalendarEvent
|
|||
|
||||
def appointment_group_json(group, user, session, options={})
|
||||
orig_context = @context
|
||||
@context = group.context
|
||||
@context = group.contexts_for_user(user).first
|
||||
@user_json_is_admin = nil # when returning multiple groups, @current_user may be admin over some contexts but not others. so we need to recheck
|
||||
|
||||
include = options[:include] || []
|
||||
hash = api_json(group, user, session, :only => %w{id context_code created_at description end_at location_address location_name max_appointments_per_participant min_appointments_per_participant participants_per_appointment start_at title updated_at workflow_state participant_visibility}, :methods => :sub_context_codes)
|
||||
hash = api_json(group, user, session, :only => %w{id created_at description end_at location_address location_name max_appointments_per_participant min_appointments_per_participant participants_per_appointment start_at title updated_at workflow_state participant_visibility}, :methods => :sub_context_codes)
|
||||
hash['context_codes'] = group.context_codes_for_user(user)
|
||||
hash['requiring_action'] = group.requiring_action?(user)
|
||||
if group.new_appointments.present?
|
||||
hash['new_appointments'] = group.new_appointments.map{ |event| calendar_event_json(event, user, session, :skip_details => true, :appointment_group_id => group.id) }
|
||||
|
|
|
@ -25,7 +25,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
expected_fields = [
|
||||
'appointments_count', 'context_code', 'created_at', 'description',
|
||||
'appointments_count', 'context_codes', 'created_at', 'description',
|
||||
'end_at', 'id', 'location_address', 'location_name',
|
||||
'max_appointments_per_participant', 'min_appointments_per_participant',
|
||||
'participant_type', 'participant_visibility',
|
||||
|
@ -34,11 +34,11 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
]
|
||||
|
||||
it 'should return manageable appointment groups' do
|
||||
ag1 = @course.appointment_groups.create(:title => "something")
|
||||
ag1 = AppointmentGroup.create!(:title => "something", :contexts => [@course])
|
||||
cat = @course.group_categories.create
|
||||
ag2 = @course.appointment_groups.create(:title => "another", :sub_context_codes => [cat.asset_string])
|
||||
ag3 = Course.create.appointment_groups.create(:title => "inaccessible")
|
||||
ag4 = @course.appointment_groups.create(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]])
|
||||
ag2 = AppointmentGroup.create!(:title => "another", :contexts => [@course], :sub_context_codes => [cat.asset_string])
|
||||
ag3 = AppointmentGroup.create!(:title => "inaccessible", :contexts => [Course.create!])
|
||||
ag4 = AppointmentGroup.create!(:title => "past", :contexts => [@course], :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]])
|
||||
|
||||
json = api_call(:get, "/api/v1/appointment_groups?scope=manageable", {
|
||||
:controller => 'appointment_groups', :action => 'index', :format => 'json', :scope => 'manageable'})
|
||||
|
@ -49,36 +49,36 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it "should return past manageable appointment groups, if requested" do
|
||||
ag = @course.appointment_groups.create(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]], :contexts => [@course])
|
||||
json = api_call(:get, "/api/v1/appointment_groups?scope=manageable&include_past_appointments=1", {
|
||||
:controller => 'appointment_groups', :action => 'index', :format => 'json', :scope => 'manageable', :include_past_appointments => '1'})
|
||||
json.size.should eql 1
|
||||
end
|
||||
|
||||
it 'should return reservable appointment groups' do
|
||||
ag1 = @course.appointment_groups.create(:title => "can't reserve")
|
||||
ag1 = AppointmentGroup.create!(:title => "can't reserve", :contexts => [@course])
|
||||
ag1.publish!
|
||||
ag2 = Course.create.appointment_groups.create(:title => "me neither")
|
||||
ag2 = AppointmentGroup.create!(:title => "me neither", :contexts => [Course.create!])
|
||||
ag2.publish!
|
||||
|
||||
student_in_course :course => course(:active_all => true), :user => @me
|
||||
ag3 = @course.appointment_groups.create(:title => "enrollment not active")
|
||||
ag3 = AppointmentGroup.create!(:title => "enrollment not active", :contexts => [@course])
|
||||
ag3.publish!
|
||||
|
||||
student_in_course :course => course(:active_all => true), :user => @me, :active_all => true
|
||||
ag4 = @course.appointment_groups.create(:title => "unpublished")
|
||||
ag5 = @course.appointment_groups.create(:title => "no times")
|
||||
ag4 = AppointmentGroup.create!(:title => "unpublished", :contexts => [@course])
|
||||
ag5 = AppointmentGroup.create!(:title => "no times", :contexts => [@course])
|
||||
ag5.publish!
|
||||
|
||||
ag6 = @course.appointment_groups.create(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]])
|
||||
ag6 = AppointmentGroup.create!(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]], :contexts => [@course])
|
||||
ag6.publish!
|
||||
cat = @course.group_categories.create
|
||||
mygroup = cat.groups.create(:context => @course)
|
||||
mygroup.users << @me
|
||||
@me.reload
|
||||
ag7 = @course.appointment_groups.create(:title => "double yay", :sub_context_codes => [cat.asset_string], :new_appointments => [["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
ag7 = AppointmentGroup.create!(:title => "double yay", :sub_context_codes => [cat.asset_string], :new_appointments => [["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]], :contexts => [@course])
|
||||
ag7.publish!
|
||||
ag8 = @course.appointment_groups.create(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]])
|
||||
ag8 = AppointmentGroup.create!(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]], :contexts => [@course])
|
||||
ag8.publish!
|
||||
|
||||
json = api_call(:get, "/api/v1/appointment_groups?scope=reservable", {
|
||||
|
@ -91,7 +91,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
|
||||
it "should return past reservable appointment groups, if requested" do
|
||||
student_in_course :course => course(:active_all => true), :user => @me, :active_all => true
|
||||
ag = @course.appointment_groups.create(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "past", :new_appointments => [["#{Time.now.year - 1}-01-01 12:00:00", "#{Time.now.year - 1}-01-01 13:00:00"]], :contexts => [@course])
|
||||
ag.publish!
|
||||
json = api_call(:get, "/api/v1/appointment_groups?scope=reservable&include_past_appointments=1", {
|
||||
:controller => 'appointment_groups', :action => 'index', :format => 'json', :scope => 'reservable', :include_past_appointments => '1'})
|
||||
|
@ -99,7 +99,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should paginate appointment groups' do
|
||||
ids = 25.times.map { |i| @course.appointment_groups.create(:title => "#{i}").id }
|
||||
ids = 25.times.map { |i| AppointmentGroup.create!(:title => "#{i}".object_id, :contexts => [@course]) }
|
||||
json = api_call(:get, "/api/v1/appointment_groups?scope=manageable&per_page=10", {
|
||||
:controller => 'appointment_groups', :action => 'index', :format => 'json',
|
||||
:scope => 'manageable', :per_page => '10'})
|
||||
|
@ -114,7 +114,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should include appointments and child_events, if requested' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]], :contexts => [@course])
|
||||
student = student_in_course(:course => @course, :active_all => true).user
|
||||
ag.appointments.first.reserve_for student, @me
|
||||
@user = @me
|
||||
|
@ -136,7 +136,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should get a manageable appointment group' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
|
||||
json = api_call(:get, "/api/v1/appointment_groups/#{ag.id}", {
|
||||
:controller => 'appointment_groups', :action => 'show', :format => 'json', :id => ag.id.to_s})
|
||||
|
@ -149,7 +149,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should include child_events, if requested' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
student = student_in_course(:course => @course, :active_all => true).user
|
||||
ag.appointments.first.reserve_for student, @me
|
||||
@user = @me
|
||||
|
@ -169,7 +169,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
it 'should get a reservable appointment group' do
|
||||
student_in_course :course => course(:active_all => true), :user => @me, :active_all => true
|
||||
@user = @me
|
||||
ag = @course.appointment_groups.create(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]], :contexts => [@course])
|
||||
ag.publish!
|
||||
|
||||
json = api_call(:get, "/api/v1/appointment_groups/#{ag.id}", {
|
||||
|
@ -182,7 +182,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
it 'should require action until the min has been met' do
|
||||
student_in_course :course => course(:active_all => true), :user => @me, :active_all => true
|
||||
@user = @me
|
||||
ag = @course.appointment_groups.create(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]], :min_appointments_per_participant => 1)
|
||||
ag = AppointmentGroup.create!(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"]], :min_appointments_per_participant => 1, :contexts => [@course])
|
||||
ag.publish!
|
||||
appt = ag.appointments.first
|
||||
|
||||
|
@ -206,14 +206,14 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
@user = @me
|
||||
raw_api_call(:post, "/api/v1/appointment_groups",
|
||||
{:controller => 'appointment_groups', :action => 'create', :format => 'json'},
|
||||
{:appointment_group => {:context_code => @course.asset_string, :title => "ohai"} })
|
||||
{:appointment_group => {:context_codes => [@course.asset_string], :title => "ohai"} })
|
||||
JSON.parse(response.body)['status'].should == 'unauthorized'
|
||||
end
|
||||
|
||||
it 'should create a new appointment group' do
|
||||
json = api_call(:post, "/api/v1/appointment_groups",
|
||||
{:controller => 'appointment_groups', :action => 'create', :format => 'json'},
|
||||
{:appointment_group => {:context_code => @course.asset_string, :title => "ohai", :new_appointments => {'0' => ["2012-01-01 12:00:00", "2012-01-01 13:00:00"]}} })
|
||||
{:appointment_group => {:context_codes => [@course.asset_string], :title => "ohai", :new_appointments => {'0' => ["2012-01-01 12:00:00", "2012-01-01 13:00:00"]}} })
|
||||
json.keys.sort.should eql((expected_fields + ['new_appointments']).sort)
|
||||
json['start_at'].should eql "2012-01-01T12:00:00Z"
|
||||
json['end_at'].should eql "2012-01-01T13:00:00Z"
|
||||
|
@ -224,7 +224,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
it 'should create a new appointment group with a sub_context' do
|
||||
json = api_call(:post, "/api/v1/appointment_groups",
|
||||
{:controller => 'appointment_groups', :action => 'create', :format => 'json'},
|
||||
{:appointment_group => {:context_code => @course.asset_string, :sub_context_codes => [@course.default_section.asset_string], :title => "ohai"} })
|
||||
{:appointment_group => {:context_codes => [@course.asset_string], :sub_context_codes => [@course.default_section.asset_string], :title => "ohai"} })
|
||||
json.keys.sort.should eql expected_fields
|
||||
json['workflow_state'].should eql 'pending'
|
||||
json['sub_context_codes'].should eql [@course.default_section.asset_string]
|
||||
|
@ -233,7 +233,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
it 'should enforce update permissions' do
|
||||
student_in_course :course => course(:active_all => true), :user => @me, :active_all => true
|
||||
@user = @me
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
raw_api_call(:put, "/api/v1/appointment_groups/#{ag.id}",
|
||||
{:controller => 'appointment_groups', :action => 'update', :format => 'json', :id => ag.id.to_s},
|
||||
{:appointment_group => {:title => "lol"} })
|
||||
|
@ -241,7 +241,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should update an appointment group' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
json = api_call(:put, "/api/v1/appointment_groups/#{ag.id}",
|
||||
{:controller => 'appointment_groups', :action => 'update', :format => 'json', :id => ag.id.to_s},
|
||||
{:appointment_group => {:title => "lol"} })
|
||||
|
@ -250,7 +250,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should ignore updates to readonly fields' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
json = api_call(:put, "/api/v1/appointment_groups/#{ag.id}",
|
||||
{:controller => 'appointment_groups', :action => 'update', :format => 'json', :id => ag.id.to_s},
|
||||
{:appointment_group => {:title => "lol", :sub_context_codes => [@course.default_section.asset_string]} })
|
||||
|
@ -260,7 +260,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
end
|
||||
|
||||
it 'should publish an appointment group in an update through the api' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
ag.workflow_state.should == 'pending'
|
||||
json = api_call(:put, "/api/v1/appointment_groups/#{ag.id}",
|
||||
{:controller => 'appointment_groups', :action => 'update', :format => 'json', :id => ag.id.to_s},
|
||||
|
@ -272,7 +272,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
it 'should publish an appointment group when creating through the api when requested' do
|
||||
json = api_call(:post, "/api/v1/appointment_groups",
|
||||
{:controller => 'appointment_groups', :action => 'create', :format => 'json'},
|
||||
{:appointment_group => {:context_code => @course.asset_string, :title => "ohai", :new_appointments => {'0' => ["2012-01-01 12:00:00", "2012-01-01 13:00:00"]}, :publish => '1'} })
|
||||
{:appointment_group => {:context_codes => [@course.asset_string], :title => "ohai", :new_appointments => {'0' => ["2012-01-01 12:00:00", "2012-01-01 13:00:00"]}, :publish => '1'} })
|
||||
json['workflow_state'].should eql 'active'
|
||||
AppointmentGroup.find(json['id']).workflow_state.should eql 'active'
|
||||
end
|
||||
|
@ -280,14 +280,14 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
it 'should enforce delete permissions' do
|
||||
student_in_course :course => course(:active_all => true), :user => @me, :active_all => true
|
||||
@user = @me
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
raw_api_call(:delete, "/api/v1/appointment_groups/#{ag.id}",
|
||||
{:controller => 'appointment_groups', :action => 'destroy', :format => 'json', :id => ag.id.to_s})
|
||||
JSON.parse(response.body)['status'].should == 'unauthorized'
|
||||
end
|
||||
|
||||
it 'should delete an appointment group' do
|
||||
ag = @course.appointment_groups.create(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag = AppointmentGroup.create!(:title => "something", :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
json = api_call(:delete, "/api/v1/appointment_groups/#{ag.id}",
|
||||
{:controller => 'appointment_groups', :action => 'destroy', :format => 'json', :id => ag.id.to_s})
|
||||
json.keys.sort.should eql expected_fields
|
||||
|
@ -297,7 +297,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
|
||||
types = {
|
||||
'users' => proc {
|
||||
@ag = @course.appointment_groups.create(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@ag = AppointmentGroup.create!(:title => "yay", :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]], :contexts => [@course])
|
||||
@ag.publish!
|
||||
student1 = student_in_course(:course => @course, :active_all => true).user
|
||||
@ag.appointments.first.reserve_for student1, @me
|
||||
|
@ -305,7 +305,7 @@ describe AppointmentGroupsController, :type => :integration do
|
|||
},
|
||||
'groups' => proc {
|
||||
cat = @course.group_categories.create
|
||||
@ag = @course.appointment_groups.create(:title => "yay", :sub_context_codes => [cat.asset_string], :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@ag = AppointmentGroup.create!(:title => "yay", :sub_context_codes => [cat.asset_string], :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]], :contexts => [@course])
|
||||
@ag.publish!
|
||||
group1 = cat.groups.create(:context => @course)
|
||||
group1.users << student_in_course(:course => @course, :active_all => true).user
|
||||
|
|
|
@ -120,7 +120,7 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
|
||||
context 'appointments' do
|
||||
it 'should include appointments for teachers (with participant info)' do
|
||||
ag1 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag1 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
event1 = ag1.appointments.first
|
||||
student_ids = []
|
||||
3.times {
|
||||
|
@ -129,7 +129,7 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
}
|
||||
|
||||
cat = @course.group_categories.create
|
||||
ag2 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
ag2 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
event2 = ag2.appointments.first
|
||||
group_ids = []
|
||||
group_student_ids = []
|
||||
|
@ -172,13 +172,13 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
@teacher = @course.admins.first
|
||||
|
||||
student_in_course :course => @course, :user => @me, :active_all => true
|
||||
group1 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
group1 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
group1.publish!
|
||||
event1 = group1.appointments.first
|
||||
3.times { event1.reserve_for(student_in_course(:course => @course, :active_all => true).user, @teacher) }
|
||||
|
||||
cat = @course.group_categories.create
|
||||
group2 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
group2 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
group2.publish!
|
||||
event2 = group2.appointments.first
|
||||
g = cat.groups.create(:context => @course)
|
||||
|
@ -208,7 +208,7 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
@teacher = @course.admins.first
|
||||
|
||||
student_in_course :course => @course, :user => @me, :active_all => true
|
||||
group = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :participant_visibility => 'private', :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
group = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :participant_visibility => 'private', :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
group.publish!
|
||||
event = group.appointments.first
|
||||
event.reserve_for(@me, @teacher)
|
||||
|
@ -231,7 +231,7 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
@teacher = @course.admins.first
|
||||
|
||||
student_in_course :course => @course, :user => @me, :active_all => true
|
||||
group = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :participant_visibility => 'protected', :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
group = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :participant_visibility => 'protected', :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
group.publish!
|
||||
event = group.appointments.first
|
||||
event.reserve_for(@me, @teacher)
|
||||
|
@ -257,8 +257,15 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
@teacher = @course.admins.first
|
||||
student_in_course :course => @course, :user => @me, :active_all => true
|
||||
otherguy = student_in_course(:course => @course, :active_all => true).user
|
||||
ag1 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
|
||||
course1 = @course
|
||||
course_with_teacher(:user => @teacher, :active_all => true)
|
||||
course2, @course = @course, course1
|
||||
|
||||
ag1 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [course2])
|
||||
ag1.publish!
|
||||
ag1.contexts = [course1, course2]
|
||||
ag1.save!
|
||||
event1 = ag1.appointments.first
|
||||
my_personal_appointment = event1.reserve_for(@me, @me)
|
||||
event1.reserve_for(otherguy, otherguy)
|
||||
|
@ -269,7 +276,8 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
othergroup = cat.groups.create(:context => @course)
|
||||
othergroup.users << otherguy
|
||||
@me.reload
|
||||
ag2 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
|
||||
ag2 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [course1, course2])
|
||||
ag2.publish!
|
||||
event2 = ag2.appointments.first
|
||||
my_group_appointment = event2.reserve_for(mygroup, @me)
|
||||
|
@ -322,7 +330,7 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
|
||||
student_in_course(:course => @course, :user => (@other_guy = user), :active_all => true)
|
||||
|
||||
@ag1 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00", "2012-01-01 13:00:00", "2012-01-01 14:00:00"]])
|
||||
@ag1 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00", "2012-01-01 13:00:00", "2012-01-01 14:00:00"]], :contexts => [@course])
|
||||
@ag1.publish!
|
||||
@event1 = @ag1.appointments.first
|
||||
@event2 = @ag1.appointments.last
|
||||
|
@ -333,7 +341,7 @@ describe CalendarEventsApiController, :type => :integration do
|
|||
@group.users << @other_guy
|
||||
@other_group = cat.groups.create(:context => @course)
|
||||
@me.reload
|
||||
@ag2 = @course.appointment_groups.create(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]])
|
||||
@ag2 = AppointmentGroup.create!(:title => "something", :participants_per_appointment => 4, :sub_context_codes => [cat.asset_string], :new_appointments => [["2012-01-01 12:00:00", "2012-01-01 13:00:00"]], :contexts => [@course])
|
||||
@ag2.publish!
|
||||
@event3 = @ag2.appointments.first
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ def appointment_group_model(opts={})
|
|||
if sub_context = opts.delete(:sub_context)
|
||||
opts[:sub_context_codes] = [sub_context.asset_string]
|
||||
end
|
||||
@appointment_group = @course.appointment_groups.create!(valid_appointment_group_attributes.merge(opts))
|
||||
@appointment_group = AppointmentGroup.create!(valid_appointment_group_attributes.merge(opts))
|
||||
@appointment_group
|
||||
end
|
||||
|
||||
|
@ -61,6 +61,7 @@ end
|
|||
|
||||
def valid_appointment_group_attributes
|
||||
{
|
||||
:title => "some title"
|
||||
:title => "some title",
|
||||
:contexts => [@course]
|
||||
}
|
||||
end
|
||||
|
|
|
@ -21,11 +21,11 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
|
||||
describe 'appointment_group_deleted.email' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
course_with_student(:active_all => true)
|
||||
appointment_group_model(:contexts => [@course])
|
||||
@appointment_group.cancel_reason = 'just because'
|
||||
|
||||
generate_message(:appointment_group_deleted, :email, @appointment_group)
|
||||
generate_message(:appointment_group_deleted, :email, @appointment_group, :user => @user)
|
||||
|
||||
@message.subject.should include('some title')
|
||||
@message.body.should include('some title')
|
||||
|
|
|
@ -21,11 +21,11 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
|
||||
describe 'appointment_group_deleted.facebook' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
student_in_course(:active_all => true)
|
||||
appointment_group_model(:contexts => [@course])
|
||||
@appointment_group.cancel_reason = 'just because'
|
||||
|
||||
generate_message(:appointment_group_deleted, :facebook, @appointment_group)
|
||||
generate_message(:appointment_group_deleted, :facebook, @appointment_group, :user => @user)
|
||||
|
||||
@message.body.should include('some title')
|
||||
@message.body.should include('just because')
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_deleted.sms' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
@appointment_group.cancel_reason = 'just because'
|
||||
|
||||
generate_message(:appointment_group_deleted, :sms, @appointment_group)
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_deleted.twitter' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
@appointment_group.cancel_reason = 'just because'
|
||||
|
||||
generate_message(:appointment_group_deleted, :twitter, @appointment_group)
|
||||
|
|
|
@ -21,10 +21,10 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
|
||||
describe 'appointment_group_published.email' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
course_with_student(:active_all => true)
|
||||
appointment_group_model(:contexts => [@course])
|
||||
|
||||
generate_message(:appointment_group_published, :email, @appointment_group)
|
||||
generate_message(:appointment_group_published, :email, @appointment_group, :user => @user)
|
||||
|
||||
@message.subject.should include('some title')
|
||||
@message.body.should include('some title')
|
||||
|
@ -36,7 +36,7 @@ describe 'appointment_group_published.email' do
|
|||
user = user_model
|
||||
@course = course_model
|
||||
cat = @course.group_categories.create(:name => 'teh category')
|
||||
appointment_group_model(:context => @course, :sub_context => cat)
|
||||
appointment_group_model(:contexts => [@course], :sub_context => cat)
|
||||
|
||||
generate_message(:appointment_group_published, :email, @appointment_group)
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
|
||||
describe 'appointment_group_published.facebook' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
course_with_student(:active_all => true)
|
||||
appointment_group_model(:contexts => [@course])
|
||||
|
||||
generate_message(:appointment_group_published, :facebook, @appointment_group)
|
||||
generate_message(:appointment_group_published, :facebook, @appointment_group, :user => @user)
|
||||
|
||||
@message.body.should include('some title')
|
||||
@message.body.should include(@course.name)
|
||||
|
@ -35,7 +35,7 @@ describe 'appointment_group_published.facebook' do
|
|||
user = user_model
|
||||
@course = course_model
|
||||
cat = @course.group_categories.create(:name => 'teh category')
|
||||
appointment_group_model(:context => @course, :sub_context => cat)
|
||||
appointment_group_model(:contexts => [@course], :sub_context => cat)
|
||||
|
||||
generate_message(:appointment_group_published, :facebook, @appointment_group)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_published.sms' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
|
||||
generate_message(:appointment_group_published, :sms, @appointment_group)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_published.summary' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
|
||||
generate_message(:appointment_group_published, :summary, @appointment_group)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_published.twitter' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
|
||||
generate_message(:appointment_group_published, :twitter, @appointment_group)
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
|
||||
describe 'appointment_group_updated.email' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
user = course_with_student(:active_all => true)
|
||||
appointment_group_model(:contexts => [@course])
|
||||
|
||||
generate_message(:appointment_group_updated, :email, @appointment_group)
|
||||
generate_message(:appointment_group_updated, :email, @appointment_group, :user => @user)
|
||||
|
||||
@message.subject.should include('some title')
|
||||
@message.body.should include('some title')
|
||||
|
@ -36,7 +36,7 @@ describe 'appointment_group_updated.email' do
|
|||
user = user_model
|
||||
@course = course_model
|
||||
cat = @course.group_categories.create(:name => 'teh category')
|
||||
appointment_group_model(:context => @course, :sub_context => cat)
|
||||
appointment_group_model(:contexts => [@course], :sub_context => cat)
|
||||
|
||||
generate_message(:appointment_group_updated, :email, @appointment_group)
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
|
||||
describe 'appointment_group_updated.facebook' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
course_with_student(:active_all => true)
|
||||
appointment_group_model(:contexts => [@course])
|
||||
|
||||
generate_message(:appointment_group_updated, :facebook, @appointment_group)
|
||||
generate_message(:appointment_group_updated, :facebook, @appointment_group, :user => @user)
|
||||
|
||||
@message.body.should include('some title')
|
||||
@message.body.should include(@course.name)
|
||||
|
@ -35,7 +35,7 @@ describe 'appointment_group_updated.facebook' do
|
|||
user = user_model
|
||||
@course = course_model
|
||||
cat = @course.group_categories.create(:name => 'teh category')
|
||||
appointment_group_model(:context => @course, :sub_context => cat)
|
||||
appointment_group_model(:contexts => [@course], :sub_context => cat)
|
||||
|
||||
generate_message(:appointment_group_updated, :facebook, @appointment_group)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_updated.sms' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
|
||||
generate_message(:appointment_group_updated, :sms, @appointment_group)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_updated.email' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
|
||||
generate_message(:appointment_group_updated, :summary, @appointment_group)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/messages_helper')
|
|||
describe 'appointment_group_updated.twitter' do
|
||||
it "should render" do
|
||||
user = user_model
|
||||
appointment_group_model(:context => course_model)
|
||||
appointment_group_model(:contexts => [course_model])
|
||||
|
||||
generate_message(:appointment_group_updated, :twitter, @appointment_group)
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ describe AppointmentGroup do
|
|||
it "should ensure the course section matches the course" do
|
||||
AppointmentGroup.new(
|
||||
:title => "test",
|
||||
:context => @course,
|
||||
:contexts => [@course],
|
||||
:sub_context_codes => [CourseSection.create.asset_string]
|
||||
).should_not be_valid
|
||||
end
|
||||
|
@ -35,7 +35,7 @@ describe AppointmentGroup do
|
|||
it "should ensure the group category matches the course" do
|
||||
AppointmentGroup.new(
|
||||
:title => "test",
|
||||
:context => @course,
|
||||
:contexts => [@course],
|
||||
:sub_context_codes => [GroupCategory.create.asset_string]
|
||||
).should_not be_valid
|
||||
end
|
||||
|
@ -43,18 +43,62 @@ describe AppointmentGroup do
|
|||
it "should ignore invalid sub context types" do
|
||||
group = AppointmentGroup.new(
|
||||
:title => "test",
|
||||
:context => @course,
|
||||
:contexts => [@course],
|
||||
:sub_context_codes => [Account.create.asset_string]
|
||||
)
|
||||
group.should be_valid
|
||||
group.sub_context_codes.should be_empty
|
||||
end
|
||||
|
||||
it "should only add contexts" do
|
||||
course1 = @course
|
||||
course_with_student(:active_all => true)
|
||||
course2 = @course
|
||||
|
||||
group = AppointmentGroup.new(
|
||||
:title => "test",
|
||||
:contexts => [course1],
|
||||
:sub_context_codes => [Account.create.asset_string]
|
||||
)
|
||||
|
||||
group.contexts = [course2]
|
||||
group.save!
|
||||
|
||||
group.contexts.should eql [course1, course2]
|
||||
|
||||
# also make sure you can't get duplicates
|
||||
group.contexts = [course1]
|
||||
group.save!
|
||||
group.contexts.should eql [course1, course2]
|
||||
end
|
||||
end
|
||||
|
||||
context "add context" do
|
||||
it "should update appointments effective_context_code" do
|
||||
course(:active_all => true)
|
||||
course1 = @course
|
||||
course(:active_all => true)
|
||||
course2 = @course
|
||||
|
||||
group = AppointmentGroup.create!(
|
||||
:title => "test",
|
||||
:contexts => [course1],
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']]
|
||||
)
|
||||
|
||||
group.appointments.map(&:effective_context_code).should eql [course1.asset_string]
|
||||
|
||||
group.contexts = [course1, course2]
|
||||
group.save!
|
||||
group.reload
|
||||
group.appointments.map(&:effective_context_code).should eql ["#{course1.asset_string},#{course2.asset_string}"]
|
||||
end
|
||||
end
|
||||
|
||||
context "add_appointment" do
|
||||
before do
|
||||
course_with_student(:active_all => true)
|
||||
@ag = AppointmentGroup.create!(:title => "test", :context => @course, :new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']])
|
||||
@ag = AppointmentGroup.create!(:title => "test", :contexts => [@course], :new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']])
|
||||
@appointment = @ag.appointments.first
|
||||
@appointment.should_not be_nil
|
||||
end
|
||||
|
@ -117,22 +161,32 @@ describe AppointmentGroup do
|
|||
@course.enroll_user(@user, 'TaEnrollment', :section => section2, :limit_privileges_to_course_section => true).accept!
|
||||
@ta = @user
|
||||
|
||||
@g1 = AppointmentGroup.create(:title => "test", :context => @course)
|
||||
@g1 = AppointmentGroup.create(:title => "test", :contexts => [@course])
|
||||
@g1.publish!
|
||||
@g2 = AppointmentGroup.create(:title => "test", :context => @course)
|
||||
@g3 = AppointmentGroup.create(:title => "test", :context => @course, :sub_context_codes => [@course.default_section.asset_string])
|
||||
@g2 = AppointmentGroup.create(:title => "test", :contexts => [@course])
|
||||
@g3 = AppointmentGroup.create(:title => "test", :contexts => [@course], :sub_context_codes => [@course.default_section.asset_string])
|
||||
@g3.publish!
|
||||
@g4 = AppointmentGroup.create(:title => "test", :context => @course, :sub_context_codes => [gc.asset_string])
|
||||
@g4 = AppointmentGroup.create(:title => "test", :contexts => [@course], :sub_context_codes => [gc.asset_string])
|
||||
@g4.publish!
|
||||
@g5 = AppointmentGroup.create(:title => "test", :context => @course, :sub_context_codes => [section2.asset_string])
|
||||
@g5 = AppointmentGroup.create(:title => "test", :contexts => [@course], :sub_context_codes => [section2.asset_string])
|
||||
@g5.publish!
|
||||
@g6 = AppointmentGroup.create(:title => "test", :context => other_course)
|
||||
@g6 = AppointmentGroup.create(:title => "test", :contexts => [other_course])
|
||||
@g6.publish!
|
||||
|
||||
# multiple sub_contexts
|
||||
@g7 = AppointmentGroup.create(:title => "test", :context => @course, :sub_context_codes => [@course.default_section.asset_string, section2.asset_string])
|
||||
@g7 = AppointmentGroup.create(:title => "test", :contexts => [@course], :sub_context_codes => [@course.default_section.asset_string, section2.asset_string])
|
||||
@g7.publish!
|
||||
|
||||
# multiple contexts
|
||||
course_bak, teacher_bak = @course, @teacher
|
||||
course_with_teacher(:active_all => true)
|
||||
@course2, @teacher2 = @course, @teacher
|
||||
course_with_teacher(:user => @teacher2, :active_all => true)
|
||||
teacher_in_course(:course => @course)
|
||||
@course3, @teacher3, @course, @teacher = @course, @teacher, course_bak, teacher_bak
|
||||
@g8 = AppointmentGroup.create(:title => "test", :contexts => [@course2, @course3])
|
||||
@g8.publish!
|
||||
|
||||
@groups = [@g1, @g2, @g3, @g4, @g5, @g7]
|
||||
end
|
||||
|
||||
|
@ -169,6 +223,16 @@ describe AppointmentGroup do
|
|||
@g7.grants_right?(@student, nil, :reserve).should be_true
|
||||
@g7.grants_right?(@student_in_section2, nil, :reserve).should be_true
|
||||
@g7.grants_right?(@student_in_section3, nil, :reserve).should be_false
|
||||
|
||||
# multiple contexts
|
||||
@student_in_course1 = @student
|
||||
student_in_course(:course => @course2, :active_all => true)
|
||||
@student_in_course2 = @user
|
||||
student_in_course(:course => @course3, :active_all => true)
|
||||
@student_in_course3 = @user
|
||||
@g8.grants_right?(@student_in_course1, nil, :reserve).should be_false
|
||||
@g8.grants_right?(@student_in_course2, nil, :reserve).should be_true
|
||||
@g8.grants_right?(@student_in_course3, nil, :reserve).should be_true
|
||||
end
|
||||
|
||||
|
||||
|
@ -199,6 +263,11 @@ describe AppointmentGroup do
|
|||
visible_groups = AppointmentGroup.manageable_by(@student).sort_by(&:id)
|
||||
visible_groups.should eql []
|
||||
@groups.each{ |g| g.grants_right?(@student, nil, :manage).should be_false }
|
||||
|
||||
# multiple contexts
|
||||
@g8.grants_right?(@teacher, nil, :manage).should be_false # not in any courses
|
||||
@g8.grants_right?(@teacher2, nil, :manage).should be_true
|
||||
@g8.grants_right?(@teacher3, nil, :manage).should be_false # not in all courses
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -216,7 +285,7 @@ describe AppointmentGroup do
|
|||
channel.confirm
|
||||
end
|
||||
|
||||
@ag = @course.appointment_groups.create(:title => "test", :new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']])
|
||||
@ag = AppointmentGroup.create!(:title => "test", :contexts => [@course], :new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']])
|
||||
end
|
||||
|
||||
it "should notify all participants when publishing" do
|
||||
|
@ -244,7 +313,8 @@ describe AppointmentGroup do
|
|||
@unpublished_course.enroll_user(@student, 'StudentEnrollment')
|
||||
@unpublished_course.enroll_user(@teacher, 'TeacherEnrollment')
|
||||
|
||||
@ag = @unpublished_course.appointment_groups.create(:title => "test",
|
||||
@ag = AppointmentGroup.create!(:title => "test",
|
||||
:contexts => [@unpublished_course],
|
||||
:new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']])
|
||||
@ag.publish!
|
||||
@ag.messages_sent.should be_empty
|
||||
|
@ -258,7 +328,7 @@ describe AppointmentGroup do
|
|||
course_with_teacher(:active_all => true)
|
||||
@teacher = @user
|
||||
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :new_appointments => [['2012-01-01 17:00:00', '2012-01-01 18:00:00']])
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :new_appointments => [['2012-01-01 17:00:00', '2012-01-01 18:00:00']])
|
||||
appt = ag.appointments.first
|
||||
participants = 3.times.map {
|
||||
student_in_course(:course => @course, :active_all => true)
|
||||
|
@ -279,7 +349,7 @@ describe AppointmentGroup do
|
|||
before do
|
||||
course_with_teacher(:active_all => true)
|
||||
@teacher = @user
|
||||
@ag = @course.appointment_groups.create(:title => "test", :participants_per_appointment => 2, :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :participants_per_appointment => 2, :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@appointment = @ag.appointments.first
|
||||
@ag.reload.available_slots.should eql 4
|
||||
end
|
||||
|
@ -354,7 +424,7 @@ describe AppointmentGroup do
|
|||
@gc = @group1.group_category
|
||||
@group2 = @gc.groups.create!(:name => "group2")
|
||||
|
||||
@ag = @course.appointment_groups.create(:title => "test", :participants_per_appointment => 2, :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@ag = AppointmentGroup.create!(:title => "test", :contexts => [@course], :participants_per_appointment => 2, :new_appointments => [["#{Time.now.year + 1}-01-01 12:00:00", "#{Time.now.year + 1}-01-01 13:00:00"], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
end
|
||||
|
||||
it "should return possible participants" do
|
||||
|
|
|
@ -160,10 +160,13 @@ describe CalendarEvent do
|
|||
it "should return events implicitly tied to the contexts (via effective_context_string)" do
|
||||
@teacher = user
|
||||
@course.enroll_teacher(@teacher).accept!
|
||||
g1 = @course.appointment_groups.create(:title => "foo")
|
||||
course1 = @course
|
||||
course_with_teacher(@teacher)
|
||||
course2, @course = @course, course1
|
||||
g1 = AppointmentGroup.create(:title => "foo", :contexts => [course1, course2])
|
||||
g1.publish!
|
||||
a1 = g1.appointments.create.reserve_for(@student, @student)
|
||||
g2 = @course.appointment_groups.create(:title => "foo", :sub_context_codes => [@course.default_section.asset_string])
|
||||
g2 = AppointmentGroup.create(:title => "foo", :contexts => [@course], :sub_context_codes => [@course.default_section.asset_string])
|
||||
g2.publish!
|
||||
a2 = g2.appointments.create.reserve_for(@student, @student)
|
||||
pe = @course.calendar_events.create!
|
||||
|
@ -258,7 +261,7 @@ describe CalendarEvent do
|
|||
@student1 = @user
|
||||
@other_section = @course.course_sections.create!
|
||||
@other_course = Course.create!
|
||||
@ag = AppointmentGroup.create(:title => "test", :context => @course)
|
||||
@ag = AppointmentGroup.create(:title => "test", :contexts => [@course])
|
||||
@ag.publish!
|
||||
@appointment = @ag.appointments.create(:start_at => '2012-01-01 12:00:00', :end_at => '2012-01-01 13:00:00')
|
||||
end
|
||||
|
@ -280,7 +283,7 @@ describe CalendarEvent do
|
|||
@group = c1.groups.create(:context => @course)
|
||||
@group.users << @student1 << @student2
|
||||
|
||||
@ag2 = AppointmentGroup.create!(:title => "test", :context => @course, :sub_context_codes => [c1.asset_string])
|
||||
@ag2 = AppointmentGroup.create!(:title => "test", :contexts => [@course], :sub_context_codes => [c1.asset_string])
|
||||
@ag2.publish!
|
||||
@appointment2 = @ag2.appointments.create(:start_at => '2012-01-01 12:00:00', :end_at => '2012-01-01 13:00:00')
|
||||
|
||||
|
@ -337,7 +340,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should allow multiple participants in an appointment, up to the limit" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :participants_per_appointment => 2,
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :participants_per_appointment => 2,
|
||||
:new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
ag.publish!
|
||||
|
@ -356,7 +359,7 @@ describe CalendarEvent do
|
|||
it "should give preference to the calendar's appointment limit" do
|
||||
ag = AppointmentGroup.create!(
|
||||
:title => "testing...",
|
||||
:context => @course,
|
||||
:contexts => [@course],
|
||||
:participants_per_appointment => 2,
|
||||
:new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
|
@ -384,7 +387,7 @@ describe CalendarEvent do
|
|||
it "should revert to the appointment group's participant_limit when appropriate" do
|
||||
ag = AppointmentGroup.create!(
|
||||
:title => "testing...",
|
||||
:context => @course,
|
||||
:contexts => [@course],
|
||||
:participants_per_appointment => 2,
|
||||
:new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
|
@ -403,7 +406,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should not let participants exceed max_appointments_per_participant" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :max_appointments_per_participant => 1,
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :max_appointments_per_participant => 1,
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00'], ['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
ag.publish!
|
||||
|
@ -415,7 +418,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should cancel existing reservations if cancel_existing = true" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :max_appointments_per_participant => 1,
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :max_appointments_per_participant => 1,
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00'], ['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
ag.publish!
|
||||
|
@ -428,7 +431,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should enforce the section" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course.course_sections.create,
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course.course_sections.create],
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']]
|
||||
)
|
||||
ag.publish!
|
||||
|
@ -445,7 +448,7 @@ describe CalendarEvent do
|
|||
c2 = @course.group_categories.create
|
||||
g2 = c2.groups.create(:context => @course)
|
||||
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :sub_context_codes => [c1.asset_string],
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :sub_context_codes => [c1.asset_string],
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']]
|
||||
)
|
||||
appointment = ag.appointments.first
|
||||
|
@ -479,7 +482,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should unlock the appointment when the last reservation is canceled" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :participants_per_appointment => 2,
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :participants_per_appointment => 2,
|
||||
:new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
appointment = ag.appointments.first
|
||||
|
@ -497,7 +500,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should copy the group attributes to the initial appointments" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :description => "hello\nworld",
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :description => "hello\nworld",
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']]
|
||||
)
|
||||
e = ag.appointments.first
|
||||
|
@ -524,7 +527,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should copy the group attributes to subsequent appointments" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course)
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course])
|
||||
ag.update_attributes(
|
||||
:title => 'haha',
|
||||
:new_appointments => [['2012-01-01 12:00:00', '2012-01-01 13:00:00']]
|
||||
|
@ -540,7 +543,7 @@ describe CalendarEvent do
|
|||
end
|
||||
|
||||
it "should allow a user to re-reserve a slot after canceling" do
|
||||
ag = AppointmentGroup.create(:title => "test", :context => @course, :participants_per_appointment => 1,
|
||||
ag = AppointmentGroup.create(:title => "test", :contexts => [@course], :participants_per_appointment => 1,
|
||||
:new_appointments => [['2012-01-01 13:00:00', '2012-01-01 14:00:00']]
|
||||
)
|
||||
appointment = ag.appointments.first
|
||||
|
|
|
@ -319,7 +319,7 @@ describe Course do
|
|||
event2.updating_user = @teacher
|
||||
event2.save!
|
||||
event3 = event2.child_events.first
|
||||
appointment_group = @course.appointment_groups.create
|
||||
appointment_group = AppointmentGroup.create! :title => "ag", :contexts => [@course]
|
||||
appointment_group.publish!
|
||||
assignment = @course.assignments.create!
|
||||
|
||||
|
@ -2425,7 +2425,7 @@ describe Course, "conclusions" do
|
|||
context "appointment cancelation" do
|
||||
before do
|
||||
course_with_student(:active_all => true)
|
||||
@ag = @course.appointment_groups.create(:title => "test", :new_appointments => [['2010-01-01 13:00:00', '2010-01-01 14:00:00'], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@ag = AppointmentGroup.create!(:title => "test", :contexts => [@course], :new_appointments => [['2010-01-01 13:00:00', '2010-01-01 14:00:00'], ["#{Time.now.year + 1}-01-01 13:00:00", "#{Time.now.year + 1}-01-01 14:00:00"]])
|
||||
@ag.appointments.each do |a|
|
||||
a.reserve_for(@user, @user)
|
||||
end
|
||||
|
|
|
@ -1460,7 +1460,7 @@ describe User do
|
|||
describe "calendar_events_for_calendar" do
|
||||
it "should include own scheduled appointments" do
|
||||
course_with_student(:active_all => true)
|
||||
ag = @course.appointment_groups.create(:title => 'test appointment', :new_appointments => [[Time.now, Time.now + 1.hour], [Time.now + 1.hour, Time.now + 2.hour]])
|
||||
ag = AppointmentGroup.create!(:title => 'test appointment', :contexts => [@course], :new_appointments => [[Time.now, Time.now + 1.hour], [Time.now + 1.hour, Time.now + 2.hour]])
|
||||
ag.appointments.first.reserve_for(@user, @user)
|
||||
events = @user.calendar_events_for_calendar
|
||||
events.size.should eql 1
|
||||
|
@ -1470,7 +1470,7 @@ describe User do
|
|||
it "should include manageable appointments" do
|
||||
course(:active_all => true)
|
||||
@user = @course.instructors.first
|
||||
ag = @course.appointment_groups.create(:title => 'test appointment', :new_appointments => [[Time.now, Time.now + 1.hour]])
|
||||
ag = AppointmentGroup.create!(:title => 'test appointment', :contexts => [@course], :new_appointments => [[Time.now, Time.now + 1.hour]])
|
||||
events = @user.calendar_events_for_calendar
|
||||
events.size.should eql 1
|
||||
events.first.title.should eql 'test appointment'
|
||||
|
@ -1481,7 +1481,7 @@ describe User do
|
|||
it "should include manageable appointment groups" do
|
||||
course(:active_all => true)
|
||||
@user = @course.instructors.first
|
||||
ag = @course.appointment_groups.create(:title => 'test appointment', :new_appointments => [[Time.now, Time.now + 1.hour]])
|
||||
ag = AppointmentGroup.create!(:title => 'test appointment', :contexts => [@course], :new_appointments => [[Time.now, Time.now + 1.hour]])
|
||||
events = @user.upcoming_events
|
||||
events.size.should eql 1
|
||||
events.first.title.should eql 'test appointment'
|
||||
|
|
|
@ -9,12 +9,12 @@ shared_examples_for "calendar2 selenium tests" do
|
|||
tomorrow = Date.today.to_s
|
||||
default_params = {
|
||||
:title => "new appointment group",
|
||||
:context => @course,
|
||||
:contexts => [@course],
|
||||
:new_appointments => [
|
||||
[tomorrow + ' 12:00:00', tomorrow + ' 13:00:00'],
|
||||
]
|
||||
}
|
||||
ag = @course.appointment_groups.create!(default_params.merge(params))
|
||||
ag = AppointmentGroup.create!(default_params.merge(params))
|
||||
ag.publish!
|
||||
ag.title
|
||||
end
|
||||
|
|
|
@ -331,6 +331,16 @@ describe "dashboard" do
|
|||
assignment_menu.should include_text(assignment.title)
|
||||
end
|
||||
|
||||
it "should display appointment groups in todo list" do
|
||||
ag = AppointmentGroup.create! :title => "appointment group",
|
||||
:contexts => [@course],
|
||||
:new_appointments => [[Time.now.utc + 2.hour, Time.now.utc + 3.hour]]
|
||||
student_in_course(:course => @course, :active_all => true)
|
||||
ag.appointments.first.reserve_for(@student, @student)
|
||||
get "/"
|
||||
f('#right-side .events_list').text.should include 'appointment group'
|
||||
end
|
||||
|
||||
it "should show submitted essay quizzes in the todo list" do
|
||||
quiz_title = 'new quiz'
|
||||
student_in_course
|
||||
|
|
|
@ -9,9 +9,11 @@ describe "scheduler" do
|
|||
|
||||
def fill_out_appointment_group_form(new_appointment_text)
|
||||
driver.find_element(:css, '.create_link').click
|
||||
edit_form = driver.find_element(:id, 'edit_appointment_form')
|
||||
edit_form = f('#edit_appointment_form')
|
||||
keep_trying_until { edit_form.should be_displayed }
|
||||
replace_content(find_with_jquery('input[name="title"]'), new_appointment_text)
|
||||
f('.ag_contexts_selector').click
|
||||
f('[name="context_codes[]"]').click
|
||||
date_field = edit_form.find_element(:css, '.date_field')
|
||||
date_field.click
|
||||
wait_for_animations
|
||||
|
@ -300,7 +302,7 @@ describe "scheduler" do
|
|||
end
|
||||
|
||||
it "should allow me to override the participant limit on a slot-by-slot basis" do
|
||||
create_appointment_group :participants_per_appointment => 2, :context => @course
|
||||
create_appointment_group :participants_per_appointment => 2
|
||||
get "/calendar2"
|
||||
wait_for_ajaximations
|
||||
click_scheduler_link
|
||||
|
@ -325,6 +327,36 @@ describe "scheduler" do
|
|||
ag.appointments.first.participants_per_appointment.should be_nil
|
||||
end
|
||||
|
||||
it "should allow me to create a course with multiple contexts" do
|
||||
course1 = @course
|
||||
course_with_teacher(:user => @teacher, :active_all => true)
|
||||
get "/calendar2"
|
||||
click_scheduler_link
|
||||
fill_out_appointment_group_form('multiple contexts')
|
||||
course_box = f("[value=#{@course.asset_string}]")
|
||||
course_box.click
|
||||
ff('.ag_sections_toggle').last.click
|
||||
|
||||
# sections should get checked by their parent
|
||||
section_box = f("[value=#{@course.course_sections.first.asset_string}]")
|
||||
section_box[:checked].should be_true
|
||||
|
||||
# unchecking all sections should uncheck their parent
|
||||
section_box.click
|
||||
course_box[:checked].should be_false
|
||||
|
||||
# checking all sections should check parent
|
||||
section_box.click
|
||||
course_box[:checked].should be_true
|
||||
|
||||
driver.find_element(:css, '.ui-dialog-buttonset .ui-button-primary').click
|
||||
wait_for_ajaximations
|
||||
ag = AppointmentGroup.first
|
||||
ag.contexts.should include course1
|
||||
ag.contexts.should include @course
|
||||
ag.sub_contexts.should eql []
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "as a student" do
|
||||
|
@ -339,6 +371,22 @@ describe "scheduler" do
|
|||
wait_for_ajax_requests
|
||||
end
|
||||
|
||||
it "should let me reserve appointment groups for contexts I am in" do
|
||||
my_course = @course
|
||||
course_with_student(:active_all => true)
|
||||
other_course = @course
|
||||
|
||||
create_appointment_group(:contexts => [other_course, my_course])
|
||||
|
||||
get "/calendar2"
|
||||
click_scheduler_link
|
||||
wait_for_ajaximations
|
||||
click_appointment_link
|
||||
|
||||
reserve_appointment_manual(0)
|
||||
driver.find_element(:css, '.fc-event').should include_text "Reserved"
|
||||
end
|
||||
|
||||
it "should allow me to cancel existing reservation and sign up for the appointment group from the calendar" do
|
||||
tomorrow = (Date.today + 1).to_s
|
||||
create_appointment_group(:max_appointments_per_participant => 1,
|
||||
|
|
Loading…
Reference in New Issue