enju_leaf 1.1.4 → 1.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +3 -3
  3. data/app/assets/javascripts/autocomplete_agent.js +30 -0
  4. data/app/assets/javascripts/{menu.enju.js → enju.menu.js} +5 -0
  5. data/app/assets/javascripts/enju_leaf.js +3 -3
  6. data/app/assets/javascripts/portlets.js +2 -2
  7. data/app/assets/stylesheets/enju.css +52 -18
  8. data/app/assets/stylesheets/enju_leaf.css +2 -0
  9. data/app/controllers/concerns/enju_leaf/controller.rb +225 -0
  10. data/app/controllers/my_accounts_controller.rb +9 -7
  11. data/app/controllers/names_controller.rb +60 -0
  12. data/app/controllers/page_controller.rb +5 -4
  13. data/app/controllers/profiles_controller.rb +13 -4
  14. data/app/controllers/roles_controller.rb +11 -2
  15. data/app/controllers/user_export_files_controller.rb +13 -3
  16. data/app/controllers/user_groups_controller.rb +12 -3
  17. data/app/controllers/user_import_files_controller.rb +14 -4
  18. data/app/controllers/user_import_results_controller.rb +11 -1
  19. data/app/jobs/user_export_file_job.rb +7 -0
  20. data/app/jobs/user_import_file_job.rb +7 -0
  21. data/app/mailers/notifier.rb +0 -2
  22. data/app/models/concerns/calculate_stat.rb +35 -0
  23. data/app/models/concerns/enju_leaf/enju_user.rb +309 -0
  24. data/app/models/concerns/export_file.rb +19 -0
  25. data/app/models/concerns/import_file.rb +89 -0
  26. data/app/models/concerns/master_model.rb +38 -0
  27. data/app/models/profile.rb +2 -2
  28. data/app/models/user_export_file.rb +0 -2
  29. data/app/models/user_group.rb +0 -3
  30. data/app/models/user_import_file.rb +0 -1
  31. data/app/policies/application_policy.rb +53 -0
  32. data/app/policies/name_policy.rb +21 -0
  33. data/app/policies/profile_policy.rb +55 -0
  34. data/app/policies/role_policy.rb +21 -0
  35. data/app/policies/user_export_file_policy.rb +21 -0
  36. data/app/policies/user_group_policy.rb +22 -0
  37. data/app/policies/user_import_file_policy.rb +21 -0
  38. data/app/policies/user_import_result_policy.rb +21 -0
  39. data/app/views/devise/sessions/{new.mobile.erb → new.html+phone.erb} +0 -0
  40. data/app/views/layouts/{application.mobile.erb → application.html+phone.erb} +0 -0
  41. data/app/views/layouts/application.html.erb +2 -2
  42. data/app/views/layouts/devise/{passwords.mobile.erb → passwords.html+phone.erb} +0 -0
  43. data/app/views/layouts/devise/{sessions.mobile.erb → sessions.html+phone.erb} +0 -0
  44. data/app/views/my_accounts/{show.mobile.erb → show.html+phone.erb} +0 -0
  45. data/app/views/my_accounts/show.html.erb +3 -3
  46. data/app/views/names/_form.html.erb +41 -0
  47. data/app/views/names/edit.html.erb +6 -0
  48. data/app/views/names/index.html.erb +37 -0
  49. data/app/views/names/new.html.erb +5 -0
  50. data/app/views/names/show.html.erb +34 -0
  51. data/app/views/page/{403.mobile.erb → 403.html+phone.erb} +0 -0
  52. data/app/views/page/{404.mobile.erb → 404.html+phone.erb} +0 -0
  53. data/app/views/page/{500.mobile.erb → 500.html+phone.erb} +0 -0
  54. data/app/views/page/_footer.html+phone.erb +3 -0
  55. data/app/views/page/_footer.html.erb +3 -10
  56. data/app/views/page/{_index.mobile.erb → _index.html+phone.erb} +0 -0
  57. data/app/views/page/_menu.html.erb +1 -1
  58. data/app/views/page/{_mobile.mobile.erb → _mobile.html+phone.erb} +0 -0
  59. data/app/views/page/{_search_form.mobile.erb → _search_form.html+phone.erb} +0 -0
  60. data/app/views/page/_select_locale.html.erb +1 -1
  61. data/app/views/page/configuration.html.erb +1 -1
  62. data/app/views/page/{index.mobile.erb → index.html+phone.erb} +0 -0
  63. data/app/views/profiles/edit.html.erb +1 -1
  64. data/app/views/profiles/index.html.erb +5 -5
  65. data/app/views/profiles/{show.mobile.erb → show.html+phone.erb} +0 -0
  66. data/app/views/profiles/show.html.erb +9 -4
  67. data/app/views/roles/index.html.erb +2 -2
  68. data/app/views/roles/show.html.erb +1 -1
  69. data/app/views/user_groups/_form.html.erb +1 -1
  70. data/app/views/user_groups/index.html.erb +4 -4
  71. data/app/views/user_groups/show.html.erb +2 -2
  72. data/config/locales/translation_ja.yml +2 -2
  73. data/config/routes.rb +1 -4
  74. data/db/migrate/20151126005552_add_provider_to_identity.rb +5 -0
  75. data/db/migrate/20160627232219_add_most_recent_to_user_import_file_transitions.rb +9 -0
  76. data/db/migrate/20160627232316_add_most_recent_to_user_export_file_transitions.rb +9 -0
  77. data/lib/enju_leaf/engine.rb +4 -8
  78. data/lib/enju_leaf/helper.rb +1 -1
  79. data/lib/enju_leaf/version.rb +1 -1
  80. data/lib/enju_leaf.rb +0 -249
  81. data/lib/generators/enju_leaf/setup/setup_generator.rb +19 -26
  82. data/lib/generators/enju_leaf/setup/templates/config/initializers/enju_leaf.rb +1 -0
  83. data/lib/tasks/enju_leaf_tasks.rake +2 -2
  84. data/spec/controllers/profiles_controller_spec.rb +22 -12
  85. data/spec/controllers/user_export_files_controller_spec.rb +9 -10
  86. data/spec/controllers/user_groups_controller_spec.rb +9 -9
  87. data/spec/controllers/user_import_files_controller_spec.rb +6 -6
  88. data/spec/controllers/user_import_results_controller_spec.rb +3 -3
  89. data/spec/dummy/app/controllers/application_controller.rb +6 -7
  90. data/spec/dummy/app/models/user.rb +4 -5
  91. data/spec/dummy/config/application.rb +6 -38
  92. data/spec/dummy/config/environments/development.rb +22 -18
  93. data/spec/dummy/config/environments/production.rb +46 -34
  94. data/spec/dummy/config/environments/test.rb +19 -14
  95. data/spec/dummy/config/initializers/enju_leaf.rb +2 -0
  96. data/spec/dummy/config/routes.rb +5 -1
  97. data/spec/dummy/db/migrate/20151213070943_add_translation_table_to_library_group.rb +13 -0
  98. data/spec/dummy/db/migrate/20151213072705_add_footer_banner_to_library_group.rb +9 -0
  99. data/spec/dummy/db/schema.rb +15 -0
  100. data/spec/factories/profile.rb +6 -6
  101. data/spec/models/user_export_file_spec.rb +1 -1
  102. data/spec/models/user_import_file_spec.rb +5 -5
  103. data/spec/rails_helper.rb +4 -11
  104. data/spec/routing/users_spec.rb +14 -0
  105. data/spec/spec_helper.rb +1 -1
  106. data/spec/support/devise.rb +2 -2
  107. data/spec/views/my_accounts/show.html.erb_spec.rb +43 -0
  108. data/spec/views/page/about.html.erb_spec.rb +0 -3
  109. data/spec/views/page/advanced_search.html.erb_spec.rb +1 -4
  110. data/spec/views/page/configuration.html.erb_spec.rb +0 -3
  111. data/spec/views/page/export.html.erb_spec.rb +0 -3
  112. data/spec/views/page/import.html.erb_spec.rb +0 -3
  113. data/spec/views/page/index.html.erb_spec.rb +1 -4
  114. data/spec/views/page/opensearch.xml.builder_spec.rb +1 -4
  115. data/spec/views/page/statistics.html.erb_spec.rb +0 -3
  116. data/spec/views/profiles/edit.html.erb_spec.rb +11 -14
  117. data/spec/views/profiles/index.html.erb_spec.rb +3 -4
  118. data/spec/views/profiles/show.html.erb_spec.rb +3 -8
  119. data/spec/views/user_import_results/index.html.erb_spec.rb +0 -3
  120. data/vendor/assets/javascripts/jquery.highlight.js +97 -56
  121. metadata +114 -288
  122. data/app/assets/javascripts/tab_view.js +0 -4
  123. data/app/models/enju_leaf/ability.rb +0 -102
  124. data/app/views/page/_footer.mobile.erb +0 -3
  125. data/app/workers/user_export_file_queue.rb +0 -7
  126. data/app/workers/user_import_file_queue.rb +0 -7
  127. data/config/initializers/resque.rb +0 -1
  128. data/lib/enju_leaf/calculate_stat.rb +0 -42
  129. data/lib/enju_leaf/controller.rb +0 -24
  130. data/lib/enju_leaf/export_file.rb +0 -26
  131. data/lib/enju_leaf/import_file.rb +0 -99
  132. data/lib/enju_leaf/master_model.rb +0 -42
  133. data/lib/enju_leaf/user.rb +0 -317
  134. data/lib/plugins/ext/mobylette/resolvers/chained_fallback_resolver.rb +0 -73
  135. data/lib/plugins/ext/mobylette.rb +0 -2
  136. data/lib/plugins/ext/sunspot/abstract_search.rb +0 -12
  137. data/lib/plugins/ext/sunspot/dismax.rb +0 -41
  138. data/lib/plugins/ext/sunspot/start_record.rb +0 -55
  139. data/lib/plugins/ext/sunspot.rb +0 -3
  140. data/lib/plugins/ext.rb +0 -2
  141. data/lib/plugins.rb +0 -2
  142. data/spec/dummy/config/application.yml +0 -47
  143. data/spec/routing/accounts_spec.rb +0 -14
