active-fedora 7.3.1 → 8.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +17 -7
  3. data/Gemfile +0 -3
  4. data/active-fedora.gemspec +5 -5
  5. data/gemfiles/rails3.gemfile +5 -0
  6. data/gemfiles/rails4.1.gemfile +5 -0
  7. data/gemfiles/rails4.gemfile +5 -0
  8. data/lib/active_fedora.rb +1 -1
  9. data/lib/active_fedora/associations/belongs_to_association.rb +8 -21
  10. data/lib/active_fedora/attributes.rb +13 -12
  11. data/lib/active_fedora/base.rb +1 -1
  12. data/lib/active_fedora/datastream.rb +3 -6
  13. data/lib/active_fedora/indexing.rb +1 -1
  14. data/lib/active_fedora/om_datastream.rb +1 -5
  15. data/lib/active_fedora/predicates.rb +2 -2
  16. data/lib/active_fedora/rdf.rb +6 -2
  17. data/lib/active_fedora/rdf/fcrepo.rb +326 -0
  18. data/lib/active_fedora/rdf/identifiable.rb +6 -3
  19. data/lib/active_fedora/rdf/indexing.rb +3 -15
  20. data/lib/active_fedora/rdf/persistence.rb +33 -0
  21. data/lib/active_fedora/rdf/project_hydra.rb +12 -0
  22. data/lib/active_fedora/rdf/rdf_datastream.rb +33 -15
  23. data/lib/active_fedora/rdf_xml_writer.rb +2 -2
  24. data/lib/active_fedora/relationship_graph.rb +8 -8
  25. data/lib/active_fedora/semantic_node.rb +3 -15
  26. data/lib/active_fedora/solr_digital_object.rb +2 -2
  27. data/lib/active_fedora/solr_service.rb +1 -8
  28. data/lib/active_fedora/version.rb +1 -1
  29. data/lib/generators/active_fedora/config/fedora/templates/fedora.yml +24 -0
  30. data/lib/tasks/active_fedora_dev.rake +1 -1
  31. data/spec/integration/belongs_to_association_spec.rb +0 -5
  32. data/spec/integration/json_serialization_spec.rb +1 -1
  33. data/spec/integration/load_from_solr_spec.rb +8 -1
  34. data/spec/integration/ntriples_datastream_spec.rb +18 -18
  35. data/spec/integration/om_datastream_spec.rb +2 -2
  36. data/spec/integration/rdf_nested_attributes_spec.rb +1 -1
  37. data/spec/integration/relation_delegation_spec.rb +3 -3
  38. data/spec/samples/hydra-mods_article_datastream.rb +0 -4
  39. data/spec/support/an_active_model.rb +0 -4
  40. data/spec/unit/active_fedora_spec.rb +3 -3
  41. data/spec/unit/attributes_spec.rb +37 -54
  42. data/spec/unit/base_extra_spec.rb +0 -9
  43. data/spec/unit/om_datastream_spec.rb +14 -14
  44. data/spec/unit/rdf_resource_datastream_spec.rb +59 -9
  45. data/spec/unit/rdf_vocab_spec.rb +30 -0
  46. data/spec/unit/solr_digital_object_spec.rb +2 -2
  47. data/spec/unit/solr_service_spec.rb +0 -6
  48. data/spec/unit/validations_spec.rb +4 -4
  49. metadata +27 -32
  50. data/lib/active_fedora/rdf/object_resource.rb +0 -20
@@ -7,7 +7,7 @@
7
7
  # subject.descMetadata.set = base
8
8
  # subject.descMetadata.set # => <ActiveFedora::Base>
9
9
  # subject.descMetadata.set.title # => 'test'
10
- module ActiveFedora::Rdf::Identifiable
10
+ module ActiveFedora::RDF::Identifiable
11
11
  extend ActiveSupport::Concern
12
12
  delegate :parent, :dump, :query, :rdf_type, :to => :resource
13
13
 
@@ -17,7 +17,9 @@ module ActiveFedora::Rdf::Identifiable
17
17
  # If there is no RdfResource, make a dummy one and freeze its graph.
18
18
  def resource
19
19
  return self.send(self.class.resource_datastream).resource unless self.class.resource_datastream.nil?
