# frozen_string_literal: true

require 'test_helper'

class PostTest < ActiveSupport::TestCase
  setup do
    @site = create :site
    @post = @site.posts.create(title: SecureRandom.hex,
                               description: SecureRandom.hex)
  end

  teardown do
    @site.destroy
  end

  test 'se puede acceder a los valores' do
    assert @site.posts.size.positive?
    assert @post.title.value.size.positive?
    assert @post.content.size.positive?
  end

  test 'no se puede setear cualquier atributo' do
    assert_raise NoMethodError do
      @post.verdura = 'verdura'
    end
  end

  test 'se pueden eliminar' do
    assert @post.destroy

    # Destruir el Post no modifica el sitio
    @site.reload

    assert_not File.exist?(@post.path.absolute)
    assert_not @site.posts(lang: @post.lang.value).include?(@post)
  end

  test 'se puede ver el contenido completo despuƩs de guardar' do
    assert @post.save

    # Queremos saber si todos los atributos del post terminaron en el
    # archivo
    @post.attributes.each do |attr|
      metadata = @post.send(attr)
      # ignorar atributos que no son datos
      next unless metadata.is_a? MetadataTemplate

      if metadata.empty?
        assert_not @post.document.data[attr.to_s].present?
      elsif metadata.type == :lang
        assert @post.path.relative.starts_with?("_#{metadata.value}/")
      elsif @post.document.respond_to? attr
        assert_equal metadata.value, @post.document.send(attr), attr
      else
        assert_equal metadata.value, @post.document.data[attr.to_s], attr
      end
    end
  end

  test 'se pueden validar' do
    assert @post.valid?

    # XXX: si usamos nil va a traer el valor original del documento, no
    # queremos tener esa informaciĆ³n sincronizada...
    @post.title.value = ''

    assert_not @post.valid?
  end

  test 'se pueden guardar sin validar' do
    assert @post.valid?
    @post.title.value = ''
    assert @post.save(validate: false)
  end

  test 'se pueden guardar los cambios' do
    title = SecureRandom.hex
    @post.title.value = title
    @post.description.value = title
    @post.categories.value << title

    assert @post.save

    Dir.chdir(@site.path) do
      collection = Jekyll::Collection.new(@site.jekyll, I18n.locale.to_s)
      document = Jekyll::Document.new(@post.path.value,
                                      site: @site.jekyll,
                                      collection: collection)
      document.read!

      assert document.data['categories'].include?(title)
      assert_equal title, document.data['title']
      assert_equal title, document.data['description']
      assert_equal 'post', document.data['layout']
    end
  end

  test 'se puede cambiar el slug' do
    @post.title.value = SecureRandom.hex
    assert_not @post.slug.changed?
    assert @post.slug.valid?

    ex_slug = @post.slug.value
    @post.slug.value = SecureRandom.hex

    assert_not_equal ex_slug, @post.slug.value
    assert_equal ex_slug, @post.slug.value_was
    assert @post.slug.changed?
    assert @post.slug.valid?
  end

  test 'se puede cambiar la fecha' do
    assert @post.date.valid?

    ex_date = @post.date.value
    @post.date.value = 2.days.ago

    assert_not_equal ex_date, @post.date.value
    assert_equal ex_date, @post.date.value_was
    assert @post.date.changed?
    assert @post.date.valid?
  end

  test 'al cambiar slug o fecha cambia el archivo de ubicacion' do
    hoy = 2.days.from_now.to_time
    path_was = @post.path.absolute
    @post.slug.value = title = SecureRandom.hex
    @post.date.value = hoy

    assert @post.path.changed?
    assert_equal "_es/#{hoy.strftime('%F')}-#{title}.markdown",
                 @post.path.relative

    assert @post.save
    assert_equal "_es/#{hoy.strftime('%F')}-#{title}.markdown",
                 @post.document.relative_path
    assert_not File.exist?(path_was)
    assert File.exist?(@post.path.absolute)
  end

  test 'new?' do
    post = @site.posts.build title: SecureRandom.hex,
                             description: SecureRandom.hex
    assert post.new?
    assert post.save
    assert_not post.new?
  end

  test 'no podemos pisar otros archivos' do
    post = @site.posts.create title: SecureRandom.hex,
                              description: SecureRandom.hex

    @post.slug.value = post.slug.value
    @post.date.value = post.date.value

    assert_not @post.save
    assert File.exist?(@post.path.absolute)
    assert File.exist?(@post.path.value_was)
  end

  test 'se pueden crear nuevos' do
    post = @site.posts.build(layout: :post)
    post.title.value = SecureRandom.hex
    post.content.value = SecureRandom.hex
    post.description.value = SecureRandom.hex

    assert post.new?
    assert post.save
    assert File.exist?(post.path.absolute)
  end

  test 'se pueden inicializar con valores' do
    title = SecureRandom.hex
    post = @site.posts.build(title: title,
                             description: title,
                             content: title)

    assert_equal title, post.title.value
    assert_equal title, post.description.value
    assert_equal title, post.content.value
    assert post.save
  end

  test 'no se pueden repetir los nombres' do
    title = SecureRandom.hex
    post = @site.posts.build(title: title,
                             description: title,
                             content: title)

    slug = post.slug.value

    assert post.save

    another_post = @site.posts.build(title: title, description: title, content: title)

    assert_equal slug, another_post.slug.value
    assert another_post.save
    assert_not_equal slug, another_post.slug.value
  end
end