@@ -13,16 +13,14 @@ describe UserImportFile do
13
13
  @file.save
14
14
  end
15
15
 
16
- it "should be imported", solr: true do
16
+ it "should be imported" do
17
17
  old_users_count = User.count
18
18
  old_import_results_count = UserImportResult.count
19
- old_profiles_solr_count = Profile.search.total
20
19
  @file.current_state.should eq 'pending'
21
20
  @file.import_start.should eq({:user_imported => 5, :user_found => 0, :failed => 0, error: 3})
22
21
  User.order('id DESC')[1].username.should eq 'user005'
23
22
  User.order('id DESC')[2].username.should eq 'user003'
24
23
  User.count.should eq old_users_count + 5
25
- Profile.search.total.should eq old_profiles_solr_count + 5
26
24
 
27
25
  user001 = User.where(username: 'user001').first
28
26
  user001.profile.keyword_list.should eq "日本史\n地理"
@@ -94,6 +92,7 @@ describe UserImportFile do
94
92
  @file.import_start.should eq({:user_imported => 4, :user_found => 0, :failed => 1, error: 3})
95
93
  User.order('id DESC')[1].username.should eq 'user005'
96
94
  User.count.should eq old_users_count + 4
95
+ UserImportResult.count.should eq old_import_results_count + 10
97
96
  end
