Revision 1297:0a574315af3e .svn/pristine/57

View differences:

.svn/pristine/57/57004ea0d71683df384c4e3126bc90d754acca49.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  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 MemberTest < ActiveSupport::TestCase
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
           :groups_users,
30
           :watchers,
31
           :journals, :journal_details,
32
           :messages,
33
           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
34
           :boards
35

  
36
  include Redmine::I18n
37

  
38
  def setup
39
    @jsmith = Member.find(1)
40
  end
41

  
42
  def test_create
43
    member = Member.new(:project_id => 1, :user_id => 4, :role_ids => [1, 2])
44
    assert member.save
45
    member.reload
46

  
47
    assert_equal 2, member.roles.size
48
    assert_equal Role.find(1), member.roles.sort.first
49
  end
50

  
51
  def test_update
52
    assert_equal "eCookbook", @jsmith.project.name
53
    assert_equal "Manager", @jsmith.roles.first.name
54
    assert_equal "jsmith", @jsmith.user.login
55

  
56
    @jsmith.mail_notification = !@jsmith.mail_notification
57
    assert @jsmith.save
58
  end
59

  
60
  def test_update_roles
61
    assert_equal 1, @jsmith.roles.size
62
    @jsmith.role_ids = [1, 2]
63
    assert @jsmith.save
64
    assert_equal 2, @jsmith.reload.roles.size
65
  end
66

  
67
  def test_validate
68
    member = Member.new(:project_id => 1, :user_id => 2, :role_ids => [2])
69
    # same use can't have more than one membership for a project
70
    assert !member.save
71

  
72
    # must have one role at least
73
    user = User.new(:firstname => "new1", :lastname => "user1", :mail => "test_validate@somenet.foo")
74
    user.login = "test_validate"
75
    user.password, user.password_confirmation = "password", "password"
76
    assert user.save
77

  
78
    set_language_if_valid 'fr'
79
    member = Member.new(:project_id => 1, :user_id => user.id, :role_ids => [])
80
    assert !member.save
81
    assert_include I18n.translate('activerecord.errors.messages.empty'), member.errors[:role]
82
    str = "R\xc3\xb4le doit \xc3\xaatre renseign\xc3\xa9(e)"
83
    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
84
    assert_equal str, [member.errors.full_messages].flatten.join
85
  end
86

  
87
  def test_validate_member_role
88
    user = User.new(:firstname => "new1", :lastname => "user1", :mail => "test_validate@somenet.foo")
89
    user.login = "test_validate_member_role"
90
    user.password, user.password_confirmation = "password", "password"
91
    assert user.save
92
    member = Member.new(:project_id => 1, :user_id => user.id, :role_ids => [5])
93
    assert !member.save
94
  end
95

  
96
  def test_destroy
97
    category1 = IssueCategory.find(1)
98
    assert_equal @jsmith.user.id, category1.assigned_to_id
99
    assert_difference 'Member.count', -1 do
100
      assert_difference 'MemberRole.count', -1 do
101
        @jsmith.destroy
102
      end
103
    end
104
    assert_raise(ActiveRecord::RecordNotFound) { Member.find(@jsmith.id) }
105
    category1.reload
106
    assert_nil category1.assigned_to_id
107
  end
108

  
109
  def test_sort_without_roles
110
    a = Member.new(:roles => [Role.first])
111
    b = Member.new
112

  
113
    assert_equal -1, a <=> b
114
    assert_equal 1,  b <=> a
115
  end
116

  
117
  def test_sort_without_principal
118
    role = Role.first
119
    a = Member.new(:roles => [role], :principal => User.first)
120
    b = Member.new(:roles => [role])
121

  
122
    assert_equal -1, a <=> b
123
    assert_equal 1,  b <=> a
124
  end
125

  
126
  context "removing permissions" do
127
    setup do
128
      Watcher.delete_all("user_id = 9")
129
      user = User.find(9)
130
      # public
131
      Watcher.create!(:watchable => Issue.find(1), :user => user)
132
      # private
133
      Watcher.create!(:watchable => Issue.find(4), :user => user)
134
      Watcher.create!(:watchable => Message.find(7), :user => user)
