frontend unit tests

toasts component testing

conditional import of angular setup-jest for vscode-jest support

Update jest.config.js

Create open-documents.service.spec.ts

Add unit tests for all REST services

settings service test

Remove component from settings service test

Create permissions.service.spec.ts

upload documents service tests

Update package.json

Create toast.service.spec.ts

Tasks service test

Statistics widget component tests

Update permissions.service.ts

Create app.component.spec.ts

settings component testing

tasks component unit testing

Management list component generic tests

Some management component tests

document notes component unit tests

Create document-list.component.spec.ts

Create save-view-config-dialog.component.spec.ts

Create filter-editor.component.spec.ts

small and large document cards unit testing

Create bulk-editor.component.spec.ts

document detail unit tests

saving work on documentdetail component spec

Create document-asn.component.spec.ts

dashboard & widgets unit testing

Fix ResizeObserver mock

common component unit tests

fix some merge errors

Update app-frame.component.spec.ts

Create page-header.component.spec.ts

input component unit tests

FilterableDropdownComponent unit testing

and found minor errors

update taskservice unit tests

Edit dialogs unit tests

Create date-dropdown.component.spec.ts

Remove selectors from guard tests

confirm dialog component tests

app frame component test

Miscellaneous component tests

Update document-list-view.service.spec.ts

directives unit tests

Remove unused resizeobserver mock

guard unit tests

Update query-params.spec.ts

try to fix flaky playwright

filter rules utils & testing

Interceptor unit tests

Pipes unit testing

Utils unit tests

Update upload-documents.service.spec.ts

consumer status service tests

Update setup-jest.ts

Create document-list-view.service.spec.ts

Update app-routing.module.ts
This commit is contained in:
shamoon
2023-05-23 15:02:54 -07:00
parent e329f6cdf1
commit 06def8c11e
145 changed files with 14832 additions and 169 deletions

View File

@@ -0,0 +1,55 @@
import { Component } from '@angular/core'
import { AbstractInputComponent } from './abstract-input'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
@Component({
template: `
<div>
<input
#inputField
type="text"
class="form-control"
[class.is-invalid]="error"
[id]="inputId"
[(ngModel)]="value"
(change)="onChange(value)"
[disabled]="disabled"
/>
</div>
`,
})
class TestComponent extends AbstractInputComponent<string> {
constructor() {
super()
}
}
describe(`AbstractInputComponent`, () => {
let component: TestComponent
let fixture: ComponentFixture<TestComponent>
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [TestComponent],
providers: [],
imports: [FormsModule, ReactiveFormsModule],
}).compileComponents()
fixture = TestBed.createComponent(TestComponent)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should assign uuid', () => {
component.ngOnInit()
expect(component.inputId).not.toBeUndefined()
})
it('should support focus', () => {
const focusSpy = jest.spyOn(component.inputField.nativeElement, 'focus')
component.focus()
expect(focusSpy).toHaveBeenCalled()
})
})

View File

@@ -1,5 +1,5 @@
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" (blur)="onTouched()" [disabled]="disabled">
<input #inputField type="checkbox" class="form-check-input" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" (blur)="onTouched()" [disabled]="disabled">
<label class="form-check-label" [for]="inputId">{{title}}</label>
<div *ngIf="hint" class="form-text text-muted">{{hint}}</div>
</div>

View File

@@ -0,0 +1,39 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { CheckComponent } from './check.component'
import {
FormsModule,
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
describe('CheckComponent', () => {
let component: CheckComponent
let fixture: ComponentFixture<CheckComponent>
let input: HTMLInputElement
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [CheckComponent],
providers: [],
imports: [FormsModule, ReactiveFormsModule],
}).compileComponents()
fixture = TestBed.createComponent(CheckComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
input = component.inputField.nativeElement
})
it('should support use of checkbox', () => {
input.checked = true
input.dispatchEvent(new Event('change'))
fixture.detectChanges()
expect(component.value).toBeTruthy()
input.checked = false
input.dispatchEvent(new Event('change'))
fixture.detectChanges()
expect(component.value).toBeFalsy()
})
})

View File

