- <% if publication.author_first_name.empty? && publication.author_last_name.empty? %>
+ <% if publication.author_first_name.empty? && publication.author_last_name.empty? %>
<% publication.author_first_name << '' %>
<% publication.author_last_name << '' %>
- <% end %>
+ <% end %>
- <% publication.author_first_name.each_with_index do |_, index| %>
-
-<%= button_tag "Add Author", type: "button", id: "add_author_btn", onclick: "addAuthor('#{name}')", class: "btn btn-primary" %>
+
+<%= button_tag "Add " + author_or_artist_label, type: "button", id: "add_author_btn", onclick: "addAuthor('#{name}')", class: "btn btn-primary" %>
diff --git a/app/views/partials/_publications_colleges.html.erb b/app/views/partials/_publications_colleges.html.erb
index 7aee9b7c..9d6a9442 100644
--- a/app/views/partials/_publications_colleges.html.erb
+++ b/app/views/partials/_publications_colleges.html.erb
@@ -1,13 +1,16 @@
<%= form.label :other_college, 'Other College' %>
diff --git a/spec/features/author_management/adding_authors_spec.rb b/spec/features/author_management/adding_authors_spec.rb
new file mode 100644
index 00000000..e89a4993
--- /dev/null
+++ b/spec/features/author_management/adding_authors_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Adding Authors', :feature, js: true do
+ let(:submitter) { FactoryBot.create(:submitter) }
+
+ before do
+ create_submitter(submitter)
+ end
+
+ it 'adds authors to a new publication' do
+ visit new_other_publication_path
+ expect(page).to have_current_path(Rails.application.routes.url_helpers.new_other_publication_path)
+
+ # Verify blank input fields for author's first name and last name
+ # to be present on page load
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 1)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 1)
+ check_field_values_by_index(0, '', '')
+
+ # Fill out the fields with the first author's name
+ first_name_fields.last.set('First0')
+ last_name_fields.last.set('Last0')
+
+ # Click "Add Author" and verify new and old fields
+ click_on 'Add Author'
+
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 2)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 2)
+
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, '', '')
+
+ # Fill in second author's name
+ first_name_fields.last.set('First1')
+ last_name_fields.last.set('Last1')
+
+ # Click "Add Author" again
+ click_on 'Add Author'
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 3)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 3)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, '', '')
+
+ # Fill in third author's name
+ first_name_fields.last.set('First2')
+ last_name_fields.last.set('Last2')
+
+ # Click "Add Author" again
+ click_on 'Add Author'
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 4)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 4)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+ check_field_values_by_index(3, '', '')
+
+ # Fill in fourth author's name
+ first_name_fields.last.set('First3')
+ last_name_fields.last.set('Last3')
+
+ # Fill in the rest of the fields
+ fill_in 'other_publication[work_title]', with: 'Title'
+ fill_in 'other_publication[other_title]', with: 'Subtitle'
+ fill_in 'other_publication[uc_department]', with: 'Department'
+ fill_in 'other_publication[publication_date]', with: 'Date'
+ fill_in 'other_publication[url]', with: 'URL'
+ fill_in 'other_publication[doi]', with: 'DOI'
+
+ # Click "Submit" and verify that we are redirected to the index page
+ # and that a success message is displayed
+ click_on 'Submit'
+ expect(page).to have_current_path(Rails.application.routes.url_helpers.publications_path)
+ expect(page).to have_text 'Other Publication was successfully created.'
+
+ # Click on the hyperlink on the id of the newly created publication
+ # and verify that the author names are correct
+ click_on OtherPublication.last.work_title.to_s
+ expect(page).to have_current_path(Rails.application.routes.url_helpers.other_publication_path(OtherPublication.last.id))
+ expect(page).to have_text 'First0 Last0'
+ expect(page).to have_text 'First1 Last1'
+ expect(page).to have_text 'First2 Last2'
+ expect(page).to have_text 'First3 Last3'
+ end
+
+ it 'adds authors to an existing publication' do
+ # Create a new publication. Adding author functionality for a new publication
+ # is tested in the previous test.
+ create_other_publication # Defined in spec/support/helpers/feature_spec_helpers/author_management.rb
+
+ # Click on the hyperlink on the id of the newly created publication
+ # and verify that the author names are correct
+ click_on OtherPublication.last.work_title.to_s
+ expect(page).to have_current_path(Rails.application.routes.url_helpers.other_publication_path(OtherPublication.last.id))
+ expect(page).to have_selector('td', text: 'First0 Last0') # Information is in table format on the show page
+
+ # Click on "Edit" and verify that we are redirected to the edit page
+ # and that the author names are correct
+ click_on 'Edit'
+ expect(page).to have_current_path(Rails.application.routes.url_helpers.edit_other_publication_path(OtherPublication.last.id))
+ check_field_values_by_index(0, 'First0', 'Last0')
+
+ # Add another author and verify that the author names are correct
+ click_on 'Add Author'
+ first_name_fields.last.set('First1')
+ last_name_fields.last.set('Last1')
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+
+ # Add a third author and verify that the author names are correct
+ click_on 'Add Author'
+ first_name_fields.last.set('First2')
+ last_name_fields.last.set('Last2')
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+
+ # Save the changes and verify that we are redirected to the show page
+ # and that the author names are correct
+ click_on 'Submit'
+ expect(page).to have_current_path(Rails.application.routes.url_helpers.other_publication_path(OtherPublication.last.id))
+ expect(page).to have_text 'Other Publication was successfully updated.'
+ expect(page).to have_selector('td', text: 'First0 Last0, First1 Last1, First2 Last2') # Information is in table format on the show page
+ end
+end
diff --git a/spec/features/author_management/author_vs_artist_labels_spec.rb b/spec/features/author_management/author_vs_artist_labels_spec.rb
new file mode 100644
index 00000000..e341c50e
--- /dev/null
+++ b/spec/features/author_management/author_vs_artist_labels_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+# When adding an author or artist for a publication, the page should
+# correctly display the title of the author or artist as "Author" or "Artist".
+# This is a feature test that checks the behavior of the page when adding
+# and deleting authors and artists.
+describe 'Author and Artist labels', :feature, js: true do
+ let(:submitter) { FactoryBot.create(:submitter) }
+
+ before do
+ create_submitter(submitter)
+ end
+
+ it 'uses the title of Author for new books' do
+ visit new_book_path
+ expect(page).to have_content('Add Author')
+ expect(page).not_to have_content('Add Artist')
+ first_name_fields.last.set('First0')
+ last_name_fields.last.set('Last0')
+ click_on 'Add Author'
+ first_name_fields.last.set('First1')
+ last_name_fields.last.set('Last1')
+ click_on 'Add Author'
+ expect(page).to have_selector('button', text: 'Remove Author', count: 2)
+ expect(page).not_to have_selector('button', text: 'Remove Artist')
+ first('button', text: 'Remove Author').click
+ expect(page).to have_selector('button', text: 'Remove Author', count: 1)
+ expect(page).not_to have_content('Artist')
+ end
+
+ it 'has the title of Artist for new artworks' do
+ visit new_artwork_path
+ expect(page).to have_content('Add Artist')
+ expect(page).not_to have_content('Add Author')
+ first_name_fields.last.set('First0')
+ last_name_fields.last.set('Last0')
+ click_on 'Add Artist'
+ first_name_fields.last.set('First1')
+ last_name_fields.last.set('Last1')
+ click_on 'Add Artist'
+ expect(page).to have_selector('button', text: 'Remove Artist', count: 2)
+ expect(page).not_to have_selector('button', text: 'Remove Author')
+ first('button', text: 'Remove Artist').click
+ expect(page).to have_selector('button', text: 'Remove Artist', count: 1)
+ expect(page).not_to have_content('Author')
+ end
+end
diff --git a/spec/features/author_management/removing_authors_spec.rb b/spec/features/author_management/removing_authors_spec.rb
new file mode 100644
index 00000000..de4ec0de
--- /dev/null
+++ b/spec/features/author_management/removing_authors_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Removing Authors', :feature, js: true do
+ let(:submitter) { FactoryBot.create(:submitter) }
+
+ before do
+ create_submitter(submitter)
+ create_other_publication
+ add_three_more_authors_to_publication(OtherPublication.last)
+ visit edit_other_publication_path(OtherPublication.last)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 4)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 4)
+ end
+
+ it 'removes the second author from the publication' do
+ # Remove the second author
+ remove_author_at_index(1)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 3)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 3)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First2', 'Last2')
+ check_field_values_by_index(2, 'First3', 'Last3')
+
+ # Remove the second author again (should be "First2")
+ remove_author_at_index(1)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 2)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 2)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First3', 'Last3')
+
+ # Remove the second author again (should be "First3")
+ remove_author_at_index(1)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 1)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 1)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ end
+
+ it 'removes the last author from the publication' do
+ remove_author_at_index(3)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 3)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 3)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+
+ remove_author_at_index(2)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 2)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 2)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+
+ remove_author_at_index(1)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 1)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 1)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ end
+
+ it 'does not have a Remove Author button for the first author' do
+ expect(first_author_element).not_to have_selector('button', text: 'Remove Author')
+ end
+end
diff --git a/spec/features/author_management/updating_authors_spec.rb b/spec/features/author_management/updating_authors_spec.rb
new file mode 100644
index 00000000..7037e7d2
--- /dev/null
+++ b/spec/features/author_management/updating_authors_spec.rb
@@ -0,0 +1,118 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Adding Authors', :feature, js: true do
+ let(:submitter) { FactoryBot.create(:submitter) }
+
+ before do
+ create_submitter(submitter)
+ end
+
+ it "allows the user to update the first author's information" do
+ create_other_publication
+ add_three_more_authors_to_publication(OtherPublication.last)
+ visit edit_other_publication_path(OtherPublication.last)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 4)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 4)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+ check_field_values_by_index(3, 'First3', 'Last3')
+
+ # Update the first author's name
+ first_name_fields.first.set('First0modified')
+ last_name_fields.first.set('Last0modified')
+ click_on 'Submit'
+
+ expect(page).to have_current_path(other_publication_path(OtherPublication.last))
+ expect(page).to have_content('First0modified')
+ expect(page).to have_content('Last0modified')
+ expect(page).to have_content('First1')
+ expect(page).to have_content('Last1')
+ expect(page).to have_content('First2')
+ expect(page).to have_content('Last2')
+ expect(page).to have_content('First3')
+ expect(page).to have_content('Last3')
+ end
+
+ it "allows the user to update the second author's information" do
+ create_other_publication
+ add_three_more_authors_to_publication(OtherPublication.last)
+ visit edit_other_publication_path(OtherPublication.last)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 4)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 4)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+ check_field_values_by_index(3, 'First3', 'Last3')
+
+ # Update the second author's name
+ first_name_fields[1].set('First1modified')
+ last_name_fields[1].set('Last1modified')
+ click_on 'Submit'
+
+ expect(page).to have_current_path(other_publication_path(OtherPublication.last))
+ expect(page).to have_content('First0')
+ expect(page).to have_content('Last0')
+ expect(page).to have_content('First1modified')
+ expect(page).to have_content('Last1modified')
+ expect(page).to have_content('First2')
+ expect(page).to have_content('Last2')
+ expect(page).to have_content('First3')
+ expect(page).to have_content('Last3')
+ end
+
+ it "allows the user to update the last author's information" do
+ create_other_publication
+ add_three_more_authors_to_publication(OtherPublication.last)
+ visit edit_other_publication_path(OtherPublication.last)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 4)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 4)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+ check_field_values_by_index(3, 'First3', 'Last3')
+
+ # Update the last author's name
+ first_name_fields.last.set('First3modified')
+ last_name_fields.last.set('Last3modified')
+ click_on 'Submit'
+
+ expect(page).to have_current_path(other_publication_path(OtherPublication.last))
+ expect(page).to have_content('First0')
+ expect(page).to have_content('Last0')
+ expect(page).to have_content('First1')
+ expect(page).to have_content('Last1')
+ expect(page).to have_content('First2')
+ expect(page).to have_content('Last2')
+ expect(page).to have_content('First3modified')
+ expect(page).to have_content('Last3modified')
+ end
+
+ it 'persists the changes when refreshing the page' do
+ create_other_publication
+ add_three_more_authors_to_publication(OtherPublication.last)
+ visit edit_other_publication_path(OtherPublication.last)
+ expect(page).to have_selector("input[name='other_publication[author_first_name][]']", count: 4)
+ expect(page).to have_selector("input[name='other_publication[author_last_name][]']", count: 4)
+ check_field_values_by_index(0, 'First0', 'Last0')
+ check_field_values_by_index(1, 'First1', 'Last1')
+ check_field_values_by_index(2, 'First2', 'Last2')
+ check_field_values_by_index(3, 'First3', 'Last3')
+
+ # Update the first author's name
+ first_name_fields.first.set('First0modified')
+ last_name_fields.first.set('Last0modified')
+ first_name_fields[1].set('First1modified')
+ last_name_fields[1].set('Last1modified')
+ first_name_fields[2].set('First2modified')
+ last_name_fields[2].set('Last2modified')
+ first_name_fields.last.set('First3modified')
+ last_name_fields.last.set('Last3modified')
+ click_on 'Submit'
+
+ page.driver.browser.navigate.refresh
+ expect(page).to have_text('First0modified Last0modified, First1modified Last1modified, First2modified Last2modified, First3modified Last3modified')
+ end
+end
diff --git a/spec/features/create_artwork_spec.rb b/spec/features/create_artwork_spec.rb
index bee8bc5b..82b9dd0f 100644
--- a/spec/features/create_artwork_spec.rb
+++ b/spec/features/create_artwork_spec.rb
@@ -14,7 +14,7 @@
# New artwork Page
expect(page).to have_current_path(Rails.application.routes.url_helpers.new_artwork_path)
(0..artwork.author_first_name.count - 1).each do |i|
- click_on('Add Author') if i != 0
+ click_on('Add Artist') if i != 0
all(:xpath, "//input[@name='artwork[author_first_name][]']").last.set(artwork.author_first_name[i])
all(:xpath, "//input[@name='artwork[author_last_name][]']").last.set(artwork.author_last_name[i])
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 84ff5fd6..418d45ae 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -72,6 +72,9 @@
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
+
+ # Include helpers for feature tests
+ config.include FeatureSpecHelpers::AuthorManagement, type: :feature
end
def create_submitter(submitter)
diff --git a/spec/support/helpers/feature_spec_helpers/author_management.rb b/spec/support/helpers/feature_spec_helpers/author_management.rb
new file mode 100644
index 00000000..e802e5d1
--- /dev/null
+++ b/spec/support/helpers/feature_spec_helpers/author_management.rb
@@ -0,0 +1,115 @@
+# frozen_string_literal: true
+
+module FeatureSpecHelpers
+ # AuthorManagement provides helper methods for managing author fields in feature tests.
+ # It includes functionality to add, remove, and verify authors in a publication context,
+ # specifically catering to dynamic web page interactions with Capybara.
+ # Methods within this module handle tasks like removing authors at a specific index,
+ # checking field values, and finding parent elements in the DOM structure.
+ module AuthorManagement
+ def remove_author_at_index(index)
+ return if index.zero? # The first author cannot be removed
+ return unless valid_index?(index)
+
+ # Find the element at the given index
+ # (index + 1) is used because nth-child is 1-indexed
+ author_to_remove = find("#author_group > :nth-child(#{index + 1})")
+ return unless author_to_remove
+
+ # Find the remove button in the author_to_remove element and click it
+ remove_button = author_to_remove.find('button', text: 'Remove Author', match: :first)
+ remove_button.click
+ rescue Capybara::ElementNotFound => e
+ raise "Remove Author button could not be found: #{e.message}"
+ end
+
+ def check_field_values_by_index(index, expected_first_name, expected_last_name)
+ return unless valid_index?(index)
+
+ verify_field_value(
+ fields: first_name_fields,
+ index:,
+ expected_value: expected_first_name,
+ field_name: 'First name'
+ )
+
+ verify_field_value(
+ fields: last_name_fields,
+ index:,
+ expected_value: expected_last_name,
+ field_name: 'Last name'
+ )
+ end
+
+ # Assuming authors are direct children of #author_group
+ # This method finds the first author element
+ def first_author_element
+ find('#author_group > :first-child')
+ end
+
+ private
+
+ # Returns the collection of author first name fields.
+ # @return [Array] The collection of author first name fields.
+ def first_name_fields
+ all("input[name$='[author_first_name][]']", wait: Capybara.default_max_wait_time)
+ end
+
+ # Returns the collection of author last name fields.
+ # @return [Array] The collection of author last name fields.
+ def last_name_fields
+ all("input[name$='[author_last_name][]']", wait: Capybara.default_max_wait_time)
+ end
+
+ # Validates if the provided index is within the range of existing author fields.
+ # @param [Integer] index - The index to validate.
+ # @return [Boolean] True if the index is valid, false otherwise.
+ def valid_index?(index)
+ index.between?(0, [first_name_fields.size, last_name_fields.size].min - 1)
+ end
+
+ # Verifies the value of a field against the expected value.
+ # @param fields: [Array] The collection of fields to verify.
+ # @param index: [Integer] The index of the field to check.
+ # @param expected_value: [String] The expected value of the field.
+ # @param field_name: [String] The name of the field (for error messages).
+ def verify_field_value(fields:, index:, expected_value:, field_name:)
+ field = fields[index]
+ actual_value = field.value
+ error_message = "#{field_name} at index #{index} does not match"
+ expect(actual_value).to eq(expected_value), error_message
+ end
+
+ # navigates to the new other publication page and fills out the form.
+ def create_other_publication
+ visit new_other_publication_path
+
+ # Fill out the fields with the first author's name
+ first_name_fields.last.set('First0')
+ last_name_fields.last.set('Last0')
+
+ # Fill in the rest of the fields
+ fill_in 'other_publication[work_title]', with: 'Title'
+ fill_in 'other_publication[other_title]', with: 'Subtitle'
+ fill_in 'other_publication[uc_department]', with: 'Department'
+ fill_in 'other_publication[publication_date]', with: 'Date'
+ fill_in 'other_publication[url]', with: 'URL'
+ fill_in 'other_publication[doi]', with: 'DOI'
+
+ click_on 'Submit'
+ end
+
+ # Adds three more authors to a publication. Valid only within
+ # the context of a feature test with an already created publication.
+ def add_three_more_authors_to_publication(publication)
+ visit edit_other_publication_path(publication)
+ 3.times do
+ current_count = first_name_fields.size
+ click_on 'Add Author'
+ first_name_fields.last.set("First#{current_count}")
+ last_name_fields.last.set("Last#{current_count}")
+ end
+ click_on 'Submit'
+ end
+ end
+end