<%= ts("Created at %{date_created} and updated at %{date_updated}", :date_created => archive_faq.created_at, :date_updated => archive_faq.updated_at) %>
@@ -8,21 +8,24 @@
<% if @archive_faq.slug == "search-and-browse" %>
- <%= ts("Our search engine has recently been updated, and this FAQ is based on our old version. We're working on bringing you more up-to-date information, but in the meantime, you can find out more in our %{elasticsearch_post}!", elasticsearch_post: link_to(ts("news post announcing the search and filter updates"), admin_post_path(10575))).html_safe %>
+ <%= t(".elasticsearch_update_notice_html", elasticsearch_news_link: link_to(t(".elasticsearch_news"), admin_post_path(10_575))) %>
<% end %>
- <% if logged_in_as_admin? %>
+ <% if policy(ArchiveFaq).translation_access? %>
- <% if logged_in_as_admin? %>
+ <% if policy(:wrangling).edit? %>
Updated: <%=h @wrangling_guideline.updated_at %> | <%= link_to ts('Edit'), edit_wrangling_guideline_path(@wrangling_guideline) %>
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index 853290df404..0646f44702a 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -149,8 +149,6 @@ ignore_missing:
- successfully_sent # should be feedbacks.create.successfully_sent
# Files: app/controllers/languages_controller.rb and app/controllers/locales_controller.rb
- successfully_added # should be languages.create.successfully_added and locales.create.successfully_added
- # Files: app/views/admin/_admin_nav.html.erb and app/views/admin_posts/show.html.erb
- - admin.admin_nav.delete
# File: app/views/admin/admin_invitations/find.html.erb
- admin.admin_invitations.find.find_email
- admin.admin_invitations.find.find_token
diff --git a/config/locales/controllers/en.yml b/config/locales/controllers/en.yml
index 647293d6d83..ea56888e5be 100644
--- a/config/locales/controllers/en.yml
+++ b/config/locales/controllers/en.yml
@@ -1,6 +1,9 @@
---
en:
admin:
+ access:
+ action_access_denied: Sorry, only an authorized admin can do that.
+ page_access_denied: Sorry, only an authorized admin can access the page you were trying to reach.
admin_invitations:
find:
user_not_found: No results were found. Try another search.
@@ -11,6 +14,14 @@ en:
admin_users:
destroy_user_creations:
success: All creations by user %{login} have been deleted.
+ archive_faqs:
+ create:
+ success: Archive FAQ was successfully created.
+ default_locale_only: Sorry, this action is only available for English FAQs.
+ update:
+ success: Archive FAQ was successfully updated.
+ update_positions:
+ success: Archive FAQs order was successfully updated.
blocked:
users:
create:
@@ -99,6 +110,13 @@ en:
muted: You have muted the user %{name}.
destroy:
unmuted: You have unmuted the user %{name}.
+ questions:
+ not_found: Sorry, we couldn't find the FAQ you were looking for.
+ update_positions:
+ success: Question order has been successfully updated.
+ tag_wranglings:
+ index:
+ page_subtitle: fandoms
users:
passwords:
create:
@@ -120,3 +138,8 @@ en:
works:
drafts:
page_title: "%{username} - Drafts"
+ wrangling_guidelines:
+ create: Wrangling Guideline was successfully created.
+ delete: Wrangling Guideline was successfully deleted.
+ reorder: Wrangling Guidelines order was successfully updated.
+ update: Wrangling Guideline was successfully updated.
diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml
index f33c121bb78..98566ffcc69 100644
--- a/config/locales/views/en.yml
+++ b/config/locales/views/en.yml
@@ -91,6 +91,17 @@ en:
queue: Manage Queue
requests: Manage Requests
page_heading: Invite New Users
+ admin_nav:
+ ao3_news: AO3 News
+ archive_faq: Archive FAQ
+ faq:
+ reorder_questions: Reorder Questions
+ known_issues: Known Issues
+ landmark: Admin Navigation
+ news:
+ delete_post: Delete Post
+ post_ao3_news: Post AO3 News
+ wrangling_guidelines: Wrangling Guidelines
admin_options:
delete:
bookmark: Delete Bookmark
@@ -376,6 +387,24 @@ en:
roles:
heading: 'Your admin roles:'
none: You currently have no admin roles assigned to you.
+ archive_faqs:
+ admin_index:
+ confirm_delete: Are you sure you want to delete this FAQ category?
+ created_updated_date: Created at %{date_created} and updated at %{date_updated}
+ delete: Delete
+ edit: Edit
+ manage_faqs: Manage Archive FAQs
+ new_faq_category: New FAQ Category
+ page_heading: Archive FAQ
+ reorder_faqs: Reorder FAQs
+ show: Show
+ show:
+ edit: Edit
+ elasticsearch_news: news post announcing the search and filter updates
+ elasticsearch_update_notice_html: Our search engine has recently been updated, and this FAQ is based on our old version. We're working on bringing you more up-to-date information, but in the meantime, you can find out more in our %{elasticsearch_news_link}!
+ no_category_entries: We're sorry, there are currently no entries in this category.
+ page_heading: Archive FAQ
+ screencast: 'Screencast:'
blocked:
block: Block
unblock: Unblock
@@ -1583,6 +1612,34 @@ en:
show:
last_wrangled_html: "%{wrangler_login} last wrangled at %{time}."
tags_wrangled_csv: Tags Wrangled (CSV)
+ tag_wranglings:
+ wrangler_dashboard:
+ characters_by_fandom: Characters by fandom (%{count})
+ fandoms_by_media: Fandoms by media (%{count})
+ freeforms_by_fandom: Freeforms by fandom (%{count})
+ new_tag: New Tag
+ relationships_by_fandom: Relationships by fandom (%{count})
+ search_tags: Search Tags
+ tag_type:
+ character: Characters
+ fandom: Fandoms
+ freeform: Freeforms
+ merger: Mergers
+ relationship: Relationships
+ subtag: SubTags
+ tag_type_and_count: "%{tag_type} (%{count})"
+ unsorted_tags: Unsorted Tags (%{count})
+ use_type:
+ bookmarks: Bookmarks
+ drafts: Drafts
+ external_works: External Works
+ private_bookmarks: Private Bookmarks
+ taggings_count: Taggings Count
+ works: Works
+ use_type_and_count: "%{use_type} (%{count})"
+ wranglers: Wranglers
+ wrangling_home: Wrangling Home
+ wrangling_tools: Wrangling Tools
tags:
index:
about:
@@ -1768,6 +1825,34 @@ en:
privacy_policy: Privacy Policy
tos: Terms of Service
welcome_html: Hi! It looks like you've just logged in to AO3 for the first time. For help getting started on AO3, check out some %{new_user_tips_link} or browse through %{our_faqs_link}.
+ sidebar:
+ catch:
+ history: History
+ inbox: Inbox (%{inbox_number})
+ statistics: Statistics
+ subscriptions: Subscriptions
+ choices:
+ all_pseuds: All Pseuds (%{pseud_number})
+ dashboard: Dashboard
+ preferences: Preferences
+ profile: Profile
+ pseud_switcher: Pseud Switcher
+ pseuds: Pseuds
+ skins: Skins
+ landmark:
+ catch: Catch
+ choices: Choices
+ pitch: Pitch
+ switch: Switch
+ pitch:
+ collections: Collections (%{coll_number})
+ drafts: Drafts (%{drafts_number})
+ switch:
+ assignments: Assignments (%{assignment_number})
+ claims: Claims (%{claim_number})
+ co_creator_requests: Co-Creator Requests (%{count})
+ related_works: Related Works (%{related_works_number})
+ sign_ups: Sign-ups (%{signup_number})
works:
adult:
caution: This work could have adult content. If you continue, you have agreed that you are willing to see such content.
diff --git a/features/admins/admin_post_faqs.feature b/features/admins/admin_post_faqs.feature
index e30edfdd34d..918c6b19435 100644
--- a/features/admins/admin_post_faqs.feature
+++ b/features/admins/admin_post_faqs.feature
@@ -3,11 +3,11 @@ Feature: Admin Actions to Post FAQs
As an an admin
I want to be able to manage the archive FAQ
- Scenario: Post and edit a FAQ
+ Scenario Outline: Authorized admin posts, edits and deletes a FAQ category
When I go to the archive_faqs page
Then I should see "Some commonly asked questions about the Archive are answered here"
And I should not see "Some text"
- When I am logged in as an admin
+ When I am logged in as a "" admin
And I follow "Admin Posts"
And I follow "Archive FAQ" within "#header"
Then I should not see "Some text"
@@ -17,7 +17,7 @@ Feature: Admin Actions to Post FAQs
And I fill in "Category name*" with "New subsection"
And I fill in "Anchor name*" with "whatisao3"
And I press "Post"
- Then I should see "ArchiveFaq was successfully created"
+ Then I should see "Archive FAQ was successfully created"
When I go to the archive_faqs page
And I follow "New subsection"
Then I should see "Some text, that is sufficiently long to pass validation" within ".userstuff"
@@ -26,10 +26,38 @@ Feature: Admin Actions to Post FAQs
And I press "Post"
Then I should see "New Content, yay"
And I should not see "Some text"
+ When I go to the archive_faqs page
+ And I follow "Delete"
+ Then I should see "Are you sure you want to delete the FAQ Category"
+ When I press "Yes, Delete FAQ Category"
+ Then I should not see "New subsection"
+
+ Examples:
+ | role |
+ | support |
+ | superadmin |
+ | docs |
+
+ @javascript
+ Scenario Outline: Authorized admin deletes a FAQ question
+ Given 1 Archive FAQ with 1 question exists
+ And I am logged in as a "" admin
+ And I go to the archive_faqs page
+ And I follow "Edit"
+ And I follow "Remove Question"
+ And I press "Post"
+ Then I should see "Archive FAQ was successfully updated."
+ And I should see "We're sorry, there are currently no entries in this category."
+
+ Examples:
+ | role |
+ | support |
+ | superadmin |
+ | docs |
Scenario: Post a translated FAQ for a locale, then change the locale's code.
Given basic languages
- And I am logged in as a "translation" admin
+ And I am logged in as a "superadmin" admin
# Post "en" FAQ
When I go to the archive_faqs page
@@ -39,23 +67,25 @@ Feature: Admin Actions to Post FAQs
And I fill in "Category name*" with "New subsection"
And I fill in "Anchor name*" with "whatisao3"
And I press "Post"
- Then I should see "ArchiveFaq was successfully created"
+ Then I should see "Archive FAQ was successfully created"
# Translate FAQ to "de"
- When I follow "Archive FAQ"
+ When I am logged in as a "translation" admin
+ And I follow "Admin Posts"
+ And I follow "Archive FAQ"
And I select "Deutsch" from "Language:"
And I press "Go" within "div#inner.wrapper"
And I follow "Edit"
And I fill in "Question*" with "Was ist AO3?"
- And I fill in "Answer*" with "Einige Text, das ist lang genug, um die Überprüfung bestanden."
+ And I fill in "Answer*" with "Einiger Text, der lang genug ist, um die Überprüfung zu bestehen."
And I fill in "Category name*" with "Neuer Abschnitt"
And I check "Question translated"
And I press "Post"
- Then I should see "ArchiveFaq was successfully updated."
+ Then I should see "Archive FAQ was successfully updated."
And I should not see "New subsection"
And I should see "Neuer Abschnitt"
And I should see "Was ist AO3?"
- And I should see "Einige Text"
+ And I should see "Einiger Text"
# Change locale "de" to "ger"
When I go to the locales page
@@ -83,4 +113,89 @@ Feature: Admin Actions to Post FAQs
And I press "Go" within "div#inner.wrapper"
And I follow "Neuer Abschnitt"
Then I should see "Was ist AO3?"
- And I should see "Einige Text"
+ And I should see "Einiger Text"
+
+ Scenario: Links to create, reorder and delete FAQ categories are not shown for non-English language FAQs
+ Given basic languages
+ And 1 Archive FAQ exists
+ And I am logged in as a "superadmin" admin
+ When I go to the archive_faqs page
+ Then I should see "New FAQ Category"
+ And I should see "Reorder FAQs"
+ And I should see "Delete"
+ And I should see "Edit"
+ When I select "Deutsch" from "Language:"
+ And I press "Go" within "div#inner.wrapper"
+ Then I should not see "New FAQ Category"
+ And I should not see "Reorder FAQs"
+ And I should not see "Delete"
+ But I should see "Edit"
+
+ @javascript
+ Scenario: Links to add, reorder and remove FAQ questions are not shown for non-English language FAQs
+ Given basic languages
+ And 1 Archive FAQ with 1 question exists
+ And I am logged in as a "superadmin" admin
+ When I go to the archive_faqs page
+ And I follow "Edit"
+ Then I should see "Reorder Questions"
+ And I should see "Remove Question"
+ And I should see "Add Question"
+ But I should not see "Question translated"
+ When I select "Deutsch" from "Language:"
+ And I press "Go" within "div#inner.wrapper"
+ And I follow "Edit"
+ Then I should not see "Reorder Questions"
+ And I should not see "Remove Question"
+ And I should not see "Add Question"
+ But I should see "Question translated"
+
+ Scenario: Translation admins do not see links to edit English language FAQs
+ Given basic languages
+ And 1 Archive FAQ exists
+ And I am logged in as a "translation" admin
+ When I go to the archive_faqs page
+ Then I should not see "Edit"
+ And I should not see "New FAQ Category"
+ And I should not see "Reorder FAQs"
+ And I should not see "Delete"
+ When I follow "Show"
+ Then I should not see "Edit" within ".header"
+ But I should see "Updated:" within ".header"
+ When I go to the archive_faqs page
+ And I select "Deutsch" from "Language:"
+ And I press "Go" within "div#inner.wrapper"
+ Then I should see "Edit"
+ And I should not see "New FAQ Category"
+ And I should not see "Reorder FAQs"
+ And I should not see "Delete"
+ When I follow "Show"
+ Then I should see "Edit" within ".header"
+ And I should see "Updated:" within ".header"
+
+ Scenario Outline: Links to create and edit FAQs are not shown to unauthorized admins
+ Given an archive FAQ category with the title "Very important FAQ" exists
+ And I am logged in as a "" admin
+ When I follow "Admin Posts"
+ Then I should not see "Archive FAQ" within "#header"
+ When I go to the archive_faqs page
+ Then I should not see "Edit"
+ And I should not see "New FAQ Category"
+ And I should not see "Reorder FAQs"
+ And I should not see "Delete"
+ But I should see "Available Categories"
+ When I follow "Very important FAQ"
+ Then I should not see "Edit"
+ And I should not see "Updated:"
+
+ Examples:
+ | role |
+ | board |
+ | board_assistants_team |
+ | communications |
+ | development_and_membership |
+ | elections |
+ | legal |
+ | tag_wrangling |
+ | policy_and_abuse |
+ | open_doors |
diff --git a/features/admins/admin_post_issues.feature b/features/admins/admin_post_issues.feature
index fdfdb508fbe..cdedac3a957 100644
--- a/features/admins/admin_post_issues.feature
+++ b/features/admins/admin_post_issues.feature
@@ -3,9 +3,9 @@ Feature: Admin Actions to Post Known Issues
As an an admin
I want to be able to report known issues
- Scenario: Post known issues
- When I am logged in as an admin
- And I follow "Admin Posts"
+ Scenario Outline: Authorized admin posts, edits, and deletes known issues
+ Given I am logged in as a "" admin
+ When I follow "Admin Posts"
And I follow "Known Issues" within "#header"
And I follow "make a new known issues post"
And I fill in "known_issue_title" with "First known problem"
@@ -18,15 +18,36 @@ Feature: Admin Actions to Post Known Issues
And I follow "Known Issues" within "#header"
And I follow "Show"
Then I should see "First known problem"
-
- Scenario: Edit known issues
- Given I have posted known issues
When I edit known issues
Then I should see "Known issue was successfully updated"
And I should not see "First known problem"
And I should see "This is a bit of a problem, and this is too"
-
- Scenario: Delete known issues
- Given I have posted known issues
When I delete known issues
Then I should not see "First known problem"
+
+ Examples:
+ | role |
+ | support |
+ | superadmin |
+
+ Scenario Outline: Links to edit and create known issues are not shown to unauthorized admins
+ Given I have posted known issues
+ And I am logged in as a "" admin
+ When I follow "Admin Posts"
+ Then I should not see "Known Issues" within "#header"
+ When I go to the known issues page
+ Then I should not see "Edit" within ".actions"
+
+ Examples:
+ | role |
+ | board |
+ | board_assistants_team |
+ | communications |
+ | development_and_membership |
+ | docs |
+ | elections |
+ | legal |
+ | translation |
+ | tag_wrangling |
+ | policy_and_abuse |
+ | open_doors |
diff --git a/features/admins/admin_reorder_faq.feature b/features/admins/admin_reorder_faq.feature
index d06f3d67a12..0073cb5dd60 100644
--- a/features/admins/admin_reorder_faq.feature
+++ b/features/admins/admin_reorder_faq.feature
@@ -5,7 +5,7 @@ Feature: Rearrange Archive FAQs
I want to be able to reorder the FAQs
Scenario: Rearrange FAQs
- Given I am logged in as an admin
+ Given I am logged in as a "superadmin" admin
And 3 Archive FAQs exist
When I go to the FAQ reorder page
And I fill in "archive_faqs_1" with "3"
diff --git a/features/admins/admin_reorder_faq_questions.feature b/features/admins/admin_reorder_faq_questions.feature
index 4f5c1b40ebe..2142bccc0ec 100644
--- a/features/admins/admin_reorder_faq_questions.feature
+++ b/features/admins/admin_reorder_faq_questions.feature
@@ -4,7 +4,7 @@ Feature: Admin Actions to re-order questions in a FAQ Category
I want to be able to re-order the questions in a FAQ Category
Scenario: Re-order the questions in a FAQ Category
- Given I am logged in as an admin
+ Given I am logged in as a "superadmin" admin
And I make a multi-question FAQ post
When I go to the archive_faqs page
And I follow "Standard FAQ Category"
diff --git a/features/bookmarks/bookmark_indexing.feature b/features/bookmarks/bookmark_indexing.feature
index 7bd9a41cd36..e32a131c35e 100644
--- a/features/bookmarks/bookmark_indexing.feature
+++ b/features/bookmarks/bookmark_indexing.feature
@@ -63,7 +63,7 @@ Feature: Bookmark Indexing
Given a canonical fandom "Veronica Mars"
And a canonical fandom "Veronica Mars (TV)"
And bookmarks of external works and series tagged with the fandom tag "Veronica Mars"
- And I am logged in as an admin
+ And I am logged in as a "tag_wrangling" admin
When I syn the tag "Veronica Mars" to "Veronica Mars (TV)"
And I go to the bookmarks tagged "Veronica Mars (TV)"
Then I should see "BookmarkedExternalWork"
diff --git a/features/importing/work_import.feature b/features/importing/work_import.feature
index 15948aaa697..fa98e6e3866 100644
--- a/features/importing/work_import.feature
+++ b/features/importing/work_import.feature
@@ -355,3 +355,20 @@ Feature: Import Works
And I should not see "This chapter is a draft and hasn't been posted yet!"
When I follow "Next Chapter"
Then I should not see "This chapter is a draft and hasn't been posted yet!"
+
+ Scenario: Importing as an archivist for an existing Archive author should send translated claim email
+ Given a locale with translated emails
+ And the following activated users exist
+ | login | email |
+ | sam | sam@example.com |
+ | notsam | notsam@example.com |
+ And the user "sam" enables translated emails
+ And all emails have been delivered
+ When I import the mock work "http://import-site-without-tags" by "sam" with email "sam@example.com" and by "notsam" with email "notsam@example.com"
+ Then I should see import confirmation
+ And 1 email should be delivered to "sam@example.com"
+ And the email should contain claim information
+ And the email to "sam" should be translated
+ And 1 email should be delivered to "notsam@example.com"
+ And the email should contain claim information
+ And the email to "notsam" should be non-translated
diff --git a/features/other_a/invite_request.feature b/features/other_a/invite_request.feature
index 8d8a4f5725d..09f4ab3ad98 100644
--- a/features/other_a/invite_request.feature
+++ b/features/other_a/invite_request.feature
@@ -156,3 +156,21 @@ Feature: Invite requests
When I follow "Delete"
Then I should see "Invitation successfully destroyed"
And "user1" should have "4" invitations
+
+ Scenario: Translated email is sent when invitation request is declined by admin
+ Given a locale with translated emails
+ And invitations are required
+ And the user "user1" exists and is activated
+ And the user "notuser1" exists and is activated
+ And the user "user1" enables translated emails
+ And all emails have been delivered
+ When as "user1" I request some invites
+ And as "notuser1" I request some invites
+ And I view requests as an admin
+ And I press "Decline All"
+ Then "user1" should be emailed
+ And the email should have "Additional invitation request declined" in the subject
+ And the email to "user1" should be translated
+ Then "notuser1" should be emailed
+ And the email should have "Additional invitation request declined" in the subject
+ And the email to "notuser1" should be non-translated
diff --git a/features/other_a/profile_edit.feature b/features/other_a/profile_edit.feature
index 4f6186226ca..1f9e0e6b593 100644
--- a/features/other_a/profile_edit.feature
+++ b/features/other_a/profile_edit.feature
@@ -148,6 +148,17 @@ Scenario: Changing email address -- can't be the same as another user's
And I should not see "foo@ao3.org"
And I should see "bar@ao3.org"
+Scenario: Changing email address -- Translated email is sent when user enables locale settings
+ Given a locale with translated emails
+ And the user "editname" enables translated emails
+ And all emails have been delivered
+ When I am logged in as "editname"
+ And I want to edit my profile
+ And I change my email
+ Then the email address "bar@ao3.org" should be emailed
+ And the email should have "Email changed" in the subject
+ And the email to email address "bar@ao3.org" should be translated
+
Scenario: Date of birth - under age
When I enter a birthdate that shows I am under age
diff --git a/features/step_definitions/admin_steps.rb b/features/step_definitions/admin_steps.rb
index e20e50c1324..fa8e38d8926 100644
--- a/features/step_definitions/admin_steps.rb
+++ b/features/step_definitions/admin_steps.rb
@@ -102,8 +102,8 @@
click_button("Update")
end
-Given /^I have posted known issues$/ do
- step %{I am logged in as an admin}
+Given "I have posted known issues" do
+ step %{I am logged in as a super admin}
step %{I follow "Admin Posts"}
step %{I follow "Known Issues" within "#header"}
step %{I follow "make a new known issues post"}
@@ -223,6 +223,10 @@
allow(Comment).to receive(:per_page).and_return(amount)
end
+Given "an archive FAQ category with the title {string} exists" do |title|
+ FactoryBot.create(:archive_faq, title: title)
+end
+
### WHEN
When /^I visit the last activities item$/ do
@@ -272,9 +276,18 @@
click_button("Post")
end
-When /^(\d+) Archive FAQs? exists?$/ do |n|
- (1..n.to_i).each do |i|
- FactoryBot.create(:archive_faq, id: i)
+When "{int} Archive FAQ(s) exist(s)" do |n|
+ (1..n).each do |i|
+ FactoryBot.create(:archive_faq, id: i, title: "The #{i} FAQ")
+ end
+end
+
+When "{int} Archive FAQ(s) with {int} question(s) exist(s)" do |faqs, questions|
+ (1..faqs).each do |i|
+ archive_faq = FactoryBot.create(:archive_faq, id: i)
+ (1..questions).each do
+ FactoryBot.create(:question, archive_faq: archive_faq)
+ end
end
end
@@ -286,8 +299,7 @@
Resque.enqueue(AdminSetting, :check_queue)
end
-When /^I edit known issues$/ do
- step %{I am logged in as an admin}
+When "I edit known issues" do
step %{I follow "Admin Posts"}
step %{I follow "Known Issues" within "#header"}
step %{I follow "Edit"}
@@ -296,8 +308,7 @@
step %{I press "Post"}
end
-When /^I delete known issues$/ do
- step %{I am logged in as an admin}
+When "I delete known issues" do
step %{I follow "Admin Posts"}
step %{I follow "Known Issues" within "#header"}
step %{I follow "Delete"}
diff --git a/features/step_definitions/email_custom_steps.rb b/features/step_definitions/email_custom_steps.rb
index e03db12e2da..bb3cf14bb84 100644
--- a/features/step_definitions/email_custom_steps.rb
+++ b/features/step_definitions/email_custom_steps.rb
@@ -27,6 +27,12 @@
step(%{the email to "#{user}" should not contain "translation missing"}) # missing translations in the target language fall back to English
end
+Then "the email to email address {string} should be translated" do |email_address|
+ step(%{the email to email address "#{email_address}" should contain "Translated footer"})
+ step(%{the email to email address "#{email_address}" should not contain "fan-run and fan-supported archive"}) # untranslated English text
+ step(%{the email to email address "#{email_address}" should not contain "translation missing"}) # missing translations in the target language fall back to English
+end
+
Then "the last email to {string} should be translated" do |user|
step(%{the last email to "#{user}" should contain "Translated footer"})
step(%{the last email to "#{user}" should not contain "fan-run and fan-supported archive"}) # untranslated English text
@@ -44,6 +50,10 @@
expect(emails("to: \"#{email_for(@user.email)}\"")).not_to be_empty
end
+Then "the email address {string} should be emailed" do |email_address|
+ expect(emails("to: \"#{email_for(email_address)}\"")).not_to be_empty
+end
+
Then "{string} should not be emailed" do |user|
@user = User.find_by(login: user)
expect(emails("to: \"#{email_for(@user.email)}\"")).to be_empty
@@ -60,6 +70,16 @@
end
end
+Then "the email to email address {string} should contain {string}" do |email_address, text|
+ email = emails("to: \"#{email_for(email_address)}\"").first
+ if email.multipart?
+ expect(email.text_part.body).to match(text)
+ expect(email.html_part.body).to match(text)
+ else
+ expect(email.body).to match(text)
+ end
+end
+
Then "the last email to {string} should contain {string}" do |user, text|
@user = User.find_by(login: user)
email = emails("to: \"#{email_for(@user.email)}\"").last
@@ -82,6 +102,16 @@
end
end
+Then "the email to email address {string} should not contain {string}" do |email_address, text|
+ email = emails("to: \"#{email_for(email_address)}\"").first
+ if email.multipart?
+ expect(email.text_part.body).not_to match(text)
+ expect(email.html_part.body).not_to match(text)
+ else
+ expect(email.body).not_to match(text)
+ end
+end
+
Then "the last email to {string} should not contain {string}" do |user, text|
@user = User.find_by(login: user)
email = emails("to: \"#{email_for(@user.email)}\"").last
diff --git a/features/step_definitions/invite_steps.rb b/features/step_definitions/invite_steps.rb
index 3011381e863..6adc74971ef 100644
--- a/features/step_definitions/invite_steps.rb
+++ b/features/step_definitions/invite_steps.rb
@@ -128,6 +128,16 @@ def invite(attributes = {})
step %{I press "Send Request"}
end
+When "as {string} I request some invites" do |user|
+ step %{I am logged in as "#{user}"}
+ step %{I go to my user page}
+ step %{I follow "Invitations"}
+ step %{I follow "Request invitations"}
+ step %{I fill in "How many invitations would you like? (max 10)" with "3"}
+ step %{I fill in "Please specify why you'd like them:" with "I want them for a friend"}
+ step %{I press "Send Request"}
+end
+
When /^I view requests as an admin$/ do
step %{I am logged in as an admin}
step %{I follow "Invitations"}
diff --git a/features/step_definitions/tag_steps.rb b/features/step_definitions/tag_steps.rb
index 92d01d5d457..2d88ae3d455 100644
--- a/features/step_definitions/tag_steps.rb
+++ b/features/step_definitions/tag_steps.rb
@@ -197,7 +197,7 @@
end
Given /^I have posted a Wrangling Guideline?(?: titled "([^\"]*)")?$/ do |title|
- step %{I am logged in as an admin}
+ step %{I am logged in as a "tag_wrangling" admin}
visit new_wrangling_guideline_path
if title
fill_in("Guideline text", with: "This is a page about how we wrangle things.")
@@ -427,6 +427,11 @@
assert tag.type == tag_type
end
+Then "the {string} tag should be an unsorted tag" do |tagname|
+ tag = Tag.find_by(name: tagname)
+ expect(tag).to be_a(UnsortedTag)
+end
+
Then(/^the "([^"]*)" tag should (be|not be) canonical$/) do |tagname, canonical|
tag = Tag.find_by(name: tagname)
expected = canonical == "be"
diff --git a/features/step_definitions/work_import_steps.rb b/features/step_definitions/work_import_steps.rb
index 25360c974f0..16701b894ca 100644
--- a/features/step_definitions/work_import_steps.rb
+++ b/features/step_definitions/work_import_steps.rb
@@ -72,6 +72,17 @@ def mock_external
step %{I select "English" from "Choose a language"}
end
+When "I import the mock work {string} by {string} with email {string} and by {string} with email {string}" do |url, creator_name, creator_email, cocreator_name, cocreator_email|
+ step(%{I start importing "#{url}" with a mock website as an archivist})
+ step(%{I check "Import for others ONLY with permission"})
+ step(%{I fill in "external_author_name" with "#{creator_name}"})
+ step(%{I fill in "external_author_email" with "#{creator_email}"})
+ step(%{I fill in "external_coauthor_name" with "#{cocreator_name}"})
+ step(%{I fill in "external_coauthor_email" with "#{cocreator_email}"})
+ step(%{I check "Post without previewing"})
+ step(%{I press "Import"})
+end
+
When /^I import "(.*)"( with a mock website)?$/ do |url, mock|
step %{I start importing "#{url}"#{mock}}
step %{I press "Import"}
diff --git a/features/tags_and_wrangling/tag_wrangling.feature b/features/tags_and_wrangling/tag_wrangling.feature
index 78a3532f65f..680d9822844 100644
--- a/features/tags_and_wrangling/tag_wrangling.feature
+++ b/features/tags_and_wrangling/tag_wrangling.feature
@@ -311,7 +311,7 @@ Feature: Tag wrangling
Scenario: An admin can see the troubleshoot button on a tag page
Given a canonical fandom "Cowboy Bebop"
- And I am logged in as an admin
+ And I am logged in as a "tag_wrangling" admin
When I view the tag "Cowboy Bebop"
Then I should see "Troubleshoot"
diff --git a/features/tags_and_wrangling/tag_wrangling_admin.feature b/features/tags_and_wrangling/tag_wrangling_admin.feature
index 1d8982c1b34..9768229853b 100644
--- a/features/tags_and_wrangling/tag_wrangling_admin.feature
+++ b/features/tags_and_wrangling/tag_wrangling_admin.feature
@@ -11,7 +11,7 @@ Feature: Tag wrangling
And I go to my bookmarks page
And I go to my works page
And I go to the work "Luncheon"
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I edit the tag "Amelie"
And I fill in "Synonym of" with "Amélie"
And I press "Save changes"
@@ -34,7 +34,7 @@ Feature: Tag wrangling
Scenario: Admin can rename a tag using Eastern characters
- Given I am logged in as an admin
+ Given I am logged in as a "tag_wrangling" admin
And a fandom exists with name: "先生", canonical: false
When I edit the tag "先生"
And I fill in "Name" with "てりやき"
@@ -86,3 +86,87 @@ Feature: Tag wrangling
Then I should see "Tags Wrangled (CSV)"
When I follow "Tags Wrangled (CSV)"
Then I should download a csv file with the header row "Name Last Updated Type Merger Fandoms Unwrangleable"
+
+ Scenario Outline: Authorized admins have the tag wrangling item in the admin navbar
+
+ Given I am logged in as a "" admin
+ Then I should see "Tag Wrangling" within "ul.admin.primary.navigation"
+
+ Examples:
+ | role |
+ | superadmin |
+ | tag_wrangling |
+
+ Scenario Outline: Unauthorized admins do not have the tag wrangling item in the admin navbar
+
+ Given I am logged in as a "" admin
+ Then I should not see "Tag Wrangling" within "ul.admin.primary.navigation"
+
+ Examples:
+ | role |
+ | board |
+ | board_assistants_team |
+ | communications |
+ | development_and_membership |
+ | docs |
+ | elections |
+ | legal |
+ | translation |
+ | support |
+ | policy_and_abuse |
+ | open_doors |
+
+ Scenario Outline: Fully-authorized admins get the wrangling dashboard sidebar
+
+ Given I am logged in as a "" admin
+ And basic tags
+ When I go to the tags page
+ Then I should see "Wrangling Tools" within "div#dashboard"
+ And I should see "Wranglers" within "div#dashboard"
+ And I should see "Search Tags" within "div#dashboard"
+ And I should see "New Tag" within "div#dashboard"
+ But I should not see "Wrangling Home" within "div#dashboard"
+
+ Examples:
+ | role |
+ | superadmin |
+ | tag_wrangling |
+
+ Scenario Outline: Read-authorized admins get a partial wrangling dashboard sidebar
+
+ Given I am logged in as a "" admin
+ And basic tags
+ When I go to the tags page
+ Then I should see "Wrangling Tools" within "div#dashboard"
+ And I should see "Search Tags" within "div#dashboard"
+ But I should not see "Wranglers" within "div#dashboard"
+ And I should not see "New Tag" within "div#dashboard"
+ And I should not see "Wrangling Home" within "div#dashboard"
+
+ Examples:
+ | role |
+ | policy_and_abuse |
+
+ Scenario Outline: Unauthorized admins do not get the wrangling dashboard sidebar
+
+ Given I am logged in as a "" admin
+ And basic tags
+ When I go to the tags page
+ Then I should not see "Wrangling Tools"
+ And I should not see "Wranglers"
+ And I should not see "Search Tags"
+ And I should not see "New Tag"
+ And I should not see "Wrangling Home"
+
+ Examples:
+ | role |
+ | board |
+ | board_assistants_team |
+ | communications |
+ | development_and_membership |
+ | docs |
+ | elections |
+ | legal |
+ | translation |
+ | support |
+ | open_doors |
diff --git a/features/tags_and_wrangling/tag_wrangling_characters.feature b/features/tags_and_wrangling/tag_wrangling_characters.feature
index 9d65608c959..6c9c2e3561f 100644
--- a/features/tags_and_wrangling/tag_wrangling_characters.feature
+++ b/features/tags_and_wrangling/tag_wrangling_characters.feature
@@ -53,7 +53,7 @@ Scenario: character wrangling - syns, mergers, characters, autocompletes
When I follow "Edit The First Doctor"
Then I should not see "Make tag non-canonical and unhook all associations"
- Given I am logged in as an admin
+ Given I am logged in as a "tag_wrangling" admin
When I edit the tag "The First Doctor"
Then I should see "Make tag non-canonical and unhook all associations"
And I should see "The Doctor (1st)"
@@ -129,7 +129,7 @@ Scenario: character wrangling - syns, mergers, characters, autocompletes
When I follow "First Doctor"
Then I should see "John Smith"
And I should see "The Doctor"
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I edit the tag "First Doctor"
And I fill in "Synonym of" with "First Doctor (DW)"
And I press "Save changes"
diff --git a/features/tags_and_wrangling/tag_wrangling_fandoms.feature b/features/tags_and_wrangling/tag_wrangling_fandoms.feature
index 7ca8a94ceb9..a440ccfd39f 100644
--- a/features/tags_and_wrangling/tag_wrangling_fandoms.feature
+++ b/features/tags_and_wrangling/tag_wrangling_fandoms.feature
@@ -116,7 +116,7 @@ Scenario: fandoms wrangling - syns, mergers, autocompletes, metatags
When I edit the tag "Stargate SG-1"
Then I should see "Stargate SG-1: Ark of Truth" within "div#child_SubTag_associations_to_remove_checkboxes"
And I should see "Stargate Franchise" within "div#parent_MetaTag_associations_to_remove_checkboxes"
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I edit the tag "Stargate SG-1"
And I fill in "Synonym of" with "Stargate SG-1: Greatest Show in the Universe"
And I press "Save changes"
diff --git a/features/tags_and_wrangling/tag_wrangling_freeforms.feature b/features/tags_and_wrangling/tag_wrangling_freeforms.feature
index 5f5e2a18627..f1a8786b92f 100644
--- a/features/tags_and_wrangling/tag_wrangling_freeforms.feature
+++ b/features/tags_and_wrangling/tag_wrangling_freeforms.feature
@@ -95,7 +95,7 @@ Scenario: freeforms wrangling - syns, mergers, autocompletes, metatags
Then I should see "Tag was updated"
When I follow "Alternate Universe Pirates"
Then I should see "Alternate Universe Space Pirates"
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I edit the tag "Alternate Universe Pirates"
And I fill in "Synonym of" with "Alternate Universe Pirrrates"
And I press "Save changes"
diff --git a/features/tags_and_wrangling/tag_wrangling_more.feature b/features/tags_and_wrangling/tag_wrangling_more.feature
index 5856829cec0..95dbaca5136 100644
--- a/features/tags_and_wrangling/tag_wrangling_more.feature
+++ b/features/tags_and_wrangling/tag_wrangling_more.feature
@@ -221,7 +221,7 @@ Feature: Tag wrangling: assigning wranglers, using the filters on the Wranglers
When I am logged in as a random user
And I view the tag "Cowboy Bebop"
Then I should see "Sorry, you don't have permission to access the page you were trying to reach."
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I view the tag "Cowboy Bebop"
Then I should not see "Please log in as an admin"
And I should see "Cowboy Bebop"
diff --git a/features/tags_and_wrangling/tag_wrangling_relationships.feature b/features/tags_and_wrangling/tag_wrangling_relationships.feature
index 5c49e38dabd..f9977998532 100644
--- a/features/tags_and_wrangling/tag_wrangling_relationships.feature
+++ b/features/tags_and_wrangling/tag_wrangling_relationships.feature
@@ -14,7 +14,7 @@ Scenario: relationship wrangling - syns, mergers, characters, autocompletes
And a canonical character "Zoe Washburne"
And a canonical character "Jack Harkness"
And a canonical character "Ianto Jones"
- And I am logged in as an admin
+ And I am logged in as a "tag_wrangling" admin
And I follow "Tag Wrangling"
# create a new canonical relationship from tag wrangling interface
@@ -126,7 +126,7 @@ Scenario: relationship wrangling - syns, mergers, characters, autocompletes
When I follow "Jack Harkness/Ianto Jones"
Then I should see "Jack Harkness/Robot Ianto Jones"
And I should see "Jack Harkness/Male Character"
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I edit the tag "Jack Harkness/Ianto Jones"
And I fill in "Synonym of" with "Captain Jack Harkness/Ianto Jones"
And I press "Save changes"
@@ -270,7 +270,7 @@ Scenario: AO3-2147 Creating a new merger to a non-can tag while adding character
And I should see "Testypants/Testyskirt"
And the "Canonical" checkbox should be checked and disabled
- When I am logged in as an admin
+ When I am logged in as a "tag_wrangling" admin
And I edit the tag "Testing McTestypants/Testing McTestySkirt"
And I fill in "Synonym of" with "Dame Tester/Sir Tester"
And I press "Save changes"
diff --git a/features/tags_and_wrangling/tag_wrangling_unsorted.feature b/features/tags_and_wrangling/tag_wrangling_unsorted.feature
index dfc829f45fd..b95e004b62c 100644
--- a/features/tags_and_wrangling/tag_wrangling_unsorted.feature
+++ b/features/tags_and_wrangling/tag_wrangling_unsorted.feature
@@ -58,3 +58,49 @@ Feature: Tag Wrangling - Unsorted Tags
When I select "UnsortedTag" from "tag_type"
And I press "Save changes"
Then I should see "Tag was updated."
+
+ Scenario Outline: Editing unsorted tags as a fully authorized admin
+ Given an unsorted_tag exists with name: "Admin unsorted tag"
+ And I am logged in as a "" admin
+ When I go to the unsorted_tags page
+ And I select "Freeform" for the unsorted tag "Admin unsorted tag"
+ And I press "Update"
+ Then I should see "Tags were successfully sorted"
+ And the "Admin unsorted tag" tag should be a "Freeform" tag
+
+ Examples:
+ | role |
+ | superadmin |
+ | tag_wrangling |
+
+ Scenario Outline: Editing unsorted tags as a view-only admin
+ Given an unsorted_tag exists with name: "Admin unsorted tag"
+ And I am logged in as a "" admin
+ When I go to the unsorted_tags page
+ And I select "Freeform" for the unsorted tag "Admin unsorted tag"
+ And I press "Update"
+ Then I should see "Sorry, only an authorized admin can access the page you were trying to reach."
+ And the "Admin unsorted tag" tag should be an unsorted tag
+
+ Examples:
+ | role |
+ | policy_and_abuse |
+
+ Scenario Outline: Editing unsorted tags as an unauthorized admin
+ Given an unsorted_tag exists with name: "Admin unsorted tag"
+ And I am logged in as a "" admin
+ When I go to the unsorted_tags page
+ Then I should see "Sorry, only an authorized admin can access the page you were trying to reach."
+
+ Examples:
+ | role |
+ | board |
+ | board_assistants_team |
+ | communications |
+ | development_and_membership |
+ | docs |
+ | elections |
+ | legal |
+ | translation |
+ | support |
+ | open_doors |
diff --git a/features/tags_and_wrangling/wrangling_guidelines.feature b/features/tags_and_wrangling/wrangling_guidelines.feature
index 138b246acac..837b0709ed2 100644
--- a/features/tags_and_wrangling/wrangling_guidelines.feature
+++ b/features/tags_and_wrangling/wrangling_guidelines.feature
@@ -6,7 +6,7 @@ Feature: Wrangling Guidelines
Scenario: Post a Wrangling Guideline
- Given I am logged in as an admin
+ Given I am logged in as a "tag_wrangling" admin
And I am on the wrangling guidelines page
And I follow "New Wrangling Guideline"
And I fill in "Guideline text" with "This series of documents (Wrangling Guidelines) are intended to help tag wranglers remain consistent as they go about the business of wrangling tags by providing a set of formatting guidelines."
@@ -29,7 +29,7 @@ Feature: Wrangling Guidelines
Scenario: Reorder Wrangling Guidelines
- Given I am logged in as an admin
+ Given I am logged in as a "tag_wrangling" admin
And 3 Wrangling Guidelines exist
When I go to the Wrangling Guidelines reorder page
And I fill in "wrangling_guidelines_1" with "3"
@@ -44,7 +44,7 @@ Feature: Wrangling Guidelines
Scenario: Delete Wrangling Guideline
- Given I am logged in as an admin
+ Given I am logged in as a "tag_wrangling" admin
And I have posted a Wrangling Guideline titled "Relationship Tags"
When I go to the Wrangling Guidelines page
And I follow "Delete"
diff --git a/spec/controllers/archive_faqs_controller_spec.rb b/spec/controllers/archive_faqs_controller_spec.rb
index d7109cc5562..678a4c78508 100644
--- a/spec/controllers/archive_faqs_controller_spec.rb
+++ b/spec/controllers/archive_faqs_controller_spec.rb
@@ -6,6 +6,104 @@
include LoginMacros
include RedirectExpectationHelper
+ fully_authorized_roles = %w[superadmin docs support]
+
+ shared_examples "an action only fully authorized admins can access" do
+ before { fake_login_admin(admin) }
+
+ context "with no role" do
+ let(:admin) { create(:admin, roles: []) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - fully_authorized_roles).each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ fully_authorized_roles.each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "succeeds" do
+ subject
+ success
+ end
+ end
+ end
+ end
+
+ translation_authorized_roles = %w[superadmin docs support translation]
+
+ shared_examples "an action translation authorized admins can access" do
+ before { fake_login_admin(admin) }
+
+ context "with no role" do
+ let(:admin) { create(:admin, roles: []) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - translation_authorized_roles).each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ translation_authorized_roles.each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "succeeds" do
+ subject
+ success
+ end
+ end
+ end
+ end
+
+ shared_examples "a non-English action that nobody can access" do
+ before { fake_login_admin(admin) }
+
+ context "with no role" do
+ let(:admin) { create(:admin, roles: []) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(archive_faqs_path, "Sorry, this action is only available for English FAQs.")
+ end
+ end
+
+ Admin::VALID_ROLES.each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(archive_faqs_path, "Sorry, this action is only available for English FAQs.")
+ end
+ end
+ end
+ end
+
let(:non_standard_locale) { create(:locale) }
let(:user_locale) { create(:locale) }
let(:user) do
@@ -112,7 +210,8 @@
describe "GET #show" do
it "raises a 404 for an invalid id" do
params = { id: "angst", language_id: "en" }
- expect { get :show, params: params }.to raise_error ActiveRecord::RecordNotFound
+ expect { get :show, params: params }
+ .to raise_exception(ActiveRecord::RecordNotFound)
end
end
@@ -135,5 +234,155 @@
"The specified locale does not exist.")
end
end
+
+ subject { patch :update, params: { id: faq, archive_faq: { title: "Changed" }, language_id: locale } }
+ let(:success) do
+ I18n.with_locale(locale) do
+ expect { faq.reload }
+ .to change { faq.title }
+ end
+ it_redirects_to_with_notice(faq, "Archive FAQ was successfully updated.")
+ end
+
+ context "for the default locale" do
+ let(:locale) { "en" }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "an action translation authorized admins can access"
+ end
+ end
+
+ describe "GET #edit" do
+ subject { get :edit, params: { id: faq, language_id: locale } }
+ let(:faq) { create(:archive_faq) }
+ let(:success) do
+ expect(response).to render_template(:edit)
+ end
+
+ context "for the default locale" do
+ let(:locale) { "en" }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "an action translation authorized admins can access"
+ end
+ end
+
+ describe "GET #new" do
+ subject { get :new, params: { language_id: locale } }
+ let(:success) do
+ expect(response).to render_template(:new)
+ end
+
+ context "for the default locale" do
+ let(:locale) { "en" }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "a non-English action that nobody can access"
+ end
+ end
+
+ describe "POST #create" do
+ subject { post :create, params: { archive_faq: attributes_for(:archive_faq), language_id: locale } }
+ let(:success) do
+ expect(ArchiveFaq.count).to eq(1)
+ it_redirects_to_with_notice(assigns[:archive_faq], "Archive FAQ was successfully created.")
+ end
+
+ context "for the default locale" do
+ let(:locale) { I18n.default_locale }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "a non-English action that nobody can access"
+ end
+ end
+
+ describe "GET #manage" do
+ subject { get :manage, params: { language_id: locale } }
+ let(:success) do
+ expect(response).to render_template(:manage)
+ end
+
+ context "for the default locale" do
+ let(:locale) { "en" }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "a non-English action that nobody can access"
+ end
+ end
+
+ describe "POST #update_positions" do
+ subject { post :update_positions, params: { archive_faqs: [3, 1, 2], language_id: locale } }
+ let!(:faq1) { create(:archive_faq, position: 1) }
+ let!(:faq2) { create(:archive_faq, position: 2) }
+ let!(:faq3) { create(:archive_faq, position: 3) }
+ let(:success) do
+ expect(faq1.reload.position).to eq(3)
+ expect(faq2.reload.position).to eq(1)
+ expect(faq3.reload.position).to eq(2)
+ it_redirects_to_with_notice(archive_faqs_path, "Archive FAQs order was successfully updated.")
+ end
+
+ context "for the default locale" do
+ let(:locale) { I18n.default_locale }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "a non-English action that nobody can access"
+ end
+ end
+
+ describe "GET #confirm_delete" do
+ subject { get :confirm_delete, params: { id: faq, language_id: locale } }
+ let(:faq) { create(:archive_faq) }
+ let(:success) do
+ expect(response).to render_template(:confirm_delete)
+ end
+
+ context "for the default locale" do
+ let(:locale) { "en" }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "a non-English action that nobody can access"
+ end
+ end
+
+ describe "DELETE #destroy" do
+ subject { delete :destroy, params: { id: faq, language_id: locale } }
+ let(:faq) { create(:archive_faq) }
+ let(:success) do
+ expect { faq.reload }
+ .to raise_exception(ActiveRecord::RecordNotFound)
+ it_redirects_to(archive_faqs_path)
+ end
+
+ context "for the default locale" do
+ let(:locale) { I18n.default_locale }
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ context "for a non-default locale" do
+ let(:locale) { non_standard_locale.iso }
+ it_behaves_like "a non-English action that nobody can access"
+ end
end
end
diff --git a/spec/controllers/inbox_controller_spec.rb b/spec/controllers/inbox_controller_spec.rb
index 21815b1bbd7..9e29317db9e 100644
--- a/spec/controllers/inbox_controller_spec.rb
+++ b/spec/controllers/inbox_controller_spec.rb
@@ -19,6 +19,111 @@
"Sorry, you don't have permission to access the page you were trying to reach.")
end
+ context "when logged in as an admin" do
+ context "when the admin does not have the correct authorization" do
+ context "when the admin has no role" do
+ let(:admin) { create(:admin, roles: []) }
+
+ before { fake_login_admin(admin) }
+
+ it "redirects with error" do
+ get :show, params: { user_id: user.login }
+
+ it_redirects_to_with_error(root_path, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - %w[superadmin policy_and_abuse]).each do |role|
+ context "when the admin has the #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "redirects with error" do
+ get :show, params: { user_id: user.login }
+
+ it_redirects_to_with_error(root_path, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+ end
+
+ %w[superadmin policy_and_abuse].each do |role|
+ context "when the admin is authorized with the #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "renders the user inbox" do
+ get :show, params: { user_id: user.login }
+ expect(response).to render_template("show")
+ expect(assigns(:inbox_total)).to eq(0)
+ expect(assigns(:unread)).to eq(0)
+ end
+
+ context "with unread comments" do
+ let!(:inbox_comments) do
+ Array.new(3) do |i|
+ create(:inbox_comment, user: user, created_at: Time.now.utc + i.days)
+ end
+ end
+
+ it "renders non-zero unread count" do
+ get :show, params: { user_id: user.login }
+ expect(assigns(:inbox_comments)).to eq(inbox_comments.reverse)
+ expect(assigns(:inbox_total)).to eq(3)
+ expect(assigns(:unread)).to eq(3)
+ end
+
+ it "renders oldest first" do
+ get :show, params: { user_id: user.login, filters: { date: "asc" } }
+ expect(assigns(:filters)[:date]).to eq("asc")
+ expect(assigns(:inbox_comments)).to eq(inbox_comments)
+ expect(assigns(:inbox_total)).to eq(3)
+ expect(assigns(:unread)).to eq(3)
+ end
+ end
+
+ context "with 1 read and 1 unread" do
+ let!(:read_comment) { create(:inbox_comment, user: user, read: true) }
+ let!(:unread_comment) { create(:inbox_comment, user: user) }
+
+ it "renders only unread" do
+ get :show, params: { user_id: user.login, filters: { read: "false" } }
+ expect(assigns(:filters)[:read]).to eq("false")
+ expect(assigns(:inbox_comments)).to eq([unread_comment])
+ expect(assigns(:inbox_total)).to eq(2)
+ expect(assigns(:unread)).to eq(1)
+ end
+ end
+
+ context "with 1 replied and 1 unreplied" do
+ let!(:replied_comment) { create(:inbox_comment, user: user, replied_to: true) }
+ let!(:unreplied_comment) { create(:inbox_comment, user: user) }
+
+ it "renders only unreplied" do
+ get :show, params: { user_id: user.login, filters: { replied_to: "false" } }
+ expect(assigns(:filters)[:replied_to]).to eq("false")
+ expect(assigns(:inbox_comments)).to eq([unreplied_comment])
+ expect(assigns(:inbox_total)).to eq(2)
+ expect(assigns(:unread)).to eq(2)
+ end
+ end
+
+ context "with a deleted comment" do
+ let(:inbox_comment) { create(:inbox_comment, user: user) }
+
+ it "excludes deleted comments" do
+ inbox_comment.feedback_comment.destroy!
+ get :show, params: { user_id: user.login }
+ expect(assigns(:inbox_total)).to eq(0)
+ expect(assigns(:unread)).to eq(0)
+ end
+ end
+ end
+ end
+ end
+
context "when logged in as the same user" do
before { fake_login_known_user(user) }
@@ -82,7 +187,7 @@
let(:inbox_comment) { create(:inbox_comment, user: user) }
it "excludes deleted comments" do
- inbox_comment.feedback_comment.destroy
+ inbox_comment.feedback_comment.destroy!
get :show, params: { user_id: user.login }
expect(assigns(:inbox_total)).to eq(0)
expect(assigns(:unread)).to eq(0)
@@ -149,92 +254,107 @@
end
describe "PUT #update" do
- before { fake_login_known_user(user) }
-
- context "with no comments selected" do
- it "redirects to inbox with caution and a notice" do
- put :update, params: { user_id: user.login, read: "yeah" }
- it_redirects_to_with_caution_and_notice(user_inbox_path(user),
- "Please select something first",
- "Inbox successfully updated.")
- end
-
- it "redirects to the previously viewed page if HTTP_REFERER is set, with a caution and a notice" do
- @request.env['HTTP_REFERER'] = root_path
- put :update, params: { user_id: user.login, read: "yeah" }
- it_redirects_to_with_caution_and_notice(root_path,
- "Please select something first",
- "Inbox successfully updated.")
+ %w[superadmin policy_and_abuse].each do |role|
+ context "when logged in as an admin with the role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "redirects to root with error" do
+ put :update, params: { user_id: user.login }
+ it_redirects_to_with_error(root_path, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
end
end
- context "with unread comments" do
- let!(:inbox_comment_1) { create(:inbox_comment, user: user) }
- let!(:inbox_comment_2) { create(:inbox_comment, user: user) }
-
- it "marks all as read and redirects to inbox with a notice" do
- parameters = {
- user_id: user.login,
- inbox_comments: [inbox_comment_1.id, inbox_comment_2.id],
- read: "yeah"
- }
+ context "when logged in as the comment receiver" do
+ before { fake_login_known_user(user) }
- put :update, params: parameters
- it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
+ context "with no comments selected" do
+ it "redirects to inbox with caution and a notice" do
+ put :update, params: { user_id: user.login, read: "yeah" }
+ it_redirects_to_with_caution_and_notice(user_inbox_path(user),
+ "Please select something first",
+ "Inbox successfully updated.")
+ end
- inbox_comment_1.reload
- expect(inbox_comment_1.read).to be_truthy
- inbox_comment_2.reload
- expect(inbox_comment_2.read).to be_truthy
+ it "redirects to the previously viewed page if HTTP_REFERER is set, with a caution and a notice" do
+ @request.env["HTTP_REFERER"] = root_path
+ put :update, params: { user_id: user.login, read: "yeah" }
+ it_redirects_to_with_caution_and_notice(root_path,
+ "Please select something first",
+ "Inbox successfully updated.")
+ end
end
- it "marks one as read and redirects to inbox with a notice" do
- put :update, params: { user_id: user.login, inbox_comments: [inbox_comment_1.id], read: "yeah" }
- it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
+ context "with unread comments" do
+ let!(:inbox_comment1) { create(:inbox_comment, user: user) }
+ let!(:inbox_comment2) { create(:inbox_comment, user: user) }
+
+ it "marks all as read and redirects to inbox with a notice" do
+ parameters = {
+ user_id: user.login,
+ inbox_comments: [inbox_comment1.id, inbox_comment2.id],
+ read: "yeah"
+ }
+
+ put :update, params: parameters
+ it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
+
+ inbox_comment1.reload
+ expect(inbox_comment1.read).to be_truthy
+ inbox_comment2.reload
+ expect(inbox_comment2.read).to be_truthy
+ end
- inbox_comment_1.reload
- expect(inbox_comment_1.read).to be_truthy
- inbox_comment_2.reload
- expect(inbox_comment_2.read).to be_falsy
- end
+ it "marks one as read and redirects to inbox with a notice" do
+ put :update, params: { user_id: user.login, inbox_comments: [inbox_comment1.id], read: "yeah" }
+ it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
- it "deletes one and redirects to inbox with a notice" do
- put :update, params: { user_id: user.login, inbox_comments: [inbox_comment_1.id], delete: "yeah" }
- it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
+ inbox_comment1.reload
+ expect(inbox_comment1.read).to be_truthy
+ inbox_comment2.reload
+ expect(inbox_comment2.read).to be_falsy
+ end
- expect(InboxComment.find_by(id: inbox_comment_1.id)).to be_nil
- inbox_comment_2.reload
- expect(inbox_comment_2.read).to be_falsy
+ it "deletes one and redirects to inbox with a notice" do
+ put :update, params: { user_id: user.login, inbox_comments: [inbox_comment1.id], delete: "yeah" }
+ it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
+
+ expect(InboxComment.find_by(id: inbox_comment1.id)).to be_nil
+ inbox_comment2.reload
+ expect(inbox_comment2.read).to be_falsy
+ end
end
- end
- context "with a read comment and redirects to inbox with a notice" do
- let!(:inbox_comment) { create(:inbox_comment, user: user, read: true) }
+ context "with a read comment and redirects to inbox with a notice" do
+ let!(:inbox_comment) { create(:inbox_comment, user: user, read: true) }
- it "marks as unread and redirects to inbox with a notice" do
- put :update, params: { user_id: user.login, inbox_comments: [inbox_comment.id], unread: "yeah" }
- it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
+ it "marks as unread and redirects to inbox with a notice" do
+ put :update, params: { user_id: user.login, inbox_comments: [inbox_comment.id], unread: "yeah" }
+ it_redirects_to_with_notice(user_inbox_path(user), "Inbox successfully updated.")
- inbox_comment.reload
- expect(inbox_comment.read).to be_falsy
- end
+ inbox_comment.reload
+ expect(inbox_comment.read).to be_falsy
+ end
- it "marks as unread and returns a JSON response" do
- parameters = {
- user_id: user.login,
- inbox_comments: [inbox_comment.id],
- unread: "yeah",
- format: "json"
- }
+ it "marks as unread and returns a JSON response" do
+ parameters = {
+ user_id: user.login,
+ inbox_comments: [inbox_comment.id],
+ unread: "yeah",
+ format: "json"
+ }
- put :update, params: parameters
+ put :update, params: parameters
- inbox_comment.reload
- expect(inbox_comment.read).to be_falsy
+ inbox_comment.reload
+ expect(inbox_comment.read).to be_falsy
- parsed_body = JSON.parse(response.body, symbolize_names: true)
- expect(parsed_body[:item_success_message]).to eq("Inbox successfully updated.")
- expect(response).to have_http_status(:success)
+ parsed_body = JSON.parse(response.body, symbolize_names: true)
+ expect(parsed_body[:item_success_message]).to eq("Inbox successfully updated.")
+ expect(response).to have_http_status(:success)
+ end
end
end
end
diff --git a/spec/controllers/known_issues_controller_spec.rb b/spec/controllers/known_issues_controller_spec.rb
new file mode 100644
index 00000000000..13b797656b9
--- /dev/null
+++ b/spec/controllers/known_issues_controller_spec.rb
@@ -0,0 +1,187 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe KnownIssuesController do
+ include LoginMacros
+ include RedirectExpectationHelper
+
+ allowed_roles = %w[superadmin support]
+
+ shared_examples "denies access to unauthorized admins" do
+ context "when logged in as an admin with no role" do
+ let(:admin) { create(:admin) }
+
+ it "redirects with an error" do
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - allowed_roles).each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ it "redirects with an error" do
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+ end
+
+ describe "GET #show" do
+ let(:known_issue) { create(:known_issue) }
+
+ it_behaves_like "denies access to unauthorized admins" do
+ before do
+ fake_login_admin(admin)
+ get :show, params: { id: known_issue.id }
+ end
+ end
+
+ allowed_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ before do
+ fake_login_admin(admin)
+ end
+
+ it "allows access" do
+ get :show, params: { id: known_issue.id }
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
+ end
+
+ describe "GET #new" do
+ it_behaves_like "denies access to unauthorized admins" do
+ before do
+ fake_login_admin(admin)
+ get :new
+ end
+ end
+
+ allowed_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ before do
+ fake_login_admin(admin)
+ end
+
+ it "allows access" do
+ get :new
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
+ end
+
+ describe "GET #edit" do
+ let(:known_issue) { create(:known_issue) }
+
+ it_behaves_like "denies access to unauthorized admins" do
+ before do
+ fake_login_admin(admin)
+ get :edit, params: { id: known_issue.id }
+ end
+ end
+
+ allowed_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ before do
+ fake_login_admin(admin)
+ end
+
+ it "allows access" do
+ get :edit, params: { id: known_issue.id }
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
+ end
+
+ describe "POST #create" do
+ let(:params) { { known_issue: attributes_for(:known_issue) } }
+
+ it_behaves_like "denies access to unauthorized admins" do
+ before do
+ fake_login_admin(admin)
+ post :create, params: params
+ end
+ end
+
+ allowed_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ before do
+ fake_login_admin(admin)
+ end
+
+ it "creates a known issue" do
+ expect { post :create, params: params }
+ .to change { KnownIssue.count }
+ .by(1)
+ end
+ end
+ end
+ end
+
+ describe "PUT #update" do
+ let(:known_issue) { create(:known_issue) }
+ let(:params) { { id: known_issue.id, known_issue: { title: "Brand new title" } } }
+
+ it_behaves_like "denies access to unauthorized admins" do
+ before do
+ fake_login_admin(admin)
+ put :update, params: params
+ end
+ end
+
+ allowed_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ before do
+ fake_login_admin(admin)
+ end
+
+ it "updates the known issue successfully" do
+ put :update, params: params
+ expect(known_issue.reload.title).to eq("Brand new title")
+ end
+ end
+ end
+ end
+
+ describe "DELETE #destroy" do
+ let(:known_issue) { create(:known_issue) }
+
+ it_behaves_like "denies access to unauthorized admins" do
+ before do
+ fake_login_admin(admin)
+ delete :destroy, params: { id: known_issue.id }
+ end
+ end
+
+ allowed_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ before do
+ fake_login_admin(admin)
+ end
+
+ it "deletes the known issue" do
+ delete :destroy, params: { id: known_issue.id }
+ expect { known_issue.reload }
+ .to raise_exception(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/questions_controller_spec.rb b/spec/controllers/questions_controller_spec.rb
new file mode 100644
index 00000000000..8cf8e4086da
--- /dev/null
+++ b/spec/controllers/questions_controller_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe QuestionsController do
+ include LoginMacros
+ include RedirectExpectationHelper
+
+ fully_authorized_roles = %w[superadmin docs support]
+
+ shared_examples "an action only fully authorized admins can access" do
+ before { fake_login_admin(admin) }
+
+ context "with no role" do
+ let(:admin) { create(:admin, roles: []) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - fully_authorized_roles).each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ fully_authorized_roles.each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "succeeds" do
+ subject
+ success
+ end
+ end
+ end
+ end
+
+ describe "GET #manage" do
+ let(:faq) { create(:archive_faq) }
+ subject { get :manage, params: { archive_faq_id: faq } }
+ let(:success) do
+ expect(response).to render_template(:manage)
+ end
+
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+
+ describe "POST #update_positions" do
+ let(:faq) { create(:archive_faq) }
+ let!(:question1) { create(:question, archive_faq: faq, position: 1) }
+ let!(:question2) { create(:question, archive_faq: faq, position: 2) }
+ let!(:question3) { create(:question, archive_faq: faq, position: 3) }
+ subject { post :update_positions, params: { archive_faq_id: faq, questions: [3, 1, 2] } }
+ let(:success) do
+ expect(question1.reload.position).to eq(3)
+ expect(question2.reload.position).to eq(1)
+ expect(question3.reload.position).to eq(2)
+ it_redirects_to_with_notice(faq, "Question order has been successfully updated.")
+ end
+
+ it_behaves_like "an action only fully authorized admins can access"
+ end
+end
diff --git a/spec/controllers/tag_wranglings_controller_spec.rb b/spec/controllers/tag_wranglings_controller_spec.rb
index 26d24190301..581a1772925 100644
--- a/spec/controllers/tag_wranglings_controller_spec.rb
+++ b/spec/controllers/tag_wranglings_controller_spec.rb
@@ -4,60 +4,144 @@
include LoginMacros
include RedirectExpectationHelper
- before do
- fake_login
- controller.current_user.roles << Role.new(name: "tag_wrangler")
+ full_access_roles = %w[superadmin tag_wrangling].freeze
+ read_access_roles = %w[superadmin policy_and_abuse tag_wrangling].freeze
+
+ shared_examples "an action only authorized admins can access" do |authorized_roles:|
+ before do
+ fake_login_admin(admin)
+ end
+
+ context "when logged in as an admin with no role" do
+ let(:admin) { create(:admin) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - authorized_roles).each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ authorized_roles.each do |admin_role|
+ context "when logged in as an admin with role #{admin_role}" do
+ let(:admin) { create(:admin, roles: [admin_role]) }
+
+ it "succeeds" do
+ subject
+ success
+ end
+ end
+ end
end
- shared_examples "set last wrangling activity" do
- it "sets the last wrangling activity time to now", :frozen do
- user = controller.current_user
- expect(user.last_wrangling_activity.updated_at).to eq(Time.now.utc)
+ describe "GET #index" do
+ let(:success) { expect(response).to have_http_status(:success) }
+
+ context "when the show parameter is absent" do
+ subject { get :index }
+
+ it_behaves_like "an action only authorized admins can access", authorized_roles: read_access_roles
+
+ context "when logged in as a tag wrangler" do
+ before do
+ fake_login_known_user(create(:tag_wrangler))
+ end
+
+ it "shows the wrangling tools page" do
+ subject
+ success
+ end
+ end
+ end
+
+ context "when the show parameter is present" do
+ subject { get :index, params: { show: "fandoms" } }
+
+ it_behaves_like "an action only authorized admins can access", authorized_roles: read_access_roles
+
+ context "when logged in as a tag wrangler" do
+ before do
+ fake_login_known_user(create(:tag_wrangler))
+ end
+
+ it "shows the wrangling tools page" do
+ subject
+ success
+ end
+ end
end
end
- describe "#wrangle" do
- let(:page_options) { { page: 1, sort_column: "name", sort_direction: "ASC" } }
+ describe "POST #wrangle" do
+ shared_examples "set last wrangling activity" do
+ before do
+ fake_login_known_user(create(:tag_wrangler))
+ subject
+ end
+
+ it "sets the last wrangling activity time to now", :frozen do
+ user = controller.current_user
+ expect(user.last_wrangling_activity.updated_at).to eq(Time.now.utc)
+ end
+ end
it "displays error when there are no fandoms to wrangle to" do
+ fake_login_known_user(create(:tag_wrangler))
character = create(:character)
+ page_options = { page: 1, sort_column: "name", sort_direction: "ASC" }
post :wrangle, params: { fandom_string: "", selected_tags: [character.id] }
it_redirects_to_with_error(tag_wranglings_path(page_options), "There were no Fandom tags!")
end
context "when making tags canonical" do
+ subject { post :wrangle, params: { canonicals: [tag1.id, tag2.id] } }
let(:tag1) { create(:character) }
let(:tag2) { create(:character) }
-
- before do
- post :wrangle, params: { canonicals: [tag1.id, tag2.id] }
+ let(:success) do
+ expect(tag1.reload.canonical?).to be(true)
+ expect(tag2.reload.canonical?).to be(true)
end
- include_examples "set last wrangling activity"
+ it_behaves_like "set last wrangling activity"
+ it_behaves_like "an action only authorized admins can access", authorized_roles: full_access_roles
end
context "when assigning tags to a medium" do
+ subject { post :wrangle, params: { media: medium.name, selected_tags: [fandom1.id, fandom2.id] } }
let(:fandom1) { create(:fandom, canonical: true) }
let(:fandom2) { create(:fandom, canonical: true) }
let(:medium) { create(:media) }
-
- before do
- post :wrangle, params: { media: medium.name, selected_tags: [fandom1.id, fandom2.id] }
+ let(:success) do
+ expect(fandom1.medias).to include(medium)
+ expect(fandom2.medias).to include(medium)
end
- include_examples "set last wrangling activity"
+ it_behaves_like "set last wrangling activity"
+ it_behaves_like "an action only authorized admins can access", authorized_roles: full_access_roles
end
context "when adding tags to a fandom" do
+ subject { post :wrangle, params: { fandom_string: fandom.name, selected_tags: [tag1.id, tag2.id] } }
let(:tag1) { create(:character) }
let(:tag2) { create(:character) }
let(:fandom) { create(:fandom, canonical: true) }
-
- before do
- post :wrangle, params: { fandom_string: fandom.name, selected_tags: [tag1.id, tag2.id] }
+ let(:success) do
+ expect(tag1.fandoms).to include(fandom)
+ expect(tag2.fandoms).to include(fandom)
end
- include_examples "set last wrangling activity"
+ it_behaves_like "set last wrangling activity"
+ it_behaves_like "an action only authorized admins can access", authorized_roles: full_access_roles
end
end
end
diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb
index 9be54190b26..d5a174e9ab2 100644
--- a/spec/controllers/tags_controller_spec.rb
+++ b/spec/controllers/tags_controller_spec.rb
@@ -1,9 +1,12 @@
-require 'spec_helper'
+require "spec_helper"
describe TagsController do
include LoginMacros
include RedirectExpectationHelper
+ wrangling_full_access_roles = %w[superadmin tag_wrangling].freeze
+ wrangling_read_access_roles = (wrangling_full_access_roles + %w[policy_and_abuse]).freeze
+
let(:user) { create(:tag_wrangler) }
before { fake_login_known_user(user) }
@@ -14,6 +17,41 @@
end
end
+ shared_examples "an action only authorized admins can access" do |authorized_roles:|
+ before { fake_login_admin(admin) }
+
+ context "with no role" do
+ let(:admin) { create(:admin, roles: []) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - authorized_roles).each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "redirects with an error" do
+ subject
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ authorized_roles.each do |role|
+ context "with role #{role}" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "succeeds" do
+ subject
+ success
+ end
+ end
+ end
+ end
+
describe "#create" do
let(:tag_params) do
{ name: Faker::FunnyName.name, canonical: "0", type: "Character" }
@@ -72,6 +110,13 @@
run_all_indexing_jobs
end
+ subject { get :wrangle, params: { id: fandom.name, show: "freeforms", status: "unwrangled" } }
+ let(:success) do
+ expect(assigns(:tags)).to include(freeform1)
+ end
+
+ it_behaves_like "an action only authorized admins can access", authorized_roles: wrangling_read_access_roles
+
it "includes unwrangled freeforms" do
get :wrangle, params: { id: fandom.name, show: "freeforms", status: "unwrangled" }
expect(assigns(:tags)).to include(freeform1)
@@ -121,40 +166,35 @@
@character3 = FactoryBot.create(:character, canonical: false)
@character2 = FactoryBot.create(:character, canonical: false, merger: @character3)
@work = FactoryBot.create(:work,
- fandom_string: "#{@fandom1.name}",
- character_string: "#{@character1.name},#{@character2.name}",
- freeform_string: "#{@freeform1.name}")
+ fandom_string: @fandom1.name.to_s,
+ character_string: "#{@character1.name},#{@character2.name}",
+ freeform_string: @freeform1.name.to_s)
end
it "should redirect to the wrangle action for that tag" do
- expect(put :mass_update, params: { id: @fandom1.name, show: 'freeforms', status: 'unwrangled' }).
- to redirect_to wrangle_tag_path(id: @fandom1.name,
- show: 'freeforms',
- status: 'unwrangled',
- page: 1,
- sort_column: 'name',
- sort_direction: 'ASC')
+ expect(put(:mass_update, params: { id: @fandom1.name, show: "freeforms", status: "unwrangled" }))
+ .to redirect_to wrangle_tag_path(id: @fandom1.name,
+ show: "freeforms",
+ status: "unwrangled",
+ page: 1,
+ sort_column: "name",
+ sort_direction: "ASC")
end
- context "with one canonical fandom in the fandom string and a selected freeform" do
- before do
- put :mass_update, params: { id: @fandom1.name, show: 'freeforms', status: 'unwrangled', fandom_string: @fandom2.name, selected_tags: [@freeform1.id] }
- end
-
- it "updates the tags successfully" do
- get :wrangle, params: { id: @fandom1.name, show: 'freeforms', status: 'unwrangled' }
- expect(assigns(:tags)).not_to include(@freeform1)
-
- @freeform1.reload
- expect(@freeform1.fandoms).to include(@fandom2)
- end
+ subject { put :mass_update, params: { id: @fandom1.name, show: "freeforms", status: "unwrangled", fandom_string: @fandom2.name, selected_tags: [@freeform1.id] } }
+ let(:success) do
+ get :wrangle, params: { id: @fandom1.name, show: "freeforms", status: "unwrangled" }
+ expect(assigns(:tags)).not_to include(@freeform1)
- include_examples "set last wrangling activity"
+ @freeform1.reload
+ expect(@freeform1.fandoms).to include(@fandom2)
end
+ it_behaves_like "an action only authorized admins can access", authorized_roles: wrangling_full_access_roles
+
context "with one canonical and one noncanonical fandoms in the fandom string and a selected freeform" do
before do
- put :mass_update, params: { id: @fandom1.name, show: 'freeforms', status: 'unwrangled', fandom_string: "#{@fandom2.name},#{@fandom3.name}", selected_tags: [@freeform1.id] }
+ put :mass_update, params: { id: @fandom1.name, show: "freeforms", status: "unwrangled", fandom_string: "#{@fandom2.name},#{@fandom3.name}", selected_tags: [@freeform1.id] }
end
it "updates the tags successfully" do
@@ -168,7 +208,7 @@
context "with two canonical fandoms in the fandom string and a selected character" do
before do
- put :mass_update, params: { id: @fandom1.name, show: 'characters', status: 'unwrangled', fandom_string: "#{@fandom1.name},#{@fandom2.name}", selected_tags: [@character1.id] }
+ put :mass_update, params: { id: @fandom1.name, show: "characters", status: "unwrangled", fandom_string: "#{@fandom1.name},#{@fandom2.name}", selected_tags: [@character1.id] }
end
it "updates the tags successfully" do
@@ -182,7 +222,7 @@
context "with a canonical fandom in the fandom string, a selected unwrangled character, and the same character to be made canonical" do
before do
- put :mass_update, params: { id: @fandom1.name, show: 'characters', status: 'unwrangled', fandom_string: "#{@fandom1.name}", selected_tags: [@character1.id], canonicals: [@character1.id] }
+ put :mass_update, params: { id: @fandom1.name, show: "characters", status: "unwrangled", fandom_string: @fandom1.name.to_s, selected_tags: [@character1.id], canonicals: [@character1.id] }
end
it "updates the tags successfully" do
@@ -196,7 +236,7 @@
context "with a canonical fandom in the fandom string, a selected synonym character, and the same character to be made canonical" do
before do
- put :mass_update, params: { id: @fandom1.name, show: 'characters', status: 'unfilterable', fandom_string: "#{@fandom2.name}", selected_tags: [@character2.id], canonicals: [@character2.id] }
+ put :mass_update, params: { id: @fandom1.name, show: "characters", status: "unfilterable", fandom_string: @fandom2.name.to_s, selected_tags: [@character2.id], canonicals: [@character2.id] }
end
it "updates the tags successfully" do
@@ -231,6 +271,41 @@
end
end
+ describe "new" do
+ subject { get :new }
+ let(:success) do
+ expect(response).to have_http_status(:success)
+ end
+
+ it_behaves_like "an action only authorized admins can access", authorized_roles: wrangling_full_access_roles
+
+ context "when logged in as a tag wrangler" do
+ it "allows access" do
+ get :new
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
+
+ describe "show" do
+ context "when showing a banned tag" do
+ let(:tag) { create(:banned) }
+
+ subject { get :edit, params: { id: tag.name } }
+ let(:success) do
+ expect(response).to have_http_status(:success)
+ end
+
+ it_behaves_like "an action only authorized admins can access", authorized_roles: wrangling_read_access_roles
+
+ it "redirects with an error when not an admin" do
+ get :show, params: { id: tag.name }
+ it_redirects_to_with_error(tag_wranglings_path,
+ "Please log in as admin")
+ end
+ end
+ end
+
describe "show_hidden" do
let(:work) { create(:work) }
@@ -251,12 +326,17 @@
describe "edit" do
context "when editing a banned tag" do
- before do
- @tag = FactoryBot.create(:banned)
+ let(:tag) { create(:banned) }
+
+ subject { get :edit, params: { id: tag.name } }
+ let(:success) do
+ expect(response).to have_http_status(:success)
end
+ it_behaves_like "an action only authorized admins can access", authorized_roles: wrangling_read_access_roles
+
it "redirects with an error when not an admin" do
- get :edit, params: { id: @tag.name }
+ get :edit, params: { id: tag.name }
it_redirects_to_with_error(tag_wranglings_path,
"Please log in as admin")
end
@@ -299,16 +379,15 @@
end
end
- context "when logged in as an admin" do
- it "succeeds and redirects to the edit page" do
- fake_login_admin(create(:admin))
- put :update, params: { id: tag, tag: { syn_string: synonym.name }, commit: "Save changes" }
- it_redirects_to_with_notice(edit_tag_path(tag), "Tag was updated.")
-
- tag.reload
- expect(tag.merger_id).to eq(synonym.id)
- end
+ subject { put :update, params: { id: tag, tag: { syn_string: synonym.name }, commit: "Save changes" } }
+ let(:success) do
+ it_redirects_to_with_notice(edit_tag_path(tag), "Tag was updated.")
+ tag.reload
+ expect(tag.merger_id).to eq(synonym.id)
end
+
+ it_behaves_like "an action only authorized admins can access", authorized_roles: wrangling_full_access_roles
+
end
shared_examples "success message" do
@@ -369,7 +448,7 @@
end
context "when the associated tag has an invalid type" do
- # NOTE This will enter the associated tag into the freeform_string
+ # NOTE: This will enter the associated tag into the freeform_string
# field, which is not displayed on the form. This still might come up
# in the extremely rare case where a tag wrangler loads the form, a
# different tag wrangler goes in and changes the type of the tag being
diff --git a/spec/controllers/unsorted_tags_controller_spec.rb b/spec/controllers/unsorted_tags_controller_spec.rb
new file mode 100644
index 00000000000..4748903e243
--- /dev/null
+++ b/spec/controllers/unsorted_tags_controller_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe UnsortedTagsController do
+ include LoginMacros
+ include RedirectExpectationHelper
+
+ describe "POST #mass_update" do
+ context "when accessing as a guest" do
+ before do
+ post :mass_update
+ end
+
+ it "redirects with an error" do
+ it_redirects_to_with_error(
+ new_user_session_path,
+ "Sorry, you don't have permission to access the page you were trying to reach. Please log in."
+ )
+ end
+ end
+
+ context "when logged in as a non-tag-wrangler user" do
+ let(:user) { create(:user) }
+
+ before do
+ fake_login_known_user(user)
+ post :mass_update
+ end
+
+ it "redirects with an error" do
+ it_redirects_to_with_error(
+ user_path(user),
+ "Sorry, you don't have permission to access the page you were trying to reach."
+ )
+ end
+ end
+
+ context "when logged in as an admin with no roles" do
+ before do
+ fake_login_admin(create(:admin))
+ post :mass_update
+ end
+
+ it "redirects with an error" do
+ it_redirects_to_with_error(root_path, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+
+ (Admin::VALID_ROLES - %w[superadmin tag_wrangling]).each do |admin_role|
+ context "when logged in as a #{admin_role} admin" do
+ before do
+ fake_login_admin(create(:admin, roles: [admin_role]))
+ post :mass_update
+ end
+
+ it "redirects with an error" do
+ it_redirects_to_with_error(root_path, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/wrangling_guidelines_controller_spec.rb b/spec/controllers/wrangling_guidelines_controller_spec.rb
index f87eb72de2e..c66430023ac 100644
--- a/spec/controllers/wrangling_guidelines_controller_spec.rb
+++ b/spec/controllers/wrangling_guidelines_controller_spec.rb
@@ -7,14 +7,14 @@
let(:admin) { create(:admin) }
describe "GET #index" do
- let!(:guideline_1) { create(:wrangling_guideline, position: 9001) }
- let!(:guideline_2) { create(:wrangling_guideline, position: 2) }
- let!(:guideline_3) { create(:wrangling_guideline, position: 7) }
+ let!(:guideline1) { create(:wrangling_guideline, position: 9001) }
+ let!(:guideline2) { create(:wrangling_guideline, position: 2) }
+ let!(:guideline3) { create(:wrangling_guideline, position: 7) }
it "renders" do
get :index
expect(response).to render_template("index")
- expect(assigns(:wrangling_guidelines)).to eq([guideline_2, guideline_3, guideline_1])
+ expect(assigns(:wrangling_guidelines)).to eq([guideline2, guideline3, guideline1])
end
end
@@ -39,13 +39,28 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- before { fake_login_admin(admin) }
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
- it "renders" do
- get :new
- expect(response).to render_template("new")
- expect(assigns(:wrangling_guideline)).to be_a_new(WranglingGuideline)
+ it "redirects with error" do
+ fake_login_admin(admin)
+ get :new
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ it "renders" do
+ fake_login_admin(admin)
+ get :new
+ expect(response).to render_template("new")
+ expect(assigns(:wrangling_guideline)).to be_a_new(WranglingGuideline)
+ end
end
end
end
@@ -61,15 +76,32 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- let(:guideline) { create(:wrangling_guideline) }
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:guideline) { create(:wrangling_guideline) }
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "redirects with error" do
+ get :edit, params: { id: guideline.id }
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:guideline) { create(:wrangling_guideline) }
+ let(:admin) { create(:admin, roles: [role]) }
- before { fake_login_admin(admin) }
+ before { fake_login_admin(admin) }
- it "renders" do
- get :edit, params: { id: guideline.id }
- expect(response).to render_template("edit")
- expect(assigns(:wrangling_guideline)).to eq(guideline)
+ it "renders" do
+ get :edit, params: { id: guideline.id }
+ expect(response).to render_template("edit")
+ expect(assigns(:wrangling_guideline)).to eq(guideline)
+ end
end
end
end
@@ -85,17 +117,33 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- let!(:guideline_1) { create(:wrangling_guideline, position: 9001) }
- let!(:guideline_2) { create(:wrangling_guideline, position: 2) }
- let!(:guideline_3) { create(:wrangling_guideline, position: 7) }
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "redirects with error" do
+ get :manage
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let!(:guideline1) { create(:wrangling_guideline, position: 9001) }
+ let!(:guideline2) { create(:wrangling_guideline, position: 2) }
+ let!(:guideline3) { create(:wrangling_guideline, position: 7) }
+ let(:admin) { create(:admin, roles: [role]) }
- before { fake_login_admin(admin) }
+ before { fake_login_admin(admin) }
- it "renders" do
- get :manage
- expect(response).to render_template("manage")
- expect(assigns(:wrangling_guidelines)).to eq([guideline_2, guideline_3, guideline_1])
+ it "renders" do
+ get :manage
+ expect(response).to render_template("manage")
+ expect(assigns(:wrangling_guidelines)).to eq([guideline2, guideline3, guideline1])
+ end
end
end
end
@@ -111,24 +159,43 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- before { fake_login_admin(admin) }
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
- it "creates and redirects to new wrangling guideline" do
- title = "Wrangling 101"
- content = "JUST DO IT!"
- post :create, params: { wrangling_guideline: { title: title, content: content } }
+ before { fake_login_admin(admin) }
- guideline = WranglingGuideline.find_by_title(title)
- expect(assigns(:wrangling_guideline)).to eq(guideline)
- expect(assigns(:wrangling_guideline).content).to eq(sanitize_value("content", content))
- it_redirects_to_with_notice(wrangling_guideline_path(guideline), "Wrangling Guideline was successfully created.")
+ it "redirects with error" do
+ title = "Wrangling 101"
+ content = "JUST DO IT!"
+ post :create, params: { wrangling_guideline: { title: title, content: content } }
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
end
+ end
- it "renders new if create fails" do
- # Cannot save a content-free guideline
- post :create, params: { wrangling_guideline: { title: "Wrangling 101" } }
- expect(response).to render_template("new")
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "creates and redirects to new wrangling guideline" do
+ title = "Wrangling 101"
+ content = "JUST DO IT!"
+ post :create, params: { wrangling_guideline: { title: title, content: content } }
+
+ guideline = WranglingGuideline.find_by(title: title)
+ expect(assigns(:wrangling_guideline)).to eq(guideline)
+ expect(assigns(:wrangling_guideline).content).to eq(sanitize_value("content", content))
+ it_redirects_to_with_notice(wrangling_guideline_path(guideline), "Wrangling Guideline was successfully created.")
+ end
+
+ it "renders new if create fails" do
+ # Cannot save a content-free guideline
+ post :create, params: { wrangling_guideline: { title: "Wrangling 101" } }
+ expect(response).to render_template("new")
+ end
end
end
end
@@ -144,25 +211,44 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- let(:guideline) { create(:wrangling_guideline) }
-
- before { fake_login_admin(admin) }
-
- it "updates and redirects to updated wrangling guideline" do
- title = "Wrangling 101"
- expect(guideline.title).not_to eq(title)
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:guideline) { create(:wrangling_guideline) }
+ let(:admin) { create(:admin, roles: [role]) }
- put :update, params: { id: guideline.id, wrangling_guideline: { title: title } }
+ before { fake_login_admin(admin) }
- expect(assigns(:wrangling_guideline)).to eq(guideline)
- expect(assigns(:wrangling_guideline).title).to eq(title)
- it_redirects_to_with_notice(wrangling_guideline_path(guideline), "Wrangling Guideline was successfully updated.")
+ it "redirects with error" do
+ title = "Wrangling 101"
+ expect(guideline.title).not_to eq(title)
+ put :update, params: { id: guideline.id, wrangling_guideline: { title: title } }
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
end
+ end
- it "renders edit if update fails" do
- put :update, params: { id: guideline.id, wrangling_guideline: { title: nil } }
- expect(response).to render_template("edit")
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:guideline) { create(:wrangling_guideline) }
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "updates and redirects to updated wrangling guideline" do
+ title = "Wrangling 101"
+ expect(guideline.title).not_to eq(title)
+
+ put :update, params: { id: guideline.id, wrangling_guideline: { title: title } }
+
+ expect(assigns(:wrangling_guideline)).to eq(guideline)
+ expect(assigns(:wrangling_guideline).title).to eq(title)
+ it_redirects_to_with_notice(wrangling_guideline_path(guideline), "Wrangling Guideline was successfully updated.")
+ end
+
+ it "renders edit if update fails" do
+ put :update, params: { id: guideline.id, wrangling_guideline: { title: nil } }
+ expect(response).to render_template("edit")
+ end
end
end
end
@@ -178,25 +264,45 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- let!(:guideline_1) { create(:wrangling_guideline, position: 1) }
- let!(:guideline_2) { create(:wrangling_guideline, position: 2) }
- let!(:guideline_3) { create(:wrangling_guideline, position: 3) }
-
- before { fake_login_admin(admin) }
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let!(:guideline1) { create(:wrangling_guideline, position: 1) }
+ let!(:guideline2) { create(:wrangling_guideline, position: 2) }
+ let!(:guideline3) { create(:wrangling_guideline, position: 3) }
+ let(:admin) { create(:admin, roles: [role]) }
- it "updates positions and redirects to index" do
- expect(WranglingGuideline.order('position ASC')).to eq([guideline_1, guideline_2, guideline_3])
- post :update_positions, params: { wrangling_guidelines: [3, 2, 1] }
+ before { fake_login_admin(admin) }
- expect(assigns(:wrangling_guidelines)).to eq(WranglingGuideline.order('position ASC'))
- expect(assigns(:wrangling_guidelines)).to eq([guideline_3, guideline_2, guideline_1])
- it_redirects_to_with_notice(wrangling_guidelines_path, "Wrangling Guidelines order was successfully updated.")
+ it "redirects with error" do
+ expect(WranglingGuideline.order("position ASC")).to eq([guideline1, guideline2, guideline3])
+ post :update_positions, params: { wrangling_guidelines: [3, 2, 1] }
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
end
+ end
- it "redirects to index given no params" do
- post :update_positions
- it_redirects_to(wrangling_guidelines_path)
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let!(:guideline1) { create(:wrangling_guideline, position: 1) }
+ let!(:guideline2) { create(:wrangling_guideline, position: 2) }
+ let!(:guideline3) { create(:wrangling_guideline, position: 3) }
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "updates positions and redirects to index" do
+ expect(WranglingGuideline.order("position ASC")).to eq([guideline1, guideline2, guideline3])
+ post :update_positions, params: { wrangling_guidelines: [3, 2, 1] }
+
+ expect(assigns(:wrangling_guidelines)).to eq(WranglingGuideline.order("position ASC"))
+ expect(assigns(:wrangling_guidelines)).to eq([guideline3, guideline2, guideline1])
+ it_redirects_to_with_notice(wrangling_guidelines_path, "Wrangling Guidelines order was successfully updated.")
+ end
+
+ it "redirects to index given no params" do
+ post :update_positions
+ it_redirects_to(wrangling_guidelines_path)
+ end
end
end
end
@@ -212,15 +318,33 @@
it_redirects_to_with_notice(root_path, "I'm sorry, only an admin can look at that area")
end
- context "when logged in as admin" do
- let(:guideline) { create(:wrangling_guideline) }
+ %w[board communications translation policy_and_abuse docs support open_doors].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:guideline) { create(:wrangling_guideline) }
+ let(:admin) { create(:admin, roles: [role]) }
+
+ before { fake_login_admin(admin) }
+
+ it "redirects with error" do
+ delete :destroy, params: { id: guideline.id }
+
+ it_redirects_to_with_error(root_url, "Sorry, only an authorized admin can access the page you were trying to reach.")
+ end
+ end
+ end
+
+ %w[tag_wrangling superadmin].each do |role|
+ context "when logged in as an admin with #{role} role" do
+ let(:guideline) { create(:wrangling_guideline) }
+ let(:admin) { create(:admin, roles: [role]) }
- before { fake_login_admin(admin) }
+ before { fake_login_admin(admin) }
- it "deletes and redirects to index" do
- delete :destroy, params: { id: guideline.id }
- expect(WranglingGuideline.find_by_id(guideline.id)).to be_nil
- it_redirects_to_with_notice(wrangling_guidelines_path, "Wrangling Guideline was successfully deleted.")
+ it "deletes and redirects to index" do
+ delete :destroy, params: { id: guideline.id }
+ expect(WranglingGuideline.find_by(id: guideline.id)).to be_nil
+ it_redirects_to_with_notice(wrangling_guidelines_path, "Wrangling Guideline was successfully deleted.")
+ end
end
end
end
diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb
index f2fc7c3e5ef..b0f209dc798 100644
--- a/spec/mailers/user_mailer_spec.rb
+++ b/spec/mailers/user_mailer_spec.rb
@@ -149,7 +149,7 @@
title = "Façade"
title2 = Faker::Book.title
- subject(:email) { UserMailer.claim_notification(author.id, [work.id, work2.id], true) }
+ subject(:email) { UserMailer.claim_notification(author.id, [work.id, work2.id]) }
let(:author) { create(:user) }
let(:work) { create(:work, title: title, authors: [author.pseuds.first]) }
diff --git a/test/mailers/previews/user_mailer_preview.rb b/test/mailers/previews/user_mailer_preview.rb
index 19ae2739bb0..4310f51a96a 100644
--- a/test/mailers/previews/user_mailer_preview.rb
+++ b/test/mailers/previews/user_mailer_preview.rb
@@ -34,10 +34,24 @@ def feedback
UserMailer.feedback(feedback.id)
end
- def claim_notification_registered
+ def claim_notification
work = create(:work)
creator_id = work.pseuds.first.user.id
- UserMailer.claim_notification(creator_id, [work.id], true)
+ UserMailer.claim_notification(creator_id, [work.id])
+ end
+
+ def invite_request_declined
+ user = create(:user, :for_mailer_preview)
+ total = params[:total] || 1
+ reason = "test reason"
+ UserMailer.invite_request_declined(user.id, total, reason)
+ end
+
+ def change_email
+ user = create(:user, :for_mailer_preview)
+ old_email = user.email
+ new_email = "new_email"
+ UserMailer.change_email(user.id, old_email, new_email)
end
private