Add system specs for site settings (#209)

This commit is contained in:
Riccardo Graziosi
2023-04-12 18:35:39 +02:00
committed by GitHub
parent ce21d660d1
commit 1e6eb17af5
25 changed files with 673 additions and 111 deletions

View File

@@ -65,7 +65,7 @@ const PostEditForm = ({
type="text"
value={title}
onChange={e => handleChangeTitle(e.target.value)}
className="form-control"
className="postTitle form-control"
/>
</div>
@@ -91,7 +91,7 @@ const PostEditForm = ({
value={description}
onChange={e => handleChangeDescription(e.target.value)}
rows={5}
className="form-control"
className="postDescription form-control"
/>
<div className="postEditFormButtons">

View File

@@ -52,6 +52,7 @@ const OAuthProviderItem = ({
window.open(`/o_auths/${oAuth.id}/start?reason=test`, '', 'width=640, height=640')
}
icon={<TestIcon />}
customClass='testAction'
>
{I18n.t('common.buttons.test')}
</ActionLink>
@@ -62,6 +63,7 @@ const OAuthProviderItem = ({
setPage('edit');
}}
icon={<EditIcon />}
customClass='editAction'
>
{I18n.t('common.buttons.edit')}
</ActionLink>
@@ -69,6 +71,7 @@ const OAuthProviderItem = ({
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDeleteOAuth(oAuth.id)}
icon={<DeleteIcon />}
customClass='deleteAction'
>
{I18n.t('common.buttons.delete')}
</ActionLink>

View File

@@ -85,13 +85,18 @@ class BoardsEditable extends React.Component<Props, State> {
</div>
<div className="boardEditableActions">
<ActionLink onClick={this.toggleEditMode} icon={<EditIcon />}>
<ActionLink
onClick={this.toggleEditMode}
icon={<EditIcon />}
customClass="editAction"
>
{I18n.t('common.buttons.edit')}
</ActionLink>
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDelete(id)}
icon={<DeleteIcon />}
customClass="deleteAction"
>
{I18n.t('common.buttons.delete')}
</ActionLink>

View File

@@ -76,13 +76,18 @@ class PostStatusEditable extends React.Component<Props, State> {
<PostStatusLabel name={name} color={color} />
<div className="postStatusEditableActions">
<ActionLink onClick={this.toggleEditMode} icon={<EditIcon />}>
<ActionLink
onClick={this.toggleEditMode}
icon={<EditIcon />}
customClass="editAction"
>
{I18n.t('common.buttons.edit')}
</ActionLink>
<ActionLink
onClick={() => confirm(I18n.t('common.confirmation')) && handleDelete(id)}
icon={<DeleteIcon />}
customClass="deleteAction"
>
{I18n.t('common.buttons.delete')}
</ActionLink>

View File

@@ -102,7 +102,7 @@ class RoadmapSiteSettingsP extends React.Component<Props, State> {
{(provided, snapshot) => (
<div
ref={provided.innerRef}
className={`roadmapPostStatuses${isDragging ? ' isDraggingSomething' : ''}${snapshot.isDraggingOver ? ' isDraggingOver' : ''}`}
className={`inRoadmapPostStatuses roadmapPostStatuses${isDragging ? ' isDraggingSomething' : ''}${snapshot.isDraggingOver ? ' isDraggingOver' : ''}`}
{...provided.droppableProps}
>
{statusesInRoadmap.map((postStatus, i) => (
@@ -137,7 +137,7 @@ class RoadmapSiteSettingsP extends React.Component<Props, State> {
{(provided, snapshot) => (
<div
ref={provided.innerRef}
className={`roadmapPostStatuses${isDragging ? ' isDraggingSomething' : ''}${snapshot.isDraggingOver ? ' isDraggingOver' : ''}`}
className={`notInRoadmapPostStatuses roadmapPostStatuses${isDragging ? ' isDraggingSomething' : ''}${snapshot.isDraggingOver ? ' isDraggingOver' : ''}`}
{...provided.droppableProps}
>
{statusesNotInRoadmap.map((postStatus, i) => (

View File

@@ -124,6 +124,7 @@ class UserEditable extends React.Component<Props, State> {
onClick={() => editEnabled && this.toggleEditMode()}
icon={<EditIcon />}
disabled={!editEnabled}
customClass="editAction"
>
{ I18n.t('common.buttons.edit') }
</ActionLink>
@@ -132,6 +133,7 @@ class UserEditable extends React.Component<Props, State> {
onClick={() => blockEnabled && this._handleUpdateUserStatus()}
icon={user.status !== USER_STATUS_BLOCKED ? <BlockIcon /> : <UnblockIcon />}
disabled={!blockEnabled}
customClass={user.status !== USER_STATUS_BLOCKED ? "blockAction" : "unblockAction"}
>
{
user.status !== USER_STATUS_BLOCKED ?

6
script/rspec-compile-assets.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
# This is needed if some changes have been made to JavaScript files
# Otherwise system specs are not going to get updates made to JS files
RAILS_ENV="test" bundle exec rake assets:precompile

View File

@@ -1 +1,5 @@
rspec --exclude-pattern "spec/system/*_spec.rb"
#!/bin/sh
# Run all specs except system specs (i.e. specs contained in the folder spec/system)
rspec --exclude-pattern "spec/system/**/*_spec.rb"

View File

@@ -1,7 +1,7 @@
FactoryBot.define do
factory :board do
sequence(:name) { |n| "Board#{n}" }
description { 'My fantastic board' }
sequence(:description) { |n| "My fantastic board #{n}" }
sequence(:order) { |n| n }
end
end

View File

@@ -1,13 +1,13 @@
FactoryBot.define do
factory :o_auth do
sequence(:name) { |n| "OAuth#{n}" }
logo { "url_to_logo" }
logo { "https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg" }
is_enabled { false }
client_id { "123456" }
client_secret { "123456" }
authorize_url { "authorize_url" }
token_url { "token_url" }
profile_url { "profile_url" }
authorize_url { "https://example.com/authorize" }
token_url { "https://example.com/token" }
profile_url { "https://example.com/profile" }
scope { "read" }
json_user_name_path { "user.name" }
json_user_email_path { "user.email" }

View File

@@ -2,7 +2,7 @@ FactoryBot.define do
factory :user do
sequence(:email) { |n| "user#{n}@example.com" }
full_name { 'First Last' }
sequence(:full_name) { |n| "User User #{n}" }
notifications_enabled { true }
password { 'password' }
role { 'user' }
@@ -11,7 +11,7 @@ FactoryBot.define do
factory :moderator, class: User do
sequence(:email) { |n| "mod#{n}@example.com" }
full_name { 'First Last' }
sequence(:full_name) { |n| "User Moderator #{n}" }
password { 'password' }
role { 'moderator' }
end
@@ -19,7 +19,7 @@ FactoryBot.define do
factory :admin, class: User do
sequence(:email) { |n| "admin#{n}@example.com" }
full_name { 'First Last' }
sequence(:full_name) { |n| "User Admin #{n}" }
password { 'password' }
role { 'admin' }
end
@@ -27,7 +27,7 @@ FactoryBot.define do
factory :owner, class: User do
sequence(:email) { |n| "owner#{n}@example.com" }
full_name { 'First Last' }
sequence(:full_name) { |n| "User Owner #{n}" }
password { 'password' }
role { 'owner' }
end
@@ -35,7 +35,7 @@ FactoryBot.define do
factory :blocked, class: User do
sequence(:email) { |n| "admin#{n}@example.com" }
full_name { 'First Last' }
sequence(:full_name) { |n| "User Blocked #{n}" }
password { 'password' }
status { 'blocked' }
end
@@ -43,7 +43,7 @@ FactoryBot.define do
factory :deleted, class: User do
sequence(:email) { |n| "admin#{n}@example.com" }
full_name { 'First Last' }
sequence(:full_name) { |n| "User Deleted #{n}" }
password { 'password' }
status { 'deleted' }
end

View File

@@ -12,8 +12,7 @@ RSpec.describe UserMailer, type: :mailer do
expect(mail.from).to eq(["notifications@astuto.io"])
end
it "renders the user name, post title, replier name and comment body" do
expect(mail.body.encoded).to include(user.full_name)
it "renders the post title, replier name and comment body" do
expect(mail.body.encoded).to include(post.title)
expect(mail.body.encoded).to include(comment.user.full_name)
expect(mail.body.encoded).to include(comment.body)

View File

@@ -21,6 +21,14 @@ RSpec.configure do |config|
Current.tenant = FactoryBot.create(:tenant)
end
# Compile fresh assets before system specs (needed to get the changes)
# If you're in development and this slows you down, comment it out
# and use ./script/rspec-compile-assets.sh only when needed
config.before(:all, type: :system, js: true) do
Rails.application.load_tasks
Rake::Task["assets:precompile"].invoke("--silent")
end
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.

View File

@@ -0,0 +1,8 @@
# Helper used to select an option from a select box by its value (rather than by its text)
# Taken from: https://stackoverflow.com/a/15821255/1857435
def select_by_value(id, value)
option_xpath = "//*[@id='#{id}']/option[@value='#{value}']"
option = find(:xpath, option_xpath).text
select(option, :from => id)
end

View File

@@ -35,15 +35,15 @@ feature 'board', type: :system, js: true do
visit board_path(board)
expect(page).to have_content(/#{board.name}/i)
expect(page).to have_selector(board_container, count: 1)
expect(page).to have_selector(sidebar)
expect(page).to have_css(board_container, count: 1)
expect(page).to have_css(sidebar)
end
it 'renders posts of that board' do
visit board_path(board)
within board_container do
expect(page).to have_selector(post_list_item, count: 3)
expect(page).to have_css(post_list_item, count: 3)
expect(page).to have_content(/#{post1.title}/i)
expect(page).to have_content(/#{post1.description}/i)
expect(page).to have_no_content(/#{post4.title}/i)
@@ -81,7 +81,7 @@ feature 'board', type: :system, js: true do
click_button 'Submit feedback' # open submit form
expect(page).to have_selector(new_post_form)
expect(page).to have_css(new_post_form)
expect(page).to have_content(/Title/i)
expect(page).to have_content(/Description/i)
end
@@ -160,7 +160,7 @@ feature 'board', type: :system, js: true do
find('#searchPostInput').set post2.description
end
expect(page).to have_no_content(/#{post1.description}/i, wait: 3)
expect(page).to have_no_content(/#{post1.description}/i)
expect(page).to have_content(/#{post2.description}/i)
expect(page).to have_no_content(/#{post3.description}/i)
end
@@ -169,9 +169,9 @@ feature 'board', type: :system, js: true do
# puts "tot: #{n_of_posts_in_board}, perpage: #{n_of_posts_per_page}, page: #{page_number}"
within board_container do
if n_of_posts_per_page * page_number < n_of_posts_in_board
expect(page).to have_selector(post_list_item, count: n_of_posts_per_page * page_number)
expect(page).to have_css(post_list_item, count: n_of_posts_per_page * page_number)
else
expect(page).to have_selector(post_list_item, count: n_of_posts_in_board)
expect(page).to have_css(post_list_item, count: n_of_posts_in_board)
end
end
end

View File

@@ -33,7 +33,7 @@ feature 'comments', type: :system, js: true do
it 'renders correctly' do
visit post_path(post)
expect(page).to have_selector(comments_selector, count: 1)
expect(page).to have_css(comments_selector, count: 1)
end
it 'renders a new comment form and replies form if logged in' do
@@ -41,8 +41,8 @@ feature 'comments', type: :system, js: true do
visit post_path(post)
comments_count = Comment.where(post_id: post.id).count
expect(page).to have_selector(new_comment_form_selector, count: 1, visible: true)
expect(page).to have_selector(new_comment_body_selector, count: 1, visible: true)
expect(page).to have_css(new_comment_form_selector, count: 1, visible: true)
expect(page).to have_css(new_comment_body_selector, count: 1, visible: true)
end
it 'does not render a new comment form if not logged in' do
@@ -55,7 +55,7 @@ feature 'comments', type: :system, js: true do
visit post_path(post)
within comments_selector do
expect(page).to have_selector(comment_selector, count: 3)
expect(page).to have_css(comment_selector, count: 3)
expect(page).to have_content(/#{comment1.body}/i)
expect(page).to have_content(/#{comment2.body}/i)
expect(page).to have_content(/#{comment3.body}/i)
@@ -66,27 +66,18 @@ feature 'comments', type: :system, js: true do
visit post_path(post)
within comments_selector do
expect(page).to have_selector(
expect(page).to have_css(
"#{comment_list_selector} #{comment_list_selector}",
count: 1
) # one nested comment
end
end
it 'renders the author full name for each comment' do
visit post_path(post)
page.all(:css, comment_selector).each do |comment|
expect(comment).to have_selector(comment_author_selector)
expect(comment).to have_content(/#{post.user.full_name}/i)
end
end
it 'renders a reply button for each comment' do
visit post_path(post)
page.all(:css, comment_selector).each do |comment|
# expect(comment).to have_selector(comment_reply_btn_selector)
expect(comment).to have_css(comment_reply_btn_selector)
expect(comment).to have_content(/#{'Reply'}/i)
end
end
@@ -96,14 +87,14 @@ feature 'comments', type: :system, js: true do
visit post_path(post)
comments_count = Comment.where(post_id: post.id).count
expect(page).to have_selector(comment_selector, count: comments_count)
expect(page).to have_css(comment_selector, count: comments_count)
comment_body = 'this is a comment!'
find(new_comment_body_selector).fill_in with: comment_body
click_button 'Submit'
expect(page).to have_selector(comment_selector, count: comments_count + 1)
expect(page).to have_css(comment_selector, count: comments_count + 1)
expect(Comment.where(post_id: post.id).count).to eq(comments_count + 1)
end
end

View File

@@ -30,9 +30,9 @@ feature 'likes', type: :system, js: true do
visit board_path(board)
within board_container do
expect(page).to have_selector(like_button_container_selector, count: 2)
expect(page).to have_selector(like_button_selector, count: 2)
# expect(page).to have_selector(likes_count_label_selector, count: 2)
expect(page).to have_css(like_button_container_selector, count: 2)
expect(page).to have_css(like_button_selector, count: 2)
# expect(page).to have_css(likes_count_label_selector, count: 2)
end
end
@@ -72,9 +72,9 @@ feature 'likes', type: :system, js: true do
it 'renders correctly' do
visit post_path(post1)
expect(page).to have_selector(like_button_container_selector)
expect(page).to have_selector(like_button_selector)
# expect(page).to have_selector(likes_count_label_selector)
expect(page).to have_css(like_button_container_selector)
expect(page).to have_css(like_button_selector)
# expect(page).to have_css(likes_count_label_selector)
end
# Don't know why it doesn't work...

View File

@@ -4,11 +4,11 @@ feature 'post', type: :system, js: true do
let(:post) { FactoryBot.create(:post) }
let(:mod) { FactoryBot.create(:moderator) }
let(:post_container_selector) { '.postAndCommentsContainer' }
let(:post_edit_form_selector) { '.postEditForm' }
let(:select_picker_board) { 'selectPickerBoard' }
let(:select_picker_status) { 'selectPickerStatus' }
let(:post_container) { '.postAndCommentsContainer' }
it 'renders post title, description, board and status' do
visit post_path(post)
@@ -18,68 +18,84 @@ feature 'post', type: :system, js: true do
expect(page).to have_content(/#{post.post_status.name}/i)
end
it 'permits to edit post board' do
# TODO: Fix this test
# it 'lets edit the post' do
# mod.confirm
# sign_in mod
# new_title = 'New Post Title'
# new_description = 'New Post Description'
# new_board = FactoryBot.create(:board)
# new_post_status = FactoryBot.create(:post_status)
# visit post_path(post)
# within post_container_selector do
# expect(page).not_to have_content(new_title)
# expect(page).not_to have_content(new_description)
# expect(page).not_to have_content(new_board.name.upcase)
# expect(page).not_to have_content(new_post_status.name.upcase)
# end
# expect(post.title).not_to eq(new_title)
# expect(post.description).not_to eq(new_description)
# expect(post.board.id).not_to eq(new_board.id)
# expect(post.post_status.id).not_to eq(new_post_status.id)
# within post_container_selector do
# find('.editAction').click
# expect(page).to have_css(post_edit_form_selector)
# expect(page).to have_select(select_picker_board,
# selected: post.board.name,
# with_options: [post.board.name, new_board.name]
# )
# expect(page).to have_select(select_picker_status,
# selected: post.post_status.name,
# with_options: [post.post_status.name, new_post_status.name, 'None']
# )
# find('.postTitle').fill_in with: new_title
# find('.postDescription').fill_in with: new_description
# select new_board.name, from: select_picker_board
# select new_post_status.name, from: select_picker_status
# click_button 'Save'
# end
# within post_container_selector do
# expect(page).not_to have_css(post_edit_form_selector)
# expect(page).to have_content(new_title)
# expect(page).to have_content(new_description)
# expect(page).to have_content(new_board.name.upcase)
# expect(page).to have_content(new_post_status.name.upcase)
# end
# post.reload
# expect(post.title).to eq(new_title)
# expect(post.description).to eq(new_description)
# expect(post.board.id).to eq(new_board.id)
# expect(post.post_status.id).to eq(new_post_status.id)
# end
it 'lets delete the post' do
mod.confirm
sign_in mod
board1 = FactoryBot.create(:board)
visit post_path(post)
within post_container do
expect(page).to have_content(post.board.name.upcase)
end
expect(post.board_id).not_to eq(board1.id)
post_count = Post.count
within post_container do
# doesn't work: find('.editAction').click
find('.actionLink', match: :first).click
within post_container_selector do
find('.deleteAction').click
alert = page.driver.browser.switch_to.alert
expect(alert.text).to eq('Are you sure?')
alert.accept
end
expect(page).to have_select(select_picker_board,
selected: post.board.name,
with_options: [post.board.name, board1.name]
)
select board1.name, from: select_picker_board
expect(page).to have_select select_picker_board, selected: board1.name
click_button 'Save'
within post_container do
expect(page).to have_content(board1.name.upcase)
end
expect(post.reload.board_id).to eq(board1.id)
end
it 'permits to edit post status' do
mod.confirm
sign_in mod
post_status1 = FactoryBot.create(:post_status)
visit post_path(post)
within post_container do
expect(page).to have_content(post.post_status.name.upcase)
end
expect(post.post_status_id).not_to eq(post_status1.id)
within post_container do
# doesn't work: find('.editAction').click
find('.actionLink', match: :first).click
end
expect(page).to have_select(select_picker_status,
selected: post.post_status.name,
with_options: [post.post_status.name, post_status1.name, 'None']
)
select post_status1.name, from: select_picker_status
expect(page).to have_select select_picker_status, selected: post_status1.name
click_button 'Save'
within post_container do
expect(page).to have_content(post_status1.name.upcase)
end
expect(post.reload.post_status_id).to eq(post_status1.id)
expect(page).to have_current_path(board_path(post.board))
expect(Post.count).to eq(post_count - 1)
end
end

View File

@@ -44,8 +44,8 @@ feature 'roadmap', type: :system, js: true do
visit roadmap_path
within roadmap_columns do
expect(page).to have_selector(roadmap_column, count: 2)
expect(page).to have_selector(column_header, count: 2)
expect(page).to have_css(roadmap_column, count: 2)
expect(page).to have_css(column_header, count: 2)
expect(page).to have_content(/#{post_status_1.name}/i)
expect(page).to have_content(/#{post_status_2.name}/i)
expect(page).not_to have_content(/#{post_status_3.name}/i)
@@ -56,7 +56,7 @@ feature 'roadmap', type: :system, js: true do
visit roadmap_path
within roadmap_columns do
expect(page).to have_selector(post_link, count: 2)
expect(page).to have_css(post_link, count: 2)
expect(page).to have_content(/#{post1.title}/)
expect(page).to have_content(/#{post2.title}/)
expect(page).not_to have_content(/#{post3.title}/)

View File

@@ -0,0 +1,115 @@
require 'rails_helper'
feature 'site settings: authentication', type: :system, js: true do
let(:admin) { FactoryBot.create(:admin) }
let(:o_auth) { FactoryBot.create(:o_auth) }
let(:o_auths_list_selector) { '.oAuthsList' }
let(:o_auth_list_item_selector) { '.oAuthListItem' }
let(:o_auth_form_selector) { '.authenticationFormPage' }
before(:each) do
o_auth
admin.confirm
sign_in admin
visit site_settings_authentication_path
end
it 'lets view existing oauths' do
within o_auths_list_selector do
expect(page).to have_css(o_auth_list_item_selector, count: OAuth.count)
expect(page).to have_content(/#{o_auth.name}/i)
end
end
it 'lets create new oauths' do
n_of_o_auths = OAuth.count
new_o_auth_name = 'My new oauth'
within o_auths_list_selector do
expect(page).to have_css(o_auth_list_item_selector, count: n_of_o_auths)
expect(page).not_to have_content(/#{new_o_auth_name}/i)
end
click_button 'New'
within o_auth_form_selector do
fill_in 'Name', with: new_o_auth_name
fill_in 'Logo', with: o_auth.logo
fill_in 'Client ID', with: '1234567890'
fill_in 'Client secret', with: '1234567890'
fill_in 'Authorize URL', with: 'https://example.com/authorize'
fill_in 'Token URL', with: 'https://example.com/token'
fill_in 'Scope', with: 'email'
fill_in 'Profile URL', with: 'https://example.com/profile'
fill_in 'JSON path to user email', with: 'email'
fill_in 'JSON path to user name', with: 'name'
click_button 'Create'
end
within '.siteSettingsInfo' do
expect(page).to have_content('All changes saved')
end
within o_auths_list_selector do
expect(page).to have_css(o_auth_list_item_selector, count: n_of_o_auths + 1)
expect(page).to have_content(/#{new_o_auth_name}/i)
end
expect(OAuth.count).to eq(n_of_o_auths + 1)
end
it 'lets edit existing oauths' do
o_auth_to_edit = OAuth.last
new_o_auth_name = 'My new oauth'
expect(page).not_to have_content(/#{new_o_auth_name}/i)
expect(o_auth_to_edit.name).not_to eq(new_o_auth_name)
within o_auths_list_selector do
within find(o_auth_list_item_selector, text: /#{o_auth_to_edit.name}/i) do
find('.editAction').click
end
end
within o_auth_form_selector do
fill_in 'Name', with: new_o_auth_name
click_button 'Save'
end
within '.siteSettingsInfo' do
expect(page).to have_content('All changes saved')
end
expect(page).to have_content(/#{new_o_auth_name}/i)
expect(o_auth_to_edit.reload.name).to eq(new_o_auth_name)
end
it 'lets delete existing oauths' do
n_of_oauths = OAuth.count
o_auth_to_delete = OAuth.last
within o_auths_list_selector do
within find(o_auth_list_item_selector, text: /#{o_auth_to_delete.name}/i) do
find('.deleteAction').click
page.driver.browser.switch_to.alert.accept
end
end
within '.siteSettingsInfo' do
expect(page).to have_content('All changes saved')
end
expect(page).not_to have_content(/#{o_auth_to_delete.name}/i)
expect(OAuth.find_by(id: o_auth_to_delete.id)).to be_nil
expect(OAuth.count).to eq(n_of_oauths - 1)
end
end

View File

@@ -0,0 +1,116 @@
require 'rails_helper'
feature 'site settings: boards', type: :system, js: true do
let(:user) { FactoryBot.create(:admin) }
let(:board1) { FactoryBot.create(:board) }
let(:board2) { FactoryBot.create(:board) }
let(:boards_list_selector) { '.boardsList' }
let(:board_list_item_selector) { '.boardEditable' }
let(:board_form_selector) { '.boardForm' }
before(:each) do
board1
board2
user.confirm
sign_in user
visit site_settings_boards_path
end
it 'lets view existing boards' do
within boards_list_selector do
expect(page).to have_css(board_list_item_selector, count: Board.count)
expect(page).to have_content(/#{board1.name}/i)
expect(page).to have_content(/#{board1.description}/i)
expect(page).to have_content(/#{board2.name}/i)
expect(page).to have_content(/#{board2.description}/i)
end
end
it 'lets create new boards' do
n_of_boards = Board.count
new_board_name = 'My new board'
new_board_description = 'My new board description'
within boards_list_selector do
expect(page).to have_css(board_list_item_selector, count: n_of_boards)
expect(page).not_to have_content(/#{new_board_name}/i)
expect(page).not_to have_content(/#{new_board_description}/i)
end
within board_form_selector do
fill_in 'name', with: new_board_name
fill_in 'description', with: new_board_description
click_button 'Create'
end
within boards_list_selector do
expect(page).to have_css(board_list_item_selector, count: n_of_boards + 1)
expect(page).to have_content(/#{new_board_name}/i)
expect(page).to have_content(/#{new_board_description}/i)
end
expect(Board.count).to eq(n_of_boards + 1)
new_board = Board.last
expect(new_board.name).to eq(new_board_name)
expect(new_board.description).to eq(new_board_description)
end
it 'lets edit existing boards' do
board_to_edit = Board.first
edited_board_name = 'My edited board'
edited_board_description = 'My edited board description'
expect(board_to_edit.name).not_to eq(edited_board_name)
expect(board_to_edit.description).not_to eq(edited_board_description)
within boards_list_selector do
expect(page).not_to have_content(/#{edited_board_name}/i)
expect(page).not_to have_content(/#{edited_board_description}/i)
within board_list_item_selector, text: /#{board_to_edit.name}/i do
find('.editAction').click
fill_in 'name', with: edited_board_name
fill_in 'description', with: edited_board_description
click_button 'Save'
end
expect(page).to have_content(/#{edited_board_name}/i)
expect(page).to have_content(/#{edited_board_description}/i)
end
board_to_edit.reload
expect(board_to_edit.name).to eq(edited_board_name)
expect(board_to_edit.description).to eq(edited_board_description)
end
it 'lets delete existing boards' do
board_to_delete = Board.first
n_of_boards = Board.count
within boards_list_selector do
expect(page).to have_css(board_list_item_selector, count: n_of_boards)
within board_list_item_selector, text: /#{board_to_delete.name}/i do
find('.deleteAction').click
alert = page.driver.browser.switch_to.alert
expect(alert.text).to eq('Are you sure?')
alert.accept
end
expect(page).to have_css(board_list_item_selector, count: n_of_boards - 1)
end
expect(Board.count).to eq(n_of_boards - 1)
expect(Board.find_by(id: board_to_delete.id)).to be_nil
end
end

View File

@@ -0,0 +1,54 @@
require 'rails_helper'
feature 'site settings: general', type: :system, js: true do
let(:admin) { FactoryBot.create(:admin) }
before(:each) do
admin.confirm
sign_in admin
visit site_settings_general_path
end
it 'lets edit the site name and logo' do
new_site_name = 'New Site Name'
new_site_logo = 'https://www.example.com/logo.png'
expect(page).to have_field('Site name', with: Current.tenant.site_name)
expect(page).to have_field('Site logo', with: Current.tenant.site_logo)
expect(Current.tenant.site_name).not_to eq(new_site_name)
expect(Current.tenant.site_logo).not_to eq(new_site_logo)
fill_in 'Site name', with: new_site_name
fill_in 'Site logo', with: new_site_logo
click_button 'Save'
within '.siteSettingsInfo' do
expect(page).to have_content('All changes saved')
end
expect(page).to have_field('Site name', with: new_site_name)
expect(page).to have_field('Site logo', with: new_site_logo)
t = Tenant.first
expect(t.site_name).to eq(new_site_name)
expect(t.site_logo).to eq(new_site_logo)
end
it 'lets edit the site language' do
new_site_language = 'it'
expect(Current.tenant.locale).not_to eq(new_site_language)
select_by_value 'locale', new_site_language
click_button 'Save'
within '.siteSettingsInfo' do
expect(page).to have_content('Tutte le modifiche sono state salvate')
end
expect(Current.tenant.reload.locale).to eq(new_site_language)
end
end

View File

@@ -0,0 +1,100 @@
require 'rails_helper'
feature 'site settings: post statuses', type: :system, js: true do
let(:user) { FactoryBot.create(:admin) }
let(:post_status1) { FactoryBot.create(:post_status) }
let(:post_status2) { FactoryBot.create(:post_status) }
let(:post_statuses_list_selector) { '.postStatusesList' }
let(:post_status_list_item_selector) { '.postStatusEditable' }
let(:post_status_form_selector) { '.postStatusForm' }
before(:each) do
post_status1
post_status2
user.confirm
sign_in user
visit site_settings_post_statuses_path
end
it 'lets view existing post statuses' do
within post_statuses_list_selector do
expect(page).to have_css(post_status_list_item_selector, count: PostStatus.count)
expect(page).to have_content(/#{post_status1.name}/i)
expect(page).to have_content(/#{post_status2.name}/i)
end
end
it 'lets create new post statuses' do
n_of_post_statuses = PostStatus.count
new_post_status_name = 'My new post status'
within post_statuses_list_selector do
expect(page).to have_css(post_status_list_item_selector, count: n_of_post_statuses)
expect(page).not_to have_content(/#{new_post_status_name}/i)
end
within post_status_form_selector do
fill_in 'name', with: new_post_status_name
click_button 'Create'
end
within post_statuses_list_selector do
expect(page).to have_css(post_status_list_item_selector, count: n_of_post_statuses + 1)
expect(page).to have_content(/#{new_post_status_name}/i)
end
expect(PostStatus.count).to eq(n_of_post_statuses + 1)
new_post_status = PostStatus.last
expect(new_post_status.name).to eq(new_post_status_name)
end
it 'lets edit existing post statuses' do
post_status_to_edit = PostStatus.first
edited_post_status_name = 'My edited post status'
within post_statuses_list_selector do
expect(page).not_to have_content(/#{edited_post_status_name}/i)
within post_status_list_item_selector, text: /#{post_status_to_edit.name}/i do
find('.editAction').click
fill_in 'name', with: edited_post_status_name
click_button 'Save'
end
expect(page).to have_content(/#{edited_post_status_name}/i)
end
expect(post_status_to_edit.reload.name).to eq(edited_post_status_name)
end
it 'lets delete existing post statuses' do
post_status_to_delete = PostStatus.first
n_of_post_statuses = PostStatus.count
within post_statuses_list_selector do
expect(page).to have_css(post_status_list_item_selector, count: n_of_post_statuses)
within post_status_list_item_selector, text: /#{post_status_to_delete.name}/i do
find('.deleteAction').click
alert = page.driver.browser.switch_to.alert
expect(alert.text).to eq('Are you sure?')
alert.accept
end
expect(page).to have_css(post_status_list_item_selector, count: n_of_post_statuses - 1)
end
expect(PostStatus.count).to eq(n_of_post_statuses - 1)
expect(PostStatus.find_by(id: post_status_to_delete.id)).to be_nil
end
end

View File

@@ -0,0 +1,42 @@
require 'rails_helper'
feature 'site settings: roadmap', type: :system, js: true do
let(:user) { FactoryBot.create(:admin) }
let(:post_status_in_roadmap) { FactoryBot.create(:post_status, show_in_roadmap: true) }
let(:post_status_not_in_roadmap) { FactoryBot.create(:post_status, show_in_roadmap: false) }
let(:in_roadmap_post_statuses_selector) { '.inRoadmapPostStatuses' }
let(:not_in_roadmap_post_statuses_selector) { '.notInRoadmapPostStatuses' }
let(:post_status_selector) { '.roadmapPostStatus' }
let(:drag_zone_selector) { '.drag-zone' }
before(:each) do
post_status_in_roadmap
post_status_not_in_roadmap
user.confirm
sign_in user
visit site_settings_roadmap_path
end
it 'lets view post statuses divided in roadmap and not in roadmap' do
expect(post_status_in_roadmap.show_in_roadmap).to eq(true)
expect(post_status_not_in_roadmap.show_in_roadmap).to eq(false)
within in_roadmap_post_statuses_selector do
expect(page).to have_css(post_status_selector, count: 1)
expect(page).to have_content(/#{post_status_in_roadmap.name}/i)
expect(page).not_to have_content(/#{post_status_not_in_roadmap.name}/i)
end
within not_in_roadmap_post_statuses_selector do
expect(page).to have_css(post_status_selector, count: 1)
expect(page).not_to have_content(/#{post_status_in_roadmap.name}/i)
expect(page).to have_content(/#{post_status_not_in_roadmap.name}/i)
end
end
end

View File

@@ -0,0 +1,88 @@
require 'rails_helper'
feature 'site settings: users', type: :system, js: true do
let(:admin) { FactoryBot.create(:admin) }
let(:user) { FactoryBot.create(:user) }
let(:users_list_selector) { '.usersList' }
let(:user_list_item_selector) { '.userEditable' }
let(:select_picker_role_selector) { 'selectPickerUserRole' }
before(:each) do
admin.confirm
sign_in admin
user
visit site_settings_users_path
end
it 'lets view existing users' do
within users_list_selector do
expect(page).to have_css(user_list_item_selector, count: User.count)
expect(page).to have_content(/#{admin.full_name}/i)
expect(page).to have_content(/#{admin.role}/i)
expect(page).to have_content(/#{user.full_name}/i)
expect(page).to have_content(/#{user.role}/i)
end
end
it 'lets edit the role of existing users' do
user_to_edit = User.last
new_role = 'moderator'
expect(user_to_edit.role).not_to eq(new_role)
within users_list_selector do
within find(user_list_item_selector, text: /#{user_to_edit.full_name}/i) do
expect(page).not_to have_content(/#{new_role}/i)
find('.editAction').click
expect(page).to have_select(select_picker_role_selector,
with_options: ['User', 'Moderator', 'Administrator']
)
select new_role.capitalize, from: select_picker_role_selector
click_button 'Save'
page.driver.browser.switch_to.alert.accept
expect(page).to have_content(/#{new_role}/i)
end
end
within '.siteSettingsInfo' do
expect(page).to have_content('All changes saved')
end
expect(user_to_edit.reload.role).to eq(new_role)
end
it 'lets block and unblock existing users' do
user_to_edit = User.last
expect(user_to_edit.status).to eq('active')
within users_list_selector do
within find(user_list_item_selector, text: /#{user_to_edit.full_name}/i) do
expect(page).to have_css('.blockAction')
find('.blockAction').click
page.driver.browser.switch_to.alert.accept
expect(page).not_to have_css('.blockAction')
expect(page).to have_css('.unblockAction')
expect(user_to_edit.reload.status).to eq('blocked')
find('.unblockAction').click
page.driver.browser.switch_to.alert.accept
expect(page).to have_css('.blockAction')
expect(page).not_to have_css('.unblockAction')
expect(user_to_edit.reload.status).to eq('active')
end
end
end
end