releaf-content 0.2.1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +19 -21
  3. data/app/assets/javascripts/{releaf/controllers → controllers}/releaf/content/nodes.js +0 -0
  4. data/app/assets/stylesheets/{releaf/controllers → controllers}/releaf/content/nodes.scss +0 -0
  5. data/app/builders/releaf/content/builders/action_dialog.rb +9 -1
  6. data/app/builders/releaf/content/builders/tree.rb +1 -1
  7. data/app/builders/releaf/content/content_type_dialog_builder.rb +2 -2
  8. data/app/builders/releaf/content/nodes/form_builder.rb +3 -3
  9. data/app/builders/releaf/content/nodes/index_builder.rb +1 -1
  10. data/app/builders/releaf/content/nodes/toolbox_builder.rb +0 -5
  11. data/app/controllers/releaf/content/nodes_controller.rb +109 -129
  12. data/app/middleware/releaf/content/routes_reloader.rb +12 -4
  13. data/app/services/releaf/content/node/copy.rb +90 -0
  14. data/app/services/releaf/content/node/move.rb +21 -0
  15. data/app/services/releaf/content/node/save_under_parent.rb +22 -0
  16. data/app/services/releaf/content/node/service.rb +17 -0
  17. data/app/validators/releaf/content/node/singleness_validator.rb +1 -24
  18. data/lib/releaf-content.rb +85 -6
  19. data/lib/releaf/content/acts_as_node.rb +0 -5
  20. data/lib/releaf/content/acts_as_node/active_record/acts/node.rb +2 -8
  21. data/lib/releaf/content/configuration.rb +61 -0
  22. data/lib/releaf/content/engine.rb +1 -34
  23. data/lib/releaf/content/node.rb +30 -101
  24. data/lib/releaf/content/node_mapper.rb +28 -2
  25. data/lib/releaf/content/route.rb +37 -25
  26. data/spec/builders/content/nodes/action_dialog_spec.rb +39 -0
  27. data/spec/builders/content/nodes/form_builder_spec.rb +47 -3
  28. data/spec/builders/content/nodes/toolbox_builder_spec.rb +1 -32
  29. data/spec/controllers/releaf/content/nodes_controller_spec.rb +42 -11
  30. data/spec/features/nodes_services_spec.rb +207 -0
  31. data/spec/features/nodes_spec.rb +328 -30
  32. data/spec/lib/releaf/content/acts_as_node_spec.rb +4 -32
  33. data/spec/lib/releaf/content/configuration_spec.rb +159 -0
  34. data/spec/lib/releaf/content/engine_spec.rb +149 -0
  35. data/spec/lib/releaf/content/node_spec.rb +66 -324
  36. data/spec/lib/releaf/content/route_spec.rb +223 -34
  37. data/spec/middleware/routes_reloader_spec.rb +62 -14
  38. data/spec/routing/node_mapper_spec.rb +223 -55
  39. data/spec/services/releaf/content/node/copy_spec.rb +115 -0
  40. data/spec/services/releaf/content/node/move_spec.rb +20 -0
  41. data/spec/services/releaf/content/node/save_under_parent_spec.rb +49 -0
  42. data/spec/services/releaf/content/node/service_spec.rb +19 -0
  43. metadata +38 -21
  44. data/app/builders/releaf/content/go_to_dialog_builder.rb +0 -9
  45. data/app/views/releaf/content/nodes/go_to_dialog.ruby +0 -1
  46. data/lib/releaf/content/builders_autoload.rb +0 -18
  47. data/releaf-content.gemspec +0 -20
@@ -35,23 +35,15 @@ describe ActsAsNode do
35
35
  end
36
36
  end
37
37
 
38
- describe "#node" do
39
- it "returns corresponding node object" do
40
- allow_any_instance_of(Releaf::Content::Node::RootValidator).to receive(:validate)
41
- node = create(:node, content_type: "Book", content_attributes: {title: "xx"})
42
- expect(Book.last.node).to eq(node)
43
- end
44
- end
45
-
46
38
  context ".acts_as_node_params" do
47
39
  before do
48
- allow_any_instance_of(Releaf::Core::ResourceParams).to receive(:values).and_return(["a", "b"])
40
+ allow_any_instance_of(Releaf::ResourceParams).to receive(:values).and_return(["a", "b"])
49
41
  end
50
42
 
51
43
  context "when `params` configuration is nil" do
52
44
  it "returns model params with `id` param" do
53
45
  allow(Book).to receive(:acts_as_node_configuration).and_return(params: nil)
54
- expect(Releaf::Core::ResourceParams).to receive(:new).with(Book).and_call_original
46
+ expect(Releaf::ResourceParams).to receive(:new).with(Book).and_call_original
55
47
  expect(Book.acts_as_node_params).to eq(["a", "b", :id])
56
48
  end
57
49
  end
@@ -66,13 +58,13 @@ describe ActsAsNode do
66
58
 
67
59
  context ".acts_as_node_fields" do
68
60
  before do
69
- allow_any_instance_of(Releaf::Core::ResourceFields).to receive(:values).and_return(["a", "b"])
61
+ allow_any_instance_of(Releaf::ResourceFields).to receive(:values).and_return(["a", "b"])
70
62
  end
