renuo-cms-rails 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1cf6e98e641d7bf6fcaa1909862c6c76bad61b10
4
- data.tar.gz: 6b1e0eab22ea12f2cc570a7ee0a13bb6ad58e506
3
+ metadata.gz: 3fda16518538093c40b2c44a78900bff6163220d
4
+ data.tar.gz: b309d93121355109393d8864cebfc9090410eaf6
5
5
  SHA512:
6
- metadata.gz: d687588afffbfa05caaff48b1ba41beb1da919ddd0a57bae7707600a9f0e42a1afd4ae8619a3dddc3de0f72ff1b876ddf7b308e2163137ccd1cba56e9dc35ead
7
- data.tar.gz: 7731659391360e60806d0985a7489a71bc00a07609de7bd3b5e7547c72cb4027a40029829153b634793aef3286b4059ac28845c4427fb4ca3b9485f8c724ae38
6
+ metadata.gz: a5f49188f3f8718b14255b86a8d3d76c1984a21f2af014ec7e6d756604ac67399a1312660933005c38385943f1243220631262783084506b17f7e33d70698530
7
+ data.tar.gz: a0bc61c75aa044511b5d8eada8e1c6828a4002cdf5c31cfdbf180e2d0c5ffeede9d3aa076fc5a8271cb9fc5d4dcd7bca3a780f9c3f39e8b3543bff77de940836
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## Version 0.2.0
2
+
3
+ * implement server side caching of cms contents
4
+
1
5
  ## Version 0.1.0
2
6
 
3
7
  * add https:// by default to api_host if no protocol is given
data/README.md CHANGED
@@ -30,6 +30,14 @@ And then execute:
30
30
  bundle