20
- ActiveFedora::Rdf::ObjectResource.new(self.pid).freeze
20
+ klass = Class.new(ActiveTriples::Resource)
21
+ klass.send(:include, ActiveFedora::RDF::Persistence)
22
+ klass.new(ActiveFedora::RDF::Persistence::BASE_URI + self.pid).freeze
21
23
  end
22
24
 
23
25
  module ClassMethods
@@ -56,7 +58,8 @@ module ActiveFedora::Rdf::Identifiable
56
58
  # for URI configurations not of form base_uri + pid
57
59
  # @param [RDF::URI] uri URI to convert to pid
58
60
  def pid_from_subject(uri)
59
- base_uri = resource_datastream ? self.ds_specs[resource_datastream.to_s][:type].resource_class.base_uri : ActiveFedora::Rdf::ObjectResource.base_uri
61
+ base_uri = self.ds_specs[resource_datastream.to_s][:type].resource_class.base_uri if resource_datastream
62
+ base_uri = base_uri || ActiveFedora::RDF::Persistence::BASE_URI
60
63
  uri.to_s.gsub(base_uri, "")
61
64
  end
62
65
  end
@@ -1,24 +1,17 @@
1
1
  module ActiveFedora
2
- module Rdf
2
+ module RDF
3
3
  module Indexing
4
- extend Deprecation
5
4
  extend ActiveSupport::Concern
6
5
 
7
- # In active_fedora 8, we can get the prefix part from Datastream.prefix
8
6
  def apply_prefix(name)
9
- "#{dsid.underscore}__#{name}"
10
- end
11
-
12
- def prefix(name)
13
- Deprecation.warn Indexing, "prefix is deprecated. Use apply_prefix instead. In active-fedora 8, the prefix method will just return the prefix to be applied, and will not do the applying. This will enable conformity between OmDatastream and RdfDatastream"
14
- apply_prefix(name)
7
+ prefix + name.to_s
15
8
  end
16
9
 
17
10
  def to_solr(solr_doc = Hash.new) # :nodoc:
18
11
  fields.each do |field_key, field_info|
19
12
  values = resource.get_values(field_key)
20
13
  Array(values).each do |val|
21
- if val.kind_of? RDF::URI
14
+ if val.kind_of? ::RDF::URI
22
15
  val = val.to_s
23
16
  elsif val.kind_of? ActiveTriples::Resource
24
17
  val = val.solrize
@@ -43,11 +36,6 @@ module ActiveFedora
43
36
  end
44
37
 
45
38
  module ClassMethods
46
- def prefix(dsid, name)
47
- Deprecation.warn Indexing, "prefix is deprecated and will be removed in active-fedora 8.0.0.", caller
48
- "#{dsid.underscore}__#{name}".to_sym
49
- end
50
-
51
39
  # Gives the datatype for a column.
52
40
  def type(field)
53
41
  config_for_term_or_uri(field).type
@@ -0,0 +1,33 @@
1
+ module ActiveFedora
2
+ module RDF
3
+ #
4
+ # Mixin for adding datastream persistence to an ActiveTriples::Resource
5
+ # descendant so that it may be used to back an ActiveFedora::RDFDatastream.
6
+ #
7
+ # @see ActiveFedora::RDFDatastream.resource_class
8
+ # @see ActiveFedora::Rdf::ObjectResource
9
+ #
10
+ module Persistence
11
+ extend ActiveSupport::Concern
12
+
13
+ BASE_URI = 'info:fedora/'
14
+
15
+ included do
16
+ configure :base_uri => BASE_URI unless base_uri
17
+ attr_accessor :datastream
18
+ end
19
+
20
+ # Overrides ActiveTriples::Resource
21
+ def persist!
22
+ return false unless datastream and datastream.respond_to? :digital_object
23
+ @persisted ||= datastream.digital_object.save
24
+ end
25
+
26
+ # Overrides ActiveTriples::Resource
27
+ def persisted?
28
+ @persisted ||= (not datastream.new?)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'rdf'
3
+ class ActiveFedora::RDF::ProjectHydra < ::RDF::StrictVocabulary("http://projecthydra.org/ns/relations#")
4
+ property :hasProfile,
5
+ label: "Has Profile".freeze,
6
+ subPropertyOf: "info:fedora/fedora-system:def/relations-external#fedoraRelationship".freeze,
7
+ type: "rdf:Property".freeze
8
+ property :isGovernedBy,
9
+ label: "Is Governed By".freeze,
10
+ subPropertyOf: "info:fedora/fedora-system:def/relations-external#fedoraRelationship".freeze,
11
+ type: "rdf:Property".freeze
12
+ end
@@ -2,8 +2,9 @@ module ActiveFedora
2
2
  class RDFDatastream < ActiveFedora::Datastream