@@ -1,6 +1,5 @@
import { Component, forwardRef, Input, OnInit } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
import { v4 as uuidv4 } from 'uuid'
import { Component, forwardRef } from '@angular/core'
import { NG_VALUE_ACCESSOR } from '@angular/forms'
import { AbstractInputComponent } from '../abstract-input'
@Component({

View File

@@ -11,7 +11,7 @@
</ng-template>
<input class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [autoClose]="'outside'" [ngbPopover]="popContent" placement="bottom" popoverClass="shadow">
<input #inputField class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [autoClose]="'outside'" [ngbPopover]="popContent" placement="bottom" popoverClass="shadow">
<button class="btn btn-outline-secondary" type="button" (click)="randomize()">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dice-5" viewBox="0 0 16 16">

View File

@@ -0,0 +1,72 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
import { ColorComponent } from './color.component'
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
import { ColorSliderModule } from 'ngx-color/slider'
describe('ColorComponent', () => {
let component: ColorComponent
let fixture: ComponentFixture<ColorComponent>
let input: HTMLInputElement
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [ColorComponent],
providers: [],
imports: [
FormsModule,
ReactiveFormsModule,
NgbPopoverModule,
ColorSliderModule,
],
}).compileComponents()
fixture = TestBed.createComponent(ColorComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
input = component.inputField.nativeElement
})
it('should support use of input', () => {
input.value = '#ff0000'
component.colorChanged(input.value)
fixture.detectChanges()
expect(component.value).toEqual('#ff0000')
})
it('should set swatch color', () => {
const swatch: HTMLSpanElement = fixture.nativeElement.querySelector(
'span.input-group-text'
)
expect(swatch.style.backgroundColor).toEqual('')
component.value = '#ff0000'
fixture.detectChanges()
expect(swatch.style.backgroundColor).toEqual('rgb(255, 0, 0)')
})
it('should show color slider popover', () => {
component.value = '#ff0000'
input.dispatchEvent(new MouseEvent('click'))
fixture.detectChanges()
expect(
fixture.nativeElement.querySelector('ngb-popover-window')
).not.toBeUndefined()
expect(
fixture.nativeElement.querySelector('color-slider')
).not.toBeUndefined()
fixture.nativeElement
.querySelector('color-slider')
.dispatchEvent(new Event('change'))
})
it('should allow randomize color and update value', () => {
expect(component.value).toBeUndefined()
component.randomize()
expect(component.value).not.toBeUndefined()
})
})

View File

@@ -1,7 +1,7 @@
<div class="mb-3">
<label class="form-label" [for]="inputId">{{title}}</label>
<div class="input-group" [class.is-invalid]="error">
<input class="form-control" [class.is-invalid]="error" [placeholder]="placeholder" [id]="inputId" maxlength="10"
<input #inputField class="form-control" [class.is-invalid]="error" [placeholder]="placeholder" [id]="inputId" maxlength="10"
(dateSelect)="onChange(value)" (change)="onChange(value)" (keypress)="onKeyPress($event)" (paste)="onPaste($event)"
name="dp" [(ngModel)]="value" ngbDatepicker #datePicker="ngbDatepicker" #datePickerContent="ngModel" [disabled]="disabled">
<button class="btn btn-outline-secondary calendar" (click)="datePicker.toggle()" type="button" [disabled]="disabled">

View File

