active-fedora 11.1.6 → 11.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4288e97d72b9829adfa9892a3013ddc587624bc
4
- data.tar.gz: 78a3834e826d71206fae523c8c70c48538bc3f0c
3
+ metadata.gz: b5718b93144050d065de0a17b2a483d64227f43b
4
+ data.tar.gz: 69c0d340816d9fe60d9eab9304464c020879ad07
5
5
  SHA512:
6
- metadata.gz: 2b0fbfc067535245ae40b410fcc8641b4a042c84c2d07ae248225cb2998ed2dc4728d2dcfef81f8cb5540771c2afd7578bdb5c8584e9e438ee4725bb9289c610
7
- data.tar.gz: 3111010745fb585c75009fd10e7d221e6339c588fa907374966186641135d5f21114b10680cccd0844a7de1b89f57ca3da35ef0ed605a8bb81e924afbe6f42b1
6
+ metadata.gz: 96f4efe5a38cbb1e4a1e577defd7373fa9ca2b85e5f08d5b0a4bfb1376915e2c98d5b2b1b95d211a51316d1acff74676aee9cae932716687c4f4a0f2f2242c20
7
+ data.tar.gz: 05abe1815355410f735cc17f2c283d1961a567e0b565deac21f59124c7f5974b5ab2d78639d44c782f9658fee9dc81f68c8fda27dea367d0b9afff5355628c29
@@ -1,12 +1,12 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  sudo: false
4
- rvm: 2.4.0
4
+ rvm: 2.4.1
5
5
  matrix:
6
6
  include:
7
- - rvm: 2.3.3
8
- env: "RAILS_VERSION=4.2.7.1"
9
- - env: "RSOLR_VERSION=2.0.0.pre1"
7
+ - rvm: 2.3.4
8
+ env: "RAILS_VERSION=4.2.8"
9
+ - env: "RSOLR_VERSION=2.0.1"
10
10
  global_env:
11
11
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
12
12
  before_install:
@@ -21,12 +21,13 @@ Gem::Specification.new do |s|
21
21
  s.add_dependency "active-triples", '~> 0.11.0'
22
22
  s.add_dependency "deprecation"
23
23
  s.add_dependency "ldp", '~> 0.6.0'
24
+ s.add_dependency "ruby-progressbar", '~> 1.0'
24
25
 
25
26
  s.add_development_dependency "rails"
26
27
  s.add_development_dependency "rdoc"
27
28
  s.add_development_dependency "yard"
28
29
  s.add_development_dependency "rake"
29
- s.add_development_dependency "solr_wrapper", "~> 0.15"
30
+ s.add_development_dependency "solr_wrapper", "~> 1.0"
30
31
  s.add_development_dependency 'fcrepo_wrapper', '~> 0.2'
31
32
  s.add_development_dependency "rspec", "~> 3.0"
32
33
  s.add_development_dependency "rspec-its"
@@ -40,7 +40,7 @@ module ActiveFedora
40
40
  id = ActiveFedora::Associations::IDComposite.new([identifier], translate_uri_to_id).first
41
41
  @ldp_source = build_ldp_resource id
42
42
  else
43
- raise "The first argument to #{self} must be a Hash, String or RDF::URI. You provided a #{uri.class}"
43
+ raise "The first argument to #{self} must be a Hash, String or RDF::URI. You provided a #{identifier.class}"
44
44
  end
45
45
 
46
46
  @attributes = {}.with_indifferent_access
@@ -108,7 +108,7 @@ module ActiveFedora
108
108
  end
109
109
 
110
110
  begin
111
- fedora_yml = YAML.safe_load(config_erb)
111
+ fedora_yml = YAML.safe_load(config_erb, [], [], true) # allow YAML aliases
112
112
  rescue Psych::SyntaxError => e
113
113
  raise "fedora.yml was found, but could not be parsed. " \
114
114
  "Error #{e.message}"
@@ -132,7 +132,7 @@ module ActiveFedora
132
132
  end
133
133
 
134
134
  begin
135
- solr_yml = YAML.safe_load(config_erb)
135
+ solr_yml = YAML.safe_load(config_erb, [], [], true) # allow YAML aliases
136
136
  rescue StandardError
137
137
  raise("solr.yml was found, but could not be parsed.\n")
138
138
  end
@@ -2,26 +2,57 @@ module ActiveFedora
2
2
  class FixityService
3
3
  extend ActiveSupport::Concern
4
4
 
5
- attr_accessor :target, :response
5
+ attr_accessor :target
6
6
 
7
- # @param [String, RDF::URI] target url for a Fedora resource
7
+ # @param [String, RDF::URI] target url for a Fedora resource.
8
8
  def initialize(target)
9
9
  raise ArgumentError, 'You must provide a uri' unless target
10
10
  @target = target.to_s
