Skip to content

Commit

Permalink
Migration and migration specs
Browse files Browse the repository at this point in the history
  • Loading branch information
gangelo committed Feb 15, 2024
1 parent 2e4191e commit b15f534
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 176 deletions.
20 changes: 16 additions & 4 deletions lib/dsu/migration/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ def to_migration_version

# The migration version before running this migration.
def migration_version
# Typically we should not be using models in any of the migration services
# because if these change, the migrations will break. However, using
# the MigrationVersion model is an exception because it is a very simple
# model and is unlikely to change.
@migration_version ||= Models::MigrationVersion.new.version
end

Expand All @@ -62,7 +66,7 @@ def create_backup

return puts 'Skipping: backup already exists.' if backup_exist?

FileUtils.cp_r(dsu_folder, backup_folder) unless pretend?
FileUtils.cp_r(dsu_folder, backup_folder)
puts 'Done.'
end

Expand All @@ -74,13 +78,21 @@ def backup_folder
@backup_folder ||= File.join(root_folder, "dsu-#{from_migration_version}-backup")
end

def update_migration_version
def update_migration_version!
puts 'Updating migration version...'
puts

return if pretend? || migration_version == Migration::VERSION
return if pretend? || migration_version == to_migration_version

Models::MigrationVersion.new(version: Migration::VERSION).save!
Models::MigrationVersion.new(version: to_migration_version).save!
end

def seed_data_folder
seed_data_dsu_folder_for(migration_version: to_migration_version)
end

def raise_backup_folder_does_not_exist_error_if!
raise "Backup folder #{backup_folder} does not exist, cannot continue" unless backup_exist?
end
end
end
Expand Down
29 changes: 2 additions & 27 deletions lib/dsu/migration/service_20230613121411.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ class Service20230613121411 < Service
def run_migration!
super

raise "Backup folder #{backup_folder} does not exist, cannot continue" unless backup_exist?
raise_backup_folder_does_not_exist_error_if!

# TODO: save old dsu entries to migrate them to the new dsu entries
delete_old_config_file
delete_old_entries_folder
delete_old_themes_folder
Expand Down Expand Up @@ -47,35 +46,11 @@ def themes_folder_from
File.join(dsu_folder_from, 'themes')
end

# To folders

def dsu_folder_to
File.join(root_folder, 'dsu')
end

def entries_folder_to
File.join(dsu_folder_to, 'entries')
end

def themes_folder_to
File.join(dsu_folder_to, 'entries')
end

def seed_data_folder20230613121411
File.join(seed_data_folder, to_migration_version)
end

def create_new_dsu_folders
puts 'Creating new dsu folders...'
puts

if pretend?
FileUtils.cp_r(File.join(seed_data_folder20230613121411, '.'),
root_folder, noop: true, verbose: true)
else
FileUtils.cp_r(File.join(seed_data_folder20230613121411, '.'),
root_folder)
end
FileUtils.cp_r(File.join(seed_data_folder, '.'), File.join(root_folder, 'dsu')) unless pretend?
end

# Deletes
Expand Down
4 changes: 3 additions & 1 deletion lib/dsu/migration/service_20240210161248.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class Service20240210161248 < Service
def run_migration!
super

raise_backup_folder_does_not_exist_error_if!

add_new_color_themes
create_default_project
update_configuration
Expand All @@ -37,7 +39,7 @@ def add_new_color_themes
destination_theme_file_path = File.join(Dsu::Support::Fileable.themes_folder, theme_file)
# next if File.exist?(destination_theme_file_path)

source_theme_file_path = File.join(Dsu::Support::Fileable.seed_data_folder, 'themes', theme_file)
source_theme_file_path = File.join(seed_data_folder, 'themes', theme_file)
FileUtils.cp(source_theme_file_path, destination_theme_file_path) unless pretend?
puts I18n.t('migrations.information.theme_copied',
from: source_theme_file_path, to: destination_theme_file_path)
Expand Down
4 changes: 2 additions & 2 deletions lib/dsu/support/fileable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ def backup_folder(version:)

# Seed data folders

def seed_data_folder
File.join(gem_dir, 'lib/seed_data')
def seed_data_dsu_folder_for(migration_version:)
File.join(gem_dir, 'lib/seed_data', migration_version.to_s, 'dsu')
end

