From 8d5f409a3a3b87362f2254af7e6f30503348a94b Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Tue, 26 Sep 2023 16:48:20 -0700 Subject: [PATCH 1/9] add an aria-label to the modal close link --- app/views/components/widget/_no_modal.html.erb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/components/widget/_no_modal.html.erb b/app/views/components/widget/_no_modal.html.erb index 341a911e4..048a6ac9d 100644 --- a/app/views/components/widget/_no_modal.html.erb +++ b/app/views/components/widget/_no_modal.html.erb @@ -12,7 +12,10 @@ <% unless form.delivery_method == "inline" %> - × + × <% end %> <% if form.instructions? %> @@ -25,7 +28,6 @@ A red asterisk (*) indicates a required field.

-
<%= render 'components/forms/flash', form: form %> <%= render partial: "components/forms/custom", locals: { form: form, questions: form.questions } %> From 5bb7b1fd57a8c6babe2ad64c2d0ca8dda61fa5b0 Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 09:43:05 -0700 Subject: [PATCH 2/9] translation required text --- app/views/components/forms/_custom_layout.html.erb | 2 +- app/views/components/widget/_no_modal.html.erb | 4 ++-- config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/zh-CN.yml | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/views/components/forms/_custom_layout.html.erb b/app/views/components/forms/_custom_layout.html.erb index 917fb1e9b..2ca7103a7 100644 --- a/app/views/components/forms/_custom_layout.html.erb +++ b/app/views/components/forms/_custom_layout.html.erb @@ -16,7 +16,7 @@

<% end %>

- A red asterisk (*) indicates a required field. + <%= t :required_text_html %>

<%= render 'components/forms/flash', form: form %> <%= render partial: "components/forms/custom", locals: { form: form, questions: form.questions } %> diff --git a/app/views/components/widget/_no_modal.html.erb b/app/views/components/widget/_no_modal.html.erb index 048a6ac9d..7c3151907 100644 --- a/app/views/components/widget/_no_modal.html.erb +++ b/app/views/components/widget/_no_modal.html.erb @@ -22,10 +22,10 @@

<%= sanitize(form.instructions) %>

- <% end %> + <% end -%>

- A red asterisk (*) indicates a required field. + <%= t :required_field_html %>

<%= render 'components/forms/flash', form: form %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 500f93346..111d3724e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -138,6 +138,7 @@ en-US: characters_allowed: "characters allowed" characters_left: "characters left" form: + required_field_html: 'A red asterisk (*) indicates a required field.' submit: "Submit" submit_thankyou: "Thank you. Your feedback has been received." help_improve: "Help improve this site" diff --git a/config/locales/es.yml b/config/locales/es.yml index 04331cd21..bdffeb0a0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -26,6 +26,7 @@ es: characters_allowed: "caracteres permitidos" characters_left: "caracteres restantes" form: + required_field_html: 'Un asterisco rojo (*) indica un campo obligatorio.' submit: "Enviar" submit_thankyou: "Gracias. Su comentario ha sido recibido." help_improve: "Ayuda a mejorar este sitio" diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 740b29950..cd126e8dc 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -46,6 +46,7 @@ zh-CN: characters_allowed: "允许的字符" characters_left: "剩余字符数" form: + required_field_html: '红色星号 (*) 表示必填字段。' submit: "提交" submit_thankyou: "谢谢. 已收到您的反馈." help_improve: "帮助改善这个网站" From 2b6502a4724fc08b80eda1b416cace9631a655e9 Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 14:43:27 -0700 Subject: [PATCH 3/9] add cx_action_plans --- app/controllers/cx_action_plans_controller.rb | 70 +++++++++ app/models/cx_action_plan.rb | 2 + app/serializers/cx_action_plan_serializer.rb | 3 + .../cx_action_plans/_cx_action_plan.html.erb | 22 +++ app/views/cx_action_plans/_form.html.erb | 37 +++++ app/views/cx_action_plans/edit.html.erb | 10 ++ app/views/cx_action_plans/index.html.erb | 14 ++ app/views/cx_action_plans/new.html.erb | 9 ++ app/views/cx_action_plans/show.html.erb | 10 ++ config/routes.rb | 1 + .../20230927214053_create_cx_action_plans.rb | 12 ++ spec/models/cx_action_plan_spec.rb | 5 + spec/requests/cx_action_plans_spec.rb | 135 ++++++++++++++++++ 13 files changed, 330 insertions(+) create mode 100644 app/controllers/cx_action_plans_controller.rb create mode 100644 app/models/cx_action_plan.rb create mode 100644 app/serializers/cx_action_plan_serializer.rb create mode 100644 app/views/cx_action_plans/_cx_action_plan.html.erb create mode 100644 app/views/cx_action_plans/_form.html.erb create mode 100644 app/views/cx_action_plans/edit.html.erb create mode 100644 app/views/cx_action_plans/index.html.erb create mode 100644 app/views/cx_action_plans/new.html.erb create mode 100644 app/views/cx_action_plans/show.html.erb create mode 100644 db/migrate/20230927214053_create_cx_action_plans.rb create mode 100644 spec/models/cx_action_plan_spec.rb create mode 100644 spec/requests/cx_action_plans_spec.rb diff --git a/app/controllers/cx_action_plans_controller.rb b/app/controllers/cx_action_plans_controller.rb new file mode 100644 index 000000000..04dfadad3 --- /dev/null +++ b/app/controllers/cx_action_plans_controller.rb @@ -0,0 +1,70 @@ +class CxActionPlansController < ApplicationController + before_action :set_cx_action_plan, only: %i[ show edit update destroy ] + + # GET /cx_action_plans or /cx_action_plans.json + def index + @cx_action_plans = CxActionPlan.all + end + + # GET /cx_action_plans/1 or /cx_action_plans/1.json + def show + end + + # GET /cx_action_plans/new + def new + @cx_action_plan = CxActionPlan.new + end + + # GET /cx_action_plans/1/edit + def edit + end + + # POST /cx_action_plans or /cx_action_plans.json + def create + @cx_action_plan = CxActionPlan.new(cx_action_plan_params) + + respond_to do |format| + if @cx_action_plan.save + format.html { redirect_to cx_action_plan_url(@cx_action_plan), notice: "Cx action plan was successfully created." } + format.json { render :show, status: :created, location: @cx_action_plan } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @cx_action_plan.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /cx_action_plans/1 or /cx_action_plans/1.json + def update + respond_to do |format| + if @cx_action_plan.update(cx_action_plan_params) + format.html { redirect_to cx_action_plan_url(@cx_action_plan), notice: "Cx action plan was successfully updated." } + format.json { render :show, status: :ok, location: @cx_action_plan } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @cx_action_plan.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /cx_action_plans/1 or /cx_action_plans/1.json + def destroy + @cx_action_plan.destroy + + respond_to do |format| + format.html { redirect_to cx_action_plans_url, notice: "Cx action plan was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_cx_action_plan + @cx_action_plan = CxActionPlan.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def cx_action_plan_params + params.require(:cx_action_plan).permit(:service_provider_id, :year, :delivered_current_year, :to_deliver_next_year) + end +end diff --git a/app/models/cx_action_plan.rb b/app/models/cx_action_plan.rb new file mode 100644 index 000000000..13cafe6ab --- /dev/null +++ b/app/models/cx_action_plan.rb @@ -0,0 +1,2 @@ +class CxActionPlan < ApplicationRecord +end diff --git a/app/serializers/cx_action_plan_serializer.rb b/app/serializers/cx_action_plan_serializer.rb new file mode 100644 index 000000000..bfff3ee29 --- /dev/null +++ b/app/serializers/cx_action_plan_serializer.rb @@ -0,0 +1,3 @@ +class CxActionPlanSerializer < ActiveModel::Serializer + attributes :id, :service_provider_id, :year, :delivered_current_year, :to_deliver_next_year +end diff --git a/app/views/cx_action_plans/_cx_action_plan.html.erb b/app/views/cx_action_plans/_cx_action_plan.html.erb new file mode 100644 index 000000000..689c5c99a --- /dev/null +++ b/app/views/cx_action_plans/_cx_action_plan.html.erb @@ -0,0 +1,22 @@ +
+