31
31
  ```
32
32
 
33
+ To use the JS client you need to include the following JS file in your project (please use the latest version, which can be found here: https://www.jsdelivr.com/projects/renuo-cms-client):
34
+
35
+ ```html
36
+ <script src="https://cdn.jsdelivr.net/renuo-cms-client/XXX/renuo-cms-client.min.js" integrity="sha256-XXX" crossorigin="anonymous"></script>
37
+ ```
38
+
39
+ Use a fixed version of the library so you are not affected by changes without testing them, and to have a consistent behavior for all users.
40
+
33
41
  ## Usage
34
42
 
35
43
  ### CMS Helper
data/lib/railtie.rb CHANGED
@@ -1,6 +1,18 @@
1
1
  module Railtie
2
2
  class Railtie < Rails::Railtie
3
- # initializer 'setup renuo cms' do
4
- # end
3
+ initializer 'renuo_cms_rails' do |app|
4
+ app.config.after_initialize do
5
+ require 'benchmark'
6
+ require 'digest/sha1'
7
+
8
+ time = Benchmark.measure do
9
+ Rails.logger.info 'Initializing Renuo CMS Rails Cache...'
10
+ cache = RenuoCmsRails::Cache.initialize_cache
11
+ cache_details = "found #{cache.size} contents, sha1: #{Digest::SHA1.hexdigest(cache.to_s)}"
12
+ Rails.logger.info "CMS cache details: #{cache_details}"
13
+ end
14
+ Rails.logger.info "Done initializing Renuo CMS Rails Cache (#{time.real.round(3)}s)"
15
+ end
16
+ end
5
17
  end
6
18
  end
@@ -1,6 +1,9 @@
1
1
  require 'renuo_cms_rails/version'
2
2
  require 'renuo_cms_rails/config'
3
3
  require 'renuo_cms_rails/cms_helper'
4
+ require 'renuo_cms_rails/api'
5
+ require 'renuo_cms_rails/cache'
6
+ require_relative 'railtie' if defined?(Rails::Railtie)
4
7
 
5
8
  ActiveSupport.on_load(:action_view) do
6
9
  include RenuoCmsRails::CmsHelper
@@ -0,0 +1,14 @@
1
+ require_relative 'api/contents'
2
+
3
+ module RenuoCmsRails
4
+ module API
5
+ # Fetches the contents from the API. It returns a hash where the key is the content_path and the value is the
6
+ # content string.
7
+ # @return [Hash<String, String>] the contents from the API
8
+ def fetch_contents
9
+ Contents.new(RenuoCmsRails.config).fetch
10
+ end
11
+
12
+ module_function :fetch_contents
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ module RenuoCmsRails
2
+ module API
3
+ class Contents
4
+ MAX_CACHE_TTL = 60 * 2 # 2 minutes
5
+
6
+ # @param [RenuoCmsRails::Config] config
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+
11
+ def url
12
+ "#{@config.api_host_with_protocol}/v1/#{@config.api_key}/content_blocks?_=#{cache_time}"
13
+ end
14
+
15
+ # :reek:UtilityFunction
16
+ def cache_time
17
+ # note: using integer division for rounding, so that we get a new key every 2 minutes, e.g.
18
+ # part 1: 249 / 120 = 2 (not 2.075)
19
+ # part 2: 2 * 120 = 240
20
+ # all: (249 / 120) * 120 = 240
21
+ (Time.now.to_i / MAX_CACHE_TTL) * MAX_CACHE_TTL
22
+ end
23
+
24
+ def fetch
25
+ uri = URI(url)
26
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
27
+ request = Net::HTTP::Get.new uri
28
+ handle_response(http.request(request))
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def handle_response(response)
35
+ return {} unless response.is_a?(Net::HTTPOK)
36
+ convert_json(response)
37
+ end
38
+
39
+ # :reek:UtilityFunction
40
+ def convert_json(response)
41
+ content_blocks_json = JSON.parse(response.body)['content_blocks']
42
+ return {} unless content_blocks_json
43
+ content_blocks_json.map { |block_json| [block_json['content_path'], block_json['content']] }.to_h
44
+ rescue JSON::ParserError
45
+ {}
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'cache/cacher'
2
+
3
+ module RenuoCmsRails
4
+ module Cache
5
+ @cache = Cacher.new(RenuoCmsRails::API)
6
+
7
+ attr_reader :cache
8
+
9
+ # Initializes the cache. This will connect via HTTPS to the configured CMS host, so make sure that the host is
10
+ # configured prior to calling this method.
11
+ delegate :initialize_cache, to: :cache
12
+
13
+ # Gets the content if the content with the content_path is in the cache, nil otherwise.
14
+ # @param [String] content_path
15
+ # @return [String]
16
+ delegate :get, to: :cache
17
+
18
+ module_function :cache, :get, :initialize_cache
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module RenuoCmsRails
2
+ module Cache
3
+ class Cacher
4
+ def initialize(api)
5
+ @api = api
6
+ end
7
+
8
+ def initialize_cache
9
+ @contents = @api.fetch_contents
10
+ end
11
+
12
+ def get(content_path)
13
+ return unless @contents
14
+ @contents[content_path]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,9 +2,11 @@ require 'action_view/helpers'
2
2
 
3
3
  module RenuoCmsRails
4
4
  module CmsHelper
5
- def cms(path, default_value = nil, &block)
5
+ def cms(i18n_path, default_value = nil, &block)
6
+ path = i18n_path.tr('.', '-')
6
7
  content_path = RenuoCmsRails.config.content_path_generator.call(path)
7
- default_translation = capture_default_value(path, default_value, &block)
8
+ cache = RenuoCmsRails::Cache.cache.get(content_path)
9
+ default_translation = cache&.html_safe || capture_default_value(path, i18n_path, default_value, &block)
8
10
  content_tag(:div, default_translation, data: cms_attributes(content_path))
9
11
  end
10
12
 
@@ -19,11 +21,11 @@ module RenuoCmsRails
19
21
  cms_attributes
20
22
  end
21
23
 
22
- def capture_default_value(path, default_value)
24
+ def capture_default_value(_path, i18n_path, default_value)
23
25
  return default_value if default_value
24
26
  return capture { yield } if block_given?
25
27
 
26
- I18n.t(path)
28
+ I18n.t(i18n_path)
27
29
  end
28
30
  end
29
31
  end
@@ -1,3 +1,3 @@
1
1
  module RenuoCmsRails
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -31,4 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'climate_control', '>= 0.0.3'
32
32
  spec.add_development_dependency 'rubocop', '>= 0.39.0'
33
33
  spec.add_development_dependency 'reek', '>= 4.0.1'
34
+ spec.add_development_dependency 'timecop', '>= 0.8.0'
35
+ spec.add_development_dependency 'webmock', '>= 2.0.3'
34
36
  end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ describe RenuoCmsRails::API::Contents do
5
+ before do
6
+ config = RenuoCmsRails::Config.new
7
+ config.api_host = 'example.com'
8
+ config.api_key = 'somekey'
9
+ config.private_api_key = 'pk'
10
+ @contents_api = RenuoCmsRails::API::Contents.new(config)
11
+ end
12
+
13
+ describe '#build_url' do
14
+ it 'calculates the correct cache time' do
15
+ Timecop.freeze(Time.at(10).utc) { expect(@contents_api.cache_time).to eq(0) }
16
+ Timecop.freeze(Time.at(60).utc) { expect(@contents_api.cache_time).to eq(0) }
17
+ Timecop.freeze(Time.at(90).utc) { expect(@contents_api.cache_time).to eq(0) }
18
+ Timecop.freeze(Time.at(119).utc) { expect(@contents_api.cache_time).to eq(0) }
19
+ Timecop.freeze(Time.at(120).utc) { expect(@contents_api.cache_time).to eq(120) }
20
+ Timecop.freeze(Time.at(121).utc) { expect(@contents_api.cache_time).to eq(120) }
21
+ Timecop.freeze(Time.at(239).utc) { expect(@contents_api.cache_time).to eq(120) }
22
+ Timecop.freeze(Time.at(240).utc) { expect(@contents_api.cache_time).to eq(240) }
23
+ Timecop.freeze(Time.at(240).utc) { expect(@contents_api.cache_time).to eq(240) }
24
+ Timecop.freeze(Time.at(959).utc) { expect(@contents_api.cache_time).to eq(840) }
25
+ Timecop.freeze(Time.at(960).utc) { expect(@contents_api.cache_time).to eq(960) }
26
+ Timecop.freeze(Time.at(961).utc) { expect(@contents_api.cache_time).to eq(960) }
27
+ end
28
+
29
+ describe '#url' do
30
+ it 'builds the correct url' do
31
+ Timecop.freeze(Time.at(123).utc) do
32
+ url = 'https://example.com/v1/somekey/content_blocks?_=120'
33
+ expect(@contents_api.url).to eq(url)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#fetch' do
39
+ def valid_api_response
40
+ time_json = '"updated_at":"2016-04-11T12:30:38.029Z","created_at":"2016-01-11T12:30:38.029Z"'
41
+ cb1 = "{\"content\":\"content1\",\"content_path\":\"path1\",\"api_key\":\"somekey\",#{time_json}}"
42
+ cb2 = "{\"content\":\"content2\",\"content_path\":\"path2\",\"api_key\":\"somekey\",#{time_json}}"
43
+ "{\"content_blocks\":[#{cb1}, #{cb2}]}"
44
+ end
45
+
46
+ def test_request(contents_api, api_response)
47
+ Timecop.freeze(Time.at(123).utc) do
48
+ stub_request(:get, contents_api.url).with(headers: { 'Host' => 'example.com' }).to_return(body: api_response)
49
+ return contents_api.fetch
50
+ end
51
+ end
52
+
53
+ it 'fetches the contents via HTTPS' do
54
+ contents = test_request(@contents_api, valid_api_response)
55
+ expect(contents['path1']).to eq('content1')
56
+ expect(contents['path2']).to eq('content2')
57
+ expect(contents['path3']).to eq(nil)
58
+ end
59
+
60
+ it 'fetches the contents via HTTP' do
61
+ config = RenuoCmsRails::Config.new
62
+ config.api_host = 'http://example.com'
63
+ config.api_key = 'somekey'
64
+ config.private_api_key = 'pk'
65
+ contents_api = RenuoCmsRails::API::Contents.new(config)
66
+ contents = test_request(contents_api, valid_api_response)
67
+ expect(contents['path1']).to eq('content1')
68
+ expect(contents['path2']).to eq('content2')
69
+ expect(contents['path3']).to eq(nil)
70
+ end
71
+
72
+ it 'returns an empty hash if the JSON is invalid' do
73
+ config = RenuoCmsRails::Config.new
74
+ config.api_host = 'http://example.com'
75
+ config.api_key = 'somekey'
76
+ config.private_api_key = 'pk'
77
+ contents_api = RenuoCmsRails::API::Contents.new(config)
78
+ expect(test_request(contents_api, '{{invalid json')).to eq({})
79
+ end
80
+
81
+ it 'returns an empty hash if the JSON is not complete' do
82
+ config = RenuoCmsRails::Config.new
83
+ config.api_host = 'http://example.com'
84
+ config.api_key = 'somekey'
85
+ config.private_api_key = 'pk'
86
+ contents_api = RenuoCmsRails::API::Contents.new(config)
87
+ expect(test_request(contents_api, '{"missing":"stuff"}')).to eq({})
88
+ end
89
+
90
+ it 'returns an empty hash if the API request was not successful' do
91
+ config = RenuoCmsRails::Config.new
92
+ config.api_host = 'http://example.com'
93
+ config.api_key = 'somekey'
94
+ config.private_api_key = 'pk'
95
+ contents_api = RenuoCmsRails::API::Contents.new(config)
96
+
97
+ Timecop.freeze(Time.at(123).utc) do
98
+ stub_request(:get, contents_api.url).with(headers: { 'Host' => 'example.com' }).to_return(
99
+ status: [500, 'Internal Server Error']
100
+ )
101
+ expect(contents_api.fetch).to eq({})
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe RenuoCmsRails::API do
4
+ describe '#fetch_contents' do
5
+ it 'loads the contents' do
6
+ RenuoCmsRails.reset
7
+ RenuoCmsRails.config.api_host = 'example.com'
8
+ RenuoCmsRails.config.api_key = 'apikey'
9
+ RenuoCmsRails.config.private_api_key = 'pk'
10
+
11
+ Timecop.freeze(Time.at(123).utc) do
12
+ stub_request(:get, 'https://example.com/v1/apikey/content_blocks?_=120').with(
13
+ headers: { 'Host' => 'example.com' }
14
+ ).to_return(body: { content_blocks: [{ content: 'somecontent', content_path: 'somepath' }] }.to_json)
15
+ contents = RenuoCmsRails::API.fetch_contents
16
+ expect(contents['somepath']).to eq('somecontent')
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe RenuoCmsRails::Cache do
4
+ describe '#cache' do
5
+ it 'returns a cache instance' do
6
+ expect(described_class.cache).to be_a(RenuoCmsRails::Cache::Cacher)
7
+ end
8
+
9
+ it 'returns the same instance two times' do
10
+ expect(described_class.cache).to be(described_class.cache)
11
+ end
12
+ end
13
+
14
+ describe '#initialize_cache' do
15
+ it 'delegates the method call initialize_cache to the cacher' do
16
+ expect(described_class.cache).to receive(:initialize_cache)
17
+ described_class.initialize_cache
18
+ end
19
+ end
20
+
21
+ describe '#get' do
22
+ it 'delegates the method call get(key) to the cacher' do
23
+ expect(described_class.cache).to receive(:get).with('content.path')
24
+ described_class.get('content.path')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe RenuoCmsRails::Cache::Cacher do
4
+ describe '#initialize_cache' do
5
+ it 'calls the api to initialize the cache' do
6
+ api = double(fetch_contents: 'contents')
7
+ cacher = described_class.new(api)
8
+ expect(api).to receive(:fetch_contents)
9
+ cacher.initialize_cache
10
+ expect(cacher.instance_variable_get('@contents')).to eq('contents')
11
+ end
12
+ end
13
+
14
+ describe '#get' do
15
+ it 'gets the cached content' do
16
+ cacher = described_class.new(nil)
17
+ cacher.instance_variable_set('@contents', 'a' => 'aa', 'b' => 'bb')
18
+ expect(cacher.get('a')).to eq('aa')
19
+ expect(cacher.get('b')).to eq('bb')
20
+ expect(cacher.get('c')).to eq(nil)
21
+ end
22
+
23
+ it 'gets returns nil if the cache is not initialized' do
24
+ cacher = described_class.new(nil)
25
+ expect(cacher.get('a')).to eq(nil)
26
+ end
27
+ end
28
+ end
@@ -17,7 +17,7 @@ describe RenuoCmsRails::CmsHelper do
17
17
 
18
18
  node = Capybara.string cms('some.content', 'Some CMS content')
19
19
  expect(node).to have_css('div', text: 'Some CMS content')
20
- expect(node).to have_css("div[data-content-path='some.content-en']")
20
+ expect(node).to have_css("div[data-content-path='some-content-en']")
21
21
  expect(node).to have_css("div[data-api-host='https://some.host']")
22
22
  expect(node).to have_css("div[data-api-key='apikey']")
23
23
  expect(node).not_to have_css('div[data-private-api-key]')
@@ -28,34 +28,57 @@ describe RenuoCmsRails::CmsHelper do
28
28
 
29
29
  node = Capybara.string cms('some.content', 'Some CMS content')
30
30
  expect(node).to have_css('div', text: 'Some CMS content')
31
- expect(node).to have_css("div[data-content-path='some.content-en']")
31
+ expect(node).to have_css("div[data-content-path='some-content-en']")
32
32
  expect(node).to have_css("div[data-api-host='https://some.host']")
33
33
  expect(node).to have_css("div[data-api-key='apikey']")
34
34
  expect(node).to have_css("div[data-private-api-key='pk']")
35
35
  end
36
+ describe '#capture_default_value' do
37
+ it 'captures a block' do
38
+ allow(self).to receive(:cms_admin?).and_return(false)
36
39
 
37
- it 'captures a block' do
38
- allow(self).to receive(:cms_admin?).and_return(false)
40
+ node = Capybara.string cms('some.content') { content_tag('p', 'Block content!') }
41
+ expect(node).not_to have_css('div', text: 'Some CMS content')
42
+ expect(node).to have_css('div p', text: 'Block content!')
43
+ expect(node).to have_css("div[data-content-path='some-content-en']")
44
+ expect(node).to have_css("div[data-api-host='https://some.host']")
45
+ expect(node).to have_css("div[data-api-key='apikey']")
46
+ expect(node).not_to have_css('div[data-private-api-key]')
47
+ end
39
48
 
40
- node = Capybara.string cms('some.content') { content_tag('p', 'Block content!') }
41
- expect(node).not_to have_css('div', text: 'Some CMS content')
42
- expect(node).to have_css('div p', text: 'Block content!')
43
- expect(node).to have_css("div[data-content-path='some.content-en']")
44
- expect(node).to have_css("div[data-api-host='https://some.host']")
45
- expect(node).to have_css("div[data-api-key='apikey']")
46
- expect(node).not_to have_css('div[data-private-api-key]')
47
- end
49
+ it 'translates a key as content' do
50
+ allow(self).to receive(:cms_admin?).and_return(false)
48
51
 
49
- it 'translates a key as content' do
50
- allow(self).to receive(:cms_admin?).and_return(false)
52
+ I18n.backend.store_translations :en, some: { content: 'I18n.t content!' }
53
+ node = Capybara.string cms('some.content')
54
+ expect(node).to have_css('div', text: 'I18n.t content!')
55
+ expect(node).to have_css("div[data-content-path='some-content-en']")
56
+ expect(node).to have_css("div[data-api-host='https://some.host']")
57
+ expect(node).to have_css("div[data-api-key='apikey']")
58
+ expect(node).not_to have_css('div[data-private-api-key]')
59
+ end
51
60
 
52
- I18n.backend.store_translations :en, some: { content: 'I18n.t content!' }
53
- node = Capybara.string cms('some.content')
54
- expect(node).to have_css('div', text: 'I18n.t content!')
55
- expect(node).to have_css("div[data-content-path='some.content-en']")
56
- expect(node).to have_css("div[data-api-host='https://some.host']")
57
- expect(node).to have_css("div[data-api-key='apikey']")
58
- expect(node).not_to have_css('div[data-private-api-key]')
61
+ it 'uses the cache as prio 1' do
62
+ allow(self).to receive(:cms_admin?).and_return(false)
63
+
64
+ original = RenuoCmsRails::Cache.instance_variable_get('@cache')
65
+ expect(original).to receive(:get).with('some-content-en').and_return('Cached content!')
66
+ node1 = Capybara.string cms('some.content')
67
+ expect(node1).to have_css('div', text: 'Cached content!')
68
+
69
+ expect(original).to receive(:get).with('some-content-en').and_return('Cached content!')
70
+ node2 = Capybara.string cms('some.content') { content_tag('p', 'Block content!') }
71
+ expect(node2).to have_css('div', text: 'Cached content!')
72
+
73
+ expect(original).to receive(:get).with('some-content-en').and_return('Cached content!')
74
+ I18n.backend.store_translations :en, some: { content: 'I18n.t content!' }
75
+ node3 = Capybara.string cms('some.content')
76
+ expect(node3).to have_css('div', text: 'Cached content!')
77
+
78
+ expect(original).to receive(:get).with('some-content-en').and_return('Cached content!')
79
+ node4 = Capybara.string cms('some.content', 'default content')
80
+ expect(node4).to have_css('div', text: 'Cached content!')
81
+ end
59
82
  end
60
83
 
61
84
  it 'uses the custom content_path_generator config' do
@@ -64,6 +87,6 @@ describe RenuoCmsRails::CmsHelper do
64
87
  RenuoCmsRails.config.content_path_generator = ->(path) { "#{I18n.locale}--#{path}" }
65
88
 
66
89
  node = Capybara.string cms('some.content', 'Some CMS content')
67
- expect(node).to have_css("div[data-content-path='en--some.content']")
90
+ expect(node).to have_css("div[data-content-path='en--some-content']")
68
91
  end
69
92
  end
data/spec/spec_helper.rb CHANGED
@@ -2,3 +2,4 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
2
2
  require 'renuo-cms-rails'
3
3
  require 'capybara'
4
4
  require 'climate_control'
5
+ require 'webmock/rspec'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renuo-cms-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Elmer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-25 00:00:00.000000000 Z
11
+ date: 2016-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -164,6 +164,34 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: 4.0.1
167
+ - !ruby/object:Gem::Dependency
168
+ name: timecop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 0.8.0
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 0.8.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: webmock
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: 2.0.3
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: 2.0.3
167
195
  description: The Renuo CLI automates some commonly used workflows by providing a command
168
196
  line interface.
169
197
  email:
@@ -186,10 +214,18 @@ files:
186
214
  - Rakefile
187
215
  - lib/railtie.rb
188
216
  - lib/renuo-cms-rails.rb
217
+ - lib/renuo_cms_rails/api.rb
218
+ - lib/renuo_cms_rails/api/contents.rb
219
+ - lib/renuo_cms_rails/cache.rb
220
+ - lib/renuo_cms_rails/cache/cacher.rb
189
221
  - lib/renuo_cms_rails/cms_helper.rb
190
222
  - lib/renuo_cms_rails/config.rb
191
223
  - lib/renuo_cms_rails/version.rb
192
224
  - renuo_cms_rails.gemspec
225
+ - spec/renuo_cms_rails/api/contents_spec.rb
226
+ - spec/renuo_cms_rails/api_spec.rb
227
+ - spec/renuo_cms_rails/cache_spec.rb
228
+ - spec/renuo_cms_rails/cacher/cacher_spec.rb
193
229
  - spec/renuo_cms_rails/cms_helper_spec.rb
194
230
  - spec/renuo_cms_rails/config_spec.rb
195
231
  - spec/spec_helper.rb
@@ -219,6 +255,10 @@ signing_key:
219
255
  specification_version: 4
220
256
  summary: Rails helpers for the renuo-cms
221
257
  test_files:
258
+ - spec/renuo_cms_rails/api/contents_spec.rb
259
+ - spec/renuo_cms_rails/api_spec.rb
260
+ - spec/renuo_cms_rails/cache_spec.rb
261
+ - spec/renuo_cms_rails/cacher/cacher_spec.rb
222
262
  - spec/renuo_cms_rails/cms_helper_spec.rb
223
263
  - spec/renuo_cms_rails/config_spec.rb
224
264
  - spec/spec_helper.rb