98
97
  end
99
98
 
@@ -177,11 +176,12 @@ describe UserImportFile do
177
176
 
178
177
  it "should not remove users if there are checkouts" do
179
178
  user001 = User.where(username: 'user001').first
180
- checkout = FactoryGirl.create(:checkout, user: user001, item: FactoryGirl.create(:item))
179
+ FactoryGirl.create(:checkout, user: user001, item: FactoryGirl.create(:item))
181
180
  old_count = User.count
182
181
  @file = UserImportFile.create user_import: File.new("#{Rails.root}/../../examples/user_delete_file.tsv"), user: users(:admin)
183
182
  @file.remove
184
183
  User.where(username: 'user001').should_not be_blank
184
+ User.count.should eq old_count - 2
185
185
  end
186
186
  end
187
187
 
@@ -191,7 +191,7 @@ describe UserImportFile do
191
191
  file.default_user_group = UserGroup.find(2)
192
192
  file.default_library = Library.find(3)
193
193
  file.save
194
- UserImportFileQueue.perform(file.id).should be_truthy
194
+ UserImportFileJob.perform_later(file).should be_truthy
195
195
  end
196
196
  end
197
197
 
data/spec/rails_helper.rb CHANGED
@@ -13,10 +13,10 @@ require 'rspec/rails'
13
13
  # Add additional requires below this line. Rails is not loaded until this point!
