render_sync 0.5.0

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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +153 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +22 -0
  5. data/README.md +521 -0
  6. data/Rakefile +9 -0
  7. data/app/assets/javascripts/sync.coffee +355 -0
  8. data/app/controllers/sync/refetches_controller.rb +56 -0
  9. data/app/helpers/render_sync/config_helper.rb +15 -0
  10. data/config/routes.rb +3 -0
  11. data/config/sync.yml +21 -0
  12. data/lib/generators/render_sync/install_generator.rb +14 -0
  13. data/lib/generators/render_sync/templates/sync.ru +14 -0
  14. data/lib/generators/render_sync/templates/sync.yml +34 -0
  15. data/lib/render_sync.rb +174 -0
  16. data/lib/render_sync/action.rb +39 -0
  17. data/lib/render_sync/actions.rb +114 -0
  18. data/lib/render_sync/channel.rb +23 -0
  19. data/lib/render_sync/clients/dummy.rb +22 -0
  20. data/lib/render_sync/clients/faye.rb +104 -0
  21. data/lib/render_sync/clients/pusher.rb +77 -0
  22. data/lib/render_sync/controller_helpers.rb +33 -0
  23. data/lib/render_sync/engine.rb +24 -0
  24. data/lib/render_sync/erb_tracker.rb +49 -0
  25. data/lib/render_sync/faye_extension.rb +45 -0
  26. data/lib/render_sync/model.rb +174 -0
  27. data/lib/render_sync/model_actions.rb +60 -0
  28. data/lib/render_sync/model_change_tracking.rb +97 -0
  29. data/lib/render_sync/model_syncing.rb +65 -0
  30. data/lib/render_sync/model_touching.rb +35 -0
  31. data/lib/render_sync/partial.rb +112 -0
  32. data/lib/render_sync/partial_creator.rb +47 -0
  33. data/lib/render_sync/reactor.rb +48 -0
  34. data/lib/render_sync/refetch_model.rb +21 -0
  35. data/lib/render_sync/refetch_partial.rb +43 -0
  36. data/lib/render_sync/refetch_partial_creator.rb +21 -0
  37. data/lib/render_sync/renderer.rb +19 -0
  38. data/lib/render_sync/resource.rb +115 -0
  39. data/lib/render_sync/scope.rb +113 -0
  40. data/lib/render_sync/scope_definition.rb +30 -0
  41. data/lib/render_sync/view_helpers.rb +106 -0
  42. data/test/dummy/README.rdoc +28 -0
  43. data/test/dummy/Rakefile +6 -0
  44. data/test/dummy/app/assets/javascripts/application.js +13 -0
  45. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  46. data/test/dummy/app/controllers/application_controller.rb +5 -0
  47. data/test/dummy/app/helpers/application_helper.rb +2 -0
  48. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  49. data/test/dummy/app/views/sync/users/_show.html.erb +1 -0
  50. data/test/dummy/app/views/sync/users/refetch/_show.html.erb +1 -0
  51. data/test/dummy/bin/bundle +3 -0
  52. data/test/dummy/bin/rails +4 -0
  53. data/test/dummy/bin/rake +4 -0
  54. data/test/dummy/config.ru +4 -0
  55. data/test/dummy/config/application.rb +22 -0
  56. data/test/dummy/config/boot.rb +5 -0
  57. data/test/dummy/config/database.yml +8 -0
  58. data/test/dummy/config/environment.rb +5 -0
  59. data/test/dummy/config/environments/development.rb +29 -0
  60. data/test/dummy/config/environments/production.rb +80 -0
  61. data/test/dummy/config/environments/test.rb +36 -0
  62. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  63. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  64. data/test/dummy/config/initializers/inflections.rb +16 -0
  65. data/test/dummy/config/initializers/mime_types.rb +5 -0
  66. data/test/dummy/config/initializers/secret_token.rb +12 -0
  67. data/test/dummy/config/initializers/session_store.rb +3 -0
  68. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  69. data/test/dummy/config/locales/en.yml +23 -0
  70. data/test/dummy/config/routes.rb +56 -0
  71. data/test/dummy/log/test.log +626 -0
  72. data/test/dummy/public/404.html +58 -0
  73. data/test/dummy/public/422.html +58 -0
  74. data/test/dummy/public/500.html +57 -0
  75. data/test/dummy/public/favicon.ico +0 -0
  76. data/test/em_minitest_spec.rb +100 -0
  77. data/test/fixtures/sync_auth_token_missing.yml +6 -0
  78. data/test/fixtures/sync_erb.yml +7 -0
  79. data/test/fixtures/sync_faye.yml +7 -0
  80. data/test/fixtures/sync_pusher.yml +8 -0
  81. data/test/models/group.rb +3 -0
  82. data/test/models/project.rb +2 -0
  83. data/test/models/todo.rb +8 -0
  84. data/test/models/user.rb +82 -0
  85. data/test/sync/abstract_controller.rb +3 -0
  86. data/test/sync/action_test.rb +82 -0
  87. data/test/sync/channel_test.rb +15 -0
  88. data/test/sync/config_test.rb +25 -0
  89. data/test/sync/erb_tracker_test.rb +72 -0
  90. data/test/sync/faye_extension_test.rb +87 -0
  91. data/test/sync/message_test.rb +159 -0
  92. data/test/sync/model_test.rb +315 -0
  93. data/test/sync/partial_creator_test.rb +35 -0
  94. data/test/sync/partial_test.rb +107 -0
  95. data/test/sync/protected_attributes_test.rb +39 -0
  96. data/test/sync/reactor_test.rb +18 -0
  97. data/test/sync/refetch_model_test.rb +26 -0
  98. data/test/sync/refetch_partial_creator_test.rb +16 -0
  99. data/test/sync/refetch_partial_test.rb +74 -0
  100. data/test/sync/renderer_test.rb +19 -0
  101. data/test/sync/resource_test.rb +181 -0
  102. data/test/sync/scope_definition_test.rb +39 -0
  103. data/test/sync/scope_test.rb +113 -0
  104. data/test/test_helper.rb +66 -0
  105. data/test/travis/sync.ru +14 -0
  106. data/test/travis/sync.yml +21 -0
  107. metadata +317 -0