# Projects
Expand Down
161 changes: 62 additions & 99 deletions spec/dsu/migration/service20230613121411_spec.rb
Original file line number Diff line number Diff line change
@@ -1,129 +1,92 @@
# frozen_string_literal: true

RSpec.describe Dsu::Migration::Service20230613121411 do
RSpec.describe Dsu::Migration::Service20230613121411, type: :migration do
subject(:service) { described_class.new(options: options) }

shared_examples 'the migration is successful' do
it 'backs up the old config file' do
expect(File.exist?(File.join(backup_folder, Dsu::Support::Fileable.config_file_name))).to be true
end

it 'backs up the old entry files' do
entries_folder = File.basename(Dsu::Support::Fileable.entries_folder)
expect(File.exist?(File.join(backup_folder, entries_folder, Dsu::Support::Fileable.entries_file_name(time: time)))).to be true
end

it 'backs up the old theme files' do
themes_folder = File.basename(Dsu::Support::Fileable.themes_folder)
expect(File.exist?(File.join(backup_folder, themes_folder, Dsu::Support::Fileable.theme_file_name(theme_name: theme_name)))).to be true
end

it 'creates the new config file' do
expect(File.exist?(Dsu::Support::Fileable.config_path)).to be true
end

it 'copies the new theme files' do
theme_names = %w[cherry default lemon matrix whiteout]
themes_exist = theme_names.all? { |theme_name| File.exist?(Dsu::Support::Fileable.themes_path(theme_name: theme_name)) }
expect(themes_exist).to be true
end

it 'creates an initial entry group' do
expect(File.exist?(Dsu::Support::Fileable.entries_path(time: time))).to be true
end
before do
create(:migration_version, version: migration_version, options: options)
end

let(:dsu_folder) { File.join(temp_folder, 'dsu') }

let(:options) { {} }
let(:migration_version) { 0 }

describe 'class methods' do
describe '.run_migrations?' do
context 'when the migration version is current' do
before do
create(:migration_version, :with_current_version)
end
describe '#initialize' do
let(:migration_version) { 20240210161248 } # rubocop:disable Style/NumericLiterals

it 'returns false' do
expect(described_class.run_migrations?).to be(false)
end
end
it_behaves_like 'no error is raised'
end

context 'when the migration version less than 20230613121411' do
before do
create(:migration_version, version: 20230613121411 - 1) # rubocop:disable Style/NumericLiterals
end
describe '#migrate_if!' do
subject(:service_migrate_if) { service.migrate_if! }

it 'returns true' do
expect(described_class.run_migrations?).to be(true)
end
context 'when the migration version is not 0' do
before do
mock_migration_version_for(version: migration_version)
service_migrate_if
end

context 'when the migration version greater than the current version' do
before do
create(:migration_version, version: Dsu::Migration::VERSION + 1)
end
let(:migration_version) { 20240210161248 } # rubocop:disable Style/NumericLiterals
let(:expected) { File.join('spec', 'fixtures', 'folders', migration_version.to_s) }
let(:actual) { dsu_folder }

it 'returns false' do
expect(described_class.run_migrations?).to be(false)
end
it 'does not make any changes to the dsu folder structure or configuration file' do
expect(dsu_folders_and_file_contents_match?(expected: expected, actual: actual)).to be(true)
end
end
end

context 'when migrations should not be run' do
subject(:service) { build(:migration_service) }

before do
create(:migration_version, :with_current_version)
end

specify 'the migration version file exists' do
migration_version = create(:migration_version, :with_current_version)
expect(migration_version).to exist
end

it 'does not run migrations' do
expect { service.call }.to output(/Nothing to do/).to_stdout
end
end

context 'when migrations should be run' do
subject(:service) { build(:migration_service) }

before do
FileUtils.touch(Dsu::Support::Fileable.config_path)
FileUtils.touch(Dsu::Support::Fileable.entries_path(time: time))
FileUtils.touch(Dsu::Support::Fileable.themes_path(theme_name: theme_name))
end
context 'when the migration version is 0' do
before do
mock_migration_version_for(version: migration_version)
service_migrate_if
end