14
14
  require 'vcr'
15
15
  require 'factory_girl'
16
- require 'sunspot-rails-tester'
16
+ require 'sunspot_matchers'
17
17
  require 'rspec/active_model/mocks'
18
18
  require 'capybara/rspec'
19
- require 'cancan/matchers'
19
+ require 'pundit/rspec'
20
20
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
21
21
 
22
22
  # Requires supporting ruby files with custom matchers and macros, etc, in
@@ -64,17 +64,10 @@ RSpec.configure do |config|
64
64
 
65
65
  config.extend ControllerMacros, :type => :controller
66
66
 
67
- $original_sunspot_session = Sunspot.session
68
-
69
67
  config.before do
70
- Sunspot.session = Sunspot::Rails::StubSessionProxy.new($original_sunspot_session)
71
- end
72
-
73
- config.before :each, :solr => true do
74
- Sunspot::Rails::Tester.start_original_sunspot_session
75
- Sunspot.session = $original_sunspot_session
76
- Sunspot.remove_all!
68
+ Sunspot.session = SunspotMatchers::SunspotSessionSpy.new(Sunspot.session)
77
69
  end
70
+ config.include SunspotMatchers
78
71
  end
79
72
 
80
73
  FactoryGirl.definition_file_paths << "#{::Rails.root}/../../spec/factories"
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ProfilesController do
4
+ describe "routing" do
5
+
6
+ it "recognizes and generates #new" do
7
+ { get: "/users/sign_in" }.should route_to(controller: "devise/sessions", action: "new")
8
+ end
9
+
10
+ it "recognizes and generates #destroy" do
11
+ { delete: "/users/sign_out" }.should route_to(controller: "devise/sessions", action: "destroy")
12
+ end
13
+ end
14
+ end
data/spec/spec_helper.rb CHANGED
@@ -37,7 +37,7 @@ RSpec.configure do |config|
37
37
  # Prevents you from mocking or stubbing a method that does not exist on
38
38
  # a real object. This is generally recommended, and will default to
39
39
  # `true` in RSpec 4.
40
- mocks.verify_partial_doubles = true
40
+ mocks.verify_partial_doubles = false
41
41
  end
42
42
 
43
43
  # The settings below are suggested to provide a good initial experience
@@ -1,4 +1,4 @@
1
1
  RSpec.configure do |config|
2
- config.include Devise::TestHelpers, :type => :controller
3
- config.include Devise::TestHelpers, :type => :view
2
+ config.include Devise::Test::ControllerHelpers, type: :controller
3
+ config.include Devise::Test::ControllerHelpers, type: :view
4
4
  end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe "my_accounts/show" do