3
3
  include Solrizer::Common
4
4
  include ActiveTriples::NestedAttributes
5
- include Rdf::Indexing
6
- extend ActiveTriples::Properties
5
+ include RDF::Indexing
6
+ include ActiveTriples::Properties
7
+ include ActiveTriples::Reflection
7
8
 
8
9
  delegate :rdf_subject, :set_value, :get_values, :attributes=, :to => :resource
9
10
 
@@ -16,11 +17,23 @@ module ActiveFedora
16
17
  @subject_block ||= lambda { |ds| ds.pid }
17
18
  end
18
19
 
19
- # Utility method which can be overridden to determine the object
20
- # resource that is created.
21
- def resource_class
22
- Rdf::ObjectResource
23
- end
20
+ ##
21
+ # @param [Class] an object to set as the resource class, Must be a descendant of
22
+ # ActiveTriples::Resource and include ActiveFedora::Rdf::Persistence.
23
+ #
24
+ # @return [Class] the object resource class
25
+ def resource_class(klass=nil)
26
+ if klass
27
+ raise ArgumentError, "#{self} already has a resource_class #{@resource_class}, cannot redefine it to #{klass}" if @resource_class and klass != @resource_class
28
+ raise ArgumentError, "#{klass} must be a subclass of ActiveTriples::Resource" unless klass < ActiveTriples::Resource
29
+ end
30
+
31
+ @resource_class ||= begin
32
+ klass = Class.new(klass || ActiveTriples::Resource)
33
+ klass.send(:include, RDF::Persistence)
34
+ klass
35
+ end
36
+ end
24
37
  end
25
38
 
26
39
  before_save do
@@ -62,13 +75,18 @@ module ActiveFedora
62
75
  # set_value, get_value, and property accessors are delegated to this object.
63
76
  def resource
64
77
  @resource ||= begin
65
- r = self.singleton_class.resource_class.new(digital_object ? self.class.rdf_subject.call(self) : nil)
66
- r.singleton_class.properties = self.class.properties
67
- r.singleton_class.properties.keys.each do |property|
68
- r.singleton_class.send(:register_property, property)
78
+ klass = self.class.resource_class
79
+ klass.properties.merge(self.class.properties).each do |prop, config|
80
+ klass.property(config.term,
81
+ predicate: config.predicate,
82
+ class_name: config.class_name,
83
+ multivalue: config.multivalue)
69
84
  end
85
+ klass.accepts_nested_attributes_for(*nested_attributes_options.keys) unless nested_attributes_options.blank?
86
+ uri_stub = digital_object ? self.class.rdf_subject.call(self) : nil
87
+
88
+ r = klass.new(uri_stub)
70
89
  r.datastream = self
71
- r.singleton_class.accepts_nested_attributes_for(*nested_attributes_options.keys) unless nested_attributes_options.blank?
72
90
  r << deserialize
73
91
  r
74
92
  end
@@ -99,7 +117,7 @@ module ActiveFedora
99
117
  end
100
118
 
101
119
  def deserialize(data=nil)
102
- return RDF::Graph.new if new? && data.nil?
120
+ return ::RDF::Graph.new if new? && data.nil?
103
121
 
104
122
  if data.nil?
105
123
  data = datastream_content
@@ -108,10 +126,10 @@ module ActiveFedora
108
126
  end
109
127
 
110
128
  # Because datastream_content can return nil, we should check that here.
111
- return RDF::Graph.new if data.nil?
129
+ return ::RDF::Graph.new if data.nil?
112
130
 
113
131
  data.force_encoding('utf-8')
114
- RDF::Graph.new << RDF::Reader.for(serialization_format).new(data)
132
+ ::RDF::Graph.new << ::RDF::Reader.for(serialization_format).new(data)
115
133
  end
116
134
 