11
11
  end
12
12
 
13
- # Executes a fixity check on Fedora and saves the Faraday::Response.
13
+ def response
14
+ @response ||= fixity_response_from_fedora
15
+ end
16
+
17
+ # For backwards compat, check always insists on doing a new request.
18
+ # you might want verified? instead which uses a cached request.
14
19
  # @return true or false
15
20
  def check
16
- @response = fixity_response_from_fedora
21
+ @response = nil
22
+ verified?
23
+ end
24
+
25
+ # Executes a fixity check on Fedora
26
+ # @return true or false
27
+ def verified?
17
28
  status.include?(success)
18
29
  end
19
30
 
31
+ # An array of 1 or more literals reported by Fedora.
32
+ # See 'success' for which one indicates fixity check is good.
20
33
  def status
21
34
  fixity_graph.query(predicate: premis_status_predicate).map(&:object) +
22
35
  fixity_graph.query(predicate: fedora_status_predicate).map(&:object)
23
36
  end
24
37
 
38
+ # the currently calculated checksum, as a string URI, like
39
+ # "urn:sha1:09a848b79f86f3a4f3f301b8baafde455d6f8e0e"
40
+ def expected_message_digest
41
+ fixity_graph.query(predicate: ::RDF::Vocab::PREMIS.hasMessageDigest).first.try(:object).try(:to_s)
42
+ end
43
+
44
+ # integer, as reported by fedora. bytes maybe?
45
+ def expected_size
46
+ fixity_graph.query(predicate: ::RDF::Vocab::PREMIS.hasSize).first.try(:object).try(:to_s).try(:to_i)
47
+ end
48
+
49
+ # Fedora response as an ::RDF::Graph object. Public API, so consumers
50
+ # can do with it what they will, especially if future fedora versions
51
+ # add more things to it.
52
+ def response_graph
53
+ fixity_graph
54
+ end
55
+
25
56
  private
26
57
 
27
58
  def premis_status_predicate
@@ -46,7 +77,7 @@ module ActiveFedora
46
77
  end
47
78
 
48
79
  def fixity_graph
49
- ::RDF::Graph.new << ::RDF::Reader.for(:ttl).new(response.body)
80
+ @fixity_graph ||= ::RDF::Graph.new << ::RDF::Reader.for(:ttl).new(response.body)
50
81
  end
51
82
 
52
83
  # See https://jira.duraspace.org/browse/FCREPO-1247
@@ -13,6 +13,7 @@ module ActiveFedora
13
13
 
14
14
  eager_autoload do
15
15
  autoload :Map
16
+ autoload :DescendantFetcher
16
17
  end
17
18
 
18
19
  included do
@@ -82,26 +83,44 @@ module ActiveFedora
82
83
  end
83
84
  end
84
85
 
85
- def reindex_everything
86
- descendants = descendant_uris(ActiveFedora.fedora.base_uri)
87
- descendants.shift # Discard the root uri
86
+ # @param [Integer] batch_size - The number of Fedora objects to process for each SolrService.add call. Default 50.
87
+ # @param [Boolean] softCommit - Do we perform a softCommit when we add the to_solr objects to SolrService. Default true.
88
+ # @param [Boolean] progress_bar - If true output progress bar information. Default false.
89
+ # @param [Boolean] final_commit - If true perform a hard commit to the Solr service at the completion of the batch of updates. Default false.
90
+ def reindex_everything(batch_size: 50, softCommit: true, progress_bar: false, final_commit: false)
91
+ # skip root url
92
+ descendants = descendant_uris(ActiveFedora.fedora.base_uri, exclude_uri: true)
93
+
94
+ batch = []
95
+
96
+ progress_bar_controller = ProgressBar.create(total: descendants.count, format: "%t: |%B| %p%% %e") if progress_bar
97
+
88
98
  descendants.each do |uri|
89
99
  logger.debug "Re-index everything ... #{uri}"
90
- ActiveFedora::Base.find(ActiveFedora::Base.uri_to_id(uri)).update_index
100
+
101
+ batch << ActiveFedora::Base.find(ActiveFedora::Base.uri_to_id(uri)).to_solr
102
+
103
+ if (batch.count % batch_size).zero?
104
+ SolrService.add(batch, softCommit: softCommit)
105
+ batch.clear
106
+ end
107
+
108
+ progress_bar_controller.increment if progress_bar_controller
109
+ end
110
+
111
+ if batch.present?
112
+ SolrService.add(batch, softCommit: softCommit)
113
+ batch.clear
91
114
  end
92
- end
93
115
 