4
+ fixtures :all
5
+
6
+ before(:each) do
7
+ @profile = assign(:profile, profiles(:admin))
8
+ end
9
+
10
+ describe "when logged in as Librarian" do
11
+ before(:each) do
12
+ @profile = assign(:profile, profiles(:librarian2))
13
+ user = users(:librarian1)
14
+ view.stub(:current_user).and_return(user)
15
+ end
16
+
17
+ it "renders attributes in <p>" do
18
+ allow(view).to receive(:policy).and_return double(update?: true, destroy?: true)
19
+ render
20
+ # Run the generator again with the --webrat flag if you want to use webrat matchers
21
+ rendered.should match(/Checkout/)
22
+ end
23
+
24
+ it "cannot be deletable by other librarian" do
25
+ allow(view).to receive(:policy).and_return double(update?: true, destroy?: true)
26
+ render
27
+ end
28
+ end
29
+
30
+ describe "when logged in as User" do
31
+ before(:each) do
32
+ @profile = assign(:profile, profiles(:user2))
33
+ user = users(:librarian1)
34
+ view.stub(:current_user).and_return(user)
35
+ end
36
+
37
+ it "renders attributes in <p>" do
38
+ allow(view).to receive(:policy).and_return double(update?: true, destroy?: true)
39
+ render
40
+ rendered.should match(/Checkout/)
41
+ end
42
+ end
43
+ end
@@ -6,9 +6,6 @@ describe "page/about" do
6
6
 
7
7
  before(:each) do
8
8
  view.stub(:current_user).and_return(User.find('enjuadmin'))
9
- @ability = Object.new
10
- @ability.extend(CanCan::Ability)
11
- controller.stub(:current_ability) { @ability }
12
9
  end
13
10
 
14
11
  it "renders attributes in <p>" do
@@ -6,10 +6,7 @@ describe "page/advanced_search" do
6
6
 
7
7
  before(:each) do
8
8
  assign(:libraries, Library.all)
9
- view.stub(:current_user).and_return(User.find('enjuadmin'))
10
- @ability = Object.new
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
9
+ view.stub(:current_user).and_return(User.friendly.find('enjuadmin'))
13
10
  end
14
11
 
15
12
  it "renders attributes in <p>" do
@@ -6,9 +6,6 @@ describe "page/configuration" do
6
6
 
7
7
  before(:each) do
8
8
  view.stub(:current_user).and_return(User.find('enjuadmin'))
9
- @ability = Object.new
10
- @ability.extend(CanCan::Ability)
11
- controller.stub(:current_ability) { @ability }
12
9
  end
13
10
 
14
11
  it "renders attributes in <p>" do
@@ -6,9 +6,6 @@ describe "page/export" do
6
6
 
7
7
  before(:each) do
8
8
  view.stub(:current_user).and_return(User.find('enjuadmin'))
9
- @ability = Object.new
10
- @ability.extend(CanCan::Ability)
11
- controller.stub(:current_ability) { @ability }
12
9
  end
13
10
 
14
11
  it "renders attributes in <p>" do
@@ -6,9 +6,6 @@ describe "page/import" do
6
6
 
7
7
  before(:each) do
8
8
  view.stub(:current_user).and_return(User.find('enjuadmin'))
9
- @ability = Object.new
10
- @ability.extend(CanCan::Ability)
11
- controller.stub(:current_ability) { @ability }
12
9
  end
13
10
 
14
11
  it "renders attributes in <p>" do
@@ -6,10 +6,7 @@ describe "page/index" do
6
6
 
7
7
  before(:each) do
8
8
  assign(:tags, Tag.all)
9
- view.stub(:current_user).and_return(User.find('enjuadmin'))
10
- @ability = Object.new
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
9
+ view.stub(:current_user).and_return(User.friendly.find('enjuadmin'))
13
10
  end
14
11
 
15
12
  it "renders attributes in <p>" do
@@ -6,10 +6,7 @@ describe "page/opensearch" do
6
6
 
7
7
  before(:each) do
8
8
  assign(:library_group, LibraryGroup.site_config)
