diff --git a/app/models/metadata_image.rb b/app/models/metadata_image.rb index 6ca63c0..763d484 100644 --- a/app/models/metadata_image.rb +++ b/app/models/metadata_image.rb @@ -5,19 +5,42 @@ class MetadataImage < MetadataTemplate # Una ruta vacía a la imagen con una descripción vacía def default_value - { 'path' => '', 'description' => '' } + { 'path' => nil, 'description' => nil } end def empty? value == default_value end + def validate + super + + errors << I18n.t('metadata.image.path_required') if path_missing? + + errors.compact! + errors.empty? + end + + # Determina si necesitamos la imagen pero no la tenemos + def path_missing? + required && !value['path'].blank? + end + + # Determina si el archivo ya fue subido + def uploaded? + value['path'].is_a?(String) + end + + # Determina si la ruta es opcional pero deja pasar si la ruta se + # especifica + def path_optional? + !required && value['path'].blank? + end + # Asociar la imagen subida al sitio y obtener la ruta - # rubocop:disable Metrics/CyclomaticComplexity def save - return true if !required && value['path'].blank? - return false if required && value['path'].blank? - return true if value['path'].is_a? String + return true if uploaded? + return true if path_optional? return false unless hardlink.zero? # Modificar el valor actual @@ -25,7 +48,6 @@ class MetadataImage < MetadataTemplate true end - # rubocop:enable Metrics/CyclomaticComplexity def to_param { name => %i[description path] } @@ -36,7 +58,7 @@ class MetadataImage < MetadataTemplate # # @return ActiveStorage::Attachment def static_file - if value['path'].is_a? String + if uploaded? blob = ActiveStorage::Blob.find_by(key: key_from_path) @static_file ||= site.static_files.find_by(blob_id: blob.id) else diff --git a/config/locales/es.yml b/config/locales/es.yml index 6359671..f16d6b2 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -16,6 +16,8 @@ es: cant_be_empty: 'El campo no puede estar vacío' image: cant_be_empty: 'El campo no puede estar vacío' + not_an_image: 'No es una imagen' + path_required: 'Se necesita un archivo de imagen' exceptions: post: site_missing: 'Necesita una instancia de Site' diff --git a/doc/uploads.md b/doc/uploads.md index 4686004..c2154f4 100644 --- a/doc/uploads.md +++ b/doc/uploads.md @@ -85,3 +85,10 @@ Entonces: ## Dependencias Usamos VIPS para procesar imágenes con bajo consumo de recursos + +## TODO + +* Crear una vista de galería +* Poder elegir imágenes desde la galería +* Optimizar las imágenes subidas + * Crear un paquete de oxipng para Alpine diff --git a/test/controllers/posts_controller_test.rb b/test/controllers/posts_controller_test.rb index bad8d0f..254b928 100644 --- a/test/controllers/posts_controller_test.rb +++ b/test/controllers/posts_controller_test.rb @@ -92,4 +92,29 @@ class PostsControllerTest < ActionDispatch::IntegrationTest assert_equal I18n.t('post_service.destroyed', title: @post.title.value), @site.repository.rugged.head.target.message end + + test 'se pueden subir imágenes' do + patch site_post_url(@site, @post.id), + headers: @authorization, + params: { + post: { + image: { + path: fixture_file_upload('files/logo.png', 'image/png'), + description: 'hola' + } + } + } + + assert_equal 302, response.status + + @site = Site.find(@site.id) + # TODO: Implementar reload + @post = @site.posts.find(@post.id) + + Dir.chdir(@site.path) do + assert File.exist?(@post.image.value['path']) + end + + assert_equal 'hola', @post.image.value['description'] + end end