Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facilitators can create workshops with regional partners #20881

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/src/code-studio/pd/permission.js
Expand Up @@ -14,6 +14,8 @@ export default class Permission {

this.isWorkshopAdmin = this.hasPermission('workshop_admin');
this.isFacilitator = this.hasPermission('facilitator');
// CSF Facilitators can create workshops, other facilitators cannot
this.isCsfFacilitator = this.hasPermission('csf_facilitator');
this.isOrganizer = this.hasPermission('workshop_organizer');
this.isPartner = this.hasPermission('partner');
}
Expand Down
Expand Up @@ -121,9 +121,10 @@ export default class WorkshopForm extends React.Component {
);
initialState.sessions = this.prepareSessionsForForm(props.workshop.sessions);
this.loadAvailableFacilitators(props.workshop.course);
this.loadRegionalPartners();
}

this.loadRegionalPartners();

return initialState;
}

Expand Down
8 changes: 5 additions & 3 deletions apps/src/code-studio/pd/workshop_dashboard/workshop_index.jsx
Expand Up @@ -65,12 +65,14 @@ export default class WorkshopIndex extends React.Component {

render() {
const showOrganizer = this.permission.isWorkshopAdmin;
const canDelete = this.permission.isWorkshopAdmin || this.permission.isOrganizer;
const canCreate = (this.permission.isWorkshopAdmin || this.permission.isOrganizer || this.permission.isCsfFacilitator);

return (
<div>
<h1>Your Workshops</h1>
<ButtonToolbar>
{(this.permission.isWorkshopAdmin || this.permission.isOrganizer) &&
{canCreate &&
(
<Button className="btn-primary" onClick={this.handleNewWorkshopClick}>
New Workshop
Expand All @@ -91,7 +93,7 @@ export default class WorkshopIndex extends React.Component {
<ServerSortWorkshopTable
queryUrl={FILTER_API_URL}
queryParams={filterParams.inProgress}
canDelete
canDelete={canDelete}
tableId="inProgressWorkshopsTable"
showOrganizer={showOrganizer}
moreUrl={this.generateFilterUrl('In Progress')}
Expand All @@ -100,7 +102,7 @@ export default class WorkshopIndex extends React.Component {
<ServerSortWorkshopTable
queryUrl={FILTER_API_URL}
queryParams={filterParams.notStarted}
canDelete
canDelete={canDelete}
tableId="notStartedWorkshopsTable"
showSignupUrl
showOrganizer={showOrganizer}
Expand Down
Expand Up @@ -14,7 +14,7 @@ def for_school_district_and_course

# GET /api/v1/regional_partners
def index
regional_partners = current_user.permission?(UserPermission::WORKSHOP_ADMIN) ? RegionalPartner.all : current_user.regional_partners
regional_partners = (current_user.facilitator? || current_user.workshop_admin?) ? RegionalPartner.all : current_user.regional_partners

render json: regional_partners.order(:name).map {|partner| {id: partner.id, name: partner.name}}
end
Expand Down
2 changes: 2 additions & 0 deletions dashboard/app/controllers/pd/workshop_dashboard_controller.rb
Expand Up @@ -11,6 +11,8 @@ def index
permission_list = []
permission_list << :workshop_organizer if current_user.workshop_organizer?
permission_list << :facilitator if current_user.facilitator?
# CSF Facilitators have special permissions. For the time being, they are the only ones that have special permissions
permission_list << :csf_facilitator if Pd::CourseFacilitator.exists?(facilitator: current_user, course: Pd::Workshop::COURSE_CSF)
permission_list << :partner if RegionalPartner.where(contact_id: current_user.id).exists?
@permission = permission_list unless permission_list.empty?
end
Expand Down
5 changes: 5 additions & 0 deletions dashboard/app/models/ability.rb
Expand Up @@ -106,8 +106,13 @@ def initialize(user)
workshop.facilitators.include? user
end
can [:read, :start, :end, :workshop_survey_report, :summary, :filter], Pd::Workshop, facilitators: {id: user.id}
can [:read, :update], Pd::Workshop, organizer_id: user.id
can :create, Pd::Workshop do |_|
Pd::CourseFacilitator.exists?(facilitator: user, course: Pd::Workshop::COURSE_CSF)
end
can :manage_attendance, Pd::Workshop, facilitators: {id: user.id}, ended_at: nil
can :create, Pd::FacilitatorProgramRegistration, user_id: user.id
can :read, Pd::CourseFacilitator, facilitator_id: user.id
end

if user.district_contact?
Expand Down
Expand Up @@ -4,7 +4,7 @@ class Api::V1::Pd::CourseFacilitatorsControllerTest < ::ActionController::TestCa
{
admin: :success,
workshop_organizer: :success,
facilitator: :forbidden,
facilitator: :success,
teacher: :forbidden
}.each do |user_type, response|
test_user_gets_response_for(
Expand Down
Expand Up @@ -256,6 +256,18 @@ class Api::V1::Pd::WorkshopsControllerTest < ::ActionController::TestCase
params: -> {{pd_workshop: workshop_params}}
)

test 'csf facilitators can create workshops' do
facilitator = create :facilitator
Pd::CourseFacilitator.create(facilitator: facilitator, course: Pd::Workshop::COURSE_CSF)

sign_in(facilitator)

assert_creates(Pd::Workshop) do
post :create, params: {pd_workshop: workshop_params}
assert_response :success
end
end

# Action: Destroy

test 'organizers can delete their workshops' do
Expand Down Expand Up @@ -315,9 +327,20 @@ class Api::V1::Pd::WorkshopsControllerTest < ::ActionController::TestCase
assert_response :forbidden
end

test 'Facilitators can update workshops they organized' do
sign_in(@facilitator)

workshop = create :pd_workshop, organizer: @facilitator
put :update, params: {
id: workshop.id,
pd_workshop: workshop_params
}
assert_response :success
end

test_user_gets_response_for(
:update,
name: 'facilitators cannot update workshops',
name: 'facilitators cannot update workshops they did not organize',
method: :put,
response: :forbidden,
user: -> {@facilitator},
Expand Down
Expand Up @@ -19,6 +19,16 @@ class Pd::WorkshopDashboardControllerTest < ::ActionController::TestCase
end
end

test 'csf facilitator has permission reflected' do
user = create :facilitator
Pd::CourseFacilitator.create(facilitator: user, course: Pd::Workshop::COURSE_CSF)

sign_in(user)
get :index
assert_response :success
assert_equal [:facilitator, :csf_facilitator], assigns(:permission)
end

test 'a user who is both a facilitator and an organizer has their permission reflected' do
user = create(:workshop_organizer)
user.permission = UserPermission::FACILITATOR
Expand Down