135
      Watcher.create!(:watchable => Wiki.find(2), :user => user)
136
      Watcher.create!(:watchable => WikiPage.find(3), :user => user)
137
    end
138

  
139
    context "of user" do
140
      setup do
141
        @member = Member.create!(:project => Project.find(2), :principal => User.find(9), :role_ids => [1, 2])
142
      end
143

  
144
      context "by deleting membership" do
145
        should "prune watchers" do
146
          assert_difference 'Watcher.count', -4 do
147
            @member.destroy
148
          end
149
        end
150
      end
151

  
152
      context "by updating roles" do
153
        should "prune watchers" do
154
          Role.find(2).remove_permission! :view_wiki_pages
155
          member = Member.first(:order => 'id desc')
156
          assert_difference 'Watcher.count', -2 do
157
            member.role_ids = [2]
158
            member.save
159
          end
160
          assert !Message.find(7).watched_by?(@user)
161
        end
162
      end
163
    end
164

  
165
    context "of group" do
166
      setup do
167
        group = Group.find(10)
168
        @member = Member.create!(:project => Project.find(2), :principal => group, :role_ids => [1, 2])
169
        group.users << User.find(9)
170
      end
171

  
172
      context "by deleting membership" do
173
        should "prune watchers" do
174
          assert_difference 'Watcher.count', -4 do
175
            @member.destroy
176
          end
177
        end
178
      end
179

  
180
      context "by updating roles" do
181
        should "prune watchers" do
182
          Role.find(2).remove_permission! :view_wiki_pages
183
          assert_difference 'Watcher.count', -2 do
184
            @member.role_ids = [2]
185
            @member.save
186
          end
187
        end
188
      end
189
    end
190
  end
191
end
.svn/pristine/57/57507b03cb311c6e4bc85c45f93614c9f70496e1.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  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 RoutingEnumerationsTest < ActionController::IntegrationTest
21
  def test_enumerations
22
    assert_routing(
23
        { :method => 'get', :path => "/enumerations" },
24
        { :controller => 'enumerations', :action => 'index' }
25
      )
26
    assert_routing(
27
        { :method => 'get', :path => "/enumerations/new" },
28
        { :controller => 'enumerations', :action => 'new' }
29
      )
30
    assert_routing(
31
        { :method => 'post', :path => "/enumerations" },
32
        { :controller => 'enumerations', :action => 'create' }
33
      )
34
    assert_routing(
35
        { :method => 'get', :path => "/enumerations/2/edit" },
36
        { :controller => 'enumerations', :action => 'edit', :id => '2' }
37
      )
38
    assert_routing(
39
        { :method => 'put', :path => "/enumerations/2" },
40
        { :controller => 'enumerations', :action => 'update', :id => '2' }
41
      )
42
    assert_routing(
43
        { :method => 'delete', :path => "/enumerations/2" },
44
        { :controller => 'enumerations', :action => 'destroy', :id => '2' }
45
      )
46
    assert_routing(
47
        { :method => 'get', :path => "/enumerations/issue_priorities.xml" },
48
        { :controller => 'enumerations', :action => 'index', :type => 'issue_priorities', :format => 'xml' }
49
      )
50
  end
51
end
.svn/pristine/57/5759679756dee3807c5bd95dd3954626c17593aa.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  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 RoutingQueriesTest < ActionController::IntegrationTest
21
  def test_queries
22
    assert_routing(
23
        { :method => 'get', :path => "/queries.xml" },
24
        { :controller => 'queries', :action => 'index', :format => 'xml' }
25
      )
26
    assert_routing(
27
        { :method => 'get', :path => "/queries.json" },
28
        { :controller => 'queries', :action => 'index', :format => 'json' }
29
      )
30
    assert_routing(
31
        { :method => 'get', :path => "/queries/new" },
32
        { :controller => 'queries', :action => 'new' }
33
      )
34
    assert_routing(
35
        { :method => 'post', :path => "/queries" },
36
        { :controller => 'queries', :action => 'create' }
37
      )
38
    assert_routing(
39
        { :method => 'get', :path => "/queries/1/edit" },
40
        { :controller => 'queries', :action => 'edit', :id => '1' }
41
      )