@@ -0,0 +1,103 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
import { DateComponent } from './date.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import {
NgbDateParserFormatter,
NgbDatepickerModule,
} from '@ng-bootstrap/ng-bootstrap'
import { RouterTestingModule } from '@angular/router/testing'
import { LocalizedDateParserFormatter } from 'src/app/utils/ngb-date-parser-formatter'
describe('DateComponent', () => {
let component: DateComponent
let fixture: ComponentFixture<DateComponent>
let input: HTMLInputElement
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [DateComponent],
providers: [
{
provide: NgbDateParserFormatter,
useClass: LocalizedDateParserFormatter,
},
],
imports: [
FormsModule,
ReactiveFormsModule,
HttpClientTestingModule,
NgbDatepickerModule,
RouterTestingModule,
],
}).compileComponents()
fixture = TestBed.createComponent(DateComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
input = component.inputField.nativeElement
})
it('should support use of input field', () => {
input.value = '5/14/20'
input.dispatchEvent(new Event('change'))
fixture.detectChanges()
expect(component.value).toEqual({ day: 14, month: 5, year: 2020 })
})
it('should use localzed placeholder from settings', () => {
component.ngOnInit()
expect(component.placeholder).toEqual('mm/dd/yyyy')
})
it('should support suggestions', () => {
expect(component.value).toBeUndefined()
component.suggestions = ['2023-05-31', '2014-05-14']
fixture.detectChanges()
const suggestionAnchor: HTMLAnchorElement =
fixture.nativeElement.querySelector('a')
suggestionAnchor.click()
expect(component.value).toEqual({ day: 31, month: 5, year: 2023 })
})
it('should limit keyboard events', () => {
let event: KeyboardEvent = new KeyboardEvent('keypress', {
key: '9',
})
let eventSpy = jest.spyOn(event, 'preventDefault')
input.dispatchEvent(event)
expect(eventSpy).not.toHaveBeenCalled()
event = new KeyboardEvent('keypress', {
key: '{',
})
eventSpy = jest.spyOn(event, 'preventDefault')
input.dispatchEvent(event)
expect(eventSpy).toHaveBeenCalled()
})
it('should support paste', () => {
expect(component.value).toBeUndefined()
const date = '5/4/20'
const clipboardData = {
dropEffect: null,
effectAllowed: null,
files: null,
items: null,
types: null,
clearData: null,
getData: () => date,
setData: null,
setDragImage: null,
}
const event = new Event('paste')
event['clipboardData'] = clipboardData
input.dispatchEvent(event)
expect(component.value).toEqual({ day: 4, month: 5, year: 2020 })
})
})

View File

@@ -1,7 +1,7 @@
<div class="mb-3">
<label class="form-label" [for]="inputId">{{title}}</label>
<div class="input-group" [class.is-invalid]="error">
<input type="number" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [class.is-invalid]="error" [disabled]="disabled">
<input #inputField type="number" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [class.is-invalid]="error" [disabled]="disabled">
<button *ngIf="showAdd" class="btn btn-outline-secondary" type="button" id="button-addon1" (click)="nextAsn()" [disabled]="disabled">+1</button>
</div>
<div class="invalid-feedback">

View File

@@ -0,0 +1,79 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
import { NumberComponent } from './number.component'
import { DocumentService } from 'src/app/services/rest/document.service'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { of } from 'rxjs'
describe('NumberComponent', () => {
let component: NumberComponent
let fixture: ComponentFixture<NumberComponent>
let input: HTMLInputElement
let documentService: DocumentService
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [NumberComponent],
providers: [DocumentService],
imports: [FormsModule, ReactiveFormsModule, HttpClientTestingModule],
}).compileComponents()
fixture = TestBed.createComponent(NumberComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
documentService = TestBed.inject(DocumentService)
fixture.detectChanges()
input = component.inputField.nativeElement
})
// TODO: why doesnt this work?
// it('should support use of input field', () => {
// expect(component.value).toBeUndefined()
// input.stepUp()
// console.log(input.value);
// input.dispatchEvent(new Event('change'))
// fixture.detectChanges()
// expect(component.value).toEqual('3')
// })
it('should support +1 ASN', () => {
const listAllSpy = jest.spyOn(documentService, 'listFiltered')
listAllSpy
.mockReturnValueOnce(
of({
count: 1,
all: [1],
results: [
{
id: 1,
archive_serial_number: 1000,
},
],
})
)
.mockReturnValueOnce(
of({
count: 0,
all: [],
results: [],
})
)
expect(component.value).toBeUndefined()
component.nextAsn()
expect(component.value).toEqual(1001)
// this time results are empty
component.value = undefined
component.nextAsn()
expect(component.value).toEqual(1)
component.value = 1002
component.nextAsn()
expect(component.value).toEqual(1002)
})
})

View File

