hydra-pbcore 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,96 @@
1
+ module HydraPbcore::Methods
2
+
3
+ # Module for inserting different types of PBcore xml nodes into
4
+ # an existing PBcore document
5
+
6
+ module ClassMethods
7
+
8
+ def publisher_template(opts={})
9
+ builder = Nokogiri::XML::Builder.new do |xml|
10
+ xml.pbcorePublisher {
11
+ xml.publisher
12
+ xml.publisherRole(:source=>"PBCore publisherRole")
13
+ }
14
+ end
15
+ return builder.doc.root
16
+ end
17
+
18
+ def contributor_template(opts={})
19
+ builder = Nokogiri::XML::Builder.new do |xml|
20
+ xml.pbcoreContributor {
21
+ xml.contributor
22
+ xml.contributorRole(:source=>"MARC relator terms")
23
+ }
24
+ end
25
+ return builder.doc.root
26
+ end
27
+
28
+ def previous_template(opts={})
29
+ builder = Nokogiri::XML::Builder.new do |xml|
30
+ xml.instantiationRelation {
31
+ xml.instantiationRelationType(:annotation=>"One of a multi-part instantiation") {
32
+ xml.text "Follows in Sequence"
33
+ }
34
+ xml.instantiationRelationIdentifier(:source=>"Rock and Roll Hall of Fame and Museum")
35
+ }
36
+ end
37
+ return builder.doc.root
38
+ end
39
+
40
+ def next_template(opts={})
41
+ builder = Nokogiri::XML::Builder.new do |xml|
42
+ xml.instantiationRelation {
43
+ xml.instantiationRelationType(:annotation=>"One of a multi-part instantiation") {
44
+ xml.text "Precedes in Sequence"
45
+ }
46
+ xml.instantiationRelationIdentifier(:source=>"Rock and Roll Hall of Fame and Museum")
47
+ }
48
+ end
49
+ return builder.doc.root
50
+ end
51
+
52
+ end
53
+
54
+ def self.included(klass)
55
+ klass.extend(ClassMethods)
56
+ end
57
+
58
+ def insert_node(type, opts={})
59
+
60
+ unless self.class.respond_to?("#{type}_template".to_sym)
61
+ raise "No XML template is defined for a PBcore node of type #{type}."
62
+ end
63
+
64
+ node = self.class.send("#{type}_template".to_sym)
65
+ nodeset = self.find_by_terms(type.to_sym)
66
+
67
+ unless nodeset.nil?
68
+ if nodeset.empty?
69
+ if opts[:root]
70
+ self.find_by_terms(opts[:root].to_sym).first.add_child(node)
71
+ else
72
+ self.ng_xml.root.add_child(node)
73
+ end
74
+ index = 0
75
+ else
76
+ nodeset.after(node)
77
+ index = nodeset.length
78
+ end
79
+ self.dirty = true
80
+ end
81
+
82
+ return node, index
83
+
84
+ end
85
+
86
+ def remove_node(type, index)
87
+ if type == "education" or type == "television"
88
+ self.find_by_terms(type.to_sym).slice(index.to_i).parent.remove
89
+ else
90
+ self.find_by_terms(type.to_sym).slice(index.to_i).remove
91
+ end
92
+ self.dirty = true
93
+ end
94
+
95
+
96
+ end
@@ -0,0 +1,169 @@
1
+ require "spec_helper"
2
+
3
+ describe HydraPbcore::Datastream::DigitalDocument do
4
+
5
+ before(:each) do
6
+ @object_ds = HydraPbcore::Datastream::DigitalDocument.new(nil, nil)
7
+ end
8
+
9
+ describe ".update_indexed_attributes" do
10
+ it "should update all of the fields in #xml_template and fields not requiring additional inserted nodes" do
11
+ [
12
+ [:pbc_id],
13
+ [:main_title],
14
+ [:alternative_title],
15
+ [:chapter],
16
+ [:episode],
17
+ [:label],
18
+ [:segment],
19
+ [:subtitle],
20
+ [:track],
21
+ [:translation],
22
+ [:summary],
23
+ [:parts_list],
24
+ [:lc_subject],
25
+ [:lc_name],
26
+ [:rh_subject],
27
+ [:getty_genre],
28
+ [:lc_genre],
29
+ [:lc_subject_genre],
30
+ [:event_series],
31
+ [:event_place],
32
+ [:event_date],
33
+ [:contributor_name],
34
+ [:contributor_role],
35
+ [:publisher_name],
36
+ [:publisher_role],
37
+ [:note],
38
+ [:archival_collection],
39
+ [:archival_series],
40
+ [:collection_number],
41
+ [:accession_number],
42
+ [:usage],
43
+ ].each do |pointer|
44
+ test_val = "#{pointer.last.to_s} value"
45
+ @object_ds.update_values( {pointer=>{"0"=>test_val}} )
46
+ @object_ds.get_values(pointer).first.should == test_val
47
+ @object_ds.get_values(pointer).length.should == 1
48
+ end
49
+ end
50
+
51
+ it "should work for fields that require added xml nodes" do
52
+ @object_ds.insert_node("publisher")
53
+ @object_ds.insert_node("contributor")
54
+ [
55
+ [:publisher_name],
56
+ [:publisher_role],
57
+ [:contributor_name],
58
+ [:contributor_role]
59
+ ].each do |pointer|
60
+ test_val = "#{pointer.last.to_s} value"
61
+ @object_ds.update_indexed_attributes( {pointer=>{"0"=>test_val}} )
62
+ @object_ds.get_values(pointer).first.should == test_val
63
+ @object_ds.get_values(pointer).length.should == 1
64
+ end
65
+ end
66
+
67
+ it "should differentiate between multiple added nodes" do
68
+ @object_ds.insert_node(:contributor)
69
+ @object_ds.insert_node(:contributor)
70
+ @object_ds.update_indexed_attributes( {[:contributor_name] => { 0 => "first contributor" }} )
71
+ @object_ds.update_indexed_attributes( {[:contributor_name] => { 1 => "second contributor" }} )
72
+ @object_ds.update_indexed_attributes( {[:contributor_role] => { 0 => "first contributor role" }} )
73
+ @object_ds.update_indexed_attributes( {[:contributor_role] => { 1 => "second contributor role" }} )
74
+ @object_ds.get_values(:contributor).length.should == 2
75
+ @object_ds.get_values(:contributor_name)[0].should == "first contributor"
76
+ @object_ds.get_values(:contributor_name)[1].should == "second contributor"
77
+ @object_ds.get_values(:contributor_role)[0].should == "first contributor role"
78
+ @object_ds.get_values(:contributor_role)[1].should == "second contributor role"
79
+ end
80
+
81
+ end
82
+
83
+ describe "#xml_template" do
84
+ it "should return an empty xml document matching a valid exmplar" do
85
+ # insert additional nodes
86
+ @object_ds.insert_node("publisher")
87
+ @object_ds.insert_node("contributor")
88
+ @object_ds.insert_node("publisher")
89
+ @object_ds.insert_node("contributor")
90
+
91
+ # update additional nodes that OM will insert automatically
92
+ @object_ds.update_indexed_attributes({ [:alternative_title] => { 0 => "inserted" }} )
93
+ @object_ds.update_indexed_attributes({ [:chapter] => { 0 => "inserted" }} )
94
+ @object_ds.update_indexed_attributes({ [:episode] => { 0 => "inserted" }} )
95
+ @object_ds.update_indexed_attributes({ [:label] => { 0 => "inserted" }} )
96
+ @object_ds.update_indexed_attributes({ [:segment] => { 0 => "inserted" }} )
97
+ @object_ds.update_indexed_attributes({ [:subtitle] => { 0 => "inserted" }} )
98
+ @object_ds.update_indexed_attributes({ [:track] => { 0 => "inserted" }} )
99
+ @object_ds.update_indexed_attributes({ [:translation] => { 0 => "inserted" }} )
100
+ @object_ds.update_indexed_attributes({ [:lc_subject] => { 0 => "inserted" }} )
101
+ @object_ds.update_indexed_attributes({ [:lc_name] => { 0 => "inserted" }} )
102
+ @object_ds.update_indexed_attributes({ [:rh_subject] => { 0 => "inserted" }} )
103
+ @object_ds.update_indexed_attributes({ [:getty_genre] => { 0 => "inserted" }} )
104
+ @object_ds.update_indexed_attributes({ [:lc_genre] => { 0 => "inserted" }} )
105
+ @object_ds.update_indexed_attributes({ [:lc_subject_genre] => { 0 => "inserted" }} )
106
+ @object_ds.update_indexed_attributes({ [:subject] => { 0 => "inserted" }} )
107
+ @object_ds.update_indexed_attributes({ [:genre] => { 0 => "inserted" }} )
108
+
109
+ # Load example fixture
110
+ f = fixture "pbcore_digital_document_template.xml"
111
+ ref_node = Nokogiri::XML(f)
112
+ f.close
113
+
114
+ # Nokogiri-fy our sample document and reorder nodes
115
+ sample_node = Nokogiri::XML(@object_ds.to_xml)
116
+ reordered = HydraPbcore::Behaviors.reorder_document(sample_node)
117
+
118
+ # Save this for later...
119
+ out = File.new("tmp/pbcore_digital_document_sample.xml", "w")
120
+ out.write(reordered.to_s)
121
+ out.close
122
+
123
+ EquivalentXml.equivalent?(ref_node, reordered, opts = { :element_order => false, :normalize_whitespace => true }).should be_true
124
+ HydraPbcore::Behaviors.validate(reordered).should be_empty
125
+
126
+ end
127
+ end
128
+
129
+ describe ".insert_node" do
130
+ it "should return a node and index for a given template type" do
131
+ ["publisher", "contributor"].each do |type|
132
+ node, index = @object_ds.insert_node(type.to_s)
133
+ index.should == 0
134
+ @object_ds.dirty?.should be_true
135
+ node, index = @object_ds.insert_node(type.to_s)
136
+ index.should == 1
137
+ end
138
+ end
139
+
140
+ it "should raise an exception for non-exisitent templates" do
141
+ lambda { @object_ds.insert_node("blarg") }.should raise_error
142
+ end
143
+ end
144
+
145
+ describe ".remove_node" do
146
+ it "should remove a node a given type and index" do
147
+ ["publisher", "contributor"].each do |type|
148
+ @object_ds.insert_node(type.to_sym)
149
+ @object_ds.insert_node(type.to_sym)
150
+ @object_ds.find_by_terms(type.to_sym).count.should == 2
151
+ @object_ds.remove_node(type.to_sym, "1")
152
+ @object_ds.find_by_terms(type.to_sym).count.should == 1
153
+ @object_ds.remove_node(type.to_sym, "0")
154
+ @object_ds.find_by_terms(type.to_sym).count.should == 0
155
+ end
156
+ end
157
+
158
+ end
159
+
160
+ describe "default fields" do
161
+
162
+ it "such as media type should be 'Moving image'" do
163
+ pending "No default fields defined yet"
164
+ @object_ds.get_values([:media_type]).first.should == "Moving image"
165
+ end
166
+
167
+ end
168
+
169
+ end
@@ -0,0 +1,189 @@
1
+ require "spec_helper"
2
+
3
+ describe HydraPbcore::Datastream::Document do
4
+
5
+ before(:each) do
6
+ @object_ds = HydraPbcore::Datastream::Document.new(nil, nil)
7
+ end
8
+
9
+ describe ".update_indexed_attributes" do
10
+ it "should update all of the fields in #xml_template and fields not requiring additional inserted nodes" do
11
+ [
12
+ [:pbc_id],
13
+ [:main_title],
14
+ [:alternative_title],
15
+ [:chapter],
16
+ [:episode],
17
+ [:label],
18
+ [:segment],
19
+ [:subtitle],
20
+ [:track],
21
+ [:translation],
22
+ [:summary],
23
+ [:parts_list],
24
+ [:lc_subject],
25
+ [:lc_name],
26
+ [:rh_subject],
27
+ [:getty_genre],
28
+ [:lc_genre],
29
+ [:lc_subject_genre],
30
+ [:event_series],
31
+ [:event_place],
32
+ [:event_date],
33
+ [:contributor_name],
34
+ [:contributor_role],
35
+ [:publisher_name],
36
+ [:publisher_role],
37
+ [:note],
38
+ [:creation_date],
39
+ [:barcode],
40
+ [:repository],
41
+ [:format],
42
+ [:standard],
43
+ [:media_type],
44
+ [:generation],
45
+ [:language],
46
+ [:colors],
47
+ [:archival_collection],
48
+ [:archival_series],
49
+ [:collection_number],
50
+ [:accession_number],
51
+ [:usage],
52
+ [:condition_note],
53
+ [:cleaning_note]
54
+ ].each do |pointer|
55
+ test_val = "#{pointer.last.to_s} value"
56
+ @object_ds.update_values( {pointer=>{"0"=>test_val}} )
57
+ @object_ds.get_values(pointer).first.should == test_val
58
+ @object_ds.get_values(pointer).length.should == 1
59
+ end
60
+ end
61
+
62
+ it "should work for fields that require added xml nodes" do
63
+ @object_ds.insert_node("publisher")
64
+ @object_ds.insert_node("contributor")
65
+ [
66
+ [:publisher_name],
67
+ [:publisher_role],
68
+ [:contributor_name],
69
+ [:contributor_role]
70
+ ].each do |pointer|
71
+ test_val = "#{pointer.last.to_s} value"
72
+ @object_ds.update_indexed_attributes( {pointer=>{"0"=>test_val}} )
73
+ @object_ds.get_values(pointer).first.should == test_val
74
+ @object_ds.get_values(pointer).length.should == 1
75
+ end
76
+ end
77
+
78
+ it "should differentiate between multiple added nodes" do
79
+ @object_ds.insert_node(:contributor)
80
+ @object_ds.insert_node(:contributor)
81
+ @object_ds.update_indexed_attributes( {[:contributor_name] => { 0 => "first contributor" }} )
82
+ @object_ds.update_indexed_attributes( {[:contributor_name] => { 1 => "second contributor" }} )
83
+ @object_ds.update_indexed_attributes( {[:contributor_role] => { 0 => "first contributor role" }} )
84
+ @object_ds.update_indexed_attributes( {[:contributor_role] => { 1 => "second contributor role" }} )
85
+ @object_ds.get_values(:contributor).length.should == 2
86
+ @object_ds.get_values(:contributor_name)[0].should == "first contributor"
87
+ @object_ds.get_values(:contributor_name)[1].should == "second contributor"
88
+ @object_ds.get_values(:contributor_role)[0].should == "first contributor role"
89
+ @object_ds.get_values(:contributor_role)[1].should == "second contributor role"
90
+ end
91
+
92
+ end
93
+
94
+ describe "#xml_template" do
95
+ it "should return an empty xml document matching a valid exmplar" do
96
+ # insert additional nodes
97
+ @object_ds.insert_node("publisher")
98
+ @object_ds.insert_node("contributor")
99
+ @object_ds.insert_node("publisher")
100
+ @object_ds.insert_node("contributor")
101
+
102
+ # update additional nodes that OM will insert automatically
103
+ @object_ds.update_indexed_attributes({ [:alternative_title] => { 0 => "inserted" }} )
104
+ @object_ds.update_indexed_attributes({ [:chapter] => { 0 => "inserted" }} )
105
+ @object_ds.update_indexed_attributes({ [:episode] => { 0 => "inserted" }} )
106
+ @object_ds.update_indexed_attributes({ [:label] => { 0 => "inserted" }} )
107
+ @object_ds.update_indexed_attributes({ [:segment] => { 0 => "inserted" }} )
108
+ @object_ds.update_indexed_attributes({ [:subtitle] => { 0 => "inserted" }} )
109
+ @object_ds.update_indexed_attributes({ [:track] => { 0 => "inserted" }} )
110
+ @object_ds.update_indexed_attributes({ [:translation] => { 0 => "inserted" }} )
111
+ @object_ds.update_indexed_attributes({ [:lc_subject] => { 0 => "inserted" }} )
112
+ @object_ds.update_indexed_attributes({ [:lc_name] => { 0 => "inserted" }} )
113
+ @object_ds.update_indexed_attributes({ [:rh_subject] => { 0 => "inserted" }} )
114
+ @object_ds.update_indexed_attributes({ [:getty_genre] => { 0 => "inserted" }} )
115
+ @object_ds.update_indexed_attributes({ [:lc_genre] => { 0 => "inserted" }} )
116
+ @object_ds.update_indexed_attributes({ [:lc_subject_genre] => { 0 => "inserted" }} )
117
+ @object_ds.update_indexed_attributes({ [:subject] => { 0 => "inserted" }} )
118
+ @object_ds.update_indexed_attributes({ [:genre] => { 0 => "inserted" }} )
119
+ @object_ds.update_indexed_attributes({ [:condition_note] => { 0 => "inserted" }} )
120
+ @object_ds.update_indexed_attributes({ [:cleaning_note] => { 0 => "inserted" }} )
121
+
122
+ # Load example fixture
123
+ f = fixture "pbcore_document_template.xml"
124
+ ref_node = Nokogiri::XML(f)
125
+ f.close
126
+
127
+ # Nokogiri-fy our sample document and reorder nodes
128
+ sample_node = Nokogiri::XML(@object_ds.to_xml)
129
+ reordered = HydraPbcore::Behaviors.reorder_document(sample_node)
130
+
131
+ # Save this for later...
132
+ out = File.new("tmp/pbcore_document_sample.xml", "w")
133
+ out.write(reordered.to_s)
134
+ out.close
135
+
136
+ EquivalentXml.equivalent?(ref_node, reordered, opts = { :element_order => false, :normalize_whitespace => true }).should be_true
137
+ HydraPbcore::Behaviors.validate(reordered).should be_empty
138
+
139
+ end
140
+ end
141
+
142
+ describe ".insert_node" do
143
+ it "should return a node and index for a given template type" do
144
+ ["publisher", "contributor"].each do |type|
145
+ node, index = @object_ds.insert_node(type.to_s)
146
+ index.should == 0
147
+ @object_ds.dirty?.should be_true
148
+ node, index = @object_ds.insert_node(type.to_s)
149
+ index.should == 1
150
+ end
151
+ end
152
+
153
+ it "should raise an exception for non-exisitent templates" do
154
+ lambda { @object_ds.insert_node("blarg") }.should raise_error
155
+ end
156
+ end
157
+
158
+ describe ".remove_node" do
159
+ it "should remove a node a given type and index" do
160
+ ["publisher", "contributor"].each do |type|
161
+ @object_ds.insert_node(type.to_sym)
162
+ @object_ds.insert_node(type.to_sym)
163
+ @object_ds.find_by_terms(type.to_sym).count.should == 2
164
+ @object_ds.remove_node(type.to_sym, "1")
165
+ @object_ds.find_by_terms(type.to_sym).count.should == 1
166
+ @object_ds.remove_node(type.to_sym, "0")
167
+ @object_ds.find_by_terms(type.to_sym).count.should == 0
168
+ end
169
+ end
170
+
171
+ end
172
+
173
+ describe "default fields" do
174
+
175
+ it "such as media type should be 'Moving image'" do
176
+ @object_ds.get_values([:media_type]).first.should == "Moving image"
177
+ end
178
+
179
+ it "such as colors should be 'Color'" do
180
+ @object_ds.get_values([:colors]).first.should == "Color"
181
+ end
182
+
183
+ it "such as generation should be 'Original'" do
184
+ @object_ds.get_values([:generation]).first.should == "Original"
185
+ end
186
+
187
+ end
188
+
189
+ end