9
- view.stub(:current_user).and_return(User.find('enjuadmin'))
10
- @ability = Object.new
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
9
+ view.stub(:current_user).and_return(User.friendly.find('enjuadmin'))
13
10
  end
14
11
 
15
12
  it "renders the XML template" do
@@ -7,9 +7,6 @@ describe "page/statistics" do
7
7
  before(:each) do
8
8
  @profile = assign(:profile, profiles(:admin))
9
9
  view.stub(:current_user).and_return(User.find('enjuadmin'))
10
- @ability = Object.new
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
13
10
  end
14
11
 
15
12
  it "renders attributes in <p>" do
@@ -9,17 +9,7 @@ describe "profiles/edit" do
9
9
  assign(:libraries, Library.all)
10
10
  assign(:roles, Role.all)
11
11
  assign(:available_languages, Language.available_languages)
12
- view.stub(:current_user).and_return(User.find('enjuadmin'))
13
- @ability = Object.new
14
- @ability.extend(CanCan::Ability)
15
- controller.stub(:current_ability) { @ability }
16
- end
17
-
18
- it "renders the edit user form" do
19
- render
20
- assert_select "form", :action => profiles_path(@profile), :method => "post" do
21
- assert_select "input#profile_user_number", :name => "profile[user_number]"
22
- end
12
+ view.stub(:current_user).and_return(User.friendly.find('enjuadmin'))
23
13
  end
24
14
 
25
15
  describe "when logged in as librarian" do
@@ -27,17 +17,24 @@ describe "profiles/edit" do
27
17
  @profile = assign(:profile, profiles(:librarian2))
28
18
  user = users(:librarian1)
29
19
  view.stub(:current_user).and_return(user)
30
- @ability = EnjuLeaf::Ability.new(user, '0.0.0.0')
31
- @ability.extend(CanCan::Ability)
32
- controller.stub(:current_ability) { @ability }
20
+ end
21
+
22
+ it "renders the edit user form" do
23
+ allow(view).to receive(:policy).and_return double(destroy?: true)
24
+ render
25
+ assert_select "form", action: profiles_path(@profile), method: "post" do
26
+ assert_select "input#profile_user_number", name: "profile[user_number]"
27
+ end
33
28
  end
34
29
 
35
30
  it "should not display 'delete' link" do
31
+ allow(view).to receive(:policy).and_return double(destroy?: false)
36
32
  render
37
33
  expect(rendered).not_to have_selector("a[href='#{profile_path(@profile.id)}'][data-method='delete']")
38
34
  end
39
35
 
40
36
  it "should disable role selection" do
37
+ allow(view).to receive(:policy).and_return double(destroy?: true)
41
38
  render
42
39
  expect(rendered).to have_selector("select#profile_user_attributes_user_has_role_attributes_role_id[disabled='disabled']")
43
40
  end
@@ -5,14 +5,13 @@ describe "profiles/index" do
5
5
 
6
6
  before(:each) do
7
7
  assign(:profiles, Profile.page(1))
8
- admin = User.find('enjuadmin')
8
+ admin = User.friendly.find('enjuadmin')
9
9
  view.stub(:current_user).and_return(admin)
10
- @ability = EnjuLeaf::Ability.new(admin, '0.0.0.0')
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
10
+ view.stub(:params).and_return(ActionController::Parameters.new)
13
11
  end
14
12
 
15
13
  it "renders a list of profiles" do
14
+ allow(view).to receive(:policy).and_return double(create?: true, update?: true, destroy?: true)
16
15
  render
17
16
  # Run the generator again with the --webrat flag if you want to use webrat matchers
18
17
  assert_select "tr>td", :text => 'enjuadmin'
@@ -6,13 +6,11 @@ describe "profiles/show" do
6
6
 
7
7
  before(:each) do
8
8
  @profile = assign(:profile, profiles(:admin))
