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