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 |