+ Service provider: + <%= cx_action_plan.service_provider_id %> +

+ +

+ Year: + <%= cx_action_plan.year %> +

+ +

+ Delivered current year: + <%= cx_action_plan.delivered_current_year %> +

+ +

+ To deliver next year: + <%= cx_action_plan.to_deliver_next_year %> +

+ +
diff --git a/app/views/cx_action_plans/_form.html.erb b/app/views/cx_action_plans/_form.html.erb new file mode 100644 index 000000000..3eab89d0b --- /dev/null +++ b/app/views/cx_action_plans/_form.html.erb @@ -0,0 +1,37 @@ +<%= form_with(model: cx_action_plan) do |form| %> + <% if cx_action_plan.errors.any? %> +
+

<%= pluralize(cx_action_plan.errors.count, "error") %> prohibited this cx_action_plan from being saved:

+ +
    + <% cx_action_plan.errors.each do |error| %> +
  • <%= error.full_message %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form.label :service_provider_id, style: "display: block" %> + <%= form.number_field :service_provider_id %> +
+ +
+ <%= form.label :year, style: "display: block" %> + <%= form.number_field :year %> +
+ +
+ <%= form.label :delivered_current_year, style: "display: block" %> + <%= form.text_area :delivered_current_year %> +
+ +
+ <%= form.label :to_deliver_next_year, style: "display: block" %> + <%= form.text_area :to_deliver_next_year %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/cx_action_plans/edit.html.erb b/app/views/cx_action_plans/edit.html.erb new file mode 100644 index 000000000..987cd4020 --- /dev/null +++ b/app/views/cx_action_plans/edit.html.erb @@ -0,0 +1,10 @@ +

Editing cx action plan

+ +<%= render "form", cx_action_plan: @cx_action_plan %> + +
+ +
+ <%= link_to "Show this cx action plan", @cx_action_plan %> | + <%= link_to "Back to cx action plans", cx_action_plans_path %> +
diff --git a/app/views/cx_action_plans/index.html.erb b/app/views/cx_action_plans/index.html.erb new file mode 100644 index 000000000..8a6a73cfb --- /dev/null +++ b/app/views/cx_action_plans/index.html.erb @@ -0,0 +1,14 @@ +

<%= notice %>

+ +

Cx action plans

+ +
+ <% @cx_action_plans.each do |cx_action_plan| %> + <%= render cx_action_plan %> +

+ <%= link_to "Show this cx action plan", cx_action_plan %> +

+ <% end %> +
+ +<%= link_to "New cx action plan", new_cx_action_plan_path %> diff --git a/app/views/cx_action_plans/new.html.erb b/app/views/cx_action_plans/new.html.erb new file mode 100644 index 000000000..7b38a81af --- /dev/null +++ b/app/views/cx_action_plans/new.html.erb @@ -0,0 +1,9 @@ +

New cx action plan

+ +<%= render "form", cx_action_plan: @cx_action_plan %> + +
+ +
+ <%= link_to "Back to cx action plans", cx_action_plans_path %> +
diff --git a/app/views/cx_action_plans/show.html.erb b/app/views/cx_action_plans/show.html.erb new file mode 100644 index 000000000..cbb81462b --- /dev/null +++ b/app/views/cx_action_plans/show.html.erb @@ -0,0 +1,10 @@ +

<%= notice %>