94
- def descendant_uris(uri)
95
- resource = Ldp::Resource::RdfSource.new(ActiveFedora.fedora.connection, uri)
96
- # GET could be slow if it's a big resource, we're using HEAD to avoid this problem,
97
- # but this causes more requests to Fedora.
98
- return [] unless resource.head.rdf_source?
99
- immediate_descendant_uris = resource.graph.query(predicate: ::RDF::Vocab::LDP.contains).map { |descendant| descendant.object.to_s }
100
- all_descendants_uris = [uri]
101
- immediate_descendant_uris.each do |descendant_uri|
102
- all_descendants_uris += descendant_uris(descendant_uri)
116
+ if final_commit
117
+ logger.debug "Solr hard commit..."
118
+ SolrService.commit
103
119
  end
104
- all_descendants_uris
120
+ end
121
+
122
+ def descendant_uris(uri, exclude_uri: false)
123
+ DescendantFetcher.new(uri, exclude_self: exclude_uri).descendant_and_self_uris
105
124
  end
106
125
  end
107
126
  end
@@ -0,0 +1,101 @@
1
+ module ActiveFedora
2
+ module Indexing
3
+ # Finds all descendent URIs of a given repo URI (usually the base URI).
4
+ #
5
+ # This is a slow and non-performant thing to do, we need to fetch every single
6
+ # object from the repo.
7
+ #
8
+ # The DescendantFetcher is also capable of partitioning the URIs into "priority" URIs
9
+ # that will be first in the returned list. These prioritized URIs belong to objects
10
+ # with certain hasModel models. This feature is used in some hydra apps that need to
11
+ # index 'permissions' objects before other objects to have the solr indexing work right.
12
+ # And so by default, the prioritized class names are the ones form Hydra::AccessControls,
13
+ # but you can alter the prioritized model name list, or set it to the empty array.
14
+ #
15
+ # DescendantFetcher.new(ActiveFedora.fedora.base_uri).descendent_and_self_uris
16
+ # #=> array including self uri and descendent uris with "prioritized" (by default)
17
+ # Hydra::AccessControls permissions) objects FIRST.
18
+ #
19
+ # Change the default prioritized hasModel names:
20
+ #
21
+ # ActiveFedora::Indexing::DescendantFetcher.default_priority_models = []
22
+ class DescendantFetcher
23
+ HAS_MODEL_PREDICATE = ActiveFedora::RDF::Fcrepo::Model.hasModel
24
+
25
+ class_attribute :default_priority_models, instance_accessor: false
26
+ self.default_priority_models = %w(Hydra::AccessControl Hydra::AccessControl::Permissions).freeze
27
+
28
+ attr_reader :uri, :priority_models
29
+
30
+ def initialize(uri,
31
+ priority_models: self.class.default_priority_models, exclude_self: false)
32
+ @uri = uri
33
+ @priority_models = priority_models
34
+ @exclude_self = exclude_self
35
+ end
36
+
37
+ def descendant_and_self_uris
38
+ partitioned = descendant_and_self_uris_partitioned
39
+ partitioned[:priority] + partitioned[:other]
40
+ end
41
+
42
+ # returns a hash where key :priority is an array of all prioritized
43
+ # type objects, key :other is an array of the rest.
44
+ def descendant_and_self_uris_partitioned
45
+ resource = Ldp::Resource::RdfSource.new(ActiveFedora.fedora.connection, uri)
46
+ # GET could be slow if it's a big resource, we're using HEAD to avoid this problem,
47
+ # but this causes more requests to Fedora.
48
+ return partitioned_uris unless resource.head.rdf_source?
49
+
50
+ add_self_to_partitioned_uris unless @exclude_self
51
+
52
+ immediate_descendant_uris = rdf_graph.query(predicate: ::RDF::Vocab::LDP.contains).map { |descendant| descendant.object.to_s }
53
+ immediate_descendant_uris.each do |descendant_uri|
54
+ self.class.new(
55
+ descendant_uri,
56
+ priority_models: priority_models
57
+ ).descendant_and_self_uris_partitioned.tap do |descendant_partitioned|
58
+ partitioned_uris[:priority].concat descendant_partitioned[:priority]
59
+ partitioned_uris[:other].concat descendant_partitioned[:other]
60
+ end
61
+ end
62
+ partitioned_uris
63
+ end
64
+
65
+ protected
66
+
67
+ def rdf_resource
68
+ @rdf_resource ||= Ldp::Resource::RdfSource.new(ActiveFedora.fedora.connection, uri)
69
+ end
70
+
71
+ def rdf_graph
72
+ @rdf_graph ||= rdf_resource.graph
73
+ end
74
+
75
+ def partitioned_uris
76
+ @partitioned_uris ||= {
77
+ priority: [],
78
+ other: []
79
+ }
80
+ end
81
+
82
+ def rdf_graph_models
83
+ rdf_graph.query(predicate: HAS_MODEL_PREDICATE).collect(&:object).collect do |rdf_object|
84
+ rdf_object.to_s if rdf_object.literal?
85
+ end.compact
86
+ end
87
+
88
+ def prioritized_object?
89
+ priority_models.present? && (rdf_graph_models & priority_models).count > 0
90
+ end
91
+
92
+ def add_self_to_partitioned_uris
93
+ if prioritized_object?
94
+ partitioned_uris[:priority] << rdf_resource.subject
95
+ else
96
+ partitioned_uris[:other] << rdf_resource.subject
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -11,7 +11,15 @@ module ActiveFedora::Indexing
11
11
  end