@@ -0,0 +1,36 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
ReactiveFormsModule,
NG_VALUE_ACCESSOR,
} from '@angular/forms'
import { PasswordComponent } from './password.component'
describe('PasswordComponent', () => {
let component: PasswordComponent
let fixture: ComponentFixture<PasswordComponent>
let input: HTMLInputElement
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [PasswordComponent],
providers: [],
imports: [FormsModule, ReactiveFormsModule],
}).compileComponents()
fixture = TestBed.createComponent(PasswordComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
input = component.inputField.nativeElement
})
it('should support use of input field', () => {
expect(component.value).toBeUndefined()
// TODO: why doesnt this work?
// input.value = 'foo'
// input.dispatchEvent(new Event('change'))
// fixture.detectChanges()
// expect(component.value).toEqual('foo')
})
})

View File

@@ -0,0 +1,66 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
ReactiveFormsModule,
NG_VALUE_ACCESSOR,
} from '@angular/forms'
import { PermissionsFormComponent } from './permissions-form.component'
import { SelectComponent } from '../../select/select.component'
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'
import { PermissionsGroupComponent } from '../permissions-group/permissions-group.component'
import { PermissionsUserComponent } from '../permissions-user/permissions-user.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { NgSelectModule } from '@ng-select/ng-select'
describe('PermissionsFormComponent', () => {
let component: PermissionsFormComponent
let fixture: ComponentFixture<PermissionsFormComponent>
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [
PermissionsFormComponent,
SelectComponent,
PermissionsGroupComponent,
PermissionsUserComponent,
],
providers: [],
imports: [
FormsModule,
ReactiveFormsModule,
NgbAccordionModule,
HttpClientTestingModule,
NgSelectModule,
],
}).compileComponents()
fixture = TestBed.createComponent(PermissionsFormComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should support use of select for owner', () => {
const changeSpy = jest.spyOn(component, 'onChange')
component.ngOnInit()
component.users = [
{
id: 2,
username: 'foo',
},
{
id: 3,
username: 'bar',
},
]
component.form.get('owner').patchValue(2)
fixture.detectChanges()
expect(changeSpy).toHaveBeenCalledWith({
owner: 2,
set_permissions: {
view: { users: [], groups: [] },
change: { users: [], groups: [] },
},
})
})
})

View File