42
    assert_routing(
43
        { :method => 'put', :path => "/queries/1" },
44
        { :controller => 'queries', :action => 'update', :id => '1' }
45
      )
46
    assert_routing(
47
        { :method => 'delete', :path => "/queries/1" },
48
        { :controller => 'queries', :action => 'destroy', :id => '1' }
49
      )
50
  end
51

  
52
  def test_queries_scoped_under_project
53
    assert_routing(
54
        { :method => 'get', :path => "/projects/redmine/queries/new" },
55
        { :controller => 'queries', :action => 'new', :project_id => 'redmine' }
56
      )
57
    assert_routing(
58
        { :method => 'post', :path => "/projects/redmine/queries" },
59
        { :controller => 'queries', :action => 'create', :project_id => 'redmine' }
60
      )
61
  end
62
end
.svn/pristine/57/57718143646b44780eedc46df03edb8ea5a87f0c.svn-base
1
# = Redmine configuration file
2
#
3
# Each environment has it's own configuration options.  If you are only
4
# running in production, only the production block needs to be configured.
5
# Environment specific configuration options override the default ones.
6
#
7
# Note that this file needs to be a valid YAML file.
8
# DO NOT USE TABS! Use 2 spaces instead of tabs for identation.
9
#
10
# == Outgoing email settings (email_delivery setting)
11
#
12
# === Common configurations
13
#
14
# ==== Sendmail command
15
#
16
# production:
17
#   email_delivery:
18
#     delivery_method: :sendmail
19
#
20
# ==== Simple SMTP server at localhost
21
#
22
# production:
23
#   email_delivery:
24
#     delivery_method: :smtp
25
#     smtp_settings:
26
#       address: "localhost"
27
#       port: 25
28
#
29
# ==== SMTP server at example.com using LOGIN authentication and checking HELO for foo.com
30
#
31
# production:
32
#   email_delivery:
33
#     delivery_method: :smtp
34
#     smtp_settings:
35
#       address: "example.com"
36
#       port: 25
37
#       authentication: :login
38
#       domain: 'foo.com'
39
#       user_name: 'myaccount'
40
#       password: 'password'
41
#
42
# ==== SMTP server at example.com using PLAIN authentication
43
#
44
# production:
45
#   email_delivery:
46
#     delivery_method: :smtp
47
#     smtp_settings:
48
#       address: "example.com"
49
#       port: 25
50
#       authentication: :plain
51
#       domain: 'example.com'
52
#       user_name: 'myaccount'
53
#       password: 'password'
54
#
55
# ==== SMTP server at using TLS (GMail)
56
#
57
# This might require some additional configuration. See the guides at:
58
# http://www.redmine.org/projects/redmine/wiki/EmailConfiguration
59
#
60
# production:
61
#   email_delivery:
62
#     delivery_method: :smtp
63
#     smtp_settings:
64
#       enable_starttls_auto: true
65
#       address: "smtp.gmail.com"
66
#       port: 587
67
#       domain: "smtp.gmail.com" # 'your.domain.com' for GoogleApps
68
#       authentication: :plain
69
#       user_name: "your_email@gmail.com"
70
#       password: "your_password"
71
#
72
#
73
# === More configuration options
74
#
75
# See the "Configuration options" at the following website for a list of the
76
# full options allowed:
77
#
78
# http://wiki.rubyonrails.org/rails/pages/HowToSendEmailsWithActionMailer
79

  
80

  
81
# default configuration options for all environments
82
default:
83
  # Outgoing emails configuration (see examples above)
84
  email_delivery:
85
    delivery_method: :smtp
86
    smtp_settings:
87
      address: smtp.example.net
88
      port: 25
89
      domain: example.net
90
      authentication: :login
91
      user_name: "redmine@example.net"
92
      password: "redmine"
93

  
94
  # Absolute path to the directory where attachments are stored.
95
  # The default is the 'files' directory in your Redmine instance.
96
  # Your Redmine instance needs to have write permission on this
97
  # directory.
98
  # Examples:
99
  # attachments_storage_path: /var/redmine/files
100
  # attachments_storage_path: D:/redmine/files