12
12
 
13
13
  def dup
14
- self.class.new(@hash.deep_dup)
14
+ self.class.new(to_hash)
15
+ end
16
+
17
+ def merge(new_hash)
18
+ self.class.new(to_hash.merge(new_hash))
19
+ end
20
+
21
+ def to_hash
22
+ @hash.deep_dup
15
23
  end
16
24
 
17
25
  # this enables a cleaner API for solr integration
@@ -19,8 +27,8 @@ module ActiveFedora::Indexing
19
27
  attr_accessor :data_type, :behaviors, :term
20
28
  attr_reader :key
21
29
 
22
- def initialize(name, &_block)
23
- @behaviors = []
30
+ def initialize(name, behaviors: [], &_block)
31
+ @behaviors = behaviors
24
32
  @data_type = :string
25
33
  @key = name
26
34
  yield self if block_given?
@@ -61,7 +61,12 @@ module ActiveFedora
61
61
  # Serialize the resource's RDF relationships to solr
62
62
  # @param [Hash] solr_doc @deafult an empty Hash
63
63
  def solrize_rdf_assertions(solr_doc = {})
64
- solr_doc.merge rdf_service.new(object).generate_solr_document
64
+ solr_doc.merge rdf_indexer.generate_solr_document
65
+ end
66
+
67
+ # @return IndexingService
68
+ def rdf_indexer
69
+ rdf_service.new(object, object.class.index_config)
65
70
  end
66
71
  end
67
72
  end
@@ -15,8 +15,8 @@ module ActiveFedora::RDF
15
15
 
16
16
  # Inserts each solr field map configuration into the FieldMap class
17
17
  # @param [Symbol] name the name of the property on the object that we're indexing
18
- # @param [Object] index_field_config an instance of ActiveFedora::Indexing::Map::IndexObject
19
- # @param [Object] object the instance of ActiveFedora::Base which is being indexed into Solr
18
+ # @param [ActiveFedora::Indexing::Map::IndexObject] index_field_config describes how the object should be indexed
19
+ # @param [ActiveFedora::Base] object the object to be indexed into Solr
20
20
  def insert(name, index_field_config, object)
21
21
  self[index_field_config.key.to_s] ||= FieldMapEntry.new
22
22
  PolymorphicBuilder.new(self[index_field_config.key.to_s], index_field_config, object, name).build
@@ -3,9 +3,10 @@ module ActiveFedora::RDF
3
3
  # It might be possible for two properties to share a single field map entry if they use the same solr key.
4
4
  # @attribute [Symbol] type the data type hint for Solrizer
5
5
  # @attribute [Array] behaviors the indexing hints such as :stored_searchable or :symbol
6
- # @attribute [Array] values the actual values that get sent to solr
6
+ # @!attribute [w] values the raw values
7
7
  class FieldMapEntry
8
- attr_accessor :type, :behaviors, :values
8
+ attr_accessor :type, :behaviors
9
+ attr_writer :values
9
10
 
10
11
  def initialize
11
12
  @behaviors = []
@@ -15,14 +16,15 @@ module ActiveFedora::RDF
15
16
  # Merges any existing values for solr fields with new, incoming values and ensures that resulting values are unique.
16
17
  # @param [Symbol] type the data type for the field such as :string, :date, :integer
17
18
  # @param [Array] behaviors Solrizer's behaviors for indexing such as :stored_searhable, :symbol
18
- # @param [Array] values existing values for the solr field
19
- def merge!(type, behaviors, values)
19
+ # @param [Array] new_values values to append into the existing solr field
20
+ def merge!(type, behaviors, new_values)
20
21
  self.type ||= type
21
22
  self.behaviors += behaviors
22
23
  self.behaviors.uniq!
23
- self.values += values
24
+ self.values += new_values
24
25
  end
25
26
 
27
+ # @return [Array] the actual values that get sent to solr
26
28
  def values
27
29
  @values.map do |value|
28
30
  ValueCaster.new(value).value
@@ -6,11 +6,17 @@ module ActiveFedora::RDF
6
6
  # @see ActiveFedora::IndexingService
7
7
  class IndexingService
8
8
  include Solrizer::Common
9
- attr_reader :object
9
+ attr_reader :object, :index_config
10
10
 
