Skip to content
Merged
3 changes: 2 additions & 1 deletion app/dashboards/letter_dashboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class LetterDashboard < Administrate::BaseDashboard
letter_owner: Field::BelongsTo,
letter_publisher: Field::BelongsTo,
created_at: Field::DateTime,
updated_at: Field::DateTime
updated_at: Field::DateTime,
published: Field::Boolean
}.freeze

# COLLECTION_ATTRIBUTES
Expand Down
35 changes: 9 additions & 26 deletions spec/requests/admin/letters_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,62 @@
require 'rails_helper'

RSpec.describe 'Admin::Letters' do
# LetterDashboard::SHOW_PAGE_ATTRIBUTES includes :published, but ATTRIBUTE_TYPES has
# no :published entry. This breaks the show page directly (show.html.erb iterates
# SHOW_PAGE_ATTRIBUTES), and also breaks index: Administrate's own
# sanitized_order_params helper (called from the custom _collection.html.erb, used
# for both index and show) always calls dashboard#item_associations, which
# unconditionally reads show_page_attributes regardless of which page is asking.
def published_not_in_attribute_types
'known bug: LetterDashboard::SHOW_PAGE_ATTRIBUTES includes :published, which has no ' \
'entry in ATTRIBUTE_TYPES - raises RuntimeError via Administrate::BaseDashboard#' \
'attribute_type_for, reached from show.html.erb directly and from index.html.erb via ' \
'sanitized_order_params -> #item_associations (always uses show_page_attributes)'
end

describe 'GET index' do
it 'requires authentication' do
get admin_letters_path
expect(response).to have_http_status(:unauthorized)
end

it 'renders successfully when authenticated' do
skip(published_not_in_attribute_types)
create(:letter)
get admin_letters_path, headers: admin_auth_headers
expect(response).to have_http_status(:ok)
end

# LetterDashboard's index table renders COLLECTION_ATTRIBUTES (date/recipients/
# entities) as columns, not the display_resource string - each row's link to
# admin_letter_path(letter) is what reliably identifies which letter a row is.
it 'includes letters within the given start_date/end_date range' do
skip(published_not_in_attribute_types)
in_range = create(:letter, date: DateTime.new(1960, 6, 1), code: 'IN-RANGE')
get admin_letters_path(start_date: '1960-01-01', end_date: '1960-12-31'), headers: admin_auth_headers
expect(response.body).to include("Letter ##{in_range.legacy_pk}")
expect(response.body).to include(admin_letter_path(in_range))
end

it 'excludes dated letters outside the given start_date/end_date range' do
skip(published_not_in_attribute_types)
out_of_range = create(:letter, date: DateTime.new(1900, 1, 1), code: 'OUT-OF-RANGE')
get admin_letters_path(start_date: '1960-01-01', end_date: '1960-12-31'), headers: admin_auth_headers
expect(response.body).not_to include("Letter ##{out_of_range.legacy_pk}")
expect(response.body).not_to include(admin_letter_path(out_of_range))
end

it 'always includes undated letters, regardless of the date range' do
skip(published_not_in_attribute_types)
undated = create(:letter, date: nil, code: 'UNDATED')
get admin_letters_path(start_date: '1960-01-01', end_date: '1960-12-31'), headers: admin_auth_headers
expect(response.body).to include("Letter ##{undated.legacy_pk}")
expect(response.body).to include(admin_letter_path(undated))
end

it 'restores start_date/end_date from the referer when the request omits them' do
skip(published_not_in_attribute_types)
in_range = create(:letter, date: DateTime.new(1960, 6, 1), code: 'IN-RANGE')
out_of_range = create(:letter, date: DateTime.new(1900, 1, 1), code: 'OUT-OF-RANGE')
referer = "#{admin_letters_url}?start_date=1960-01-01&end_date=1960-12-31"

get admin_letters_path, headers: admin_auth_headers.merge('HTTP_REFERER' => referer)

expect(response.body).to include("Letter ##{in_range.legacy_pk}")
expect(response.body).not_to include("Letter ##{out_of_range.legacy_pk}")
expect(response.body).to include(admin_letter_path(in_range))
expect(response.body).not_to include(admin_letter_path(out_of_range))
end

it 'ignores the referer when it is not an admin/letters URL' do
skip(published_not_in_attribute_types)
out_of_range = create(:letter, date: DateTime.new(1900, 1, 1), code: 'OUT-OF-RANGE')
referer = "#{admin_entities_url}?start_date=1960-01-01&end_date=1960-12-31"

get admin_letters_path, headers: admin_auth_headers.merge('HTTP_REFERER' => referer)

expect(response.body).to include("Letter ##{out_of_range.legacy_pk}")
expect(response.body).to include(admin_letter_path(out_of_range))
end
end

describe 'GET show' do
it 'renders successfully when authenticated' do
skip(published_not_in_attribute_types)
letter = create(:letter)
get admin_letter_path(letter), headers: admin_auth_headers
expect(response).to have_http_status(:ok)
Expand Down
Loading