renuo-cms-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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