+ +<%= render @cx_action_plan %> + +
+ <%= link_to "Edit this cx action plan", edit_cx_action_plan_path(@cx_action_plan) %> | + <%= link_to "Back to cx action plans", cx_action_plans_path %> + + <%= button_to "Destroy this cx action plan", @cx_action_plan, method: :delete %> +
diff --git a/config/routes.rb b/config/routes.rb index 4dce97061..c09975771 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,6 +3,7 @@ require 'sidekiq/web' Rails.application.routes.draw do + resources :cx_action_plans resources :ivn_components devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } diff --git a/db/migrate/20230927214053_create_cx_action_plans.rb b/db/migrate/20230927214053_create_cx_action_plans.rb new file mode 100644 index 000000000..657968609 --- /dev/null +++ b/db/migrate/20230927214053_create_cx_action_plans.rb @@ -0,0 +1,12 @@ +class CreateCxActionPlans < ActiveRecord::Migration[7.0] + def change + create_table :cx_action_plans do |t| + t.integer :service_provider_id + t.integer :year + t.text :delivered_current_year + t.text :to_deliver_next_year + + t.timestamps + end + end +end diff --git a/spec/models/cx_action_plan_spec.rb b/spec/models/cx_action_plan_spec.rb new file mode 100644 index 000000000..6ebec0ef9 --- /dev/null +++ b/spec/models/cx_action_plan_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe CxActionPlan, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/cx_action_plans_spec.rb b/spec/requests/cx_action_plans_spec.rb new file mode 100644 index 000000000..587952eb8 --- /dev/null +++ b/spec/requests/cx_action_plans_spec.rb @@ -0,0 +1,135 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to test the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. + +RSpec.describe "/cx_action_plans", type: :request do + + # This should return the minimal set of attributes required to create a valid + # CxActionPlan. As you add validations to CxActionPlan, be sure to + # adjust the attributes here as well. + let(:valid_attributes) { + skip("Add a hash of attributes valid for your model") + } + + let(:invalid_attributes) { + skip("Add a hash of attributes invalid for your model") + } + + describe "GET /index" do + it "renders a successful response" do + CxActionPlan.create! valid_attributes + get cx_action_plans_url + expect(response).to be_successful + end + end + + describe "GET /show" do + it "renders a successful response" do + cx_action_plan = CxActionPlan.create! valid_attributes + get cx_action_plan_url(cx_action_plan) + expect(response).to be_successful + end + end + + describe "GET /new" do + it "renders a successful response" do + get new_cx_action_plan_url + expect(response).to be_successful + end + end + + describe "GET /edit" do + it "renders a successful response" do + cx_action_plan = CxActionPlan.create! valid_attributes + get edit_cx_action_plan_url(cx_action_plan) + expect(response).to be_successful + end + end + + describe "POST /create" do + context "with valid parameters" do + it "creates a new CxActionPlan" do + expect { + post cx_action_plans_url, params: { cx_action_plan: valid_attributes } + }.to change(CxActionPlan, :count).by(1) + end + + it "redirects to the created cx_action_plan" do + post cx_action_plans_url, params: { cx_action_plan: valid_attributes } + expect(response).to redirect_to(cx_action_plan_url(CxActionPlan.last)) + end + end + + context "with invalid parameters" do + it "does not create a new CxActionPlan" do + expect { + post cx_action_plans_url, params: { cx_action_plan: invalid_attributes } + }.to change(CxActionPlan, :count).by(0) + end + + + it "renders a response with 422 status (i.e. to display the 'new' template)" do + post cx_action_plans_url, params: { cx_action_plan: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + + end + end + + describe "PATCH /update" do + context "with valid parameters" do + let(:new_attributes) { + skip("Add a hash of attributes valid for your model") + } + + it "updates the requested cx_action_plan" do + cx_action_plan = CxActionPlan.create! valid_attributes + patch cx_action_plan_url(cx_action_plan), params: { cx_action_plan: new_attributes } + cx_action_plan.reload + skip("Add assertions for updated state") + end + + it "redirects to the cx_action_plan" do + cx_action_plan = CxActionPlan.create! valid_attributes + patch cx_action_plan_url(cx_action_plan), params: { cx_action_plan: new_attributes } + cx_action_plan.reload + expect(response).to redirect_to(cx_action_plan_url(cx_action_plan)) + end + end + + context "with invalid parameters" do + + it "renders a response with 422 status (i.e. to display the 'edit' template)" do + cx_action_plan = CxActionPlan.create! valid_attributes + patch cx_action_plan_url(cx_action_plan), params: { cx_action_plan: invalid_attributes } + expect(response).to have_http_status(:unprocessable_entity) + end + + end + end + + describe "DELETE /destroy" do + it "destroys the requested cx_action_plan" do + cx_action_plan = CxActionPlan.create! valid_attributes + expect { + delete cx_action_plan_url(cx_action_plan) + }.to change(CxActionPlan, :count).by(-1) + end + + it "redirects to the cx_action_plans list" do + cx_action_plan = CxActionPlan.create! valid_attributes + delete cx_action_plan_url(cx_action_plan) + expect(response).to redirect_to(cx_action_plans_url) + end + end +end From 3f7f00de42c8f13813d92c5f3118244e483e9bab Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 15:54:57 -0700 Subject: [PATCH 4/9] /admin/cx_action_plans --- .../{ => admin}/cx_action_plans_controller.rb | 8 ++-- app/models/cx_action_plan.rb | 1 + .../cx_action_plans/_cx_action_plan.html.erb | 0 .../admin/cx_action_plans/_form.html.erb | 37 +++++++++++++++ app/views/admin/cx_action_plans/edit.html.erb | 13 ++++++ .../admin/cx_action_plans/index.html.erb | 44 ++++++++++++++++++ app/views/admin/cx_action_plans/new.html.erb | 11 +++++ app/views/admin/cx_action_plans/show.html.erb | 46 +++++++++++++++++++ app/views/cx_action_plans/_form.html.erb | 37 --------------- app/views/cx_action_plans/edit.html.erb | 10 ---- app/views/cx_action_plans/index.html.erb | 14 ------ app/views/cx_action_plans/new.html.erb | 9 ---- app/views/cx_action_plans/show.html.erb | 10 ---- config/routes.rb | 3 +- db/schema.rb | 11 ++++- 15 files changed, 169 insertions(+), 85 deletions(-) rename app/controllers/{ => admin}/cx_action_plans_controller.rb (77%) rename app/views/{ => admin}/cx_action_plans/_cx_action_plan.html.erb (100%) create mode 100644 app/views/admin/cx_action_plans/_form.html.erb create mode 100644 app/views/admin/cx_action_plans/edit.html.erb create mode 100644 app/views/admin/cx_action_plans/index.html.erb create mode 100644 app/views/admin/cx_action_plans/new.html.erb create mode 100644 app/views/admin/cx_action_plans/show.html.erb delete mode 100644 app/views/cx_action_plans/_form.html.erb delete mode 100644 app/views/cx_action_plans/edit.html.erb delete mode 100644 app/views/cx_action_plans/index.html.erb delete mode 100644 app/views/cx_action_plans/new.html.erb delete mode 100644 app/views/cx_action_plans/show.html.erb diff --git a/app/controllers/cx_action_plans_controller.rb b/app/controllers/admin/cx_action_plans_controller.rb similarity index 77% rename from app/controllers/cx_action_plans_controller.rb rename to app/controllers/admin/cx_action_plans_controller.rb index 04dfadad3..8f1ee7f71 100644 --- a/app/controllers/cx_action_plans_controller.rb +++ b/app/controllers/admin/cx_action_plans_controller.rb @@ -1,4 +1,4 @@ -class CxActionPlansController < ApplicationController +class Admin::CxActionPlansController < AdminController before_action :set_cx_action_plan, only: %i[ show edit update destroy ] # GET /cx_action_plans or /cx_action_plans.json @@ -12,11 +12,13 @@ def show # GET /cx_action_plans/new def new + @service_providers = ServiceProvider.all.includes(:organization).order('organizations.name', 'service_providers.name') @cx_action_plan = CxActionPlan.new end # GET /cx_action_plans/1/edit def edit + @service_providers = ServiceProvider.all.includes(:organization).order('organizations.name', 'service_providers.name') end # POST /cx_action_plans or /cx_action_plans.json @@ -25,7 +27,7 @@ def create respond_to do |format| if @cx_action_plan.save - format.html { redirect_to cx_action_plan_url(@cx_action_plan), notice: "Cx action plan was successfully created." } + format.html { redirect_to admin_cx_action_plan_url(@cx_action_plan), notice: "Cx action plan was successfully created." } format.json { render :show, status: :created, location: @cx_action_plan } else format.html { render :new, status: :unprocessable_entity } @@ -38,7 +40,7 @@ def create def update respond_to do |format| if @cx_action_plan.update(cx_action_plan_params) - format.html { redirect_to cx_action_plan_url(@cx_action_plan), notice: "Cx action plan was successfully updated." } + format.html { redirect_to admin_cx_action_plan_url(@cx_action_plan), notice: "Cx action plan was successfully updated." } format.json { render :show, status: :ok, location: @cx_action_plan } else format.html { render :edit, status: :unprocessable_entity } diff --git a/app/models/cx_action_plan.rb b/app/models/cx_action_plan.rb index 13cafe6ab..d90f9e63b 100644 --- a/app/models/cx_action_plan.rb +++ b/app/models/cx_action_plan.rb @@ -1,2 +1,3 @@ class CxActionPlan < ApplicationRecord + belongs_to :service_provider end diff --git a/app/views/cx_action_plans/_cx_action_plan.html.erb b/app/views/admin/cx_action_plans/_cx_action_plan.html.erb similarity index 100% rename from app/views/cx_action_plans/_cx_action_plan.html.erb rename to app/views/admin/cx_action_plans/_cx_action_plan.html.erb diff --git a/app/views/admin/cx_action_plans/_form.html.erb b/app/views/admin/cx_action_plans/_form.html.erb new file mode 100644 index 000000000..1cd5a5a02 --- /dev/null +++ b/app/views/admin/cx_action_plans/_form.html.erb @@ -0,0 +1,37 @@ +<%= form_with(model: cx_action_plan, url: cx_action_plan.persisted? ? admin_cx_action_plan_path : admin_cx_action_plans_path, local: true, data: { turbo: false }) do |form| %> + <% if cx_action_plan.errors.any? %> +
+