117
135
  def serialization_format
@@ -5,7 +5,7 @@ module ActiveFedora
5
5
  # with an rdf:Description container for the properties
6
6
  # the default behavior for RDF:RDFXML::Writer is to change that element if
7
7
  # an rdf:type assertion is present; this is incompatible with Fedora 3
8
- class RDFXMLWriter < RDF::RDFXML::Writer
8
+ class RDFXMLWriter < ::RDF::RDFXML::Writer
9
9
  # Display a subject.
10
10
  #
11
11
  # If the Haml template contains an entry matching the subject's rdf:type URI, that entry will be used as the template for this subject and it's properties.
@@ -32,7 +32,7 @@ module ActiveFedora
32
32
  subject_done(subject)
33
33
 
34
34
  properties = properties_for_subject(subject)
35
- typeof = type_of(properties[RDF.type.to_s], subject)
35
+ typeof = type_of(properties[::RDF.type.to_s], subject)
36
36
  prop_list = order_properties(properties)
37
37
 
38
38
  add_debug {"subject: #{curie.inspect}, typeof: #{typeof.inspect}, props: #{prop_list.inspect}"}
@@ -17,7 +17,7 @@ module ActiveFedora
17
17
  unless has_predicate? uri
18
18
  relationships[uri] = []
19
19
  end
20
- object = RDF::Literal.new(object) if literal
20
+ object = ::RDF::Literal.new(object) if literal
21
21
  unless relationships[uri].include?(object)
22
22
  @dirty = true
23
23
  relationships[uri] << object
@@ -54,8 +54,8 @@ module ActiveFedora
54
54
 
55
55
  def to_graph(subject_uri)
56
56
  # need to destroy relationships and rewrite it.
57
- subject = RDF::URI.new(subject_uri)
58
- graph = RDF::Graph.new
57
+ subject = ::RDF::URI.new(subject_uri)
58
+ graph = ::RDF::Graph.new
59
59
  relationships.each do |predicate, values|
60
60
  values.each do |object|
61
61
  graph.insert build_statement(subject, predicate, object)
@@ -72,8 +72,8 @@ module ActiveFedora
72
72
  def build_statement(uri, predicate, target)
73
73
  raise "Not allowed anymore" if uri == :self
74
74
  target = target.internal_uri if target.respond_to? :internal_uri
75
- subject = RDF::URI.new(uri) #TODO cache
76
- if target.is_a? RDF::Literal or target.is_a? RDF::Resource
75
+ subject = ::RDF::URI.new(uri) #TODO cache
76
+ if target.is_a? ::RDF::Literal or target.is_a? ::RDF::Resource
77
77
  object = target
78
78
  else
79
79
  begin
@@ -87,14 +87,14 @@ module ActiveFedora
87
87
  rescue URI::InvalidURIError
88
88
  raise ArgumentError, "Invalid target \"#{target}\". Target must be specified as a literal, or be a valid URI."
89
89
  end
90
- object = RDF::URI.new(target)
90
+ object = ::RDF::URI.new(target)
91
91
  end
92
- RDF::Statement.new(subject, uri_predicate(predicate), object)
92
+ ::RDF::Statement.new(subject, uri_predicate(predicate), object)
93
93
 
94
94
  end
95
95
 
96
96
  def uri_predicate(predicate)
97
- return predicate if predicate.kind_of? RDF::URI
97
+ return predicate if predicate.kind_of? ::RDF::URI
98
98
  ActiveFedora::Predicates.find_graph_predicate(predicate)
99
99
  end
100
100
  end
@@ -1,7 +1,6 @@
1
1
  module ActiveFedora
2
2
  module SemanticNode
3
3
  extend ActiveSupport::Concern
4
- extend Deprecation
5
4
 
6
5
  attr_accessor :relationships_loaded
7
6
  attr_accessor :load_from_solr, :subject
@@ -30,9 +29,9 @@ module ActiveFedora
30
29
  end
31
30
 
32
31
  def relationships=(xml)
33
- RDF::RDFXML::Reader.new(xml) do |reader|
32
+ ::RDF::RDFXML::Reader.new(xml) do |reader|
34
33
  reader.each_statement do |statement|