71
63
 
72
64
  context "when `fields` configuration is nil" do
73
65
  it "returns model fields" do
74
66
  allow(Book).to receive(:acts_as_node_configuration).and_return(fields: nil)
75
- expect(Releaf::Core::ResourceFields).to receive(:new).with(Book).and_call_original
67
+ expect(Releaf::ResourceFields).to receive(:new).with(Book).and_call_original
76
68
  expect(Book.acts_as_node_fields).to eq(["a", "b"])
77
69
  end
78
70
  end
@@ -85,16 +77,6 @@ describe ActsAsNode do
85
77
  end
86
78
  end
87
79
 
88
- context ".nodes" do
89
- it "loads tree nodes" do
90
- expect(Node).to receive(:where).with(content_type: Book.name)
91
- Book.nodes
92
- end
93
-
94
- it "returns relation" do
95
- expect(Book.nodes.class).to eq(Node::ActiveRecord_Relation)
96
- end
97
- end
98
80
  end
99
81
 
100
82
  describe ActionController::Acts::Node do
@@ -104,15 +86,5 @@ describe ActsAsNode do
104
86
  end
105
87
  end
106
88
 
107
- context ".nodes" do
108
- it "loads tree nodes" do
109
- expect(Node).to receive(:where).with(content_type: ContactFormController.name)
110
- ContactFormController.nodes
111
- end
112
-
113
- it "returns array" do
114
- expect(ContactFormController.nodes.class).to eq(Node::ActiveRecord_Relation)
115
- end
116
- end
117
89
  end
118
90
  end
