diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 15f8dd83dd..eff47efcf2 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -2,16 +2,16 @@ module SearchHelper # rubocop:todo Style/Documentation def stock_plate_uuids - Settings.purposes.select { |_uuid, config| config.input_plate }.keys + Settings.purposes.select { |_uuid, config| config[:input_plate] }.keys end def self.stock_plate_names - Settings.purposes.values.select(&:input_plate).map(&:name) + Settings.purposes.values.select { |item| item[:input_plate] == true }.pluck(:name) end # Returns purpose names of stock plates using stock_plate flag instead of input_plate. def self.stock_plate_names_with_flag - Settings.purposes.values.select(&:stock_plate).map(&:name) + Settings.purposes.values.select { |item| item[:stock_plate] == true }.pluck(:name) end def self.purpose_config_for_purpose_name(purpose_name) diff --git a/app/models/concerns/presenters/creation_behaviour.rb b/app/models/concerns/presenters/creation_behaviour.rb index 1566f2d196..783af422b2 100644 --- a/app/models/concerns/presenters/creation_behaviour.rb +++ b/app/models/concerns/presenters/creation_behaviour.rb @@ -23,7 +23,7 @@ def compatible_tube_rack_purposes # Eventually this will end up on our labware_creators/creations module def purposes_of_type(type) - compatible_purposes.select { |_uuid, purpose| purpose.asset_type == type } + compatible_purposes.select { |_uuid, purpose| purpose[:asset_type] == type } end def construct_buttons(scope) @@ -34,9 +34,9 @@ def construct_buttons(scope) parent_uuid: uuid, parent: labware, purpose_uuid: purpose_uuid, - name: purpose_settings.name, - type: purpose_settings.asset_type, - filters: purpose_settings.filters || {} + name: purpose_settings[:name], + type: purpose_settings[:asset_type], + filters: purpose_settings[:filters] || {} ) end .force diff --git a/app/models/concerns/presenters/robot_controlled.rb b/app/models/concerns/presenters/robot_controlled.rb index 5ac31bb738..98e9b25d61 100644 --- a/app/models/concerns/presenters/robot_controlled.rb +++ b/app/models/concerns/presenters/robot_controlled.rb @@ -17,9 +17,10 @@ def suitable_robots end def suitable_for_labware?(config) - config - .beds - .detect { |_bed, bed_config| bed_config.purpose == purpose_name && bed_config.states.include?(labware.state) } + config[:beds] + .detect do |_bed, bed_config| + bed_config[:purpose] == purpose_name && bed_config[:states].include?(labware.state) + end .present? end diff --git a/app/models/concerns/presenters/submission_behaviour.rb b/app/models/concerns/presenters/submission_behaviour.rb index 3940061d43..954bd9702e 100644 --- a/app/models/concerns/presenters/submission_behaviour.rb +++ b/app/models/concerns/presenters/submission_behaviour.rb @@ -3,7 +3,7 @@ # Include in a presenter to add support for creating a submission module Presenters::SubmissionBehaviour def each_submission_option - purpose_config.submission_options.each do |button_text, options| + purpose_config[:submission_options].each do |button_text, options| submission_options = options.to_hash submission_options[:asset_groups] = asset_groups submission_options[:labware_barcode] = labware.labware_barcode.human diff --git a/app/models/labware_creators/merged_plate.rb b/app/models/labware_creators/merged_plate.rb index 61776dda96..622fb0d0cc 100644 --- a/app/models/labware_creators/merged_plate.rb +++ b/app/models/labware_creators/merged_plate.rb @@ -29,7 +29,7 @@ def labware_wells # @return [Array] Purpose name strings. # def expected_source_purposes - Settings.purposes.dig(@purpose_uuid, :merged_plate).source_purposes + Settings.purposes.dig(@purpose_uuid, :merged_plate)[:source_purposes] end # @@ -38,7 +38,7 @@ def expected_source_purposes # @return [String] Some descriptive text. # def help_text - Settings.purposes.dig(@purpose_uuid, :merged_plate).help_text + Settings.purposes.dig(@purpose_uuid, :merged_plate)[:help_text] end def barcodes=(barcodes) diff --git a/app/models/labware_creators/multi_stamp_tubes.rb b/app/models/labware_creators/multi_stamp_tubes.rb index c69b5196bc..66beeb29f4 100644 --- a/app/models/labware_creators/multi_stamp_tubes.rb +++ b/app/models/labware_creators/multi_stamp_tubes.rb @@ -125,7 +125,7 @@ def request_hash(transfer) # Returns: a hash containing the submission parameters # Adds: errors if there is more than one submission specified def configured_params - submission_options_from_config = purpose_config.submission_options + submission_options_from_config = purpose_config[:submission_options] # if there's more than one appropriate submission, we can't know which one to choose, # so don't create one. diff --git a/app/models/labware_creators/stamped_plate_adding_randomised_controls.rb b/app/models/labware_creators/stamped_plate_adding_randomised_controls.rb index 0f85990334..428c0bb42d 100644 --- a/app/models/labware_creators/stamped_plate_adding_randomised_controls.rb +++ b/app/models/labware_creators/stamped_plate_adding_randomised_controls.rb @@ -79,9 +79,9 @@ def generate_control_locations_from_purpose_config control_locations = [] list_of_controls.count.times do |control_index| control = list_of_controls[control_index] - if control.fixed_location? + if control[:fixed_location].present? # use the location specified in the purpose config for this control - control_locations.push(control.fixed_location) + control_locations.push(control[:fixed_location]) else # sample a random parent well and fetch its location (child not created yet) control_locations.push(parent.wells.sample.position['name']) @@ -92,13 +92,13 @@ def generate_control_locations_from_purpose_config def check_control_rules_from_config(control_locations) list_of_rules.each do |rule| - case rule.type + case rule[:type] when 'not' # locations must not match this combination of wells (order is important) - return false if control_locations == rule.value + return false if control_locations == rule[:value] when 'well_exclusions' # locations must not be in this list well locations (exclusions) - return false if control_locations.any? { |location| rule.value.include?(location) } + return false if control_locations.any? { |location| rule[:value].include?(location) } else # check for unrecognised rule type raise StandardError, "Unrecognised control locations rule type from purpose config #{rule.type}" diff --git a/app/models/presenters/plate_presenter.rb b/app/models/presenters/plate_presenter.rb index 7ae03673d0..6bad80f164 100644 --- a/app/models/presenters/plate_presenter.rb +++ b/app/models/presenters/plate_presenter.rb @@ -110,14 +110,14 @@ def csv_file_links links = purpose_config .fetch(:file_links, []) - .select { |link| can_be_enabled?(link&.states) } + .select { |link| can_be_enabled?(link[:states]) } .map do |link| [ - link.name, + link[:name], [ :limber_plate, :export, - { id: link.id, limber_plate_id: human_barcode, format: :csv, **link.params || {} } + { id: link[:id], limber_plate_id: human_barcode, format: :csv, **link[:params] || {} } ] ] end diff --git a/app/models/presenters/presenter.rb b/app/models/presenters/presenter.rb index 2fe917878d..c78d4362a9 100644 --- a/app/models/presenters/presenter.rb +++ b/app/models/presenters/presenter.rb @@ -57,7 +57,7 @@ def content_title end def default_printer - @default_printer ||= Settings.printers[purpose_config.default_printer_type] + @default_printer ||= Settings.printers[purpose_config[:default_printer_type]] end def default_label_count diff --git a/app/models/presenters/tube_presenter.rb b/app/models/presenters/tube_presenter.rb index 40d9b24598..0727d2e909 100644 --- a/app/models/presenters/tube_presenter.rb +++ b/app/models/presenters/tube_presenter.rb @@ -46,9 +46,9 @@ def custom_metadata_fields end def sequencescape_submission - return nil if purpose_config.submission.empty? + return nil if purpose_config[:submission].empty? - s = SequencescapeSubmission.new(purpose_config.submission.to_hash.merge(assets: [labware.uuid])) + s = SequencescapeSubmission.new(purpose_config[:submission].to_hash.merge(assets: [labware.uuid])) yield s if block_given? s end @@ -72,15 +72,15 @@ def transfer_volumes? def csv_file_links purpose_config .fetch(:file_links, []) - .select { |link| can_be_enabled?(link&.states) } + .select { |link| can_be_enabled?(link[:states]) } .map do |link| - format_extension = link.format || 'csv' + format_extension = link[:format] || 'csv' [ - link.name, + link[:name], [ :limber_tube, :tubes_export, - { id: link.id, limber_tube_id: human_barcode, format: format_extension, **link.params || {} } + { id: link[:id], limber_tube_id: human_barcode, format: format_extension, **link[:params] || {} } ] ] end diff --git a/app/models/presenters/tube_rack_presenter.rb b/app/models/presenters/tube_rack_presenter.rb index d11d4ac325..4229738d1f 100644 --- a/app/models/presenters/tube_rack_presenter.rb +++ b/app/models/presenters/tube_rack_presenter.rb @@ -42,9 +42,10 @@ def tube_failing_applicable? def csv_file_links purpose_config .fetch(:file_links, []) - .select { |link| can_be_enabled?(link&.states) } + .select { |link| can_be_enabled?(link[:states]) } .map do |link| - [link.name, [:limber_tube_rack, :tube_racks_export, { id: link.id, limber_tube_rack_id: uuid, format: :csv }]] + [link[:name], + [:limber_tube_rack, :tube_racks_export, { id: link[:id], limber_tube_rack_id: uuid, format: :csv }]] end end diff --git a/config/initializers/custom_configuration.rb b/config/initializers/custom_configuration.rb new file mode 100644 index 0000000000..a38dfd71a4 --- /dev/null +++ b/config/initializers/custom_configuration.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +# Parent configuration mixin. +module Settings + # Configuration for the application, including loaders for various configurations. + + # This will create class-level functions so that they could be accessed like + # Settings.searches, Settings.transfer_templates, etc. + class CustomConfiguration + def initialize(config_hash) + @children = config_hash.with_indifferent_access + + # When you invoke, Settings.configuration.searches in settings.rb, it would invoke static + # methods declared through this block. + @children.each do |key, value| + # For every getter method, it creates a method that returns an Item instance + # with the key and value from the configuration hash. + define_singleton_method(key) { Item.new(key, value) } + # For every setter method, it creates a method that sets the value in the children hash. + # This allows you to do Settings.configuration.searches = new_value. + define_singleton_method("#{key}=") { |new_value| @children[key] = new_value } + end + end + + # Configuration item. It recursively builds a structure + # that allows for nested configurations to be accessed easily. + # It includes Enumerable to allow iteration over its children. + # + # Each child can be a nested configuration or a simple value. + # This allows for a flexible and dynamic configuration structure. + # + # @example + # config = Settings.configuration + # config.searches.some_child.some_grandchild + # config.searches.some_child.some_grandchild = new_value + # + class Item + include Enumerable + + attr_reader :children, :configuration + + # rubocop:disable Metrics/MethodLength + def initialize(configuration, children = {}) + @children = children + @configuration = configuration + + # Dynamically defines getter and setter methods for each child key in the configuration. + # + # For each key-value pair in the children hash: + # - If the value is a nested hash (ActiveSupport::HashWithIndifferentAccess), + # it creates a getter method that returns a new Item instance, allowing for recursive access. + # - If the value is a simple value, it creates a getter method that returns the value directly. + # - For every key, it also creates a setter method to update the value in the children hash. + # + # This enables flexible, dot-notation access and assignment for deeply nested configuration structures. + # + # Example: + # config = Settings.configuration + # config.searches.some_child.some_grandchild # Access nested value + # config.searches.some_child.some_grandchild = val # Set nested value + children.each do |key, child| + if child.is_a?(ActiveSupport::HashWithIndifferentAccess) + next if respond_to?(key) + + child_item = Item.new(configuration, child) + define_singleton_method(key) { child_item } + else + define_singleton_method(key) { child } + end + define_singleton_method("#{key}=") { |new_value| @children[key] = new_value } + end + end + # rubocop:enable Metrics/MethodLength + + delegate :[]=, to: :@children + + def fetch(key, default = nil) + @children.fetch(key, default) + end + + def each(...) + children.each(...) + end + end + end +end diff --git a/config/initializers/settings.rb b/config/initializers/settings.rb index 73f35f132b..1d7ce35395 100644 --- a/config/initializers/settings.rb +++ b/config/initializers/settings.rb @@ -1,56 +1,77 @@ # frozen_string_literal: true -require 'config_loader/pipelines_loader' - -# Global setting object loaded from `config/settings/_environment_.yml` which is -# generated on running `rake config:generate` -class Settings - class << self - def configuration_filename - Rails.root.join('config', 'settings', "#{Rails.env}.yml") - end - private :configuration_filename - - def instance # rubocop:todo Metrics/AbcSize - return @instance if @instance.present? - - # Ideally we'd do Hashie::Mash.load(File.read(configuration_filename)) here - # but the creates an immutable setting object that messes with tests. - # Immutability is good here though, so we should probably fix that. - # Added flag onto safe_load to allow read of anchors (aliases) in yml files. - config_file_descriptor = File.open(configuration_filename, 'r:bom|utf-8') - @instance = Hashie::Mash.new(YAML.safe_load(config_file_descriptor, permitted_classes: [Symbol], aliases: true)) - - # To view a list of pipeline groups and respective pipelines: - # e.g. Settings.pipelines.group_by(&:pipeline_group).transform_values { |pipelines| pipelines.map(&:name) } - @instance.pipelines = ConfigLoader::PipelinesLoader.new.pipelines - - @instance - rescue Errno::ENOENT - # This before we've fully initialized and is intended to report issues to - # the user. - # rubocop:disable Style/StderrPuts - star_length = [96, 12 + configuration_filename.to_s.length].max - $stderr.puts('*' * star_length) - $stderr.puts "WARNING! No #{configuration_filename}" - $stderr.puts "You need to run 'rake config:generate' and can ignore this message if that's what you are doing!" - $stderr.puts('*' * star_length) - # rubocop:enable Style/StderrPuts +# Parent settings mixin. +module Settings + CONFIGURATION_TYPES = %i[ + searches + transfer_templates + printers + purposes + purpose_uuids + robots + default_pmb_templates + default_sprint_templates + default_printer_type_names + submission_templates + poolings + ].freeze + + # This loop declares Settings. method declarations + # using metaprogramming. For example, when it will add purposes method for Settings, and + # when it is invoked, it will use the CustomConfiguration class to send the value for it. + CONFIGURATION_TYPES.each do |config| + # Accessor + unless respond_to?(config) + self.class.send(:define_method, config, proc { + value = Settings.configuration.send(config) + value.respond_to?(:children) ? value.children : value + }) end + # Mutator + next if respond_to?("#{config}=") - delegate_missing_to :instance + # rubocop:disable Lint/DuplicateBranch + self.class.send(:define_method, "#{config}=", proc { |value| + config_value = Settings.configuration.send(config) + if config_value.respond_to?(:children) + if config_value.children.is_a?(Hash) && value.is_a?(Hash) + config_value.children.replace(value) + elsif config_value.children.is_a?(Array) && value.is_a?(Array) + config_value.children.replace(value) + else + Settings.configuration.send("#{config}=", value) + end + else + Settings.configuration.send("#{config}=", value) + end + }) + # rubocop:enable Lint/DuplicateBranch + end - def reinitialize - @instance = nil - self - end + # Delegates Settings.pipelines to the PipelinesLoader + def self.pipelines + @pipelines ||= ConfigLoader::PipelinesLoader.new.pipelines end -end -Rails.application.config.to_prepare do - # By re-initializing here we gain: - # - Clear hot-reloading of classes like PipelineList when in development mode - # - Reloading of the settings in development mode, meaning you don't need to - # restart following a rake config:generate - Settings.reinitialize.instance + def self.pipelines=(value) + @pipelines = value + end + + def self.load_yaml + config = Rails.root.join('config', 'settings', "#{Rails.env}.yml") + return unless File.exist?(config) + + config_file_descriptor = File.open(config, 'r:bom|utf-8') + # Returns a Hash with the configuration data + config_data = YAML.safe_load(config_file_descriptor, permitted_classes: [Symbol], aliases: true) + raise "Configuration file #{config} is not valid YAML." if config_data.blank? + + config_data.with_indifferent_access + end + + # Returns an instance of CustomConfiguration that provides access to the + # configuration data loaded from the YAML file. + def self.configuration + @configuration ||= CustomConfiguration.new(load_yaml) + end end diff --git a/config/settings/test.yml b/config/settings/test.yml index 3034a3623e..b84ce4173b 100644 --- a/config/settings/test.yml +++ b/config/settings/test.yml @@ -7,5 +7,11 @@ :purposes: {} :purpose_uuids: {} :robots: {} -:locations: {} +:default_pmb_templates: {} +:default_sprint_templates: {} +:default_printer_type_names: {} +:submission_templates: {} :qc_purposes: [] +:locations: {} +:pipelines: {} +:poolings: {} diff --git a/spec/data/config.yml b/spec/data/config.yml new file mode 100644 index 0000000000..92153b095d --- /dev/null +++ b/spec/data/config.yml @@ -0,0 +1,109 @@ +# The current file has been automatically generated by running the task: +# > rake config:generate +# It is recommended if you need to do any changes in config to modify the +# required config file under config/pipelines or config/purposes and rerun +# the task +--- +:searches: + Find assets by barcode: 7e660cbc-6951-11f0-8c10-ded867e19c6b + Find project by name: 7e668c82-6951-11f0-8c10-ded867e19c6b + Find study by name: 7e66e272-6951-11f0-8c10-ded867e19c6b +:transfer_templates: + 384 plate to tube: 7c673a8a-6951-11f0-8c10-ded867e19c6b + Transfer columns 1-1: 7d590ff4-6951-11f0-8c10-ded867e19c6b +:printers: + :plate_a: g316bc + :plate_b: g311bc2 + :tube_rack: heron-bc2 + :tube: g311bc1 + :limit: 5 + :default_count: 2 +:purposes: + 9e42476c-6951-11f0-b542-ded867e19c6b: + :name: LBC 5p GEX Dil + :default_printer_type: :plate_a + :presenter_class: Presenters::NormalisedBinnedPlatePresenter + :creator_class: LabwareCreators::NormalisedBinnedPlate + :label_class: Labels::PlateLabel + :file_links: + - name: Download Hamilton Cherrypick to 5 prime Dilution CSV + id: hamilton_cherrypick_to_5p_gex_dilution + - name: Download Concentration (ng/ul) CSV + id: concentrations_ngul + :state_changer_class: StateChangers::PlateStateChanger + :submission: {} + :printer_type: 96 Well Plate + :pmb_template: sqsc_96plate_label_template_code39 + :sprint_template: plate_96.yml.erb + :asset_type: plate + :dilutions: + :target_amount_ng: 50 + :target_volume: 20 + :minimum_source_volume: 0.2 + :bins: + - colour: 1 + pcr_cycles: 16 + max: 26 + - colour: 2 + pcr_cycles: 14 + min: 26 +:purpose_uuids: + LBC 5p GEX Dil: 9e42476c-6951-11f0-b542-ded867e19c6b + LBC 5p GEX Frag 2XP: 9e5190f0-6951-11f0-b542-ded867e19c6b + LBC 5p GEX LigXP: 9e5424dc-6951-11f0-b542-ded867e19c6b +:robots: + bravo-lb-cherrypick-to-lb-shear: + :name: bravo LB Cherrypick => LB Shear + :verify_robot: false + :require_robot: false + :beds: + '580000007860': + :purpose: LB Cherrypick + :states: + - passed + :label: Bed 7 + :shared_parent: false + '580000009659': + :purpose: LB Shear + :states: + - pending + :label: Bed 9 + :parent: '580000007860' + :target_state: passed + bravo-lb-shear-to-lb-post-shear: + :name: bravo LB Shear => LB Post Shear + :verify_robot: false + :require_robot: false + :beds: + '580000009659': + :purpose: LB Shear + :states: + - passed + :label: Bed 9 + :shared_parent: false + '580000007860': + :purpose: LB Post Shear + :states: + - pending + :label: Bed 7 + :parent: '580000009659' + :target_state: passed +:default_pmb_templates: + :plate_double: plate_6mm_double_code39 + :plate_a: sqsc_96plate_label_template_code39 + :tube_rack: sqsc_96plate_label_template_code39 + :tube: tube_label_template_1d +:default_sprint_templates: + :plate_double: plate_384.yml.erb + :plate_a: plate_96.yml.erb + :tube_rack: plate_96.yml.erb + :tube: tube_label_template_1d.yml.erb +:default_printer_type_names: + :plate_double: 384 Well Plate Double + :plate_a: 96 Well Plate + :tube_rack: 96 Well Plate + :tube: 1D Tube +:submission_templates: + Limber - Cardinal: 7b7a63e0-6951-11f0-8c10-ded867e19c6b + Limber - Cardinal cell banking: 7b7bc1e0-6951-11f0-8c10-ded867e19c6b +poolings: diff --git a/spec/fixtures/config/poolings/donor_pooling.yml b/spec/fixtures/config/poolings/donor_pooling.yml index ecc363fddb..b7a5818d86 100644 --- a/spec/fixtures/config/poolings/donor_pooling.yml +++ b/spec/fixtures/config/poolings/donor_pooling.yml @@ -3,99 +3,99 @@ donor_pooling: # Maping between number of samples to number of pools. number_of_pools: - 96: 8 - 95: 8 - 94: 8 - 93: 8 - 92: 8 - 91: 8 - 90: 8 - 89: 8 - 88: 8 - 87: 7 - 86: 7 - 85: 7 - 84: 7 - 83: 7 - 82: 7 - 81: 7 - 80: 7 - 79: 7 - 78: 7 - 77: 7 - 76: 6 - 75: 6 - 74: 6 - 73: 6 - 72: 6 - 71: 6 - 70: 6 - 69: 6 - 68: 6 - 67: 6 - 66: 6 - 65: 5 - 64: 5 - 63: 5 - 62: 5 - 61: 5 - 60: 5 - 59: 5 - 58: 5 - 57: 5 - 56: 5 - 55: 5 - 54: 5 - 53: 5 - 52: 4 - 51: 4 - 50: 4 - 49: 4 - 48: 4 - 47: 4 - 46: 4 - 45: 4 - 44: 4 - 43: 4 - 42: 4 - 41: 4 - 40: 4 - 39: 3 - 38: 3 - 37: 3 - 36: 3 - 35: 3 - 34: 3 - 33: 3 - 32: 3 - 31: 3 - 30: 3 - 29: 3 - 28: 3 - 27: 3 - 26: 2 - 25: 2 - 24: 2 - 23: 2 - 22: 2 - 21: 2 - 20: 1 - 19: 1 - 18: 1 - 17: 1 - 16: 1 - 15: 1 - 14: 1 - 13: 1 - 12: 1 - 11: 1 - 10: 1 - 9: 1 - 8: 1 - 7: 1 - 6: 1 - 5: 1 - 4: 1 - 3: 1 - 2: 1 - 1: 1 + '96': 8, + '95': 8, + '94': 8, + '93': 8, + '92': 8, + '91': 8, + '90': 8, + '89': 8, + '88': 8, + '87': 7, + '86': 7, + '85': 7, + '84': 7, + '83': 7, + '82': 7, + '81': 7, + '80': 7, + '79': 7, + '78': 7, + '77': 7, + '76': 6, + '75': 6, + '74': 6, + '73': 6, + '72': 6, + '71': 6, + '70': 6, + '69': 6, + '68': 6, + '67': 6, + '66': 6, + '65': 5, + '64': 5, + '63': 5, + '62': 5, + '61': 5, + '60': 5, + '59': 5, + '58': 5, + '57': 5, + '56': 5, + '55': 5, + '54': 5, + '53': 5, + '52': 4, + '51': 4, + '50': 4, + '49': 4, + '48': 4, + '47': 4, + '46': 4, + '45': 4, + '44': 4, + '43': 4, + '42': 4, + '41': 4, + '40': 4, + '39': 3, + '38': 3, + '37': 3, + '36': 3, + '35': 3, + '34': 3, + '33': 3, + '32': 3, + '31': 3, + '30': 3, + '29': 3, + '28': 3, + '27': 3, + '26': 2, + '25': 2, + '24': 2, + '23': 2, + '22': 2, + '21': 2, + '20': 1, + '19': 1, + '18': 1, + '17': 1, + '16': 1, + '15': 1, + '14': 1, + '13': 1, + '12': 1, + '11': 1, + '10': 1, + '9': 1, + '8': 1, + '7': 1, + '6': 1, + '5': 1, + '4': 1, + '3': 1, + '2': 1, + '1': 1 diff --git a/spec/initializers/settings_spec.rb b/spec/initializers/settings_spec.rb new file mode 100644 index 0000000000..614a08e4ed --- /dev/null +++ b/spec/initializers/settings_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'rails_helper' + +# rubocop:disable RSpec/EmptyExampleGroup +RSpec.describe Settings, skip: 'WIP' do + before do + config = Rails.root.join('spec/data/config.yml') + config_file_descriptor = File.open(config, 'r:bom|utf-8') + # Returns a Hash with the configuration data + config_data = YAML.safe_load(config_file_descriptor, permitted_classes: [Symbol], aliases: true) + allow(described_class).to receive(:load_yaml).and_return(config_data) + described_class.instance_variable_set(:@configuration, nil) + end +end +# rubocop:enable RSpec/EmptyExampleGroup