1 import { provideHttpClientTesting } from '@angular/common/http/testing'
2 import { ComponentFixture, TestBed } from '@angular/core/testing'
3 import { FormsModule, ReactiveFormsModule } from '@angular/forms'
4 import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
5 import { NgSelectModule } from '@ng-select/ng-select'
6 import { of } from 'rxjs'
7 import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
8 import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
9 import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe'
10 import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
11 import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
12 import { MailRuleService } from 'src/app/services/rest/mail-rule.service'
13 import { StoragePathService } from 'src/app/services/rest/storage-path.service'
14 import { SettingsService } from 'src/app/services/settings.service'
15 import { NumberComponent } from '../../input/number/number.component'
16 import { PermissionsGroupComponent } from '../../input/permissions/permissions-group/permissions-group.component'
17 import { PermissionsUserComponent } from '../../input/permissions/permissions-user/permissions-user.component'
18 import { SelectComponent } from '../../input/select/select.component'
19 import { TagsComponent } from '../../input/tags/tags.component'
20 import { TextComponent } from '../../input/text/text.component'
21 import { SwitchComponent } from '../../input/switch/switch.component'
22 import { EditDialogMode } from '../edit-dialog.component'
24 DOCUMENT_SOURCE_OPTIONS,
25 SCHEDULE_DATE_FIELD_OPTIONS,
26 WORKFLOW_ACTION_OPTIONS,
27 WORKFLOW_TYPE_OPTIONS,
28 WorkflowEditDialogComponent,
29 } from './workflow-edit-dialog.component'
30 import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
31 import { Workflow } from 'src/app/data/workflow'
35 } from 'src/app/data/workflow-trigger'
36 import { CdkDragDrop } from '@angular/cdk/drag-drop'
40 } from 'src/app/data/workflow-action'
41 import { MATCHING_ALGORITHMS, MATCH_AUTO } from 'src/app/data/matching-model'
42 import { ConfirmButtonComponent } from '../../confirm-button/confirm-button.component'
43 import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
44 import { CustomFieldDataType } from 'src/app/data/custom-field'
46 const workflow: Workflow = {
54 type: WorkflowTriggerType.Consumption,
55 sources: [DocumentSource.ConsumeFolder],
62 type: WorkflowActionType.Assignment,
67 type: WorkflowActionType.Assignment,
73 describe('WorkflowEditDialogComponent', () => {
74 let component: WorkflowEditDialogComponent
75 let settingsService: SettingsService
76 let fixture: ComponentFixture<WorkflowEditDialogComponent>
79 TestBed.configureTestingModule({
81 WorkflowEditDialogComponent,
82 IfPermissionsDirective,
89 PermissionsUserComponent,
90 PermissionsGroupComponent,
92 ConfirmButtonComponent,
94 imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
98 provide: CorrespondentService,
112 provide: DocumentTypeService,
126 provide: StoragePathService,
140 provide: MailRuleService,
149 provide: CustomFieldsService,
157 data_type: CustomFieldDataType.String,
162 data_type: CustomFieldDataType.Date,
168 provideHttpClient(withInterceptorsFromDi()),
169 provideHttpClientTesting(),
171 }).compileComponents()
173 fixture = TestBed.createComponent(WorkflowEditDialogComponent)
174 settingsService = TestBed.inject(SettingsService)
175 settingsService.currentUser = { id: 99, username: 'user99' }
176 component = fixture.componentInstance
178 fixture.detectChanges()
181 it('should support create and edit modes, support adding triggers and actions on new workflow', () => {
182 component.dialogMode = EditDialogMode.CREATE
183 const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
184 const editTitleSpy = jest.spyOn(component, 'getEditTitle')
185 fixture.detectChanges()
186 expect(createTitleSpy).toHaveBeenCalled()
187 expect(editTitleSpy).not.toHaveBeenCalled()
188 expect(component.object).toBeUndefined()
189 component.addAction()
190 expect(component.object).not.toBeUndefined()
191 expect(component.object.actions).toHaveLength(1)
192 component.object = undefined
193 component.addTrigger()
194 expect(component.object).not.toBeUndefined()
195 expect(component.object.triggers).toHaveLength(1)
197 component.dialogMode = EditDialogMode.EDIT
198 fixture.detectChanges()
199 expect(editTitleSpy).toHaveBeenCalled()
202 it('should return source options, type options, type name, schedule date field options', () => {
204 expect(component.sourceOptions).toEqual(DOCUMENT_SOURCE_OPTIONS)
205 expect(component.triggerTypeOptions).toEqual(WORKFLOW_TYPE_OPTIONS)
207 component.getTriggerTypeOptionName(WorkflowTriggerType.DocumentAdded)
208 ).toEqual('Document Added')
209 expect(component.getTriggerTypeOptionName(null)).toEqual('')
210 expect(component.sourceOptions).toEqual(DOCUMENT_SOURCE_OPTIONS)
211 expect(component.actionTypeOptions).toEqual(WORKFLOW_ACTION_OPTIONS)
213 component.getActionTypeOptionName(WorkflowActionType.Assignment)
214 ).toEqual('Assignment')
215 expect(component.getActionTypeOptionName(null)).toEqual('')
216 expect(component.scheduleDateFieldOptions).toEqual(
217 SCHEDULE_DATE_FIELD_OPTIONS
221 it('should support add and remove triggers and actions', () => {
222 component.object = workflow
223 component.addTrigger()
224 expect(component.object.triggers.length).toEqual(2)
225 component.addAction()
226 expect(component.object.actions.length).toEqual(3)
227 component.removeTrigger(1)
228 expect(component.object.triggers.length).toEqual(1)
229 component.removeAction(1)
230 expect(component.object.actions.length).toEqual(2)
233 it('should update order and remove ids from actions on drag n drop', () => {
234 const action1 = workflow.actions[0]
235 const action2 = workflow.actions[1]
236 component.object = workflow
238 component.onActionDrop({ previousIndex: 0, currentIndex: 1 } as CdkDragDrop<
241 expect(component.object.actions).toEqual([action2, action1])
242 expect(action1.id).toBeNull()
243 expect(action2.id).toBeNull()
246 it('should not include auto matching in algorithms', () => {
247 expect(component.getMatchingAlgorithms()).not.toContain(
248 MATCHING_ALGORITHMS.find((a) => a.id === MATCH_AUTO)
252 it('should disable or enable action fields based on removal action type', () => {
253 const workflow: Workflow = {
262 type: WorkflowActionType.Removal,
263 remove_all_tags: true,
264 remove_all_document_types: true,
265 remove_all_correspondents: true,
266 remove_all_storage_paths: true,
267 remove_all_custom_fields: true,
268 remove_all_owners: true,
269 remove_all_permissions: true,
273 component.object = workflow
276 component['checkRemovalActionFields'](workflow)
278 // Assert that the action fields are disabled or enabled correctly
280 component.actionFields.at(0).get('remove_tags').disabled
283 component.actionFields.at(0).get('remove_document_types').disabled
286 component.actionFields.at(0).get('remove_correspondents').disabled
289 component.actionFields.at(0).get('remove_storage_paths').disabled
292 component.actionFields.at(0).get('remove_custom_fields').disabled
295 component.actionFields.at(0).get('remove_owners').disabled
298 component.actionFields.at(0).get('remove_view_users').disabled
301 component.actionFields.at(0).get('remove_view_groups').disabled
304 component.actionFields.at(0).get('remove_change_users').disabled
307 component.actionFields.at(0).get('remove_change_groups').disabled
310 workflow.actions[0].remove_all_tags = false
311 workflow.actions[0].remove_all_document_types = false
312 workflow.actions[0].remove_all_correspondents = false
313 workflow.actions[0].remove_all_storage_paths = false
314 workflow.actions[0].remove_all_custom_fields = false
315 workflow.actions[0].remove_all_owners = false
316 workflow.actions[0].remove_all_permissions = false
318 component['checkRemovalActionFields'](workflow)
320 // Assert that the action fields are disabled or enabled correctly
321 expect(component.actionFields.at(0).get('remove_tags').disabled).toBeFalsy()
323 component.actionFields.at(0).get('remove_document_types').disabled
326 component.actionFields.at(0).get('remove_correspondents').disabled
329 component.actionFields.at(0).get('remove_storage_paths').disabled
332 component.actionFields.at(0).get('remove_custom_fields').disabled
335 component.actionFields.at(0).get('remove_owners').disabled
338 component.actionFields.at(0).get('remove_view_users').disabled
341 component.actionFields.at(0).get('remove_view_groups').disabled
344 component.actionFields.at(0).get('remove_change_users').disabled
347 component.actionFields.at(0).get('remove_change_groups').disabled
351 it('should prune empty nested objects on save', () => {
352 component.object = workflow
353 component.addTrigger()
354 component.addAction()
355 expect(component.objectForm.get('actions').value[0].email).not.toBeNull()
356 expect(component.objectForm.get('actions').value[0].webhook).not.toBeNull()
358 expect(component.objectForm.get('actions').value[0].email).toBeNull()
359 expect(component.objectForm.get('actions').value[0].webhook).toBeNull()