123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- require 'rails_helper'
- require 'models/core_workflow/base'
- RSpec.describe 'CoreWorkflow > Action', mariadb: true, type: :model do
- include_context 'with core workflow base'
- describe '.perform - Stop after match' do
- let(:stop_after_match) { false }
- before do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.priority_id': {
- operator: 'hide',
- hide: 'true'
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.priority_id': {
- operator: 'show',
- show: 'true'
- },
- },
- stop_after_match: stop_after_match)
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.priority_id': {
- operator: 'hide',
- hide: 'true'
- },
- })
- end
- it 'does not stop' do
- expect(result[:visibility]['priority_id']).to eq('hide')
- end
- describe 'with stop_after_match' do
- let(:stop_after_match) { true }
- it 'does stop' do
- expect(result[:visibility]['priority_id']).to eq('show')
- end
- end
- end
- describe '.perform - Condition - Custom module' do
- let(:modules) { ['CoreWorkflow::Custom::Testa', 'CoreWorkflow::Custom::Testb', 'CoreWorkflow::Custom::Testc'] }
- let(:custom_class_false) do
- Class.new(CoreWorkflow::Custom::Backend) do
- def selected_attribute_match?
- false
- end
- end
- end
- let(:custom_class_true) do
- Class.new(CoreWorkflow::Custom::Backend) do
- def selected_attribute_match?
- true
- end
- end
- end
- let!(:workflow) do
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'custom.module': {
- operator: operator,
- value: modules,
- },
- })
- end
- describe 'with "match all modules" false' do
- let(:operator) { 'match all modules' }
- before do
- stub_const 'CoreWorkflow::Custom::Testa', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testb', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testc', custom_class_false
- end
- it 'does not match' do
- expect(result[:matched_workflows]).not_to include(workflow.id)
- end
- end
- describe 'with "match all modules" true' do
- let(:operator) { 'match all modules' }
- before do
- stub_const 'CoreWorkflow::Custom::Testa', custom_class_true
- stub_const 'CoreWorkflow::Custom::Testb', custom_class_true
- stub_const 'CoreWorkflow::Custom::Testc', custom_class_true
- end
- it 'does match' do
- expect(result[:matched_workflows]).to include(workflow.id)
- end
- end
- describe 'with "match all modules" blank' do
- let(:modules) { [] }
- let(:operator) { 'match all modules' }
- it 'does match' do
- expect(result[:matched_workflows]).to include(workflow.id)
- end
- end
- describe 'with "match one module" true' do
- let(:operator) { 'match one module' }
- before do
- stub_const 'CoreWorkflow::Custom::Testa', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testb', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testc', custom_class_true
- end
- it 'does match' do
- expect(result[:matched_workflows]).to include(workflow.id)
- end
- end
- describe 'with "match one module" false' do
- let(:operator) { 'match one module' }
- before do
- stub_const 'CoreWorkflow::Custom::Testa', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testb', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testc', custom_class_false
- end
- it 'does not match' do
- expect(result[:matched_workflows]).not_to include(workflow.id)
- end
- end
- describe 'with "match one module" blank' do
- let(:modules) { [] }
- let(:operator) { 'match one module' }
- it 'does match' do
- expect(result[:matched_workflows]).to include(workflow.id)
- end
- end
- describe 'with "match no modules" true' do
- let(:operator) { 'match no modules' }
- before do
- stub_const 'CoreWorkflow::Custom::Testa', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testb', custom_class_false
- stub_const 'CoreWorkflow::Custom::Testc', custom_class_false
- end
- it 'does match' do
- expect(result[:matched_workflows]).to include(workflow.id)
- end
- end
- describe 'with "match no modules" false' do
- let(:operator) { 'match no modules' }
- before do
- stub_const 'CoreWorkflow::Custom::Testa', custom_class_true
- stub_const 'CoreWorkflow::Custom::Testb', custom_class_true
- stub_const 'CoreWorkflow::Custom::Testc', custom_class_true
- end
- it 'does not match' do
- expect(result[:matched_workflows]).not_to include(workflow.id)
- end
- end
- describe 'with "match no modules" blank' do
- let(:modules) { [] }
- let(:operator) { 'match no modules' }
- it 'does match' do
- expect(result[:matched_workflows]).to include(workflow.id)
- end
- end
- end
- describe '.perform - Select' do
- let!(:workflow1) do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'select',
- select: [ticket.group.id.to_s]
- },
- })
- end
- let!(:workflow2) do
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is',
- value: ticket.group.id.to_s
- },
- },
- perform: {
- 'ticket.owner_id': {
- operator: 'select',
- select: [action_user.id.to_s]
- },
- })
- end
- it 'does match workflows' do
- expect(result[:matched_workflows]).to include(workflow1.id, workflow2.id)
- end
- it 'does select group' do
- expect(result[:select]['group_id']).to eq(ticket.group.id.to_s)
- end
- it 'does select owner (recursion)' do
- expect(result[:select]['owner_id']).to eq(action_user.id.to_s)
- end
- it 'does rerun 2 times (group select + owner select)' do
- expect(result[:rerun_count]).to eq(2)
- end
- end
- describe '.perform - Auto Select' do
- let!(:workflow1) do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'auto_select',
- auto_select: true
- },
- })
- end
- let!(:workflow2) do
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is',
- value: ticket.group.id.to_s
- },
- },
- perform: {
- 'ticket.owner_id': {
- operator: 'auto_select',
- auto_select: true
- },
- })
- end
- it 'does match workflows' do
- expect(result[:matched_workflows]).to include(workflow1.id, workflow2.id)
- end
- it 'does select group' do
- expect(result[:select]['group_id']).to eq(ticket.group.id.to_s)
- end
- it 'does select owner (recursion)' do
- expect(result[:select]['owner_id']).to eq(action_user.id.to_s)
- end
- it 'does rerun 2 times (group select + owner select)' do
- expect(result[:rerun_count]).to eq(2)
- end
- describe 'with owner' do
- let(:payload) do
- base_payload.merge('params' => {
- 'group_id' => ticket.group.id.to_s,
- 'owner_id' => action_user.id.to_s,
- })
- end
- it 'does not select owner' do
- expect(result[:select]['owner_id']).to be_nil
- end
- it 'does rerun 0 times' do
- expect(result[:rerun_count]).to eq(0)
- end
- end
- end
- describe '.perform - Fill in' do
- let!(:workflow1) do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'select',
- select: [ticket.group.id.to_s]
- },
- })
- end
- let!(:workflow2) do
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is',
- value: ticket.group.id.to_s
- },
- },
- perform: {
- 'ticket.title': {
- operator: 'fill_in',
- fill_in: 'hello'
- },
- })
- end
- it 'does match workflows' do
- expect(result[:matched_workflows]).to include(workflow1.id, workflow2.id)
- end
- it 'does select group' do
- expect(result[:select]['group_id']).to eq(ticket.group.id.to_s)
- end
- it 'does fill in title' do
- expect(result[:fill_in]['title']).to eq('hello')
- end
- it 'does rerun 1 time (group select + title fill in)' do
- expect(result[:rerun_count]).to eq(1)
- end
- end
- describe '.perform - Fill in empty' do
- let!(:workflow1) do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'select',
- select: [ticket.group.id.to_s]
- },
- })
- end
- let!(:workflow2) do
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is',
- value: ticket.group.id.to_s
- },
- },
- perform: {
- 'ticket.title': {
- operator: 'fill_in_empty',
- fill_in_empty: 'hello'
- },
- })
- end
- it 'does match workflows' do
- expect(result[:matched_workflows]).to include(workflow1.id, workflow2.id)
- end
- it 'does select group' do
- expect(result[:select]['group_id']).to eq(ticket.group.id.to_s)
- end
- it 'does fill in title' do
- expect(result[:fill_in]['title']).to eq('hello')
- end
- it 'does rerun 1 time (group select + title fill in)' do
- expect(result[:rerun_count]).to eq(1)
- end
- describe 'with title' do
- let(:payload) do
- base_payload.merge('params' => {
- 'title' => 'ha!',
- })
- end
- it 'does not fill in title' do
- expect(result[:fill_in]['title']).to be_nil
- end
- it 'does rerun 1 times (group select)' do
- expect(result[:rerun_count]).to eq(1)
- end
- end
- end
- describe '.perform - Rerun attributes default cache bug' do
- before do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'select',
- select: [ticket.group.id.to_s]
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is_set',
- },
- },
- perform: {
- 'ticket.owner_id': {
- operator: 'select',
- select: [action_user.id.to_s]
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.owner_id': {
- operator: 'not_set',
- },
- },
- perform: {
- 'ticket.priority_id': {
- operator: 'hide',
- hide: 'true'
- },
- })
- end
- it 'does not hide priority id' do
- expect(result[:visibility]['priority_id']).to eq('show')
- end
- end
- describe '.perform - Clean up params after restrict values removed selected value by set_fixed_to' do
- let(:payload) do
- base_payload.merge('params' => {
- 'owner_id' => action_user.id,
- })
- end
- before do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'select',
- select: [ticket.group.id.to_s]
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is_set',
- },
- },
- perform: {
- 'ticket.owner_id': {
- operator: 'set_fixed_to',
- set_fixed_to: ['']
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.owner_id': {
- operator: 'is_set',
- },
- },
- perform: {
- 'ticket.priority_id': {
- operator: 'hide',
- hide: 'true'
- },
- })
- end
- it 'does not allow owner_id' do
- expect(result[:restrict_values]['owner_id']).not_to include(action_user.id)
- end
- it 'does not hide priority id' do
- expect(result[:visibility]['priority_id']).to eq('show')
- end
- end
- describe '.perform - Clean up params after restrict values removed selected value by remove_option' do
- let(:payload) do
- base_payload.merge('params' => {
- 'owner_id' => action_user.id,
- })
- end
- before do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'select',
- select: [ticket.group.id.to_s]
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.group_id': {
- operator: 'is_set',
- },
- },
- perform: {
- 'ticket.owner_id': {
- operator: 'remove_option',
- remove_option: [action_user.id]
- },
- })
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.owner_id': {
- operator: 'is_set',
- },
- },
- perform: {
- 'ticket.priority_id': {
- operator: 'hide',
- hide: 'true'
- },
- })
- end
- it 'does not allow owner_id' do
- expect(result[:restrict_values]['owner_id']).not_to include(action_user.id)
- end
- it 'does not hide priority id' do
- expect(result[:visibility]['priority_id']).to eq('show')
- end
- end
- describe '.perform - Clean up params after restrict values removed selected value by default attributes' do
- let(:payload) do
- base_payload.merge('params' => {
- 'owner_id' => action_user.id,
- })
- end
- before do
- create(:core_workflow,
- object: 'Ticket',
- condition_selected: {
- 'ticket.owner_id': {
- operator: 'is_set',
- },
- },
- perform: {
- 'ticket.priority_id': {
- operator: 'hide',
- hide: 'true'
- },
- })
- end
- it 'does not allow owner_id' do
- expect(result[:restrict_values]['owner_id']).not_to include(action_user.id)
- end
- it 'does not hide priority id' do
- expect(result[:visibility]['priority_id']).to eq('show')
- end
- end
- describe '.perform - Default - auto selection based on only_shown_if_selectable' do
- it 'does auto select group' do
- expect(result[:select]['group_id']).not_to be_nil
- end
- it 'does auto hide group' do
- expect(result[:visibility]['group_id']).to eq('hide')
- end
- end
- describe '.perform - One field and two perform actions' do
- before do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.owner_id': {
- operator: %w[select set_optional],
- select: [action_user.id.to_s],
- set_optional: 'true',
- },
- })
- end
- it 'does auto select owner' do
- expect(result[:select]['owner_id']).to eq(action_user.id.to_s)
- end
- it 'does set owner optional' do
- expect(result[:mandatory]['owner_id']).to be(false)
- end
- end
- describe '.perform - Hide mobile based on user login' do
- let(:base_payload) do
- {
- 'event' => 'core_workflow',
- 'request_id' => 'default',
- 'class_name' => 'User',
- 'screen' => 'create',
- 'params' => {
- 'login' => 'nicole.special@zammad.org',
- },
- }
- end
- before do
- create(:core_workflow,
- object: 'User',
- condition_selected: { 'user.login'=>{ 'operator' => 'is', 'value' => 'nicole.special@zammad.org' } },
- perform: { 'user.mobile'=>{ 'operator' => 'hide', 'hide' => 'true' } },)
- end
- it 'does hide mobile for user' do
- expect(result[:visibility]['mobile']).to eq('hide')
- end
- end
- describe '.perform - Readonly' do
- let!(:workflow1) do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'set_readonly',
- set_readonly: 'true'
- },
- })
- end
- it 'does match workflow' do
- expect(result[:matched_workflows]).to include(workflow1.id)
- end
- it 'does set group readonly' do
- expect(result[:readonly]['group_id']).to be(true)
- end
- context 'when readonly unset' do
- let!(:workflow2) do
- create(:core_workflow,
- object: 'Ticket',
- perform: {
- 'ticket.group_id': {
- operator: 'unset_readonly',
- unset_readonly: 'true'
- },
- })
- end
- it 'does match workflows' do
- expect(result[:matched_workflows]).to include(workflow1.id, workflow2.id)
- end
- it 'does set group readonly' do
- expect(result[:readonly]['group_id']).to be(false)
- end
- end
- end
- end
|