refactor and add specs for the content entry liquid drop

did committed Feb 08, 2015
commit 475b3daa52a8e90380cc3b5811cf9c0b0813bd60
Showing 4 changed files with 178 additions and 72 deletions
locomotive/steam/liquid/drops/content_entry.rb b/lib/locomotive/steam/liquid/drops/content_entry.rb +66 -64
@@ @@ -1,78 +1,80 @@
- # module Locomotive
- # module Liquid
- # module Drops
- # class ContentEntry < Base
+ module Locomotive
+ module Steam
+ module Liquid
+ module Drops
+ class ContentEntry < Base
- # delegate :_slug, :_permalink, :_translated, :seo_title, :meta_keywords, :meta_description, to: :@_source
+ delegate :_slug, :_translated, :seo_title, :meta_keywords, :meta_description, to: :@_source
- # def _id
- # @_source._id.to_s
- # end
+ alias :_permalink :_slug
- # def _label
- # @_label ||= @_source._label
- # end
+ def _id
+ @_source._id.to_s
+ end
- # # Returns the next content for the parent content type.
- # # If no content is found, nil is returned.
- # #
- # # Usage:
- # #
- # # {% if article.next %}
- # # <a href="/articles/{{ article.next._permalink }}">Read next article</a>
- # # {% endif %}
- # #
- # def next
- # @next ||= @_source.next.to_liquid
- # end
+ def _label
+ @_label ||= @_source._label
+ end
- # # Returns the previous content for the parent content type.
- # # If no content is found, nil is returned.
- # #
- # # Usage:
- # #
- # # {% if article.previous %}
- # # <a href="/articles/{{ article.previous._permalink }}">Read previous article</a>
- # # {% endif %}
- # #
- # def previous
- # @previous ||= @_source.previous.to_liquid
- # end
+ # Returns the next content for the parent content type.
+ # If no content is found, nil is returned.
+ #
+ # Usage:
+ #
+ # {% if article.next %}
+ # <a href="{% path_to article.next %}">Read next article</a>
+ # {% endif %}
+ #
+ def next
+ @next ||= repository.next(@_source).to_liquid
+ end
- # def errors
- # @_source.errors.messages.to_hash.stringify_keys
- # end
+ # Returns the previous content for the parent content type.
+ # If no content is found, nil is returned.
+ #
+ # Usage:
+ #
+ # {% if article.previous %}
+ # <a href="{% path_to article.previous %}">Read previous article</a>
+ # {% endif %}
+ #
+ def previous
+ @previous ||= repository.previous(@_source).to_liquid
+ end
- # def before_method(meth)
- # return '' if @_source.nil?
+ def errors
+ @_source.errors.messages.to_hash.stringify_keys
+ end
- # if not @@forbidden_attributes.include?(meth.to_s)
- # value = @_source.send(meth)
+ def before_method(meth)
+ return '' if @_source.nil?
- # if value.respond_to?(:all) # check for an association
- # filter_and_order_list(value)
- # else
- # value
- # end
- # else
- # nil
- # end
- # end
+ if not @@forbidden_attributes.include?(meth.to_s)
+ value = @_source.send(meth)
- # protected
+ # check for an association (lazy loading)
+ if value.respond_to?(:all)
+ filter_association(value)
+ else
+ value
+ end
+ else
+ nil
+ end
+ end
- # def filter_and_order_list(list)
- # conditions, order_by = HashWithIndifferentAccess.new(_visible: true), nil
+ protected
- # if @context['with_scope']
- # conditions.merge!(@context['with_scope'])
- # order_by = conditions.delete(:order_by).try(:split)
- # end
+ def repository
+ @context.registers[:services].repositories.content_entry
+ end
- # list.filtered(conditions, order_by)
- # end
+ def filter_association(association)
+ repository.filter(association, @context['with_scope'] || {})
+ end
- # end
- # end
- # end
- # end
+ end
+ end
+ end
+ end
+ end
locomotive/steam/liquid/tags/path_helper.rb b/lib/locomotive/steam/liquid/tags/path_helper.rb +12 -5
@@ @@ -43,14 +43,21 @@ module Locomotive
# Note/TODO: we manipulate here only Liquid drops!
case handle
- when Locomotive::Page then handle
- when Locomotive::Liquid::Drops::Page then handle.instance_variable_get(:@_source)
- when String then fetch_page(site, handle)
- when Locomotive::ContentEntry then fetch_page(site, handle, true)
- when Locomotive::Liquid::Drops::ContentEntry then fetch_page(site, handle.instance_variable_get(:@_source), true)
+ when String then fetch_page(site, handle)
+ when Locomotive::Steam::Liquid::Drops::Page then handle.instance_variable_get(:@_source)
+ when Locomotive::Steam::Liquid::Drops::ContentEntry then fetch_page(site, handle.instance_variable_get(:@_source), true)
else
nil
end
+ # case handle
+ # when Locomotive::Page then handle
+ # when Locomotive::Liquid::Drops::Page then handle.instance_variable_get(:@_source)
+ # when String then fetch_page(site, handle)
+ # when Locomotive::ContentEntry then fetch_page(site, handle, true)
+ # when Locomotive::Liquid::Drops::ContentEntry then fetch_page(site, handle.instance_variable_get(:@_source), true)
+ # else
+ # nil
+ # end
end
def fetch_page(site, handle, templatized = false)
locomotive/steam/repositories/content_entry.rb b/lib/locomotive/steam/repositories/content_entry.rb +20 -3
@@ @@ -4,18 +4,35 @@ module Locomotive
class ContentEntry < Struct.new(:site)
- def all(content_type, conditions = {})
+ def all(type, conditions = {})
# TODO
end
- def group_by_select_option(content_type, name)
+ def filter(association, conditions = {})
+ # only visible entries
+ conditions[:_visible] = true
+
+ order_by = conditions.delete(:order_by).try(:split)
+
+ association.filtered(conditions, order_by)
+ end
+
+ def next(entry)
+ entry.next
+ end
+
+ def previous(entry)
+ entry.previous
+ end
+
+ def group_by_select_option(type, name)
klass = content_type.entries.klass
order = content_type.order_by_definition
klass.send(:group_by_select_option, name, order)
end
- def select_options(content_type, name)
+ def select_options(type, name)
klass = content_type.entries.klass
klass.send(:"#{name}_options").map { |option| option['name'] }
end
spec/unit/liquid/drops/content_entry_spec.rb +80 -0
@@ @@ -0,0 +1,80 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Liquid::Drops::ContentEntry do
+
+ let(:entry) { instance_double('Article', _id: 42, title: 'Hello world', _label: 'Hello world', _slug: 'hello-world', _translated: false, seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description') }
+ let(:assigns) { {} }
+ let(:services) { Locomotive::Steam::Services.build_instance }
+ let(:context) { ::Liquid::Context.new(assigns, {}, { services: services }) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry).tap { |d| d.context = context } }
+
+ subject { drop }
+
+ it 'gives access to general attributes' do
+ expect(subject._id).to eq '42'
+ expect(subject._label).to eq 'Hello world'
+ expect(subject._slug).to eq 'hello-world'
+ expect(subject._permalink).to eq 'hello-world'
+ expect(subject.seo_title).to eq 'seo title'
+ expect(subject.meta_keywords).to eq 'keywords'
+ expect(subject.meta_description).to eq 'description'
+ end
+
+ describe '#before_method (dynamic attributes)' do
+
+ describe 'simple ones' do
+ it { expect(subject.before_method(:title)).to eq 'Hello world' }
+ end
+
+ describe 'relationship field' do
+
+ let(:authors) { instance_double('Authors', all: ['john', 'jane']) }
+ let(:entry) { instance_double('Article', authors: authors) }
+
+ before do
+ allow(services.repositories.content_entry).to receive(:filter).with(authors, {}).and_return(authors.all)
+ end
+
+ it { expect(subject.before_method(:authors).first).to eq 'john' }
+
+ end
+
+ end
+
+ describe '#next' do
+
+ let(:next_entry) { instance_double('NextEntry', to_liquid: true) }
+
+ before do
+ expect(services.repositories.content_entry).to receive(:next).with(entry).and_return(next_entry)
+ end
+
+ it { expect(subject.next).to eq true }
+
+ end
+
+ describe '#previous' do
+
+ let(:previous_entry) { instance_double('PreviousEntry', to_liquid: true) }
+
+ before do
+ expect(services.repositories.content_entry).to receive(:previous).with(entry).and_return(previous_entry)
+ end
+
+ it { expect(subject.previous).to eq true }
+
+ end
+
+ describe '#errors' do
+
+ let(:errors) { instance_double('Errors', messages: { title: ['not_blank'] }) }
+
+ before do
+ expect(entry).to receive(:errors).and_return(errors)
+ end
+
+ it { expect(subject.errors).to eq('title' => ['not_blank']) }
+
+ end
+
+ end