35
- literal = statement.object.kind_of?(RDF::Literal)
34
+ literal = statement.object.kind_of?(::RDF::Literal)
36
35
  object = literal ? statement.object.value : statement.object.to_str
37
36
  object_relations.add(statement.predicate, object, literal)
38
37
  end
@@ -121,7 +120,7 @@ module ActiveFedora
121
120
 
122
121
  def ids_for_outbound(predicate)
123
122
  (object_relations[predicate] || []).map do |o|
124
- o = o.to_s if o.kind_of? RDF::Literal
123
+ o = o.to_s if o.kind_of? ::RDF::Literal
125
124
  o.kind_of?(String) ? self.class.pid_from_uri(o) : o.pid
126
125
  end
127
126
  end
@@ -132,17 +131,6 @@ module ActiveFedora
132
131
  end
133
132
 
134
133
  module ClassMethods
135
- # @param [String,Array] uris a single uri (as a string) or a list of uris to convert to pids
136
- # @return [String] the pid component of the URI
137
- def pids_from_uris(uris)
138
- Deprecation.warn(SemanticNode, "pids_from_uris has been deprecated and will be removed in active-fedora 8.0.0", caller)
139
- if uris.kind_of? String
140
- pid_from_uri(uris)
141
- else
142
- Array(uris).map {|uri| pid_from_uri(uri)}
143
- end
144
- end
145
-
146
134
  # Returns a suitable uri object for :has_model
147
135
  # Should reverse Model#from_class_uri
148
136
  def to_class_uri(attrs = {})
@@ -47,10 +47,10 @@ module ActiveFedora
47
47
  attribute = original_class.defined_attributes[field]
48
48
  field_name = attribute.primary_solr_name
49
49
  raise KeyError, "Tried to fetch `#{field}' from solr, but it isn't indexed." unless field_name
50
- val = solr_doc.fetch field_name, default
50
+ val = Array(solr_doc.fetch(field_name, default))
51
51
  case attribute.type
52
52
  when :date
53
- val.is_a?(Array) ? val.map{|v| Date.parse v} : Date.parse(val)
53
+ val.map{|v| Date.parse v}
54
54
  else
55
55
  val
56
56
  end
@@ -2,7 +2,6 @@ require 'rsolr'
2
2
 
3
3
  module ActiveFedora
4
4
  class SolrService
5
- extend Deprecation
6
5
 
7
6
  attr_reader :conn
8
7
 
@@ -63,7 +62,6 @@ module ActiveFedora
63
62
  model_value = Model.from_class_uri(value)
64
63
 
65
64
  if model_value
66
-
67
65
  # Set as the first model in case opts[:class] was nil
68
66
  best_model_match ||= model_value
69
67
 
@@ -98,12 +96,7 @@ module ActiveFedora
98
96
  def solr_name(*args)
99
97
  Solrizer.default_field_mapper.solr_name(*args)
100
98
  end
101
-
102
- def escape_uri_for_query(uri)
103
- Deprecation.warn SolrService, "escape_uri_for_query is deprecated and will be removed in active-fedora 8.0.0. Use RSolr.escape instead."
104
- RSolr.escape(uri)
105
- end
106
-
99
+
107
100
  # Create a query with a clause for each key, value
108
101
  # @param [Hash, Array<Array<String>>] args key is the predicate, value is the target_uri
109
102
  # @param [String] join_with ('AND') the value we're joining the clauses with
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "7.3.1"
2
+ VERSION = "8.0.0.rc1"
3
3
  end
@@ -2,13 +2,37 @@ development:
2
2
  user: fedoraAdmin
3
3
  password: fedoraAdmin
4
4
  url: http://127.0.0.1:8983/fedora
5
+ ########
6
+ # optional parameters available for active fedora uncomment to send values
7
+ ########
8
+ # timeout: 60
9
+ # open_timeout: nil
10
+ # ssl_client_cert: <ssl certificate>
11
+ # ssl_client_key: <ssl key>
12
+ # validateChecksum: false
5
13
  test: &TEST
6
14
  user: fedoraAdmin
7
15
  password: fedoraAdmin
8
16
  url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/fedora-test" %>
17
+ ########
18
+ # optional parameters available for active fedora uncomment to send values
19
+ ########
20
+ # timeout: 60
21
+ # open_timeout: nil
22
+ # ssl_client_cert: <ssl certificate>
23
+ # ssl_client_key: <ssl key>
24
+ # validateChecksum: false
9
25
  production:
10
26
  user: fedoraAdmin
11
27
  password: fedoraAdmin
12
28
  url: http://your.production.server:8080/fedora
29
+ ########
30
+ # optional parameters available for active fedora uncomment to send values
31
+ ########
32
+ # timeout: 60
33
+ # open_timeout: nil
34
+ # ssl_client_cert: <ssl certificate>
35
+ # ssl_client_key: <ssl key>
36
+ # validateChecksum: false
13
37
  cucumber:
14
38
  <<: *TEST
@@ -1,7 +1,7 @@
1
1
  APP_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../")
2
2
 
3
3
  require 'jettywrapper'
4
- JETTY_ZIP_BASENAME = 'v7.3.0'
4
+ JETTY_ZIP_BASENAME = 'master'
5
5
  Jettywrapper.url = "https://github.com/projecthydra/hydra-jetty/archive/#{JETTY_ZIP_BASENAME}.zip"
6
6
 
7
7
  namespace :active_fedora do
@@ -45,11 +45,6 @@ describe ActiveFedora::Base do
45
45
  book[:library_id] = library.id
46
46
  book.library_id.should == library.id
47
47
  end
48
-
49
- it "safely handles invalid data" do
50
- book[:library_id] = 'bad:identifier'
51
- book.library.should be_nil
52
- end
53
48
  end
54
49
 
55
50
  describe "getting the id property" do
@@ -19,7 +19,7 @@ describe "Objects should be serialized to JSON" do
19
19
  after do
20
20
  Object.send(:remove_const, :Foo)
21
21
  end
22
- subject { Foo.new(foo: "baz", bar: 'quix') }
22
+ subject { Foo.new(foo: ["baz"], bar: 'quix') }
23
23
  before { subject.stub(pid: 'test:123') }
24
24
  it "should have to_json" do
25
25
  json = JSON.parse(subject.to_json)
@@ -10,6 +10,10 @@ describe "Loading from solr" do
10
10
  index.type :date
11
11
  index.as :stored_searchable, :sortable
12
12
  end
13
+ property :date_modified, predicate: RDF::DC.date do |index|
14
+ index.type :date
15
+ index.as :stored_sortable
16
+ end
13
17
  property :identifier, predicate: RDF::DC.identifier do |index|
14
18
  index.type :integer
15
19
  index.as :stored_searchable, :sortable
@@ -28,13 +32,15 @@ describe "Loading from solr" do
28
32
  has_metadata 'rdf', type: MyRdfDatastream
29
33
  has_metadata 'om', type: MyOmDatastream
30
34
  has_attributes :based_near, :related_url, :part, :date_uploaded, datastream: 'rdf', multiple: true
35
+ has_attributes :date_modified, datastream: 'rdf', multiple: false
31
36
  has_attributes :title, :identifier, datastream: 'rdf', multiple: false
32
37
  has_attributes :duck, datastream: 'om', multiple: false
33
38
  end
34
39
  end
35
40
 
36
41
  let!(:original) { RdfTest.create!(title: "PLAN 9 FROM OUTER SPACE",
37
- date_uploaded: Date.parse('1959-01-01'),
42
+ date_uploaded: [Date.parse('1959-01-01')],
43
+ date_modified: Date.parse('1999-01-01'),
38
44
  duck: "quack",
39
45
  identifier: 12345) }
40
46
 
@@ -50,6 +56,7 @@ describe "Loading from solr" do
50
56
  obj = RdfTest.load_instance_from_solr original.pid
51
57
  expect(obj.title).to eq "PLAN 9 FROM OUTER SPACE"
52
58
  expect(obj.date_uploaded).to eq [Date.parse('1959-01-01')]
59
+ expect(obj.date_modified).to eq Date.parse('1999-01-01')
53
60
  expect(obj.identifier).to eq 12345
54
61
  expect{obj.part}.to raise_error KeyError, "Tried to fetch `part' from solr, but it isn't indexed."
55
62
  expect(ActiveFedora::Base.logger).to receive(:info).with "Couldn't get duck out of solr, because the datastream 'MyOmDatastream' doesn't respond to 'primary_solr_name'. Trying another way."