Revision 1298:4f746d8966dd .svn/pristine/13
| .svn/pristine/13/134682aa67acff21c24711968698972a9dfb0d8a.svn-base | ||
|---|---|---|
| 1 |
<h2><%= link_to l(:label_role_plural), :controller => 'roles', :action => 'index' %> » <%=l(:label_role_new)%></h2> |
|
| 2 |
|
|
| 3 |
<% labelled_tabular_form_for :role, @role, :url => { :action => 'new' }, :html => {:id => 'role_form'} do |f| %>
|
|
| 4 |
<%= render :partial => 'form', :locals => { :f => f } %>
|
|
| 5 |
<%= submit_tag l(:button_create) %> |
|
| 6 |
<% end %> |
|
| .svn/pristine/13/134ab6c377c7865f7eab83c298719a41c97ec009.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 19 |
|
|
| 20 |
class AttachmentsTest < ActionController::IntegrationTest |
|
| 21 |
fixtures :projects, :enabled_modules, |
|
| 22 |
:users, :roles, :members, :member_roles, |
|
| 23 |
:trackers, :projects_trackers, |
|
| 24 |
:issue_statuses, :enumerations |
|
| 25 |
|
|
| 26 |
def test_upload_as_js_and_attach_to_an_issue |
|
| 27 |
log_user('jsmith', 'jsmith')
|
|
| 28 |
|
|
| 29 |
token = ajax_upload('myupload.txt', 'File content')
|
|
| 30 |
|
|
| 31 |
assert_difference 'Issue.count' do |
|
| 32 |
post '/projects/ecookbook/issues', {
|
|
| 33 |
:issue => {:tracker_id => 1, :subject => 'Issue with upload'},
|
|
| 34 |
:attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
|
|
| 35 |
} |
|
| 36 |
assert_response 302 |
|
| 37 |
end |
|
| 38 |
|
|
| 39 |
issue = Issue.order('id DESC').first
|
|
| 40 |
assert_equal 'Issue with upload', issue.subject |
|
| 41 |
assert_equal 1, issue.attachments.count |
|
| 42 |
|
|
| 43 |
attachment = issue.attachments.first |
|
| 44 |
assert_equal 'myupload.txt', attachment.filename |
|
| 45 |
assert_equal 'My uploaded file', attachment.description |
|
| 46 |
assert_equal 'File content'.length, attachment.filesize |
|
| 47 |
end |
|
| 48 |
|
|
| 49 |
def test_upload_as_js_and_preview_as_inline_attachment |
|
| 50 |
log_user('jsmith', 'jsmith')
|
|
| 51 |
|
|
| 52 |
token = ajax_upload('myupload.jpg', 'JPEG content')
|
|
| 53 |
|
|
| 54 |
post '/issues/preview/new/ecookbook', {
|
|
| 55 |
:issue => {:tracker_id => 1, :description => 'Inline upload: !myupload.jpg!'},
|
|
| 56 |
:attachments => {'1' => {:filename => 'myupload.jpg', :description => 'My uploaded file', :token => token}}
|
|
| 57 |
} |
|
| 58 |
assert_response :success |
|
| 59 |
|
|
| 60 |
attachment_path = response.body.match(%r{<img src="(/attachments/download/\d+/myupload.jpg)"})[1]
|
|
| 61 |
assert_not_nil token, "No attachment path found in response:\n#{response.body}"
|
|
| 62 |
|
|
| 63 |
get attachment_path |
|
| 64 |
assert_response :success |
|
| 65 |
assert_equal 'JPEG content', response.body |
|
| 66 |
end |
|
| 67 |
|
|
| 68 |
def test_upload_and_resubmit_after_validation_failure |
|
| 69 |
log_user('jsmith', 'jsmith')
|
|
| 70 |
|
|
| 71 |
token = ajax_upload('myupload.txt', 'File content')
|
|
| 72 |
|
|
| 73 |
assert_no_difference 'Issue.count' do |
|
| 74 |
post '/projects/ecookbook/issues', {
|
|
| 75 |
:issue => {:tracker_id => 1, :subject => ''},
|
|
| 76 |
:attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
|
|
| 77 |
} |
|
| 78 |
assert_response :success |
|
| 79 |
end |
|
| 80 |
assert_select 'input[type=hidden][name=?][value=?]', 'attachments[p0][token]', token |
|
| 81 |
assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'myupload.txt' |
|
| 82 |
assert_select 'input[name=?][value=?]', 'attachments[p0][description]', 'My uploaded file' |
|
| 83 |
|
|
| 84 |
assert_difference 'Issue.count' do |
|
| 85 |
post '/projects/ecookbook/issues', {
|
|
| 86 |
:issue => {:tracker_id => 1, :subject => 'Issue with upload'},
|
|
| 87 |
:attachments => {'p0' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
|
|
| 88 |
} |
|
| 89 |
assert_response 302 |
|
| 90 |
end |
|
| 91 |
|
|
| 92 |
issue = Issue.order('id DESC').first
|
|
| 93 |
assert_equal 'Issue with upload', issue.subject |
|
| 94 |
assert_equal 1, issue.attachments.count |
|
| 95 |
|
|
| 96 |
attachment = issue.attachments.first |
|
| 97 |
assert_equal 'myupload.txt', attachment.filename |
|
| 98 |
assert_equal 'My uploaded file', attachment.description |
|
| 99 |
assert_equal 'File content'.length, attachment.filesize |
|
| 100 |
end |
|
| 101 |
|
|
| 102 |
def test_upload_as_js_and_destroy |
|
| 103 |
log_user('jsmith', 'jsmith')
|
|
| 104 |
|
|
| 105 |
token = ajax_upload('myupload.txt', 'File content')
|
|
| 106 |
|
|
| 107 |
attachment = Attachment.order('id DESC').first
|
|
| 108 |
attachment_path = "/attachments/#{attachment.id}.js?attachment_id=1"
|
|
| 109 |
assert_include "href: '#{attachment_path}'", response.body, "Path to attachment: #{attachment_path} not found in response:\n#{response.body}"
|
|
| 110 |
|
|
| 111 |
assert_difference 'Attachment.count', -1 do |
|
| 112 |
delete attachment_path |
|
| 113 |
assert_response :success |
|
| 114 |
end |
|
| 115 |
|
|
| 116 |
assert_include "$('#attachments_1').remove();", response.body
|
|
| 117 |
end |
|
| 118 |
|
|
| 119 |
private |
|
| 120 |
|
|
| 121 |
def ajax_upload(filename, content, attachment_id=1) |
|
| 122 |
assert_difference 'Attachment.count' do |
|
| 123 |
post "/uploads.js?attachment_id=#{attachment_id}&filename=#{filename}", content, {"CONTENT_TYPE" => 'application/octet-stream'}
|
|
| 124 |
assert_response :success |
|
| 125 |
assert_equal 'text/javascript', response.content_type |
|
| 126 |
end |
|
| 127 |
|
|
| 128 |
token = response.body.match(/\.val\('(\d+\.[0-9a-f]+)'\)/)[1]
|
|
| 129 |
assert_not_nil token, "No upload token found in response:\n#{response.body}"
|
|
| 130 |
token |
|
| 131 |
end |
|
| 132 |
end |
|
| .svn/pristine/13/1360db03d113fb07eff0808c5131dd75d05da3fd.svn-base | ||
|---|---|---|
| 1 |
// ** I18N |
|
| 2 |
|
|
| 3 |
// Calendar DE language |
|
| 4 |
// Author: Jack (tR), <jack@jtr.de> |
|
| 5 |
// Encoding: any |
|
| 6 |
// Distributed under the same terms as the calendar itself. |
|
| 7 |
|
|
| 8 |
// For translators: please use UTF-8 if possible. We strongly believe that |
|
| 9 |
// Unicode is the answer to a real internationalized world. Also please |
|
| 10 |
// include your contact information in the header, as can be seen above. |
|
| 11 |
|
|
| 12 |
// full day names |
|
| 13 |
Calendar._DN = new Array |
|
| 14 |
("Sonntag",
|
|
| 15 |
"Montag", |
|
| 16 |
"Dienstag", |
|
| 17 |
"Mittwoch", |
|
| 18 |
"Donnerstag", |
|
| 19 |
"Freitag", |
|
| 20 |
"Samstag", |
|
| 21 |
"Sonntag"); |
|
| 22 |
|
|
| 23 |
// Please note that the following array of short day names (and the same goes |
|
| 24 |
// for short month names, _SMN) isn't absolutely necessary. We give it here |
|
| 25 |
// for exemplification on how one can customize the short day names, but if |
|
| 26 |
// they are simply the first N letters of the full name you can simply say: |
|
| 27 |
// |
|
| 28 |
// Calendar._SDN_len = N; // short day name length |
|
| 29 |
// Calendar._SMN_len = N; // short month name length |
|
| 30 |
// |
|
| 31 |
// If N = 3 then this is not needed either since we assume a value of 3 if not |
|
| 32 |
// present, to be compatible with translation files that were written before |
|
| 33 |
// this feature. |
|
| 34 |
|
|
| 35 |
// First day of the week. "0" means display Sunday first, "1" means display |
|
| 36 |
// Monday first, etc. |
|
| 37 |
Calendar._FD = 1; |
|
| 38 |
|
|
| 39 |
// short day names |
|
| 40 |
Calendar._SDN = new Array |
|
| 41 |
("So",
|
|
| 42 |
"Mo", |
|
| 43 |
"Di", |
|
| 44 |
"Mi", |
|
| 45 |
"Do", |
|
| 46 |
"Fr", |
|
| 47 |
"Sa", |
|
| 48 |
"So"); |
|
| 49 |
|
|
| 50 |
// full month names |
|
| 51 |
Calendar._MN = new Array |
|
| 52 |
("Januar",
|
|
| 53 |
"Februar", |
|
| 54 |
"M\u00e4rz", |
|
| 55 |
"April", |
|
| 56 |
"Mai", |
|
| 57 |
"Juni", |
|
| 58 |
"Juli", |
|
| 59 |
"August", |
|
| 60 |
"September", |
|
| 61 |
"Oktober", |
|
| 62 |
"November", |
|
| 63 |
"Dezember"); |
|
| 64 |
|
|
| 65 |
// short month names |
|
| 66 |
Calendar._SMN = new Array |
|
| 67 |
("Jan",
|
|
| 68 |
"Feb", |
|
| 69 |
"M\u00e4r", |
|
| 70 |
"Apr", |
|
| 71 |
"May", |
|
| 72 |
"Jun", |
|
| 73 |
"Jul", |
|
| 74 |
"Aug", |
|
| 75 |
"Sep", |
|
| 76 |
"Okt", |
|
| 77 |
"Nov", |
|
| 78 |
"Dez"); |
|
| 79 |
|
|
| 80 |
// tooltips |
|
| 81 |
Calendar._TT = {};
|
|
| 82 |
Calendar._TT["INFO"] = "\u00DCber dieses Kalendarmodul"; |
|
| 83 |
|
|
| 84 |
Calendar._TT["ABOUT"] = |
|
| 85 |
"DHTML Date/Time Selector\n" + |
|
| 86 |
"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-) |
|
| 87 |
"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + |
|
| 88 |
"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + |
|
| 89 |
"\n\n" + |
|
| 90 |
"Datum ausw\u00e4hlen:\n" + |
|
| 91 |
"- Benutzen Sie die \xab, \xbb Buttons um das Jahr zu w\u00e4hlen\n" + |
|
| 92 |
"- Benutzen Sie die " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Buttons um den Monat zu w\u00e4hlen\n" + |
|
| 93 |
"- F\u00fcr eine Schnellauswahl halten Sie die Maustaste \u00fcber diesen Buttons fest."; |
|
| 94 |
Calendar._TT["ABOUT_TIME"] = "\n\n" + |
|
| 95 |
"Zeit ausw\u00e4hlen:\n" + |
|
| 96 |
"- Klicken Sie auf die Teile der Uhrzeit, um diese zu erh\u00F6hen\n" + |
|
| 97 |
"- oder klicken Sie mit festgehaltener Shift-Taste um diese zu verringern\n" + |
|
| 98 |
"- oder klicken und festhalten f\u00fcr Schnellauswahl."; |
|
| 99 |
|
|
| 100 |
Calendar._TT["TOGGLE"] = "Ersten Tag der Woche w\u00e4hlen"; |
|
| 101 |
Calendar._TT["PREV_YEAR"] = "Voriges Jahr (Festhalten f\u00fcr Schnellauswahl)"; |
|
| 102 |
Calendar._TT["PREV_MONTH"] = "Voriger Monat (Festhalten f\u00fcr Schnellauswahl)"; |
|
| 103 |
Calendar._TT["GO_TODAY"] = "Heute ausw\u00e4hlen"; |
|
| 104 |
Calendar._TT["NEXT_MONTH"] = "N\u00e4chst. Monat (Festhalten f\u00fcr Schnellauswahl)"; |
|
| 105 |
Calendar._TT["NEXT_YEAR"] = "N\u00e4chst. Jahr (Festhalten f\u00fcr Schnellauswahl)"; |
|
| 106 |
Calendar._TT["SEL_DATE"] = "Datum ausw\u00e4hlen"; |
|
| 107 |
Calendar._TT["DRAG_TO_MOVE"] = "Zum Bewegen festhalten"; |
|
| 108 |
Calendar._TT["PART_TODAY"] = " (Heute)"; |
|
| 109 |
|
|
| 110 |
// the following is to inform that "%s" is to be the first day of week |
|
| 111 |
// %s will be replaced with the day name. |
|
| 112 |
Calendar._TT["DAY_FIRST"] = "Woche beginnt mit %s "; |
|
| 113 |
|
|
| 114 |
// This may be locale-dependent. It specifies the week-end days, as an array |
|
| 115 |
// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 |
|
| 116 |
// means Monday, etc. |
|
| 117 |
Calendar._TT["WEEKEND"] = "0,6"; |
|
| 118 |
|
|
| 119 |
Calendar._TT["CLOSE"] = "Schlie\u00dfen"; |
|
| 120 |
Calendar._TT["TODAY"] = "Heute"; |
|
| 121 |
Calendar._TT["TIME_PART"] = "(Shift-)Klick oder Festhalten und Ziehen um den Wert zu \u00e4ndern"; |
|
| 122 |
|
|
| 123 |
// date formats |
|
| 124 |
Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; |
|
| 125 |
Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; |
|
| 126 |
|
|
| 127 |
Calendar._TT["WK"] = "wk"; |
|
| 128 |
Calendar._TT["TIME"] = "Zeit:"; |
|
| .svn/pristine/13/137331c94a623d300b9797520d5d31b04bbcafd5.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 19 |
|
|
| 20 |
class AdminTest < ActionController::IntegrationTest |
|
| 21 |
fixtures :projects, :trackers, :issue_statuses, :issues, |
|
| 22 |
:enumerations, :users, :issue_categories, |
|
| 23 |
:projects_trackers, |
|
| 24 |
:roles, |
|
| 25 |
:member_roles, |
|
| 26 |
:members, |
|
| 27 |
:enabled_modules, |
|
| 28 |
:workflows |
|
| 29 |
|
|
| 30 |
def test_add_user |
|
| 31 |
log_user("admin", "admin")
|
|
| 32 |
get "/users/new" |
|
| 33 |
assert_response :success |
|
| 34 |
assert_template "users/new" |
|
| 35 |
post "/users/create", |
|
| 36 |
:user => { :login => "psmith", :firstname => "Paul",
|
|
| 37 |
:lastname => "Smith", :mail => "psmith@somenet.foo", |
|
| 38 |
:language => "en", :password => "psmith09", |
|
| 39 |
:password_confirmation => "psmith09" } |
|
| 40 |
|
|
| 41 |
user = User.find_by_login("psmith")
|
|
| 42 |
assert_kind_of User, user |
|
| 43 |
assert_redirected_to "/users/#{ user.id }/edit"
|
|
| 44 |
|
|
| 45 |
logged_user = User.try_to_login("psmith", "psmith09")
|
|
| 46 |
assert_kind_of User, logged_user |
|
| 47 |
assert_equal "Paul", logged_user.firstname |
|
| 48 |
|
|
| 49 |
put "users/#{user.id}", :id => user.id, :user => { :status => User::STATUS_LOCKED }
|
|
| 50 |
assert_redirected_to "/users/#{ user.id }/edit"
|
|
| 51 |
locked_user = User.try_to_login("psmith", "psmith09")
|
|
| 52 |
assert_equal nil, locked_user |
|
| 53 |
end |
|
| 54 |
|
|
| 55 |
test "Add a user as an anonymous user should fail" do |
|
| 56 |
post '/users/create', |
|
| 57 |
:user => { :login => 'psmith', :firstname => 'Paul'},
|
|
| 58 |
:password => "psmith09", :password_confirmation => "psmith09" |
|
| 59 |
assert_response :redirect |
|
| 60 |
assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fusers" |
|
| 61 |
end |
|
| 62 |
end |
|
| .svn/pristine/13/1398acbd60647babc95a74c09ce2afa2acef1b0b.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
require File.expand_path('../../../../../../test_helper', __FILE__)
|
|
| 19 |
|
|
| 20 |
class Redmine::Views::Builders::JsonTest < ActiveSupport::TestCase |
|
| 21 |
|
|
| 22 |
def test_hash |
|
| 23 |
assert_json_output({'person' => {'name' => 'Ryan', 'age' => 32}}) do |b|
|
|
| 24 |
b.person do |
|
| 25 |
b.name 'Ryan' |
|
| 26 |
b.age 32 |
|
| 27 |
end |
|
| 28 |
end |
|
| 29 |
end |
|
| 30 |
|
|
| 31 |
def test_hash_hash |
|
| 32 |
assert_json_output({'person' => {'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
|
|
| 33 |
b.person do |
|
| 34 |
b.name 'Ryan' |
|
| 35 |
b.birth :city => 'London', :country => 'UK' |
|
| 36 |
end |
|
| 37 |
end |
|
| 38 |
|
|
| 39 |
assert_json_output({'person' => {'id' => 1, 'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
|
|
| 40 |
b.person :id => 1 do |
|
| 41 |
b.name 'Ryan' |
|
| 42 |
b.birth :city => 'London', :country => 'UK' |
|
| 43 |
end |
|
| 44 |
end |
|
| 45 |
end |
|
| 46 |
|
|
| 47 |
def test_array |
|
| 48 |
assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
|
|
| 49 |
b.array :books do |b| |
|
| 50 |
b.book :title => 'Book 1', :author => 'B. Smith' |
|
| 51 |
b.book :title => 'Book 2', :author => 'G. Cooper' |
|
| 52 |
end |
|
| 53 |
end |
|
| 54 |
|
|
| 55 |
assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
|
|
| 56 |
b.array :books do |b| |
|
| 57 |
b.book :title => 'Book 1' do |
|
| 58 |
b.author 'B. Smith' |
|
| 59 |
end |
|
| 60 |
b.book :title => 'Book 2' do |
|
| 61 |
b.author 'G. Cooper' |
|
| 62 |
end |
|
| 63 |
end |
|
| 64 |
end |
|
| 65 |
end |
|
| 66 |
|
|
| 67 |
def test_array_with_content_tags |
|
| 68 |
assert_json_output({'books' => [{'value' => 'Book 1', 'author' => 'B. Smith'}, {'value' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
|
|
| 69 |
b.array :books do |b| |
|
| 70 |
b.book 'Book 1', :author => 'B. Smith' |
|
| 71 |
b.book 'Book 2', :author => 'G. Cooper' |
|
| 72 |
end |
|
| 73 |
end |
|
| 74 |
end |
|
| 75 |
|
|
| 76 |
def test_nested_arrays |
|
| 77 |
assert_json_output({'books' => [{'authors' => ['B. Smith', 'G. Cooper']}]}) do |b|
|
|
| 78 |
b.array :books do |books| |
|
| 79 |
books.book do |book| |
|
| 80 |
book.array :authors do |authors| |
|
| 81 |
authors.author 'B. Smith' |
|
| 82 |
authors.author 'G. Cooper' |
|
| 83 |
end |
|
| 84 |
end |
|
| 85 |
end |
|
| 86 |
end |
|
| 87 |
end |
|
| 88 |
|
|
| 89 |
def assert_json_output(expected, &block) |
|
| 90 |
builder = Redmine::Views::Builders::Json.new(ActionDispatch::TestRequest.new, ActionDispatch::TestResponse.new) |
|
| 91 |
block.call(builder) |
|
| 92 |
assert_equal(expected, ActiveSupport::JSON.decode(builder.output)) |
|
| 93 |
end |
|
| 94 |
end |
|
| .svn/pristine/13/13a9de4a4790249b88f8367228e59b3e03f18775.svn-base | ||
|---|---|---|
| 1 |
<div class="contextual"> |
|
| 2 |
<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
|
|
| 3 |
</div> |
|
| 4 |
|
|
| 5 |
<%= render_timelog_breadcrumb %> |
|
| 6 |
|
|
| 7 |
<h2><%= l(:label_spent_time) %></h2> |
|
| 8 |
|
|
| 9 |
<% form_tag({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
|
|
| 10 |
<% @criterias.each do |criteria| %> |
|
| 11 |
<%= hidden_field_tag 'criterias[]', criteria, :id => nil %> |
|
| 12 |
<% end %> |
|
| 13 |
<%= render :partial => 'timelog/date_range' %> |
|
| 14 |
|
|
| 15 |
<p><label for='columns'><%= l(:label_details) %></label>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'], |
|
| 16 |
[l(:label_month), 'month'], |
|
| 17 |
[l(:label_week), 'week'], |
|
| 18 |
[l(:label_day_plural).titleize, 'day']], @columns), |
|
| 19 |
:onchange => "this.form.onsubmit();" %> |
|
| 20 |
|
|
| 21 |
<label for='criterias'><%= l(:button_add) %></label>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l_or_humanize(@available_criterias[k][:label]), k]}),
|
|
| 22 |
:onchange => "this.form.submit();", |
|
| 23 |
:style => 'width: 200px', |
|
| 24 |
:id => nil, |
|
| 25 |
:disabled => (@criterias.length >= 3), :id => "criterias") %> |
|
| 26 |
<%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns}, :class => 'icon icon-reload' %></p>
|
|
| 27 |
<% end %> |
|
| 28 |
|
|
| 29 |
<% unless @criterias.empty? %> |
|
| 30 |
<div class="total-hours"> |
|
| 31 |
<p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p> |
|
| 32 |
</div> |
|
| 33 |
|
|
| 34 |
<% unless @hours.empty? %> |
|
| 35 |
<div class="autoscroll"> |
|
| 36 |
<table class="list" id="time-report"> |
|
| 37 |
<thead> |
|
| 38 |
<tr> |
|
| 39 |
<% @criterias.each do |criteria| %> |
|
| 40 |
<th><%= l_or_humanize(@available_criterias[criteria][:label]) %></th> |
|
| 41 |
<% end %> |
|
| 42 |
<% columns_width = (40 / (@periods.length+1)).to_i %> |
|
| 43 |
<% @periods.each do |period| %> |
|
| 44 |
<th class="period" width="<%= columns_width %>%"><%= period %></th> |
|
| 45 |
<% end %> |
|
| 46 |
<th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th> |
|
| 47 |
</tr> |
|
| 48 |
</thead> |
|
| 49 |
<tbody> |
|
| 50 |
<%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
|
|
| 51 |
<tr class="total"> |
|
| 52 |
<td><%= l(:label_total) %></td> |
|
| 53 |
<%= '<td></td>' * (@criterias.size - 1) %> |
|
| 54 |
<% total = 0 -%> |
|
| 55 |
<% @periods.each do |period| -%> |
|
| 56 |
<% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%> |
|
| 57 |
<td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
|
|
| 58 |
<% end -%> |
|
| 59 |
<td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
|
|
| 60 |
</tr> |
|
| 61 |
</tbody> |
|
| 62 |
</table> |
|
| 63 |
</div> |
|
| 64 |
|
|
| 65 |
<% other_formats_links do |f| %> |
|
| 66 |
<%= f.link_to 'CSV', :url => params %> |
|
| 67 |
<% end %> |
|
| 68 |
<% end %> |
|
| 69 |
<% end %> |
|
| 70 |
|
|
| 71 |
<% html_title l(:label_spent_time), l(:label_report) %> |
|
| 72 |
|
|
| .svn/pristine/13/13d58fac9d8f76e7061c50c043e9ceb3e590857c.svn-base | ||
|---|---|---|
| 1 |
class Namespace::SharedPluginController < ApplicationController |
|
| 2 |
def an_action |
|
| 3 |
render_class_and_action 'from beta_plugin' |
|
| 4 |
end |
|
| 5 |
end |
|
Also available in: Unified diff