@@ -0,0 +1,59 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
import { PermissionsGroupComponent } from './permissions-group.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { NgSelectModule } from '@ng-select/ng-select'
import { GroupService } from 'src/app/services/rest/group.service'
import { of } from 'rxjs'
describe('PermissionsGroupComponent', () => {
let component: PermissionsGroupComponent
let fixture: ComponentFixture<PermissionsGroupComponent>
let groupService: GroupService
let groupServiceSpy
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [PermissionsGroupComponent],
providers: [GroupService],
imports: [
FormsModule,
ReactiveFormsModule,
HttpClientTestingModule,
NgSelectModule,
],
}).compileComponents()
groupService = TestBed.inject(GroupService)
groupServiceSpy = jest.spyOn(groupService, 'listAll').mockReturnValue(
of({
count: 2,
all: [2, 3],
results: [
{
id: 2,
name: 'Group 2',
},
{
id: 3,
name: 'Group 3',
},
],
})
)
fixture = TestBed.createComponent(PermissionsGroupComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should get groups, support use of select', () => {
component.writeValue({ id: 2, name: 'Group 2' })
expect(component.value).toEqual({ id: 2, name: 'Group 2' })
expect(groupServiceSpy).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,60 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
NG_VALUE_ACCESSOR,
ReactiveFormsModule,
} from '@angular/forms'
import { PermissionsUserComponent } from './permissions-user.component'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { NgSelectModule } from '@ng-select/ng-select'
import { GroupService } from 'src/app/services/rest/group.service'
import { of } from 'rxjs'
import { UserService } from 'src/app/services/rest/user.service'
describe('PermissionsUserComponent', () => {
let component: PermissionsUserComponent
let fixture: ComponentFixture<PermissionsUserComponent>
let userService: UserService
let userServiceSpy
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [PermissionsUserComponent],
providers: [UserService],
imports: [
FormsModule,
ReactiveFormsModule,
HttpClientTestingModule,
NgSelectModule,
],
}).compileComponents()
userService = TestBed.inject(UserService)
userServiceSpy = jest.spyOn(userService, 'listAll').mockReturnValue(
of({
count: 2,
all: [2, 3],
results: [
{
id: 2,
name: 'User 2',
},
{
id: 3,
name: 'User 3',
},
],
})
)
fixture = TestBed.createComponent(PermissionsUserComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should get users, support use of select', () => {
component.writeValue({ id: 2, name: 'User 2' })
expect(component.value).toEqual({ id: 2, name: 'User 2' })
expect(userServiceSpy).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,121 @@
import {
ComponentFixture,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing'
import {
FormsModule,
ReactiveFormsModule,
NG_VALUE_ACCESSOR,
} from '@angular/forms'
import { SelectComponent } from './select.component'
import { PaperlessTag } from 'src/app/data/paperless-tag'
import {
DEFAULT_MATCHING_ALGORITHM,
MATCH_ALL,
} from 'src/app/data/matching-model'
import { NgSelectModule } from '@ng-select/ng-select'
import { RouterTestingModule } from '@angular/router/testing'
const items: PaperlessTag[] = [
{
id: 1,
name: 'Tag1',
is_inbox_tag: false,
matching_algorithm: DEFAULT_MATCHING_ALGORITHM,
},
{
id: 2,
name: 'Tag2',
is_inbox_tag: true,
matching_algorithm: MATCH_ALL,
match: 'str',
},
{
id: 10,
name: 'Tag10',
is_inbox_tag: false,
matching_algorithm: DEFAULT_MATCHING_ALGORITHM,
},
]
describe('SelectComponent', () => {
let component: SelectComponent
let fixture: ComponentFixture<SelectComponent>
let input: HTMLInputElement
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [SelectComponent],
providers: [],
imports: [
FormsModule,
ReactiveFormsModule,
NgSelectModule,
RouterTestingModule,
],
}).compileComponents()
fixture = TestBed.createComponent(SelectComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should support private items', () => {
component.value = 3
component.items = items
expect(component.items).toContainEqual({
id: 3,
name: 'Private',
private: true,
})
component.checkForPrivateItems([4, 5])
expect(component.items).toContainEqual({
id: 4,
name: 'Private',
private: true,
})
expect(component.items).toContainEqual({
id: 5,
name: 'Private',
private: true,
})
})
it('should support suggestions', () => {
expect(component.value).toBeUndefined()
component.items = items
component.suggestions = [1, 2]
fixture.detectChanges()
const suggestionAnchor: HTMLAnchorElement =
fixture.nativeElement.querySelector('a')
suggestionAnchor.click()
expect(component.value).toEqual(1)
})
it('should support create new and emit the value', () => {
expect(component.allowCreateNew).toBeFalsy()
component.items = items
let createNewVal
component.createNew.subscribe((v) => (createNewVal = v))
expect(component.allowCreateNew).toBeTruthy()
component.onSearch({ term: 'foo' })
component.addItem(undefined)
expect(createNewVal).toEqual('foo')
component.addItem('bar')
expect(createNewVal).toEqual('bar')
component.onSearch({ term: 'baz' })
component.clickNew()
expect(createNewVal).toEqual('baz')
})
it('should clear search term on blur after delay', fakeAsync(() => {
const clearSpy = jest.spyOn(component, 'clearLastSearchTerm')
component.onBlur()
tick(3000)
expect(clearSpy).toHaveBeenCalled()
}))
})

View File