<%= pluralize(cx_action_plan.errors.count, "error") %> prohibited this cx_action_plan from being saved:

+ +
    + <% cx_action_plan.errors.each do |error| %> +
  • <%= error.full_message %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form.label :service_provider_id, class: "usa-label" %> + <%= form.select :service_provider_id, options_for_select(@service_providers.map { |p| ["#{p.organization.abbreviation} - #{p.name}", p.id] }, cx_action_plan.service_provider_id), { prompt: "Which Service Provider?" }, { class: "usa-select" } %> +
+ +
+ <%= form.label :year, class: "usa-label" %> + <%= form.number_field :year, class: "usa-input" %> +
+ +
+ <%= form.label :delivered_current_year, class: "usa-label" %> + <%= form.text_area :delivered_current_year, class: "usa-textarea" %> +
+ +
+ <%= form.label :to_deliver_next_year, class: "usa-label" %> + <%= form.text_area :to_deliver_next_year, class: "usa-textarea" %> +
+ +

+ <%= form.submit class: "usa-button" %> +

+<% end %> diff --git a/app/views/admin/cx_action_plans/edit.html.erb b/app/views/admin/cx_action_plans/edit.html.erb new file mode 100644 index 000000000..f826fa8ef --- /dev/null +++ b/app/views/admin/cx_action_plans/edit.html.erb @@ -0,0 +1,13 @@ +<% content_for :navigation_title do %> + Editing CX Action Plan +<% end %> + +

+ <%= link_to admin_cx_action_plan_path(@cx_action_plan) do %> + + Back to CX Action Plan + <% end %> +

+

+ +<%= render "form", cx_action_plan: @cx_action_plan %> diff --git a/app/views/admin/cx_action_plans/index.html.erb b/app/views/admin/cx_action_plans/index.html.erb new file mode 100644 index 000000000..640d2a596 --- /dev/null +++ b/app/views/admin/cx_action_plans/index.html.erb @@ -0,0 +1,44 @@ +<% content_for :navigation_title do %> + CX Action Plans + + <%= link_to new_admin_cx_action_plan_path, class: "usa-button usa-button-inverted float-right" do %> + + New CX Action Plan + <% end %> +<% end %> + +
+ + + + + + + + + + <% @cx_action_plans.each do |cx_action_plan| %> + + + + + + + <% end %> +
+ Organization name + + Service Provider name + + Year + +
+ <%= cx_action_plan.service_provider.organization.name %> + + <%= cx_action_plan.service_provider.name %> + + <%= cx_action_plan.year %> + + <%= link_to 'View', admin_cx_action_plan_path(cx_action_plan) %> +
+
diff --git a/app/views/admin/cx_action_plans/new.html.erb b/app/views/admin/cx_action_plans/new.html.erb new file mode 100644 index 000000000..b6ae15f2f --- /dev/null +++ b/app/views/admin/cx_action_plans/new.html.erb @@ -0,0 +1,11 @@ +<% content_for :navigation_title do %> + New CX Action Plan +<% end %> +

+ <%= link_to admin_cx_action_plans_path do %> + + Back to CX Action Plans + <% end %> +

+ +<%= render "form", cx_action_plan: @cx_action_plan %> diff --git a/app/views/admin/cx_action_plans/show.html.erb b/app/views/admin/cx_action_plans/show.html.erb new file mode 100644 index 000000000..edd16a422 --- /dev/null +++ b/app/views/admin/cx_action_plans/show.html.erb @@ -0,0 +1,46 @@ +<% content_for :navigation_title do %> + CX Action Plan + <%= link_to edit_admin_cx_action_plan_path(@cx_action_plan), class: "usa-button usa-button-inverted float-right" do %> + + Edit + <% end %> +<% end %> +

