hydra-collections 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.gitmodules +4 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +16 -0
  7. data/Gemfile +12 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +133 -0
  10. data/Rakefile +12 -0
  11. data/app/assets/javascripts/hydra/batch_select.js +41 -0
  12. data/app/assets/javascripts/hydra_collections.js +12 -0
  13. data/app/controllers/collections_controller.rb +18 -0
  14. data/app/helpers/batch_select_helper.rb +25 -0
  15. data/app/helpers/collections_helper.rb +14 -0
  16. data/app/models/collection.rb +16 -0
  17. data/app/views/batch_select/_add_button.html.erb +3 -0
  18. data/app/views/batch_select/_check_all.html.erb +4 -0
  19. data/app/views/batch_select/_tools.html.erb +10 -0
  20. data/app/views/collections/_button_create_collection.html.erb +2 -0
  21. data/app/views/collections/_form.html.erb +36 -0
  22. data/app/views/collections/_form_for_select_collection.html.erb +13 -0
  23. data/app/views/collections/new.html.erb +3 -0
  24. data/app/views/collections/show.html.erb +9 -0
  25. data/config/jetty.yml +6 -0
  26. data/config/routes.rb +3 -0
  27. data/fedora_conf/conf/development/fedora.fcfg +946 -0
  28. data/fedora_conf/conf/test/fedora.fcfg +946 -0
  29. data/hydra-collections.gemspec +27 -0
  30. data/lib/hydra-collections.rb +7 -0
  31. data/lib/hydra/collection.rb +52 -0
  32. data/lib/hydra/collections.rb +12 -0
  33. data/lib/hydra/collections/accepts_batches.rb +55 -0
  34. data/lib/hydra/collections/collectible.rb +24 -0
  35. data/lib/hydra/collections/search_service.rb +58 -0
  36. data/lib/hydra/collections/version.rb +5 -0
  37. data/lib/hydra/collections_controller_behavior.rb +108 -0
  38. data/lib/hydra/datastreams/collection_rdf_datastream.rb +36 -0
  39. data/solr_conf/conf/schema.xml +372 -0
  40. data/solr_conf/conf/solrconfig.xml +163 -0
  41. data/solr_conf/solr.xml +35 -0
  42. data/spec/controllers/accepts_batches_spec.rb +72 -0
  43. data/spec/controllers/collections_controller_spec.rb +93 -0
  44. data/spec/factories.rb +18 -0
  45. data/spec/factories/.gitkeep +0 -0
  46. data/spec/factories/users.rb +31 -0
  47. data/spec/helpers/collections_helper_spec.rb +29 -0
  48. data/spec/lib/collectible_spec.rb +31 -0
  49. data/spec/lib/search_service_spec.rb +41 -0
  50. data/spec/models/collection_spec.rb +100 -0
  51. data/spec/spec_helper.rb +24 -0
  52. data/spec/support/Gemfile +19 -0
  53. data/spec/support/app/models/sample.rb +37 -0
  54. data/spec/support/app/models/solr_document.rb +5 -0
  55. data/spec/support/app/views/catalog/_document_header.html.erb +11 -0
  56. data/spec/support/app/views/catalog/_sort_and_per_page.html.erb +20 -0
  57. data/spec/support/config/initializers/hydra_config.rb +28 -0
  58. data/spec/support/db/migrate/20111101221803_create_searches.rb +16 -0
  59. data/spec/support/lib/generators/test_app_generator.rb +54 -0
  60. data/spec/support/lib/tasks/rspec.rake +9 -0
  61. data/tasks/hydra-collections-dev.rake +68 -0
  62. data/tasks/jetty.rake +40 -0
  63. metadata +194 -0
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+ class CollectibleThing < ActiveFedora::Base
3
+ include Hydra::Collections::Collectible
4
+ end
5
+
6
+ describe Hydra::Collections::Collectible do
7
+ before do
8
+ @collection1 = FactoryGirl.create(:collection)
9
+ @collection2 = FactoryGirl.create(:collection)
10
+ @collectible = CollectibleThing.new
11
+ end
12
+ describe "collections associations" do
13
+ it "should allow adding and removing" do
14
+ @collectible.save
15
+ @collection1.members << @collectible
16
+ @collection1.save
17
+ @collectible.collections << @collection2
18
+ reloaded = CollectibleThing.find(@collectible.pid)
19
+ @collection2.members.should == [@collectible]
20
+ reloaded.collections.should == [@collection1, @collection2]
21
+ end
22
+ end
23
+ describe "index_collection_pids" do
24
+ it "should add pids for all associated collections" do
25
+ @collectible.save
26
+ @collectible.collections << @collection1
27
+ @collectible.collections << @collection2
28
+ @collectible.index_collection_pids["collection_sim"].should == [@collection1.pid, @collection2.pid]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::Collections::SearchService do
4
+ before do
5
+ @login = 'vanessa'
6
+ @session = {:history => [17, 14, 12, 9]}
7
+ @service = Hydra::Collections::SearchService.new(@session, @login)
8
+ end
9
+
10
+ it "should get the documents for the first history entry" do
11
+ Search.should_receive(:find).with(17).and_return(Search.new(:query_params=>{:q=>"World Peace"}))
12
+ @service.should_receive(:get_search_results).and_return([:one, [:doc1, :doc2]])
13
+ @service.last_search_documents.should == [:doc1, :doc2]
14
+ end
15
+
16
+ describe 'apply_gated_search' do
17
+ before(:each) do
18
+ RoleMapper.stub(:roles).with(@login).and_return(['umg/test.group.1'])
19
+ params = @service.apply_gated_search({}, {})
20
+ @group_query = params[:fq].first.split(' OR ')[1]
21
+ end
22
+ it "should escape slashes in groups" do
23
+ @group_query.should == 'edit_access_group_ssim:umg\/test.group.1'
24
+ end
25
+ it "should allow overriding Solr's access control suffix" do
26
+ module Hydra
27
+ module Collections
28
+ class SearchService
29
+ def solr_access_control_suffix(key)
30
+ "edit_#{key}_customfield"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ @service = Hydra::Collections::SearchService.new({}, '')
36
+ params = @service.apply_gated_search({}, {})
37
+ @public_query = params[:fq].first.split(' OR ')[0]
38
+ @public_query.should == 'edit_group_customfield:public'
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,100 @@
1
+ # Copyright © 2013 The Pennsylvania State University
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ describe Collection do
18
+ before(:all) do
19
+ @user = FactoryGirl.find_or_create(:user)
20
+ class GenericFile < ActiveFedora::Base
21
+ end
22
+ end
23
+ after(:all) do
24
+ @user.destroy
25
+ Object.send(:remove_const, :GenericFile)
26
+ end
27
+ before(:each) do
28
+ @collection = Collection.new
29
+ @collection.apply_depositor_metadata(@user.user_key)
30
+ @collection.save
31
+ @gf1 = GenericFile.create
32
+ @gf2 = GenericFile.create
33
+ end
34
+ after(:each) do
35
+ @collection.destroy rescue
36
+ @gf1.destroy
37
+ @gf2.destroy
38
+ end
39
+ it "should have a depositor" do
40
+ @collection.depositor.should == @user.user_key
41
+ end
42
+ it "should allow the depositor to edit and read" do
43
+ ability = Ability.new(@user)
44
+ ability.can?(:read, @collection).should == true
45
+ ability.can?(:edit, @collection).should == true
46
+ end
47
+ it "should be empty by default" do
48
+ @collection.members.should be_empty
49
+ end
50
+ it "should have many files" do
51
+ @collection.members = [@gf1, @gf2]
52
+ @collection.save
53
+ Collection.find(@collection.pid).members.should == [@gf1, @gf2]
54
+ end
55
+ it "should allow new files to be added" do
56
+ @collection.members = [@gf1]
57
+ @collection.save
58
+ @collection = Collection.find(@collection.pid)
59
+ @collection.members << @gf2
60
+ @collection.save
61
+ Collection.find(@collection.pid).members.should == [@gf1, @gf2]
62
+ end
63
+ it "should set the date uploaded on create" do
64
+ @collection.save
65
+ @collection.date_uploaded.should be_kind_of(Date)
66
+ end
67
+ it "should update the date modified on update" do
68
+ uploaded_date = Date.today
69
+ modified_date = Date.tomorrow
70
+ Date.stub(:today).and_return(uploaded_date, modified_date)
71
+ @collection.save
72
+ @collection.date_modified.should == uploaded_date
73
+ @collection.members = [@gf1]
74
+ @collection.save
75
+ @collection.date_modified.should == modified_date
76
+ end
77
+ it "should have a title" do
78
+ @collection.title = "title"
79
+ @collection.save
80
+ Collection.find(@collection.pid).title.should == @collection.title
81
+ end
82
+ it "should have a description" do
83
+ @collection.description = "description"
84
+ @collection.save
85
+ Collection.find(@collection.pid).description.should == @collection.description
86
+ end
87
+ it "should have the expected display terms" do
88
+ @collection.terms_for_display.should == [:title, :description, :date_uploaded, :date_modified]
89
+ end
90
+ it "should have the expected edit terms" do
91
+ @collection.terms_for_editing.should == [:title,:description]
92
+ end
93
+ it "should not delete member files when deleted" do
94
+ @collection.members = [@gf1, @gf2]
95
+ @collection.save
96
+ @collection.destroy
97
+ lambda {GenericFile.find(@gf1.pid)}.should_not raise_error ActiveFedora::ObjectNotFoundError
98
+ lambda {GenericFile.find(@gf2.pid)}.should_not raise_error ActiveFedora::ObjectNotFoundError
99
+ end
100
+ end
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ ENV["RAILS_ENV"] ||= 'test'
4
+
5
+ require File.expand_path("config/environment", ENV['RAILS_ROOT'] || File.expand_path("../internal", __FILE__))
6
+ require 'rspec/rails'
7
+ require 'hydra-collections'
8
+
9
+ FactoryGirl.definition_file_paths = [File.expand_path("../factories", __FILE__)]
10
+ FactoryGirl.find_definitions
11
+
12
+ RSpec.configure do |config|
13
+ config.use_transactional_fixtures = true
14
+ config.include Devise::TestHelpers, :type => :controller
15
+ config.before(:each, :type=>"controller") { @routes = Hydra::Collections::Engine.routes }
16
+ end
17
+
18
+ module FactoryGirl
19
+ def self.find_or_create(handle, by=:email)
20
+ tmpl = FactoryGirl.build(handle)
21
+ tmpl.class.send("find_by_#{by}".to_sym, tmpl.send(by)) || FactoryGirl.create(handle)
22
+ end
23
+ end
24
+
@@ -0,0 +1,19 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails'
4
+ gem 'sqlite3'
5
+ gem 'devise'
6
+ gem 'hydra-head'
7
+ gem 'hydra-collections', :path=>'../../'
8
+
9
+ gem 'rspec-rails'
10
+ gem 'factory_girl'
11
+
12
+ # Gems used only for assets and not required
13
+ # in production environments by default.
14
+ group :assets do
15
+ gem 'sass-rails', '~> 3.2.3'
16
+ gem 'coffee-rails', '~> 3.2.1'
17
+ gem 'jquery-rails'
18
+ gem 'uglifier', '>= 1.0.3'
19
+ end
@@ -0,0 +1,37 @@
1
+ class Sample
2
+ # This is a stub model for testing.
3
+
4
+ cattr_accessor :objects
5
+ self.objects = {}
6
+
7
+ def self.create(params={})
8
+ obj = Sample.new
9
+ obj.save
10
+ obj
11
+ end
12
+
13
+ def save()
14
+ @pid ||= "sample:#{(rand * 1000).to_i}"
15
+ self.class.objects[@pid] = self
16
+ end
17
+
18
+ def update_attributes(attributes)
19
+ attributes.each do |k, v|
20
+ instance_variable_set "@#{k.to_s}".to_sym, v
21
+
22
+ self.class.send :attr_accessor, k
23
+ end
24
+ end
25
+
26
+ def self.find(pid)
27
+ objects[pid]
28
+ end
29
+
30
+ def pid
31
+ @pid
32
+ end
33
+
34
+ def destroy
35
+ self.class.objects.delete(@pid)
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class SolrDocument
3
+
4
+ include Blacklight::Solr::Document
5
+ end
@@ -0,0 +1,11 @@
1
+
2
+ <% # header bar for doc items in index view -%>
3
+ <div class="documentHeader clearfix">
4
+ <%= button_for_add_to_batch(document) %>
5
+ <% # main title container for doc partial view -%>
6
+ <h5 class="index_title"><%= t('blacklight.search.documents.counter', :counter => (document_counter + 1 + @response.params[:start].to_i)) %><%= link_to_document document, :label=>document_show_link_field(document), :counter => (document_counter + 1 + @response.params[:start].to_i) %></h5>
7
+
8
+
9
+ <% # bookmark functions for items/docs -%>
10
+ <%= render_index_doc_actions document, :wrapping_class => "documentFunctions span2" %>
11
+ </div>
@@ -0,0 +1,20 @@
1
+ <div id="sortAndPerPage">
2
+ <div class="page_links">
3
+ <%= render :partial => "paginate_compact" %>
4
+ </div>
5
+ <%= render :partial => 'sort_widget' %>
6
+
7
+ <%= render :partial => 'per_page_widget' %>
8
+
9
+ <%= button_for_create_collection %>
10
+
11
+
12
+ <% c1 = Collection.new(title:"title1") %>
13
+ <% c1.apply_depositor_metadata("cam156@psu.edu") %>
14
+ <% c1.save %>
15
+ <% c2 = Collection.new(title:"title2") %>
16
+ <% c2.apply_depositor_metadata("cam156@psu.edu") %>
17
+ <% c2.save %>
18
+ <%= render partial: 'collections/form_for_select_collection', locals: {user_collections: [c1,c2]} %>
19
+
20
+ </div>
@@ -0,0 +1,28 @@
1
+ # The following lines determine which user attributes your hydrangea app will use
2
+ # This configuration allows you to use the out of the box ActiveRecord associations between users and user_attributes
3
+ # It also allows you to specify your own user attributes
4
+ # The easiest way to override these methods would be to create your own module to include in User
5
+ # For example you could create a module for your local LDAP instance called MyLocalLDAPUserAttributes:
6
+ # User.send(:include, MyLocalLDAPAttributes)
7
+ # As long as your module includes methods for full_name, affiliation, and photo the personalization_helper should function correctly
8
+ #
9
+
10
+ # windows doesn't properly require hydra-head (from the gemfile), so we need to require it explicitly here:
11
+ require 'hydra/head' unless defined? Hydra
12
+
13
+ if Hydra.respond_to?(:configure)
14
+ Hydra.configure(:shared) do |config|
15
+ # This specifies the solr field names of permissions-related fields.
16
+ # You only need to change these values if you've indexed permissions by some means other than the Hydra's built-in tooling.
17
+ # If you change these, you must also update the permissions request handler in your solrconfig.xml to return those values
18
+ indexer = Solrizer::Descriptor.new(:string, :stored, :indexed, :multivalued)
19
+ config[:permissions] = {
20
+ :discover => {:group =>ActiveFedora::SolrService.solr_name("discover_access_group", indexer), :individual=>ActiveFedora::SolrService.solr_name("discover_access_person", indexer)},
21
+ :read => {:group =>ActiveFedora::SolrService.solr_name("read_access_group", indexer), :individual=>ActiveFedora::SolrService.solr_name("read_access_person", indexer)},
22
+ :edit => {:group =>ActiveFedora::SolrService.solr_name("edit_access_group", indexer), :individual=>ActiveFedora::SolrService.solr_name("edit_access_person", indexer)},
23
+ :owner => ActiveFedora::SolrService.solr_name("depositor", indexer),
24
+ :embargo_release_date => ActiveFedora::SolrService.solr_name("embargo_release_date", Solrizer::Descriptor.new(:date, :stored, :indexed))
25
+ }
26
+
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class CreateSearches < ActiveRecord::Migration
3
+ def self.up
4
+ create_table :searches do |t|
5
+ t.text :query_params
6
+ t.integer :user_id
7
+
8
+ t.timestamps
9
+ end
10
+ add_index :searches, :user_id
11
+ end
12
+
13
+ def self.down
14
+ drop_table :searches
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ require 'rails/generators'
2
+
3
+ class TestAppGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../../../../support", __FILE__)
5
+
6
+ def run_blacklight_generator
7
+ say_status("warning", "GENERATING BL", :yellow)
8
+
9
+ generate 'blacklight', '--devise'
10
+ end
11
+
12
+ def run_hydra_head_generator
13
+ say_status("warning", "GENERATING HH", :yellow)
14
+
15
+ generate 'hydra:head', '-f'
16
+ end
17
+
18
+ def run_migrations
19
+ rake("db:migrate")
20
+ end
21
+
22
+ # Inject call to Hydra::Collections.add_routes in config/routes.rb
23
+ def inject_routes
24
+ insert_into_file "config/routes.rb", :after => '.draw do' do
25
+ "\n # Add Collections routes."
26
+ "\n mount Hydra::Collections::Engine => '/'"
27
+ end
28
+ end
29
+
30
+ def copy_rspec_rake_task
31
+ copy_file "lib/tasks/rspec.rake"
32
+ end
33
+
34
+ def copy_hydra_config
35
+ copy_file "config/initializers/hydra_config.rb"
36
+ end
37
+
38
+ def delete_generated_noise
39
+ remove_file("public/index.html")
40
+ remove_file("spec/models/user_spec.rb")
41
+ end
42
+
43
+ def copy_view_overrides
44
+ directory("app/views/catalog")
45
+ end
46
+
47
+ # Inject call to Hydra::Collections.add_routes in config/routes.rb
48
+ def inject_javascript
49
+ insert_into_file "app/assets/javascripts/application.js", :after => '/= require_tree .' do
50
+ "\n #include javascript for batches and collections\n//= require hydra/batch_select\n//= require hydra_collections"
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec/core/rake_task'
2
+ desc "run the hydra-collections gem spec"
3
+ gem_home = File.expand_path('../../../../..', __FILE__)
4
+ RSpec::Core::RakeTask.new(:myspec) do |t|
5
+ t.pattern = gem_home + '/spec/**/*_spec.rb'
6
+ t.rspec_opts = "--colour"
7
+ t.ruby_opts = "-I#{gem_home}/spec"
8
+ end
9
+
@@ -0,0 +1,68 @@
1
+ require 'rspec/core'
2
+ require 'rspec/core/rake_task'
3
+ APP_ROOT="." # for jettywrapper
4
+ require 'jettywrapper'
5
+ ENV["RAILS_ROOT"] ||= 'spec/internal'
6
+
7
+ desc 'Spin up hydra-jetty and run specs'
8
+ task :ci => ['jetty:config'] do
9
+ puts 'running continuous integration'
10
+ jetty_params = Jettywrapper.load_config
11
+ error = Jettywrapper.wrap(jetty_params) do
12
+ Rake::Task['spec'].invoke
13
+ end
14
+ raise "test failures: #{error}" if error
15
+ end
16
+
17
+ desc "Run specs"
18
+ # Note: this is _not_ an RSpec::Core::RakeTask.
19
+ # It's a regular rake task that calls the RSpec RakeTask that's defined in spec/support/lib/tasks/rspec.rake
20
+ task :spec => [:generate] do |t|
21
+ focused_spec = ENV['SPEC'] ? " SPEC=#{File.join(GEM_ROOT, ENV['SPEC'])}" : ''
22
+ within_test_app do
23
+ system "rake myspec#{focused_spec}"
24
+ abort "Error running hydra-collections" unless $?.success?
25
+ end
26
+ end
27
+
28
+ desc "Create the test rails app"
29
+ task :generate do
30
+ unless File.exists?('spec/internal/Rakefile')
31
+ puts "Generating rails app"
32
+ `rails new spec/internal`
33
+ puts "Copying gemfile"
34
+ `cp spec/support/Gemfile spec/internal`
35
+ puts "Copying generator"
36
+ `cp -r spec/support/lib/generators spec/internal/lib`
37
+ Bundler.with_clean_env do
38
+ within_test_app do
39
+ puts "Bundle install"
40
+ `bundle install`
41
+ puts "running test_app_generator"
42
+ system "rails generate test_app"
43
+
44
+ puts "running migrations"
45
+ puts `rake db:migrate db:test:prepare`
46
+ end
47
+ end
48
+ end
49
+ puts "Done generating test app"
50
+ end
51
+
52
+ desc "Clean out the test rails app"
53
+ task :clean do
54
+ puts "Removing sample rails app"
55
+ `rm -rf spec/internal`
56
+ end
57
+
58
+ def within_test_app
59
+ FileUtils.cd('spec/internal')
60
+ yield
61
+ FileUtils.cd('../..')
62
+ end
63
+
64
+ namespace :meme do
65
+ desc "configure jetty to generate checksums"
66
+ task :config do
67
+ end
68
+ end