cobranding 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,151 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Cobranding::Layout do
4
+
5
+ before :each do
6
+ @context = Object.new
7
+ def @context.test_tag_for_cobranding
8
+ "Woo woo"
9
+ end
10
+
11
+ cache = ActiveSupport::Cache::MemoryStore.new
12
+ Rails.stub!(:cache).and_return(cache)
13
+ end
14
+
15
+ it "should be able to evaluate a template from HTML" do
16
+ layout = Cobranding::Layout.new("<html>Test</html>")
17
+ layout.evaluate(@context).should == "<html>Test</html>"
18
+ end
19
+
20
+ it "should replace {{}} markup with predefined method calls" do
21
+ layout = Cobranding::Layout.new("<html>Test {{test_tag}}</html>")
22
+ layout.evaluate(@context).should == "<html>Test Woo woo</html>"
23
+ end
24
+
25
+ it "should replace {{}} markup with predefined method calls using a custom suffix" do
26
+ def @context.test_tag_for_layout
27
+ "custom suffix"
28
+ end
29
+ layout = Cobranding::Layout.new("<html>Test {{test_tag}}</html>")
30
+ layout.evaluate(@context, :suffix => "_for_layout").should == "<html>Test custom suffix</html>"
31
+ end
32
+
33
+ it "should replace {{}} markup with predefined method calls using a custom prefix" do
34
+ def @context.cobranding_test_tag
35
+ "custom prefix"
36
+ end
37
+ layout = Cobranding::Layout.new("<html>Test {{test_tag}}</html>")
38
+ layout.evaluate(@context, :prefix => "cobranding_").should == "<html>Test custom prefix</html>"
39
+ end
40
+
41
+ it "should replace {{}} markup with predefined method calls using a custom prefix and suffix" do
42
+ def @context.cobranding_test_tag_for_layout
43
+ "custom prefix and suffix"
44
+ end
45
+ layout = Cobranding::Layout.new("<html>Test {{test_tag}}</html>")
46
+ layout.evaluate(@context, :prefix => "cobranding_", :suffix => "_for_layout").should == "<html>Test custom prefix and suffix</html>"
47
+ end
48
+
49
+ it "should ignore spaces in {{}} markup tags" do
50
+ layout = Cobranding::Layout.new("<html>Test {{ test_tag }}</html>")
51
+ layout.evaluate(@context).should == "<html>Test Woo woo</html>"
52
+ end
53
+
54
+ it "should ignore method calls that are not defined" do
55
+ layout = Cobranding::Layout.new("<html>Test {{no_tag}}</html>")
56
+ layout.evaluate(@context).should == "<html>Test </html>"
57
+ end
58
+
59
+ it "should not allow malicious markup tags" do
60
+ layout = Cobranding::Layout.new("<html>Test {{test_tag; File.read('/etc/passwd')}}</html>")
61
+ layout.evaluate(@context).should == "<html>Test {{test_tag; File.read('/etc/passwd')}}</html>"
62
+ end
63
+
64
+ it "should strip extra new lines since they are stupid" do
65
+ layout = Cobranding::Layout.new("<html>Test\r\n\t \n Newline\n\n\n</html>")
66
+ layout.evaluate(@context).should == "<html>Test\n Newline\n</html>"
67
+ end
68
+
69
+ it "should escape ERB code so evil things can't happen" do
70
+ layout = Cobranding::Layout.new("<html>Test <%= File.read('/etc/passwd') %></html>")
71
+ layout.evaluate(@context).should == "<html>Test &lt;%= File.read('/etc/passwd') %&gt;</html>"
72
+ end
73
+
74
+ it "should be able to get a layout from a URL" do
75
+ stub_request(:get, "localhost/layout?site=1").to_return(:status => [200, "Success"], :body => "<html>{{test_tag}}</html>")
76
+ layout = Cobranding::Layout.get("http://localhost/layout", :params => {:site => 1})
77
+ layout.evaluate(@context).should == "<html>Woo woo</html>"
78
+ end
79
+
80
+ it "should be able to get a layout from URL components" do
81
+ stub_request(:get, "https://localhost:444/layout/path?site=1").to_return(:status => [200, "Success"], :body => "<html>{{test_tag}}</html>")
82
+ layout = Cobranding::Layout.get("path", :scheme => "https", :host => "localhost", :port => 444, :base => "/layout", :params => {:site => 1})
83
+ layout.evaluate(@context).should == "<html>Woo woo</html>"
84
+ end
85
+
86
+ it "should be able to get a layout from a URL with a POST" do
87
+ stub_request(:post, "localhost/layout").with(:params => {"site" => "1"}, :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).to_return(:status => [200, "Success"], :body => "<html>{{test_tag}}</html>")
88
+ layout = Cobranding::Layout.get("http://localhost/layout", :method => :post, :site => 1)
89
+ layout.evaluate(@context).should == "<html>Woo woo</html>"
90
+ end
91
+
92
+ it "should be able to get a layout from a URL without caching" do
93
+ stub_request(:get, "localhost/layout?site=1").to_return(:status => [200, "Success"], :body => "<html>{{test_tag}}</html>")
94
+ Rails.stub!(:cache).and_return(nil)
95
+ layout = Cobranding::Layout.get("http://localhost/layout", :params => {:site => 1})
96
+ layout.evaluate(@context).should == "<html>Woo woo</html>"
97
+ end
98
+
99
+ it "should generate consistent cache keys" do
100
+ key_1 = Cobranding::Layout.cache_key("http://localhost/layout", :params => {:a => 1, :b => 2})
101
+ key_2 = Cobranding::Layout.cache_key("http://localhost/layout", :params => {"a" => "1", "b" => "2"})
102
+ key_3 = Cobranding::Layout.cache_key("http://localhost/layout?b=2&a=1")
103
+ key_4 = Cobranding::Layout.cache_key("http://localhost/layout?b=1&a=2")
104
+ key_5 = Cobranding::Layout.cache_key("http://localhost/layout_2", :params => {:a => 1, :b => 2})
105
+ key_1.should == key_2
106
+ key_1.should == key_3
107
+ key_1.should_not == key_4
108
+ key_1.should_not == key_5
109
+ end
110
+
111
+ it "should read a layout from the cache if it is found" do
112
+ key = Cobranding::Layout.cache_key("http://localhost/layout")
113
+ cached_layout = Cobranding::Layout.new("<html>Cached</html>")
114
+ Rails.cache.write(key, cached_layout)
115
+ layout = Cobranding::Layout.get("http://localhost/layout", :ttl => 300)
116
+ layout.evaluate(@context).should == "<html>Cached</html>"
117
+ end
118
+
119
+ it "should not write a layout to the cache if :ttl is not specified" do
120
+ stub_request(:get, "http://localhost/layout?v=1").to_return(:status => 200, :body => "<html>{{test_tag}}</html>")
121
+ key = Cobranding::Layout.cache_key("http://localhost/layout", :params => {:v => 1})
122
+ layout = Cobranding::Layout.get("http://localhost/layout", :params => {:v => 1})
123
+ layout.evaluate(@context).should == "<html>Woo woo</html>"
124
+ cached_layout = Rails.cache.read(key)
125
+ cached_layout.should == nil
126
+ end
127
+
128
+ it "should expand relative URL's in the HTML based on the request URL" do
129
+ html = "<a href=\"http://example.com/\"><img src=/logo.gif></a><A HREF='/test2'><IMG SRC=\"/images/new_logo.gif\" id=\"/logo\"></A>"
130
+ stub_request(:get, "http://localhost/layout").to_return(:status => 200, :body => html)
131
+ layout = Cobranding::Layout.get("http://localhost/layout")
132
+ layout.evaluate(@context).should == "<a href=\"http://example.com/\"><img src=http://localhost/logo.gif></a><A HREF='http://localhost/test2'><IMG SRC=\"http://localhost/images/new_logo.gif\" id=\"/logo\"></A>"
133
+ end
134
+
135
+ it "should expand relative URL's in the HTML based on the :base_url option" do
136
+ html = "<a href=\"http://example.com/\"><img src=/logo.gif></a><A HREF='/test2'><IMG SRC=\"/images/new_logo.gif\" id=\"/logo\"></A>"
137
+ stub_request(:get, "http://localhost/layout").to_return(:status => 200, :body => html)
138
+ layout = Cobranding::Layout.get("http://localhost/layout", :base_url => "https://secure.example.com/")
139
+ layout.evaluate(@context).should == "<a href=\"http://example.com/\"><img src=https://secure.example.com/logo.gif></a><A HREF='https://secure.example.com/test2'><IMG SRC=\"https://secure.example.com/images/new_logo.gif\" id=\"/logo\"></A>"
140
+ end
141
+
142
+ it "should process the layout HTML with a block in case it needs to be munged" do
143
+ html = 'this is <!--#include virtual="test_tag" --> stuff'
144
+ stub_request(:get, "http://localhost/layout").to_return(:status => 200, :body => html)
145
+ layout = Cobranding::Layout.get("http://localhost/layout") do |code|
146
+ code.gsub('i', '!')
147
+ code.gsub(/<!--#\s*include\s+virtual="([^"]+)"\s*-->/, '{{ \1 }}')
148
+ end
149
+ layout.evaluate(@context).should == "this is Woo woo stuff"
150
+ end
151
+ end
@@ -0,0 +1,111 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Cobranding::PersistentLayout do
4
+
5
+ class Cobranding::PersistentLayout::Tester1
6
+ attr_accessor :src, :url
7
+ include Cobranding::PersistentLayout
8
+ end
9
+
10
+ class Cobranding::PersistentLayout::Tester2
11
+ attr_accessor :layout_src, :layout_url, :layout_url_options
12
+ include Cobranding::PersistentLayout
13
+ self.layout_src_attribute = :layout_src
14
+ self.layout_url_attribute = :layout_url
15
+ self.layout_url_options_attribute = :layout_url_options
16
+ end
17
+
18
+ class Cobranding::PersistentLayout::Tester3
19
+ attr_accessor :src, :url
20
+ include Cobranding::PersistentLayout
21
+ self.layout_preprocessor = lambda{|html| html.gsub('s', "$")}
22
+ end
23
+
24
+ class Cobranding::PersistentLayout::Tester4
25
+ attr_accessor :src, :url
26
+ include Cobranding::PersistentLayout
27
+ self.layout_preprocessor = :replace_i
28
+
29
+ def replace_i (html)
30
+ html.gsub('i', '!')
31
+ end
32
+ end
33
+
34
+ it "should fetch the layout and store the source into default fields" do
35
+ model = Cobranding::PersistentLayout::Tester1.new
36
+ model.url = "http://localhost/layout"
37
+ layout = Cobranding::Layout.new("<html/>")
38
+ Cobranding::Layout.should_receive(:get).with("http://localhost/layout", {}).and_return(layout)
39
+ model.fetch_layout
40
+ model.src.should == layout.src
41
+ model.layout.should == layout
42
+ end
43
+
44
+ it "should fetch the layout and store the source into a specified fields" do
45
+ model = Cobranding::PersistentLayout::Tester2.new
46
+ model.layout_url = "http://localhost/layout"
47
+ model.layout_url_options = {"params" => {"v" => 1}}
48
+ layout = Cobranding::Layout.new("<html/>")
49
+ Cobranding::Layout.should_receive(:get).with("http://localhost/layout", {"params" => {"v" => 1}}).and_return(layout)
50
+ model.fetch_layout
51
+ model.layout_src.should == layout.src
52
+ model.layout.should == layout
53
+ end
54
+
55
+ it "should create a layout from the compiled source in the field" do
56
+ model = Cobranding::PersistentLayout::Tester1.new
57
+ layout = Cobranding::Layout.new("<html/>")
58
+ model.src = layout.src
59
+ model.layout.src.should == layout.src
60
+ model.layout.object_id.should_not == layout.object_id
61
+ model.layout.object_id.should == model.layout.object_id
62
+ end
63
+
64
+ context "fetching with preprocessor" do
65
+ let(:url){ "http://localhost/layout" }
66
+ before :each do
67
+ stub_request(:get, url).to_return(:status => 200, :body => "This is a test")
68
+ end
69
+
70
+ it "should not invoke a preprocessor if it isn't defined" do
71
+ model = Cobranding::PersistentLayout::Tester1.new
72
+ model.url = url
73
+ model.fetch_layout
74
+ model.src.should == Cobranding::Layout.new("This is a test").src
75
+ end
76
+
77
+ it "should use a Proc as the layout preprocessor" do
78
+ model = Cobranding::PersistentLayout::Tester3.new
79
+ model.url = url
80
+ model.fetch_layout
81
+ model.src.should == Cobranding::Layout.new("Thi$ i$ a te$t").src
82
+ end
83
+
84
+ it "should use an instance method as the layout preprocessor" do
85
+ model = Cobranding::PersistentLayout::Tester4.new
86
+ model.url = url
87
+ model.fetch_layout
88
+ model.src.should == Cobranding::Layout.new("Th!s !s a test").src
89
+ end
90
+ end
91
+
92
+ context "setting html with preprocessor" do
93
+ it "should not invoke a preprocessor if it isn't defined" do
94
+ model = Cobranding::PersistentLayout::Tester1.new
95
+ model.layout_html = "This is a test"
96
+ model.src.should == Cobranding::Layout.new("This is a test").src
97
+ end
98
+
99
+ it "should use a Proc as the layout preprocessor" do
100
+ model = Cobranding::PersistentLayout::Tester3.new
101
+ model.layout_html = "This is a test"
102
+ model.src.should == Cobranding::Layout.new("Thi$ i$ a te$t").src
103
+ end
104
+
105
+ it "should use an instance method as the layout preprocessor" do
106
+ model = Cobranding::PersistentLayout::Tester4.new
107
+ model.layout_html = "This is a test"
108
+ model.src.should == Cobranding::Layout.new("Th!s !s a test").src
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'logger'
3
+ require 'webmock/rspec'
4
+ rails_version = ENV["RAILS_VERSION"] || ">=3.0.5"
5
+ gem 'activesupport', rails_version
6
+ gem 'actionpack', rails_version
7
+ begin
8
+ require 'simplecov'
9
+ SimpleCov.start do
10
+ add_filter "/spec/"
11
+ end
12
+ rescue LoadError
13
+ # simplecov not installed
14
+ end
15
+
16
+ WebMock.disable_net_connect!
17
+
18
+ require File.expand_path('../../lib/cobranding', __FILE__)
19
+
20
+
21
+ module Rails
22
+ end
23
+
24
+ def Rails.env
25
+ "test"
26
+ end
27
+
28
+ def Rails.cache
29
+ @cache ||= ActiveSupport::Cache::MemoryStore.new
30
+ end
31
+
32
+ def Rails.logger
33
+ @logger ||= Logger.new(StringIO.new)
34
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cobranding
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brian Durand
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: actionpack
16
+ requirement: &70231273526100 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70231273526100
25
+ - !ruby/object:Gem::Dependency
26
+ name: rest-client
27
+ requirement: &70231273525080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70231273525080
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70231273524440 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 2.0.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70231273524440
47
+ - !ruby/object:Gem::Dependency
48
+ name: webmock
49
+ requirement: &70231273539980 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70231273539980
58
+ description: Provides Rails view layouts from an HTTP service.
59
+ email:
60
+ - mdobrota@tribune.com
61
+ - ddpr@tribune.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files:
65
+ - README.rdoc
66
+ files:
67
+ - License.txt
68
+ - README.rdoc
69
+ - Rakefile
70
+ - lib/cobranding.rb
71
+ - lib/cobranding/helper.rb
72
+ - lib/cobranding/layout.rb
73
+ - lib/cobranding/persistent_layout.rb
74
+ - spec/helper_spec.rb
75
+ - spec/layout_spec.rb
76
+ - spec/persistent_layout_spec.rb
77
+ - spec/spec_helper.rb
78
+ homepage:
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --line-numbers
83
+ - --inline-source
84
+ - --main
85
+ - README.rdoc
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 1.8.10
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Provides Rails view layouts from an HTTP service
106
+ test_files: []