2019-11-26 15:22:04 +00:00
require 'rails_helper'
RSpec . describe 'Ticket zoom' , type : :system do
2020-08-07 14:48:09 +00:00
describe 'owner auto-assignment' , authenticated_as : :authenticate do
2019-11-26 15:22:04 +00:00
let! ( :ticket ) { create ( :ticket , group : Group . find_by ( name : 'Users' ) , state : Ticket :: State . find_by ( name : 'new' ) ) }
let! ( :session_user ) { User . find_by ( login : 'master@example.com' ) }
context 'for agent disabled' do
2020-08-07 14:48:09 +00:00
def authenticate
2019-11-26 15:22:04 +00:00
Setting . set ( 'ticket_auto_assignment' , false )
Setting . set ( 'ticket_auto_assignment_selector' , { condition : { 'ticket.state_id' = > { operator : 'is' , value : Ticket :: State . by_category ( :work_on ) . pluck ( :id ) } } } )
Setting . set ( 'ticket_auto_assignment_user_ids_ignore' , [ ] )
2020-08-07 14:48:09 +00:00
true
2019-11-26 15:22:04 +00:00
end
it 'do not assign ticket to current session user' do
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( 'select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : '-' ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
context 'for agent enabled' do
2020-08-07 14:48:09 +00:00
def authenticate
2019-11-26 15:22:04 +00:00
Setting . set ( 'ticket_auto_assignment' , true )
Setting . set ( 'ticket_auto_assignment_selector' , { condition : { 'ticket.state_id' = > { operator : 'is' , value : Ticket :: State . by_category ( :work_on ) . pluck ( :id ) } } } )
2020-08-07 14:48:09 +00:00
Setting . set ( 'ticket_auto_assignment_user_ids_ignore' , setting_user_ids_ignore ) if defined? ( setting_user_ids_ignore )
true
2019-11-26 15:22:04 +00:00
end
context 'with empty "ticket_auto_assignment_user_ids_ignore"' do
it 'assigns ticket to current session user' do
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( '.content.active select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : session_user . fullname ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
context 'with "ticket_auto_assignment_user_ids_ignore" (as integer)' do
2020-08-07 14:48:09 +00:00
let ( :setting_user_ids_ignore ) { session_user . id }
2019-11-26 15:22:04 +00:00
2020-08-07 14:48:09 +00:00
it 'assigns ticket not to current session user' do
2019-11-26 15:22:04 +00:00
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( 'select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : '-' ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
context 'with "ticket_auto_assignment_user_ids_ignore" (as string)' do
2020-08-07 14:48:09 +00:00
let ( :setting_user_ids_ignore ) { session_user . id . to_s }
2019-11-26 15:22:04 +00:00
2020-08-07 14:48:09 +00:00
it 'assigns ticket not to current session user' do
2019-11-26 15:22:04 +00:00
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( 'select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : '-' ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
context 'with "ticket_auto_assignment_user_ids_ignore" (as [integer])' do
2020-08-07 14:48:09 +00:00
let ( :setting_user_ids_ignore ) { [ session_user . id ] }
2019-11-26 15:22:04 +00:00
2020-08-07 14:48:09 +00:00
it 'assigns ticket not to current session user' do
2019-11-26 15:22:04 +00:00
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( 'select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : '-' ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
context 'with "ticket_auto_assignment_user_ids_ignore" (as [string])' do
2020-08-07 14:48:09 +00:00
let ( :setting_user_ids_ignore ) { [ session_user . id . to_s ] }
2019-11-26 15:22:04 +00:00
2020-08-07 14:48:09 +00:00
it 'assigns ticket not to current session user' do
2019-11-26 15:22:04 +00:00
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( 'select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : '-' ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
context 'with "ticket_auto_assignment_user_ids_ignore" and other user ids' do
2020-08-07 14:48:09 +00:00
let ( :setting_user_ids_ignore ) { [ 99_999 , 999_999 ] }
2019-11-26 15:22:04 +00:00
2020-08-07 14:48:09 +00:00
it 'assigns ticket to current session user' do
2019-11-26 15:22:04 +00:00
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
expect ( page ) . to have_css ( 'select[name=owner_id]' )
expect ( page ) . to have_select ( 'owner_id' ,
selected : session_user . fullname ,
options : [ '-' , 'Agent 1 Test' , 'Test Master Agent' ] )
end
end
end
end
end
2020-01-10 12:01:33 +00:00
context 'when ticket has an attachment' do
let ( :group ) { Group . find_by ( name : 'Users' ) }
let ( :ticket ) { create ( :ticket , group : group ) }
let ( :article ) { create ( :ticket_article , ticket : ticket ) }
let ( :attachment_name ) { 'some_file.txt' }
before do
Store . add (
object : 'Ticket::Article' ,
o_id : article . id ,
data : 'some content' ,
filename : attachment_name ,
preferences : {
'Content-Type' = > 'text/plain' ,
} ,
created_by_id : 1 ,
)
end
context 'article was already forwarded once' do
before do
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
find ( 'a[data-type=emailForward]' ) . click
click ( '.js-reset' )
have_no_css ( '.js-reset' )
end
end
it 'adds attachments when forwarding multiple times' do
within ( :active_content ) do
find ( 'a[data-type=emailForward]' ) . click
end
within ( '.js-writeArea' ) do
expect ( page ) . to have_text attachment_name
end
end
end
end
2020-04-27 13:40:28 +00:00
context 'replying' do
context 'Group without signature' do
let ( :ticket ) { create ( :ticket ) }
2020-06-19 09:17:18 +00:00
let ( :current_user ) { create ( :agent , password : 'test' , groups : [ ticket . group ] ) }
2020-04-27 13:40:28 +00:00
before do
# initial article to reply to
create ( :ticket_article , ticket : ticket )
end
2020-06-18 11:51:25 +00:00
it 'ensures that text input opens on multiple replies' , authenticated_as : :current_user do
2020-04-27 13:40:28 +00:00
visit " ticket/zoom/ #{ ticket . id } "
2 . times do | article_offset |
articles_existing = 1
articles_expected = articles_existing + ( article_offset + 1 )
all ( 'a[data-type=emailReply]' ) . last . click
# wait till input box expands completely
2020-08-24 13:40:28 +00:00
find ( '.attachmentPlaceholder-label' ) . in_fixed_position
2020-08-26 12:31:33 +00:00
expect ( page ) . to have_no_css ( '.attachmentPlaceholder-hint' )
2020-04-27 13:40:28 +00:00
find ( '.articleNewEdit-body' ) . send_keys ( 'Some reply' )
click '.js-submit'
expect ( page ) . to have_css ( '.ticket-article-item' , count : articles_expected )
end
end
end
2020-09-11 07:25:47 +00:00
context 'to inbound phone call' , current_user_id : - > { agent . id } , authenticated_as : - > { agent } do
let ( :agent ) { create ( :agent , groups : [ Group . first ] ) }
let ( :customer ) { create ( :agent ) }
let ( :ticket ) { create ( :ticket , customer : customer , group : agent . groups . first ) }
let! ( :article ) { create ( :ticket_article , :inbound_phone , ticket : ticket ) }
it 'goes to customer email' do
visit " ticket/zoom/ #{ ticket . id } "
within :active_ticket_article , article do
click '.js-ArticleAction[data-type=emailReply]'
end
within :active_content do
within '.article-new' do
expect ( find ( '[name=to]' , visible : :all ) . value ) . to eq customer . email
end
end
end
end
context 'to outbound phone call' , current_user_id : - > { agent . id } , authenticated_as : - > { agent } do
let ( :agent ) { create ( :agent , groups : [ Group . first ] ) }
let ( :customer ) { create ( :agent ) }
let ( :ticket ) { create ( :ticket , customer : customer , group : agent . groups . first ) }
let! ( :article ) { create ( :ticket_article , :outbound_phone , ticket : ticket ) }
it 'goes to customer email' do
visit " ticket/zoom/ #{ ticket . id } "
within :active_ticket_article , article do
click '.js-ArticleAction[data-type=emailReply]'
end
within :active_content do
within '.article-new' do
expect ( find ( '[name=to]' , visible : :all ) . value ) . to eq customer . email
end
end
end
end
2020-04-27 13:40:28 +00:00
end
2020-04-13 18:24:03 +00:00
2020-08-07 14:48:09 +00:00
describe 'delete article' , authenticated_as : :authenticate do
let ( :group ) { Group . first }
let ( :admin ) { create :admin , groups : [ group ] }
let ( :agent ) { create :agent , groups : [ group ] }
let ( :other_agent ) { create :agent , groups : [ group ] }
2020-07-13 09:14:15 +00:00
let ( :customer ) { create :customer }
let ( :article ) { send ( item ) }
2020-04-13 18:24:03 +00:00
2020-08-07 14:48:09 +00:00
def authenticate
Setting . set ( 'ui_ticket_zoom_article_delete_timeframe' , setting_delete_timeframe ) if defined? ( setting_delete_timeframe )
article
user
end
2020-04-13 18:24:03 +00:00
def article_communication
2020-06-19 09:17:18 +00:00
create_ticket_article ( sender_name : 'Agent' , internal : false , type_name : 'email' , updated_by : customer )
2020-04-13 18:24:03 +00:00
end
2020-07-13 09:14:15 +00:00
def article_note_self
create_ticket_article ( sender_name : 'Agent' , internal : true , type_name : 'note' , updated_by : user )
end
def article_note_other
create_ticket_article ( sender_name : 'Agent' , internal : true , type_name : 'note' , updated_by : other_agent )
2020-04-13 18:24:03 +00:00
end
def article_note_customer
2020-06-19 09:17:18 +00:00
create_ticket_article ( sender_name : 'Customer' , internal : false , type_name : 'note' , updated_by : customer )
2020-04-13 18:24:03 +00:00
end
2020-07-13 09:14:15 +00:00
def article_note_communication_self
create ( :ticket_article_type , name : 'note_communication' , communication : true )
create_ticket_article ( sender_name : 'Agent' , internal : true , type_name : 'note_communication' , updated_by : user )
end
def article_note_communication_other
2020-04-13 18:24:03 +00:00
create ( :ticket_article_type , name : 'note_communication' , communication : true )
2020-07-13 09:14:15 +00:00
create_ticket_article ( sender_name : 'Agent' , internal : true , type_name : 'note_communication' , updated_by : other_agent )
2020-04-13 18:24:03 +00:00
end
def create_ticket_article ( sender_name : , internal : , type_name : , updated_by : )
2020-08-07 14:48:09 +00:00
UserInfo . current_user_id = updated_by . id
ticket = create :ticket , group : group , customer : customer
2020-04-13 18:24:03 +00:00
create ( :ticket_article ,
sender_name : sender_name , internal : internal , type_name : type_name , ticket : ticket ,
body : " to be deleted #{ offset } #{ item } " ,
created_at : offset . ago , updated_at : offset . ago )
end
context 'going through full stack' do
context 'as admin' do
2020-06-19 09:17:18 +00:00
let ( :user ) { admin }
2020-07-13 09:14:15 +00:00
let ( :item ) { 'article_note_self' }
2020-04-13 18:24:03 +00:00
let ( :offset ) { 0 . minutes }
it 'succeeds' do
ensure_websocket do
2020-08-07 14:48:09 +00:00
visit " ticket/zoom/ #{ article . ticket . id } "
2020-04-13 18:24:03 +00:00
end
2020-08-07 14:48:09 +00:00
within :active_ticket_article , article do
2020-04-13 18:24:03 +00:00
click '.js-ArticleAction[data-type=delete]'
end
in_modal do
click '.js-submit'
end
wait . until_disappears { find :active_ticket_article , article , wait : false }
end
end
end
context 'verifying permissions matrix' do
shared_examples 'according to permission matrix' do | item : , expects_visible : , offset : , description : |
context " looking at #{ description } #{ item } " do
2020-08-07 14:48:09 +00:00
let ( :item ) { item }
let ( :offset ) { offset }
2020-04-13 18:24:03 +00:00
let ( :matcher ) { expects_visible ? :have_css : :have_no_css }
it expects_visible ? 'delete button is visible' : 'delete button is not visible' do
2020-08-07 14:48:09 +00:00
visit " ticket/zoom/ #{ article . ticket . id } "
2020-04-13 18:24:03 +00:00
2020-08-07 14:48:09 +00:00
within :active_ticket_article , article do
2020-04-13 18:24:03 +00:00
expect ( page ) . to send ( matcher , '.js-ArticleAction[data-type=delete]' , wait : 0 )
end
end
end
end
shared_examples 'deleting ticket article' do | item : , now : , later : , much_later : |
include_examples 'according to permission matrix' , item : item , expects_visible : now , offset : 0 . minutes , description : 'just created'
include_examples 'according to permission matrix' , item : item , expects_visible : later , offset : 6 . minutes , description : 'few minutes old'
include_examples 'according to permission matrix' , item : item , expects_visible : much_later , offset : 11 . minutes , description : 'very old'
end
context 'as admin' do
2020-06-19 09:17:18 +00:00
let ( :user ) { admin }
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
item : 'article_communication' ,
2020-07-13 09:14:15 +00:00
now : false , later : false , much_later : false
include_examples 'deleting ticket article' ,
item : 'article_note_self' ,
now : true , later : true , much_later : false
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
2020-07-13 09:14:15 +00:00
item : 'article_note_other' ,
now : false , later : false , much_later : false
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
item : 'article_note_customer' ,
2020-07-13 09:14:15 +00:00
now : false , later : false , much_later : false
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
2020-07-13 09:14:15 +00:00
item : 'article_note_communication_self' ,
now : false , later : false , much_later : false
include_examples 'deleting ticket article' ,
item : 'article_note_communication_other' ,
now : false , later : false , much_later : false
2020-04-13 18:24:03 +00:00
end
context 'as agent' do
2020-06-19 09:17:18 +00:00
let ( :user ) { agent }
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
item : 'article_communication' ,
now : false , later : false , much_later : false
include_examples 'deleting ticket article' ,
2020-07-13 09:14:15 +00:00
item : 'article_note_self' ,
2020-04-13 18:24:03 +00:00
now : true , later : true , much_later : false
2020-07-13 09:14:15 +00:00
include_examples 'deleting ticket article' ,
item : 'article_note_other' ,
now : false , later : false , much_later : false
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
item : 'article_note_customer' ,
now : false , later : false , much_later : false
include_examples 'deleting ticket article' ,
2020-07-13 09:14:15 +00:00
item : 'article_note_communication_self' ,
now : false , later : false , much_later : false
include_examples 'deleting ticket article' ,
item : 'article_note_communication_other' ,
now : false , later : false , much_later : false
2020-04-13 18:24:03 +00:00
end
context 'as customer' do
2020-06-19 09:17:18 +00:00
let ( :user ) { customer }
2020-04-13 18:24:03 +00:00
include_examples 'deleting ticket article' ,
item : 'article_communication' ,
now : false , later : false , much_later : false
include_examples 'deleting ticket article' ,
item : 'article_note_customer' ,
now : false , later : false , much_later : false
end
2020-04-13 20:26:09 +00:00
context 'with custom offset' do
2020-08-07 14:48:09 +00:00
let ( :setting_delete_timeframe ) { 6_000 }
2020-04-13 20:26:09 +00:00
context 'as admin' do
2020-06-19 09:17:18 +00:00
let ( :user ) { admin }
2020-04-13 20:26:09 +00:00
2020-07-13 09:14:15 +00:00
include_examples 'according to permission matrix' , item : 'article_note_self' , expects_visible : true , offset : 5000 . seconds , description : 'outside of delete timeframe'
include_examples 'according to permission matrix' , item : 'article_note_self' , expects_visible : false , offset : 8000 . seconds , description : 'outside of delete timeframe'
2020-04-13 20:26:09 +00:00
end
context 'as agent' do
2020-06-19 09:17:18 +00:00
let ( :user ) { agent }
2020-04-13 20:26:09 +00:00
2020-07-13 09:14:15 +00:00
include_examples 'according to permission matrix' , item : 'article_note_self' , expects_visible : true , offset : 5000 . seconds , description : 'outside of delete timeframe'
include_examples 'according to permission matrix' , item : 'article_note_self' , expects_visible : false , offset : 8000 . seconds , description : 'outside of delete timeframe'
2020-04-13 20:26:09 +00:00
end
end
context 'with timeframe as 0' do
2020-08-07 14:48:09 +00:00
let ( :setting_delete_timeframe ) { 0 }
2020-04-13 20:26:09 +00:00
context 'as agent' do
2020-06-19 09:17:18 +00:00
let ( :user ) { agent }
2020-04-13 20:26:09 +00:00
2020-07-13 09:14:15 +00:00
include_examples 'according to permission matrix' , item : 'article_note_self' , expects_visible : true , offset : 99 . days , description : 'long after'
2020-04-13 20:26:09 +00:00
end
end
end
context 'button is hidden on the go' do
2020-08-07 14:48:09 +00:00
let ( :setting_delete_timeframe ) { 5 }
2020-04-13 20:26:09 +00:00
2020-06-19 09:17:18 +00:00
let ( :user ) { agent }
2020-07-13 09:14:15 +00:00
let ( :item ) { 'article_note_self' }
2020-04-13 20:26:09 +00:00
let! ( :article ) { send ( item ) }
let ( :offset ) { 0 . seconds }
it 'successfully' do
2020-08-07 14:48:09 +00:00
visit " ticket/zoom/ #{ article . ticket . id } "
2020-04-13 20:26:09 +00:00
within :active_ticket_article , article do
find '.js-ArticleAction[data-type=delete]' # make sure delete button did show up
2020-08-07 14:48:09 +00:00
expect ( page ) . to have_no_css ( '.js-ArticleAction[data-type=delete]' )
2020-04-13 20:26:09 +00:00
end
end
2020-04-13 18:24:03 +00:00
end
end
2020-06-02 11:01:16 +00:00
2020-06-15 22:11:29 +00:00
context 'S/MIME active' , authenticated_as : :authenticate do
2020-06-02 11:01:16 +00:00
let ( :system_email_address ) { 'smime1@example.com' }
let ( :email_address ) { create ( :email_address , email : system_email_address ) }
let ( :group ) { create ( :group , email_address : email_address ) }
let ( :agent_groups ) { [ group ] }
2020-06-19 09:17:18 +00:00
let ( :agent ) { create ( :agent , groups : agent_groups ) }
2020-06-02 11:01:16 +00:00
let ( :sender_email_address ) { 'smime2@example.com' }
2020-06-19 09:17:18 +00:00
let ( :customer ) { create ( :customer , email : sender_email_address ) }
2020-06-02 11:01:16 +00:00
let! ( :ticket ) { create ( :ticket , group : group , owner : agent , customer : customer ) }
2020-06-15 22:11:29 +00:00
def authenticate
2020-06-02 11:01:16 +00:00
Setting . set ( 'smime_integration' , true )
2020-06-15 22:11:29 +00:00
agent
2020-06-02 11:01:16 +00:00
end
context 'received mail' do
context 'article meta information' do
context 'success' do
it 'shows encryption/sign information' do
create ( :ticket_article , preferences : {
security : {
type : 'S/MIME' ,
encryption : {
success : true ,
comment : 'COMMENT_ENCRYPT_SUCCESS' ,
} ,
sign : {
success : true ,
comment : 'COMMENT_SIGN_SUCCESS' ,
} ,
}
} , ticket : ticket )
visit " # ticket/zoom/ #{ ticket . id } "
expect ( page ) . to have_css ( 'svg.icon-lock' )
expect ( page ) . to have_css ( 'svg.icon-signed' )
open_article_meta
expect ( page ) . to have_css ( 'span' , text : 'Encrypted' )
expect ( page ) . to have_css ( 'span' , text : 'Signed' )
expect ( page ) . to have_css ( 'span[title=COMMENT_ENCRYPT_SUCCESS]' )
expect ( page ) . to have_css ( 'span[title=COMMENT_SIGN_SUCCESS]' )
end
end
context 'error' do
it 'shows create information about encryption/sign failed' do
create ( :ticket_article , preferences : {
security : {
type : 'S/MIME' ,
encryption : {
success : false ,
comment : 'Encryption failed because XXX' ,
} ,
sign : {
success : false ,
comment : 'Sign failed because XXX' ,
} ,
}
} , ticket : ticket )
visit " # ticket/zoom/ #{ ticket . id } "
expect ( page ) . to have_css ( 'svg.icon-not-signed' )
open_article_meta
expect ( page ) . to have_css ( 'div.alert.alert--warning' , text : 'Encryption failed because XXX' )
expect ( page ) . to have_css ( 'div.alert.alert--warning' , text : 'Sign failed because XXX' )
end
end
end
context 'certificate not present at time of arrival' do
it 'retry' do
smime1 = create ( :smime_certificate , :with_private , fixture : system_email_address )
smime2 = create ( :smime_certificate , :with_private , fixture : sender_email_address )
mail = Channel :: EmailBuild . build (
from : sender_email_address ,
to : system_email_address ,
body : 'somebody with some text' ,
content_type : 'text/plain' ,
security : {
type : 'S/MIME' ,
sign : {
success : true ,
} ,
encryption : {
success : true ,
} ,
} ,
)
smime1 . destroy
smime2 . destroy
parsed_mail = Channel :: EmailParser . new . parse ( mail . to_s )
ticket , article , _user , _mail = Channel :: EmailParser . new . process ( { group_id : group . id } , parsed_mail [ 'raw' ] )
expect ( Ticket :: Article . find ( article . id ) . body ) . to eq ( 'no visible content' )
create ( :smime_certificate , fixture : sender_email_address )
create ( :smime_certificate , :with_private , fixture : system_email_address )
visit " # ticket/zoom/ #{ ticket . id } "
2020-08-26 12:31:33 +00:00
expect ( page ) . to have_no_css ( '.article-content' , text : 'somebody with some text' )
2020-06-02 11:01:16 +00:00
click '.js-securityRetryProcess'
expect ( page ) . to have_css ( '.article-content' , text : 'somebody with some text' )
end
end
end
2020-07-13 18:22:58 +00:00
context 'replying' , authenticated_as : :setup_and_authenticate do
2020-06-02 11:01:16 +00:00
2020-07-13 18:22:58 +00:00
def setup_and_authenticate
2020-06-02 11:01:16 +00:00
create ( :ticket_article , ticket : ticket , from : customer . email )
create ( :smime_certificate , :with_private , fixture : system_email_address )
create ( :smime_certificate , fixture : sender_email_address )
2020-07-13 18:22:58 +00:00
authenticate
2020-06-02 11:01:16 +00:00
end
it 'plain' do
visit " # ticket/zoom/ #{ ticket . id } "
all ( 'a[data-type=emailReply]' ) . last . click
find ( '.articleNewEdit-body' ) . send_keys ( 'Test' )
expect ( page ) . to have_css ( '.js-securityEncrypt.btn--active' , wait : 5 )
expect ( page ) . to have_css ( '.js-securitySign.btn--active' , wait : 5 )
click '.js-securityEncrypt'
click '.js-securitySign'
click '.js-submit'
expect ( page ) . to have_css ( '.ticket-article-item' , count : 2 )
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'encryption' ] [ 'success' ] ) . to be nil
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'sign' ] [ 'success' ] ) . to be nil
end
it 'signed' do
visit " # ticket/zoom/ #{ ticket . id } "
all ( 'a[data-type=emailReply]' ) . last . click
find ( '.articleNewEdit-body' ) . send_keys ( 'Test' )
expect ( page ) . to have_css ( '.js-securityEncrypt.btn--active' , wait : 5 )
expect ( page ) . to have_css ( '.js-securitySign.btn--active' , wait : 5 )
click '.js-securityEncrypt'
click '.js-submit'
expect ( page ) . to have_css ( '.ticket-article-item' , count : 2 )
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'encryption' ] [ 'success' ] ) . to be nil
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'sign' ] [ 'success' ] ) . to be true
end
it 'encrypted' do
visit " # ticket/zoom/ #{ ticket . id } "
all ( 'a[data-type=emailReply]' ) . last . click
find ( '.articleNewEdit-body' ) . send_keys ( 'Test' )
expect ( page ) . to have_css ( '.js-securityEncrypt.btn--active' , wait : 5 )
expect ( page ) . to have_css ( '.js-securitySign.btn--active' , wait : 5 )
click '.js-securitySign'
click '.js-submit'
expect ( page ) . to have_css ( '.ticket-article-item' , count : 2 )
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'encryption' ] [ 'success' ] ) . to be true
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'sign' ] [ 'success' ] ) . to be nil
end
it 'signed and encrypted' do
visit " # ticket/zoom/ #{ ticket . id } "
all ( 'a[data-type=emailReply]' ) . last . click
find ( '.articleNewEdit-body' ) . send_keys ( 'Test' )
expect ( page ) . to have_css ( '.js-securityEncrypt.btn--active' , wait : 5 )
expect ( page ) . to have_css ( '.js-securitySign.btn--active' , wait : 5 )
click '.js-submit'
expect ( page ) . to have_css ( '.ticket-article-item' , count : 2 )
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'encryption' ] [ 'success' ] ) . to be true
expect ( Ticket :: Article . last . preferences [ 'security' ] [ 'sign' ] [ 'success' ] ) . to be true
end
end
context 'Group default behavior' do
let ( :smime_config ) { { } }
2020-06-19 10:29:40 +00:00
def authenticate
Setting . set ( 'smime_integration' , true )
2020-06-02 11:01:16 +00:00
Setting . set ( 'smime_config' , smime_config )
create ( :ticket_article , ticket : ticket , from : customer . email )
create ( :smime_certificate , :with_private , fixture : system_email_address )
create ( :smime_certificate , fixture : sender_email_address )
2020-06-19 10:29:40 +00:00
agent
2020-06-02 11:01:16 +00:00
end
shared_examples 'security defaults example' do | sign : , encrypt : |
it " security defaults sign: #{ sign } , encrypt: #{ encrypt } " do
within ( :active_content ) do
encrypt_button = find ( '.js-securityEncrypt' , wait : 5 )
sign_button = find ( '.js-securitySign' , wait : 5 )
await_empty_ajax_queue
active_button_class = '.btn--active'
expect ( encrypt_button . matches_css? ( active_button_class , wait : 2 ) ) . to be ( encrypt )
expect ( sign_button . matches_css? ( active_button_class , wait : 2 ) ) . to be ( sign )
end
end
end
shared_examples 'security defaults' do | sign : , encrypt : |
before do
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
all ( 'a[data-type=emailReply]' ) . last . click
find ( '.articleNewEdit-body' ) . send_keys ( 'Test' )
await_empty_ajax_queue
end
end
include_examples 'security defaults example' , sign : sign , encrypt : encrypt
end
shared_examples 'security defaults group change' do | sign : , encrypt : |
before do
visit " # ticket/zoom/ #{ ticket . id } "
within ( :active_content ) do
all ( 'a[data-type=emailReply]' ) . last . click
find ( '.articleNewEdit-body' ) . send_keys ( 'Test' )
await_empty_ajax_queue
select new_group . name , from : 'group_id'
end
end
include_examples 'security defaults example' , sign : sign , encrypt : encrypt
end
context 'not configured' do
it_behaves_like 'security defaults' , sign : true , encrypt : true
end
context 'configuration present' do
let ( :smime_config ) do
{
'group_id' = > group_defaults
}
end
let ( :group_defaults ) do
{
'default_encryption' = > {
group . id . to_s = > default_encryption ,
} ,
'default_sign' = > {
group . id . to_s = > default_sign ,
}
}
end
let ( :default_sign ) { true }
let ( :default_encryption ) { true }
shared_examples 'sign and encrypt variations' do | check_examples_name |
it_behaves_like check_examples_name , sign : true , encrypt : true
context 'no value' do
let ( :group_defaults ) { { } }
it_behaves_like check_examples_name , sign : true , encrypt : true
end
context 'signing disabled' do
let ( :default_sign ) { false }
it_behaves_like check_examples_name , sign : false , encrypt : true
end
context 'encryption disabled' do
let ( :default_encryption ) { false }
it_behaves_like check_examples_name , sign : true , encrypt : false
end
end
context 'same Group' do
it_behaves_like 'sign and encrypt variations' , 'security defaults'
end
context 'Group change' do
let ( :new_group ) { create ( :group , email_address : email_address ) }
let ( :agent_groups ) { [ group , new_group ] }
let ( :group_defaults ) do
{
'default_encryption' = > {
new_group . id . to_s = > default_encryption ,
} ,
'default_sign' = > {
new_group . id . to_s = > default_sign ,
}
}
end
it_behaves_like 'sign and encrypt variations' , 'security defaults group change'
end
end
end
end
2020-07-14 06:20:25 +00:00
describe 'linking Knowledge Base answer' do
include_context 'basic Knowledge Base'
let ( :ticket ) { create :ticket , group : Group . find_by ( name : 'Users' ) }
let ( :answer ) { published_answer }
let ( :translation ) { answer . translations . first }
shared_examples 'verify linking' do
it 'allows to look up an answer' do
visit " # ticket/zoom/ #{ ticket . id } "
within :active_content do
within '.link_kb_answers' do
find ( '.js-add' ) . click
find ( '.js-input' ) . send_keys translation . title
find ( %( li[data-value=" #{ translation . id } "] ) ) . click
expect ( find ( '.link_kb_answers ol' ) ) . to have_text translation . title
end
end
end
end
context 'with ES' , searchindex : true , authenticated_as : :authenticate do
def authenticate
configure_elasticsearch ( required : true , rebuild : true ) do
answer
end
true
end
include_examples 'verify linking'
end
context 'without ES' , authenticated_as : :authenticate do
def authenticate
answer
true
end
include_examples 'verify linking'
end
end
2020-08-13 09:17:14 +00:00
describe 'forwarding article with an image' do
let ( :ticket_article_body ) do
filename = 'squares.png'
file = File . binread ( Rails . root . join ( " spec/fixtures/image/ #{ filename } " ) )
ext = File . extname ( filename ) [ 1 ... ]
base64 = Base64 . encode64 ( file ) . delete ( " \n " )
" <img style='width: 1004px; max-width: 100%;' src= \\ \" data:image/ #{ ext } ;base64, #{ base64 } \\ \" ><br> "
end
def current_ticket
Ticket . find current_url . split ( '/' ) . last
end
def create_ticket
visit '#ticket/create'
within :active_content do
find ( '[data-type=email-out]' ) . click
find ( '[name=title]' ) . fill_in with : 'Title'
find ( '[name=customer_id_completion]' ) . fill_in with : 'customer@example.com'
find ( '[name=group_id]' ) . select 'Users'
find ( :richtext ) . execute_script " this.innerHTML = \" #{ ticket_article_body } \" "
find ( '.js-submit' ) . click
end
await_empty_ajax_queue
end
def forward
within :active_content do
click '.js-ArticleAction[data-type=emailForward]'
fill_in 'To' , with : 'customer@example.com'
find ( '.js-submit' ) . click
end
await_empty_ajax_queue
end
def images_identical? ( image_a , image_b )
return false if image_a . height != image_b . height
return false if image_a . width != image_b . width
image_a . height . times do | y |
image_a . row ( y ) . each_with_index do | pixel , x |
2020-08-18 13:01:18 +00:00
return false if pixel != image_b [ x , y ]
2020-08-13 09:17:14 +00:00
end
end
true
end
it 'keeps image intact' do
create_ticket
forward
images = current_ticket . articles . map do | article |
ChunkyPNG :: Image . from_string article . attachments . first . content
end
expect ( images_identical? ( images . first , images . second ) ) . to be ( true )
end
end
2020-08-20 07:10:08 +00:00
context 'object manager attribute permission view' do
let! ( :group_users ) { Group . find_by ( name : 'Users' ) }
shared_examples 'shows attributes and values for agent view and editable' do
it 'shows attributes and values for agent view and editable' , authenticated_as : :current_user do
visit " ticket/zoom/ #{ ticket . id } "
refresh # refresh to have assets generated for ticket
expect ( page ) . to have_select ( 'state_id' , options : [ 'new' , 'open' , 'pending reminder' , 'pending close' , 'closed' ] )
expect ( page ) . to have_select ( 'priority_id' )
expect ( page ) . to have_select ( 'owner_id' )
expect ( page ) . to have_css ( 'div.tabsSidebar-tab[data-tab=customer]' )
end
end
shared_examples 'shows attributes and values for agent view but disabled' do
it 'shows attributes and values for agent view but disabled' , authenticated_as : :current_user do
visit " ticket/zoom/ #{ ticket . id } "
refresh # refresh to have assets generated for ticket
expect ( page ) . to have_css ( 'select[name=state_id][disabled]' )
expect ( page ) . to have_css ( 'select[name=priority_id][disabled]' )
expect ( page ) . to have_css ( 'select[name=owner_id][disabled]' )
expect ( page ) . to have_css ( 'div.tabsSidebar-tab[data-tab=customer]' )
end
end
shared_examples 'shows attributes and values for customer view' do
it 'shows attributes and values for customer view' , authenticated_as : :current_user do
visit " ticket/zoom/ #{ ticket . id } "
refresh # refresh to have assets generated for ticket
expect ( page ) . to have_select ( 'state_id' , options : %w[ new open closed ] )
2020-08-26 12:31:33 +00:00
expect ( page ) . to have_no_select ( 'priority_id' )
expect ( page ) . to have_no_select ( 'owner_id' )
expect ( page ) . to have_no_css ( 'div.tabsSidebar-tab[data-tab=customer]' )
2020-08-20 07:10:08 +00:00
end
end
context 'as customer' do
let! ( :current_user ) { create ( :customer ) }
let ( :ticket ) { create ( :ticket , customer : current_user ) }
include_examples 'shows attributes and values for customer view'
end
context 'as agent with full permissions' do
let ( :current_user ) { create ( :agent , groups : [ group_users ] ) }
let ( :ticket ) { create ( :ticket , group : group_users ) }
include_examples 'shows attributes and values for agent view and editable'
end
context 'as agent with change permissions' do
let! ( :current_user ) { create ( :agent ) }
let ( :ticket ) { create ( :ticket , group : group_users ) }
before do
current_user . group_names_access_map = {
group_users . name = > %w[ read change ] ,
}
end
include_examples 'shows attributes and values for agent view and editable'
end
context 'as agent with read permissions' do
let! ( :current_user ) { create ( :agent ) }
let ( :ticket ) { create ( :ticket , group : group_users ) }
before do
current_user . group_names_access_map = {
group_users . name = > 'read' ,
}
end
include_examples 'shows attributes and values for agent view but disabled'
end
context 'as agent+customer with full permissions' do
let! ( :current_user ) { create ( :agent_and_customer , groups : [ group_users ] ) }
context 'normal ticket' do
let ( :ticket ) { create ( :ticket , group : group_users ) }
include_examples 'shows attributes and values for agent view and editable'
end
context 'ticket where current_user is also customer' do
let ( :ticket ) { create ( :ticket , customer : current_user , group : group_users ) }
include_examples 'shows attributes and values for agent view and editable'
end
end
context 'as agent+customer with change permissions' do
let! ( :current_user ) { create ( :agent_and_customer ) }
before do
current_user . group_names_access_map = {
group_users . name = > %w[ read change ] ,
}
end
context 'normal ticket' do
let ( :ticket ) { create ( :ticket , group : group_users ) }
include_examples 'shows attributes and values for agent view and editable'
end
context 'ticket where current_user is also customer' do
let ( :ticket ) { create ( :ticket , customer : current_user , group : group_users ) }
include_examples 'shows attributes and values for agent view and editable'
end
end
context 'as agent+customer with read permissions' do
let! ( :current_user ) { create ( :agent_and_customer ) }
before do
current_user . group_names_access_map = {
group_users . name = > 'read' ,
}
end
context 'normal ticket' do
let ( :ticket ) { create ( :ticket , group : group_users ) }
include_examples 'shows attributes and values for agent view but disabled'
end
context 'ticket where current_user is also customer' do
let ( :ticket ) { create ( :ticket , customer : current_user , group : group_users ) }
include_examples 'shows attributes and values for agent view but disabled'
end
end
context 'as agent+customer but only customer for the ticket (no agent access)' do
let! ( :current_user ) { create ( :agent_and_customer ) }
let ( :ticket ) { create ( :ticket , customer : current_user ) }
include_examples 'shows attributes and values for customer view'
end
end
2020-08-31 04:27:27 +00:00
describe 'note visibility' , authenticated_as : :customer do
context 'when logged in as a customer' do
let ( :customer ) { create ( :customer ) }
let ( :ticket ) { create ( :ticket , customer : customer ) }
let! ( :ticket_article ) { create ( :ticket_article , ticket : ticket ) }
let! ( :ticket_note ) { create ( :ticket_article , ticket : ticket , internal : true , type_name : 'note' ) }
it 'previously created private note is not visible' do
visit " ticket/zoom/ #{ ticket_article . ticket . id } "
expect ( page ) . to have_no_selector ( :active_ticket_article , ticket_note )
end
it 'previously created private note shows up via WS push' do
visit " ticket/zoom/ #{ ticket_article . ticket . id } "
# make sure ticket is done loading and change will be pushed via WS
find ( :active_ticket_article , ticket_article )
await_empty_ajax_queue
ticket_note . update! ( internal : false )
expect ( page ) . to have_selector ( :active_ticket_article , ticket_note )
end
end
end
2020-11-11 09:58:06 +00:00
# https://github.com/zammad/zammad/issues/3260
describe 'next in overview macro changes URL' , authenticated_as : :authenticate do
let ( :ticket_a ) { create ( :ticket , title : 'ticket a' , group : Group . first ) }
let ( :macro ) { create ( :macro , name : 'next macro' , ux_flow_next_up : 'next_from_overview' ) }
def authenticate
ticket_a && macro
true
end
it 'works' do
visit 'ticket/view/all_unassigned'
click_on 'Welcome to Zammad!'
click '.js-openDropdownMacro'
expect { find ( :element_containing , macro . name ) . click } . to change { current_url }
end
end
2019-11-26 15:22:04 +00:00
end