+ <%= link_to admin_cx_action_plans_path do %> + + Back to CX Action Plans + <% end %> +

+ +
> +

+ Organization name: + <%= @cx_action_plan.service_provider.organization.name %> +

+ +

+ Service provider: + <%= link_to @cx_action_plan.service_provider.name, admin_service_provider_path(@cx_action_plan.service_provider) %> +

+ +

+ Year: + <%= @cx_action_plan.year %> +

+ +

+ Delivered current year: + <%= to_markdown(@cx_action_plan.delivered_current_year) %> +

+ +

+ To deliver next year: + <%= to_markdown(@cx_action_plan.to_deliver_next_year) %> +

+
+ +
+
+ <%= button_to "Destroy", admin_cx_action_plan_path(@cx_action_plan), class: "usa-button usa-button--secondary float-right", method: :delete %> +
+
diff --git a/app/views/cx_action_plans/_form.html.erb b/app/views/cx_action_plans/_form.html.erb deleted file mode 100644 index 3eab89d0b..000000000 --- a/app/views/cx_action_plans/_form.html.erb +++ /dev/null @@ -1,37 +0,0 @@ -<%= form_with(model: cx_action_plan) do |form| %> - <% if cx_action_plan.errors.any? %> -
-

<%= pluralize(cx_action_plan.errors.count, "error") %> prohibited this cx_action_plan from being saved:

- -
    - <% cx_action_plan.errors.each do |error| %> -
  • <%= error.full_message %>
  • - <% end %> -
-
- <% end %> - -
- <%= form.label :service_provider_id, style: "display: block" %> - <%= form.number_field :service_provider_id %> -
- -
- <%= form.label :year, style: "display: block" %> - <%= form.number_field :year %> -
- -
- <%= form.label :delivered_current_year, style: "display: block" %> - <%= form.text_area :delivered_current_year %> -
- -
- <%= form.label :to_deliver_next_year, style: "display: block" %> - <%= form.text_area :to_deliver_next_year %> -
- -
- <%= form.submit %> -
-<% end %> diff --git a/app/views/cx_action_plans/edit.html.erb b/app/views/cx_action_plans/edit.html.erb deleted file mode 100644 index 987cd4020..000000000 --- a/app/views/cx_action_plans/edit.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -

Editing cx action plan

- -<%= render "form", cx_action_plan: @cx_action_plan %> - -
- -
- <%= link_to "Show this cx action plan", @cx_action_plan %> | - <%= link_to "Back to cx action plans", cx_action_plans_path %> -
diff --git a/app/views/cx_action_plans/index.html.erb b/app/views/cx_action_plans/index.html.erb deleted file mode 100644 index 8a6a73cfb..000000000 --- a/app/views/cx_action_plans/index.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -

<%= notice %>

- -

Cx action plans

- -
- <% @cx_action_plans.each do |cx_action_plan| %> - <%= render cx_action_plan %> -

- <%= link_to "Show this cx action plan", cx_action_plan %> -

- <% end %> -
- -<%= link_to "New cx action plan", new_cx_action_plan_path %> diff --git a/app/views/cx_action_plans/new.html.erb b/app/views/cx_action_plans/new.html.erb deleted file mode 100644 index 7b38a81af..000000000 --- a/app/views/cx_action_plans/new.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -

New cx action plan

- -<%= render "form", cx_action_plan: @cx_action_plan %> - -
- -
- <%= link_to "Back to cx action plans", cx_action_plans_path %> -
diff --git a/app/views/cx_action_plans/show.html.erb b/app/views/cx_action_plans/show.html.erb deleted file mode 100644 index cbb81462b..000000000 --- a/app/views/cx_action_plans/show.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -

<%= notice %>

