mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-25 23:56:22 +00:00
Modificar Site con un servicio
This commit is contained in:
parent
603d0cfea7
commit
f65a7f5fe2
10 changed files with 133 additions and 29 deletions
|
@ -42,6 +42,7 @@ Metrics/BlockLength:
|
|||
- 'config/initializers/devise.rb'
|
||||
- 'db/schema.rb'
|
||||
- 'config/routes.rb'
|
||||
- 'test/controllers/sites_controller_test.rb'
|
||||
|
||||
Metrics/ClassLength:
|
||||
Exclude:
|
||||
|
@ -49,6 +50,7 @@ Metrics/ClassLength:
|
|||
- 'app/controllers/posts_controller.rb'
|
||||
- 'app/controllers/sites_controller.rb'
|
||||
- 'test/models/post_test.rb'
|
||||
- 'test/controllers/sites_controller_test.rb'
|
||||
|
||||
Lint/HandleExceptions:
|
||||
Exclude:
|
||||
|
|
|
@ -29,15 +29,10 @@ class SitesController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@site = Site.new(site_params)
|
||||
@site.roles << Rol.new(site: @site,
|
||||
usuarie: current_usuarie,
|
||||
temporal: false,
|
||||
rol: 'usuarie')
|
||||
service = SiteService.new(usuarie: current_usuarie,
|
||||
params: site_params)
|
||||
|
||||
# XXX: Necesitamos escribir la configuración después porque queremos
|
||||
# registrar quién hizo los cambios en el repositorio
|
||||
if @site.save && @site.config.write(current_usuarie)
|
||||
if (@site = service.create).persisted?
|
||||
redirect_to site_path(@site)
|
||||
else
|
||||
render 'new'
|
||||
|
@ -53,9 +48,10 @@ class SitesController < ApplicationController
|
|||
@site = find_site
|
||||
authorize @site
|
||||
|
||||
# XXX: Necesitamos escribir la configuración después porque queremos
|
||||
# registrar quién hizo los cambios en el repositorio
|
||||
if @site.update(site_params) && @site.config.write(current_usuarie)
|
||||
service = SiteService.new(site: @site, params: site_params,
|
||||
usuarie: current_usuarie)
|
||||
|
||||
if service.update
|
||||
redirect_to sites_path
|
||||
else
|
||||
render 'edit'
|
||||
|
@ -64,8 +60,9 @@ class SitesController < ApplicationController
|
|||
|
||||
# Envía un archivo del directorio público de Jekyll
|
||||
def send_public_file
|
||||
authorize Site
|
||||
@site = find_site
|
||||
authorize @site
|
||||
|
||||
file = [params[:basename], params[:format]].join('.')
|
||||
path = File.join(@site.path, 'public', params[:type], file)
|
||||
path = Pathname.new path
|
||||
|
|
|
@ -316,9 +316,9 @@ class Site < ApplicationRecord
|
|||
# TODO: Guardar la configuración también, quizás aprovechando algún
|
||||
# método de ActiveRecord para que lance un salvado recursivo.
|
||||
def sync_attributes_with_config!
|
||||
config.theme = design.gem unless design_id_changed?
|
||||
config.description = description unless description_changed?
|
||||
config.title = title unless title_changed?
|
||||
config.theme = design.gem
|
||||
config.description = description
|
||||
config.title = title
|
||||
end
|
||||
|
||||
# Valida si el sitio tiene al menos una forma de alojamiento asociada
|
||||
|
|
|
@ -8,6 +8,8 @@ class Site
|
|||
# Iniciar el OpenStruct con el sitio
|
||||
super(site: site)
|
||||
|
||||
self.saved = File.exist? path
|
||||
|
||||
read
|
||||
end
|
||||
|
||||
|
@ -28,21 +30,19 @@ class Site
|
|||
end
|
||||
|
||||
# Escribe los cambios en el repositorio
|
||||
def write(usuarie = nil)
|
||||
def write
|
||||
return if persisted?
|
||||
|
||||
I18n.with_locale(usuarie.try(:lang) || I18n.default_locale) do
|
||||
Site::Writer.new(site: site, file: path,
|
||||
content: content.to_yaml, usuarie: usuarie,
|
||||
message: I18n.t('sites.repository.config')).save
|
||||
end
|
||||
self.saved = Site::Writer.new(site: site, file: path,
|
||||
content: content.to_yaml).save
|
||||
# Actualizar el hash para no escribir dos veces
|
||||
@hash = content.hash
|
||||
end
|
||||
alias save write
|
||||
|
||||
# Detecta si la configuración cambió comparando con el valor inicial
|
||||
def persisted?
|
||||
@hash == content.hash
|
||||
(@hash == content.hash) && saved
|
||||
end
|
||||
|
||||
# Obtener el contenido de la configuración como un hash, sin el
|
||||
|
|
|
@ -6,9 +6,10 @@ class Site
|
|||
# que un sitio tiene un solo origen, que siempre se trabaja con la
|
||||
# rama master, etc.
|
||||
class Repository
|
||||
attr_reader :rugged, :changes
|
||||
attr_reader :rugged, :changes, :path
|
||||
|
||||
def initialize(path)
|
||||
@path = path
|
||||
@rugged = Rugged::Repository.new(path)
|
||||
@changes = 0
|
||||
end
|
||||
|
@ -87,7 +88,7 @@ class Site
|
|||
# Guarda los cambios en git, de a un archivo por vez
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def commit(file:, usuarie:, message:)
|
||||
rugged.index.add(file)
|
||||
rugged.index.add(relativize(file))
|
||||
rugged.index.write
|
||||
|
||||
Rugged::Commit.create(rugged,
|
||||
|
@ -107,5 +108,11 @@ class Site
|
|||
def committer
|
||||
{ name: 'Sutty', email: "sutty@#{Site.domain}", time: Time.now }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def relativize(file)
|
||||
Pathname.new(file).relative_path_from(Pathname.new(path)).to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
50
app/services/site_service.rb
Normal file
50
app/services/site_service.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Se encargar de guardar cambios en sitios
|
||||
# TODO: Implementar rollback en la configuración
|
||||
# rubocop:disable Metrics/BlockLength
|
||||
SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do
|
||||
# Crea un sitio, agrega un rol nuevo y guarda los cambios a la
|
||||
# configuración en el repositorio git
|
||||
def create
|
||||
self.site = Site.new params
|
||||
|
||||
add_role temporal: false, rol: 'usuarie'
|
||||
|
||||
I18n.with_locale(usuarie.try(:lang) || I18n.default_locale) do
|
||||
site.save &&
|
||||
site.config.write &&
|
||||
commit_config(action: :create)
|
||||
end
|
||||
|
||||
site
|
||||
end
|
||||
|
||||
# Actualiza el sitio y guarda los cambios en la configuración
|
||||
def update
|
||||
I18n.with_locale(usuarie.try(:lang) || I18n.default_locale) do
|
||||
site.update_attributes(params) &&
|
||||
site.config.write &&
|
||||
commit_config(action: :update)
|
||||
end
|
||||
|
||||
site
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Guarda los cambios de la configuración en el repositorio git
|
||||
def commit_config(action:)
|
||||
site.repository
|
||||
.commit(usuarie: usuarie,
|
||||
file: site.config.path,
|
||||
message: I18n.t("site_service.#{action}",
|
||||
name: site.name))
|
||||
end
|
||||
|
||||
def add_role(temporal: true, rol: 'invitade')
|
||||
site.roles << Rol.new(site: site, usuarie: usuarie,
|
||||
temporal: temporal, rol: rol)
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/BlockLength
|
|
@ -1,4 +1,7 @@
|
|||
en:
|
||||
site_service:
|
||||
create: 'Created %{name}'
|
||||
update: 'Updated %{name}'
|
||||
post_service:
|
||||
created: 'Created "%{title}"'
|
||||
metadata:
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
es:
|
||||
site_service:
|
||||
create: 'Creado %{name}'
|
||||
update: 'Actualizado %{name}'
|
||||
post_service:
|
||||
created: 'Creado "%{title}"'
|
||||
metadata:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class SitesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@rol = create :rol
|
||||
|
@ -30,13 +32,14 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
test 'se pueden crear' do
|
||||
name = SecureRandom.hex
|
||||
design = create :design
|
||||
|
||||
post sites_url, headers: @authorization, params: {
|
||||
site: {
|
||||
name: name,
|
||||
title: name,
|
||||
description: name * 2,
|
||||
design_id: create(:design).id,
|
||||
design_id: design.id,
|
||||
licencia_id: create(:licencia).id,
|
||||
deploys_attributes: {
|
||||
'0' => {
|
||||
|
@ -52,6 +55,16 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
assert_equal @usuarie.email, site.roles.first.usuarie.email
|
||||
assert_equal 'usuarie', site.roles.first.rol
|
||||
|
||||
assert_equal name, site.name
|
||||
assert_equal name, site.title
|
||||
assert_equal name * 2, site.description
|
||||
assert_equal design, site.design
|
||||
assert_equal design.gem, site.config.theme
|
||||
assert_equal name, site.config.title
|
||||
assert_equal name * 2, site.config.description
|
||||
assert_equal I18n.t('site_service.create', name: name),
|
||||
site.repository.rugged.head.target.message
|
||||
|
||||
site.destroy
|
||||
end
|
||||
|
||||
|
@ -84,4 +97,36 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
Sidekiq::Testing.inline!
|
||||
end
|
||||
|
||||
test 'se pueden actualizar' do
|
||||
name = SecureRandom.hex
|
||||
design = create :design
|
||||
|
||||
put site_url(@site), headers: @authorization, params: {
|
||||
site: {
|
||||
name: name,
|
||||
title: name,
|
||||
description: name * 2,
|
||||
design_id: design.id,
|
||||
licencia_id: create(:licencia).id,
|
||||
deploys_attributes: {
|
||||
'0' => {
|
||||
type: 'DeployLocal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@site = Site.find(@site.id)
|
||||
|
||||
assert_equal name, @site.name
|
||||
assert_equal name, @site.title
|
||||
assert_equal name * 2, @site.description
|
||||
assert_equal design, @site.design
|
||||
assert_equal design.gem, @site.config.theme
|
||||
assert_equal name, @site.config.title
|
||||
assert_equal name * 2, @site.config.description
|
||||
assert_equal I18n.t('site_service.update', name: name),
|
||||
@site.repository.rugged.head.target.message
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,15 +23,12 @@ class ConfigText < ActiveSupport::TestCase
|
|||
@site.config.lang = 'es'
|
||||
end
|
||||
|
||||
assert @site.config.write(@usuarie)
|
||||
assert @site.config.write
|
||||
|
||||
config = Site::Config.new(@site)
|
||||
|
||||
assert_equal 'Test', config.name
|
||||
assert_equal 'es', config.lang
|
||||
|
||||
assert_equal I18n.t('sites.repository.config'),
|
||||
@site.repository.rugged.head.target.message
|
||||
end
|
||||
|
||||
test 'se puede obtener información' do
|
||||
|
|
Loading…
Reference in a new issue