From a09f049c2082b9f677a8009b3e45e2fbb2be3026 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 27 Apr 2018 15:48:26 -0300 Subject: [PATCH] WIP de reordenar posts --- app/models/post.rb | 10 ++++++++++ app/models/site.rb | 29 ++++++++++++++++++++++++----- doc/TODO.md | 2 ++ doc/reordenar.md | 15 +++++++++++++++ test/models/post_test.rb | 30 ++++++++++++++++++++++++++++++ test/models/site_test.rb | 27 +++++++++++++++++++++++++++ test/models/usuaria_test.rb | 18 ++++++++++++++++++ test/test_helper.rb | 14 ++++++++++---- 8 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 test/models/post_test.rb create mode 100644 test/models/site_test.rb create mode 100644 test/models/usuaria_test.rb diff --git a/app/models/post.rb b/app/models/post.rb index b8545b2..e70d24b 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -70,6 +70,16 @@ class Post @post.nil? || !File.exist?(@post.try(:path)) end + # El número de orden del artículo, si no tiene uno, se le asigna la + # posición en la colección de artículos + def order + get_front_matter 'order' + end + + def is_ordered? + !order.nil? + end + # Determina si fue traducido, buscando los slugs de su front_matter # lang en otras colecciones def translated? diff --git a/app/models/site.rb b/app/models/site.rb index 104b9e8..c085d61 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -69,11 +69,7 @@ class Site # Los posts de este sitio, si el sitio está traducido, trae los posts # del idioma actual, porque _posts va a estar vacío def posts - @posts ||= if i18n? - posts_for(I18n.locale.to_s) - else - posts_for('posts') - end + @posts ||= posts_for('posts') end # Obtiene todos los posts de una colección determinada @@ -82,6 +78,10 @@ class Site def posts_for(collection) return unless @jekyll.config['collections'].key? collection + # Si pedimos 'posts' pero estamos en un sitio traducido, traemos el + # idioma actual + collection = I18n.locale.to_s if collection == 'posts' && i18n? + _collection = @collections[collection] return _collection if _collection @@ -189,6 +189,25 @@ class Site end alias :dequeue! :dequeue + # Verifica si los posts están ordenados + def ordered?(collection = 'posts') + posts_for(collection).map do |p| + p.order + end.all? + end + + # Reordena la colección usando la posición actual de los artículos y + # guarda los cambios + def reorder_collection!(collection = 'posts') + posts_for(collection).each_with_index do |p, i| + p.update_attributes order: i + p.save + end + + true + end + alias :reorder_posts! :reorder_collection! + # El directorio donde se almacenan los sitios def self.site_path File.join(Rails.root, '_sites') diff --git a/doc/TODO.md b/doc/TODO.md index b6c98af..4b6df7e 100644 --- a/doc/TODO.md +++ b/doc/TODO.md @@ -2,3 +2,5 @@ * Convertir Site y Post en adaptadores de ActiveRecord, para que podamos trabajar de la forma Rails (con asociaciones, etc.) + + O tal vez solo extender Array con SiteCollection o algo así diff --git a/doc/reordenar.md b/doc/reordenar.md index 3cbf6bf..719856f 100644 --- a/doc/reordenar.md +++ b/doc/reordenar.md @@ -117,3 +117,18 @@ cambios mínimos. También podemos tomar todo el set original de fechas y asociarselo al orden nuevo de posts. Las fechas se mantienen igual, pero cambia el orden de los posts. + +Qué pasa cuando dos o más artículos comparten la misma fecha? +Normalmente se ordenan por nombre, pero en este algoritmo no entra ese +orden, se asume que siempre están una fecha adelante o atrás + +--- + +Todos los posts tienen un campo order. + +El orden se actualiza en base al orden cronologico. + +En la plantilla se puede ordenar cronólogicamente o por orden numérico. + +Es más simple de implementar y no tiene comportamientos inesperados, +como "por qué cambió de fecha?" diff --git a/test/models/post_test.rb b/test/models/post_test.rb new file mode 100644 index 0000000..c67bdb6 --- /dev/null +++ b/test/models/post_test.rb @@ -0,0 +1,30 @@ +require 'test_helper' + +class PostTest < ActiveSupport::TestCase + setup do + @user = Usuaria.find('f@kefir.red') + @path = File.join(Site.site_path_for(@user), 'cyber-women.com') + @site = @user.sites.select { |s| s.name == 'cyber-women.com' }.first + @post = @site.posts.sample + end + + test 'El post no es nuevo si ya existe' do + assert_not @post.new? + end + + test 'El post está traducido' do + assert @post.translated? + end + + test 'El post tiene un título' do + assert String, @post.title.class + end + + test 'El post tiene una fecha' do + assert DateTime, @post.date.class + end + + test 'Es obvio que un post recién cargado es válido' do + assert @post.valid? + end +end diff --git a/test/models/site_test.rb b/test/models/site_test.rb new file mode 100644 index 0000000..f640e8b --- /dev/null +++ b/test/models/site_test.rb @@ -0,0 +1,27 @@ +require 'test_helper' + +class SiteTest < ActiveSupport::TestCase + setup do + @user = Usuaria.find('f@kefir.red') + @path = File.join(Site.site_path_for(@user), 'cyber-women.com') + reset_git_repo(@path) + @site = @user.sites.select { |s| s.name == 'cyber-women.com' }.first + @site.read + end + + test "El directorio es un sitio jekyll" do + assert Site.jekyll?(@path) + end + + test 'Un directorio se puede cargar como un sitio Jekyll' do + jekyll = Site.load_jekyll @path + + assert_equal Jekyll::Site, jekyll.class + end + + test 'Los artículos no están ordenados si a alguno le falta orden' do + assert_not @site.ordered? + assert @site.reorder_collection! + assert @site.ordered? + end +end diff --git a/test/models/usuaria_test.rb b/test/models/usuaria_test.rb new file mode 100644 index 0000000..fc7d103 --- /dev/null +++ b/test/models/usuaria_test.rb @@ -0,0 +1,18 @@ +require 'test_helper' + +class UsuariaTest < ActiveSupport::TestCase + setup do + @mail = 'f@kefir.red' + @usuaria = Usuaria.find(@mail) + end + + test "La usuaria puede encontrarse por su mail" do + assert_equal @mail, @usuaria.username + end + + test "La usuaria tiene sitios" do + @usuaria.sites.each do |s| + assert_equal Site, s.class + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index e3c4ff0..aad06af 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,9 +1,15 @@ require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' +require 'open3' class ActiveSupport::TestCase - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. - fixtures :all - - # Add more helper methods to be used by all tests here... + # Resetear el repositorio a su estado original antes de leerlo + def reset_git_repo(path) + Dir.chdir(path) do + Open3::popen3('git reset --hard') do |_, _, _, thread| + # Wait for the process to finish + thread.value + end + end + end end