11
- # @param [#resource, #rdf_subject] obj the object to build an solr document for. Its class must respond to 'properties' and 'index_config'
12
- def initialize(obj)
11
+ # @param [#resource, #rdf_subject] obj the object to build an solr document for. Its class must respond to 'properties'
12
+ # @param [ActiveFedora::Indexing::Map] index_config the configuration to use to map object values to index document values
13
+ def initialize(obj, index_config = nil)
14
+ unless index_config
15
+ Deprecation.warn(self, "initializing ActiveFedora::RDF::IndexingService without an index_config is deprecated and will be removed in ActiveFedora 13.0")
16
+ index_config = obj.class.index_config
17
+ end
13
18
  @object = obj
19
+ @index_config = index_config
14
20
  end
15
21
 
16
22
  # Creates a solr document hash for the rdf assertions of the {#object}
@@ -69,10 +75,6 @@ module ActiveFedora::RDF
69
75
  object.resource
70
76
  end
71
77
 
72
- def index_config
73
- object.class.index_config
74
- end
75
-
76
78
  # returns the field map instance
77
79
  def fields
78
80
  field_map_class.new do |field_map|
@@ -2,6 +2,7 @@ require 'rsolr'
2
2
 
3
3
  module ActiveFedora
4
4
  class SolrService
5
+ attr_reader :options
5
6
  attr_writer :conn
6
7
 
7
8
  MAX_ROWS = 10_000
@@ -64,7 +65,7 @@ module ActiveFedora
64
65
  SolrService.get(query, args)['response']['numFound'].to_i
65
66
  end
66
67
 
67
- # @param [Hash] doc the document to index
68
+ # @param [Hash] doc the document to index, or an array of docs
68
69
  # @param [Hash] params
69
70
  # :commit => commits immediately
70
71
  # :softCommit => commit to memory, but don't flush to disk
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "11.1.6".freeze
2
+ VERSION = "11.2.0".freeze
3
3
  end
@@ -36,6 +36,7 @@ module ActiveFedora
36
36
  end
37
37
 
38
38
  def ldp_source
39
+ @ldp_source ||= LdpResource.new(ldp_connection, nil) if file.new_record?
39
40
  @ldp_source ||= LdpResource.new(ldp_connection, metadata_uri)
40
41
  end
41
42
 
@@ -47,6 +48,7 @@ module ActiveFedora
47
48
  raise "Save the file first" if file.new_record?
48
49
  SparqlInsert.new(changes_for_update, file.uri).execute(metadata_uri)
49
50
  @ldp_source = nil
51
+ @metadata_uri = nil
50
52
  true
51
53
  end
52
54
 
@@ -582,7 +582,7 @@ describe ActiveFedora::Base do
582
582
  Object.send(:remove_const, :MediaObject)
583
583
  end
584
584
 
585
- it "it should find the reflection that bears the predicate" do
585
+ it "finds the reflection that bears the predicate" do
586
586
  expect(MediaObject.new.association(:baubles).send(:find_reflection)).to eq Bauble._reflect_on_association(:media_object)
587
587
  end
588
588
  end
@@ -602,7 +602,7 @@ describe ActiveFedora::Base do
602
602
  Object.send(:remove_const, :MediaObject)
603
603
  end
604
604
 
605
- it "it should find the reflection that bears the predicate" do
605
+ it "finds the reflection that bears the predicate" do
606
606
  expect(MediaObject.new.association(:parts).send(:find_reflection)).to eq MasterFile._reflect_on_association(:media_object)
607
607
  end
608
608
  end
@@ -622,7 +622,7 @@ describe ActiveFedora::Base do
622
622
  Object.send(:remove_const, :MediaObject)
623
623
  end
624
624
 
625
- it "it should find the reflection that bears the predicate" do
625
+ it "finds the reflection that bears the predicate" do
626
626
  expect(MediaObject.new.association(:baubles).send(:find_reflection)).to eq MediaObject._reflect_on_association(:baubles)
627
627
  end
628
628
  end
@@ -43,13 +43,33 @@ describe ActiveFedora::Base do
43
43
  end
44
44
  end
45
45
 
46
+ describe "when some of the descendants are prioritized models" do
47
+ around do |example|
48
+ class PriorityModel < ActiveFedora::Base
49
+ end
50
+ original_defaults = ActiveFedora::Indexing::DescendantFetcher.default_priority_models
51
+ ActiveFedora::Indexing::DescendantFetcher.default_priority_models = ["PriorityModel"]
52
+
53
+ example.run
54
+
55
+ ActiveFedora::Indexing::DescendantFetcher.default_priority_models = original_defaults
56
+ Object.send(:remove_const, :PriorityModel)
57
+ end
58
+ let(:ids) { ['foo', 'bar'] }
59
+ let!(:priority_models) { [PriorityModel.create, PriorityModel.create] }
60
+
61
+ it "puts prioritized model ids first" do
62
+ expect(described_class.descendant_uris(ActiveFedora.fedora.base_uri).slice(0..(priority_models.count - 1))).to contain_exactly(*priority_models.collect(&:uri).collect(&:to_s))
63
+ end
64
+ end
65
+
46
66
  describe "reindex_everything" do