101
  attachments_storage_path:
102

  
103
  # Configuration of the autologin cookie.
104
  # autologin_cookie_name: the name of the cookie (default: autologin)
105
  # autologin_cookie_path: the cookie path (default: /)
106
  # autologin_cookie_secure: true sets the cookie secure flag (default: false)
107
  autologin_cookie_name:
108
  autologin_cookie_path:
109
  autologin_cookie_secure:
110

  
111
  # Configuration of SCM executable command.
112
  #
113
  # Absolute path (e.g. /usr/local/bin/hg) or command name (e.g. hg.exe, bzr.exe)
114
  # On Windows + CRuby, *.cmd, *.bat (e.g. hg.cmd, bzr.bat) does not work.
115
  #
116
  # On Windows + JRuby 1.6.2, path which contains spaces does not work.
117
  # For example, "C:\Program Files\TortoiseHg\hg.exe".
118
  # If you want to this feature, you need to install to the path which does not contains spaces.
119
  # For example, "C:\TortoiseHg\hg.exe".
120
  #
121
  # Examples:
122
  # scm_subversion_command: svn                                       # (default: svn)
123
  # scm_mercurial_command:  C:\Program Files\TortoiseHg\hg.exe        # (default: hg)
124
  # scm_git_command:        /usr/local/bin/git                        # (default: git)
125
  # scm_cvs_command:        cvs                                       # (default: cvs)
126
  # scm_bazaar_command:     bzr.exe                                   # (default: bzr)
127
  # scm_darcs_command:      darcs-1.0.9-i386-linux                    # (default: darcs)
128
  #
129
  scm_subversion_command:
130
  scm_mercurial_command:
131
  scm_git_command:
132
  scm_cvs_command:
133
  scm_bazaar_command:
134
  scm_darcs_command:
135

  
136
  # Key used to encrypt sensitive data in the database (SCM and LDAP passwords).
137
  # If you don't want to enable data encryption, just leave it blank.
138
  # WARNING: losing/changing this key will make encrypted data unreadable.
139
  #
140
  # If you want to encrypt existing passwords in your database:
141
  # * set the cipher key here in your configuration file
142
  # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
143
  #
144
  # If you have encrypted data and want to change this key, you have to:
145
  # * decrypt data using 'rake db:decrypt RAILS_ENV=production' first
146
  # * change the cipher key here in your configuration file
147
  # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
148
  database_cipher_key:
149

  
150
  # Set this to false to disable plugins' assets mirroring on startup.
151
  # You can use `rake redmine:plugins:assets` to manually mirror assets
152
  # to public/plugin_assets when you install/upgrade a Redmine plugin.
153
  #
154
  #mirror_plugins_assets_on_startup: false
155

  
156
  # Your secret key for verifying cookie session data integrity. If you
157
  # change this key, all old sessions will become invalid! Make sure the
158
  # secret is at least 30 characters and all random, no regular words or
159
  # you'll be exposed to dictionary attacks.
160
  #
161
  # If you have a load-balancing Redmine cluster, you have to use the
162
  # same secret token on each machine.
163
  #secret_token: 'change it to a long random string'
164

  
165
  # Absolute path (e.g. /usr/bin/convert, c:/im/convert.exe) to
166
  # the ImageMagick's `convert` binary. Used to generate attachment thumbnails.
167
  #imagemagick_convert_command:
168

  
169
  # Configuration of RMagcik font.
170
  #
171
  # Redmine uses RMagcik in order to export gantt png.
172
  # You don't need this setting if you don't install RMagcik.
173
  #
174
  # In CJK (Chinese, Japanese and Korean),
175
  # in order to show CJK characters correctly,
176
  # you need to set this configuration.
177
  #
178
  # Because there is no standard font across platforms in CJK,
179
  # you need to set a font installed in your server.
180
  #
181
  # This setting is not necessary in non CJK.
182
  #
183
  # Examples for Japanese:
184
  #   Windows:
185
  #     rmagick_font_path: C:\windows\fonts\msgothic.ttc
186
  #   Linux:
187
  #     rmagick_font_path: /usr/share/fonts/ipa-mincho/ipam.ttf