@@ -0,0 +1,35 @@
1
+ require_relative '../test_helper'
2
+
3
+ describe RenderSync::PartialCreator do
4
+ include TestHelper
5
+
6
+ before do
7
+ @context = ActionController::Base.new
8
+ @partial_creator = RenderSync::PartialCreator.new("show", User.new, scope = nil, @context)
9
+ end
10
+
11
+ describe '#channel' do
12
+ it 'always starts with a forward slash to provide Faye valid channel' do
13
+ assert_equal "/", @partial_creator.channel.first
14
+ end
15
+ end
16
+
17
+ describe '#selector' do
18
+ it 'returns a String selector where partials will be appended in DOM' do
19
+ assert @partial_creator.selector.length > 0
20
+ end
21
+ end
22
+
23
+ describe '#sync_new' do
24
+ it 'publishes a new message to faye to append new partials to DOM' do
25
+ # TODO: Stub Message
26
+ assert @partial_creator.sync_new
27
+ end
28
+ end
29
+
30
+ describe '#message' do
31
+ it 'returns a Message instance for the partial for the update action' do
32
+ assert_equal RenderSync.client.class::Message, @partial_creator.message.class
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,107 @@
1
+ require_relative '../test_helper'
2
+ require 'rails/all'
3
+ require_relative 'abstract_controller'
4
+ require_relative '../models/user'
5
+
6
+ describe RenderSync::Partial do
7
+ include TestHelper
8
+
9
+ before do
10
+ @context = ActionController::Base.new
11
+ @partial = RenderSync::Partial.new("show", User.new, nil, @context)
12
+ end
13
+
14
+ describe '#self.all' do
15
+ it 'returns an array of all Partials for given model' do
16
+ assert_equal 1, RenderSync::Partial.all(User.new, @context).size
17
+ assert_equal RenderSync::Partial, RenderSync::Partial.all(User.new, @context)[0].class
18
+ end
19
+ end
20
+
21
+ describe '#self.find' do
22
+ it 'finds partial given resource and partial name' do
23
+ Dir.stubs(:[]).returns("_show.html.erb")
24
+ assert_equal RenderSync::Partial, RenderSync::Partial.find(User.new, 'show', nil).class
25
+ end
26
+
27
+ it 'returns nil if partial does not exist' do
28
+ Dir.stubs(:[]).returns []
29
+ refute RenderSync::Partial.find(User.new, 'not_exist', nil)
30
+ end
31
+ end
32
+
33
+ describe '#render_to_string' do
34
+ it 'renders itself as a string' do
35
+ assert_equal "<h1>1<\/h1>", @partial.render_to_string
36
+ end
37
+ end
38
+
39
+ describe '#render' do
40
+ it 'renders' do
41
+ # TODO stub out
42
+ assert @partial.respond_to?(:render)
43
+ end
44
+ end
45
+
46
+ describe '#sync' do
47
+ it 'sends update to faye for given partial and update action' do
48
+ # TODO stub out
49
+ assert @partial.sync(:update)
50
+ end
51
+
52
+ it 'sends update to faye for given partial and destroy action' do
53
+ # TODO stub out
54
+ assert @partial.sync(:destroy)
55
+ end
56
+ end
57
+
58
+ describe '#message' do
59
+ it 'returns a Message instance for the partial for the update action' do
60
+ assert_equal RenderSync.client.class::Message, @partial.message(:update).class
61
+ end
62
+
63
+ it 'returns a Message instance for the partial for the destroy action' do
64
+ assert_equal RenderSync.client.class::Message, @partial.message(:destroy).class
65
+ end
66
+ end
67
+
68
+ describe '#channel_prefix' do
69
+ it 'returns a unique channel prefix for the partial given its name and resource' do
70
+ assert @partial.channel_prefix
71
+ end
72
+ end
73
+
74
+ describe 'channel_for_action' do
75
+ it 'returns the channel for the update action' do
76
+ assert @partial.channel_for_action(:update)
77
+ end
78
+
79
+ it 'returns the channel for the destroy action' do
80
+ assert @partial.channel_for_action(:destroy)
81
+ end
82
+
83
+ it 'always starts with a forward slash to provide Faye valid channel' do
84
+ assert_equal "/", @partial.channel_for_action(:update).first
85
+ assert_equal "/", @partial.channel_for_action(:destroy).first
86
+ end
87
+ end
88
+
89
+ describe '#selector_start' do
90
+ it 'returns a string for the selector to mark element beginning' do
91
+ assert @partial.selector_start.present?
92
+ end
93
+ end
94
+
95
+ describe '#selector_end' do
96
+ it 'returns a string for the selector to mark element ending' do
97
+ assert @partial.selector_end.present?
98
+ end
99
+ end
100
+
101
+ describe 'creator_for_scope' do
102
+ it 'returns a new PartialCreator for given scope' do
103
+ assert_equal RenderSync::PartialCreator, @partial.creator_for_scope(nil).class
104
+ assert @partial, @partial.creator_for_scope(nil).partial
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,39 @@
1
+ require_relative '../test_helper'
2
+ require 'mocha/setup'
3
+ require 'rails/all'
4
+
5
+ setup_database
6
+
7
+ describe RenderSync::Model do
8
+
9
+ it 'publishes record (create/update/destroy) to main new channel' do
10
+ RenderSync::Model.enable do
11
+ user = UserWithProtectedAttributes.new
12
+
13
+ # Create
14
+ user.save!
15
+ assert user.persisted?
16
+ assert_equal 1, user.sync_actions.size
17
+
18
+ assert_equal :new, user.sync_actions[0].name
19
+ assert_equal "/user_with_protected_attributes/#{user.id}", user.sync_actions[0].test_path
20
+
21
+ # Update
22
+ user.update_attribute(:name, "Foo")
23
+ assert user.persisted?
24
+ assert_equal 1, user.sync_actions.size
25
+
26
+ assert_equal :update, user.sync_actions[0].name
27
+ assert_equal "/user_with_protected_attributes/#{user.id}", user.sync_actions[0].test_path
28
+
29
+ # Destroy
30
+ user.destroy
31
+ assert user.destroyed?
32
+ assert_equal 1, user.sync_actions.size
33
+
34
+ assert_equal :destroy, user.sync_actions[0].name
35
+ assert_equal "/user_with_protected_attributes/#{user.id}", user.sync_actions[0].test_path
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../test_helper'
2
+ require 'mocha/setup'
3
+
4
+
5
+ describe RenderSync::Reactor do
6
+ include TestHelper
7
+
8
+ describe '#perform' do
9
+ it 'starts EventMachine thread and runs block' do
10
+ refute RenderSync.reactor.running?
11
+ ran_block = false
12
+ RenderSync.reactor.perform { ran_block = true}
13
+ assert RenderSync.reactor.running?
14
+ sleep 0.1
15
+ assert ran_block
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../models/user'
3
+ require 'mocha/setup'
4
+
5
+ describe RenderSync::RefetchModel do
6
+ include TestHelper
7
+
8
+ describe '#find_by_class_name_and_id' do
9
+ it 'finds record by model name and id' do
10
+ User.expects(:find).once.returns(User.new)
11
+ RenderSync::RefetchModel.stubs(:supported_classes).returns ["User"]
12
+ assert RenderSync::RefetchModel.find_by_class_name_and_id("user", 1).is_a? User
13
+ end
14
+
15
+ it 'Returns nil if class name is not sync model' do
16
+ Object.expects(:find).never
17
+ refute RenderSync::RefetchModel.find_by_class_name_and_id("object", 1)
18
+ end
19
+
20
+ it "Returns nil if record is not found for id" do
21
+ User.expects(:find).once.raises(StandardError.new("Record not found"))
22
+ RenderSync::RefetchModel.stubs(:supported_classes).returns ["User"]
23
+ refute RenderSync::RefetchModel.find_by_class_name_and_id("user", 1)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../test_helper'
2
+
3
+ describe RenderSync::RefetchPartialCreator do
4
+ include TestHelper
5
+
6
+ before do
7
+ @context = ActionController::Base.new
8
+ @partial_creator = RenderSync::RefetchPartialCreator.new("show", User.new, scope = nil, @context)
9
+ end
10
+
11
+ describe '#message' do
12
+ it 'returns a Message instance for the partial for the update action' do
13
+ assert_equal RenderSync.client.class::Message, @partial_creator.message.class
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,74 @@
1
+ require_relative '../test_helper'
2
+ require 'rails/all'
3
+ require_relative 'abstract_controller'
4
+ require_relative '../models/user'
5
+
6
+ describe RenderSync::RefetchPartial do
7
+ include TestHelper
8
+
9
+ before do
10
+ @context = ActionController::Base.new
11
+ @partial = RenderSync::RefetchPartial.new("show", User.new, nil, @context)
12
+ end
13
+
14
+ describe '#self.all' do
15
+ it 'returns an array of all Partials for given model' do
16
+ assert_equal 1, RenderSync::RefetchPartial.all(User.new, @context).size
17
+ assert_equal RenderSync::RefetchPartial, RenderSync::RefetchPartial.all(User.new, @context)[0].class
18
+ end
19
+ end
20
+
21
+ describe '#self.find' do
22
+ it 'finds partial given resource and partial name' do
23
+ assert_equal RenderSync::RefetchPartial, RenderSync::RefetchPartial.find(User.new, 'show', @context).class
24
+ end
25
+
26
+ it 'returns nil if partial does not exist' do
27
+ refute RenderSync::RefetchPartial.find(User.new, 'not_exist', nil)
28
+ end
29
+ end
30
+
31
+ describe '#self.find_by_authorized_resource' do
32
+
33
+ it 'returns partial when given auth token for resource and template' do
34
+ assert_equal RenderSync::RefetchPartial, RenderSync::RefetchPartial.find_by_authorized_resource(
35
+ @partial.resource.model,
36
+ @partial.name,
37
+ nil,
38
+ @partial.auth_token
39
+ ).class
40
+ end
41
+
42
+ it 'returns nil when given invalid auth token for resource and template' do
43
+ refute RenderSync::RefetchPartial.find_by_authorized_resource(
44
+ @partial.resource.model,
45
+ @partial.name,
46
+ nil,
47
+ "invalid auth token"
48
+ )
49
+ end
50
+ end
51
+
52
+ describe '#render_to_string' do
53
+ it 'renders itself as a string from the refetch directory' do
54
+ assert_equal "<h1>Refetch 1<\/h1>", @partial.render_to_string
55
+ end
56
+ end
57
+
58
+ describe '#message' do
59
+ it 'returns a Message instance for the partial for the update action' do
60
+ assert_equal RenderSync.client.class::Message, @partial.message(:update).class
61
+ end
62
+
63
+ it 'returns a Message instance for the partial for the destroy action' do
64
+ assert_equal RenderSync.client.class::Message, @partial.message(:destroy).class
65
+ end
66
+ end
67
+
68
+ describe 'creator_for_scope' do
69
+ it 'returns a new PartialCreator for given scope' do
70
+ assert_equal RenderSync::RefetchPartialCreator, @partial.creator_for_scope(nil).class
71
+ assert @partial, @partial.creator_for_scope(nil).partial
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,19 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../models/user'
3
+
4
+ describe RenderSync::Renderer do
5
+ include TestHelper
6
+
7
+ class ApplicationController < ActionController::Base
8
+ end
9
+
10
+ let(:renderer){ RenderSync::Renderer.new }
11
+
12
+ describe '#render_to_string' do
13
+ it 'renders partial as string' do
14
+ assert_equal "<h1>1<\/h1>", renderer.render_to_string(
15
+ partial: 'sync/users/show', locals: { user: User.new }
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,181 @@
1
+ require 'rails/all'
2
+ require_relative '../test_helper'
3
+ require_relative 'abstract_controller'
4
+ require_relative '../models/user'
5
+ require_relative '../models/project'
6
+ require_relative '../models/group'
7
+
8
+ describe RenderSync::Partial do
9
+ include TestHelper
10
+
11
+ before do
12
+ @user = User.create
13
+ @group = Group.create
14
+ @project = Project.create
15
+ end
16
+
17
+ describe '#name' do
18
+ it 'returns the underscored model class name' do
19
+ assert_equal "user", RenderSync::Resource.new(@user).name
20
+ end
21
+ end
22
+
23
+ describe '#plural_name' do
24
+ it 'returns the underscored model class name' do
25
+ assert_equal "users", RenderSync::Resource.new(@user).plural_name
26
+ end
27
+ end
28
+
29
+ describe '#id' do
30
+ it 'returns the models id' do
31
+ assert_equal 1, RenderSync::Resource.new(@user).id
32
+ end
33
+ end
34
+
35
+ describe '#scopes=' do
36
+ before do
37
+ @resource = RenderSync::Resource.new(@user)
38
+ end
39
+
40
+ it 'ignores nil' do
41
+ @resource.scopes = nil
42
+ assert_nil @resource.scopes
43
+ end
44
+
45
+ it 'converts scalar value to an array' do
46
+ @resource.scopes = :en
47
+ assert_equal [:en], @resource.scopes
48
+ end
49
+
50
+ end
51
+
52
+ describe '#scopes_path' do
53
+ describe 'a resource without a scope' do
54
+ it 'returns /' do
55
+ resource = RenderSync::Resource.new(@user)
56
+ assert_equal '/', resource.scopes_path.to_s
57
+ end
58
+ end
59
+
60
+ describe 'a resource with a simple scope' do
61
+ it 'returns a path prefixed with the scope' do
62
+ resource = RenderSync::Resource.new(@user, :admin)
63
+ assert_equal '/admin', resource.scopes_path.to_s
64
+ end
65
+ end
66
+
67
+ describe 'a resource with a parent model as scope' do
68
+ it "returns the parent model's path" do
69
+ resource = RenderSync::Resource.new(@user, @project)
70
+ assert_equal "/projects/#{@project.id}", resource.scopes_path.to_s
71
+ end
72
+ end
73
+
74
+ describe 'a resource with mixed scopes' do
75
+ it 'returns a path including all scopes' do
76
+ resource = RenderSync::Resource.new(@user, [:en, :admin, @project])
77
+ assert_equal "/en/admin/projects/#{@project.id}", resource.scopes_path.to_s
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#polymorphic_path' do
83
+ describe 'a resource without a scope' do
84
+ it 'returns the path for the model' do
85
+ assert_equal "/users/1", RenderSync::Resource.new(@user).polymorphic_path.to_s
86
+ end
87
+ end
88
+
89
+ describe 'a resource with a simple scope' do
90
+ it 'returns the path for the model, prefixed by the scope' do
91
+ resource = RenderSync::Resource.new(@user, :en)
92
+ assert_equal "/en/users/1", resource.polymorphic_path.to_s
93
+ end
94
+ end
95
+
96
+ describe 'a resource with a parent model as scope' do
97
+ it 'returns the path for the model, prefixed by parent path' do
98
+ child = RenderSync::Resource.new(@user, @project)
99
+ assert_equal "/projects/#{@project.id}/users/1", child.polymorphic_path.to_s
100
+ end
101
+ end
102
+
103
+ describe 'a resource with an RenderSync::Scope object as scope' do
104
+ it 'returns the path for the model, prefixed by sync_scope path' do
105
+ child = RenderSync::Resource.new(@user, User.cool)
106
+ assert_equal "/cool/users/1", child.polymorphic_path.to_s
107
+ end
108
+ end
109
+
110
+ describe 'a resource with an RenderSync::Scope object with AR-param as scope' do
111
+ it 'returns the path for the model, prefixed by sync_scope path' do
112
+ child = RenderSync::Resource.new(@user, User.in_group(@group))
113
+ assert_equal "/in_group/group/#{@group.id}/users/1", child.polymorphic_path.to_s
114
+ end
115
+ end
116
+
117
+ describe 'a resource with an RenderSync::Scope object with Integer-param as scope' do
118
+ it 'returns the path for the model, prefixed by sync_scope path' do
119
+ child = RenderSync::Resource.new(@user, User.with_group_id(@group.id))
120
+ assert_equal "/with_group_id/group_id/#{@group.id}/users/1", child.polymorphic_path.to_s
121
+ end
122
+ end
123
+
124
+ describe 'a resource with an RenderSync::Scope object with multiple params as scope' do
125
+ it 'returns the path for the model, prefixed by sync_scope path' do
126
+ child = RenderSync::Resource.new(@user, User.with_min_age_in_group(15, @group.id))
127
+ assert_equal "/with_min_age_in_group/age/15/group_id/#{@group.id}/users/1", child.polymorphic_path.to_s
128
+ end
129
+ end
130
+
131
+ describe 'a resource with mixed scopes' do
132
+ it 'returns the path for the model, prefixed by all scopes' do
133
+ child = RenderSync::Resource.new(@user, [:en, :admin, @project, User.cool, User.in_group(@group)])
134
+ assert_equal "/en/admin/projects/#{@project.id}/cool/in_group/group/#{@group.id}/users/1", child.polymorphic_path.to_s
135
+ end
136
+ end
137
+ end
138
+
139
+ describe '#model_path' do
140
+ it 'returns the raw path of the model without any scopes' do
141
+ child = RenderSync::Resource.new(@user, @project)
142
+ assert_equal "/users/1", child.model_path.to_s
143
+ end
144
+ end
145
+
146
+ describe '#polymorphic_new_path' do
147
+ describe 'a resource without a scope' do
148
+ it 'returns the path for the model' do
149
+ assert_equal "/users/new", RenderSync::Resource.new(@user).polymorphic_new_path.to_s
150
+ end
151
+ end
152
+
153
+ describe 'a resource with a simple scope' do
154
+ it 'returns the path for the model, prefixed by the scope' do
155
+ resource = RenderSync::Resource.new(@user, :en)
156
+ assert_equal "/en/users/new", resource.polymorphic_new_path.to_s
157
+ end
158
+ end
159
+
160
+ describe 'a resource with a parent model as scope' do
161
+ it 'returns the path for the model, prefixed by parent path' do
162
+ child = RenderSync::Resource.new(@user, @project)
163
+ assert_equal "/projects/#{@project.id}/users/new", child.polymorphic_new_path.to_s
164
+ end
165
+ end
166
+
167
+ describe 'a resource with a RenderSync::Scope object as scope' do
168
+ it 'returns the path for the model, prefixed by parent path' do
169
+ child = RenderSync::Resource.new(@user, User.cool)
170
+ assert_equal "/cool/users/new", child.polymorphic_new_path.to_s
171
+ end
172
+ end
173
+
174
+ describe 'a resource with mixed scopes' do
175
+ it 'returns the path for the model, prefixed by all scopes' do
176
+ child = RenderSync::Resource.new(@user, [:en, :admin, @project, User.cool, User.in_group(@group)])
177
+ assert_equal "/en/admin/projects/#{@project.id}/cool/in_group/group/#{@group.id}/users/new", child.polymorphic_new_path.to_s
178
+ end
179
+ end
180
+ end
181
+ end