47
67
  let(:ids) { ['foo', 'bar'] }
48
68
  let(:solr) { ActiveFedora::SolrService.instance.conn }
49
69
  before do
50
70
  solr.delete_by_query('*:*', params: { 'softCommit' => true })
51
71
  end
52
- it "calls update_index on every object represented in the sitemap" do
72
+ it "adds object to solr" do
53
73
  expect {
54
74
  described_class.reindex_everything
55
75
  }.to change { ActiveFedora::SolrService.query('id:foo').size }.from(0).to(1)
@@ -451,7 +451,7 @@ describe ActiveFedora::File do
451
451
 
452
452
  context "when Array passed to new" do
453
453
  it "raises an expection" do
454
- expect { described_class.new([]) }.to raise_error
454
+ expect { described_class.new([]) }.to raise_error(RuntimeError)
455
455
  end
456
456
  end
457
457
  end
@@ -4,6 +4,32 @@ describe ActiveFedora::FixityService do
4
4
  let(:service) { described_class.new(uri) }
5
5
  let(:uri) { RDF::URI("http://path/to/resource") }
6
6
 
7
+ let(:passing_fedora44_response_body) {
8
+ <<-EOF
9
+ @prefix premis: <http://www.loc.gov/premis/rdf/v1#> .
10
+
11
+ <http://127.0.0.1:8080/rest/dev/0k/22/5b/04/0k225b04p/files/9f296a1f-10e7-44a3-83eb-4811d611edc6/fcr:versions/version1> premis:hasFixity <http://127.0.0.1:8080/rest/dev/0k/22/5b/04/0k225b04p/files/9f296a1f-10e7-44a3-83eb-4811d611edc6/fcr:versions/version1#fixity/1493843767961> .
12
+
13
+ <http://127.0.0.1:8080/rest/dev/0k/22/5b/04/0k225b04p/files/9f296a1f-10e7-44a3-83eb-4811d611edc6/fcr:versions/version1#fixity/1493843767961> a premis:Fixity , premis:EventOutcomeDetail ;
14
+ premis:hasEventOutcome "SUCCESS"^^<http://www.w3.org/2001/XMLSchema#string> ;
15
+ premis:hasMessageDigest <urn:sha1:b995eef5262dd1c74f0ed9c96be1f404394d45dc> ;
16
+ premis:hasSize "103945"^^<http://www.w3.org/2001/XMLSchema#long> .
17
+ EOF
18
+ }
19
+
20
+ let(:failing_fedora44_response_body) {
21
+ <<-EOF
22
+ @prefix premis: <http://www.loc.gov/premis/rdf/v1#> .
23
+
24
+ <http://127.0.0.1:8080/rest/dev/ks/65/hc/20/ks65hc20t/files/e316b4b5-4627-44f8-9fdb-d2016e0e7380/fcr:versions/version3> premis:hasFixity <http://127.0.0.1:8080/rest/dev/ks/65/hc/20/ks65hc20t/files/e316b4b5-4627-44f8-9fdb-d2016e0e7380/fcr:versions/version3#fixity/1493844791463> .
25
+
26
+ <http://127.0.0.1:8080/rest/dev/ks/65/hc/20/ks65hc20t/files/e316b4b5-4627-44f8-9fdb-d2016e0e7380/fcr:versions/version3#fixity/1493844791463> a premis:Fixity , premis:EventOutcomeDetail ;
27
+ premis:hasEventOutcome "BAD_CHECKSUM"^^<http://www.w3.org/2001/XMLSchema#string> , "BAD_SIZE"^^<http://www.w3.org/2001/XMLSchema#string> ;
28
+ premis:hasMessageDigest <urn:sha1:1a89571e25dd372563a10740a883e93f8af2d146> ;
29
+ premis:hasSize "1878582"^^<http://www.w3.org/2001/XMLSchema#long> .
30
+ EOF
31
+ }
32
+
7
33
  describe "the instance" do
8
34
  subject { described_class.new(uri) }
9
35
  it { is_expected.to respond_to(:response) }
@@ -22,21 +48,21 @@ describe ActiveFedora::FixityService do
22
48
  end
23
49
  end
24
50
 
25
- describe "#check" do
51
+ describe "#verified?" do
26
52
  before { allow(service).to receive(:fixity_response_from_fedora).and_return(response) }
27
- subject { service.check }
53
+ subject { service.verified? }
28
54
 
29
55
  context "with Fedora version >= 4.4.0" do