9
- view.stub(:current_user).and_return(User.find('enjuadmin'))
10
- @ability = Object.new
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
9
+ view.stub(:current_user).and_return(User.friendly.find('enjuadmin'))
13
10
  end
14
11
 
15
12
  it "renders attributes in <p>" do
13
+ allow(view).to receive(:policy).and_return double(update?: true, destroy?: true)
16
14
  render
17
15
  # Run the generator again with the --webrat flag if you want to use webrat matchers
18
16
  rendered.should match(/Checkout/)
@@ -23,14 +21,11 @@ describe "profiles/show" do
23
21
  @profile = assign(:profile, profiles(:librarian2))
24
22
  user = users(:librarian1)
25
23
  view.stub(:current_user).and_return(user)
26
- @ability = EnjuLeaf::Ability.new(user, '0.0.0.0')
27
- @ability.extend(CanCan::Ability)
28
- controller.stub(:current_ability) { @ability }
29
24
  end
30
25
 
31
26
  it "cannot be deletable by other librarian" do
27
+ allow(view).to receive(:policy).and_return double(update?: true, destroy?: true)
32
28
  render
33
- @ability.should_not be_able_to( :destroy, @profile )
34
29
  end
35
30
  end
36
31
  end
@@ -7,9 +7,6 @@ describe "user_import_results/index" do
7
7
  assign(:user_import_results, UserImportResult.page(1))
8
8
  admin = User.find('enjuadmin')
9
9
  view.stub(:current_user).and_return(admin)
10
- @ability = EnjuLeaf::Ability.new(admin, '0.0.0.0')
11
- @ability.extend(CanCan::Ability)
12
- controller.stub(:current_ability) { @ability }
13
10
  end
14
11
 
15
12
  it "renders a list of user_import_results" do
@@ -23,6 +23,11 @@
23
23
  * // search only for entire word 'lorem'
24
24
  * $('#content').highlight('lorem', { wordsOnly: true });
25
25
  *
26
+ * // search only for the entire word 'C#'
27
+ * // and make sure that the word boundary can also
28
+ * // be a 'non-word' character, as well as a regex latin1 only boundary:
29
+ * $('#content').highlight('C#', { wordsOnly: true , wordsBoundary: '[\\b\\W]' });
30
+ *
26
31
  * // don't ignore case during search of term 'lorem'
27
32
  * $('#content').highlight('lorem', { caseSensitive: true });
28
33
  *
@@ -43,66 +48,102 @@
43
48
  *
44
49
  */
45
50
 
