add first entities and repository business logic

arnaud sellenet committed Jun 03, 2014
commit 54b6727fc8837a3e89be602368250c8c0a036c8b
Showing 9 changed files with 361 additions and 4 deletions
locomotive/steam/entities/content_type.rb b/lib/locomotive/steam/entities/content_type.rb +11 -0
@@ @@ -0,0 +1,11 @@
+ module Locomotive
+ module Steam
+ module Entities
+ class ContentType
+ include Locomotive::Entity
+ ## fields ##
+
+ end
+ end
+ end
+ end
locomotive/steam/entities/page.rb b/lib/locomotive/steam/entities/page.rb +147 -0
@@ @@ -0,0 +1,147 @@
+ module Locomotive
+ module Steam
+ module Entities
+ class Page
+ include Locomotive::Entity
+
+ ## fields ##
+ attributes :parent, :title, :slug, :fullpath, :redirect_url, :redirect_type,
+ :template, :handle, :listed, :searchable, :templatized, :content_type,
+ :published, :cache_strategy, :response_type, :position, :seo_title,
+ :meta_keywords, :meta_description, :editable_elements, :site
+
+ ## aliases ##
+ alias :listed? :listed
+ alias :published? :published
+ alias :templatized? :templatized
+ alias :searchable? :searchable
+
+ attr_accessor :templatized_from_parent
+
+
+ # Tell if the page is either the index page.
+ #
+ # @return [ Boolean ] True if index page.
+ #
+ def index?
+ 'index' == fullpath
+ end
+
+ # Tell if the page is either the index or the 404 page.
+ #
+ # @return [ Boolean ] True if index or 404 page.
+ #
+ def index_or_404?
+ %w(index 404).include?(fullpath)
+ end
+
+ alias :index_or_not_found? :index_or_404?
+
+ def with_cache?
+ self.cache_strategy != 'none'
+ end
+
+ def default_response_type?
+ self.response_type == 'text/html'
+ end
+
+ # Is it a redirect page ?
+ #
+ # @return [ Boolean ] True if the redirect_url property is set
+ #
+ def redirect?
+ !self.redirect_url.blank?
+ end
+
+ # Depth of the page in the site tree.
+ # Both the index and 404 pages are 0-depth.
+ #
+ # @return [ Integer ] The depth
+ #
+ def depth
+ return 0 if %w(index 404).include?(self.fullpath)
+ fullpath.split('/').size
+ end
+
+ def unpublished?
+ !self.published?
+ end
+
+ # Modified setter in order to set correctly the slug
+ #
+ # @param [ String ] fullpath The fullpath
+ #
+ def fullpath_with_setting_slug=(fullpath)
+ if fullpath && self.slug.nil?
+ self.slug = File.basename(fullpath)
+ end
+
+ self.fullpath_without_setting_slug = fullpath
+ end
+
+ alias_method_chain :fullpath=, :setting_slug
+
+ # Modified setter in order to set inheritance fields from parent
+ #
+ # @param [ String ] fullpath The fullpath
+ #
+ def parent_with_inheritance=(parent)
+ self.templatized_from_parent = parent.templatized?
+
+ # copy properties from the parent
+ %w(templatized content_type).each do |name|
+ self.send(:"#{name}=", parent.send(name.to_sym))
+ end
+
+ self.parent_without_inheritance = parent
+ end
+ alias_method_chain :parent=, :inheritance
+
+ # Return the fullpath dasherized and with the "*" character
+ # for the slug of templatized page.
+ #
+ # @return [ String ] The safe full path or nil if the page is not translated in the current locale
+ #
+ def safe_fullpath
+ if index_or_404?
+ slug
+ else
+ base = parent.safe_fullpath
+ _slug = if templatized? && !templatized_from_parent
+ '*'
+ else
+ slug
+ end
+ (base == 'index' ? _slug : File.join(base, _slug)).dasherize
+ end
+ end
+ # Set the source of the page without any pre-rendering. Used by the API reader.
+ #
+ # @param [ String ] content The HTML raw template
+ #
+ def raw_template=(content)
+ @source ||= {}
+ @source[:en] = content
+ end
+
+ # Return the Liquid template based on the raw_template property
+ # of the page. If the template is HAML or SLIM, then a pre-rendering to Liquid is done.
+ #
+ # @return [ String ] The liquid template or nil if not template has been provided
+ #
+ def source
+ @source ||= {}
+
+ if @source[:en]
+ @source[:en] # memoization
+ elsif self.template
+ @source[:en] = self.template.source
+ else
+ nil
+ end
+ end
+
+ end
+ end
+ end
+ end
locomotive/steam/entities/site.rb b/lib/locomotive/steam/entities/site.rb +30 -0
@@ @@ -0,0 +1,30 @@
+ module Locomotive
+ module Steam
+ module Entities
+ class Site
+ class NullObject
+ def method_missing *args
+ nil
+ end
+ end
+ include Locomotive::Entity
+
+ attributes :name, :locales, :subdomain, :domains, :seo_title,
+ :meta_keywords, :meta_description, :robots_txt, :timezone
+ ## methods ##
+
+ def default_locale
+ locales.first
+ end
+
+ def to_s
+ self.name
+ end
+
+ def to_liquid
+ NullObject.new
+ end
+ end
+ end
+ end
+ end
locomotive/steam/mapper.rb b/lib/locomotive/steam/mapper.rb +27 -4
@@ @@ -1,14 +1,37 @@
+ Dir[File.dirname(__FILE__) + '/entities/*.rb'].each { |file| require file }
+ Dir[File.dirname(__FILE__) + '/repositories/*.rb'].each { |file| require file }
+
collection :sites do
- entity Locomotive::Entities::Site
- repository Locomotive::Repositories::SitesRepository
+ entity Locomotive::Steam::Entities::Site
+ repository Locomotive::Steam::Repositories::SitesRepository
+
+ attribute :name
+ attribute :locales
+ attribute :subdomain
+ attribute :domains
+ attribute :seo_title, localized: true
+ attribute :meta_keywords, localized: true
+ attribute :meta_description, localized: true
+ attribute :robots_txt
+ attribute :timezone
+
+
end
collection :pages do
-
+ entity Locomotive::Steam::Entities::Page
+ repository Locomotive::Steam::Repositories::PagesRepository
+ attribute :fullpath
+ attribute :position
+ attribute :site, association: :sites
+ attribute :content_type, association: :content_types
end
collection :content_types do
-
+ entity Locomotive::Steam::Entities::ContentType
+ repository Locomotive::Steam::Repositories::ContentTypesRepository
+ attribute :slug
+ attribute :site, association: :sites
end
collection :content_entries do
locomotive/steam/repositories/content_types_repository.rb b/lib/locomotive/steam/repositories/content_types_repository.rb +14 -0
@@ @@ -0,0 +1,14 @@
+ module Locomotive
+ module Steam
+ module Repositories
+ class ContentTypesRepository
+ include Repository
+ def [](slug)
+ query(:en) do
+ where('slug.eq' => slug.to_s)
+ end.first
+ end
+ end
+ end
+ end
+ end
locomotive/steam/repositories/pages_repository.rb b/lib/locomotive/steam/repositories/pages_repository.rb +21 -0
@@ @@ -0,0 +1,21 @@
+ module Locomotive
+ module Steam
+ module Repositories
+ class PagesRepository
+ include Repository
+
+ def [](path)
+ matching_paths([paths])
+ end
+
+ def matching_paths(paths)
+ # TODO multilocales
+ query(:en) do
+ where('fullpath.in' => paths)
+ order_by('position ASC')
+ end
+ end
+ end
+ end
+ end
+ end
locomotive/steam/repositories/sites_repository.rb b/lib/locomotive/steam/repositories/sites_repository.rb +16 -0
@@ @@ -0,0 +1,16 @@
+ module Locomotive
+ module Steam
+ module Repositories
+ class SitesRepository
+ include Repository
+
+ def find_by_host(host)
+ # TODO multilocales
+ query(:en) do
+ where('domains.in' => host)
+ end.first
+ end
+ end
+ end
+ end
+ end
spec/unit/entities/page_spec.rb +83 -0
@@ @@ -0,0 +1,83 @@
+ require 'spec_helper'
+
+ describe 'Locomotive::Steam::Entities::Page' do
+
+ it 'builds an empty page' do
+ build_page.should_not be_nil
+ end
+
+ describe '#index?' do
+ it { build_page(fullpath: 'index').should be_index }
+ it { build_page(fullpath: 'about').should_not be_index }
+ it { build_page(fullpath: 'products/index').should_not be_index }
+ end
+
+ describe '#index_or_404?' do
+ it { build_page(fullpath: 'index').should be_index_or_404 }
+ it { build_page(fullpath: 'about').should_not be_index_or_404 }
+ it { build_page(fullpath: 'products/index').should_not be_index_or_404 }
+ it { build_page(fullpath: 'products/404').should_not be_index_or_404 }
+ it { build_page(fullpath: '404').should be_index_or_404 }
+ end
+
+ describe '#depth' do
+ it { build_page(fullpath: 'index').depth.should eq 0 }
+ it { build_page(fullpath: '404').depth.should eq 0 }
+ it { build_page(fullpath: 'about').depth.should eq 1 }
+ it { build_page(fullpath: 'about/me').depth.should eq 2 }
+ it { build_page(fullpath: 'about/index').depth.should eq 2 }
+ it { build_page(fullpath: 'about/the/team').depth.should eq 3 }
+ end
+
+ describe '#fullpath=' do
+ context 'when the page has no slug yet' do
+ it 'also sets the slug' do
+ build_page(fullpath: 'this/is/the/page_full_path').slug.should eq 'page_full_path'
+ end
+ end
+
+ context 'when the slug is already set' do
+ it 'keeps the original slug' do
+ build_page(fullpath: 'this/is/the/page_full_path', slug: 'the_slug').slug.should eq 'the_slug'
+ end
+ end
+ end
+
+ describe '#safe_fullpath' do
+ let(:index_page) { build_page(fullpath: 'index') }
+ let(:not_found_page) { build_page(fullpath: '404') }
+ let(:about_page) { build_page(fullpath: 'about_me', parent: index_page) }
+ let(:products_page) { build_page(fullpath: 'products', parent: index_page, templatized: true) }
+
+ context 'not templatized' do
+ context 'index or 404' do
+ it { index_page.safe_fullpath.should eq 'index' }
+ it { not_found_page.safe_fullpath.should eq '404' }
+ end
+
+ context 'other' do
+ it { about_page.safe_fullpath.should eq 'about-me' }
+ end
+ end
+
+ context 'templatized' do
+ subject { build_page(fullpath: 'products', parent: index_page, templatized: true) }
+ its(:safe_fullpath) { should eq '*' }
+ end
+
+ context 'templatized with not templatized parent' do
+ subject { build_page(fullpath: 'about_me/contact', parent: about_page, templatized: true) }
+ its(:safe_fullpath) { should eq 'about-me/*' }
+ end
+
+ context 'templatized parent' do
+ subject { build_page(fullpath: 'products/detail', parent: products_page) }
+ its(:safe_fullpath) { should eq '*/detail' }
+ end
+ end
+
+ def build_page(attributes = {})
+ Locomotive::Steam::Entities::Page.new(attributes)
+ end
+
+ end
spec/unit/entities/site_spec.rb +12 -0
@@ @@ -0,0 +1,12 @@
+ require 'spec_helper'
+
+ describe 'Locomotive::Steam::Entities::Site' do
+
+ describe '#default_locale' do
+ subject { Locomotive::Steam::Entities::Site.new attributes }
+ let(:attributes) { { locales: [:wk, :fr, :es] } }
+ it 'uses the first locale as default locale' do
+ expect(subject.default_locale).to eq :wk
+ end
+ end
+ end