30
56
  context "with a passing result" do
31
57
  let(:response) do
32
- instance_double("Response", body: '<subject> <http://www.loc.gov/premis/rdf/v1#hasEventOutcome> "SUCCESS"^^<http://www.w3.org/2001/XMLSchema#string> .')
58
+ instance_double("Response", body: passing_fedora44_response_body)
33
59
  end
34
60
  it { is_expected.to be true }
35
61
  end
36
62
 
37
63
  context "with a failing result" do
38
64
  let(:response) do
39
- instance_double("Response", body: '<subject> <http://www.loc.gov/premis/rdf/v1#hasEventOutcome> "BAD_CHECKSUM"^^<http://www.w3.org/2001/XMLSchema#string> .')
65
+ instance_double("Response", body: failing_fedora44_response_body)
40
66
  end
41
67
  it { is_expected.to be false }
42
68
  end
@@ -65,4 +91,38 @@ describe ActiveFedora::FixityService do
65
91
  it { is_expected.to be false }
66
92
  end
67
93
  end
94
+
95
+ describe "expected_message_digest" do
96
+ before { allow(service).to receive(:fixity_response_from_fedora).and_return(response) }
97
+ subject { service.expected_message_digest }
98
+ context "with success response" do
99
+ let(:response) do
100
+ instance_double("Response", body: passing_fedora44_response_body)
101
+ end
102
+ it { is_expected.to match(/urn:sha1:[a-f0-9]+/) }
103
+ end
104
+ context "with failure response" do
105
+ let(:response) do
106
+ instance_double("Response", body: failing_fedora44_response_body)
107
+ end
108
+ it { is_expected.to match(/urn:sha1:[a-f0-9]+/) }
109
+ end
110
+ end
111
+
112
+ describe "expected_size" do
113
+ before { allow(service).to receive(:fixity_response_from_fedora).and_return(response) }
114
+ subject { service.expected_size }
115
+ context "with success response" do
116
+ let(:response) do
117
+ instance_double("Response", body: passing_fedora44_response_body)
118
+ end
119
+ it { is_expected.to be_kind_of Numeric }
120
+ end
121
+ context "with failure response" do
122
+ let(:response) do
123
+ instance_double("Response", body: failing_fedora44_response_body)
124
+ end
125
+ it { is_expected.to be_kind_of Numeric }
126
+ end
127
+ end
68
128
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActiveFedora::Indexing::Map::IndexObject do
4
+ describe "with a block" do
5
+ subject(:instance) do
6
+ described_class.new(:name) do |index|
7
+ index.as :stored_searchable, :facetable
8
+ end
9
+ end
10
+
11
+ it "can set behaviors" do
12
+ expect(instance.behaviors).to eq [:stored_searchable, :facetable]
13
+ end
14
+ end
15
+
16
+ describe "with an initializer parameters" do
17
+ subject(:instance) do
18
+ described_class.new(:name, behaviors: [:stored_searchable, :facetable])
19
+ end
20
+
21
+ it "can set behaviors" do
22
+ expect(instance.behaviors).to eq [:stored_searchable, :facetable]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActiveFedora::Indexing::Map do
4
+ describe ".merge" do
5
+ subject(:merged) { first_map.merge(extra) }
6
+ let(:index_object1) { instance_double(described_class::IndexObject) }
7
+ let(:index_object2) { instance_double(described_class::IndexObject) }
8
+ let(:index_object3) { instance_double(described_class::IndexObject) }
9
+ let(:first_map) { described_class.new(one: index_object1, two: index_object2) }
10
+
11
+ context "with a hash" do
12
+ let(:extra) { { three: index_object3 } }
13
+ it "merges with a hash" do
14
+ expect(merged).to be_instance_of described_class
15
+ expect(merged.keys).to match_array [:one, :two, :three]
16
+ end
17
+ end
18
+
19
+ context "with another Indexing::Map" do
20
+ let(:extra) { described_class.new(three: index_object3) }
21
+ it "merges with the other map" do
22
+ expect(merged).to be_instance_of described_class
23
+ expect(merged.keys).to match_array [:one, :two, :three]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -50,11 +50,25 @@ describe ActiveFedora::RDF::IndexingService do
50
50
  end
51
51
  end
52
52
 
53
- before do
54
- allow(MyObj).to receive(:index_config).and_return(index_config)
53
+ describe "#index_config" do
54
+ subject { indexer.index_config }
55
+ context "without passing one in" do
56
+ before do
57
+ expect(Deprecation).to receive(:warn)
58
+ allow(MyObj).to receive(:index_config).and_return(index_config)
59
+ end
60
+
61
+ let(:indexer) { described_class.new(f2) }
62
+ it { is_expected.to eq(index_config) }
63
+ end
64
+
65
+ context "when passing one in" do
66
+ let(:indexer) { described_class.new(f2, index_config) }
67
+ it { is_expected.to eq(index_config) }
68
+ end
55
69
  end