let(:time) { Time.now.in_time_zone }
let(:theme_name) { 'old_theme' }
let(:backup_folder) { Dsu::Support::Fileable.backup_folder(version: 0) }
shared_examples 'the migration was run in pretend mode' do
let(:expected) { File.join('spec', 'fixtures', 'folders', migration_version.to_s) }
let(:actual) { dsu_folder }

context 'when the migration file exists' do
before do
service.call
it 'does not make any changes to the dsu folder structure or configuration file' do
expect(dsu_folders_and_file_contents_match?(expected: expected, actual: actual)).to be(true)
end
end

specify 'the migration version file exists' do
migration_version = build(:migration_version, version: 0)
expect(migration_version).to exist
context 'when the pretend option is implicitly set to true (not provided)' do
it_behaves_like 'the migration was run in pretend mode'
end

it_behaves_like 'the migration is successful'
end
context 'when the pretend option is explicitly set to true' do
let(:options) { { pretend: true } }

context 'when the migration file does not exist' do
before do
service.call
it_behaves_like 'the migration was run in pretend mode'
end

specify 'the migration version file does not exist' do
migration_version = build(:migration_version)
migration_version.delete
expect(migration_version).to_not exist
end
context 'when the pretend option is set to false' do
let(:options) { { pretend: false } }
let(:expected) { File.join('spec', 'fixtures', 'folders', 20230613121411.to_s) } # rubocop:disable Style/NumericLiterals
let(:actual) { dsu_folder }

it_behaves_like 'the migration is successful'
it 'migrates the dsu folder structure and files' do
expect(dsu_folders_and_file_contents_match?(expected: expected, actual: actual,
known_deleted_files: known_deleted_files, known_added_files: known_added_files)).to be(true)
end
end
end
end

def known_deleted_files
%w[
entries/2023-12-28.json
entries/2023-12-29.json
entries/2024-01-01.json
entries/2024-01-02.json
]
end

def known_added_files
%w[
themes/christmas.json
themes/light.json
]
end
end
36 changes: 3 additions & 33 deletions spec/dsu/migration/service20240210161248_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
let(:actual) { Dsu::Support::Fileable.dsu_folder }

it 'does not make any changes to the dsu folder structure or configuration file' do
expect(dsu_folders_match?(expected: expected, actual: actual)).to be(true)
expect(dsu_folders_and_file_contents_match?(expected: expected, actual: actual)).to be(true)
end
end

Expand All @@ -45,7 +45,7 @@
let(:actual) { Dsu::Support::Fileable.dsu_folder }

it 'does not make any changes to the dsu folder structure or configuration file' do
expect(dsu_folders_match?(expected: expected, actual: actual)).to be(true)
expect(dsu_folders_and_file_contents_match?(expected: expected, actual: actual)).to be(true)
end
end

Expand All @@ -65,37 +65,7 @@
let(:actual) { Dsu::Support::Fileable.dsu_folder }

it 'migrates the dsu folder structure and configuration file' do
expect(dsu_folders_match?(expected: expected, actual: actual)).to be(true)
end

it 'sets all the entry group versions to the correct migration version' do
all_entry_groups = Dsu::Models::EntryGroup.all
expect(all_entry_groups.all? do |entry_group|
entry_group.version == 20240210161248 # rubocop:disable Style/NumericLiterals
end).to be(true)
end

it 'sets all the color theme versions to the correct migration version' do
all_color_themes = Dsu::Models::ColorTheme.all
expect(all_color_themes.all? do |color_theme|
color_theme.version == 20240210161248 # rubocop:disable Style/NumericLiterals
end).to be(true)
end

it 'sets the configuration file version to the correct migration version' do
expect(Dsu::Models::Configuration.new.version).to eq(20240210161248) # rubocop:disable Style/NumericLiterals
end

it 'sets the migration version file version to the correct migration version' do
expect(Dsu::Models::MigrationVersion.new.version).to eq(20240210161248) # rubocop:disable Style/NumericLiterals
end

it 'copies the christmas color theme' do
expect(Dsu::Models::ColorTheme.new(theme_name: 'christmas').exist?).to be(true)
end

it 'copies the light color theme' do
expect(Dsu::Models::ColorTheme.new(theme_name: 'light').exist?).to be(true)
expect(dsu_folders_and_file_contents_match?(expected: expected, actual: actual)).to be(true)
end
end
end
Expand Down
Loading

0 comments on commit b15f534

Please sign in to comment.