@@ -0,0 +1,159 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Content::Configuration do
4
+ class ContentConfigurationDummyNode; end;
5
+ class ContentConfigurationDummyNodesController; end;
6
+ subject{ described_class.new(resources: {}) }
7
+
8
+ describe "#verify_resources_config" do
9
+ context "when valid config" do
10
+ it "does no raise an error" do
11
+ config = {'Node' => { controller: 'Releaf::Content::NodesController'}}
12
+ expect{ subject.verify_resources_config(config) }.to_not raise_error
13
+ end
14
+ end
15
+
16
+ context "when config is not a hash" do
17
+ it "raises an error" do
18
+ config = :foo
19
+ expect{ subject.verify_resources_config(config) }.to raise_error Releaf::Error, "Releaf.application.config.content.resources must be a Hash"
20
+ end
21
+ end
22
+
23
+ context "when any of the hash keys are not strings" do
24
+ it "raises an error" do
25
+ config = {Node => { controller: 'Releaf::Content::NodesController', foo: "wat"}}
26
+ expect{ subject.verify_resources_config(config) }.to raise_error Releaf::Error, "Releaf.application.config.content.resources must have string keys"
27
+ end
28
+ end
29
+
30
+ context "when any of the entries does not have a hash as a value" do
31
+ it "raises an error" do
32
+ config = {'Node' => :foo}
33
+ expect{ subject.verify_resources_config(config) }.to raise_error Releaf::Error, "Node in Releaf.application.config.content.resources must have a hash value"
34
+ end
35
+ end
36
+
37
+ context "when any of the entries does not have controller class name set" do
38
+ it "raises an error" do
39
+ config = {'Node' => { foo: "wat" }}
40
+ expect{ subject.verify_resources_config(config) }.to raise_error Releaf::Error, "Node in Releaf.application.config.content.resources must have controller class specified as a string"
41
+ end
42
+ end
43
+
44
+ context "when any of the entries does not have a string for the controller class name" do
45
+ it "raises an error" do
46
+ config = {'Node' => { controller: Releaf::Content::NodesController, foo: "wat" }}
47
+ expect{ subject.verify_resources_config(config) }.to raise_error Releaf::Error, "Node in Releaf.application.config.content.resources must have controller class specified as a string"
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#models" do
53
+ it "returns an array of node model classes" do
54
+ expect(subject).to receive(:model_names).and_return(['ContentConfigurationDummyNode', 'Object'])
55
+ expect(subject.models).to eq [ContentConfigurationDummyNode, Object]
56
+ end
57
+ end
58
+
59
+ describe "#model_names" do
60
+ it "returns an array of defined node class names" do
61
+ expect(subject).to receive(:resources).and_return(
62
+ 'ContentConfigurationDummyNode' => { controller: 'Releaf::Content::NodesController' }
63
+ )
64
+ expect(subject.model_names).to eq [ 'ContentConfigurationDummyNode' ]
65
+ end
66
+
67
+ it "caches the result" do
68
+ expect(subject).to receive(:resources).once.and_call_original
69
+ subject.model_names
70
+ subject.model_names
71
+ end
72
+ end
73
+
74
+ describe "#default_model" do
75
+ it "returns the first model from #models" do
76
+ expect(subject).to receive(:models).and_return [ :foo, :bar ]
77
+ expect(subject.default_model).to eq :foo
78
+ end
79
+ end
80
+
81
+ describe "#controllers" do
82
+ it "returns an array of node controller classes" do
83
+ expect(subject).to receive(:controller_names).and_return([
84
+ 'Releaf::Content::NodesController', 'Admin::OtherSite::OtherNodesController'
85
+ ])
86
+ expect(subject.controllers).to eq [Releaf::Content::NodesController, Admin::OtherSite::OtherNodesController]
87
+ end
88
+ end
89
+
90
+ describe "#controller_names" do
91
+ it "returns an array of defined node controller class names" do
92
+ allow(subject).to receive(:resources).and_return(
93
+ 'Node' => { controller: 'Releaf::Content::NodesController' },
94
+ 'ContentConfigurationDummyNode' => { controller: 'ContentConfigurationDummyNodesController' }
95
+ )
96
+ expect(subject.controller_names).to eq [ 'Releaf::Content::NodesController', 'ContentConfigurationDummyNodesController' ]
97
+ end
98
+
99
+ it "caches the result" do
100
+ expect(subject).to receive(:resources).once.and_call_original
101
+ subject.controller_names
102
+ subject.controller_names
103
+ end
104
+ end
105
+
106
+ describe ".routing" do
107
+ it "returns a hash with all node class names as string keys" do
108
+ allow(subject).to receive(:resources).and_return(
109
+ 'Node' => { controller: 'Releaf::Content::NodesController' },
110
+ 'ContentConfigurationDummyNode' => { controller: 'ContentConfigurationDummyNodesController' }
111
+ )
112
+ result = subject.routing
113
+ expect( result ).to be_a Hash
114
+ expect( result.keys ).to eq ['Node', 'ContentConfigurationDummyNode' ]
115
+ end
116
+
117
+ context "when node has no routing defined" do
118
+ it "returns routing hash with site and constraints set to nil" do
119
+ allow(subject).to receive(:resources).and_return(
120
+ 'Node' => { controller: 'Releaf::Content::NodesController' }
121
+ )
122
+ expect(subject.routing).to eq 'Node' => { site: nil, constraints: nil }
123
+ end
124
+ end
125
+
126
+ context "when node has nil values for site and constraints in routing config" do
127
+ it "returns routing hash with site and constraints set to nil" do
128
+ allow(subject).to receive(:resources).and_return(
129
+ 'Node' => {controller: 'Releaf::Content::NodesController', routing: { site: nil, constraints: nil }}
130
+ )
131
+ expect(subject.routing).to eq 'Node' => { site: nil, constraints: nil }
132
+ end
133
+ end
134
+
135
+ context "when node has site defined in routing config" do
136
+ it "returns the defined value in routing hash" do
137
+ allow(subject).to receive(:resources).and_return(
138
+ 'Node' => {controller: 'Releaf::Content::NodesController', routing: { site: "foo" }}
139
+ )
140
+ expect(subject.routing).to eq 'Node' => { site: "foo", constraints: nil }
141
+ end
142
+ end
143
+
144
+ context "when node has constraints defined in routing config" do
145
+ it "returns the defined value in routing hash" do
146
+ allow(subject).to receive(:resources).and_return(
147
+ 'Node' => {controller: 'Releaf::Content::NodesController', routing: { constraints: { host: /foo/ }}}
148
+ )
149
+ expect(subject.routing).to eq 'Node' => { site: nil, constraints: { host: /foo/ } }
150
+ end
151
+ end
152
+
153
+ it "caches the result" do
154
+ expect(subject).to receive(:resources).once.and_call_original
155
+ subject.routing
156
+ subject.routing
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,149 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Content do
4
+ let(:configuration){ Releaf::Content::Configuration.new(resources: {}) }
5
+
6
+ describe ".configure_component" do
7
+ it "adds new `Releaf::Content::Configuration` configuration with default resources" do
8
+ allow(Releaf::Content::Configuration).to receive(:new)
9
+ .with(resources: { 'Node' => { controller: 'Releaf::Content::NodesController' } }).and_return("_new")
10
+ expect(Releaf.application.config).to receive(:add_configuration).with("_new")
11
+ described_class.configure_component
12
+ end
13
+ end
14
+
15
+ describe ".configuration" do
16
+ it "returns a configuration instance" do
17
+ expect(Releaf.application.config).to receive(:content).and_return(:ok)
18
+ expect(described_class.configuration).to eq :ok
19
+ end
20
+ end
21
+
22
+ [ :resources, :models, :default_model, :controllers, :routing ].each do |method|
23
+ describe ".#{method}" do
24
+ it "returns the method result from the configuration instance" do
25
+ allow(described_class).to receive(:configuration).and_return(configuration)
26
+ allow(configuration).to receive(method).and_return(:ok)
27
+ expect(described_class.send(method)).to eq :ok
28
+ end
29
+ end
30
+ end
31
+
32
+ describe ".draw_component_routes", type: :routing do
33
+ before do
34
+ allow(described_class).to receive(:configuration).and_return(configuration)
35
+ allow(configuration).to receive(:resources).and_return(
36
+ 'Node' => { controller: 'Releaf::Content::NodesController' },
37
+ 'OtherSite::OtherNode' => { controller: 'Admin::OtherSite::OtherNodesController' }
38
+ )
39
+ Dummy::Application.reload_routes!
40
+ end
41
+
42
+ after(:all) do
43
+ Dummy::Application.reload_routes!
44
+ end
45
+
46
+ context "draws named admin routes for all defined content node controllers" do
47
+
48
+ it "draws #index route" do
49
+ expect( releaf_content_nodes_path ).to eq "/admin/nodes"
50
+ expect( admin_other_site_other_nodes_path ).to eq "/admin/other_nodes"
51
+ expect(get: "/admin/nodes").to route_to("releaf/content/nodes#index")
52
+ expect(get: "/admin/other_nodes").to route_to("admin/other_site/other_nodes#index")
53
+ end
54
+
55
+ it "draws #new route" do
56
+ expect( new_releaf_content_node_path ).to eq "/admin/nodes/new"
57
+ expect( new_admin_other_site_other_node_path ).to eq "/admin/other_nodes/new"
58
+ expect(get: "/admin/nodes/new").to route_to("releaf/content/nodes#new")
59
+ expect(get: "/admin/other_nodes/new").to route_to("admin/other_site/other_nodes#new")
60
+ end
61
+
62
+ it "draws #create route" do
63
+ expect(post: "/admin/nodes").to route_to("releaf/content/nodes#create")
64
+ expect(post: "/admin/other_nodes").to route_to("admin/other_site/other_nodes#create")
65
+ end
66
+
67
+ it "draws #content_type_dialog route" do
68
+ expect( content_type_dialog_releaf_content_nodes_path ).to eq "/admin/nodes/content_type_dialog"
69
+ expect( content_type_dialog_admin_other_site_other_nodes_path ).to eq "/admin/other_nodes/content_type_dialog"
70
+ expect(get: "/admin/nodes/content_type_dialog").to route_to("releaf/content/nodes#content_type_dialog")
71
+ expect(get: "/admin/other_nodes/content_type_dialog").to route_to("admin/other_site/other_nodes#content_type_dialog")
72
+ end
73
+
74
+ it "draws #generate_url route" do
75
+ expect( generate_url_releaf_content_nodes_path ).to eq "/admin/nodes/generate_url"
76
+ expect( generate_url_admin_other_site_other_nodes_path ).to eq "/admin/other_nodes/generate_url"
77
+ expect(get: "/admin/nodes/generate_url").to route_to("releaf/content/nodes#generate_url")
78
+ expect(get: "/admin/other_nodes/generate_url").to route_to("admin/other_site/other_nodes#generate_url")
79
+ end
80
+
81
+ it "draws #edit route" do
82
+ expect( edit_releaf_content_node_path(1) ).to eq "/admin/nodes/1/edit"
83
+ expect( edit_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/edit"
84
+ expect(get: "/admin/nodes/1/edit").to route_to("releaf/content/nodes#edit", "id" => "1")
85
+ expect(get: "/admin/other_nodes/1/edit").to route_to("admin/other_site/other_nodes#edit", "id" => "1")
86
+ end
87
+
88
+ it "draws #update route" do
89
+ expect(patch: "/admin/nodes/1").to route_to("releaf/content/nodes#update", "id" => "1")
90
+ expect(patch: "/admin/other_nodes/1").to route_to("admin/other_site/other_nodes#update", "id" => "1")
91
+ end
92
+
93
+ it "draws #copy_dialog route" do
94
+ expect( copy_dialog_releaf_content_node_path(1) ).to eq "/admin/nodes/1/copy_dialog"
95
+ expect( copy_dialog_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/copy_dialog"
96
+ expect(get: "/admin/nodes/1/copy_dialog").to route_to("releaf/content/nodes#copy_dialog", "id" => "1")
97
+ expect(get: "/admin/other_nodes/1/copy_dialog").to route_to("admin/other_site/other_nodes#copy_dialog", "id" => "1")
98
+ end
99
+
100
+ it "draws #copy route" do
101
+ expect( copy_releaf_content_node_path(1) ).to eq "/admin/nodes/1/copy"
102
+ expect( copy_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/copy"
103
+ expect(post: "/admin/nodes/1/copy").to route_to("releaf/content/nodes#copy", "id" => "1")
104
+ expect(post: "/admin/other_nodes/1/copy").to route_to("admin/other_site/other_nodes#copy", "id" => "1")
105
+ end
106
+
107
+ it "draws #move_dialog route" do
108
+ expect( move_dialog_releaf_content_node_path(1) ).to eq "/admin/nodes/1/move_dialog"
109
+ expect( move_dialog_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/move_dialog"
110
+ expect(get: "/admin/nodes/1/move_dialog").to route_to("releaf/content/nodes#move_dialog", "id" => "1")
111
+ expect(get: "/admin/other_nodes/1/move_dialog").to route_to("admin/other_site/other_nodes#move_dialog", "id" => "1")
112
+ end
113
+
114
+ it "draws #move route" do
115
+ expect( move_releaf_content_node_path(1) ).to eq "/admin/nodes/1/move"
116
+ expect( move_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/move"
117
+ expect(post: "/admin/nodes/1/move").to route_to("releaf/content/nodes#move", "id" => "1")
118
+ expect(post: "/admin/other_nodes/1/move").to route_to("admin/other_site/other_nodes#move", "id" => "1")
119
+ end
120
+
121
+ it "draws #toolbox route" do
122
+ expect( toolbox_releaf_content_node_path(1) ).to eq "/admin/nodes/1/toolbox"
123
+ expect( toolbox_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/toolbox"
124
+ expect(get: "/admin/nodes/1/toolbox").to route_to("releaf/content/nodes#toolbox", "id" => "1")
125
+ expect(get: "/admin/other_nodes/1/toolbox").to route_to("admin/other_site/other_nodes#toolbox", "id" => "1")
126
+ end
127
+
128
+ it "draws #confirm_destroy route" do
129
+ expect( confirm_destroy_releaf_content_node_path(1) ).to eq "/admin/nodes/1/confirm_destroy"
130
+ expect( confirm_destroy_admin_other_site_other_node_path(1) ).to eq "/admin/other_nodes/1/confirm_destroy"
131
+ expect(get: "/admin/nodes/1/confirm_destroy").to route_to("releaf/content/nodes#confirm_destroy", "id" => "1")
132
+ expect(get: "/admin/other_nodes/1/confirm_destroy").to route_to("admin/other_site/other_nodes#confirm_destroy", "id" => "1")
133
+ end
134
+
135
+ it "draws #destroy route" do
136
+ expect(delete: "/admin/nodes/1").to route_to("releaf/content/nodes#destroy", "id" => "1")
137
+ expect(delete: "/admin/other_nodes/1").to route_to("admin/other_site/other_nodes#destroy", "id" => "1")
138
+ end
139
+
140
+ it "does not draw #show route" do
141
+ expect(get: "/admin/nodes/1").to route_to("releaf/errors#page_not_found", "path" => "nodes/1")
142
+ expect(get: "/admin/other_nodes/1").to route_to("releaf/errors#page_not_found", "path" => "other_nodes/1")
143
+ end
144
+
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -42,14 +42,14 @@ describe Node do
42
42
  context 'when #content_type is nil' do
43
43
  it 'returns nil' do
44
44
  subject.content_type = nil
45
- expect( subject.content_class ).to be_nil
45
+ expect( subject.content_class ).to be nil
46
46
  end
47
47
  end
48
48
 
49
49
  context "when #content_type is blank string" do
50
50
  it 'returns nil' do
51
51
  subject.content_type = ""
52
- expect( subject.content_class ).to be_nil
52
+ expect( subject.content_class ).to be nil
53
53
  end
54
54
  end
55
55
 
@@ -121,8 +121,15 @@ describe Node do
121
121
 
122
122
  describe "#attributes_to_not_copy" do
123
123
  it "returns array with attributes" do
124
+ subject.locale = "lv"
124
125
  expect( subject.attributes_to_not_copy ).to match_array %w[content_id depth id item_position lft rgt slug created_at updated_at]
125
126
  end
127
+
128
+ context "when locale is blank" do
129
+ it "includes locale within returned list" do
130
+ expect( subject.attributes_to_not_copy ).to match_array %w[content_id depth id item_position lft rgt slug created_at updated_at locale]
131
+ end
132
+ end
126
133
  end
127
134
 
128
135
  describe "#attributes_to_copy" do
@@ -142,76 +149,7 @@ describe Node do
142
149
  end
143
150
  end
144
151
 
145
- describe "#save_under" do
146
- let(:node1) { create(:node) }
147
-
148
- it "saves node nuder node with given node_id" do
149
- node2 = create(:text_page_node, parent: node1)
150
-
151
- new_node = FactoryGirl.build(:text_page_node)
152
- new_node.send(:save_under, node2.id)
153
- expect( new_node ).to_not be_new_record
154
- expect( new_node.parent ).to eq node2
155
- end
156
-
157
- it "maintains node name, updates slug and then saves record" do
158
- new_node = FactoryGirl.build(:text_page_node)
159
- expect( new_node ).to receive(:maintain_name).ordered.and_call_original
160
- expect( new_node ).to receive(:reasign_slug).ordered.and_call_original
161
- expect( new_node ).to receive(:save!).ordered.and_call_original
162
- new_node.save_under(node1.id)
163
- end
164
-
165
- context "when #validate_root_locale_uniqueness? returns true" do
166
- it "sets locale to nil" do
167
- new_node = FactoryGirl.build(:node)
168
- allow(new_node).to receive(:validate_root_locale_uniqueness?).and_return(true)
169
- new_node.locale = 'xx'
170
- expect { new_node.save_under(nil) }.to change { new_node.locale }.from('xx').to(nil)
171
- end
172
- end
173
-
174
- context "when #validate_root_locale_uniqueness? returns false" do
175
- it "doesn't set locale to nil" do
176
- new_node = FactoryGirl.build(:node)
177
- allow(new_node).to receive(:validate_root_locale_uniqueness?).and_return(false)
178
- new_node.locale = 'xx'
179
- expect { new_node.save_under(nil) }.to_not change { new_node.locale }.from('xx')
180
- end
181
- end
182
-
183
- end
184
-
185
-
186
- describe "#duplicate_content" do
187
-
188
- context "when #content_id is blank" do
189
- let(:node) { create(:node) }
190
-
191
- it "returns nil" do
192
- expect( node.duplicate_content ).to be_nil
193
- end
194
- end
195
-
196
- context "when #content_id is not blank" do
197
- let(:node) { create(:home_page_node) }
198
-
199
- it "returns saved duplicated content" do
200
- content = double('new content')
201
- expect( content ).to receive(:save!)
202
- expect( node ).to receive_message_chain(:content, :dup).and_return(content)
203
- expect( node.duplicate_content ).to eq content
204
- end
205
-
206
- it "doesn't return same as original content" do
207
- result = node.duplicate_content
208
- expect( result ).to be_an_instance_of HomePage
209
- expect( result.id ).to_not eq node.content_id
210
- end
211
- end
212
- end
213
-
214
- describe "#copy_attributes_from" do
152
+ describe "#assign_attributes_from" do
215
153
  let(:source_node) { create(:node, active: false) }
216
154
 
217
155
  it "copies #attributes_to_copy attributes" do
@@ -225,181 +163,11 @@ describe Node do
225
163
 
226
164
  new_node = Node.new
227
165
 
228
- new_node.copy_attributes_from source_node
229
-
230
- expect( new_node.parent_id ).to be_nil
231
- expect( new_node.content_type ).to be_nil
232
- expect( new_node.active ).to be_truthy
233
- end
234
- end
235
-
236
- describe "#duplicate_under!" do
237
- let!(:source_node) { create(:node, locale: "lv") }
238
- let!(:target_node) { create(:node, locale: "en") }
239
-
240
- before do
241
- allow_any_instance_of(Releaf::Content::Node::RootValidator).to receive(:validate)
242
- end
243
-
244
- it "creates duplicated node under target node" do
245
- new_node = Node.new
246
- duplicated_content = double('content', id: 1234)
247
- expect( Node ).to receive(:new).ordered.and_return(new_node)
248
- expect( new_node ).to receive(:copy_attributes_from).with(source_node).ordered.and_call_original
249
- expect( source_node ).to receive(:duplicate_content).ordered.and_return(duplicated_content)
250
- expect( new_node ).to receive(:content_id=).with(1234).ordered
251
- expect( new_node ).to receive(:save_under).with(target_node.id).ordered.and_call_original
252
- source_node.duplicate_under!(target_node.id)
253
- end
166
+ new_node.assign_attributes_from source_node
254
167
 
255
- it "doesn't update settings timestamp" do
256
- expect( Node ).to_not receive(:updated)
257
- source_node.duplicate_under!(target_node.id)
258
- end
259
- end
260
-
261
- describe "#copy", create_nodes: true do
262
- before create_nodes: true do
263
- @home_page_node = create(:home_page_node, locale: "lv")
264
- @home_page_node_2 = create(:home_page_node, locale: "en")
265
- @text_page_node_3 = create(:text_page_node, parent_id: @home_page_node_2.id)
266
- @text_page_node_4 = create(:text_page_node, parent_id: @text_page_node_3.id)
267
- @text_page_node_5 = create(:text_page_node, parent_id: @text_page_node_4.id)
268
-
269
- # it is important to reload nodes, otherwise associations will return empty set
270
- @home_page_node.reload
271
- @home_page_node_2.reload
272
- @text_page_node_3.reload
273
- @text_page_node_4.reload
274
- end
275
-
276
- context "when one of children becomes invalid" do
277
- before do
278
- @text_page_node_4.name = nil
279
- @text_page_node_4.save(validate: false)
280
- end
281
-
282
- it "raises ActiveRecord::RecordInvalid" do
283
- expect { @text_page_node_3.copy(@home_page_node.id) }.to raise_error ActiveRecord::RecordInvalid
284
- end
285
-
286
- it "raises error on node being copied" do
287
- begin
288
- @text_page_node_3.copy(@home_page_node.id)
289
- rescue ActiveRecord::RecordInvalid => e
290
- expect( e.record ).to eq @text_page_node_3
291
- end
292
- expect(@text_page_node_3.errors.messages).to eq(base: ["descendant invalid"])
293
- end
294
-
295
- it "doesn't create any new nodes" do
296
- expect do
297
- begin
298
- @text_page_node_3.copy(@home_page_node.id)
299
- rescue ActiveRecord::RecordInvalid
300
- end
301
- end.to_not change { Node.count }
302
- end
303
-
304
- it "doesn't update settings timestamp" do
305
- expect( Node ).to_not receive(:updated)
306
- begin
307
- @text_page_node_3.copy(@home_page_node.id)
308
- rescue ActiveRecord::RecordInvalid
309
- end
310
- end
311
-
312
- end
313
-
314
-
315
- context "with corect parent_id" do
316
- it "creates node along with descendant nodes" do
317
- expect{ @text_page_node_3.copy(@home_page_node.id) }.to change{ Node.count }.by( @text_page_node_3.descendants.size + 1 )
318
- end
319
-
320
- it "correctly copies attributes" do
321
- allow( @text_page_node_3 ).to receive(:children).and_return([@text_page_node_4])
322
- allow( @text_page_node_4 ).to receive(:children).and_return([@text_page_node_5])
323
-
324
- @text_page_node_3.update_attribute(:active, false)
325
- @text_page_node_4.update_attribute(:active, false)
326
-
327
- allow( @text_page_node_3 ).to receive(:attributes_to_copy).and_return(["name", "parent_id", "content_type"])
328
-
329
- expect( @text_page_node_3 ).to receive(:duplicate_under!).and_call_original.ordered
330
- expect( @text_page_node_4 ).to receive(:duplicate_under!).and_call_original.ordered
331
- expect( @text_page_node_5 ).to receive(:duplicate_under!).and_call_original.ordered
332
-
333
- @text_page_node_3.copy(@home_page_node.id)
334
-
335
- @node_2_copy = @home_page_node.children.first
336
- @node_3_copy = @node_2_copy.children.first
337
- @node_4_copy = @node_3_copy.children.first
338
-
339
- # new nodes by default are active, however we stubbed
340
- # #attributes_to_copy of @test_node_2 to not return active attribute
341
- # Also we updated @test_node_2#active to be false.
342
- # However copy is active, because active attribute wasn't copied
343
- expect( @node_2_copy ).to be_active
344
- # for copy of @text_page_node_3 active attribute was copied however, as it
345
- # should have been
346
- expect( @node_3_copy ).to_not be_active
347
- expect( @node_4_copy ).to be_active
348
-
349
- expect( @node_2_copy.name ).to eq @text_page_node_3.name
350
- expect( @node_3_copy.name ).to eq @text_page_node_4.name
351
- expect( @node_4_copy.name ).to eq @text_page_node_5.name
352
- end
353
-
354
- it "updates settings timestamp only once" do
355
- expect( Node ).to receive(:updated).once.and_call_original
356
- @text_page_node_3.copy(@home_page_node.id)
357
- end
358
-
359
- context "when parent_id is nil" do
360
- it "creates new node" do
361
- allow_any_instance_of(Releaf::Content::Node::RootValidator).to receive(:validate)
362
- expect{ @text_page_node_3.copy(nil) }.to change{ Node.count }.by(3)
363
- end
364
- end
365
-
366
- context "when copying root nodes", create_nodes: false do
367
- context "when root locale uniqueness is validated" do
368
- it "resets locale to nil" do
369
- @text_page_node = create(:home_page_node, locale: 'en')
370
- allow_any_instance_of(Node).to receive(:validate_root_locale_uniqueness?).and_return(true)
371
- @text_page_node.copy(nil)
372
- expect( Node.last.locale ).to eq nil
373
- end
374
- end
375
-
376
- context "when root locale uniqueness is not validated" do
377
- it "doesn't reset locale to nil" do
378
- @text_page_node = create(:home_page_node, locale: 'en')
379
- allow_any_instance_of(Node).to receive(:validate_root_locale_uniqueness?).and_return(false)
380
- @text_page_node.copy(nil)
381
- expect( Node.last.locale ).to eq 'en'
382
- end
383
- end
384
- end
385
- end
386
-
387
- context "with nonexistent parent_id" do
388
- it "raises ActiveRecord::RecordInvalid" do
389
- expect { @text_page_node_3.copy(99991) }.to raise_error(ActiveRecord::RecordInvalid)
390
- end
391
- end
392
-
393
- context "with same parent_id as node.id" do
394
- it "raises ActiveRecord::RecordInvalid" do
395
- expect{ @text_page_node_3.copy(@text_page_node_3.id) }.to raise_error(ActiveRecord::RecordInvalid)
396
- end
397
- end
398
-
399
- context "when copying to child node" do
400
- it "raises ActiveRecord::RecordInvalid" do
401
- expect{ @text_page_node_3.copy(@text_page_node_4.id) }.to raise_error(ActiveRecord::RecordInvalid)
402
- end
168
+ expect( new_node.parent_id ).to be nil
169
+ expect( new_node.content_type ).to be nil
170
+ expect( new_node.active ).to be true
403
171
  end
404
172
  end
405
173
 
@@ -437,66 +205,10 @@ describe Node do
437
205
  end
438
206
 
439
207
  describe "#move" do
440
- before do
441
- @home_page_node = create(:home_page_node, locale: "lv")
442
- @home_page_node_2 = create(:home_page_node, locale: "en")
443
- @text_page_node_3 = create(:text_page_node, parent_id: @home_page_node_2.id)
444
- @text_page_node_4 = create(:text_page_node, parent_id: @text_page_node_3.id)
445
-
446
- # it is important to reload nodes, otherwise associations will return empty set
447
- @home_page_node.reload
448
- @home_page_node_2.reload
449
- @text_page_node_3.reload
450
- @text_page_node_4.reload
208
+ it "calls Node move service" do
209
+ expect(Releaf::Content::Node::Move).to receive(:call).with(node: subject, parent_id: 12)
210
+ subject.move(12)
451
211
  end
452
-
453
- context "when one of children becomes invalid" do
454
- before do
455
- @text_page_node_4.name = nil
456
- @text_page_node_4.save(validate: false)
457
- end
458
-
459
- it "raises ActiveRecord::RecordInvalid" do
460
- expect { @text_page_node_3.move(@home_page_node.id) }.to raise_error ActiveRecord::RecordInvalid
461
- end
462
-
463
- it "raises error on node being moved, even tought descendant has error" do
464
- begin
465
- @text_page_node_3.move(@home_page_node.id)
466
- rescue ActiveRecord::RecordInvalid => e
467
- expect( e.record ).to eq @text_page_node_3
468
- end
469
-
470
- expect(@text_page_node_3.errors.messages).to eq(name: [], base: ["descendant invalid"])
471
- end
472
- end
473
-
474
- context "when moving existing node to other nodes child's position" do
475
- it "changes parent_id" do
476
- expect{ @text_page_node_3.move(@home_page_node.id) }.to change{ Node.find(@text_page_node_3.id).parent_id }.from(@home_page_node_2.id).to(@home_page_node.id)
477
- end
478
- end
479
-
480
- context "when moving to self child's position" do
481
- it "raises ActiveRecord::RecordInvalid" do
482
- expect{ @text_page_node_3.move(@text_page_node_3.id) }.to raise_error(ActiveRecord::RecordInvalid)
483
- end
484
- end
485
-
486
- context "when passing nil as target node" do
487
- it "updates parent_id" do
488
- allow_any_instance_of(Releaf::Content::Node::RootValidator).to receive(:validate)
489
- @home_page_node.destroy
490
- expect{ @text_page_node_3.move(nil) }.to change { Node.find(@text_page_node_3.id).parent_id }.to(nil)
491
- end
492
- end
493
-
494
- context "when passing nonexistent target node's id" do
495
- it "raises ActiveRecord::RecordInvalid" do
496
- expect{ @text_page_node_3.move(998123) }.to raise_error(ActiveRecord::RecordInvalid)
497
- end
498
- end
499
-
500
212
  end
501
213
 
502
214
  describe "#maintain_name" do
@@ -719,20 +431,6 @@ describe Node do
719
431
  end
720
432
  end
721
433
 
722
- describe "#add_error_and_raise" do
723
- it "raises error" do
724
- expect { subject.add_error_and_raise('test error') }.to raise_error(ActiveRecord::RecordInvalid)
725
- end
726
-
727
- it "adds record on base and raise ActiveRecord::RecordInvalid" do
728
- begin
729
- subject.add_error_and_raise('test error')
730
- rescue ActiveRecord::RecordInvalid => e
731
- expect( e.record.errors[:base] ).to include 'test error'
732
- end
733
- end
734
- end
735
-
736
434
  describe "#prevent_auto_update_settings_timestamp" do
737
435
  it "sets #prevent_auto_update_settings_timestamp? to true within block" do
738
436
  expect do
@@ -769,11 +467,55 @@ describe Node do
769
467
  end
770
468
 
771
469
  describe "#path" do
772
- it "returns relative path of node" do
773
- node = described_class.new(slug: 'foo')
774
- node2 = described_class.new(slug: 'bar', parent: node)
775
- expect( node.path ).to eq '/foo'
776
- expect( node2.path ).to eq '/foo/bar'
470
+ before do
471
+ allow(subject).to receive(:path_parts).and_return(["some", "bar", "foo"])
472
+ end
473
+
474
+ it "returns relative node path built ny joining node path parts" do
475
+ expect(subject.path).to eq("/some/bar/foo")
476
+ end
477
+
478
+ context "when node has parent" do
479
+ it "ads trailing slash to returned node path" do
480
+ allow(subject).to receive(:trailing_slash_for_path?).and_return(true)
481
+ expect(subject.path).to eq("/some/bar/foo/")
482
+ end
483
+ end
484
+ end
485
+
486
+
487
+ describe "#trailing_slash_for_path?" do
488
+ context "when rails route has trailing slash enabled" do
489
+ it "returns true" do
490
+ allow(Rails.application.routes).to receive(:default_url_options).and_return(trailing_slash: true)
491
+ expect(subject.trailing_slash_for_path?).to be true
492
+ end
493
+ end
494
+
495
+ context "when rails route has trailing slash disabled" do
496
+ it "returns false" do
497
+ allow(Rails.application.routes).to receive(:default_url_options).and_return({})
498
+ expect(subject.trailing_slash_for_path?).to be false
499
+ end
500
+ end
501
+ end
502
+
503
+ describe "#path_parts" do
504
+ it "returns array with slug" do
505
+ expect(subject.path_parts).to eq([""])
506
+ subject.slug = "foo"
507
+ expect(subject.path_parts).to eq(["foo"])
508
+ end
509
+
510
+ context "when node has parent" do
511
+ it "prepends parent path parts to returned array" do
512
+ parent = described_class.new
513
+ allow(parent).to receive(:path_parts).and_return(%w(some bar))
514
+
515
+ subject.slug = "foo"
516
+ subject.parent = parent
517
+ expect(subject.path_parts).to eq(["some", "bar", "foo"])
518
+ end
777
519
  end
778
520
  end
779
521
  end