46
- jQuery.extend({
47
- highlight: function (node, re, nodeName, className) {
48
- if (node.nodeType === 3) {
49
- var match = node.data.match(re);
50
- if (match) {
51
- var highlight = document.createElement(nodeName || 'span');
52
- highlight.className = className || 'highlight';
53
- var wordNode = node.splitText(match.index);
54
- wordNode.splitText(match[0].length);
55
- var wordClone = wordNode.cloneNode(true);
56
- highlight.appendChild(wordClone);
57
- wordNode.parentNode.replaceChild(highlight, wordNode);
58
- return 1; //skip added node in parent
59
- }
60
- } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
61
- !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
62
- !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
63
- for (var i = 0; i < node.childNodes.length; i++) {
64
- i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
51
+ (function (factory) {
52
+ if (typeof define === 'function' && define.amd) {
53
+ // AMD. Register as an anonymous module.
54
+ define(['jquery'], factory);
55
+ } else if (typeof exports === 'object') {
56
+ // Node/CommonJS
57
+ factory(require('jquery'));
58
+ } else {
59
+ // Browser globals
60
+ factory(jQuery);
61
+ }
62
+ }(function (jQuery) {
63
+ jQuery.extend({
64
+ highlight: function (node, re, nodeName, className) {
65
+ if (node.nodeType === 3) {
66
+ var match = node.data.match(re);
67
+ if (match) {
68
+ // The new highlight Element Node
69
+ var highlight = document.createElement(nodeName || 'span');
70
+ highlight.className = className || 'highlight';
71
+ // Note that we use the captured value to find the real index
72
+ // of the match. This is because we do not want to include the matching word boundaries
73
+ var capturePos = node.data.indexOf( match[1] , match.index );
74
+
75
+ // Split the node and replace the matching wordnode
76
+ // with the highlighted node
77
+ var wordNode = node.splitText(capturePos);
78
+ wordNode.splitText(match[1].length);
79
+
80
+ var wordClone = wordNode.cloneNode(true);
81
+ highlight.appendChild(wordClone);
82
+ wordNode.parentNode.replaceChild(highlight, wordNode);
83
+ return 1; //skip added node in parent
84
+ }
85
+ } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
86
+ !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
87
+ !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
88
+ for (var i = 0; i < node.childNodes.length; i++) {
89
+ i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
90
+ }
65
91
  }
92
+ return 0;
66
93
  }
67
- return 0;
68
- }
69
- });
94
+ });
70
95
 
71
- jQuery.fn.unhighlight = function (options) {
72
- var settings = { className: 'highlight', element: 'span' };
73
- jQuery.extend(settings, options);
96
+ jQuery.fn.unhighlight = function (options) {
97
+ var settings = {
98
+ className: 'highlight',
99
+ element: 'span'
100
+ };
74
101
 
75
- return this.find(settings.element + "." + settings.className).each(function () {
76
- var parent = this.parentNode;
77
- parent.replaceChild(this.firstChild, this);
78
- parent.normalize();
79
- }).end();
80
- };
102
+ jQuery.extend(settings, options);
81
103
 
82
- jQuery.fn.highlight = function (words, options) {
83
- var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
84
- jQuery.extend(settings, options);
85
-
86
- if (words.constructor === String) {
87
- words = [words];
88
- }
89
- words = jQuery.grep(words, function(word, i){
90
- return word != '';
91
- });
92
- words = jQuery.map(words, function(word, i) {
93
- return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
94
- });
95
- if (words.length == 0) { return this; };
104
+ return this.find(settings.element + '.' + settings.className).each(function () {
105
+ var parent = this.parentNode;
106
+ parent.replaceChild(this.firstChild, this);
107
+ parent.normalize();
108
+ }).end();
109
+ };
96
110
 
97
- var flag = settings.caseSensitive ? "" : "i";
98
- var pattern = "(" + words.join("|") + ")";
99
- if (settings.wordsOnly) {
100
- pattern = "\\b" + pattern + "\\b";
101
- }
102
- var re = new RegExp(pattern, flag);
103
-
104
- return this.each(function () {
105
- jQuery.highlight(this, re, settings.element, settings.className);
106
- });
107
- };
111
+ jQuery.fn.highlight = function (words, options) {
112
+ var settings = {
113
+ className: 'highlight',
114
+ element: 'span',
115
+ caseSensitive: false,
116
+ wordsOnly: false,
117
+ wordsBoundary: '\\b'
118
+ };
108
119
 
120
+ jQuery.extend(settings, options);
121
+
122
+ if (typeof words === 'string') {
123
+ words = [words];
124
+ }
125
+ words = jQuery.grep(words, function(word, i){
126
+ return word != '';
127
+ });
128
+ words = jQuery.map(words, function(word, i) {
129
+ return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
130
+ });
131
+
132
+ if (words.length === 0) {
133
+ return this;
134
+ };
135
+
136
+ var flag = settings.caseSensitive ? '' : 'i';
137
+ // The capture parenthesis will make sure we can match
138
+ // only the matching word
139
+ var pattern = '(' + words.join('|') + ')';
140
+ if (settings.wordsOnly) {
141
+ pattern = settings.wordsBoundary + pattern + settings.wordsBoundary;
142
+ }
143
+ var re = new RegExp(pattern, flag);
144
+
145
+ return this.each(function () {
146
+ jQuery.highlight(this, re, settings.element, settings.className);
147
+ });
148
+ };
149
+ }));