wiki pages CRUD API
fixes CNVS-5279 test plan: - see API documentation to create/retrieve/update/delete pages - exercise endpoints, including - CRUD functionality (above) - test renaming page - test publishing / unpublishing - test creating the front page in a new course or group Change-Id: I5d3b36615b7bdbfda0d4781db14cd7d49d32eba1 Reviewed-on: https://gerrit.instructure.com/19952 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Bracken Mosbacker <bracken@instructure.com> Product-Review: Bracken Mosbacker <bracken@instructure.com> QA-Review: Adam Phillipps <adam@instructure.com>
This commit is contained in:
parent
83e192a7e8
commit
8bdfdd3103
|
@ -0,0 +1,236 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
# @API Pages
|
||||||
|
#
|
||||||
|
# Pages are rich content associated with Courses and Groups in Canvas.
|
||||||
|
# The Pages API allows you to create, retrieve, update, and delete ages.
|
||||||
|
#
|
||||||
|
# @object Page
|
||||||
|
# {
|
||||||
|
# // the unique locator for the page
|
||||||
|
# url: "my-page-title",
|
||||||
|
#
|
||||||
|
# // the title of the page
|
||||||
|
# title: "My Page Title",
|
||||||
|
#
|
||||||
|
# // the creation date for the page
|
||||||
|
# created_at: "2012-08-06T16:46:33-06:00",
|
||||||
|
#
|
||||||
|
# // the date the page was last updated
|
||||||
|
# updated_at: "2012-08-08T14:25:20-06:00",
|
||||||
|
#
|
||||||
|
# // whether this page is hidden from students
|
||||||
|
# // (note: students will never see this true; pages hidden from them will be omitted from results)
|
||||||
|
# hide_from_students: false,
|
||||||
|
#
|
||||||
|
# // roles allowed to edit the page; comma-separated list comprising a combination of
|
||||||
|
# // 'teachers', 'students', and/or 'public'
|
||||||
|
# // if not supplied, course defaults are used
|
||||||
|
# editing_roles: "teachers,students",
|
||||||
|
#
|
||||||
|
# // the User who last edited the page
|
||||||
|
# // (this may not be present if the page was imported from another system)
|
||||||
|
# last_edited_by: {
|
||||||
|
# id: 133,
|
||||||
|
# display_name: "Rey del Pueblo",
|
||||||
|
# avatar_image_url: "https://canvas.example.com/images/thumbnails/bm90aGluZyBoZXJl",
|
||||||
|
# html_url: "https://canvas.example.com/courses/789/users/133"
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
# // the page content, in HTML
|
||||||
|
# // (present when requesting a single page; omitted when listing pages)
|
||||||
|
# body: "<p>Page Content</p>",
|
||||||
|
#
|
||||||
|
# // whether the page is published
|
||||||
|
# published: true
|
||||||
|
# }
|
||||||
|
class WikiPagesApiController < ApplicationController
|
||||||
|
before_filter :require_context
|
||||||
|
before_filter :get_wiki_page, :except => [:create, :index]
|
||||||
|
|
||||||
|
include Api::V1::WikiPage
|
||||||
|
|
||||||
|
# @API List pages
|
||||||
|
#
|
||||||
|
# List the wiki pages associated with a course or group
|
||||||
|
#
|
||||||
|
# @argument sort [optional] Sort results by this field: one of 'title', 'created_at', or 'updated_at'
|
||||||
|
# @argument order [optional] The sorting order: 'asc' (default) or 'desc'
|
||||||
|
#
|
||||||
|
# @example_request
|
||||||
|
# curl -H 'Authorization: Bearer <token>' \
|
||||||
|
# https://<canvas>/api/v1/courses/123/pages?sort=title&order=asc
|
||||||
|
#
|
||||||
|
# @returns [Page]
|
||||||
|
def index
|
||||||
|
if authorized_action(@context.wiki, @current_user, :read)
|
||||||
|
pages_route = polymorphic_url([:api_v1, @context, :wiki_pages])
|
||||||
|
# omit body from selection, since it's not included in index results
|
||||||
|
scope = @context.wiki.wiki_pages.
|
||||||
|
select(%w(wiki_pages.wiki_id wiki_pages.url wiki_pages.title wiki_pages.created_at wiki_pages.updated_at wiki_pages.hide_from_students wiki_pages.editing_roles wiki_pages.workflow_state wiki_pages.user_id)).
|
||||||
|
includes(:user)
|
||||||
|
|
||||||
|
scope = @context.grants_right?(@current_user, session, :view_unpublished_items) ? scope.not_deleted : scope.active
|
||||||
|
scope = scope.visible_to_students unless @context.grants_right?(@current_user, session, :view_hidden_items)
|
||||||
|
|
||||||
|
order_clause = case params[:sort]
|
||||||
|
when 'title'
|
||||||
|
WikiPage.title_order_by_clause
|
||||||
|
when 'created_at'
|
||||||
|
'wiki_pages.created_at'
|
||||||
|
when 'updated_at'
|
||||||
|
'wiki_pages.updated_at'
|
||||||
|
else
|
||||||
|
'wiki_pages.id'
|
||||||
|
end
|
||||||
|
order_clause += ' DESC' if params[:order] == 'desc'
|
||||||
|
scope = scope.order(order_clause)
|
||||||
|
|
||||||
|
wiki_pages = Api.paginate(scope, self, pages_route)
|
||||||
|
render :json => wiki_pages_json(wiki_pages, @current_user, session)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @API Show page
|
||||||
|
#
|
||||||
|
# Retrieve the content of a wiki page
|
||||||
|
#
|
||||||
|
# @argument url the unique identifier for a page. Use 'front-page' to retrieve the front page of the wiki.
|
||||||
|
#
|
||||||
|
# @example_request
|
||||||
|
# curl -H 'Authorization: Bearer <token>' \
|
||||||
|
# https://<canvas>/api/v1/courses/123/pages/front-page
|
||||||
|
#
|
||||||
|
# @returns Page
|
||||||
|
def show
|
||||||
|
if authorized_action(@page, @current_user, :read)
|
||||||
|
@page.increment_view_count(@current_user, @context)
|
||||||
|
log_asset_access(@page, "wiki", @wiki)
|
||||||
|
render :json => wiki_page_json(@page, @current_user, session)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @API Create page
|
||||||
|
#
|
||||||
|
# Create a new wiki page
|
||||||
|
#
|
||||||
|
# @argument wiki_page[title] the title for the new page.
|
||||||
|
# @argument wiki_page[body] the content for the new page.
|
||||||
|
# @argument wiki_page[hide_from_students] [boolean] whether the page should be hidden from students.
|
||||||
|
# @argument wiki_page[notify_of_update] [boolean] whether participants should be notified when this page changes.
|
||||||
|
# @argument wiki_page[published] [optional] [boolean] whether the page is published (true) or draft state (false).
|
||||||
|
#
|
||||||
|
# @example_request
|
||||||
|
# curl -X POST -H 'Authorization: Bearer <token>' \
|
||||||
|
# https://<canvas>/api/v1/courses/123/pages?wiki_page[title]=New+page&wiki_page[body]=New+body+text
|
||||||
|
#
|
||||||
|
# @returns Page
|
||||||
|
def create
|
||||||
|
@page = @context.wiki.wiki_pages.build
|
||||||
|
if authorized_action(@page, @current_user, :update)
|
||||||
|
attrs_to_update = process_update_params
|
||||||
|
if @page.update_attributes(attrs_to_update)
|
||||||
|
log_asset_access(@page, "wiki", @wiki, 'participate')
|
||||||
|
render :json => wiki_page_json(@page, @current_user, session)
|
||||||
|
else
|
||||||
|
render :json => @page.errors.to_json, :status => :bad_request
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @API Update page
|
||||||
|
#
|
||||||
|
# Update the title or contents of a wiki page
|
||||||
|
#
|
||||||
|
# @argument url the unique identifier for a page.
|
||||||
|
# @argument wiki_page[title] [optional] the new title for the page.
|
||||||
|
# NOTE: changing a page's title will change its url. The updated url will be returned in the result.
|
||||||
|
# @argument wiki_page[body] [optional] the new content for the page.
|
||||||
|
# @argument wiki_page[hide_from_students] [optional] boolean; whether the page should be hidden from students.
|
||||||
|
# @argument wiki_page[notify_of_update] [optional] [boolean] notify participants that the wiki page has been changed.
|
||||||
|
# @argument wiki_page[published] [optional] [boolean] whether the page is published (true) or draft state (false)
|
||||||
|
#
|
||||||
|
# @example_request
|
||||||
|
# curl -X PUT -H 'Authorization: Bearer <token>' \
|
||||||
|
# https://<canvas>/api/v1/courses/123/pages/the-page-url?wiki_page[body]=Updated+body+text
|
||||||
|
#
|
||||||
|
# @returns Page
|
||||||
|
def update
|
||||||
|
if authorized_action(@page, @current_user, :update_content)
|
||||||
|
attrs_to_update = process_update_params
|
||||||
|
if @page.update_attributes(attrs_to_update)
|
||||||
|
log_asset_access(@page, "wiki", @wiki, 'participate')
|
||||||
|
@page.context_module_action(@current_user, @context, :contributed)
|
||||||
|
render :json => wiki_page_json(@page, @current_user, session)
|
||||||
|
else
|
||||||
|
render :json => @page.errors.to_json, :status => :bad_request
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @API Delete page
|
||||||
|
#
|
||||||
|
# Delete a wiki page
|
||||||
|
#
|
||||||
|
# @argument url the unique identifier for a page.
|
||||||
|
#
|
||||||
|
# @example_request
|
||||||
|
# curl -X DELETE -H 'Authorization: Bearer <token>' \
|
||||||
|
# https://<canvas>/api/v1/courses/123/pages/the-page-url
|
||||||
|
#
|
||||||
|
# @returns Page
|
||||||
|
def destroy
|
||||||
|
if authorized_action(@page, @current_user, :delete)
|
||||||
|
@page.workflow_state = 'deleted'
|
||||||
|
@page.save!
|
||||||
|
render :json => wiki_page_json(@page, @current_user, session)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def get_wiki_page
|
||||||
|
@wiki = @context.wiki
|
||||||
|
@page = @wiki.wiki_pages.not_deleted.find_by_url!(params[:url])
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_update_params
|
||||||
|
page_params = params[:wiki_page] || {}
|
||||||
|
|
||||||
|
if @page.grants_right?(@current_user, session, :update)
|
||||||
|
if page_params.has_key? :published
|
||||||
|
new_state = value_to_boolean(page_params.delete(:published)) ? 'active' : 'unpublished'
|
||||||
|
@page.workflow_state = new_state
|
||||||
|
end
|
||||||
|
|
||||||
|
roles = page_params[:editing_roles]
|
||||||
|
if roles.present?
|
||||||
|
page_params[:editing_roles] = roles.split(',').map(&:strip).reject{|role| !%w(teachers students public).include?(role)}.join(',')
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# editing_roles only allow changing content, not title or attributes
|
||||||
|
page_params.slice!(:body)
|
||||||
|
end
|
||||||
|
|
||||||
|
page_params[:user_id] = @current_user.id if @current_user
|
||||||
|
|
||||||
|
page_params
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -15,42 +15,12 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License along
|
# 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/>.
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
# @API Pages
|
|
||||||
#
|
|
||||||
# Pages are rich content associated with Courses and Groups in Canvas.
|
|
||||||
# The Pages API allows this content to be enumerated and retrieved.
|
|
||||||
#
|
|
||||||
# @object Page
|
|
||||||
# {
|
|
||||||
# // the unique locator for the page
|
|
||||||
# url: "my-page-title",
|
|
||||||
#
|
|
||||||
# // the title of the page
|
|
||||||
# title: "My Page Title",
|
|
||||||
#
|
|
||||||
# // the creation date for the page
|
|
||||||
# created_at: "2012-08-06T16:46:33-06:00",
|
|
||||||
#
|
|
||||||
# // the date the page was last updated
|
|
||||||
# updated_at: "2012-08-08T14:25:20-06:00",
|
|
||||||
#
|
|
||||||
# // whether this page is hidden from students
|
|
||||||
# // (note: students will never see this true; pages hidden from them will be omitted from results)
|
|
||||||
# hide_from_students: false,
|
|
||||||
#
|
|
||||||
# // the page content, in HTML
|
|
||||||
# // (present when requesting a single page; omitted when listing pages)
|
|
||||||
# body: "<p>Page Content</p>"
|
|
||||||
# }
|
|
||||||
class WikiPagesController < ApplicationController
|
class WikiPagesController < ApplicationController
|
||||||
before_filter :require_context
|
before_filter :require_context
|
||||||
before_filter :get_wiki_page, :except => [:index, :api_index, :api_show]
|
before_filter :get_wiki_page, :except => [:index]
|
||||||
add_crumb(proc { t '#crumbs.wiki_pages', "Pages"}) { |c| c.send :named_context_url, c.instance_variable_get("@context"), :context_wiki_pages_url }
|
add_crumb(proc { t '#crumbs.wiki_pages', "Pages"}) { |c| c.send :named_context_url, c.instance_variable_get("@context"), :context_wiki_pages_url }
|
||||||
before_filter { |c| c.active_tab = "pages" }
|
before_filter { |c| c.active_tab = "pages" }
|
||||||
|
|
||||||
include Api::V1::WikiPage
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@editing = true if Canvas::Plugin.value_to_boolean(params[:edit])
|
@editing = true if Canvas::Plugin.value_to_boolean(params[:edit])
|
||||||
if @page.deleted? && !@page.grants_right?(@current_user, session, :update) && @page.url != 'front-page'
|
if @page.deleted? && !@page.grants_right?(@current_user, session, :update) && @page.url != 'front-page'
|
||||||
|
@ -60,7 +30,8 @@ class WikiPagesController < ApplicationController
|
||||||
end
|
end
|
||||||
if is_authorized_action?(@page, @current_user, :read)
|
if is_authorized_action?(@page, @current_user, :read)
|
||||||
add_crumb(@page.title)
|
add_crumb(@page.title)
|
||||||
update_view_count(@page)
|
@page.increment_view_count(@current_user, @context)
|
||||||
|
log_asset_access(@page, "wiki", @wiki)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {render :action => "show" }
|
format.html {render :action => "show" }
|
||||||
format.json {render :json => @page.to_json }
|
format.json {render :json => @page.to_json }
|
||||||
|
@ -75,53 +46,6 @@ class WikiPagesController < ApplicationController
|
||||||
redirect_to named_context_url(@context, :context_wiki_page_url, 'front-page')
|
redirect_to named_context_url(@context, :context_wiki_page_url, 'front-page')
|
||||||
end
|
end
|
||||||
|
|
||||||
# @API List pages
|
|
||||||
#
|
|
||||||
# Lists the wiki pages associated with a course or group.
|
|
||||||
#
|
|
||||||
# @example_request
|
|
||||||
# curl -H 'Authorization: Bearer <token>' \
|
|
||||||
# https://<canvas>/api/v1/courses/123/pages
|
|
||||||
#
|
|
||||||
# @returns [Page]
|
|
||||||
def api_index
|
|
||||||
if authorized_action(@context.wiki, @current_user, :read)
|
|
||||||
pages_route = polymorphic_url([:api_v1, @context, :wiki_pages])
|
|
||||||
scope = @context.wiki.wiki_pages.order_by_id
|
|
||||||
if @context.grants_right?(@current_user, session, :view_unpublished_items)
|
|
||||||
scope = scope.not_deleted
|
|
||||||
else
|
|
||||||
scope = scope.active
|
|
||||||
end
|
|
||||||
if !@context.grants_right?(@current_user, session, :view_hidden_items)
|
|
||||||
scope = scope.visible_to_students
|
|
||||||
end
|
|
||||||
wiki_pages = Api.paginate(scope, self, pages_route)
|
|
||||||
render :json => wiki_pages_json(wiki_pages, @current_user, session)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# @API Show page
|
|
||||||
#
|
|
||||||
# Retrieves the content of a wiki page.
|
|
||||||
#
|
|
||||||
# @argument url the unique identifier for a page. Use 'front-page' to retrieve the front page of the wiki.
|
|
||||||
#
|
|
||||||
# @example_request
|
|
||||||
# curl -H 'Authorization: Bearer <token>' \
|
|
||||||
# https://<canvas>/api/v1/courses/123/pages/front-page
|
|
||||||
#
|
|
||||||
# @returns Page
|
|
||||||
def api_show
|
|
||||||
# not using get_wiki_page since this API is read-only for now
|
|
||||||
@wiki = @context.wiki
|
|
||||||
@page = @wiki.wiki_pages.not_deleted.find_by_url!(params[:url])
|
|
||||||
if authorized_action(@page, @current_user, :read)
|
|
||||||
update_view_count(@page)
|
|
||||||
render :json => wiki_page_json(@page, @current_user, session)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if authorized_action(@page, @current_user, :update_content)
|
if authorized_action(@page, @current_user, :update_content)
|
||||||
unless @page.grants_right?(@current_user, session, :update)
|
unless @page.grants_right?(@current_user, session, :update)
|
||||||
|
@ -188,15 +112,5 @@ class WikiPagesController < ApplicationController
|
||||||
end
|
end
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_view_count(page)
|
|
||||||
unless page.new_record?
|
|
||||||
page.with_versioning(false) do |p|
|
|
||||||
p.context_module_action(@current_user, @context, :read)
|
|
||||||
WikiPage.connection.execute("UPDATE wiki_pages SET view_count=COALESCE(view_count, 0) + 1 WHERE id=#{p.id}")
|
|
||||||
end
|
|
||||||
log_asset_access(page, "wiki", @wiki)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,6 +60,10 @@ class WikiPage < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.title_order_by_clause
|
||||||
|
best_unicode_collation_key('wiki_pages.title')
|
||||||
|
end
|
||||||
|
|
||||||
def ensure_unique_url
|
def ensure_unique_url
|
||||||
url_attribute = self.class.url_attribute
|
url_attribute = self.class.url_attribute
|
||||||
base_url = self.send(url_attribute)
|
base_url = self.send(url_attribute)
|
||||||
|
@ -142,7 +146,7 @@ class WikiPage < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_of_update=(val)
|
def notify_of_update=(val)
|
||||||
@wiki_page_changed = (val == '1' || val == true)
|
@wiki_page_changed = Canvas::Plugin.value_to_boolean(val)
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_of_update
|
def notify_of_update
|
||||||
|
@ -495,4 +499,14 @@ class WikiPage < ActiveRecord::Base
|
||||||
def self.comments_enabled?
|
def self.comments_enabled?
|
||||||
!Rails.env.production?
|
!Rails.env.production?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def increment_view_count(user, context = nil)
|
||||||
|
unless self.new_record?
|
||||||
|
self.with_versioning(false) do |p|
|
||||||
|
context ||= p.context
|
||||||
|
p.connection.execute("UPDATE wiki_pages SET view_count=COALESCE(view_count, 0) + 1 WHERE id=#{p.id}")
|
||||||
|
p.context_module_action(user, context, :read)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1045,11 +1045,17 @@ ActionController::Routing::Routes.draw do |map|
|
||||||
favorites.delete "users/self/favorites/courses", :action => :reset_course_favorites
|
favorites.delete "users/self/favorites/courses", :action => :reset_course_favorites
|
||||||
end
|
end
|
||||||
|
|
||||||
api.with_options(:controller => :wiki_pages) do |wiki_pages|
|
api.with_options(:controller => :wiki_pages_api) do |wiki_pages|
|
||||||
wiki_pages.get "courses/:course_id/pages", :action => :api_index, :path_name => 'course_wiki_pages'
|
wiki_pages.get "courses/:course_id/pages", :action => :index, :path_name => 'course_wiki_pages'
|
||||||
wiki_pages.get "groups/:group_id/pages", :action => :api_index, :path_name => 'group_wiki_pages'
|
wiki_pages.get "groups/:group_id/pages", :action => :index, :path_name => 'group_wiki_pages'
|
||||||
wiki_pages.get "courses/:course_id/pages/:url", :action => :api_show, :path_name => 'course_wiki_page'
|
wiki_pages.get "courses/:course_id/pages/:url", :action => :show, :path_name => 'course_wiki_page'
|
||||||
wiki_pages.get "groups/:group_id/pages/:url", :action => :api_show, :path_name => 'group_wiki_page'
|
wiki_pages.get "groups/:group_id/pages/:url", :action => :show, :path_name => 'group_wiki_page'
|
||||||
|
wiki_pages.post "courses/:course_id/pages", :action => :create
|
||||||
|
wiki_pages.post "groups/:group_id/pages", :action => :create
|
||||||
|
wiki_pages.put "courses/:course_id/pages/:url", :action => :update
|
||||||
|
wiki_pages.put "groups/:group_id/pages/:url", :action => :update
|
||||||
|
wiki_pages.delete "courses/:course_id/pages/:url", :action => :destroy
|
||||||
|
wiki_pages.delete "groups/:group_id/pages/:url", :action => :destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
api.with_options(:controller => :context_modules_api) do |context_modules|
|
api.with_options(:controller => :context_modules_api) do |context_modules|
|
||||||
|
|
|
@ -20,15 +20,18 @@ module Api::V1::WikiPage
|
||||||
include Api::V1::Json
|
include Api::V1::Json
|
||||||
include Api::V1::User
|
include Api::V1::User
|
||||||
|
|
||||||
WIKI_PAGE_JSON_ATTRS = %w(url title created_at updated_at hide_from_students)
|
WIKI_PAGE_JSON_ATTRS = %w(url title created_at updated_at hide_from_students editing_roles)
|
||||||
|
|
||||||
def wiki_page_json(wiki_page, current_user, session)
|
def wiki_page_json(wiki_page, current_user, session, include_body = true)
|
||||||
hash = api_json(wiki_page, current_user, session, :only => WIKI_PAGE_JSON_ATTRS)
|
hash = api_json(wiki_page, current_user, session, :only => WIKI_PAGE_JSON_ATTRS)
|
||||||
hash['body'] = api_user_content(wiki_page.body)
|
hash['editing_roles'] ||= 'teachers'
|
||||||
|
hash['body'] = api_user_content(wiki_page.body) if include_body
|
||||||
|
hash['last_edited_by'] = user_display_json(wiki_page.user, wiki_page.context) if wiki_page.user
|
||||||
|
hash['published'] = wiki_page.active?
|
||||||
hash
|
hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def wiki_pages_json(wiki_pages, current_user, session)
|
def wiki_pages_json(wiki_pages, current_user, session)
|
||||||
wiki_pages.map { |page| api_json(page, current_user, session, :only => WIKI_PAGE_JSON_ATTRS) }
|
wiki_pages.map { |page| wiki_page_json(page, current_user, session, false) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -218,7 +218,7 @@ describe UserContent, :type => :integration do
|
||||||
@wiki_page.workflow_state = 'active'
|
@wiki_page.workflow_state = 'active'
|
||||||
@wiki_page.save!
|
@wiki_page.save!
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@wiki_page.url}",
|
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@wiki_page.url}",
|
||||||
{ :controller => 'wiki_pages', :action => 'api_show',
|
{ :controller => 'wiki_pages_api', :action => 'show',
|
||||||
:format => 'json', :course_id => @course.id.to_s, :url => @wiki_page.url })
|
:format => 'json', :course_id => @course.id.to_s, :url => @wiki_page.url })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ describe UserContent, :type => :integration do
|
||||||
@wiki_page.save!
|
@wiki_page.save!
|
||||||
|
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@wiki_page.url}",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@wiki_page.url}",
|
||||||
{ :controller => 'wiki_pages', :action => 'api_show',
|
{ :controller => 'wiki_pages_api', :action => 'show',
|
||||||
:format => 'json', :course_id => @course.id.to_s, :url => @wiki_page.url })
|
:format => 'json', :course_id => @course.id.to_s, :url => @wiki_page.url })
|
||||||
doc = Nokogiri::HTML::DocumentFragment.parse(json['body'])
|
doc = Nokogiri::HTML::DocumentFragment.parse(json['body'])
|
||||||
doc.css('a').collect { |att| att['data-api-endpoint'] }.should == [
|
doc.css('a').collect { |att| att['data-api-endpoint'] }.should == [
|
||||||
|
@ -281,7 +281,7 @@ describe UserContent, :type => :integration do
|
||||||
@wiki_page.save!
|
@wiki_page.save!
|
||||||
|
|
||||||
json = api_call(:get, "/api/v1/groups/#{@group.id}/pages/#{@wiki_page.url}",
|
json = api_call(:get, "/api/v1/groups/#{@group.id}/pages/#{@wiki_page.url}",
|
||||||
{ :controller => 'wiki_pages', :action => 'api_show',
|
{ :controller => 'wiki_pages_api', :action => 'show',
|
||||||
:format => 'json', :group_id => @group.id.to_s, :url => @wiki_page.url })
|
:format => 'json', :group_id => @group.id.to_s, :url => @wiki_page.url })
|
||||||
doc = Nokogiri::HTML::DocumentFragment.parse(json['body'])
|
doc = Nokogiri::HTML::DocumentFragment.parse(json['body'])
|
||||||
doc.css('a').collect { |att| att['data-api-endpoint'] }.should == [
|
doc.css('a').collect { |att| att['data-api-endpoint'] }.should == [
|
||||||
|
|
|
@ -33,51 +33,231 @@ describe "Pages API", :type => :integration do
|
||||||
course_with_teacher(:course => @course, :active_all => true)
|
course_with_teacher(:course => @course, :active_all => true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should list pages, including hidden ones" do
|
describe "index" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
it "should list pages, including hidden ones" do
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}")
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
json.should == [{"hide_from_students" => false, "url" => @front_page.url, "created_at" => @front_page.created_at.as_json, "updated_at" => @front_page.updated_at.as_json, "title" => @front_page.title},
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param)
|
||||||
{"hide_from_students" => true, "url" => @hidden_page.url, "created_at" => @hidden_page.created_at.as_json, "updated_at" => @hidden_page.updated_at.as_json, "title" => @hidden_page.title}]
|
json.map {|entry| entry.slice(*%w(hide_from_students url created_at updated_at title))}.should ==
|
||||||
|
[{"hide_from_students" => false, "url" => @front_page.url, "created_at" => @front_page.created_at.as_json, "updated_at" => @front_page.updated_at.as_json, "title" => @front_page.title},
|
||||||
|
{"hide_from_students" => true, "url" => @hidden_page.url, "created_at" => @hidden_page.created_at.as_json, "updated_at" => @hidden_page.updated_at.as_json, "title" => @hidden_page.title}]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should paginate" do
|
||||||
|
2.times { |i| @wiki.wiki_pages.create!(:title => "New Page #{i}") }
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?per_page=2",
|
||||||
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param, :per_page => "2")
|
||||||
|
json.size.should == 2
|
||||||
|
urls = json.collect{ |page| page['url'] }
|
||||||
|
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?per_page=2&page=2",
|
||||||
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param, :per_page => "2", :page => "2")
|
||||||
|
json.size.should == 2
|
||||||
|
urls += json.collect{ |page| page['url'] }
|
||||||
|
|
||||||
|
urls.should == @wiki.wiki_pages.sort_by(&:id).collect(&:url)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "sorting" do
|
||||||
|
it "should sort by title (case-insensitive)" do
|
||||||
|
@wiki.wiki_pages.create! :title => 'gIntermediate Page'
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?sort=title",
|
||||||
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param,
|
||||||
|
:sort=>'title')
|
||||||
|
json.map {|page|page['title']}.should == ['Front Page', 'gIntermediate Page', 'Hidden Page']
|
||||||
|
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?sort=title&order=desc",
|
||||||
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param,
|
||||||
|
:sort=>'title', :order=>'desc')
|
||||||
|
json.map {|page|page['title']}.should == ['Hidden Page', 'gIntermediate Page', 'Front Page']
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort by created_at" do
|
||||||
|
@hidden_page.update_attribute(:created_at, 1.hour.ago)
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?sort=created_at&order=asc",
|
||||||
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param,
|
||||||
|
:sort=>'created_at', :order=>'asc')
|
||||||
|
json.map {|page|page['url']}.should == [@hidden_page.url, @front_page.url]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort by updated_at" do
|
||||||
|
Timecop.freeze(1.hour.ago) { @hidden_page.touch }
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?sort=updated_at&order=desc",
|
||||||
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>@course.to_param,
|
||||||
|
:sort=>'updated_at', :order=>'desc')
|
||||||
|
json.map {|page|page['url']}.should == [@front_page.url, @hidden_page.url]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "show" do
|
||||||
|
include Api::V1::User
|
||||||
|
def avatar_url_for_user(user, *a)
|
||||||
|
"http://www.example.com/images/messages/avatar-50.png"
|
||||||
|
end
|
||||||
|
def blank_fallback
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
@teacher.short_name = 'the teacher'
|
||||||
|
@teacher.save!
|
||||||
|
@hidden_page.user_id = @teacher.id
|
||||||
|
@hidden_page.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should retrieve page content and attributes" do
|
||||||
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
|
:controller=>"wiki_pages_api", :action=>"show", :format=>"json", :course_id=>"#{@course.id}", :url=>@hidden_page.url)
|
||||||
|
expected = { "hide_from_students" => true,
|
||||||
|
"editing_roles" => "teachers",
|
||||||
|
"last_edited_by" => user_display_json(@teacher, @course).stringify_keys!,
|
||||||
|
"url" => @hidden_page.url,
|
||||||
|
"created_at" => @hidden_page.created_at.as_json,
|
||||||
|
"updated_at" => @hidden_page.updated_at.as_json,
|
||||||
|
"title" => @hidden_page.title,
|
||||||
|
"body" => @hidden_page.body,
|
||||||
|
"published" => true }
|
||||||
|
json.should == expected
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "create" do
|
||||||
|
it "should require a title" do
|
||||||
|
api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||||
|
{}, {}, {:expected_status => 400})
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create a new page" do
|
||||||
|
json = api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||||
|
{ :wiki_page => { :title => 'New Wiki Page!', :body => 'hello new page' }})
|
||||||
|
page = @course.wiki.wiki_pages.find_by_url!(json['url'])
|
||||||
|
page.title.should == 'New Wiki Page!'
|
||||||
|
page.url.should == 'new-wiki-page'
|
||||||
|
page.body.should == 'hello new page'
|
||||||
|
page.user_id.should == @teacher.id
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create a new page in published state" do
|
||||||
|
json = api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||||
|
{ :wiki_page => { :published => true, :title => 'New Wiki Page!', :body => 'hello new page' }})
|
||||||
|
page = @course.wiki.wiki_pages.find_by_url!(json['url'])
|
||||||
|
page.should be_active
|
||||||
|
json['published'].should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create a new page in unpublished state" do
|
||||||
|
json = api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||||
|
{ :wiki_page => { :published => false, :title => 'New Wiki Page!', :body => 'hello new page' }})
|
||||||
|
page = @course.wiki.wiki_pages.find_by_url!(json['url'])
|
||||||
|
page.should be_unpublished
|
||||||
|
json['published'].should be_false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should paginate" do
|
describe "update" do
|
||||||
2.times { |i| @wiki.wiki_pages.create!(:title => "New Page #{i}") }
|
it "should update page content and attributes" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?per_page=2",
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}", :per_page=>"2")
|
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
json.size.should == 2
|
:url => @hidden_page.url },
|
||||||
urls = json.collect{ |page| page['url'] }
|
{ :wiki_page => { :title => 'No Longer Hidden Page', :hide_from_students => false,
|
||||||
|
:body => 'Information wants to be free' }})
|
||||||
|
@hidden_page.reload
|
||||||
|
@hidden_page.should be_active
|
||||||
|
@hidden_page.hide_from_students.should be_false
|
||||||
|
@hidden_page.title.should == 'No Longer Hidden Page'
|
||||||
|
@hidden_page.body.should == 'Information wants to be free'
|
||||||
|
@hidden_page.user_id.should == @teacher.id
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with unpublished page" do
|
||||||
|
before do
|
||||||
|
@hidden_page.workflow_state = 'unpublished'
|
||||||
|
@hidden_page.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should publish a page with published=true" do
|
||||||
|
json = api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}?wiki_page[published]=true",
|
||||||
|
:controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @hidden_page.url, :wiki_page => {'published' => 'true'})
|
||||||
|
json['published'].should be_true
|
||||||
|
@hidden_page.reload.should be_active
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not publish a page otherwise" do
|
||||||
|
json = api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
|
:controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @hidden_page.url)
|
||||||
|
json['published'].should be_false
|
||||||
|
@hidden_page.reload.should be_unpublished
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should unpublish a page" do
|
||||||
|
json = api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}?wiki_page[published]=false",
|
||||||
|
:controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @hidden_page.url, :wiki_page => {'published' => 'false'})
|
||||||
|
json['published'].should be_false
|
||||||
|
@hidden_page.reload.should be_unpublished
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sanitize page content" do
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @hidden_page.url },
|
||||||
|
{ :wiki_page => { :body => "<p>lolcats</p><script>alert('what')</script>" }})
|
||||||
|
@hidden_page.reload
|
||||||
|
@hidden_page.body.should == "<p>lolcats</p>alert('what')"
|
||||||
|
end
|
||||||
|
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?page=2&per_page=2",
|
it "should clean editing_roles" do
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}", :page => "2", :per_page=>"2")
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
json.size.should == 2
|
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
urls += json.collect{ |page| page['url'] }
|
:url => @hidden_page.url },
|
||||||
|
{ :wiki_page => { :editing_roles => 'teachers, chimpanzees, students' }})
|
||||||
|
@hidden_page.reload
|
||||||
|
@hidden_page.editing_roles.should == 'teachers,students'
|
||||||
|
end
|
||||||
|
|
||||||
urls.should == @wiki.wiki_pages.sort_by(&:id).collect(&:url)
|
it "should 404 if the page doesn't exist" do
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/nonexistent-url?title=renamed",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => 'nonexistent-url', :title => 'renamed' }, {}, {}, { :expected_status => 404 })
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "notify_of_update" do
|
||||||
|
before do
|
||||||
|
@front_page.update_attribute(:created_at, 1.hour.ago)
|
||||||
|
@hidden_page.update_attribute(:created_at, 1.hour.ago)
|
||||||
|
@notification = Notification.create! :name => "Updated Wiki Page"
|
||||||
|
@teacher.communication_channels.create(:path => "teacher@instructure.com").confirm!
|
||||||
|
@teacher.email_channel.notification_policies.
|
||||||
|
find_or_create_by_notification_id(@notification.id).
|
||||||
|
update_attribute(:frequency, 'immediately')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should notify iff the notify_on_update flag is sent" do
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@front_page.url}?wiki_page[body]=updated+front+page",
|
||||||
|
:controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @front_page.url, :wiki_page => { "body" => "updated front page" })
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}?wiki_page[body]=updated+hidden+page&wiki_page[notify_of_update]=true",
|
||||||
|
:controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @hidden_page.url, :wiki_page => { "body" => "updated hidden page", "notify_of_update" => 'true' })
|
||||||
|
@teacher.messages.map(&:context_id).should == [@hidden_page.id]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should retrieve page content" do
|
describe "delete" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
it "should delete a page" do
|
||||||
:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{@course.id}", :url=>@hidden_page.url)
|
api_call(:delete, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
json.should == { "hide_from_students" => true,
|
{ :controller => 'wiki_pages_api', :action => 'destroy', :format => 'json', :course_id => @course.to_param,
|
||||||
"url" => @hidden_page.url,
|
:url => @hidden_page.url })
|
||||||
"created_at" => @hidden_page.created_at.as_json,
|
@hidden_page.reload.should be_deleted
|
||||||
"updated_at" => @hidden_page.updated_at.as_json,
|
end
|
||||||
"title" => @hidden_page.title,
|
|
||||||
"body" => @hidden_page.body }
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should update view count" do
|
|
||||||
views = @front_page.view_count
|
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@front_page.url}",
|
|
||||||
:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{@course.id}", :url=>@front_page.url)
|
|
||||||
@front_page.reload
|
|
||||||
@front_page.view_count.should == views + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should return not-found on a nonexistent page" do
|
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages/nonexistent",
|
|
||||||
{ :controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{@course.id}", :url=>'nonexistent' },
|
|
||||||
{}, {}, { :expected_status => 404 })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "unpublished pages" do
|
context "unpublished pages" do
|
||||||
|
@ -89,12 +269,12 @@ describe "Pages API", :type => :integration do
|
||||||
|
|
||||||
it "should be in index" do
|
it "should be in index" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}")
|
:controller=>"wiki_pages_api", :action=>"index", :format=>"json", :course_id=>"#{@course.id}")
|
||||||
json.select{|w|w[:title] == @unpublished_page.title}.should_not be_nil
|
json.select{|w|w[:title] == @unpublished_page.title}.should_not be_nil
|
||||||
end
|
end
|
||||||
it "should show" do
|
it "should show" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@unpublished_page.url}",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@unpublished_page.url}",
|
||||||
:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{@course.id}", :url=>@unpublished_page.url)
|
:controller=>"wiki_pages_api", :action=>"show", :format=>"json", :course_id=>"#{@course.id}", :url=>@unpublished_page.url)
|
||||||
json['title'].should == @unpublished_page.title
|
json['title'].should == @unpublished_page.title
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -107,19 +287,20 @@ describe "Pages API", :type => :integration do
|
||||||
|
|
||||||
it "should list pages, excluding hidden ones" do
|
it "should list pages, excluding hidden ones" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}")
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{@course.id}")
|
||||||
json.should == [{"hide_from_students" => false, "url" => @front_page.url, "created_at" => @front_page.created_at.as_json, "updated_at" => @front_page.updated_at.as_json, "title" => @front_page.title}]
|
json.map{|entry| entry.slice(*%w(hide_from_students url created_at updated_at title))}.should ==
|
||||||
|
[{"hide_from_students" => false, "url" => @front_page.url, "created_at" => @front_page.created_at.as_json, "updated_at" => @front_page.updated_at.as_json, "title" => @front_page.title}]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should paginate, excluding hidden" do
|
it "should paginate, excluding hidden" do
|
||||||
11.times { |i| @wiki.wiki_pages.create!(:title => "New Page #{i}") }
|
11.times { |i| @wiki.wiki_pages.create!(:title => "New Page #{i}") }
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}")
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{@course.id}")
|
||||||
json.size.should == 10
|
json.size.should == 10
|
||||||
urls = json.collect{ |page| page['url'] }
|
urls = json.collect{ |page| page['url'] }
|
||||||
|
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?page=2",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages?page=2",
|
||||||
:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}", :page => "2")
|
:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{@course.id}", :page => "2")
|
||||||
json.size.should == 2
|
json.size.should == 2
|
||||||
urls += json.collect{ |page| page['url'] }
|
urls += json.collect{ |page| page['url'] }
|
||||||
|
|
||||||
|
@ -128,15 +309,15 @@ describe "Pages API", :type => :integration do
|
||||||
|
|
||||||
it "should refuse to show a hidden page" do
|
it "should refuse to show a hidden page" do
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@hidden_page.url}",
|
||||||
{:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{@course.id}", :url=>@hidden_page.url},
|
{:controller=>'wiki_pages_api', :action=>'show', :format=>'json', :course_id=>"#{@course.id}", :url=>@hidden_page.url},
|
||||||
{}, {}, { :expected_status => 401 })
|
{}, {}, { :expected_status => 401 })
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should refuse to list pages in an unpublished course" do
|
it "should refuse to list pages in an unpublished course" do
|
||||||
@course.workflow_state = 'created'
|
@course.workflow_state = 'created'
|
||||||
@course.save!
|
@course.save!
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
{:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}"},
|
{:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{@course.id}"},
|
||||||
{}, {}, { :expected_status => 401 })
|
{}, {}, { :expected_status => 401 })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -149,11 +330,11 @@ describe "Pages API", :type => :integration do
|
||||||
other_page.save!
|
other_page.save!
|
||||||
|
|
||||||
api_call(:get, "/api/v1/courses/#{other_course.id}/pages",
|
api_call(:get, "/api/v1/courses/#{other_course.id}/pages",
|
||||||
{:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{other_course.id}"},
|
{:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{other_course.id}"},
|
||||||
{}, {}, { :expected_status => 401 })
|
{}, {}, { :expected_status => 401 })
|
||||||
|
|
||||||
api_call(:get, "/api/v1/courses/#{other_course.id}/pages/front-page",
|
api_call(:get, "/api/v1/courses/#{other_course.id}/pages/front-page",
|
||||||
{:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{other_course.id}", :url=>'front-page'},
|
{:controller=>'wiki_pages_api', :action=>'show', :format=>'json', :course_id=>"#{other_course.id}", :url=>'front-page'},
|
||||||
{}, {}, { :expected_status => 401 })
|
{}, {}, { :expected_status => 401 })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -166,11 +347,12 @@ describe "Pages API", :type => :integration do
|
||||||
other_page.workflow_state = 'active'
|
other_page.workflow_state = 'active'
|
||||||
other_page.save!
|
other_page.save!
|
||||||
|
|
||||||
api_call(:get, "/api/v1/courses/#{other_course.id}/pages",
|
json = api_call(:get, "/api/v1/courses/#{other_course.id}/pages",
|
||||||
{:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{other_course.id}"})
|
{:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{other_course.id}"})
|
||||||
|
json.should_not be_empty
|
||||||
|
|
||||||
api_call(:get, "/api/v1/courses/#{other_course.id}/pages/front-page",
|
api_call(:get, "/api/v1/courses/#{other_course.id}/pages/front-page",
|
||||||
{:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{other_course.id}", :url=>'front-page'})
|
{:controller=>'wiki_pages_api', :action=>'show', :format=>'json', :course_id=>"#{other_course.id}", :url=>'front-page'})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should fulfill module progression requirements" do
|
it "should fulfill module progression requirements" do
|
||||||
|
@ -181,13 +363,65 @@ describe "Pages API", :type => :integration do
|
||||||
|
|
||||||
# index should not affect anything
|
# index should not affect anything
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
{:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :course_id=>"#{@course.id}"})
|
{:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :course_id=>"#{@course.id}"})
|
||||||
mod.evaluate_for(@user).workflow_state.should == "unlocked"
|
mod.evaluate_for(@user).workflow_state.should == "unlocked"
|
||||||
|
|
||||||
# show should count as a view
|
# show should count as a view
|
||||||
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@front_page.url}",
|
api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@front_page.url}",
|
||||||
{:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :course_id=>"#{@course.id}", :url=>@front_page.url})
|
{:controller=>'wiki_pages_api', :action=>'show', :format=>'json', :course_id=>"#{@course.id}", :url=>@front_page.url})
|
||||||
mod.evaluate_for(@user).workflow_state.should == "completed"
|
mod.evaluate_for(@user).workflow_state.should == "completed"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow editing a page" do
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@front_page.url}",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @front_page.url },
|
||||||
|
{ :publish => false, :wiki_page => { :body => '!!!!' }}, {}, {:expected_status => 401})
|
||||||
|
@front_page.reload.body.should_not == '!!!!'
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "with students in editing_roles" do
|
||||||
|
before do
|
||||||
|
@editable_page = @course.wiki.wiki_pages.create! :title => 'Editable Page', :editing_roles => 'students'
|
||||||
|
@editable_page.workflow_state = 'active'
|
||||||
|
@editable_page.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow editing the body, but not attributes" do
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@editable_page.url}",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @editable_page.url },
|
||||||
|
{ :wiki_page => { :published => false, :title => 'Broken Links', :body => '?!?!' }})
|
||||||
|
@editable_page.reload
|
||||||
|
@editable_page.should be_active
|
||||||
|
@editable_page.title.should == 'Editable Page'
|
||||||
|
@editable_page.body.should == '?!?!'
|
||||||
|
@editable_page.user_id.should == @student.id
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should fulfill module completion requirements" do
|
||||||
|
mod = @course.context_modules.create!(:name => "some module")
|
||||||
|
tag = mod.add_item(:id => @editable_page.id, :type => 'wiki_page')
|
||||||
|
mod.completion_requirements = { tag.id => {:type => 'must_contribute'} }
|
||||||
|
mod.save!
|
||||||
|
|
||||||
|
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@editable_page.url}",
|
||||||
|
{:controller=>'wiki_pages_api', :action=>'update', :format=>'json', :course_id=>"#{@course.id}",
|
||||||
|
:url=>@editable_page.url}, { :wiki_page => { :body => 'edited by student' }})
|
||||||
|
mod.evaluate_for(@user).workflow_state.should == "completed"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow creating pages" do
|
||||||
|
api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||||
|
{}, {}, {:expected_status => 401})
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow deleting pages" do
|
||||||
|
api_call(:delete, "/api/v1/courses/#{@course.id}/pages/#{@editable_page.url}",
|
||||||
|
{ :controller => 'wiki_pages_api', :action => 'destroy', :format => 'json', :course_id => @course.to_param,
|
||||||
|
:url => @editable_page.url }, {}, {}, {:expected_status => 401})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "unpublished pages" do
|
context "unpublished pages" do
|
||||||
|
@ -199,13 +433,13 @@ describe "Pages API", :type => :integration do
|
||||||
|
|
||||||
it "should not be in index" do
|
it "should not be in index" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages",
|
||||||
:controller => "wiki_pages", :action => "api_index", :format => "json", :course_id => "#{@course.id}")
|
:controller => "wiki_pages_api", :action => "index", :format => "json", :course_id => "#{@course.id}")
|
||||||
json.select { |w| w[:title] == @unpublished_page.title }.should == []
|
json.select { |w| w[:title] == @unpublished_page.title }.should == []
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not show" do
|
it "should not show" do
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@unpublished_page.url}",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@unpublished_page.url}",
|
||||||
{:controller => "wiki_pages", :action => "api_show", :format => "json", :course_id => "#{@course.id}", :url => @unpublished_page.url},
|
{:controller => "wiki_pages_api", :action => "show", :format => "json", :course_id => "#{@course.id}", :url => @unpublished_page.url},
|
||||||
{}, {}, {:expected_status => 401})
|
{}, {}, {:expected_status => 401})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -213,7 +447,7 @@ describe "Pages API", :type => :integration do
|
||||||
@course.is_public = true
|
@course.is_public = true
|
||||||
@course.save!
|
@course.save!
|
||||||
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@unpublished_page.url}",
|
json = api_call(:get, "/api/v1/courses/#{@course.id}/pages/#{@unpublished_page.url}",
|
||||||
{:controller => "wiki_pages", :action => "api_show", :format => "json", :course_id => "#{@course.id}", :url => @unpublished_page.url},
|
{:controller => "wiki_pages_api", :action => "show", :format => "json", :course_id => "#{@course.id}", :url => @unpublished_page.url},
|
||||||
{}, {}, {:expected_status => 401})
|
{}, {}, {:expected_status => 401})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -227,15 +461,37 @@ describe "Pages API", :type => :integration do
|
||||||
|
|
||||||
it "should list the contents of a group wiki" do
|
it "should list the contents of a group wiki" do
|
||||||
json = api_call(:get, "/api/v1/groups/#{@group.id}/pages",
|
json = api_call(:get, "/api/v1/groups/#{@group.id}/pages",
|
||||||
{:controller=>"wiki_pages", :action=>"api_index", :format=>"json", :group_id=>"#{@group.id}"})
|
{:controller=>'wiki_pages_api', :action=>'index', :format=>'json', :group_id=>@group.to_param})
|
||||||
json.collect { |row| row['title'] }.should == @group.wiki.wiki_pages.active.order_by_id.collect(&:title)
|
json.collect { |row| row['title'] }.should == @group.wiki.wiki_pages.active.order_by_id.collect(&:title)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should retrieve page content from a group wiki" do
|
it "should retrieve page content from a group wiki" do
|
||||||
testpage = @group.wiki.wiki_pages.last
|
testpage = @group.wiki.wiki_pages.last
|
||||||
json = api_call(:get, "/api/v1/groups/#{@group.id}/pages/#{testpage.url}",
|
json = api_call(:get, "/api/v1/groups/#{@group.id}/pages/#{testpage.url}",
|
||||||
{:controller=>"wiki_pages", :action=>"api_show", :format=>"json", :group_id=>"#{@group.id}", :url=>testpage.url})
|
{:controller=>'wiki_pages_api', :action=>'show', :format=>'json', :group_id=>@group.to_param, :url=>testpage.url})
|
||||||
json['body'].should == testpage.body
|
json['body'].should == testpage.body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should create a group wiki page" do
|
||||||
|
json = api_call(:post, "/api/v1/groups/#{@group.id}/pages?wiki_page[title]=newpage",
|
||||||
|
{:controller=>'wiki_pages_api', :action=>'create', :format=>'json', :group_id=>@group.to_param, :wiki_page => {'title' => 'newpage'}})
|
||||||
|
page = @group.wiki.wiki_pages.find_by_url!(json['url'])
|
||||||
|
page.title.should == 'newpage'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should update a group wiki page" do
|
||||||
|
testpage = @group.wiki.wiki_pages.first
|
||||||
|
api_call(:put, "/api/v1/groups/#{@group.id}/pages/#{testpage.url}?wiki_page[body]=lolcats",
|
||||||
|
{:controller=>'wiki_pages_api', :action=>'update', :format=>'json', :group_id=>@group.to_param, :url=>testpage.url, :wiki_page => {'body' => 'lolcats'}})
|
||||||
|
testpage.reload.body.should == 'lolcats'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should delete a group wiki page" do
|
||||||
|
count = @group.wiki.wiki_pages.not_deleted.size
|
||||||
|
testpage = @group.wiki.wiki_pages.last
|
||||||
|
api_call(:delete, "/api/v1/groups/#{@group.id}/pages/#{testpage.url}",
|
||||||
|
{:controller=>'wiki_pages_api', :action=>'destroy', :format=>'json', :group_id=>@group.to_param, :url=>testpage.url})
|
||||||
|
@group.reload.wiki.wiki_pages.not_deleted.size.should == count - 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue