add users from courses/:id/users page

test plan:
1. go to /courses/:id/users
2. click 'add users'
3. should work much like the add users UI in
   the course settings -> users tab, but look
   a little different

Change-Id: Icec24a41385e595d8b79dc5a7232545f0aff926e
Reviewed-on: https://gerrit.instructure.com/18888
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Ryan Florence <ryanf@instructure.com>
Product-Review: Ryan Florence <ryanf@instructure.com>
QA-Review: Ryan Florence <ryanf@instructure.com>
This commit is contained in:
Ryan Florence 2013-03-20 09:33:16 -06:00
parent 3552fb3020
commit b18af81c24
25 changed files with 586 additions and 43 deletions

View File

@ -141,12 +141,12 @@ define [
_afterRender: ->
@cacheEls()
@createBindings()
@afterRender()
# TODO: remove this when `options.views` is removed
@renderViews() if @options.views
# renderChildViews must come last! so we don't cache all the
# renderChildViews must come after cacheEls so we don't cache all the
# child views elements, bind them to model data, etc.
@renderChildViews()
@afterRender()
##
# Define in subclasses to add behavior to your view, ie. creating
@ -295,5 +295,9 @@ define [
view.render()
@[selector] ?= view
hide: -> @$el.hide()
show: -> @$el.show()
toggle: -> @$el.toggle()
Backbone.View

View File

@ -16,16 +16,18 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require [
'compiled/models/CreateUserList'
'compiled/views/courses/roster/CreateUsersView'
'compiled/views/SelectView'
'jst/courses/roster/rosterUsers'
'compiled/collections/RosterUserCollection'
'compiled/collections/SectionCollection'
'compiled/views/InputFilterView'
'compiled/views/PaginatedCollectionView'
'compiled/views/courses/RosterUserView'
'compiled/views/courses/RosterView'
'compiled/views/courses/roster/RosterUserView'
'compiled/views/courses/roster/RosterView'
'jquery'
], (SelectView, rosterUsersTemplate, RosterUserCollection, SectionCollection, InputFilterView, PaginatedCollectionView, RosterUserView, RosterView, $) ->
], (CreateUserList, CreateUsersView, SelectView, rosterUsersTemplate, RosterUserCollection, SectionCollection, InputFilterView, PaginatedCollectionView, RosterUserView, RosterView, $) ->
fetchOptions =
include: ['avatar_url', 'enrollments', 'email']
@ -43,12 +45,20 @@ require [
template: rosterUsersTemplate
roleSelectView = new SelectView
collection: users
createUsersView = new CreateUsersView
model: new CreateUserList
sections: ENV.SECTIONS
roles: ENV.ALL_ROLES
readURL: ENV.USER_LISTS_URL
updateURL: ENV.ENROLL_USERS_URL
@app = new RosterView
usersView: usersView
inputFilterView: inputFilterView
roleSelectView: roleSelectView
createUsersView: createUsersView
collection: users
roles: ENV.ALL_ROLES
permissions: ENV.permissions
@app.render()
@app.$el.appendTo $('#content')

View File

@ -9,7 +9,10 @@ require [
], ($, preventDefault) ->
do ->
dialog = $('#dialog-buttons-dialog').dialog(autoOpen: false).data('dialog')
dialog = $('#dialog-buttons-dialog').dialog({
autoOpen: false
height: 200
}).data('dialog')
$('#show-dialog-buttons-dialog').click -> dialog.open()

View File

@ -14,6 +14,7 @@ define [
buttons = $.map $buttons.toArray(), (button) ->
$button = $(button)
classes = $button.attr('class') ? ''
id = $button.attr('id')
# if you add the class 'dialog_closer' to any of the buttons,
# clicking it will cause the dialog to close
@ -32,8 +33,9 @@ define [
"data-text-while-loading": $button.data("textWhileLoading")
click: -> $button.click()
class: classes
id: id
}
# put the primary button(s) on the far right
buttons = _.sortBy buttons, (button) ->
if button.class.match(/btn-primary/) then 1 else 0
$dialog.dialog "option", "buttons", buttons
$dialog.dialog "option", "buttons", buttons

View File

@ -0,0 +1,48 @@
define ['Backbone', 'underscore'], ({Model}, _) ->
class CreateUserList extends Model
defaults:
roles: null
sections: null
course_section_id: null
enrollment_type: null
user_list: null
readURL: null
updateURL: null
step: 1
enrolledUsers: null
present: ->
json = @attributes
json.course_section_id = parseInt json.course_section_id, 10
json
toJSON: ->
attrs = [
'course_section_id'
'enrollment_type'
'user_list'
'limit_privileges_to_course_section'
]
json = _.pick @attributes, attrs...
url: ->
if @get('step') is 1
@get 'readURL'
else
@get 'updateURL'
incrementStep: ->
@set 'step', @get('step') + 1
startOver: ->
@set 'users', null
@set 'step', 1
parse: (data) ->
if _.isArray(data)
enrolledUsers: data
else
data

View File

@ -39,6 +39,12 @@ define [
# will figure out the title from the trigger if null
title: null
width: null
height: null
fixDialogButtons: true
$dialogAppendTarget: $ 'body'
className: 'dialogFormView'
@ -98,8 +104,14 @@ define [
@$el.appendTo @$dialogAppendTarget
##
# @api private
setTrigger: ->
# If your trigger isn't rendered after this view (like a parent view
# contains the trigger) then you can set this manually (like in the
# parent views afterRender), otherwise it'll use the options.
#
# @api public
#
setTrigger: (el) ->
@options.trigger = el if el
return unless @options.trigger
@$trigger = $ @options.trigger
@attachTrigger()
@ -112,7 +124,7 @@ define [
##
# @api private
renderEl: =>
@$el.html @wrapperTemplate()
@$el.html @wrapperTemplate @toJSON()
@renderOutlet()
# reassign: only render the outlout now
@renderEl = @renderOutlet
@ -120,7 +132,7 @@ define [
##
# @api private
renderOutlet: =>
html = @template @model.toJSON()
html = @template @toJSON()
@$el.find('.outlet').html html
##
@ -137,10 +149,15 @@ define [
##
# @api private
setupDialog: ->
@$el.dialog
opts =
autoOpen: false
title: @getDialogTitle()
.fixDialogButtons()
close: => @trigger 'close'
open: => @trigger 'open'
opts.width = @options.width
opts.height = @options.height
@$el.dialog(opts)
@$el.fixDialogButtons() if @options.fixDialogButtons
@dialog = @$el.data 'dialog'
##

View File

@ -7,7 +7,7 @@ define [
'jquery.toJSON'
'jquery.disableWhileLoading'
'jquery.instructure_forms'
], (Backbone, ValidatedMixin, $, _, preventDefault) ->
], (Backbone, ValidatedMixin, $, _) ->
##
# Sets model data from a form, saves it, and displays errors returned in a
@ -45,7 +45,8 @@ define [
#
# @api public
# @returns jqXHR
submit: preventDefault ->
submit: (event) ->
event?.preventDefault()
@$el.hideErrors()
data = @getFormData()

View File

@ -0,0 +1,79 @@
define [
'compiled/models/CreateUserList'
'underscore'
'i18n!create_users_view'
'compiled/views/DialogFormView'
'jst/courses/roster/createUsers'
'jst/courses/roster/createUsersWrapper'
'vendor/jquery.placeholder'
], (CreateUserList, _, I18n, DialogFormView, template, wrapper) ->
class CreateUsersView extends DialogFormView
defaults:
width: 700
height: 500
els:
'#privileges': '$privileges'
'#user_list_textarea': '$textarea'
events: _.extend({}, @::events,
'click .createUsersStartOver': 'startOver'
'click .createUsersStartOverFrd': 'startOverFrd'
'change #enrollment_type': 'changeEnrollment'
'click #enrollment_type': 'changeEnrollment'
'click .dialog_closer': 'close'
)
template: template
wrapperTemplate: wrapper
initialize: ->
@model ?= new CreateUserList
super
attach: ->
@model.on 'change:step', @render, this
@model.on 'change:enrollment_type', @maybeShowPrivileges
maybeShowPrivileges: =>
if @model.get('enrollment_type') in ['TeacherEnrollment', 'TaEnrollment']
@$privileges.show()
else
@$privileges.hide()
changeEnrollment: (event) ->
@model.set 'enrollment_type', event.target.value
openAgain: ->
@startOverFrd()
super
hasUsers: ->
@model.get('users')?.length
onSaveSuccess: ->
@model.incrementStep()
validateBeforeSave: (data) ->
if @model.get('step') is 1 and !data.user_list
user_list: [{
type: 'required'
message: I18n.t('required', 'Please enter some email addresses')
}]
else
{}
startOver: ->
@model.startOver()
startOverFrd: ->
@model.startOver()
@$textarea?.val ''
afterRender: ->
@$('[placeholder]').placeholder()
@maybeShowPrivileges()

View File

@ -15,12 +15,29 @@ define [
@child 'roleSelectView', '[data-view=roleSelect]'
@child 'createUsersView', '[data-view=createUsers]'
@optionProperty 'roles'
@optionProperty 'permissions'
template: template
els:
'#addUsers': '$addUsersButton'
afterRender: ->
# its a child view so it gets rendered automatically, need to stop it
@createUsersView.hide()
# its trigger would not be rendered yet, set it manually
@createUsersView.setTrigger @$addUsersButton
attach: ->
@collection.on 'setParam deleteParam', @fetch
@createUsersView.on 'close', @fetchOnCreateUsersClose
fetchOnCreateUsersClose: =>
@collection.fetch() if @createUsersView.hasUsers()
fetch: =>
@lastRequest?.abort()

View File

@ -303,10 +303,24 @@ class ContextController < ApplicationController
if @context.is_a?(Course)
sections = @context.course_sections.select([:id, :name])
all_roles = Role.custom_roles_and_counts_for_course(@context, @current_user)
all_roles = Role.role_data(@context, @current_user)
js_env({
:ALL_ROLES => all_roles,
:SECTIONS => sections.map { |s| { :id => s.id, :name => s.name } }
:SECTIONS => sections.map { |s| { :id => s.id, :name => s.name } },
:USER_LISTS_URL => polymorphic_path([@context, :user_lists], :format => :json),
:ENROLL_USERS_URL => course_enroll_users_url(@context),
:permissions => {
:manage_students => (manage_students = @context.grants_right?(@current_user, session, :manage_students)),
:manage_admin_users => (manage_admins = @context.grants_right?(@current_user, session, :manage_admin_users)),
:add_users => manage_students || manage_admins
},
:course => {
:completed => (completed = @context.completed?),
:soft_concluded => (soft_concluded = @context.soft_concluded?),
:concluded => completed || soft_concluded,
:teacherless => @context.teacherless?,
:available => @context.available?
}
})
elsif @context.is_a?(Group)
@users = @context.participating_users.order_by_sortable_name.uniq

View File

@ -126,6 +126,34 @@ class Role < ActiveRecord::Base
@enrollment_types
end
def self.manageable_roles_by_user(user, course)
manageable = ['ObserverEnrollment', 'DesignerEnrollment']
if course.grants_right?(user, :manage_students)
manageable << 'StudentEnrollment'
end
if course.grants_right?(user, :manage_admin_users)
manageable << 'TeacherEnrollment'
manageable << 'TaEnrollment'
elsif course.teacherless?
manageable << 'TeacherEnrollment'
end
manageable.sort
end
def self.role_data(course, user, include_inactive=false)
manageable = Role.manageable_roles_by_user(user, course)
self.custom_roles_and_counts_for_course(course, user, include_inactive).inject([]) { |roles, role|
is_manageable = manageable.include?(role[:base_role_name])
role[:manageable_by_user] = is_manageable
roles << role
role[:custom_roles].each do |custom_role|
custom_role[:manageable_by_user] = is_manageable
roles << custom_role
end
roles
}
end
def self.built_in_role_names
@built_in_role_names ||= %w(AccountAdmin) + Enrollment.valid_types
end

View File

@ -14,3 +14,4 @@
@import "jquery.ui.theme";
@import "jquery.ui.menu";
@import "overrides";

View File

@ -0,0 +1,6 @@
@import "environment";
.ui-widget {
font-size: $baseFontSize;
}

View File

@ -63,33 +63,59 @@ We want to deprecate this in favor of `form-horizontal`.
}
}
/* @styleguide Forms: Dialog Buttons
/* @styleguide Forms: Dialog Form
Elements with the `.form-controls` class in dialogs will be displayed properly,
no need to use `fixDialogButtons` on them.
Add the class `form-dialog` to get the `form-controls` to display properly in a
dialog form and proper overflow scrolling of content. No need to use
`$.fn.fixDialogButtons`.
**Note**: You must wrap your content in `.form-dialog-content` and use the
height option for jQuery UI dialog. To get the scrolling and fixed form
controls on the bottom required this.
```html
<button id="show-dialog-buttons-dialog" class="btn">Show Dialog</button>
<div id="dialog-buttons-dialog">
<form class="form-inline">
<p>Aren't the form controls beautiful?</p>
<div class="form-controls">
<button class="btn btn-primary" type="button">Submit</button>
</div>
</form>
</div>
<form id="dialog-buttons-dialog" class="form-dialog">
<div class="form-dialog-content">
<p style="height: 1000px;">Aren't the form controls beautiful?<br> Scroll down ↓</p>
<p>Hooray for scrolling</p>
</div>
<div class="form-controls">
<button class="btn btn-primary" type="button">Submit</button>
</div>
</form>
```
*/
.ui-dialog .form-controls {
padding: 10px;
margin: 0 -1em !important;
background-color: #EFEFEF;
border-top: 1px solid #DDD;
box-shadow: inset 0 1px 0 white;
text-align: right;
position: relative;
bottom: -26px;
.form-dialog {
padding-bottom: 70px !important;
margin-bottom: 0;
.form-controls {
padding: 10px;
margin: 0;
background-color: #EFEFEF;
border-top: 1px solid #DDD;
box-shadow: inset 0 1px 0 white;
text-align: right;
position: absolute;
left: 0px;
right: 0px;
bottom: 0px;
}
.form-dialog-content {
// jQuery UI handles overflow on its own, but our buttons are inside the
// default scroll area, this gives us our own scrollable content area
// while still allowing us to use the height option in $.fn.dialog
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 51px;
overflow: auto;
padding: 20px;
}
}

View File

@ -9,7 +9,6 @@
<% content_for :right_side, render(:partial => 'context/roster_right_side') %>
<% if @context.is_a?(Course) %>
<% jammit_css :roster %>
<% js_bundle :roster %>
<% else %>
<% content_for :stylesheets do %>

View File

@ -0,0 +1,142 @@
{{#ifEqual step 1}}
<div class="form-dialog-content" id="create-users-step-1">
<p>
{{#t "form_instructions"}}
Type or paste a list of email addresses below:
{{/t}}<br>
</p>
<div class="row-fluid content-box">
<textarea id="user_list_textarea" name="user_list" class="span12" rows=7 placeholder='"Example Student" &lt;student@example.com&gt;, "Lastname, Firstname" &lt;firstlast@example.com&gt;, justAnEmailAddress@example.com'>{{user_list}}</textarea>
</div>
<div class="form-horizontal">
<div class="control-group">
<label class="control-label" for="enrollment_type">{{#t "user_role"}}Role:{{/t}}</label>
<div class="controls">
<select name="enrollment_type" id="enrollment_type">
{{#each roles}}
{{#if manageable_by_user}}
<option value="{{name}}" {{#ifEqual name ../../enrollment_type}}selected{{/ifEqual}}>{{label}}</option>
{{/if}}
{{/each}}
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="course_section_id">{{#t "section"}}Section{{/t}}</label>
<div class="controls">
<select name="course_section_id" id="course_section_id">
{{#each sections}}
<option value="{{id}}" {{#ifEqual id ../course_section_id}}selected{{/ifEqual}}>{{name}}</option>
{{/each}}
</select>
</div>
</div>
<div class="control-group" id="privileges">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="limit_privileges_to_course_section" name="limit_privileges_to_course_section" value="1" {{#if limit_privileges_to_course_section}}checked{{/if}}>
{{#t "can_only_grade_students_in_section"}}Can grade students in their section only{{/t}}
</label>
</div>
</div>
</div>
</div>
<div class="form-controls">
<button
id="next-step"
class="btn btn-primary"
data-text-while-loading='{{#t "validating"}}Validating...{{/t}}'
type="submit"
>{{#t "next"}}Next{{/t}}</button>
</div>
{{/ifEqual}}
{{#ifEqual step 2}}
<div class="form-dialog-content" id="create-users-step-2">
{{#if errored_users.length}}
<div class="alert alert-error content-box">
<p>
{{#t "will_not_be_added"}}These users had errors and will not be added. Please ensure they are formatted correctly.{{/t}}<br>
<small>{{#t "example_formats"}}Examples: user@example.com, "First Last" &lt;user@example.com&gt;, "Last, First" &lt;user@example.com&gt;{{/t}}</small>
</p>
<ul class="createUsersErroredUsers">
{{#each errored_users}}
<li>{{name}} {{address}}</li>
{{/each}}
</ul>
</div>
{{/if}}
{{#if users.length}}
<div class="alert alert-notify content-box">
{{#t "adding_n_users"}}Validated and ready to add {{users.length}} users:{{/t}}
{{#if duplicates.length}}
{{#t "duplicates_removed"}}Some duplicates were removed.{{/t}}
{{/if}}
</div>
<table class="table table-bordered table-striped table-condensed" id="create-users-verified">
<thead>
<tr>
<th>{{#t "name"}}Name{{/t}}</th>
<th>{{#t "email"}}Email{{/t}}</th>
</tr>
</thead>
<tbody>
{{#each users}}
<tr>
<td>{{name}}</td>
<td>{{address}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{/if}}
</div>
<div class="form-controls">
<button
type="button"
class="btn createUsersStartOver {{#unless users.length}}btn-primary{{/unless}}"
>{{#t "go_back"}}Start Over{{/t}}</button>
{{#if users.length}}
<button
id="createUsersAddButton"
class="btn btn-primary"
data-text-while-loading='{{#t "adding"}}Adding...{{/t}}'
type="submit"
>{{#t "add_these_users"}}Add Users{{/t}}</button>
{{/if}}
</div>
{{/ifEqual}}
{{#ifEqual step 3}}
<div class="form-dialog-content" id="create-users-step-3">
<p class="content-box alert alert-success">{{#t "have_been_enrolled"}}The following users have been enrolled{{/t}}</p>
<table class="table table-bordered table-striped table-condensed" id="create-users-results">
<thead>
<tr>
<th>{{#t "name"}}Name{{/t}}</th>
<th>{{#t "email"}}Email{{/t}}</th>
<th>{{#t "section"}}Section{{/t}}</th>
</tr>
</thead>
<tbody>
{{#each enrolledUsers}}
<tr>
<td>{{enrollment.name}}</td>
<td>{{enrollment.email}}</td>
<td>{{enrollment.section}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="form-controls">
<button
class="btn show-if-step-3 createUsersStartOverFrd"
>{{#t "add_more_users"}}Add More Users{{/t}}</button>
<button
type="button"
class="btn btn-primary show-if-step-3 dialog_closer"
>{{#t "close"}}Done{{/t}}</button>
</div>
{{/ifEqual}}

View File

@ -0,0 +1,2 @@
<div class="outlet"></div>

View File

@ -14,10 +14,24 @@
>
<option value="">{{#t "all_roles"}}All Roles{{/t}}</option>
{{#each roles}}
<option value="{{name}}">{{plural_label}}</option>
<option value="{{name}}">{{label}}</option>
{{/each}}
</select>
{{#if permissions.add_users}}
{{#if course.concluded}}
<a class="btn" title='{{#t "cannot_add_users"}}New users can not be added because this course is concluded{{/t}}' disabled data-tooltip>
{{else}}
<a
class="btn btn-primary pull-right icon-add"
id="addUsers"
title='{{#t "add_people"}}Add People{{/t}}'
>{{#t "add_people"}}Add People{{/t}}</a>
{{/if}}
{{/if}}
</div>
<form data-view="createUsers" class="form-dialog"></form>
<div data-view="users" class="v-gutter"></div>

View File

@ -102,9 +102,6 @@ stylesheets:
- public/stylesheets/compiled/grading_standards.css
login:
- public/stylesheets/compiled/login.css
roster:
- public/stylesheets/compiled/course_settings.css
- public/stylesheets/compiled/roster.css
roster_user:
- public/stylesheets/compiled/roster_user.css
learning_outcomes:

View File

@ -1,6 +1,7 @@
define ['jquery'], ($) ->
$.fn.toString = ->
return '' unless this.length
id = this.attr 'id'
className = this.attr('class').replace(/\s/g, '.')
tag = this[0].tagName.toLowerCase()
@ -9,12 +10,15 @@ define ['jquery'], ($) ->
str += ".#{className}" if className
"<#{str}>"
isVisible: ($el, message) ->
isVisible: ($el, message = '') ->
ok $el.length, "elements found"
ok $el.is(':visible'), "#{$el} is visible " + message
isHidden: ($el, message) ->
ok $el.length, "elements found"
ok !$el.is(':visible'), "#{$el} is hidden " + message
hasClass: ($el, className, message) ->
ok $el.length, "elements found"
ok $el.hasClass(className), "#{$el} has class #{className} " + message

View File

@ -0,0 +1,113 @@
define [
'compiled/views/courses/roster/CreateUsersView'
'compiled/models/CreateUserList'
'helpers/assertions'
], (CreateUsersView, CreateUserList, assert) ->
view = null
server = null
module 'CreateUsersView',
setup: ->
server = sinon.fakeServer.create()
server.respondWith("POST", "/read",
[200, { "Content-Type": "application/json" }, JSON.stringify({
users: [{address: 'joe@joe.com', name: null, type: 'email'}],
errored_users: [],
duplicates: []
})])
server.respondWith("POST", "/update",
[200, { "Content-Type": "application/json" }, JSON.stringify([
enrollment: {
name: 'joe@joe.com'
email: 'joe@joe.com'
section: 'MWF'
}
])])
view = new CreateUsersView
trigger: false
title: 'test'
model: new CreateUserList
sections: [
{id: 1, name: 'MWF'}
{id: 2, name: 'TTh'}
]
roles: [
{label: 'Teacher', name: 'TeacherEnrollment', manageable_by_user: true}
{label: 'Student', name: 'StudentEnrollment', manageable_by_user: true}
{label: 'Fake', name: 'Fake', manageable_by_user: false}
]
readURL: '/read'
updateURL: '/update'
$('#fixtures').append view.$el
view.open()
teardown: ->
server.restore()
view.remove()
addUserText = ->
view.$textarea.val "joe@joe.com"
goToStep2 = ->
$('#next-step').click()
server.respond()
goToStep3 = ->
$('#createUsersAddButton').click()
server.respond()
assertVerifiedUsers = ->
ok $('#create-users-verified').html().match('joe@joe.com'), 'verified users matched'
assertEnrolledUsers = ->
ok $('#create-users-results').html().match('joe@joe.com'), 'enrolled users matched'
assertStepVisible = (step) ->
assert.isVisible $("#create-users-step-#{step}")
startOver = ->
view.$('.createUsersStartOver').click()
startOverFrd = ->
view.$('.createUsersStartOverFrd').click()
assertTextareaValue = (text) ->
equal view.$textarea.val(), text, 'textarea matches text'
test 'moves through the steps', ->
assertStepVisible 1
addUserText()
goToStep2()
assertStepVisible 2
assertVerifiedUsers()
goToStep3()
assertStepVisible 3
assertEnrolledUsers()
view.close()
test 'starts over on step 2', ->
addUserText()
goToStep2()
assertStepVisible 2
startOver()
assertStepVisible 1
assertTextareaValue 'joe@joe.com'
view.close()
test 'starts over on step 3', ->
addUserText()
goToStep2()
goToStep3()
assertStepVisible 3
startOverFrd()
assertStepVisible 1
assertTextareaValue ''
test 'resets data on close and reopen', ->
addUserText()
assertTextareaValue 'joe@joe.com'
view.close()
view.open()
assertTextareaValue ''

View File

@ -4,6 +4,7 @@
<meta http-equiv=Content-type content="text/html; charset=utf-8">
<title>Tests</title>
<link rel="stylesheet" href="support/qunit/qunit.css" type="text/css">
<link rel="stylesheet" href="../../public/stylesheets/compiled/g_base.css" type="text/css">
<style>
body {
font-family: 'Helvetica', 'Verdana';

View File

@ -246,6 +246,20 @@ describe Role do
end
end
describe "Role.role_data" do
it "returns the roles with custom roles flattened as siblings to the main roles" do
course(:account => @sub_account)
@base_types.each do |bt|
@course.enroll_user(user, bt)
@course.enroll_user(user, bt, :role_name => "custom #{bt}")
end
roles = Role.role_data(@course, @course.teachers.first)
roles.length.should == 10
end
end
it "should include inactive roles" do
@account.roles.each{|r| r.deactivate! }
all = Role.all_enrollment_roles_for_account(@sub_account, true)

View File

@ -277,6 +277,7 @@ describe "announcements" do
create_announcement_manual('input[type=checkbox][name=delay_posting]')
f('.ui-datepicker-trigger').click
datepicker_next
f('.ui-datepicker-time .ui-datepicker-ok').click
expect_new_page_load { submit_form('.form-actions') }
f('.discussion-fyi').should include_text('This topic will not be visible')
end