- -<%= render @cx_action_plan %> - -
- <%= link_to "Edit this cx action plan", edit_cx_action_plan_path(@cx_action_plan) %> | - <%= link_to "Back to cx action plans", cx_action_plans_path %> - - <%= button_to "Destroy this cx action plan", @cx_action_plan, method: :delete %> -
diff --git a/config/routes.rb b/config/routes.rb index c09975771..1ea804b35 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,6 @@ require 'sidekiq/web' Rails.application.routes.draw do - resources :cx_action_plans resources :ivn_components devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } @@ -104,6 +103,7 @@ post 'remove_service_provider_manager', to: 'service_providers#remove_service_provider_manager', as: :remove_service_provider_manager end end + resources :cx_action_plans resources :services do collection do get 'catalog', to: 'services#catalog', as: :catalog @@ -145,6 +145,7 @@ get 'events', to: 'collections#events', as: :events end end + resources :omb_cx_reporting_collections resources :cscrm_data_collections do member do diff --git a/db/schema.rb b/db/schema.rb index 07a472680..3a37111bc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_09_26_183233) do +ActiveRecord::Schema[7.0].define(version: 2023_09_27_214053) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -178,6 +178,15 @@ t.index ["user_id"], name: "index_cscrm_data_collections2_on_user_id" end + create_table "cx_action_plans", force: :cascade do |t| + t.integer "service_provider_id" + t.integer "year" + t.text "delivered_current_year" + t.text "to_deliver_next_year" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "digital_product_versions", force: :cascade do |t| t.bigint "digital_product_id" t.string "store_url" From f9581e884a9f40677192ad856c4dfab7d61f46be Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 16:05:24 -0700 Subject: [PATCH 5/9] make cx_action_plan data available via API --- .../api/v1/cx_action_plans_controller.rb | 23 +++++++++++++++++++ app/models/cx_action_plan.rb | 17 ++++++++++++++ app/serializers/cx_action_plan_serializer.rb | 15 +++++++++++- config/routes.rb | 1 + 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 app/controllers/api/v1/cx_action_plans_controller.rb diff --git a/app/controllers/api/v1/cx_action_plans_controller.rb b/app/controllers/api/v1/cx_action_plans_controller.rb new file mode 100644 index 000000000..90f0be1bc --- /dev/null +++ b/app/controllers/api/v1/cx_action_plans_controller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Api + module V1 + class CxActionPlansController < ::ApiController + def index + respond_to do |format| + format.json do + render json: CxActionPlan.order(:id), each_serializer: CxActionPlanSerializer + end + end + end + + def show + respond_to do |format| + format.json do + render json: CxActionPlan.find(params[:id]), serializer: CxActionPlanSerializer + end + end + end + end + end +end diff --git a/app/models/cx_action_plan.rb b/app/models/cx_action_plan.rb index d90f9e63b..c92e21b38 100644 --- a/app/models/cx_action_plan.rb +++ b/app/models/cx_action_plan.rb @@ -1,3 +1,20 @@ class CxActionPlan < ApplicationRecord belongs_to :service_provider + + + def organization_id + self.service_provider.organization_id + end + + def organization_name + self.service_provider.organization.name + end + + def service_provider_name + self.service_provider.name + end + + def services + self.service_provider.services + end end diff --git a/app/serializers/cx_action_plan_serializer.rb b/app/serializers/cx_action_plan_serializer.rb index bfff3ee29..d3898ddc6 100644 --- a/app/serializers/cx_action_plan_serializer.rb +++ b/app/serializers/cx_action_plan_serializer.rb @@ -1,3 +1,16 @@ class CxActionPlanSerializer < ActiveModel::Serializer - attributes :id, :service_provider_id, :year, :delivered_current_year, :to_deliver_next_year + attributes :id, + :organization_id, + :organization_name, + :service_provider_id, + :service_provider_name, + :year, + :delivered_current_year, + :to_deliver_next_year, + :services + + + def services + ActiveModel::Serializer::CollectionSerializer.new(object.services, serializer: ServiceSerializer) + end end diff --git a/config/routes.rb b/config/routes.rb index 1ea804b35..a4de109b2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,6 +45,7 @@ resources :forms, only: %i[index show] resources :websites, only: [:index] resources :service_providers, only: [:index] + resources :cx_action_plans, only: %i[index show] resources :services, only: %i[index show] resources :personas, only: [:index] resources :goals, only: [:index] From 651587ab71b3853de65cc044d5e537f9e29a6f7b Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 20:54:59 -0700 Subject: [PATCH 6/9] translate cscrm2 export values --- app/models/cscrm_data_collection2.rb | 169 +++++++++++++++++- .../cscrm_data_collections2/edit.html.erb | 2 +- 2 files changed, 165 insertions(+), 6 deletions(-) diff --git a/app/models/cscrm_data_collection2.rb b/app/models/cscrm_data_collection2.rb index 006a5980c..415266f09 100644 --- a/app/models/cscrm_data_collection2.rb +++ b/app/models/cscrm_data_collection2.rb @@ -409,6 +409,147 @@ def self.established_process_information_sharing_options } end + + # + # + # Custom logic applied to fields for data export + # example: 8 checkbox values being consolidated into a value between 1-3 + # + # + + def self.export_conversion_question_10(field) + return nil if field.length == 1 + + # 0 = Not Identified + # 1 = 1 or 2 identified + # 2 = All but suppliers identified + # 3 = All identified + # Note: Critical item selections not scored, for info only; however, + # If critical items were selected, assumption was that items had been identified + + question_option_selections = YAML.load(field) # parse the string encoded as an array, to an array + question_option_selections_without_not_identified = question_option_selections - ["Not identified"] # remove Not Identified option + question_option_selections_without_suppliers = question_option_selections_without_not_identified - ["Critical Suppliers Identified"] # remove Not Identified and Suppliers option + + if question_option_selections_without_not_identified.size == 8 # if all are selected + 3 + elsif question_option_selections_without_suppliers.size == 7 + 2 + elsif (1..2).include?(question_option_selections_without_not_identified.size) + 1 + elsif question_option_selections.include?("Not identified") + 0 + else + "not scored" + end + end + + def self.export_conversion_question_12(field) + return nil if field.length == 1 + + # 0 = Not Considered + # 1 = up to 2 selections + # 2 = 3 to 6 selections + # 3 = All + + question_option_selections = YAML.load(field) + question_option_selections_without_not_considered = question_option_selections - ["Not considered"] + question_option_selections_without_other = question_option_selections_without_not_considered - ["Other"] + + if question_option_selections_without_other.size == 7 # if all are selected + 3 + elsif (3..6).include?(question_option_selections_without_other.size) + 2 + elsif (1..2).include?(question_option_selections_without_other.size) + 1 + elsif question_option_selections.include?("Not considered") + 0 + else + "not scored" + end + end + + def self.export_conversion_question_14(field) + return nil if field.length == 1 + + # 0 = Not Considered + # 1 = Some Products and/or Services + # 2 = Some Products/All Services or All + # Products/Some Services + # 3 = All Product and Services + # Note: If 1 “all” option selected score = 2 + + question_option_selections = YAML.load(field) + question_option_selections_without_not_conducted = question_option_selections - ["Not conducted"] + + if question_option_selections_without_not_conducted.include?("Conducted for all prioritized products") && + question_option_selections_without_not_conducted.include?("Conducted for all prioritized services") + 3 + elsif question_option_selections_without_not_conducted.include?("Conducted for all prioritized products") || + question_option_selections_without_not_conducted.include?("Conducted for all prioritized services") + 2 + elsif question_option_selections_without_not_conducted.include?("Conducted for some prioritized products") || + question_option_selections_without_not_conducted.include?("Conducted for some prioritized services") + 1 + elsif question_option_selections.include?("Not conducted") + 0 + else + "not scored" + end + end + + def self.export_conversion_question_16(field) + # 0 = Not established + # 1 = Partial/in-Process Internal process + # 2 = Internal Process established and/or FASC process planned/in-process + # 3 = Internal and FASC process established + + if field == "5" + 3 + elsif field == "2" || + field == "3" || + field == "4" + 2 + elsif field == "1" + 1 + elsif field == "0" + 0 + else + "not scored" + end + end + + def self.export_conversion_question_17(field) + return nil if field.length == 1 + + # 0 = Not Considered; + # 1 = Response option(s), other than SCRAs; + # 2 = Response options includes “SCRAs” but not “mitigations” + # 3 = ”SCRAs” and “Mitigations” options selected + + question_option_selections = YAML.load(field) + + if question_option_selections.include?("SCRAs are conducted for critical suppliers") && + question_option_selections.include?("Mitigations to improve resilience/address assessed risks associated with critical suppliers are identified and implemented") + 3 + elsif question_option_selections.include?("SCRAs are conducted for critical suppliers") && + !question_option_selections.include?("Mitigations to improve resilience/address assessed risks associated with critical suppliers are identified and implemented") + 2 + elsif question_option_selections.include?("Critical Suppliers are identified in COOP and Recovery plans") || + question_option_selections.include?("Business Impact Analysis considers supplier and product dependency risks and resiliency requirements") + 1 + elsif question_option_selections.include?("Not considered") + 0 + else + "not scored" + end + end + + # + # end custom export logic + # + + def self.to_csv collections = CscrmDataCollection2.order('year, quarter') @@ -453,29 +594,33 @@ def self.to_csv "clearly_defined_roles_value", "clearly_defined_roles", "clearly_defined_roles_comments", - "identified_assets_and_essential_functions_value", "identified_assets_and_essential_functions", + "identified_assets_and_essential_functions_value", + "identified_assets_and_essential_functions_translated_value", "identified_assets_and_essential_functions_comments", "prioritization_process_value", "prioritization_process", "prioritization_process_comments", - "considerations_in_procurement_processes_value", "considerations_in_procurement_processes", + "considerations_in_procurement_processes_value", + "considerations_in_procurement_processes_translated_value", "considerations_in_procurement_processes_comments", "documented_methodology_value", "documented_methodology", "documented_methodology_comments", - "conducts_scra_for_prioritized_products_and_services_value", "conducts_scra_for_prioritized_products_and_services", + "conducts_scra_for_prioritized_products_and_services_translated_value", "conducts_scra_for_prioritized_products_and_services_comments", "personnel_required_to_complete_training_value", "personnel_required_to_complete_training", "personnel_required_to_complete_training_comments", - "established_process_information_sharing_with_fasc_value", "established_process_information_sharing_with_fasc", + "established_process_information_sharing_with_fasc_value", + "established_process_information_sharing_with_fasc_translated_value", "established_process_information_sharing_with_fasc_comments", - "cybersecurity_supply_chain_risk_considerations_value", "cybersecurity_supply_chain_risk_considerations", + "cybersecurity_supply_chain_risk_considerations_value", + "cybersecurity_supply_chain_risk_considerations_translated_value", "cybersecurity_supply_chain_risk_considerations_comments", "process_for_product_authenticity_value", "process_for_product_authenticity", @@ -534,30 +679,44 @@ def self.to_csv CscrmDataCollection2.question_9[:options].key(collection.clearly_defined_roles.to_i), collection.clearly_defined_roles, collection.clearly_defined_roles_comments, + CscrmDataCollection2.question_10[:options].key(collection.identified_assets_and_essential_functions.to_i), collection.identified_assets_and_essential_functions, + export_conversion_question_10(collection.identified_assets_and_essential_functions), collection.identified_assets_and_essential_functions_comments, + CscrmDataCollection2.question_11[:options].key(collection.prioritization_process.to_i), collection.prioritization_process, collection.prioritization_process_comments, + CscrmDataCollection2.question_12[:options].key(collection.considerations_in_procurement_processes.to_i), collection.considerations_in_procurement_processes, + export_conversion_question_12(collection.considerations_in_procurement_processes), collection.considerations_in_procurement_processes_comments, + CscrmDataCollection2.question_13[:options].key(collection.documented_methodology.to_i), collection.documented_methodology, collection.documented_methodology_comments, + CscrmDataCollection2.question_14[:options].key(collection.conducts_scra_for_prioritized_products_and_services.to_i), collection.conducts_scra_for_prioritized_products_and_services, + export_conversion_question_14(collection.conducts_scra_for_prioritized_products_and_services), collection.conducts_scra_for_prioritized_products_and_services_comments, + CscrmDataCollection2.question_15[:options].key(collection.personnel_required_to_complete_training.to_i), collection.personnel_required_to_complete_training, collection.personnel_required_to_complete_training_comments, + CscrmDataCollection2.question_16[:options].key(collection.established_process_information_sharing_with_fasc.to_i), collection.established_process_information_sharing_with_fasc, + export_conversion_question_16(collection.established_process_information_sharing_with_fasc), collection.established_process_information_sharing_with_fasc_comments, + CscrmDataCollection2.question_17[:options].key(collection.cybersecurity_supply_chain_risk_considerations.to_i), collection.cybersecurity_supply_chain_risk_considerations, + export_conversion_question_17(collection.cybersecurity_supply_chain_risk_considerations), collection.cybersecurity_supply_chain_risk_considerations_comments, + CscrmDataCollection2.question_18[:options].key(collection.process_for_product_authenticity.to_i), collection.process_for_product_authenticity, collection.process_for_product_authenticity_comments, diff --git a/app/views/admin/cscrm_data_collections2/edit.html.erb b/app/views/admin/cscrm_data_collections2/edit.html.erb index a7484c466..da45687dc 100644 --- a/app/views/admin/cscrm_data_collections2/edit.html.erb +++ b/app/views/admin/cscrm_data_collections2/edit.html.erb @@ -3,7 +3,7 @@ <% end %>

