@@ -553,8 +553,13 class ApplicationController < ActionController::Base | |||
|
553 | 553 | |
|
554 | 554 | # Renders a 200 response for successfull updates or deletions via the API |
|
555 | 555 | def render_api_ok |
|
556 | # head :ok would return a response body with one space | |
|
557 | render :text => '', :status => :ok, :layout => nil | |
|
556 | render_api_head :ok | |
|
557 | end | |
|
558 | ||
|
559 | # Renders a head API response | |
|
560 | def render_api_head(status) | |
|
561 | # #head would return a response body with one space | |
|
562 | render :text => '', :status => status, :layout => nil | |
|
558 | 563 | end |
|
559 | 564 | |
|
560 | 565 | # Renders API response on validation failure |
@@ -36,7 +36,7 class WikiController < ApplicationController | |||
|
36 | 36 | before_filter :find_wiki, :authorize |
|
37 | 37 | before_filter :find_existing_or_new_page, :only => [:show, :edit, :update] |
|
38 | 38 | before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version] |
|
39 | accept_api_auth :index, :show | |
|
39 | accept_api_auth :index, :show, :update | |
|
40 | 40 | |
|
41 | 41 | helper :attachments |
|
42 | 42 | include AttachmentsHelper |
@@ -130,15 +130,18 class WikiController < ApplicationController | |||
|
130 | 130 | # Creates a new page or updates an existing one |
|
131 | 131 | def update |
|
132 | 132 | return render_403 unless editable? |
|
133 | was_new_page = @page.new_record? | |
|
133 | 134 | @page.content = WikiContent.new(:page => @page) if @page.new_record? |
|
134 | 135 | @page.safe_attributes = params[:wiki_page] |
|
135 | 136 | |
|
136 |
@content = @page.content |
|
|
137 | @content.text = initial_page_content(@page) if @content.text.blank? | |
|
138 | # don't keep previous comment | |
|
139 | @content.comments = nil | |
|
137 | @content = @page.content | |
|
138 | content_params = params[:content] | |
|
139 | if content_params.nil? && params[:wiki_page].is_a?(Hash) | |
|
140 | content_params = params[:wiki_page].slice(:text, :comments, :version) | |
|
141 | end | |
|
142 | content_params ||= {} | |
|
140 | 143 | |
|
141 |
if !@page.new_record? && |
|
|
144 | if !@page.new_record? && content_params.present? && @content.text == content_params[:text] | |
|
142 | 145 | attachments = Attachment.attach_files(@page, params[:attachments]) |
|
143 | 146 | render_attachment_warning_if_needed(@page) |
|
144 | 147 | # don't save content if text wasn't changed |
@@ -147,14 +150,14 class WikiController < ApplicationController | |||
|
147 | 150 | return |
|
148 | 151 | end |
|
149 | 152 | |
|
150 |
@content.comments = |
|
|
151 |
@text = |
|
|
153 | @content.comments = content_params[:comments] | |
|
154 | @text = content_params[:text] | |
|
152 | 155 | if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? |
|
153 | 156 | @section = params[:section].to_i |
|
154 | 157 | @section_hash = params[:section_hash] |
|
155 | 158 | @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash) |
|
156 | 159 | else |
|
157 |
@content.version = params[: |
|
|
160 | @content.version = content_params[:version] if content_params[:version] | |
|
158 | 161 | @content.text = @text |
|
159 | 162 | end |
|
160 | 163 | @content.author = User.current |
@@ -163,17 +166,38 class WikiController < ApplicationController | |||
|
163 | 166 | attachments = Attachment.attach_files(@page, params[:attachments]) |
|
164 | 167 | render_attachment_warning_if_needed(@page) |
|
165 | 168 | call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page}) |
|
166 | redirect_to :action => 'show', :project_id => @project, :id => @page.title | |
|
169 | ||
|
170 | respond_to do |format| | |
|
171 | format.html { redirect_to :action => 'show', :project_id => @project, :id => @page.title } | |
|
172 | format.api { | |
|
173 | if was_new_page | |
|
174 | render :action => 'show', :status => :created, :location => url_for(:controller => 'wiki', :action => 'show', :project_id => @project, :id => @page.title) | |
|
175 | else | |
|
176 | render_api_ok | |
|
177 | end | |
|
178 | } | |
|
179 | end | |
|
167 | 180 | else |
|
168 | render :action => 'edit' | |
|
181 | respond_to do |format| | |
|
182 | format.html { render :action => 'edit' } | |
|
183 | format.api { render_validation_errors(@content) } | |
|
184 | end | |
|
169 | 185 | end |
|
170 | 186 | |
|
171 | 187 | rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError |
|
172 | 188 | # Optimistic locking exception |
|
173 | flash.now[:error] = l(:notice_locking_conflict) | |
|
174 | render :action => 'edit' | |
|
189 | respond_to do |format| | |
|
190 | format.html { | |
|
191 | flash.now[:error] = l(:notice_locking_conflict) | |
|
192 | render :action => 'edit' | |
|
193 | } | |
|
194 | format.api { render_api_head :conflict } | |
|
195 | end | |
|
175 | 196 | rescue ActiveRecord::RecordNotSaved |
|
176 | render :action => 'edit' | |
|
197 | respond_to do |format| | |
|
198 | format.html { render :action => 'edit' } | |
|
199 | format.api { render_validation_errors(@content) } | |
|
200 | end | |
|
177 | 201 | end |
|
178 | 202 | |
|
179 | 203 | # rename a page |
@@ -57,7 +57,7 class WikiPage < ActiveRecord::Base | |||
|
57 | 57 | # Wiki pages that are protected by default |
|
58 | 58 | DEFAULT_PROTECTED_PAGES = %w(sidebar) |
|
59 | 59 | |
|
60 | safe_attributes 'parent_id', | |
|
60 | safe_attributes 'parent_id', 'parent_title', | |
|
61 | 61 | :if => lambda {|page, user| page.new_record? || user.allowed_to?(:rename_wiki_pages, page.project)} |
|
62 | 62 | |
|
63 | 63 | def initialize(attributes=nil, *args) |
@@ -28,7 +28,7 class ApiTest::WikiPagesTest < ActionController::IntegrationTest | |||
|
28 | 28 | |
|
29 | 29 | test "GET /projects/:project_id/wiki/index.xml should return wiki pages" do |
|
30 | 30 | get '/projects/ecookbook/wiki/index.xml' |
|
31 |
assert_response |
|
|
31 | assert_response 200 | |
|
32 | 32 | assert_equal 'application/xml', response.content_type |
|
33 | 33 | assert_select 'wiki_pages[type=array]' do |
|
34 | 34 | assert_select 'wiki_page', :count => Wiki.find(1).pages.count |
@@ -38,12 +38,16 class ApiTest::WikiPagesTest < ActionController::IntegrationTest | |||
|
38 | 38 | assert_select 'created_on' |
|
39 | 39 | assert_select 'updated_on' |
|
40 | 40 | end |
|
41 | assert_select 'wiki_page' do | |
|
42 | assert_select 'title', :text => 'Page_with_an_inline_image' | |
|
43 | assert_select 'parent[title=?]', 'CookBook_documentation' | |
|
44 | end | |
|
41 | 45 | end |
|
42 | 46 | end |
|
43 | 47 | |
|
44 | 48 | test "GET /projects/:project_id/wiki/:title.xml should return wiki page" do |
|
45 | 49 | get '/projects/ecookbook/wiki/CookBook_documentation.xml' |
|
46 |
assert_response |
|
|
50 | assert_response 200 | |
|
47 | 51 | assert_equal 'application/xml', response.content_type |
|
48 | 52 | assert_select 'wiki_page' do |
|
49 | 53 | assert_select 'title', :text => 'CookBook_documentation' |
@@ -63,7 +67,7 class ApiTest::WikiPagesTest < ActionController::IntegrationTest | |||
|
63 | 67 | |
|
64 | 68 | test "GET /projects/:project_id/wiki/:title/:version.xml should return wiki page version" do |
|
65 | 69 | get '/projects/ecookbook/wiki/CookBook_documentation/2.xml' |
|
66 |
assert_response |
|
|
70 | assert_response 200 | |
|
67 | 71 | assert_equal 'application/xml', response.content_type |
|
68 | 72 | assert_select 'wiki_page' do |
|
69 | 73 | assert_select 'title', :text => 'CookBook_documentation' |
@@ -82,4 +86,83 class ApiTest::WikiPagesTest < ActionController::IntegrationTest | |||
|
82 | 86 | assert_response 401 |
|
83 | 87 | assert_equal 'application/xml', response.content_type |
|
84 | 88 | end |
|
89 | ||
|
90 | test "PUT /projects/:project_id/wiki/:title.xml should update wiki page" do | |
|
91 | assert_no_difference 'WikiPage.count' do | |
|
92 | assert_difference 'WikiContent::Version.count' do | |
|
93 | put '/projects/ecookbook/wiki/CookBook_documentation.xml', | |
|
94 | {:wiki_page => {:text => 'New content from API', :comments => 'API update'}}, | |
|
95 | credentials('jsmith') | |
|
96 | assert_response 200 | |
|
97 | end | |
|
98 | end | |
|
99 | ||
|
100 | page = WikiPage.find(1) | |
|
101 | assert_equal 'New content from API', page.content.text | |
|
102 | assert_equal 4, page.content.version | |
|
103 | assert_equal 'API update', page.content.comments | |
|
104 | assert_equal 'jsmith', page.content.author.login | |
|
105 | end | |
|
106 | ||
|
107 | test "PUT /projects/:project_id/wiki/:title.xml with current versino should update wiki page" do | |
|
108 | assert_no_difference 'WikiPage.count' do | |
|
109 | assert_difference 'WikiContent::Version.count' do | |
|
110 | put '/projects/ecookbook/wiki/CookBook_documentation.xml', | |
|
111 | {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '3'}}, | |
|
112 | credentials('jsmith') | |
|
113 | assert_response 200 | |
|
114 | end | |
|
115 | end | |
|
116 | ||
|
117 | page = WikiPage.find(1) | |
|
118 | assert_equal 'New content from API', page.content.text | |
|
119 | assert_equal 4, page.content.version | |
|
120 | assert_equal 'API update', page.content.comments | |
|
121 | assert_equal 'jsmith', page.content.author.login | |
|
122 | end | |
|
123 | ||
|
124 | test "PUT /projects/:project_id/wiki/:title.xml with stale version should respond with 409" do | |
|
125 | assert_no_difference 'WikiPage.count' do | |
|
126 | assert_no_difference 'WikiContent::Version.count' do | |
|
127 | put '/projects/ecookbook/wiki/CookBook_documentation.xml', | |
|
128 | {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '2'}}, | |
|
129 | credentials('jsmith') | |
|
130 | assert_response 409 | |
|
131 | end | |
|
132 | end | |
|
133 | end | |
|
134 | ||
|
135 | test "PUT /projects/:project_id/wiki/:title.xml should create the page if it does not exist" do | |
|
136 | assert_difference 'WikiPage.count' do | |
|
137 | assert_difference 'WikiContent::Version.count' do | |
|
138 | put '/projects/ecookbook/wiki/New_page_from_API.xml', | |
|
139 | {:wiki_page => {:text => 'New content from API', :comments => 'API create'}}, | |
|
140 | credentials('jsmith') | |
|
141 | assert_response 201 | |
|
142 | end | |
|
143 | end | |
|
144 | ||
|
145 | page = WikiPage.order('id DESC').first | |
|
146 | assert_equal 'New_page_from_API', page.title | |
|
147 | assert_equal 'New content from API', page.content.text | |
|
148 | assert_equal 1, page.content.version | |
|
149 | assert_equal 'API create', page.content.comments | |
|
150 | assert_equal 'jsmith', page.content.author.login | |
|
151 | assert_nil page.parent | |
|
152 | end | |
|
153 | ||
|
154 | test "PUT /projects/:project_id/wiki/:title.xml with parent" do | |
|
155 | assert_difference 'WikiPage.count' do | |
|
156 | assert_difference 'WikiContent::Version.count' do | |
|
157 | put '/projects/ecookbook/wiki/New_subpage_from_API.xml', | |
|
158 | {:wiki_page => {:parent_title => 'CookBook_documentation', :text => 'New content from API', :comments => 'API create'}}, | |
|
159 | credentials('jsmith') | |
|
160 | assert_response 201 | |
|
161 | end | |
|
162 | end | |
|
163 | ||
|
164 | page = WikiPage.order('id DESC').first | |
|
165 | assert_equal 'New_subpage_from_API', page.title | |
|
166 | assert_equal WikiPage.find(1), page.parent | |
|
167 | end | |
|
85 | 168 | end |
@@ -34,16 +34,6 class RoutingWikiTest < ActionController::IntegrationTest | |||
|
34 | 34 | :id => 'lalala', :format => 'pdf' } |
|
35 | 35 | ) |
|
36 | 36 | assert_routing( |
|
37 | { :method => 'get', :path => "/projects/567/wiki/lalala.xml" }, | |
|
38 | { :controller => 'wiki', :action => 'show', :project_id => '567', | |
|
39 | :id => 'lalala', :format => 'xml' } | |
|
40 | ) | |
|
41 | assert_routing( | |
|
42 | { :method => 'get', :path => "/projects/567/wiki/lalala.json" }, | |
|
43 | { :controller => 'wiki', :action => 'show', :project_id => '567', | |
|
44 | :id => 'lalala', :format => 'json' } | |
|
45 | ) | |
|
46 | assert_routing( | |
|
47 | 37 | { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/diff" }, |
|
48 | 38 | { :controller => 'wiki', :action => 'diff', :project_id => '1', |
|
49 | 39 | :id => 'CookBook_documentation' } |
@@ -54,16 +44,6 class RoutingWikiTest < ActionController::IntegrationTest | |||
|
54 | 44 | :id => 'CookBook_documentation', :version => '2' } |
|
55 | 45 | ) |
|
56 | 46 | assert_routing( |
|
57 | { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2.xml" }, | |
|
58 | { :controller => 'wiki', :action => 'show', :project_id => '1', | |
|
59 | :id => 'CookBook_documentation', :version => '2', :format => 'xml' } | |
|
60 | ) | |
|
61 | assert_routing( | |
|
62 | { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2.json" }, | |
|
63 | { :controller => 'wiki', :action => 'show', :project_id => '1', | |
|
64 | :id => 'CookBook_documentation', :version => '2', :format => 'json' } | |
|
65 | ) | |
|
66 | assert_routing( | |
|
67 | 47 | { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2/diff" }, |
|
68 | 48 | { :controller => 'wiki', :action => 'diff', :project_id => '1', |
|
69 | 49 | :id => 'CookBook_documentation', :version => '2' } |
@@ -92,14 +72,6 class RoutingWikiTest < ActionController::IntegrationTest | |||
|
92 | 72 | { :method => 'get', :path => "/projects/567/wiki/index" }, |
|
93 | 73 | { :controller => 'wiki', :action => 'index', :project_id => '567' } |
|
94 | 74 | ) |
|
95 | assert_routing( | |
|
96 | { :method => 'get', :path => "/projects/567/wiki/index.xml" }, | |
|
97 | { :controller => 'wiki', :action => 'index', :project_id => '567', :format => 'xml' } | |
|
98 | ) | |
|
99 | assert_routing( | |
|
100 | { :method => 'get', :path => "/projects/567/wiki/index.json" }, | |
|
101 | { :controller => 'wiki', :action => 'index', :project_id => '567', :format => 'json' } | |
|
102 | ) | |
|
103 | 75 | end |
|
104 | 76 | |
|
105 | 77 | def test_wiki_resources |
@@ -156,4 +128,45 class RoutingWikiTest < ActionController::IntegrationTest | |||
|
156 | 128 | :id => 'ladida', :version => '3' } |
|
157 | 129 | ) |
|
158 | 130 | end |
|
131 | ||
|
132 | def test_api | |
|
133 | assert_routing( | |
|
134 | { :method => 'get', :path => "/projects/567/wiki/my_page.xml" }, | |
|
135 | { :controller => 'wiki', :action => 'show', :project_id => '567', | |
|
136 | :id => 'my_page', :format => 'xml' } | |
|
137 | ) | |
|
138 | assert_routing( | |
|
139 | { :method => 'get', :path => "/projects/567/wiki/my_page.json" }, | |
|
140 | { :controller => 'wiki', :action => 'show', :project_id => '567', | |
|
141 | :id => 'my_page', :format => 'json' } | |
|
142 | ) | |
|
143 | assert_routing( | |
|
144 | { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2.xml" }, | |
|
145 | { :controller => 'wiki', :action => 'show', :project_id => '1', | |
|
146 | :id => 'CookBook_documentation', :version => '2', :format => 'xml' } | |
|
147 | ) | |
|
148 | assert_routing( | |
|
149 | { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2.json" }, | |
|
150 | { :controller => 'wiki', :action => 'show', :project_id => '1', | |
|
151 | :id => 'CookBook_documentation', :version => '2', :format => 'json' } | |
|
152 | ) | |
|
153 | assert_routing( | |
|
154 | { :method => 'get', :path => "/projects/567/wiki/index.xml" }, | |
|
155 | { :controller => 'wiki', :action => 'index', :project_id => '567', :format => 'xml' } | |
|
156 | ) | |
|
157 | assert_routing( | |
|
158 | { :method => 'get', :path => "/projects/567/wiki/index.json" }, | |
|
159 | { :controller => 'wiki', :action => 'index', :project_id => '567', :format => 'json' } | |
|
160 | ) | |
|
161 | assert_routing( | |
|
162 | { :method => 'put', :path => "/projects/567/wiki/my_page.xml" }, | |
|
163 | { :controller => 'wiki', :action => 'update', :project_id => '567', | |
|
164 | :id => 'my_page', :format => 'xml' } | |
|
165 | ) | |
|
166 | assert_routing( | |
|
167 | { :method => 'put', :path => "/projects/567/wiki/my_page.json" }, | |
|
168 | { :controller => 'wiki', :action => 'update', :project_id => '567', | |
|
169 | :id => 'my_page', :format => 'json' } | |
|
170 | ) | |
|
171 | end | |
|
159 | 172 | end |
General Comments 0
You need to be logged in to leave comments.
Login now