@@ -0,0 +1,140 @@
import {
ComponentFixture,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing'
import {
FormsModule,
ReactiveFormsModule,
NG_VALUE_ACCESSOR,
} from '@angular/forms'
import { TagsComponent } from './tags.component'
import { PaperlessTag } from 'src/app/data/paperless-tag'
import {
DEFAULT_MATCHING_ALGORITHM,
MATCH_ALL,
} from 'src/app/data/matching-model'
import { NgSelectModule } from '@ng-select/ng-select'
import { RouterTestingModule } from '@angular/router/testing'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { of } from 'rxjs'
import { TagService } from 'src/app/services/rest/tag.service'
import {
NgbModal,
NgbModalModule,
NgbModalRef,
} from '@ng-bootstrap/ng-bootstrap'
const tags: PaperlessTag[] = [
{
id: 1,
name: 'Tag1',
is_inbox_tag: false,
matching_algorithm: DEFAULT_MATCHING_ALGORITHM,
},
{
id: 2,
name: 'Tag2',
is_inbox_tag: true,
matching_algorithm: MATCH_ALL,
match: 'str',
},
{
id: 10,
name: 'Tag10',
is_inbox_tag: false,
matching_algorithm: DEFAULT_MATCHING_ALGORITHM,
},
]
describe('TagsComponent', () => {
let component: TagsComponent
let fixture: ComponentFixture<TagsComponent>
let input: HTMLInputElement
let modalService: NgbModal
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [TagsComponent],
providers: [
{
provide: TagService,
useValue: {
listAll: () => of(tags),
},
},
],
imports: [
FormsModule,
ReactiveFormsModule,
NgSelectModule,
RouterTestingModule,
HttpClientTestingModule,
NgbModalModule,
],
}).compileComponents()
modalService = TestBed.inject(NgbModal)
fixture = TestBed.createComponent(TagsComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
window.PointerEvent = MouseEvent as any
})
it('should support suggestions', () => {
expect(component.value).toBeUndefined()
component.value = []
component.tags = tags
component.suggestions = [1, 2]
fixture.detectChanges()
const suggestionAnchor: HTMLAnchorElement =
fixture.nativeElement.querySelector('a')
suggestionAnchor.click()
expect(component.value).toEqual([1])
})
it('should support create new and open a modal', () => {
let activeInstances: NgbModalRef[]
modalService.activeInstances.subscribe((v) => (activeInstances = v))
component.createTag('foo')
expect(modalService.hasOpenModals()).toBeTruthy()
expect(activeInstances[0].componentInstance.object.name).toEqual('foo')
})
it('should support create new using last search term and open a modal', () => {
let activeInstances: NgbModalRef[]
modalService.activeInstances.subscribe((v) => (activeInstances = v))
component.onSearch({ term: 'bar' })
component.createTag()
expect(modalService.hasOpenModals()).toBeTruthy()
expect(activeInstances[0].componentInstance.object.name).toEqual('bar')
})
it('should clear search term on blur after delay', fakeAsync(() => {
const clearSpy = jest.spyOn(component, 'clearLastSearchTerm')
component.onBlur()
tick(3000)
expect(clearSpy).toHaveBeenCalled()
}))
it('support remove tags', () => {
component.tags = tags
component.value = [1, 2]
component.removeTag(new PointerEvent('point'), 2)
expect(component.value).toEqual([1])
component.disabled = true
component.removeTag(new PointerEvent('point'), 1)
expect(component.value).toEqual([1])
})
it('should get tags', () => {
expect(component.getTag(2)).toBeNull()
component.tags = tags
expect(component.getTag(2)).toEqual(tags[1])
expect(component.getTag(4)).toBeUndefined()
})
})

View File

@@ -11,6 +11,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { PaperlessTag } from 'src/app/data/paperless-tag'
import { TagEditDialogComponent } from '../../edit-dialog/tag-edit-dialog/tag-edit-dialog.component'
import { TagService } from 'src/app/services/rest/tag.service'
import { EditDialogMode } from '../../edit-dialog/edit-dialog.component'
@Component({
providers: [
@@ -105,7 +106,7 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
var modal = this.modalService.open(TagEditDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.dialogMode = 'create'
modal.componentInstance.dialogMode = EditDialogMode.CREATE
if (name) modal.componentInstance.object = { name: name }
else if (this._lastSearchTerm)
modal.componentInstance.object = { name: this._lastSearchTerm }

View File

@@ -0,0 +1,36 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import {
FormsModule,
ReactiveFormsModule,
NG_VALUE_ACCESSOR,
} from '@angular/forms'
import { TextComponent } from './text.component'
describe('TextComponent', () => {
let component: TextComponent
let fixture: ComponentFixture<TextComponent>
let input: HTMLInputElement
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [TextComponent],
providers: [],
imports: [FormsModule, ReactiveFormsModule],
}).compileComponents()
fixture = TestBed.createComponent(TextComponent)
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR)
component = fixture.componentInstance
fixture.detectChanges()
input = component.inputField.nativeElement
})
it('should support use of input field', () => {
expect(component.value).toBeUndefined()
// TODO: why doesnt this work?
// input.value = 'foo'
// input.dispatchEvent(new Event('change'))
// fixture.detectChanges()
// expect(component.value).toEqual('foo')
})
})