<!DOCTYPE html>
<html lang='en'>
<head>
<title>Generalize issues imports (#28234). - redmine.git - Mirror of redmine code source: https://github.com/redmine/redmine</title>
<meta name='generator' content='cgit v1.2.3'/>
<meta name='robots' content='index, nofollow'/>
<link rel='stylesheet' type='text/css' href='/cgit.css'/>
<link rel='shortcut icon' href='/favicon.ico'/>
<link rel='alternate' title='Atom feed' href='https://source.dussan.org/redmine.git/atom/?h=5.0-stable' type='application/atom+xml'/>
</head>
<body>
<div id='cgit'><table id='header'>
<tr>
<td class='logo' rowspan='2'><a href='/'><img src='/cgit.png' alt='cgit logo'/></a></td>
<td class='main'><a href='/'>index</a> : <a href='/redmine.git/'>redmine.git</a></td><td class='form'><form method='get'>
<input type='hidden' name='id' value='b540046ed7084ba50f5ca280f3ffae0751af8142'/><select name='h' onchange='this.form.submit();'>
<option value='0.6-stable'>0.6-stable</option>
<option value='0.7-stable'>0.7-stable</option>
<option value='0.8-stable'>0.8-stable</option>
<option value='0.9-stable'>0.9-stable</option>
<option value='1.0-stable'>1.0-stable</option>
<option value='1.1-stable'>1.1-stable</option>
<option value='1.2-stable'>1.2-stable</option>
<option value='1.3-stable'>1.3-stable</option>
<option value='1.4-stable'>1.4-stable</option>
<option value='2.0-stable'>2.0-stable</option>
<option value='2.1-stable'>2.1-stable</option>
<option value='2.2-stable'>2.2-stable</option>
<option value='2.3-stable'>2.3-stable</option>
<option value='2.4-stable'>2.4-stable</option>
<option value='2.5-stable'>2.5-stable</option>
<option value='2.6-stable'>2.6-stable</option>
<option value='3.0-stable'>3.0-stable</option>
<option value='3.1-stable'>3.1-stable</option>
<option value='3.2-stable'>3.2-stable</option>
<option value='3.3-stable'>3.3-stable</option>
<option value='3.4-stable'>3.4-stable</option>
<option value='4.0-stable'>4.0-stable</option>
<option value='4.1-stable'>4.1-stable</option>
<option value='4.2-stable'>4.2-stable</option>
<option value='5.0-stable' selected='selected'>5.0-stable</option>
<option value='5.1-stable'>5.1-stable</option>
<option value='6.0-stable'>6.0-stable</option>
<option value='integration-to-svn-stable-1.0'>integration-to-svn-stable-1.0</option>
<option value='integration-to-svn-trunk'>integration-to-svn-trunk</option>
<option value='master'>master</option>
<option value='nbc'>nbc</option>
<option value='plugin-hooks'>plugin-hooks</option>
<option value='swistak'>swistak</option>
<option value='work'>work</option>
</select> <input type='submit' value='switch'/></form></td></tr>
<tr><td class='sub'>Mirror of redmine code source: https://github.com/redmine/redmine</td><td class='sub right'>www-data</td></tr></table>
<table class='tabs'><tr><td>
<a href='/redmine.git/?h=5.0-stable'>summary</a><a href='/redmine.git/refs/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>refs</a><a href='/redmine.git/log/?h=5.0-stable'>log</a><a href='/redmine.git/tree/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>tree</a><a class='active' href='/redmine.git/commit/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>commit</a><a href='/redmine.git/diff/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>diff</a><a href='/redmine.git/stats/?h=5.0-stable'>stats</a></td><td class='form'><form class='right' method='get' action='/redmine.git/log/'>
<input type='hidden' name='h' value='5.0-stable'/><input type='hidden' name='id' value='b540046ed7084ba50f5ca280f3ffae0751af8142'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='content'><div class='cgit-panel'><b>diff options</b><form method='get'><input type='hidden' name='h' value='5.0-stable'/><input type='hidden' name='id' value='b540046ed7084ba50f5ca280f3ffae0751af8142'/><table><tr><td colspan='2'/></tr><tr><td class='label'>context:</td><td class='ctrl'><select name='context' onchange='this.form.submit();'><option value='1'>1</option><option value='2'>2</option><option value='3' selected='selected'>3</option><option value='4'>4</option><option value='5'>5</option><option value='6'>6</option><option value='7'>7</option><option value='8'>8</option><option value='9'>9</option><option value='10'>10</option><option value='15'>15</option><option value='20'>20</option><option value='25'>25</option><option value='30'>30</option><option value='35'>35</option><option value='40'>40</option></select></td></tr><tr><td class='label'>space:</td><td class='ctrl'><select name='ignorews' onchange='this.form.submit();'><option value='0' selected='selected'>include</option><option value='1'>ignore</option></select></td></tr><tr><td class='label'>mode:</td><td class='ctrl'><select name='dt' onchange='this.form.submit();'><option value='0' selected='selected'>unified</option><option value='1'>ssdiff</option><option value='2'>stat only</option></select></td></tr><tr><td/><td class='ctrl'><noscript><input type='submit' value='reload'/></noscript></td></tr></table></form></div><table summary='commit info' class='commit-info'>
<tr><th>author</th><td>Go MAEDA &lt;maeda@farend.jp&gt;</td><td class='right'>2019-05-09 07:40:06 +0000</td></tr>
<tr><th>committer</th><td>Go MAEDA &lt;maeda@farend.jp&gt;</td><td class='right'>2019-05-09 07:40:06 +0000</td></tr>
<tr><th>commit</th><td colspan='2' class='oid'><a href='/redmine.git/commit/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>b540046ed7084ba50f5ca280f3ffae0751af8142</a> (<a href='/redmine.git/patch/?id=b540046ed7084ba50f5ca280f3ffae0751af8142'>patch</a>)</td></tr>
<tr><th>tree</th><td colspan='2' class='oid'><a href='/redmine.git/tree/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>4bc946090d4940a219e84f70ca72c5655de5be42</a></td></tr>
<tr><th>parent</th><td colspan='2' class='oid'><a href='/redmine.git/commit/?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>bcc60805c97104f44a37b92321d7aa1e5c51b622</a> (<a href='/redmine.git/diff/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142&amp;id2=bcc60805c97104f44a37b92321d7aa1e5c51b622'>diff</a>)</td></tr><tr><th>download</th><td colspan='2' class='oid'><a href='/redmine.git/snapshot/redmine-b540046ed7084ba50f5ca280f3ffae0751af8142.tar.gz'>redmine-b540046ed7084ba50f5ca280f3ffae0751af8142.tar.gz</a><br/><a href='/redmine.git/snapshot/redmine-b540046ed7084ba50f5ca280f3ffae0751af8142.zip'>redmine-b540046ed7084ba50f5ca280f3ffae0751af8142.zip</a><br/></td></tr></table>
<div class='commit-subject'>Generalize issues imports (#28234).</div><div class='commit-msg'>Extend import controller to support arbitrary imports based on Import subclasses. This way, we may add other kinds of imports, by providing some views and a custom import class. This may also be done from within plugins.

Patch by Gregor Schmidt.


git-svn-id: http://svn.redmine.org/redmine/trunk@18145 e93f8b46-1217-0410-a6f0-8f06a7374b81
</div><div class='diffstat-header'><a href='/redmine.git/diff/?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>Diffstat</a></div><table summary='diffstat' class='diffstat'><tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/controllers/imports_controller.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/controllers/imports_controller.rb</a></td><td class='right'>44</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 90.9%;'/><td class='rem' style='width: 9.1%;'/><td class='none' style='width: 0.0%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/helpers/imports_helper.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/helpers/imports_helper.rb</a></td><td class='right'>8</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 18.2%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 81.8%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/models/import.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/models/import.rb</a></td><td class='right'>12</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 27.3%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 72.7%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/models/issue_import.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/models/issue_import.rb</a></td><td class='right'>7</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 15.9%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 84.1%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='mov'><a href='/redmine.git/diff/app/views/imports/_issues_fields_mapping.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_fields_mapping.html.erb</a> (renamed from app/views/imports/_fields_mapping.html.erb)</td><td class='right'>2</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 2.3%;'/><td class='rem' style='width: 2.3%;'/><td class='none' style='width: 95.5%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/redmine.git/diff/app/views/imports/_issues_mapping.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_mapping.html.erb</a></td><td class='right'>16</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 36.4%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 63.6%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/redmine.git/diff/app/views/imports/_issues_mapping.js.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_mapping.js.erb</a></td><td class='right'>1</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 2.3%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 97.7%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/redmine.git/diff/app/views/imports/_issues_saved_objects.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_saved_objects.html.erb</a></td><td class='right'>7</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 15.9%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 84.1%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='add'><a href='/redmine.git/diff/app/views/imports/_issues_sidebar.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_sidebar.html.erb</a></td><td class='right'>3</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 6.8%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 93.2%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/views/imports/mapping.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/mapping.html.erb</a></td><td class='right'>23</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 6.8%;'/><td class='rem' style='width: 45.5%;'/><td class='none' style='width: 47.7%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/views/imports/mapping.js.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/mapping.js.erb</a></td><td class='right'>2</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 2.3%;'/><td class='rem' style='width: 2.3%;'/><td class='none' style='width: 95.5%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/views/imports/new.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/new.html.erb</a></td><td class='right'>7</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 6.8%;'/><td class='rem' style='width: 9.1%;'/><td class='none' style='width: 84.1%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/views/imports/run.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/run.html.erb</a></td><td class='right'>6</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 4.5%;'/><td class='rem' style='width: 9.1%;'/><td class='none' style='width: 86.4%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/views/imports/settings.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/settings.html.erb</a></td><td class='right'>6</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 4.5%;'/><td class='rem' style='width: 9.1%;'/><td class='none' style='width: 86.4%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/app/views/imports/show.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/show.html.erb</a></td><td class='right'>14</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 6.8%;'/><td class='rem' style='width: 25.0%;'/><td class='none' style='width: 68.2%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/config/routes.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>config/routes.rb</a></td><td class='right'>2</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 2.3%;'/><td class='rem' style='width: 2.3%;'/><td class='none' style='width: 95.5%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/lib/redmine.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>lib/redmine.rb</a></td><td class='right'>2</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 2.3%;'/><td class='rem' style='width: 2.3%;'/><td class='none' style='width: 95.5%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/test/functional/imports_controller_test.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>test/functional/imports_controller_test.rb</a></td><td class='right'>3</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 4.5%;'/><td class='rem' style='width: 2.3%;'/><td class='none' style='width: 93.2%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/test/integration/routing/imports_test.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>test/integration/routing/imports_test.rb</a></td><td class='right'>3</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 4.5%;'/><td class='rem' style='width: 2.3%;'/><td class='none' style='width: 93.2%;'/></tr></table></td></tr>
<tr><td class='mode'>-rw-r--r--</td><td class='upd'><a href='/redmine.git/diff/test/unit/issue_import_test.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>test/unit/issue_import_test.rb</a></td><td class='right'>6</td><td class='graph'><table summary='file diffstat' width='44%'><tr><td class='add' style='width: 13.6%;'/><td class='rem' style='width: 0.0%;'/><td class='none' style='width: 86.4%;'/></tr></table></td></tr>
</table><div class='diffstat-summary'>20 files changed, 121 insertions, 53 deletions</div><table summary='diff' class='diff'><tr><td><div class='head'>diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb<br/>index 54c739cca..fa02318bc 100644<br/>--- a/<a href='/redmine.git/tree/app/controllers/imports_controller.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/controllers/imports_controller.rb</a><br/>+++ b/<a href='/redmine.git/tree/app/controllers/imports_controller.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/controllers/imports_controller.rb</a></div><div class='hunk'>@@ -20,19 +20,20 @@</div><div class='ctx'> require 'csv'</div><div class='ctx'> </div><div class='ctx'> class ImportsController &lt; ApplicationController</div><div class='del'>-  menu_item :issues</div><div class='del'>-</div><div class='ctx'>   before_action :find_import, :only =&gt; [:show, :settings, :mapping, :run]</div><div class='del'>-  before_action :authorize_global</div><div class='add'>+  before_action :authorize_import</div><div class='add'>+</div><div class='add'>+  layout :import_layout</div><div class='ctx'> </div><div class='ctx'>   helper :issues</div><div class='ctx'>   helper :queries</div><div class='ctx'> </div><div class='ctx'>   def new</div><div class='add'>+    @import = import_type.new</div><div class='ctx'>   end</div><div class='ctx'> </div><div class='ctx'>   def create</div><div class='del'>-    @import = IssueImport.new</div><div class='add'>+    @import = import_type.new</div><div class='ctx'>     @import.user = User.current</div><div class='ctx'>     @import.file = params[:file]</div><div class='ctx'>     @import.set_default_settings</div><div class='hunk'>@@ -98,6 +99,14 @@ class ImportsController &lt; ApplicationController</div><div class='ctx'>     end</div><div class='ctx'>   end</div><div class='ctx'> </div><div class='add'>+  def current_menu(project)</div><div class='add'>+    if import_layout == 'admin'</div><div class='add'>+      nil</div><div class='add'>+    else</div><div class='add'>+      :application_menu</div><div class='add'>+    end</div><div class='add'>+  end</div><div class='add'>+</div><div class='ctx'>   private</div><div class='ctx'> </div><div class='ctx'>   def find_import</div><div class='hunk'>@@ -123,4 +132,31 @@ class ImportsController &lt; ApplicationController</div><div class='ctx'>   def max_items_per_request</div><div class='ctx'>     5</div><div class='ctx'>   end</div><div class='add'>+</div><div class='add'>+  def import_layout</div><div class='add'>+    import_type &amp;&amp; import_type.layout || 'base'</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def menu_items</div><div class='add'>+    menu_item = import_type ? import_type.menu_item : nil</div><div class='add'>+</div><div class='add'>+    { self.controller_name.to_sym =&gt; { :actions =&gt; {}, :default =&gt; menu_item } }</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def authorize_import</div><div class='add'>+    return render_404 unless import_type</div><div class='add'>+    return render_403 unless import_type.authorized?(User.current)</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def import_type</div><div class='add'>+    return @import_type if defined? @import_type</div><div class='add'>+</div><div class='add'>+    @import_type =</div><div class='add'>+      if @import</div><div class='add'>+        @import.class</div><div class='add'>+      else</div><div class='add'>+        type = Object.const_get(params[:type]) rescue nil</div><div class='add'>+        type &amp;&amp; type &lt; Import ? type : nil</div><div class='add'>+      end</div><div class='add'>+  end</div><div class='ctx'> end</div><div class='head'>diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb<br/>index 22f070cf5..b97576d6f 100644<br/>--- a/<a href='/redmine.git/tree/app/helpers/imports_helper.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/helpers/imports_helper.rb</a><br/>+++ b/<a href='/redmine.git/tree/app/helpers/imports_helper.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/helpers/imports_helper.rb</a></div><div class='hunk'>@@ -18,6 +18,14 @@</div><div class='ctx'> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.</div><div class='ctx'> </div><div class='ctx'> module ImportsHelper</div><div class='add'>+  def import_title</div><div class='add'>+    l(:"label_import_#{import_partial_prefix}")</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def import_partial_prefix</div><div class='add'>+    @import.class.name.sub('Import', '').underscore.pluralize</div><div class='add'>+  end</div><div class='add'>+</div><div class='ctx'>   def options_for_mapping_select(import, field, options={})</div><div class='ctx'>     tags = "".html_safe</div><div class='ctx'>     blank_text = options[:required] ? "-- #{l(:actionview_instancetag_blank_option)} --" : "&amp;nbsp;".html_safe</div><div class='head'>diff --git a/app/models/import.rb b/app/models/import.rb<br/>index 7009f2e7e..df6b085a6 100644<br/>--- a/<a href='/redmine.git/tree/app/models/import.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/models/import.rb</a><br/>+++ b/<a href='/redmine.git/tree/app/models/import.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/models/import.rb</a></div><div class='hunk'>@@ -37,6 +37,18 @@ class Import &lt; ActiveRecord::Base</div><div class='ctx'>     '%d-%m-%Y'</div><div class='ctx'>   ]</div><div class='ctx'> </div><div class='add'>+  def self.menu_item</div><div class='add'>+    nil</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def self.layout</div><div class='add'>+    'base'</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def self.authorized?(user)</div><div class='add'>+    user.admin?</div><div class='add'>+  end</div><div class='add'>+</div><div class='ctx'>   def initialize(*args)</div><div class='ctx'>     super</div><div class='ctx'>     self.settings ||= {}</div><div class='head'>diff --git a/app/models/issue_import.rb b/app/models/issue_import.rb<br/>index 6c59b26db..5a3542291 100644<br/>--- a/<a href='/redmine.git/tree/app/models/issue_import.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/models/issue_import.rb</a><br/>+++ b/<a href='/redmine.git/tree/app/models/issue_import.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/models/issue_import.rb</a></div><div class='hunk'>@@ -18,6 +18,13 @@</div><div class='ctx'> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.</div><div class='ctx'> </div><div class='ctx'> class IssueImport &lt; Import</div><div class='add'>+  def self.menu_item</div><div class='add'>+    :issues</div><div class='add'>+  end</div><div class='add'>+</div><div class='add'>+  def self.authorized?(user)</div><div class='add'>+    user.allowed_to?(:import_issues, nil, :global =&gt; true)</div><div class='add'>+  end</div><div class='ctx'> </div><div class='ctx'>   # Returns the objects that were imported</div><div class='ctx'>   def saved_objects</div><div class='head'>diff --git a/app/views/imports/_fields_mapping.html.erb b/app/views/imports/_issues_fields_mapping.html.erb<br/>index f59350116..542a956ff 100644<br/>--- a/<a href='/redmine.git/tree/app/views/imports/_fields_mapping.html.erb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/views/imports/_fields_mapping.html.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/_issues_fields_mapping.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_fields_mapping.html.erb</a></div><div class='hunk'>@@ -54,7 +54,7 @@</div><div class='ctx'> &lt;/p&gt;</div><div class='ctx'> &lt;% @custom_fields.each do |field| %&gt;</div><div class='ctx'>   &lt;p&gt;</div><div class='del'>-    &lt;label for="import_mapping_cf_&lt;% field.id %&gt;"&gt;&lt;%= field.name %&gt;&lt;/label&gt;</div><div class='add'>+    &lt;label for="import_mapping_cf_&lt;%= field.id %&gt;"&gt;&lt;%= field.name %&gt;&lt;/label&gt;</div><div class='ctx'>     &lt;%= mapping_select_tag @import, "cf_#{field.id}" %&gt;</div><div class='ctx'>   &lt;/p&gt;</div><div class='ctx'> &lt;% end %&gt;</div><div class='head'>diff --git a/app/views/imports/_issues_mapping.html.erb b/app/views/imports/_issues_mapping.html.erb<br/>new file mode 100644<br/>index 000000000..dc97d9c3a<br/>--- /dev/null<br/>+++ b/<a href='/redmine.git/tree/app/views/imports/_issues_mapping.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_mapping.html.erb</a></div><div class='hunk'>@@ -0,0 +1,16 @@</div><div class='add'>+&lt;fieldset class="box tabular"&gt;</div><div class='add'>+  &lt;legend&gt;&lt;%= l(:label_fields_mapping) %&gt;&lt;/legend&gt;</div><div class='add'>+  &lt;div id="fields-mapping"&gt;</div><div class='add'>+    &lt;%= render :partial =&gt; 'issues_fields_mapping' %&gt;</div><div class='add'>+  &lt;/div&gt;</div><div class='add'>+&lt;/fieldset&gt;</div><div class='add'>+</div><div class='add'>+&lt;%= javascript_tag do %&gt;</div><div class='add'>+  $('#fields-mapping').on('change', '#import_mapping_project_id, #import_mapping_tracker', function(){</div><div class='add'>+    $.ajax({</div><div class='add'>+      url: '&lt;%= import_mapping_path(@import, :format =&gt; 'js') %&gt;',</div><div class='add'>+      type: 'post',</div><div class='add'>+      data: $('#import-form').serialize()</div><div class='add'>+    });</div><div class='add'>+  });</div><div class='add'>+&lt;% end %&gt;</div><div class='head'>diff --git a/app/views/imports/_issues_mapping.js.erb b/app/views/imports/_issues_mapping.js.erb<br/>new file mode 100644<br/>index 000000000..012ccc537<br/>--- /dev/null<br/>+++ b/<a href='/redmine.git/tree/app/views/imports/_issues_mapping.js.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_mapping.js.erb</a></div><div class='hunk'>@@ -0,0 +1 @@</div><div class='add'>+$('#fields-mapping').html('&lt;%= escape_javascript(render :partial =&gt; 'issues_fields_mapping') %&gt;');</div><div class='head'>diff --git a/app/views/imports/_issues_saved_objects.html.erb b/app/views/imports/_issues_saved_objects.html.erb<br/>new file mode 100644<br/>index 000000000..f708a1c23<br/>--- /dev/null<br/>+++ b/<a href='/redmine.git/tree/app/views/imports/_issues_saved_objects.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_saved_objects.html.erb</a></div><div class='hunk'>@@ -0,0 +1,7 @@</div><div class='add'>+&lt;ul id="saved-items"&gt;</div><div class='add'>+  &lt;% saved_objects.each do |issue| %&gt;</div><div class='add'>+    &lt;li&gt;&lt;%= link_to_issue issue %&gt;&lt;/li&gt;</div><div class='add'>+  &lt;% end %&gt;</div><div class='add'>+&lt;/ul&gt;</div><div class='add'>+</div><div class='add'>+&lt;p&gt;&lt;%= link_to l(:label_issue_view_all), issues_path(:set_filter =&gt; 1, :status_id =&gt; '*', :issue_id =&gt; saved_objects.map(&amp;:id).join(',')) %&gt;&lt;/p&gt;</div><div class='head'>diff --git a/app/views/imports/_issues_sidebar.html.erb b/app/views/imports/_issues_sidebar.html.erb<br/>new file mode 100644<br/>index 000000000..e098175ec<br/>--- /dev/null<br/>+++ b/<a href='/redmine.git/tree/app/views/imports/_issues_sidebar.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/_issues_sidebar.html.erb</a></div><div class='hunk'>@@ -0,0 +1,3 @@</div><div class='add'>+&lt;% content_for :sidebar do %&gt;</div><div class='add'>+  &lt;%= render :partial =&gt; 'issues/sidebar' %&gt;</div><div class='add'>+&lt;% end %&gt;</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.39.1</a>) at 2025-07-09 18:38:06 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
2'>app/views/imports/mapping.html.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/mapping.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/mapping.html.erb</a></div><div class='hunk'>@@ -1,12 +1,7 @@</div><div class='del'>-&lt;h2&gt;&lt;%= l(:label_import_issues) %&gt;&lt;/h2&gt;</div><div class='add'>+&lt;h2&gt;&lt;%= import_title %&gt;&lt;/h2&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;%= form_tag(import_mapping_path(@import), :id =&gt; "import-form") do %&gt;</div><div class='del'>-  &lt;fieldset class="box tabular"&gt;</div><div class='del'>-    &lt;legend&gt;&lt;%= l(:label_fields_mapping) %&gt;&lt;/legend&gt;</div><div class='del'>-    &lt;div id="fields-mapping"&gt;</div><div class='del'>-      &lt;%= render :partial =&gt; 'fields_mapping' %&gt;</div><div class='del'>-    &lt;/div&gt;</div><div class='del'>-  &lt;/fieldset&gt;</div><div class='add'>+  &lt;%= render :partial =&gt; "#{import_partial_prefix}_mapping" %&gt;</div><div class='ctx'> </div><div class='ctx'>   &lt;div class="autoscroll"&gt;</div><div class='ctx'>   &lt;fieldset class="box"&gt;</div><div class='hunk'>@@ -28,25 +23,13 @@</div><div class='ctx'>   &lt;/p&gt;</div><div class='ctx'> &lt;% end %&gt;</div><div class='ctx'> </div><div class='del'>-&lt;% content_for :sidebar do %&gt;</div><div class='del'>-    &lt;%= render :partial =&gt; 'issues/sidebar' %&gt;</div><div class='del'>-&lt;% end %&gt;</div><div class='del'>-</div><div class='add'>+&lt;%= render :partial =&gt; "#{import_partial_prefix}_sidebar" %&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;%= javascript_tag do %&gt;</div><div class='ctx'> $(document).ready(function() {</div><div class='del'>-  $('#fields-mapping').on('change', '#import_mapping_project_id, #import_mapping_tracker', function(){</div><div class='del'>-    $.ajax({</div><div class='del'>-      url: '&lt;%= import_mapping_path(@import, :format =&gt; 'js') %&gt;',</div><div class='del'>-      type: 'post',</div><div class='del'>-      data: $('#import-form').serialize()</div><div class='del'>-    });</div><div class='del'>-  });</div><div class='del'>-</div><div class='ctx'>   $('#import-form').submit(function(){</div><div class='ctx'>     $('#import-details').show().addClass('ajax-loading');</div><div class='ctx'>     $('#import-progress').progressbar({value: 0, max: &lt;%= @import.total_items || 0 %&gt;});</div><div class='ctx'>   });</div><div class='del'>-</div><div class='ctx'> });</div><div class='ctx'> &lt;% end %&gt;</div><div class='head'>diff --git a/app/views/imports/mapping.js.erb b/app/views/imports/mapping.js.erb<br/>index 8fdf14a36..4a4358427 100644<br/>--- a/<a href='/redmine.git/tree/app/views/imports/mapping.js.erb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/views/imports/mapping.js.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/mapping.js.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/mapping.js.erb</a></div><div class='hunk'>@@ -1 +1 @@</div><div class='del'>-$('#fields-mapping').html('&lt;%= escape_javascript(render :partial =&gt; 'fields_mapping') %&gt;');</div><div class='add'>+&lt;%= render :partial =&gt; "#{import_partial_prefix}_mapping" %&gt;</div><div class='head'>diff --git a/app/views/imports/new.html.erb b/app/views/imports/new.html.erb<br/>index e20be353a..41b27d6c9 100644<br/>--- a/<a href='/redmine.git/tree/app/views/imports/new.html.erb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/views/imports/new.html.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/new.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/new.html.erb</a></div><div class='hunk'>@@ -1,6 +1,7 @@</div><div class='del'>-&lt;h2&gt;&lt;%= l(:label_import_issues) %&gt;&lt;/h2&gt;</div><div class='add'>+&lt;h2&gt;&lt;%= import_title %&gt;&lt;/h2&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;%= form_tag(imports_path, :multipart =&gt; true) do %&gt;</div><div class='add'>+  &lt;%= hidden_field_tag 'type', @import.type %&gt;</div><div class='ctx'>   &lt;fieldset class="box"&gt;</div><div class='ctx'>     &lt;legend&gt;&lt;%= l(:label_select_file_to_import) %&gt; (CSV)&lt;/legend&gt;</div><div class='ctx'>     &lt;p&gt;</div><div class='hunk'>@@ -10,6 +11,4 @@</div><div class='ctx'>   &lt;p&gt;&lt;%= submit_tag l(:label_next).html_safe + " &amp;#187;".html_safe, :name =&gt; nil %&gt;&lt;/p&gt;</div><div class='ctx'> &lt;% end %&gt;</div><div class='ctx'> </div><div class='del'>-&lt;% content_for :sidebar do %&gt;</div><div class='del'>-    &lt;%= render :partial =&gt; 'issues/sidebar' %&gt;</div><div class='del'>-&lt;% end %&gt;</div><div class='add'>+&lt;%= render :partial =&gt; "#{import_partial_prefix}_sidebar" %&gt;</div><div class='head'>diff --git a/app/views/imports/run.html.erb b/app/views/imports/run.html.erb<br/>index 2a723537e..50b47836d 100644<br/>--- a/<a href='/redmine.git/tree/app/views/imports/run.html.erb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/views/imports/run.html.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/run.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/run.html.erb</a></div><div class='hunk'>@@ -1,12 +1,10 @@</div><div class='del'>-&lt;h2&gt;&lt;%= l(:label_import_issues) %&gt;&lt;/h2&gt;</div><div class='add'>+&lt;h2&gt;&lt;%= import_title %&gt;&lt;/h2&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;div id="import-details"&gt;</div><div class='ctx'>   &lt;div id="import-progress"&gt;&lt;div id="progress-label"&gt;0 / &lt;%= @import.total_items.to_i %&gt;&lt;/div&gt;&lt;/div&gt;</div><div class='ctx'> &lt;/div&gt;</div><div class='ctx'> </div><div class='del'>-&lt;% content_for :sidebar do %&gt;</div><div class='del'>-  &lt;%= render :partial =&gt; 'issues/sidebar' %&gt;</div><div class='del'>-&lt;% end %&gt;</div><div class='add'>+&lt;%= render :partial =&gt; "#{import_partial_prefix}_sidebar" %&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;%= javascript_tag do %&gt;</div><div class='ctx'> $(document).ready(function() {</div><div class='head'>diff --git a/app/views/imports/settings.html.erb b/app/views/imports/settings.html.erb<br/>index 6edfb10af..0fbb01857 100644<br/>--- a/<a href='/redmine.git/tree/app/views/imports/settings.html.erb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/views/imports/settings.html.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/settings.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/settings.html.erb</a></div><div class='hunk'>@@ -1,4 +1,4 @@</div><div class='del'>-&lt;h2&gt;&lt;%= l(:label_import_issues) %&gt;&lt;/h2&gt;</div><div class='add'>+&lt;h2&gt;&lt;%= import_title %&gt;&lt;/h2&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;%= form_tag(import_settings_path(@import), :id =&gt; "import-form") do %&gt;</div><div class='ctx'>   &lt;fieldset class="box tabular"&gt;</div><div class='hunk'>@@ -25,6 +25,4 @@</div><div class='ctx'>   &lt;p&gt;&lt;%= submit_tag l(:label_next).html_safe + " &amp;#187;".html_safe, :name =&gt; nil %&gt;&lt;/p&gt;</div><div class='ctx'> &lt;% end %&gt;</div><div class='ctx'> </div><div class='del'>-&lt;% content_for :sidebar do %&gt;</div><div class='del'>-    &lt;%= render :partial =&gt; 'issues/sidebar' %&gt;</div><div class='del'>-&lt;% end %&gt;</div><div class='add'>+&lt;%= render :partial =&gt; "#{import_partial_prefix}_sidebar" %&gt;</div><div class='head'>diff --git a/app/views/imports/show.html.erb b/app/views/imports/show.html.erb<br/>index 19c874c91..ca963ab37 100644<br/>--- a/<a href='/redmine.git/tree/app/views/imports/show.html.erb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>app/views/imports/show.html.erb</a><br/>+++ b/<a href='/redmine.git/tree/app/views/imports/show.html.erb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>app/views/imports/show.html.erb</a></div><div class='hunk'>@@ -1,15 +1,9 @@</div><div class='del'>-&lt;h2&gt;&lt;%= l(:label_import_issues) %&gt;&lt;/h2&gt;</div><div class='add'>+&lt;h2&gt;&lt;%= import_title %&gt;&lt;/h2&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;% if @import.saved_items.count &gt; 0 %&gt;</div><div class='ctx'>   &lt;p&gt;&lt;%= l(:notice_import_finished, :count =&gt; @import.saved_items.count) %&gt;:&lt;/p&gt;</div><div class='ctx'> </div><div class='del'>-  &lt;ul id="saved-items"&gt;</div><div class='del'>-  &lt;% @import.saved_objects.each do |issue| %&gt;</div><div class='del'>-    &lt;li&gt;&lt;%= link_to_issue issue %&gt;&lt;/li&gt;</div><div class='del'>-  &lt;% end %&gt;</div><div class='del'>-  &lt;/ul&gt;</div><div class='del'>-</div><div class='del'>-  &lt;p&gt;&lt;%= link_to l(:label_issue_view_all), issues_path(:set_filter =&gt; 1, :status_id =&gt; '*', :issue_id =&gt; @import.saved_objects.map(&amp;:id).join(',')) %&gt;&lt;/p&gt;</div><div class='add'>+  &lt;%= render :partial =&gt; "#{import_partial_prefix}_saved_objects", :locals =&gt; { saved_objects: @import.saved_objects } %&gt;</div><div class='ctx'> &lt;% end %&gt;</div><div class='ctx'> </div><div class='ctx'> &lt;% if @import.unsaved_items.count &gt; 0 %&gt;</div><div class='hunk'>@@ -33,6 +27,4 @@</div><div class='ctx'>   &lt;/table&gt;</div><div class='ctx'> &lt;% end %&gt;</div><div class='ctx'> </div><div class='del'>-&lt;% content_for :sidebar do %&gt;</div><div class='del'>-    &lt;%= render :partial =&gt; 'issues/sidebar' %&gt;</div><div class='del'>-&lt;% end %&gt;</div><div class='add'>+&lt;%= render :partial =&gt; "#{import_partial_prefix}_sidebar" %&gt;</div><div class='head'>diff --git a/config/routes.rb b/config/routes.rb<br/>index 27cf36a4b..4c65f976b 100644<br/>--- a/<a href='/redmine.git/tree/config/routes.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>config/routes.rb</a><br/>+++ b/<a href='/redmine.git/tree/config/routes.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>config/routes.rb</a></div><div class='hunk'>@@ -64,7 +64,7 @@ Rails.application.routes.draw do</div><div class='ctx'>   get 'projects/:id/issues/report', :to =&gt; 'reports#issue_report', :as =&gt; 'project_issues_report'</div><div class='ctx'>   get 'projects/:id/issues/report/:detail', :to =&gt; 'reports#issue_report_details', :as =&gt; 'project_issues_report_details'</div><div class='ctx'> </div><div class='del'>-  get   '/issues/imports/new', :to =&gt; 'imports#new', :as =&gt; 'new_issues_import'</div><div class='add'>+  get   '/issues/imports/new', :to =&gt; 'imports#new', :defaults =&gt; { :type =&gt; 'IssueImport' }, :as =&gt; 'new_issues_import'</div><div class='ctx'>   post  '/imports', :to =&gt; 'imports#create', :as =&gt; 'imports'</div><div class='ctx'>   get   '/imports/:id', :to =&gt; 'imports#show', :as =&gt; 'import'</div><div class='ctx'>   match '/imports/:id/settings', :to =&gt; 'imports#settings', :via =&gt; [:get, :post], :as =&gt; 'import_settings'</div><div class='head'>diff --git a/lib/redmine.rb b/lib/redmine.rb<br/>index 45e9f1024..2de351c07 100644<br/>--- a/<a href='/redmine.git/tree/lib/redmine.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>lib/redmine.rb</a><br/>+++ b/<a href='/redmine.git/tree/lib/redmine.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>lib/redmine.rb</a></div><div class='hunk'>@@ -118,7 +118,7 @@ Redmine::AccessControl.map do |map|</div><div class='ctx'>     map.permission :view_issue_watchers, {}, :read =&gt; true</div><div class='ctx'>     map.permission :add_issue_watchers, {:watchers =&gt; [:new, :create, :append, :autocomplete_for_user]}</div><div class='ctx'>     map.permission :delete_issue_watchers, {:watchers =&gt; :destroy}</div><div class='del'>-    map.permission :import_issues, {:imports =&gt; [:new, :create, :settings, :mapping, :run, :show]}</div><div class='add'>+    map.permission :import_issues, {}</div><div class='ctx'>     # Issue categories</div><div class='ctx'>     map.permission :manage_categories, {:projects =&gt; :settings, :issue_categories =&gt; [:index, :show, :new, :create, :edit, :update, :destroy]}, :require =&gt; :member</div><div class='ctx'>   end</div><div class='head'>diff --git a/test/functional/imports_controller_test.rb b/test/functional/imports_controller_test.rb<br/>index d6a110056..a094b81eb 100644<br/>--- a/<a href='/redmine.git/tree/test/functional/imports_controller_test.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>test/functional/imports_controller_test.rb</a><br/>+++ b/<a href='/redmine.git/tree/test/functional/imports_controller_test.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>test/functional/imports_controller_test.rb</a></div><div class='hunk'>@@ -44,7 +44,7 @@ class ImportsControllerTest &lt; Redmine::ControllerTest</div><div class='ctx'>   end</div><div class='ctx'> </div><div class='ctx'>   def test_new_should_display_the_upload_form</div><div class='del'>-    get :new</div><div class='add'>+    get :new, :params =&gt; { :type =&gt; 'IssueImport' }</div><div class='ctx'>     assert_response :success</div><div class='ctx'>     assert_select 'input[name=?]', 'file'</div><div class='ctx'>   end</div><div class='hunk'>@@ -52,6 +52,7 @@ class ImportsControllerTest &lt; Redmine::ControllerTest</div><div class='ctx'>   def test_create_should_save_the_file</div><div class='ctx'>     import = new_record(Import) do</div><div class='ctx'>       post :create, :params =&gt; {</div><div class='add'>+          :type =&gt; 'IssueImport',</div><div class='ctx'>           :file =&gt; uploaded_test_file('import_issues.csv', 'text/csv')</div><div class='ctx'>         }</div><div class='ctx'>       assert_response 302</div><div class='head'>diff --git a/test/integration/routing/imports_test.rb b/test/integration/routing/imports_test.rb<br/>index ec71470d0..eb96a9a98 100644<br/>--- a/<a href='/redmine.git/tree/test/integration/routing/imports_test.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>test/integration/routing/imports_test.rb</a><br/>+++ b/<a href='/redmine.git/tree/test/integration/routing/imports_test.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>test/integration/routing/imports_test.rb</a></div><div class='hunk'>@@ -21,7 +21,8 @@ require File.expand_path('../../../test_helper', __FILE__)</div><div class='ctx'> </div><div class='ctx'> class RoutingImportsTest &lt; Redmine::RoutingTest</div><div class='ctx'>   def test_imports</div><div class='del'>-    should_route 'GET /issues/imports/new' =&gt; 'imports#new'</div><div class='add'>+    should_route 'GET /issues/imports/new' =&gt; 'imports#new', :type =&gt; 'IssueImport'</div><div class='add'>+</div><div class='ctx'>     should_route 'POST /imports' =&gt; 'imports#create'</div><div class='ctx'> </div><div class='ctx'>     should_route 'GET /imports/4ae6bc' =&gt; 'imports#show', :id =&gt; '4ae6bc'</div><div class='head'>diff --git a/test/unit/issue_import_test.rb b/test/unit/issue_import_test.rb<br/>index 9c4eafba1..4def8b120 100644<br/>--- a/<a href='/redmine.git/tree/test/unit/issue_import_test.rb?h=5.0-stable&amp;id=bcc60805c97104f44a37b92321d7aa1e5c51b622'>test/unit/issue_import_test.rb</a><br/>+++ b/<a href='/redmine.git/tree/test/unit/issue_import_test.rb?h=5.0-stable&amp;id=b540046ed7084ba50f5ca280f3ffae0751af8142'>test/unit/issue_import_test.rb</a></div><div class='hunk'>@@ -41,6 +41,12 @@ class IssueImportTest &lt; ActiveSupport::TestCase</div><div class='ctx'>     set_language_if_valid 'en'</div><div class='ctx'>   end</div><div class='ctx'> </div><div class='add'>+  def test_authorized</div><div class='add'>+    assert  IssueImport.authorized?(User.find(1)) # admins</div><div class='add'>+    assert  IssueImport.authorized?(User.find(2)) # has import_issues permission</div><div class='add'>+    assert !IssueImport.authorized?(User.find(3)) # does not have permission</div><div class='add'>+  end</div><div class='add'>+</div><div class='ctx'>   def test_create_versions_should_create_missing_versions</div><div class='ctx'>     import = generate_import_with_mapping</div><div class='ctx'>     import.mapping.merge!('fixed_version' =&gt; '9', 'create_versions' =&gt; '1')</div></td></tr></table></div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.39.1</a>) at 2025-07-09 18:38:05 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