188
  #
189
  rmagick_font_path:
190

  
191
# specific configuration options for production environment
192
# that overrides the default ones
193
production:
194

  
195
# specific configuration options for development environment
196
# that overrides the default ones
197
development:
.svn/pristine/57/57b02f2ab6d4376e071c17d4651c0cbfba20e65a.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  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 ApiTest::RolesTest < ActionController::IntegrationTest
21
  fixtures :roles
22

  
23
  def setup
24
    Setting.rest_api_enabled = '1'
25
  end
26

  
27
  context "/roles" do
28
    context "GET" do
29
      context "xml" do
30
        should "return the roles" do
31
          get '/roles.xml'
32

  
33
          assert_response :success
34
          assert_equal 'application/xml', @response.content_type
35
          assert_equal 3, assigns(:roles).size
36

  
37
          assert_tag :tag => 'roles',
38
            :attributes => {:type => 'array'},
39
            :child => {
40
              :tag => 'role',
41
              :child => {
42
                :tag => 'id',
43
                :content => '2',
44
                :sibling => {
45
                  :tag => 'name',
46
                  :content => 'Developer'
47
                }
48
              }
49
            }
50
        end
51
      end
52

  
53
      context "json" do
54
        should "return the roles" do
55
          get '/roles.json'
56

  
57
          assert_response :success
58
          assert_equal 'application/json', @response.content_type
59
          assert_equal 3, assigns(:roles).size
60

  
61
          json = ActiveSupport::JSON.decode(response.body)
62
          assert_kind_of Hash, json
63
          assert_kind_of Array, json['roles']
64
          assert_include({'id' => 2, 'name' => 'Developer'}, json['roles'])
65
        end
66
      end
67
    end
68
  end
69

  
70
  context "/roles/:id" do
71
    context "GET" do
72
      context "xml" do
73
        should "return the role" do
74
          get '/roles/1.xml'
75

  
76
          assert_response :success
77
          assert_equal 'application/xml', @response.content_type
78

  
79
          assert_select 'role' do
80
            assert_select 'name', :text => 'Manager'
81
            assert_select 'role permissions[type=array]' do
82
              assert_select 'permission', Role.find(1).permissions.size
83
              assert_select 'permission', :text => 'view_issues'
84
            end
85
          end
86
        end
87
      end
88
    end
89
  end
90
end
.svn/pristine/57/57dcf44cd4619ec1484d2a42d24efd4b48d202a4.svn-base
1
<h2><%=l(:label_document_new)%></h2>
2

  
3
<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
4
  <%= render :partial => 'form', :locals => {:f => f} %>
5
  <p><%= submit_tag l(:button_create) %></p>
6
<% end %>
.svn/pristine/57/57f355bd1bf19a701c370fb3c553495c694b4edb.svn-base
1
$('#relations').html('<%= escape_javascript(render :partial => 'issues/relations') %>');
2
<% if @relation.errors.empty? %>
3
  $('#relation_delay').val('');
4
  $('#relation_issue_to_id').val('');
5
  $('#relation_issue_to_id').focus();
6
<% end %>
.svn/pristine/57/57f5137195b9f3676e6181b2962bab9a4eb72e00.svn-base
1
<%= error_messages_for 'time_entry' %>
2
<%= back_url_hidden_field_tag %>
3

  
4
<div class="box tabular">
5
	<% if @time_entry.new_record? %>
6
	  <% if params[:project_id] || @time_entry.issue %>
7
	    <%= f.hidden_field :project_id %>
8
	  <% else %>
9
	    <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %></p>
10
	  <% end %>
11
	<% end %>
12
	<p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
13
	<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
14
	<p><%= f.text_field :hours, :size => 6, :required => true %></p>
15
	<p><%= f.text_field :comments, :size => 100, :maxlength => 255 %></p>
16
	<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
17
	<% @time_entry.custom_field_values.each do |value| %>
18
	  <p><%= custom_field_tag_with_label :time_entry, value %></p>
19
	<% end %>
20
	<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
21
</div>
22

  
23
<%= javascript_tag "observeAutocompleteField('time_entry_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))}')" %>

Also available in: Unified diff