<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>test/unit/bulk_time_entry_transaction_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -3,17 +3,27 @@ require 'fastercsv'
 class BulkTimeEntry
   def self.import_from_csv(file)
     csv_file = File.read(file)
+    row_counter = 0
 
-    FasterCSV.parse(csv_file) do |row|
-      time = TimeEntry.new(:issue_id =&gt; row[0],
-                           :comments =&gt; row[1].strip, # TODO: truncate
-                           :spent_on =&gt; row[2],
-                           :activity =&gt; TimeEntryActivity.find_by_name(row[3].strip),
-                           :hours =&gt; row[4])
-      time.user = User.find_by_login(row[5].strip)
+    begin
+      ActiveRecord::Base.transaction do
+        FasterCSV.parse(csv_file) do |row|
+          time = TimeEntry.new(:issue_id =&gt; row[0],
+                               :comments =&gt; row[1].strip, # TODO: truncate
+                               :spent_on =&gt; row[2],
+                               :activity =&gt; TimeEntryActivity.find_by_name(row[3].strip),
+                               :hours =&gt; row[4])
+          time.user = User.find_by_login(row[5].strip)
 
-      time.save!
+          time.save!
+          row_counter += 1
+        end
+      end
+    rescue ActiveRecord::StatementInvalid, ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid =&gt; ex
+      return &quot;ERROR: #{ex.message}&quot;
     end
 
+    return &quot;Imported #{row_counter} records&quot;
   end
+  
 end</diff>
      <filename>app/models/bulk_time_entry.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@ namespace :bulk_time_entry do
     task :csv =&gt; [:environment] do
       csv_file = ENV['CSV_FILE'] || File.join(RAILS_ROOT, 'time_entries.csv')
 
-      BulkTimeEntry.import_from_csv(csv_file)
+      puts BulkTimeEntry.import_from_csv(csv_file)
     end
     
   end</diff>
      <filename>lib/tasks/import_from_csv.rake</filename>
    </modified>
    <modified>
      <diff>@@ -25,6 +25,31 @@ end
 class Test::Unit::TestCase
 end
 
+module BulkTimeEntryTestHelper
+  def mock_csv_file(name, data='')
+    file = mock
+    file.stubs(:name).returns(name)
+    File.stubs(:read).with(name).returns(data)
+    file
+  end
+
+  def generate_csv_data(count=5)
+    @activity ||= TimeEntryActivity.generate!
+    @user ||= User.generate_with_protected!
+
+    @project ||= Project.generate!
+    @tracker ||= Tracker.generate!
+    @project.trackers &lt;&lt; @tracker unless @project.trackers.include? @tracker
+
+    csv_data = []
+    5.times {
+      issue = Issue.generate!(:tracker =&gt; @tracker, :project =&gt; @project)
+      csv_data &lt;&lt; [issue.id.to_s, 'A comment', Date.today.to_s, @activity.name, (rand * 10).round(2).to_s, @user.login]
+          }
+    csv_data
+  end
+end
+
 # Shoulda
 class Test::Unit::TestCase
 end</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,29 +2,12 @@ require File.dirname(__FILE__) + '/../test_helper'
 
 require 'fastercsv'
 
+# Failing records are tested in BulkTimeEntryTransaction since Rails
+# can't turn fixture transactions off for a single test case.
 class BulkTimeEntryTest &lt; Test::Unit::TestCase
-  def mock_csv_file(name, data='')
-    file = mock
-    file.stubs(:name).returns(name)
-    File.stubs(:read).with(name).returns(data)
-    file
-  end
-
-  def generate_csv_data(count=5)
-    @project ||= Project.generate!
-    @tracker ||= Tracker.generate!
-    @project.trackers &lt;&lt; @tracker unless @project.trackers.include? @tracker
-
-    csv_data = []
-    5.times {
-      issue = Issue.generate!(:tracker =&gt; @tracker, :project =&gt; @project)
-      csv_data &lt;&lt; [issue.id.to_s, 'A comment', Date.today.to_s, @activity.name, (rand * 10).round(2).to_s, @user.login]
-          }
-    csv_data
-  end
+  include BulkTimeEntryTestHelper  
 
   context &quot;#import_from_csv&quot; do
-
     context &quot;non-readable file&quot; do
       setup do
         @file = '/a/test_file.csv'
@@ -56,10 +39,6 @@ class BulkTimeEntryTest &lt; Test::Unit::TestCase
     end
 
     context &quot;valid file&quot; do
-      setup do
-        @activity = TimeEntryActivity.generate!
-        @user = User.generate_with_protected!
-      end
 
       should &quot;skip empty lines&quot;
 
@@ -93,11 +72,6 @@ class BulkTimeEntryTest &lt; Test::Unit::TestCase
         end
 
       end
-
-      context &quot;with a failing record&quot; do
-        should &quot;rollback the import if any record fails&quot;
-        should &quot;raise an exception&quot;
-      end
     end
   end
 end</diff>
      <filename>test/unit/bulk_time_entry_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8cc2fddf7f67ca66411d2f8db1348e04308c40e2</id>
    </parent>
  </parents>
  <author>
    <name>Eric Davis</name>
    <email>edavis@littlestreamsoftware.com</email>
  </author>
  <url>http://github.com/edavis10/redmine-bulk_time_entry_plugin/commit/fcca95918cca0afbbd88d3ab297b9fceea4a9f5d</url>
  <id>fcca95918cca0afbbd88d3ab297b9fceea4a9f5d</id>
  <committed-date>2009-09-28T17:02:08-07:00</committed-date>
  <authored-date>2009-09-28T17:02:08-07:00</authored-date>
  <message>[#3038] Wrapped the import in a transaction.</message>
  <tree>ff9cbfa175c3437522159cb54a8482aaf62f3620</tree>
  <committer>
    <name>Eric Davis</name>
    <email>edavis@littlestreamsoftware.com</email>
  </committer>
</commit>
