From 1256258d768d68dc195541c41204c739bb1c26e7 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 6 Oct 2023 11:52:42 -0300 Subject: [PATCH] feat: la fecha del documento es una fecha convertida a timestamp --- app/models/metadata_document_date.rb | 60 +++--------- test/models/metadata_document_date_test.rb | 105 +++++++++++++++++++++ 2 files changed, 119 insertions(+), 46 deletions(-) create mode 100644 test/models/metadata_document_date_test.rb diff --git a/app/models/metadata_document_date.rb b/app/models/metadata_document_date.rb index 324e4be8..9ad815a7 100644 --- a/app/models/metadata_document_date.rb +++ b/app/models/metadata_document_date.rb @@ -1,21 +1,17 @@ # frozen_string_literal: true # Maneja la fecha del document -class MetadataDocumentDate < MetadataTemplate +class MetadataDocumentDate < MetadataDate # La fecha por defecto es ahora! - def default_value - Date.today.to_time - end - + # # @return [Time] - def document_value - return nil if post.new? - - document.date + def default_value + super.to_time end - def indexable? - true && !private? + # @return [Time,nil] + def document_value + document.data['date'] end # Siempre es obligatorio @@ -23,42 +19,14 @@ class MetadataDocumentDate < MetadataTemplate true end - def validate - super - - errors << I18n.t('metadata.date.invalid_format') unless valid_format? - - errors.empty? - end - - # El valor puede ser un Date, Time o una String en el formato - # "yyyy-mm-dd" - # - # XXX: Date.iso8601 acepta fechas en el futuro lejano, como 20000, - # pero Jekyll las limita a cuatro cifras, así que vamos a mantener - # eso. - # - # @see {https://github.com/jekyll/jekyll/blob/master/lib/jekyll/document.rb#L15} - def value - self[:value] = - case self[:value] - when String - begin - Date.iso8601(self[:value]).to_time - rescue Date::Error - document_value || default_value - end - else - self[:value] || document_value || default_value - end - end - private - def valid_format? - return true if self[:value].is_a?(Time) - - @valid_format_re ||= /\A\d{2,4}-\d{1,2}-\d{1,2}\z/ - @valid_format_re =~ self[:value].to_s + # Las fechas de los Jekyll::Document se manejan con Time pero no nos + # importa la hora. + # + # @param :value [Any] + # @return [Time, nil] + def sanitize(value) + super(value.to_s.split(' ', 2).first)&.to_time end end diff --git a/test/models/metadata_document_date_test.rb b/test/models/metadata_document_date_test.rb new file mode 100644 index 00000000..8b7d6bff --- /dev/null +++ b/test/models/metadata_document_date_test.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +require 'test_helper' + +class MetadataDocumentDateTest < ActiveSupport::TestCase + setup do + @site = build(:site) + @document = build(:document, site: @site.jekyll, path: '') + @name = 'date' + @layout = build(:layout, site: @site) + @post = build(:post, layout: @layout, site: @site, document: @document) + @metadata = MetadataDocumentDate.new(site: @site, document: @document, name: @name, type: 'date', layout: @layout, post: @post) + end + + # Una fecha al azar en el pasado o en el futuro + def random_value + Date.today.public_send(%i[- +].sample, (0..365).to_a.sample.days).to_time + end + + test 'se guarda en el encabezado' do + assert @metadata.front_matter? + end + + test 'por defecto es la fecha de hoy' do + assert_equal Date.today.to_time, @metadata.default_value + end + + test 'puede traer el valor desde el documento' do + @document.data[@name] = random_value + + assert_equal @document.date, @metadata.document_value + assert @metadata.save + assert_equal @document[@name], @metadata.value + end + + test 'al cambiar el valor podemos obtenerlo' do + @metadata.value = value_was = random_value + @metadata.value = random_value + + assert_equal value_was, @metadata.value_was + assert_not_equal value_was, @metadata.value + end + + test 'pueden tener un valor por defecto desde el layout' do + default = random_value + + @layout = build(:layout, site: @site, metadata: { @name => { 'default' => { I18n.locale.to_s => default }}}) + @metadata = MetadataDocumentDate.new(site: @site, document: @document, name: @name, type: 'document_date', layout: @layout) + + assert_equal default, @metadata.default_value + end + + test 'no se pueden indexar' do + assert_not @metadata.indexable? + end + + test 'son públicos por defecto' do + assert_not @metadata.private? + end + + test 'se pueden hacer privados' do + @layout = build(:layout, site: @site, metadata: { @name => { 'private' => true }}) + @metadata = MetadataDocumentDate.new(site: @site, document: @document, name: @name, type: 'document_date', layout: @layout) + + assert @metadata.private? + end + + test 'se les puede asignar un valor' do + @metadata.value = value = random_value + + assert_equal value, @metadata.value + end + + test 'se le puede asignar una fecha como string' do + value = random_value + @metadata.value = value.to_s + + assert @metadata.save + assert_equal value, @metadata.value + end + + test 'el valor asignado no puede tener espacios adelante ni atrás' do + value = random_value + @metadata.value = " #{value}\n\n" + + assert @metadata.save + assert_equal value, @metadata.value + end + + test 'no pueden tener html' do + content = random_value + + @metadata.value = value = "#{content}" + + assert @metadata.save + assert_not_equal value, @metadata.value + assert_equal content, @metadata.value + end + + test 'no se pueden asignar fechas muy en el futuro' do + @metadata.value = '10000-01-01' + + assert_not @metadata.valid? + end +end