From 7cb0a4135b8d67acf71fb64badd4bff5de82ec55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 6 Jul 2020 19:53:24 +0200 Subject: [PATCH] Extract component for admin officers table This way we can remove duplication and simplify the code in the view. Note we're not using the "within" method in the tests to access a row, because it doesn't seem to work in components tests when passing the `text:` option. --- .../poll/officers/officers_component.html.erb | 36 ++++++++++++++++++ .../admin/poll/officers/officers_component.rb | 18 +++++++++ .../admin/poll/officers/_officer.html.erb | 34 +---------------- app/views/admin/poll/officers/index.html.erb | 38 +------------------ .../poll/officers/officers_component_spec.rb | 35 +++++++++++++++++ 5 files changed, 91 insertions(+), 70 deletions(-) create mode 100644 app/components/admin/poll/officers/officers_component.html.erb create mode 100644 app/components/admin/poll/officers/officers_component.rb create mode 100644 spec/components/admin/poll/officers/officers_component_spec.rb diff --git a/app/components/admin/poll/officers/officers_component.html.erb b/app/components/admin/poll/officers/officers_component.html.erb new file mode 100644 index 000000000..baf93a50f --- /dev/null +++ b/app/components/admin/poll/officers/officers_component.html.erb @@ -0,0 +1,36 @@ +<%= tag.table options do %> + + + <%= t("admin.poll_officers.officer.name") %> + <%= t("admin.poll_officers.officer.email") %> + <%= t("admin.actions.actions") %> + + + + <% officers.each do |officer| %> + + + <%= officer.name %> + + + <%= officer.email %> + + + <% if officer.persisted? %> + <%= render Admin::TableActionsComponent.new(officer, + actions: [:destroy], + destroy_text: t("admin.poll_officers.officer.delete") + ) %> + <% else %> + <%= render Admin::TableActionsComponent.new(actions: []) do |actions| %> + <%= actions.link_to t("admin.poll_officers.officer.add"), + add_user_path(officer), + method: :post, + class: "button success expanded" %> + <% end %> + <% end %> + + + <% end %> + +<% end %> diff --git a/app/components/admin/poll/officers/officers_component.rb b/app/components/admin/poll/officers/officers_component.rb new file mode 100644 index 000000000..c9972a641 --- /dev/null +++ b/app/components/admin/poll/officers/officers_component.rb @@ -0,0 +1,18 @@ +class Admin::Poll::Officers::OfficersComponent < ApplicationComponent + attr_reader :officers, :options + + def initialize(officers, **options) + @officers = officers + @options = options + end + + private + + def add_user_path(officer) + { + controller: "admin/poll/officers", + action: :create, + user_id: officer.user_id + } + end +end diff --git a/app/views/admin/poll/officers/_officer.html.erb b/app/views/admin/poll/officers/_officer.html.erb index dd3202e7d..e026254b0 100644 --- a/app/views/admin/poll/officers/_officer.html.erb +++ b/app/views/admin/poll/officers/_officer.html.erb @@ -1,33 +1 @@ - - - - - - - - - - - - - - - -
<%= t("admin.poll_officers.officer.name") %><%= t("admin.poll_officers.officer.email") %><%= t("admin.actions.actions") %>
- <%= officer.name %> - - <%= officer.email %> - - <% if officer.persisted? %> - <%= render Admin::TableActionsComponent.new(officer, - actions: [:destroy], - destroy_text: t("admin.poll_officers.officer.delete") - ) %> - <% else %> - <%= render Admin::TableActionsComponent.new(actions: []) do |actions| %> - <%= actions.link_to t("admin.poll_officers.officer.add"), { controller: "admin/poll/officers", action: :create, user_id: officer.user_id }, - method: :post, - class: "button success expanded" %> - <% end %> - <% end %> -
+<%= render Admin::Poll::Officers::OfficersComponent.new([officer]) %> diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index 1e2b4e144..c6b5caf74 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -11,43 +11,7 @@ <% if @officers.any? %> - - - - - - - - - - <% @officers.each do |officer| %> - - - - - - <% end %> - -
<%= t("admin.poll_officers.officer.name") %><%= t("admin.poll_officers.officer.email") %><%= t("admin.actions.actions") %>
- <%= officer.name %> - - <%= officer.email %> - - <% if officer.persisted? %> - <%= render Admin::TableActionsComponent.new(officer, - actions: [:destroy], - destroy_text: t("admin.poll_officers.officer.delete") - ) %> - <% else %> - <%= render Admin::TableActionsComponent.new(actions: []) do |actions| %> - <%= actions.link_to t("admin.poll_officers.officer.add"), - { controller: "admin/poll/officers", action: :create, - user_id: officer.user_id }, - method: :post, - class: "button success expanded" %> - <% end %> - <% end %> -
+ <%= render Admin::Poll::Officers::OfficersComponent.new(@officers, id: "officers") %> <%= paginate @officers %> <% end %> diff --git a/spec/components/admin/poll/officers/officers_component_spec.rb b/spec/components/admin/poll/officers/officers_component_spec.rb new file mode 100644 index 000000000..5d8e9a79a --- /dev/null +++ b/spec/components/admin/poll/officers/officers_component_spec.rb @@ -0,0 +1,35 @@ +require "rails_helper" + +describe Admin::Poll::Officers::OfficersComponent, type: :component do + let(:existing_officer) { create(:poll_officer, name: "Old officer") } + let(:new_officer) { build(:poll_officer, name: "New officer") } + let(:officers) { [existing_officer, new_officer] } + let(:component) { Admin::Poll::Officers::OfficersComponent.new(officers) } + + it "renders as many rows as officers" do + within "tbody" do + expect(page).to have_css "tr", count: 2 + expect(page).to have_css "a", count: 2 + end + end + + it "renders link to destroy for existing officers" do + render_inline component + row = page.find("tr", text: "Old officer") + + expect(row).to have_css "a[data-method='delete']", text: "Delete" + end + + it "renders link to add for new officers" do + render_inline component + row = page.find("tr", text: "New officer") + + expect(row).to have_css "a[data-method='post']", text: "Add" + end + + it "accepts table options" do + render_inline Admin::Poll::Officers::OfficersComponent.new(officers, class: "my-officers-table") + + expect(page).to have_css "table.my-officers-table" + end +end