- <%= link_to admin_cscrm_data_collections2_index_path(@cscrm_data_collection) do %> + <%= link_to admin_cscrm_data_collections2_path(@cscrm_data_collection) do %> Back to CSCRM Data Collection <% end %> From a70117ae9298ea8dd9d59a7477b977fe636277d4 Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 20:56:54 -0700 Subject: [PATCH 7/9] rm comments --- app/controllers/admin/cx_action_plans_controller.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/controllers/admin/cx_action_plans_controller.rb b/app/controllers/admin/cx_action_plans_controller.rb index 8f1ee7f71..d2dff6c4e 100644 --- a/app/controllers/admin/cx_action_plans_controller.rb +++ b/app/controllers/admin/cx_action_plans_controller.rb @@ -1,27 +1,22 @@ class Admin::CxActionPlansController < AdminController before_action :set_cx_action_plan, only: %i[ show edit update destroy ] - # GET /cx_action_plans or /cx_action_plans.json def index @cx_action_plans = CxActionPlan.all end - # GET /cx_action_plans/1 or /cx_action_plans/1.json def show end - # GET /cx_action_plans/new def new @service_providers = ServiceProvider.all.includes(:organization).order('organizations.name', 'service_providers.name') @cx_action_plan = CxActionPlan.new end - # GET /cx_action_plans/1/edit def edit @service_providers = ServiceProvider.all.includes(:organization).order('organizations.name', 'service_providers.name') end - # POST /cx_action_plans or /cx_action_plans.json def create @cx_action_plan = CxActionPlan.new(cx_action_plan_params) @@ -36,7 +31,6 @@ def create end end - # PATCH/PUT /cx_action_plans/1 or /cx_action_plans/1.json def update respond_to do |format| if @cx_action_plan.update(cx_action_plan_params) @@ -49,7 +43,6 @@ def update end end - # DELETE /cx_action_plans/1 or /cx_action_plans/1.json def destroy @cx_action_plan.destroy @@ -60,12 +53,10 @@ def destroy end private - # Use callbacks to share common setup or constraints between actions. def set_cx_action_plan @cx_action_plan = CxActionPlan.find(params[:id]) end - # Only allow a list of trusted parameters through. def cx_action_plan_params params.require(:cx_action_plan).permit(:service_provider_id, :year, :delivered_current_year, :to_deliver_next_year) end From ef002a141a28a5e7f9107b3cd034e57666052b20 Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 20:59:41 -0700 Subject: [PATCH 8/9] title row --- app/models/cscrm_data_collection2.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/cscrm_data_collection2.rb b/app/models/cscrm_data_collection2.rb index 415266f09..a669fd341 100644 --- a/app/models/cscrm_data_collection2.rb +++ b/app/models/cscrm_data_collection2.rb @@ -609,6 +609,7 @@ def self.to_csv "documented_methodology", "documented_methodology_comments", "conducts_scra_for_prioritized_products_and_services", + "conducts_scra_for_prioritized_products_and_services_value", "conducts_scra_for_prioritized_products_and_services_translated_value", "conducts_scra_for_prioritized_products_and_services_comments", "personnel_required_to_complete_training_value", From 2e96aa1aacd4ae7b310c0a86119ce1896f7f789c Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Wed, 27 Sep 2023 21:09:20 -0700 Subject: [PATCH 9/9] default spec --- .../{ => admin}/cx_action_plans_spec.rb | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) rename spec/requests/{ => admin}/cx_action_plans_spec.rb (81%) diff --git a/spec/requests/cx_action_plans_spec.rb b/spec/requests/admin/cx_action_plans_spec.rb similarity index 81% rename from spec/requests/cx_action_plans_spec.rb rename to spec/requests/admin/cx_action_plans_spec.rb index 587952eb8..a4ee7f117 100644 --- a/spec/requests/cx_action_plans_spec.rb +++ b/spec/requests/admin/cx_action_plans_spec.rb @@ -12,8 +12,8 @@ # of tools you can use to make these specs even more expressive, but we're # sticking to rails and rspec-rails APIs to keep things simple and stable. -RSpec.describe "/cx_action_plans", type: :request do - +RSpec.describe "/admin/cx_action_plans", type: :request do + # This should return the minimal set of attributes required to create a valid # CxActionPlan. As you add validations to CxActionPlan, be sure to # adjust the attributes here as well. @@ -28,7 +28,7 @@ describe "GET /index" do it "renders a successful response" do CxActionPlan.create! valid_attributes - get cx_action_plans_url + get admin_cx_action_plans_url expect(response).to be_successful end end @@ -36,14 +36,20 @@ describe "GET /show" do it "renders a successful response" do cx_action_plan = CxActionPlan.create! valid_attributes - get cx_action_plan_url(cx_action_plan) + get admin_cx_action_plan_url(cx_action_plan) expect(response).to be_successful end end describe "GET /new" do + let(:user) { FactoryBot.create(:user, :admin) } + + before do + sign_in(user) + end + it "renders a successful response" do - get new_cx_action_plan_url + get new_admin_cx_action_plan_url expect(response).to be_successful end end @@ -51,7 +57,7 @@ describe "GET /edit" do it "renders a successful response" do cx_action_plan = CxActionPlan.create! valid_attributes - get edit_cx_action_plan_url(cx_action_plan) + get edit_admin_cx_action_plan_url(cx_action_plan) expect(response).to be_successful end end @@ -60,12 +66,12 @@ context "with valid parameters" do it "creates a new CxActionPlan" do expect { - post cx_action_plans_url, params: { cx_action_plan: valid_attributes } + post admin_cx_action_plans_url, params: { cx_action_plan: valid_attributes } }.to change(CxActionPlan, :count).by(1) end it "redirects to the created cx_action_plan" do - post cx_action_plans_url, params: { cx_action_plan: valid_attributes } + post admin_cx_action_plans_url, params: { cx_action_plan: valid_attributes } expect(response).to redirect_to(cx_action_plan_url(CxActionPlan.last)) end end @@ -73,16 +79,16 @@ context "with invalid parameters" do it "does not create a new CxActionPlan" do expect { - post cx_action_plans_url, params: { cx_action_plan: invalid_attributes } + post admin_cx_action_plans_url, params: { cx_action_plan: invalid_attributes } }.to change(CxActionPlan, :count).by(0) end - + it "renders a response with 422 status (i.e. to display the 'new' template)" do - post cx_action_plans_url, params: { cx_action_plan: invalid_attributes } + post admin_cx_action_plans_url, params: { cx_action_plan: invalid_attributes } expect(response).to have_http_status(:unprocessable_entity) end - + end end @@ -94,27 +100,27 @@ it "updates the requested cx_action_plan" do cx_action_plan = CxActionPlan.create! valid_attributes - patch cx_action_plan_url(cx_action_plan), params: { cx_action_plan: new_attributes } + patch admin_cx_action_plan_url(cx_action_plan), params: { cx_action_plan: new_attributes } cx_action_plan.reload skip("Add assertions for updated state") end it "redirects to the cx_action_plan" do cx_action_plan = CxActionPlan.create! valid_attributes - patch cx_action_plan_url(cx_action_plan), params: { cx_action_plan: new_attributes } + patch admin_cx_action_plan_url(cx_action_plan), params: { cx_action_plan: new_attributes } cx_action_plan.reload expect(response).to redirect_to(cx_action_plan_url(cx_action_plan)) end end context "with invalid parameters" do - + it "renders a response with 422 status (i.e. to display the 'edit' template)" do cx_action_plan = CxActionPlan.create! valid_attributes patch cx_action_plan_url(cx_action_plan), params: { cx_action_plan: invalid_attributes } expect(response).to have_http_status(:unprocessable_entity) end - + end end