56
70
 
57
- let(:indexer) { described_class.new(f2) }
71
+ let(:indexer) { described_class.new(f2, index_config) }
58
72
 
59
73
  describe "#generate_solr_document" do
60
74
  let(:solr_obj) { indexer.generate_solr_document(lambda { |key| "solr_rdf__#{key}" }) }
@@ -11,6 +11,12 @@ describe ActiveFedora::SolrService do
11
11
 
12
12
  let(:mock_conn) { instance_double(RSolr::Client) }
13
13
 
14
+ describe '#options' do
15
+ it 'is readable' do
16
+ expect(described_class.instance.options).to include :read_timeout, :open_timeout, :url
17
+ end
18
+ end
19
+
14
20
  describe '#conn' do
15
21
  it "takes a n-arg constructor and configure for localhost" do
16
22
  expect(RSolr).to receive(:connect).with(read_timeout: 120, open_timeout: 120, url: 'http://localhost:8080/solr')
@@ -41,4 +41,29 @@ describe ActiveFedora::WithMetadata::MetadataNode do
41
41
  end
42
42
  end
43
43
  end
44
+
45
+ describe ".new" do
46
+ it "does not make a request when parent file is new" do
47
+ expect(file.ldp_source.client).not_to receive(:head)
48
+ described_class.new(file)
49
+ end
50
+ end
51
+
52
+ describe ".save" do
53
+ it "resets metadata_uri" do
54
+ expect(node.metadata_uri).to eq ::RDF::URI.new(nil)
55
+ file.content = "test"
56
+ file.save!
57
+ node.save
58
+ expect(node.metadata_uri).not_to eq ::RDF::URI.new(nil)
59
+ end
60
+
61
+ it "resets ldp_source" do
62
+ expect(node.ldp_source.new?).to be_truthy
63
+ file.content = "test"
64
+ file.save!
65
+ node.save
66
+ expect(node.ldp_source.new?).to be_falsey
67
+ end
68
+ end
44
69
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active-fedora
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.1.6
4
+ version: 11.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-04-19 00:00:00.000000000 Z
13
+ date: 2017-05-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rsolr
@@ -134,6 +134,20 @@ dependencies:
134
134
  - - "~>"
135
135
  - !ruby/object:Gem::Version
136
136
  version: 0.6.0
137
+ - !ruby/object:Gem::Dependency
138
+ name: ruby-progressbar
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '1.0'
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '1.0'
137
151
  - !ruby/object:Gem::Dependency
138
152
  name: rails
139
153
  requirement: !ruby/object:Gem::Requirement
@@ -196,14 +210,14 @@ dependencies:
196
210
  requirements:
197
211
  - - "~>"
198
212
  - !ruby/object:Gem::Version
199
- version: '0.15'
213
+ version: '1.0'
200
214
  type: :development
201
215
  prerelease: false
202
216
  version_requirements: !ruby/object:Gem::Requirement
203
217
  requirements:
204
218
  - - "~>"
205
219
  - !ruby/object:Gem::Version
206
- version: '0.15'
220
+ version: '1.0'
207
221
  - !ruby/object:Gem::Dependency
208
222
  name: fcrepo_wrapper
209
223
  requirement: !ruby/object:Gem::Requirement
@@ -429,6 +443,7 @@ files:
429
443
  - lib/active_fedora/indexers/global_indexer.rb
430
444
  - lib/active_fedora/indexers/null_indexer.rb
431
445
  - lib/active_fedora/indexing.rb
446
+ - lib/active_fedora/indexing/descendant_fetcher.rb
432
447
  - lib/active_fedora/indexing/map.rb
433
448
  - lib/active_fedora/indexing_service.rb
434
449
  - lib/active_fedora/inheritable_accessors.rb
@@ -628,6 +643,8 @@ files:
628
643
  - spec/unit/has_and_belongs_to_many_association_spec.rb
629
644
  - spec/unit/has_many_association_spec.rb
630
645
  - spec/unit/indexers/global_indexer_spec.rb
646
+ - spec/unit/indexing/map/index_object_spec.rb
647
+ - spec/unit/indexing/map_spec.rb
631
648
  - spec/unit/indexing_service_spec.rb
632
649
  - spec/unit/indexing_spec.rb
633
650
  - spec/unit/inheritance_spec.rb
@@ -684,7 +701,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
684
701
  version: '0'
685
702
  requirements: []
686
703
  rubyforge_project:
687
- rubygems_version: 2.4.5.1
704
+ rubygems_version: 2.6.11
688
705
  signing_key:
689
706
  specification_version: 4
690
707
  summary: A convenience libary for manipulating documents in the Fedora Repository.