releaf-content 2.0.0 → 2.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.
@@ -1,72 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Releaf::Content::BuildRouteObjects do
4
- let(:home_page_node) { create(:home_page_node, id: 23, locale: "lv", slug: "llvv") }
5
- let(:node) { create(:text_page_node, id: 27, parent: home_page_node, slug: "some-text") }
6
- let(:controller) { Releaf::Content::Route.default_controller( node.class ) }
7
- let(:subject) { described_class.new(node_class: node.class, node_content_class: TextPage, default_controller: controller) }
8
-
9
- describe "#call" do
10
- it "returns an array" do
11
- expect(subject.call).to be_a Array
12
- end
13
-
14
- it "returns an array of Node::Route objects" do
15
- result = subject.call
16
- expect(result.count).to eq(1)
17
- expect(result.first.class).to eq(Releaf::Content::Route)
18
- end
19
- end
20
-
21
- describe "#nodes" do
22
- it "returns all nodes" do
23
- expect(subject.nodes).to match_array([home_page_node, node])
24
- end
25
- end
26
-
27
- describe "#content_nodes" do
28
- it "returns nodes with a specified content class" do
29
- expect(subject.content_nodes).to eq([node])
30
- end
31
- end
32
-
33
- describe "#build_route_object" do
34
- let(:route) { subject.build_route_object(node) }
35
-
36
- context "when node is not available" do
37
- it "does not include it in return" do
38
- allow_any_instance_of(Node).to receive(:available?).and_return(false)
39
- expect(route).to be_nil
40
- end
41
- end
42
-
43
- it "returns a route instance" do
44
- expect(route).to be_a Releaf::Content::Route
45
- end
46
-
47
- it "assigns node_class from given node" do
48
- expect(route.node_class).to be Node
49
- end
50
-
51
- it "assigns node_id from given node" do
52
- expect(route.node_id).to eq "27"
53
- end
54
-
55
- it "assigns path from given node" do
56
- expect(route.path).to eq "/llvv/some-text"
57
- end
58
-
59
- it "assigns locale from given node" do
60
- expect(route.locale).to eq "lv"
61
- end
62
-
63
- it "assigns default_controller from given argument" do
64
- expect(route.default_controller).to be controller
65
- end
66
-
67
- it "assigns site from content routing configuration" do
68
- allow( Releaf::Content).to receive(:routing).and_return('Node' => {site: 'some_site'})
69
- expect(route.site).to eq 'some_site'
70
- end
71
- end
72
- end
@@ -1,338 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Releaf::Content::Node::Copy do
4
-
5
- let(:root_node) { create(:home_page_node) }
6
-
7
- let(:node) { create(node_factory, parent: root_node) }
8
- let(:node_factory) { :text_page_node }
9
-
10
- let(:content_factory) { :text_page }
11
- let(:content_attributes) { { } }
12
-
13
- let(:complex_node_factory) { :banner_page_node }
14
- let(:complex_content_factory) { :banner_page }
15
- let(:complex_content_duplicatable_associations) {
16
- [
17
- {
18
- banner_groups: [
19
- { banners: [] }
20
- ]
21
- }
22
- ] }
23
-
24
- let(:file) { File.new(File.expand_path('../../../../fixtures/dummy.png', __dir__)) }
25
-
26
- let(:original) { create(content_factory, content_attributes) }
27
-
28
- describe "#call" do
29
- subject { described_class.new(node: node, parent_id: root_node.id ) }
30
-
31
- it "returns node" do
32
- expect(subject.call.class).to eq(node.class)
33
- end
34
- end
35
-
36
- describe "#make_copy" do
37
- # this is a double check to verify file duplication by doing the full copying process.
38
- # #duplicate_dragonfly_attachments is tested separately in more detail below
39
- subject { described_class.new(node: node, parent_id: root_node.id ) }
40
-
41
- context "when node content has dragonfly file fields" do
42
- let(:node_factory) { complex_node_factory }
43
-
44
- it "duplicates dragonfly attachments, storing them as separate files that are no longer linked" do
45
- node.content.top_banner = file
46
- node.save!
47
- copy = subject.make_copy
48
-
49
- # make sure the uids are non-empty and different
50
- expect(node.content.top_banner_uid).to be_present
51
- expect(copy.content.top_banner_uid).to be_present
52
- expect(copy.content.top_banner_uid).to_not eq node.content.top_banner_uid
53
-
54
- # make sure the files are stored and exist
55
- expect(copy.content.top_banner.path).to start_with Dragonfly.app.datastore.root_path
56
- expect(node.content.class.find(node.content.id).top_banner.path).to start_with Dragonfly.app.datastore.root_path
57
- expect(copy.content.top_banner.path).to_not eq node.content.top_banner.path
58
- end
59
- end
60
-
61
- end
62
-
63
-
64
- describe "#duplicate_under" do
65
- let!(:source_node) { create(:node, locale: "lv") }
66
- let!(:target_node) { create(:node, locale: "en") }
67
-
68
- before do
69
- allow_any_instance_of(Releaf::Content::Node::RootValidator).to receive(:validate)
70
- subject.node = source_node
71
- subject.parent_id = target_node.id
72
- end
73
-
74
- it "creates duplicated node under target node" do
75
- new_node = Node.new
76
- duplicated_content = double('content', id: 1234)
77
- expect( Node ).to receive(:new).ordered.and_return(new_node)
78
- expect( new_node ).to receive(:assign_attributes_from).with(source_node).ordered.and_call_original
79
- expect( subject ).to receive(:duplicate_content).ordered.and_return(duplicated_content)
80
- expect( new_node ).to receive(:content_id=).with(1234).ordered
81
- expect( Releaf::Content::Node::SaveUnderParent ).to receive(:call).with(node: new_node, parent_id: target_node.id)
82
- .ordered.and_call_original
83
- expect(subject.duplicate_under).to eq(new_node)
84
- end
85
-
86
- it "doesn't update settings timestamp" do
87
- expect( Node ).to_not receive(:updated)
88
- subject.duplicate_under
89
- end
90
- end
91
-
92
-
93
- describe "#duplicate_content" do
94
-
95
- let(:content) { node.content }
96
-
97
- before do
98
- allow(subject).to receive(:node).and_return(node)
99
- end
100
-
101
- context "when node has a content object" do
102
-
103
- it "calls #duplicate_object with current content" do
104
- expect(subject).to receive(:duplicate_object).with(content).and_return(content)
105
- subject.duplicate_content
106
- end
107
-
108
- it "saves the duplicated result" do
109
- new_content = subject.duplicate_content
110
- expect(new_content.new_record?).to be false
111
- end
112
-
113
- it "returns the newly saved content" do
114
- new_content = subject.duplicate_content
115
- expect(new_content.id).to_not eq content.id
116
- end
117
- end
118
-
119
- context "when node does not have a content object" do
120
- before do
121
- node.content = nil
122
- end
123
-
124
- it "does nothing" do
125
- expect(subject).to_not receive(:duplicate_object)
126
- expect(node).to_not receive(:save!)
127
- subject.duplicate_content
128
- end
129
- it "returns nil" do
130
- expect(subject.duplicate_content).to be_nil
131
- end
132
- end
133
-
134
- end
135
-
136
-
137
- describe "#duplicate_object" do
138
-
139
- context "when object has no duplicatable associations" do
140
- let(:content_factory) { :text_page }
141
- let(:content_attributes) { { text_html: "html" } }
142
-
143
- it "builds an unsaved copy of the object" do
144
- copy = subject.duplicate_object(original)
145
- expect(copy.class).to be original.class
146
- expect(copy.new_record?).to be true
147
-
148
- expect(copy.text_html).to eq original.text_html
149
- end
150
-
151
- it "uses #deep_clone for copying" do
152
- expect(subject).to receive(:duplicatable_associations).with(original.class).and_call_original
153
- expect(original).to receive(:deep_clone).with( include: [] ).and_call_original
154
- subject.duplicate_object(original)
155
- end
156
-
157
- it "calls #supplement_object_duplication with the original object and its new copy" do
158
- copy = original.dup
159
-
160
- # stub #dup (which is called by deep_clone internally) so that it returns a known instance
161
- allow(original).to receive(:dup).and_return(copy)
162
-
163
- expect(subject).to receive(:supplement_object_duplication).with(original, copy)
164
- subject.duplicate_object(original)
165
- end
166
-
167
- end
168
-
169
- context "when object has duplicatable associations" do
170
- let(:content_factory) { complex_content_factory }
171
-
172
- let(:content_attributes) do
173
- {
174
- intro_text_html: "Intro html",
175
- banner_groups_attributes: [
176
- {
177
- title: "Group title",
178
- banners_attributes: [
179
- url: "Banner url"
180
- ]
181
- },
182
- ]
183
- }
184
- end
185
-
186
- it "passes duplicatable associations to #deep_clone" do
187
- expect(original).to receive(:deep_clone).with( include: complex_content_duplicatable_associations ).and_call_original
188
- subject.duplicate_object(original)
189
- end
190
-
191
- it "builds an unsaved copy with nested copies of associated objects" do
192
- copy = subject.duplicate_object(original)
193
- expect(copy.class).to be original.class
194
- expect(copy.new_record?).to be true
195
- expect(copy.intro_text_html).to eq original.intro_text_html
196
-
197
- original_item = original.banner_groups.first
198
- copied_item = copy.banner_groups.first
199
- expect(copied_item.class).to be original_item.class
200
- expect(copied_item.new_record?).to be true
201
- expect(copied_item.title).to eq original_item.title
202
-
203
- original_nested_item = original.banner_groups.first.banners.first
204
- copied_nested_item = copy.banner_groups.first.banners.first
205
- expect(copied_nested_item.class).to be original_nested_item.class
206
- expect(copied_nested_item.new_record?).to be true
207
- expect(copied_nested_item.url).to eq original_nested_item.url
208
- end
209
-
210
- it "calls #supplement_object_duplication on all cloned objects" do
211
- original_item = original.banner_groups.first
212
- original_nested_item = original_item.banners.first
213
-
214
- expect(subject).to receive(:supplement_object_duplication).with(original, kind_of(original.class))
215
- expect(subject).to receive(:supplement_object_duplication).with(original_item, kind_of(original_item.class))
216
- expect(subject).to receive(:supplement_object_duplication).with(original_nested_item, kind_of(original_nested_item.class))
217
- subject.duplicate_object(original)
218
- end
219
-
220
- end
221
-
222
- end
223
-
224
- describe "#supplement_object_duplication" do
225
- it "calls #duplicate_dragonfly_attachments with given original and copy" do
226
- expect(subject).to receive(:duplicate_dragonfly_attachments).with(:foo, :bar)
227
- subject.supplement_object_duplication(:foo, :bar)
228
- end
229
- end
230
-
231
- describe "#duplicatable_associations" do
232
- let(:content_class) { build(content_factory).class }
233
-
234
- it "uses Releaf::ResourceBase to detect duplicatable associations" do
235
- expect(Releaf::ResourceBase).to receive(:new).with(content_class).and_call_original
236
- subject.duplicatable_associations(content_class)
237
- end
238
-
239
- context "when given class has duplicatable associations" do
240
- it "returns duplicatable association names as nested arrays of hashes" do
241
- expect(subject.duplicatable_associations(content_class)).to eq []
242
- end
243
- end
244
-
245
- context "when given class has no duplicatable associations" do
246
- let(:content_factory) { complex_content_factory }
247
- it "returns an empty array" do
248
- expect(subject.duplicatable_associations(content_class)).to eq complex_content_duplicatable_associations
249
- end
250
- end
251
- end
252
-
253
-
254
- describe "#duplicate_dragonfly_attachments" do
255
- let(:content_factory) { complex_content_factory }
256
- let(:copy) { original.dup }
257
-
258
- context "when the original object's dragonfly attributes" do
259
-
260
- context "are blank" do
261
- it "sets the file attributes to nil on the given copy" do
262
- expect(copy).to receive(:top_banner_uid=).with(nil).ordered
263
- expect(copy).to receive(:top_banner=).with(nil).ordered
264
- subject.duplicate_dragonfly_attachments(original, copy)
265
- end
266
- end
267
-
268
- context "contain files" do
269
-
270
- it "separates the attachments so that dragonfly treats them as separate files" do
271
- # it is important that the owner class used in this test has at least two dragonfly attributes
272
- # and the test is not using the first one.
273
- # (an earlier implementation worked only with the first file
274
- # and would have passed the test if the test used the first file)
275
- expect(original.dragonfly_attachments.keys.find_index(:bottom_banner)).to be > 0
276
-
277
- original.bottom_banner = file
278
- original.save!
279
-
280
- subject.duplicate_dragonfly_attachments(original, copy)
281
- copy.save!
282
-
283
- # refetch the objects. calling #reload on them is not enough
284
- original_id = original.id
285
- copy_id = copy.id
286
- klass = original.class
287
-
288
- original = klass.find(original_id)
289
- copy = klass.find(copy_id)
290
-
291
- # make sure the uids are non-empty and different
292
- expect(original.bottom_banner_uid).to be_present
293
- expect(copy.bottom_banner_uid).to be_present
294
- expect(copy.bottom_banner_uid).to_not eq original.bottom_banner_uid
295
-
296
- # make sure the files are stored and exist
297
- expect(copy.bottom_banner.path).to start_with Dragonfly.app.datastore.root_path
298
- expect(original.bottom_banner.path).to start_with Dragonfly.app.datastore.root_path
299
- expect(copy.bottom_banner.path).to_not eq original.bottom_banner.path
300
-
301
- # make sure the metadata is readable as well
302
- expect(copy.bottom_banner.format).to eq original.bottom_banner.format
303
- end
304
-
305
- end
306
-
307
- context "contain files that are missing" do
308
-
309
- it "sets the file attributes to nil on the given copy" do
310
- original.top_banner = file
311
- original.save!
312
-
313
- original_id = original.id
314
-
315
- # simulate deletion from filesystem by setting the uid to an invalid path
316
- original.top_banner_uid = "xxx" + original.top_banner_uid
317
- original.save!
318
-
319
- klass = original.class
320
- original = klass.find(original_id)
321
-
322
- subject.duplicate_dragonfly_attachments(original, copy)
323
- copy.save!
324
- copy_id = copy.id
325
- copy = klass.find(copy_id)
326
-
327
- expect(copy.top_banner_uid).to be_nil
328
- expect(copy.top_banner).to be_nil
329
- end
330
-
331
- end
332
-
333
- end
334
- end
335
-
336
-
337
-
338
- end
@@ -1,20 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Releaf::Content::Node::Move do
4
- class DummyNodeServiceIncluder
5
- include Releaf::Content::Node::Service
6
- end
7
-
8
- let(:node){ Node.new }
9
- subject{ described_class.new(node: node, parent_id: 12) }
10
-
11
- describe "#call" do
12
- context "when parent is same" do
13
- it "does nothing and returns self" do
14
- node.parent_id = 12
15
- expect(node.class).to_not receive(:transaction)
16
- expect(subject.call).to eq(node)
17
- end
18
- end
19
- end
20
- end
@@ -1,49 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Releaf::Content::Node::SaveUnderParent do
4
- class DummyNodeServiceIncluder
5
- include Releaf::Content::Node::Service
6
- end
7
-
8
- let(:root_node){ create(:node, locale: "lv") }
9
- let(:node){ build(:text_page_node) }
10
- subject{ described_class.new(node: node, parent_id: root_node.id) }
11
-
12
- describe "#call" do
13
- it "saves node nuder node with given node_id" do
14
- node2 = create(:text_page_node, parent: root_node)
15
-
16
- subject.parent_id = node2.id
17
- subject.call
18
- expect( node ).to_not be_new_record
19
- expect( node.parent ).to eq node2
20
- end
21
-
22
- it "maintains node name and slug, then saves record" do
23
- expect( node ).to receive(:maintain_name).ordered.and_call_original
24
- expect( node ).to receive(:maintain_slug).ordered.and_call_original
25
- expect( node ).to receive(:save!).ordered.and_call_original
26
- subject.call
27
- end
28
-
29
- context "when #validate_root_locale_uniqueness? returns true" do
30
- let(:node){ root_node }
31
-
32
- it "sets locale to nil" do
33
- allow(node).to receive(:validate_root_locale_uniqueness?).and_return(true)
34
- subject.parent_id = nil
35
- expect { subject.call }.to change{ node.locale }.from("lv").to(nil)
36
- end
37
- end
38
-
39
- context "when #validate_root_locale_uniqueness? returns false" do
40
- let(:node){ root_node }
41
-
42
- it "doesn't set locale to nil" do
43
- allow(node).to receive(:validate_root_locale_uniqueness?).and_return(false)
44
- subject.parent_id = nil
45
- expect { subject.call }.to_not change{ node.locale }
46
- end
47
- end
48
- end
49
- end