diff --git a/app/assets/stylesheets/pages/calculator.scss b/app/assets/stylesheets/pages/calculator.scss index 0dede5e06..1c8178664 100644 --- a/app/assets/stylesheets/pages/calculator.scss +++ b/app/assets/stylesheets/pages/calculator.scss @@ -16,6 +16,28 @@ font-style: normal; transition: transform 0.5s ease-in-out; max-width: 300px; + @include transition(all 0.5s ease-in-out); + + &:hover { + background-color: $matte_lime_green; + } +} + +.btn-nonito { + font-size: 14px; + letter-spacing: 2px; + text-transform: uppercase; + font-weight: 400; + font-family: "Nunito", sans-serif; + font-style: normal; +} + +.dynamic-text-color { + color: var(--calculator-color); +} + +.dynamic-background-color { + background-color: var(--calculator-color); } #calc { @@ -61,6 +83,11 @@ margin-right: 0px; } +.calculator-field { + background-color: $light_gray !important; + border: 0; +} + .flex-item { display: flex; flex-wrap: wrap; diff --git a/app/assets/stylesheets/pages/feature_flags.scss b/app/assets/stylesheets/pages/feature_flags.scss index a68714537..53a8ce168 100644 --- a/app/assets/stylesheets/pages/feature_flags.scss +++ b/app/assets/stylesheets/pages/feature_flags.scss @@ -41,7 +41,6 @@ } input[type="submit"] { - background-color: $success; border: none; border-radius: 4px; color: #fff; @@ -49,11 +48,6 @@ input[type="submit"] { font-size: 16px; padding: 10px; min-width: 110px; - @include transition(all 0.5s ease-in-out); - - &:hover { - background-color: $matte_lime_green; - } } .btn-grey { diff --git a/app/controllers/account/calculators_controller.rb b/app/controllers/account/calculators_controller.rb index 4a1cd4b6a..c4d6bb1a5 100644 --- a/app/controllers/account/calculators_controller.rb +++ b/app/controllers/account/calculators_controller.rb @@ -2,10 +2,9 @@ class Account::CalculatorsController < Account::BaseController load_and_authorize_resource + before_action :check_constructor_flipper def index - render "shared/under_construction" unless Rails.env.local? - @q = collection.ransack(params[:q]) @calculators = @q.result.page(params[:page]) end @@ -95,4 +94,10 @@ def updater @calculator.update(calculator_params) end end + + def check_constructor_flipper + return if Flipper[:constructor_status].enabled? + + raise ActionController::RoutingError, "Constructor flipper is disabled" + end end diff --git a/app/controllers/calculators_controller.rb b/app/controllers/calculators_controller.rb index 4402a8969..a6b025e2c 100644 --- a/app/controllers/calculators_controller.rb +++ b/app/controllers/calculators_controller.rb @@ -2,6 +2,8 @@ class CalculatorsController < ApplicationController before_action :authenticate_user!, only: :receive_recomendations + + before_action :check_constructor_flipper, only: [:index, :show, :calculate] before_action :check_mhc_flipper, only: :mhc_calculator def index @@ -15,6 +17,8 @@ def index def show @calculator = resource + add_breadcrumb t("breadcrumbs.home"), root_path + add_breadcrumb @calculator.name end def calculate @@ -58,6 +62,12 @@ def resource collection.friendly.find(params[:slug]) end + def check_constructor_flipper + return if Flipper[:constructor_status].enabled? + + raise ActionController::RoutingError, "Constructor flipper is disabled" + end + def check_mhc_flipper return if Flipper[:mhc_calculator_status].enabled? diff --git a/app/javascript/controllers/constructors_form_indexing_controller.js b/app/javascript/controllers/constructors_form_indexing_controller.js new file mode 100644 index 000000000..9e5677b96 --- /dev/null +++ b/app/javascript/controllers/constructors_form_indexing_controller.js @@ -0,0 +1,26 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="constructors-form-indexing" +export default class extends Controller { + static targets = ["index"]; + + afterInsert(event) { + const fieldsets = this.element.querySelectorAll(":scope > .nested-fields"); + const span = fieldsets[fieldsets.length - 1].querySelector("[data-constructors-form-indexing-target='index']") + + if (span) { + span.textContent = `${fieldsets.length}`; + } + } + + afterRemove(event) { + const fieldsets = this.element.querySelectorAll(":scope > .nested-fields"); + + fieldsets.forEach((fieldset, index) => { + const span = fieldset.querySelector("[data-constructors-form-indexing-target='index']"); + if (span) { + span.textContent = `${index + 1}`; + } + }); + } +} diff --git a/app/models/formula.rb b/app/models/formula.rb index c8ef422cb..47713fda2 100644 --- a/app/models/formula.rb +++ b/app/models/formula.rb @@ -22,6 +22,8 @@ # fk_rails_... (calculator_id => calculators.id) # class Formula < ApplicationRecord + include Translatable + belongs_to :calculator validates_with FormulaValidator @@ -29,4 +31,6 @@ class Formula < ApplicationRecord validates :uk_label, :en_label, :uk_unit, :en_unit, :expression, presence: true validates :uk_label, :en_label, length: { minimum: 3, maximum: 50 } validates :en_unit, :uk_unit, length: { minimum: 1, maximum: 30 } + + translates :label, :unit end diff --git a/app/services/calculators/calculation_service.rb b/app/services/calculators/calculation_service.rb index 30c358002..087a2b063 100644 --- a/app/services/calculators/calculation_service.rb +++ b/app/services/calculators/calculation_service.rb @@ -10,7 +10,7 @@ def perform @calculator.formulas.map do |formula| result = @dentaku.evaluate(formula.expression, @inputs).round(2) - { label: formula.en_label, result: result } + { label: formula.label, result: result, unit: formula.unit } end end end diff --git a/app/views/account/calculators/partials/_category_fields.html.erb b/app/views/account/calculators/partials/_category_fields.html.erb index b90a7a26d..ab81bb659 100644 --- a/app/views/account/calculators/partials/_category_fields.html.erb +++ b/app/views/account/calculators/partials/_category_fields.html.erb @@ -1,7 +1,10 @@ -<div class="nested-fields"> - <%= f.input :en_name, label: "Category Name:" %> - <%= f.input :uk_name, label: "Uk Category Name:" %> - <%= f.input :price, label: "Category Price:" %> - - <%= link_to_remove_association "- Remove Category", f, class: "text-red-500 underline" %> -</div> +<fieldset class="bordered nested-fields"> + <legend class="admin-legend">Category <span data-constructors-form-indexing-target="index">1</span></legend> + <div> + <%= f.input :en_name, label: "Category Name:" %> + <%= f.input :uk_name, label: "Uk Category Name:" %> + <%= f.input :price, label: "Category Price:" %> + + <%= link_to_remove_association "- Remove Category", f, class: "text-red-500 underline" %> + </div> +</fieldset> diff --git a/app/views/account/calculators/partials/_field_fields.html.erb b/app/views/account/calculators/partials/_field_fields.html.erb index 2df9d0d8e..3c86bf24b 100644 --- a/app/views/account/calculators/partials/_field_fields.html.erb +++ b/app/views/account/calculators/partials/_field_fields.html.erb @@ -1,21 +1,32 @@ -<div class="nested-fields" data-controller="field-type"> - <%= f.input :en_label, label: "Field Label:" %> - <%= f.input :uk_label, label: "Uk Field Label:" %> - <%= f.input :var_name, label: "Variable Name:" %> - <%= f.input( - :kind, - collection: Field.kinds.keys.map { |key| [key.humanize, key] }, - prompt: "Select Field Type", - label: "Field Type:", - input_html: { data: { field_type_target: "fieldTypeSelect" } } - ) %> +<fieldset class="bordered nested-fields"> + <legend class="admin-legend">Field <span data-constructors-form-indexing-target="index">1</span></legend> + + <div data-controller="field-type"> + <%= f.input :en_label, label: "Field Label:" %> + <%= f.input :uk_label, label: "Uk Field Label:" %> + <%= f.input :var_name, label: "Variable Name:" %> + <%= f.input( + :kind, + collection: Field.kinds.keys.map { |key| [key.humanize, key] }, + prompt: "Select Field Type", + label: "Field Type:", + input_html: { data: { field_type_target: "fieldTypeSelect" } } + ) %> <div class="hidden category-fields" data-field-type-target="categoryFields"> - <%= f.simple_fields_for :categories do |category_fields| %> - <%= render "account/calculators/partials/category_fields", f: category_fields %> - <% end %> - <%= link_to_add_association "+ Add Category", f, :categories, partial: "account/calculators/partials/category_fields", class: "underline" %> + <fieldset class="bordered" data-controller="constructors-form-indexing" + data-action="cocoon:after-insert->constructors-form-indexing#afterInsert cocoon:after-remove->constructors-form-indexing#afterRemove"> + <legend class="admin-legend">Categories</legend> + + <%= f.simple_fields_for :categories do |category_fields| %> + <%= render "account/calculators/partials/category_fields", f: category_fields %> + <% end %> + <div class="links"> + <%= link_to_add_association "+ Add Category", f, :categories, partial: "account/calculators/partials/category_fields", class: "underline" %> + </div> + </fieldset> </div> - - <%= link_to_remove_association "- Remove Field", f, class: "text-red-500 underline" %> -</div> + + <%= link_to_remove_association "- Remove Field", f, class: "text-red-500 underline" %> + </div> +</fieldset> diff --git a/app/views/account/calculators/partials/_form.html.erb b/app/views/account/calculators/partials/_form.html.erb index 781d15c5d..438b34288 100644 --- a/app/views/account/calculators/partials/_form.html.erb +++ b/app/views/account/calculators/partials/_form.html.erb @@ -1,27 +1,36 @@ <%= simple_form_for(@calculator, url: account_calculators_path) do |f| %> <div class="form-group row"> <div class="my-auto col-12 has-float-label"> - <%= f.input :en_name, label: "Calculator Name:", class: 'form-control' %> - <%= f.input :uk_name, label: "Uk Calculator Name:", class: 'form-control' %> + <fieldset class="bordered"> + <legend class="admin-legend">Calculator</legend> + <%= f.input :en_name, label: "Calculator Name:", class: 'form-control' %> + <%= f.input :uk_name, label: "Uk Calculator Name:", class: 'form-control' %> + </fieldset> <!-- formula input--> <div id="formulas" class="space-y-4"> - <%= f.simple_fields_for :formulas do |formula_fields| %> - <%= render "account/calculators/partials/formula_fields", f: formula_fields %> - <% end %> - <div class="links"> - <%= link_to_add_association "+ Add Formula", f, :formulas, partial: "account/calculators/partials/formula_fields", class: "underline" %> - </div> + <fieldset class="bordered" data-controller="constructors-form-indexing" + data-action="cocoon:after-insert->constructors-form-indexing#afterInsert cocoon:after-remove->constructors-form-indexing#afterRemove"> + <%= f.simple_fields_for :formulas do |formula_fields| %> + <%= render "account/calculators/partials/formula_fields", f: formula_fields %> + <% end %> + <div class="links"> + <%= link_to_add_association "+ Add Formula", f, :formulas, partial: "account/calculators/partials/formula_fields", class: "underline" %> + </div> + </fieldset> </div> <!-- field input--> <div id="fields" class="space-y-4"> - <%= f.simple_fields_for :fields do |field_fields| %> - <%= render "account/calculators/partials/field_fields", f: field_fields %> - <% end %> - <div class="links"> - <%= link_to_add_association "Add Field", f, :fields, partial: "account/calculators/partials/field_fields", class: "underline" %> - </div> + <fieldset class="bordered" data-controller="constructors-form-indexing" + data-action="cocoon:after-insert->constructors-form-indexing#afterInsert cocoon:after-remove->constructors-form-indexing#afterRemove"> + <%= f.simple_fields_for :fields do |field_fields| %> + <%= render "account/calculators/partials/field_fields", f: field_fields %> + <% end %> + <div class="links"> + <%= link_to_add_association "+ Add Field", f, :fields, partial: "account/calculators/partials/field_fields", class: "underline" %> + </div> + </fieldset> </div> </div> </div> diff --git a/app/views/account/calculators/partials/_formula_fields.html.erb b/app/views/account/calculators/partials/_formula_fields.html.erb index a0787f159..ce40536f6 100644 --- a/app/views/account/calculators/partials/_formula_fields.html.erb +++ b/app/views/account/calculators/partials/_formula_fields.html.erb @@ -1,10 +1,13 @@ -<div class="nested-fields"> - <%= f.input :en_label, label: "Formula Label:" %> - <%= f.input :uk_label, label: "Uk Formula Label:" %> - <%= f.input :expression, label: "Formula Expression:" %> +<fieldset class="bordered nested-fields"> + <legend class="admin-legend">Formula <span data-constructors-form-indexing-target="index">1</span></legend> + <div> + <%= f.input :en_label, label: "Formula Label:" %> + <%= f.input :uk_label, label: "Uk Formula Label:" %> + <%= f.input :expression, label: "Formula Expression:" %> - <%= f.input :uk_unit, label: "Uk Unit Label:" %> - <%= f.input :en_unit, label: "Unit Label:" %> + <%= f.input :uk_unit, label: "Uk Unit Label:" %> + <%= f.input :en_unit, label: "Unit Label:" %> - <%= link_to_remove_association "- Remove Formula", f, class: "text-red-500 underline" %> -</div> + <%= link_to_remove_association "- Remove Formula", f, class: "text-red-500 underline" %> + </div> +</fieldset> diff --git a/app/views/account/shared/_navigation.html.erb b/app/views/account/shared/_navigation.html.erb index 264fd2e55..575b45bf9 100644 --- a/app/views/account/shared/_navigation.html.erb +++ b/app/views/account/shared/_navigation.html.erb @@ -23,7 +23,7 @@ </li> <% if user_signed_in? && current_user.admin? %> <li> - <%= link_to t("layouts.navigation.admin"), account_calculators_path, class: "tab-main-page" %> + <%= link_to t("layouts.navigation.admin"), edit_account_site_setting_path, class: "tab-main-page" %> </li> <% end %> <% if user_signed_in? %> diff --git a/app/views/calculators/partials/_calculation_results.html.erb b/app/views/calculators/partials/_calculation_results.html.erb index 72c1d9215..14199c497 100644 --- a/app/views/calculators/partials/_calculation_results.html.erb +++ b/app/views/calculators/partials/_calculation_results.html.erb @@ -1,14 +1,22 @@ -<h2 class="mt-4 text-2xl font-bold text-white underline">Calculation Results</h2> -<div class="mt-2 space-y-2 text-white"> - <% results.each do |result| %> - <div class="flex gap-2 text-lg font-medium"> - <h3> - <%= result[:label] %> - </h3> - = - <p> - <%= result[:result] %> - </p> - </div> - <% end %> +<%# TODO: Delete this and use user provided value%> +<% formula_image = "money_to_spent_2.png" %> + +<div class="calculation-results rounded jumbotron jumbotron-fluid position-relative"> + <h2 class="pt-6 text-2xl font-semibold text-center dynamic-text-color">Calculation Results</h2> + <div class="jumbotron calculation-results result main-result-container result-container"> + <% results.each do |result| %> + <div> + <%= image_tag "#{formula_image}", class: "img-margin", alt: "icon" %> + <p class="dynamic-text-color"> + <%= result[:result] %> + </p> + <p class="text-2xl dynamic-text-color"> + <%= result[:unit] %> + </p> + <p class="diapers-font-text"> + <%= result[:label] %> + </p> + </div> + <% end %> + </div> </div> diff --git a/app/views/calculators/partials/show/_constructor_calculator_description.erb b/app/views/calculators/partials/show/_constructor_calculator_description.erb new file mode 100644 index 000000000..fed35215a --- /dev/null +++ b/app/views/calculators/partials/show/_constructor_calculator_description.erb @@ -0,0 +1,8 @@ +<%# TODO: Delete this if %> +<% if false %> + <section class="description-section"> + <div class="description-block"> + <%# TODO: ADD text here %> + </div> + </section> +<% end %> diff --git a/app/views/calculators/show.html.erb b/app/views/calculators/show.html.erb index 489f4f024..82295fe22 100644 --- a/app/views/calculators/show.html.erb +++ b/app/views/calculators/show.html.erb @@ -1,21 +1,40 @@ -<div class="container place-items-center"> - <h1 class="text-4xl font-bold">Calculator <%= @calculator.name %></h1><br> +<%# TODO: Delete this and use user provided value %> +<% color = "#088F8F" %> - <%= form_with url: calculate_calculator_path(@calculator) do |form| %> - <% @calculator.fields.each do |field| %> - <div class="space-y-4 form-inputs"> - <h1><%= form.label field.var_name, field.label %></h1> - <% if field.kind == 'number' %> - <%= form.number_field "inputs[#{field.var_name}]", placeholder: field.label %> - <% else %> - <%= form.select "inputs[#{field.var_name}]", options_from_collection_for_select(field.categories, :price, :name) %> - <% end %> - </div><br> +<%# TODO: Delete this and use user provided value %> +<% calculator_image = "scales.png" %> + +<div style="--calculator-color: <%= color %>"> + <div class="rounded jumbotron jumbotron-fluid position-relative"> + <h1 class="pt-6 text-2xl font-semibold text-center font-sans dynamic-text-color">Calculator <%= @calculator.name %> <%= @text %></h1> + <div class="flex-wrap d-flex justify-content-around calculator_wrap ms-5"> + + <%= form_with html: { class: "simple_form_calculator"}, url: calculate_calculator_path(@calculator) do |form| %> + <div class="flex-item flex-column"> + <% @calculator.fields.each do |field| %> + <div class="pb-2 input_lable"><%= form.label field.var_name, field.label %></div> + <% if field.kind == 'number' %> + <div class="flex-row rounded flex-item w-100 age_wrapper form_fild"> + <%= form.number_field "inputs[#{field.var_name}]", + placeholder: field.label, + class: "required rounded w-100 calculator-field" + %> + </div> + <% else %> + <%= form.select "inputs[#{field.var_name}]", + options_from_collection_for_select(field.categories, :price, :name), + {}, + class: "flex-row rounded flex-item w-100 form_fild calculator-field" %> + <% end %> + <% end %> + <%= form.submit "Calculate", class: "btn-nonito result-btn dynamic-background-color" %> + </div> <% end %> - <div class="mt-6 form-actions"> - <%= form.submit "Calculate", class: "bg-blue-500 text-white font-semibold px-4 py-2 rounded hover:bg-blue-700" %> + <%= image_tag calculator_image, class: "scales_img", alt: t(".image_alt") %> </div> - <% end %> + </div> <%= turbo_frame_tag "calc-results" %> </div> + +<%= render "calculators/partials/show/constructor_calculator_description" %> diff --git a/app/views/layouts/_account_navbar.html.erb b/app/views/layouts/_account_navbar.html.erb index 35774f393..f3cac3796 100644 --- a/app/views/layouts/_account_navbar.html.erb +++ b/app/views/layouts/_account_navbar.html.erb @@ -8,13 +8,15 @@ <div data-burger-target="navbarNav" class="hidden xl:flex"> <ul class="admin-menu-list"> - <li class="mx-4"> - <%= link_to_unless_current t(".calculators"), account_calculators_path, title: t(".calculators"), class: "admin-menu-item" do %> - <p class="tab-active"> - <%= t(".calculators") %> - </p> - <% end %> - </li> + <% if Flipper[:constructor_status].enabled? %> + <li class="mx-4"> + <%= link_to_unless_current t(".calculators"), account_calculators_path, title: t(".calculators"), class: "admin-menu-item" do %> + <p class="tab-active"> + <%= t(".calculators") %> + </p> + <% end %> + </li> + <% end %> <li class="mx-4"> <%= link_to_unless_current t(".histories"), account_histories_path, title: t(".histories"), class: "admin-menu-item" do %> diff --git a/config/initializers/flipper/features.rb b/config/initializers/flipper/features.rb index 93387a7eb..a401be275 100644 --- a/config/initializers/flipper/features.rb +++ b/config/initializers/flipper/features.rb @@ -10,6 +10,9 @@ Flipper[:sandbox_mode].en_description = "This feature flag is responsible for enabling sandbox mode" Flipper[:sandbox_mode].uk_description = "Відкриває можливість використовувати режим пісочниці" + Flipper[:constructor_status].en_description = "This feature flag is responsible for enabling calculators constructor" + Flipper[:constructor_status].uk_description = "Відкриває можливість використовувати конструктор калькулятора" + Flipper[:mhc_calculator_status].en_description = "This feature flag is responsible for enabling mhc calculator" Flipper[:mhc_calculator_status].uk_description = "Відкриває можливість використовувати калькулятор продуктів жіночої гігієни" end diff --git a/config/locales/en/en.yml b/config/locales/en/en.yml index d03056ca6..1ccf13530 100644 --- a/config/locales/en/en.yml +++ b/config/locales/en/en.yml @@ -102,6 +102,7 @@ en: presence_error_msg: "%{field} is missing" show: welcome_header: "Welcome to ZeroWaste" + image_alt: "Scales" buttons: to_main: "To main" calculate: "Calculate" @@ -481,6 +482,8 @@ en: name: "Show calculators on the public side" sandbox_mode: name: "Enable sandbox mode" + constructor_status: + name: "Enable calculators constructor" mhc_calculator_status: name: "Enable mhc calculator" sessions: diff --git a/config/locales/uk/uk.yml b/config/locales/uk/uk.yml index 12a08caae..06f683b9e 100644 --- a/config/locales/uk/uk.yml +++ b/config/locales/uk/uk.yml @@ -84,6 +84,7 @@ uk: will_buy_diapers: "Кількість підгузків, які ще будуть використані до моменту, коли дитина перейде на звичайну білизну" money_spent: "Вартість використаних підгузків" money_will_be_spent: "Вартість підгузків, які ще будуть використані до моменту, коли дитина перейде на звичайну білизну" + image_alt: "Ваги" buttons: to_main: "На головну" calculate: "Розрахувати" @@ -441,8 +442,10 @@ uk: name: "Показати калькулятори користувачам" sandbox_mode: name: "Увімкнути режим пісочниці" - mhc_calculator_status: - name: "Увімкнути калькулятор продуктів жіночої гігієни" + constructor_status: + name: "Увімкнути конструктор калькуляторів" + mhc_calculator_status: + name: "Увімкнути калькулятор продуктів жіночої гігієни" sessions: new: log_in_header: "Увійти" diff --git a/spec/features/account/calculators_spec.rb b/spec/features/account/calculators_spec.rb index 7b57c5da3..010855a82 100644 --- a/spec/features/account/calculators_spec.rb +++ b/spec/features/account/calculators_spec.rb @@ -7,6 +7,7 @@ let!(:napkin_calculator) { create(:calculator, en_name: "Napkin Calculator") } include_context :authorize_admin + include_context :enable_calculators_constructor it "visits admin page" do visit account_calculators_path diff --git a/spec/features/navigator_spec.rb b/spec/features/navigator_spec.rb index 7d6bde298..80e75343b 100644 --- a/spec/features/navigator_spec.rb +++ b/spec/features/navigator_spec.rb @@ -20,7 +20,7 @@ it "should consist tabs" do expect(page).to have_link("Log Out", href: destroy_user_session_path, visible: :all) expect(page).to have_link("Contact us", href: new_message_path, visible: :all) - expect(page).to have_link("Admin", href: account_calculators_path, visible: :all) + expect(page).to have_link("Admin", href: edit_account_site_setting_path, visible: :all) end end diff --git a/spec/features/show_calculator_spec.rb b/spec/features/show_calculator_spec.rb index 45ff97fda..5b8cdbcd1 100644 --- a/spec/features/show_calculator_spec.rb +++ b/spec/features/show_calculator_spec.rb @@ -4,6 +4,8 @@ describe "GET #show" do let(:calculator) { create(:calculator) } + include_context :enable_calculators_constructor + before do allow(controller).to receive(:resource).and_return(calculator) end diff --git a/spec/features/visit_login_spec.rb b/spec/features/visit_login_spec.rb index 77dcd7fe5..5c95d53bb 100644 --- a/spec/features/visit_login_spec.rb +++ b/spec/features/visit_login_spec.rb @@ -6,6 +6,8 @@ let(:user) { create(:user) } let(:calculator) { create(:calculator) } + include_context :enable_calculators_constructor + it "when sign in with correct login and password" do allow_any_instance_of(ApplicationController) .to receive(:after_sign_in_path_for) diff --git a/spec/helpers/calculators/calculation_service_helper_spec.rb b/spec/helpers/calculators/calculation_service_helper_spec.rb new file mode 100644 index 000000000..1e81b43a8 --- /dev/null +++ b/spec/helpers/calculators/calculation_service_helper_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Calculators::CalculationService, type: :helper do + let(:calculator) { instance_double("Calculator", formulas: formulas) } + let(:formulas) do + [ + Formula.new(en_label: "Addition", en_unit: "units", uk_label: "Додавання", uk_unit: "одиниці", expression: "x + y"), + Formula.new(en_label: "Multiplication", en_unit: "units", uk_label: "Множення", uk_unit: "одиниці", expression: "x * y") + ] + end + let(:inputs) { ActionController::Parameters.new({ x: 5, y: 3 }) } + + before do + allow_any_instance_of(ApplicationHelper).to receive(:current_locale?).with(:en).and_return(locale_en) + end + + describe "#perform" do + subject do + I18n.with_locale(locale_en ? :en : :uk) do + described_class.new(calculator, inputs).perform + end + end + + context "when locale is English" do + let(:locale_en) { true } + + it "returns results with English labels and units" do + expect(subject).to eq([ + { label: "Addition", result: 8, unit: "units" }, + { label: "Multiplication", result: 15, unit: "units" } + ]) + end + end + + context "when locale is Ukrainian" do + let(:locale_en) { false } + + it "returns results with Ukrainian labels and units" do + expect(subject).to eq([ + { label: "Додавання", result: 8, unit: "одиниці" }, + { label: "Множення", result: 15, unit: "одиниці" } + ]) + end + end + end +end diff --git a/spec/requests/account/calculators_spec.rb b/spec/requests/account/calculators_spec.rb index ad4123801..c4f45a524 100644 --- a/spec/requests/account/calculators_spec.rb +++ b/spec/requests/account/calculators_spec.rb @@ -4,6 +4,7 @@ RSpec.describe "Account::CalculatorsController", type: :request do include_context :authorize_admin + include_context :enable_calculators_constructor let!(:calculator) { create(:calculator) } @@ -23,19 +24,15 @@ end describe "GET #index" do - context "when in production environment" do - include_context :in_production_environment + context "when flipper is turned off" do + include_context :disable_calculators_constructor - it "renders the 'under_construction' template" do - get account_calculators_path - - expect(response).to render_template("shared/under_construction") + it "raises routing error" do + expect { get account_calculators_path }.to raise_error(ActionController::RoutingError) end end - context "when in local environment" do - include_context :in_local_environment - + context "when flipper is turned on" do it "loads calculators and renders the index template" do get account_calculators_path diff --git a/spec/requests/calculators_spec.rb b/spec/requests/calculators_spec.rb index 04ec64e51..587d0f484 100644 --- a/spec/requests/calculators_spec.rb +++ b/spec/requests/calculators_spec.rb @@ -5,6 +5,8 @@ RSpec.describe CalculatorsController, type: :request do let(:calculator) { create(:calculator) } + include_context :enable_calculators_constructor + describe "GET #index" do context "when show_calculators_list feature is enabled" do include_context :show_calculators_list @@ -16,6 +18,14 @@ expect(response).to render_template(:index) expect(assigns(:calculators)).not_to be_nil end + + context "and constructor flipper is disabled" do + include_context :disable_calculators_constructor + + it "raises routing error" do + expect { get calculators_path }.to raise_error(ActionController::RoutingError) + end + end end context "when show_calculators_list feature is disabled" do diff --git a/spec/support/shared/context/feature_flags.rb b/spec/support/shared/context/feature_flags.rb index cb62bed93..13a029c9f 100644 --- a/spec/support/shared/context/feature_flags.rb +++ b/spec/support/shared/context/feature_flags.rb @@ -26,6 +26,20 @@ end end +RSpec.shared_context :enable_calculators_constructor do + before do + FeatureFlag.find_or_create_by!(name: "constructor_status") + Flipper.enable(:constructor_status) + end +end + +RSpec.shared_context :disable_calculators_constructor do + before do + FeatureFlag.find_or_create_by!(name: "constructor_status") + Flipper.disable(:constructor_status) + end +end + def sandbox_mode_context(mode) RSpec.shared_context :"sandbox_mode_#{mode}" do before do