Skip to content

Commit 7c18403

Browse files
authored
feat: new reset section command (#180)
* fix: the -h option wasn't working * feat: new reset section content command
1 parent e9e6cd0 commit 7c18403

File tree

7 files changed

+265
-5
lines changed

7 files changed

+265
-5
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# frozen_string_literal: true
2+
3+
module Maglev
4+
# Reset the content of a section type across a site and its pages
5+
class ResetSectionContent
6+
include Injectable
7+
8+
argument :site
9+
argument :theme
10+
argument :type
11+
12+
def call
13+
validate_section_type!
14+
15+
@count = 0
16+
17+
reset_content
18+
19+
@count
20+
end
21+
22+
private
23+
24+
def validate_section_type!
25+
return if theme.sections.find(type)
26+
27+
raise Maglev::Errors::UnknownSection,
28+
"Section type '#{type}' doesn't exist in the theme"
29+
end
30+
31+
def reset_content
32+
ActiveRecord::Base.transaction do
33+
reset_resource_content(site)
34+
site_pages.find_each do |page|
35+
reset_resource_content(page)
36+
end
37+
end
38+
end
39+
40+
def reset_resource_content(resource)
41+
site.each_locale do
42+
@count += reset_sections_content_of_type(resource.find_sections_by_type(type), type)
43+
end
44+
45+
resource.save!
46+
end
47+
48+
def reset_sections_content_of_type(sections, type)
49+
return 0 if sections.blank?
50+
51+
sections.map do |section|
52+
section.replace(build_default_content(type))
53+
end.size
54+
end
55+
56+
def build_default_content(type)
57+
theme.sections.find(type).build_default_content
58+
end
59+
60+
def site_pages
61+
Maglev::Page
62+
end
63+
end
64+
end

lib/commands/maglev/change_site_locales_command.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Maglev
66
class ChangeSiteLocalesCommand < Rails::Command::Base
77
desc 'change_site_locales [LOCALES]', 'Change site locales (format: label:prefix)'
88

9-
def self.banner
9+
def self.banner(_command = nil, *)
1010
'bin/rails maglev:change_site_locales [label:prefix label2:prefix2 ...]'
1111
end
1212

lib/commands/maglev/create_site_command.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Maglev
66
class CreateSiteCommand < Rails::Command::Base
77
desc 'create_site', 'Create your site'
88

9-
def self.banner
9+
def self.banner(_command = nil, *)
1010
'bin/rails maglev:create_site'
1111
end
1212

lib/commands/maglev/sections/remove_command.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module Sections
77
class RemoveCommand < Rails::Command::Base
88
desc 'remove TYPE', 'Remove a section type across the site and its pages'
99

10-
def self.banner
10+
def self.banner(_command = nil, *)
1111
'bin/rails maglev:sections:remove TYPE'
1212
end
1313

lib/commands/maglev/sections/rename_command.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
# frozen_string_literal: true
22

3+
require 'rails'
4+
35
module Maglev
46
module Sections
57
class RenameCommand < Rails::Command::Base
68
desc 'rename OLD_TYPE NEW_TYPE', 'Rename a section type across the site and its pages'
79

8-
def self.banner
10+
def self.banner(_command = nil, *)
911
'bin/rails maglev:sections:rename OLD_TYPE NEW_TYPE'
1012
end
1113

12-
def perform(old_type, new_type)
14+
def perform(*args)
1315
require File.expand_path('config/environment', Rails.root)
1416

17+
old_type, new_type = args
18+
1519
site = fetch_site
1620
theme = fetch_theme
1721

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails'
4+
5+
module Maglev
6+
module Sections
7+
class ResetCommand < Rails::Command::Base
8+
desc 'reset TYPE', 'Reset the content of a section type across the site and its pages'
9+
10+
def self.banner(_command = nil, *)
11+
'bin/rails maglev:sections:reset TYPE'
12+
end
13+
14+
def perform(type)
15+
require File.expand_path('config/environment', Rails.root)
16+
17+
site = fetch_site
18+
theme = fetch_theme
19+
20+
return if site.blank? || theme.blank?
21+
22+
count = Maglev::ResetSectionContent.call(
23+
site: site,
24+
theme: theme,
25+
type: type
26+
)
27+
28+
display_final_message(count, type)
29+
end
30+
31+
private
32+
33+
def fetch_site
34+
Maglev::Site.first.tap do |site|
35+
say("[Error] You don't seem to have an existing site. 🤔", :red) unless site
36+
end
37+
end
38+
39+
def fetch_theme
40+
Maglev.local_themes&.first.tap do |theme|
41+
say('[Error] No theme found. 🤔', :red) unless theme
42+
end
43+
end
44+
45+
def display_final_message(count, type)
46+
if count.zero?
47+
say "No section of type '#{type}' found 🤔", :yellow
48+
return
49+
end
50+
51+
say "Successfully reset content of #{count} #{'section'.pluralize(count)} of type '#{type}' 🎉",
52+
:green
53+
end
54+
end
55+
end
56+
end
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
describe Maglev::ResetSectionContent do
6+
subject { described_class.call(site: site, theme: theme, type: type) }
7+
8+
let(:site) { create(:site, locales: [{ label: 'English', prefix: 'en' }, { label: 'French', prefix: 'fr' }]) }
9+
let(:theme) { build(:theme) }
10+
let(:type) { 'jumbotron' }
11+
12+
describe 'when the site has sections of the specified type' do
13+
before do
14+
site.update!(sections_translations: {
15+
en: [{ type: 'jumbotron', settings: [{ id: 'title', value: 'Hello' }] }],
16+
fr: [{ type: 'jumbotron', settings: [{ id: 'title', value: 'Bonjour' }] }]
17+
})
18+
end
19+
20+
it 'resets the section content in all locales and returns the count' do
21+
# Two hero sections (one in each locale)
22+
expect(subject).to eq(2)
23+
24+
# Check English locale
25+
Maglev::I18n.with_locale(:en) do
26+
expect(site.reload.sections.first['type']).to eq('jumbotron')
27+
expect(site.sections.first['settings'].first['value']).to eq('Title')
28+
end
29+
30+
# Check French locale
31+
Maglev::I18n.with_locale(:fr) do
32+
expect(site.reload.sections.first['type']).to eq('jumbotron')
33+
expect(site.sections.first['settings'].first['value']).to eq('Title')
34+
end
35+
end
36+
end
37+
38+
describe 'when the site has no sections of the specified type' do
39+
before do
40+
site.update!(sections_translations: {
41+
en: [{ type: 'footer', settings: [{ value: 'Footer' }] }],
42+
fr: [{ type: 'footer', settings: [{ value: 'Pied de page' }] }]
43+
})
44+
end
45+
46+
it 'does not modify the sections and returns zero' do
47+
expect(subject).to eq(0)
48+
49+
# Check English locale
50+
Maglev::I18n.with_locale(:en) do
51+
sections = site.reload.sections
52+
expect(sections.length).to eq(1)
53+
expect(sections.first['type']).to eq('footer')
54+
expect(sections.first['settings'].first['value']).to eq('Footer')
55+
end
56+
57+
# Check French locale
58+
Maglev::I18n.with_locale(:fr) do
59+
sections = site.reload.sections
60+
expect(sections.length).to eq(1)
61+
expect(sections.first['type']).to eq('footer')
62+
expect(sections.first['settings'].first['value']).to eq('Pied de page')
63+
end
64+
end
65+
end
66+
67+
describe 'when the section type does not exist in the theme' do
68+
let(:type) { 'unknown' }
69+
70+
it 'raises an UnknownSection error' do
71+
expect { subject }.to raise_error(
72+
Maglev::Errors::UnknownSection,
73+
"Section type 'unknown' doesn't exist in the theme"
74+
)
75+
end
76+
end
77+
78+
describe 'when resetting sections across site and pages' do
79+
let!(:page) { create(:page) }
80+
81+
before do
82+
# Set up sections for both site and page
83+
site.update!(sections_translations: {
84+
en: [{ type: 'jumbotron', settings: [{ id: 'title', value: 'Site Hero' }] }, { type: 'footer' }],
85+
fr: [{ type: 'jumbotron', settings: [{ id: 'title', value: 'Site Hero FR' }] }, { type: 'footer' }]
86+
})
87+
88+
page.update!(sections_translations: {
89+
en: [{ type: 'jumbotron', settings: [{ id: 'title', value: 'Page Hero' }] },
90+
{ type: 'navigation' }],
91+
fr: [{ type: 'jumbotron', settings: [{ id: 'title', value: 'Page Hero FR' }] },
92+
{ type: 'navigation' }]
93+
})
94+
end
95+
96+
it 'resets the sections in both site and pages and returns total count' do
97+
# Four hero sections total (one per locale in both site and page)
98+
expect(subject).to eq(4)
99+
100+
# Check site sections
101+
Maglev::I18n.with_locale(:en) do
102+
sections = site.reload.sections
103+
expect(sections.map { |s| s['type'] }).to eq(%w[jumbotron footer])
104+
expect(sections.find { |s| s['type'] == 'jumbotron' }['settings'].first['value']).to eq('Title')
105+
end
106+
107+
# Check page sections
108+
Maglev::I18n.with_locale(:en) do
109+
sections = page.reload.sections
110+
expect(sections.map { |s| s['type'] }).to eq(%w[jumbotron navigation])
111+
expect(sections.find { |s| s['type'] == 'jumbotron' }['settings'].first['value']).to eq('Title')
112+
end
113+
end
114+
end
115+
116+
describe 'when sections are blank' do
117+
before do
118+
site.update!(sections_translations: {
119+
en: [],
120+
fr: []
121+
})
122+
end
123+
124+
it 'returns zero and does not modify anything' do
125+
expect(subject).to eq(0)
126+
127+
Maglev::I18n.with_locale(:en) do
128+
expect(site.reload.sections).to be_empty
129+
end
130+
131+
Maglev::I18n.with_locale(:fr) do
132+
expect(site.reload.sections).to be_empty
133+
end
134+
end
135+
end
136+
end

0 commit comments

Comments
 (0)