mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-09-16 21:55:37 -05:00
Frontend tests
This commit is contained in:
@@ -409,4 +409,13 @@ describe('MailComponent', () => {
|
|||||||
jest.advanceTimersByTime(200)
|
jest.advanceTimersByTime(200)
|
||||||
expect(editSpy).toHaveBeenCalled()
|
expect(editSpy).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should open processed mails dialog', () => {
|
||||||
|
completeSetup()
|
||||||
|
let modal: NgbModalRef
|
||||||
|
modalService.activeInstances.subscribe((refs) => (modal = refs[0]))
|
||||||
|
component.viewProcessedMails(mailRules[0] as MailRule)
|
||||||
|
const dialog = modal.componentInstance as any
|
||||||
|
expect(dialog.rule).toEqual(mailRules[0])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@@ -0,0 +1,174 @@
|
|||||||
|
import { DatePipe } from '@angular/common'
|
||||||
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||||
|
import {
|
||||||
|
HttpTestingController,
|
||||||
|
provideHttpClientTesting,
|
||||||
|
} from '@angular/common/http/testing'
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||||
|
import { FormsModule } from '@angular/forms'
|
||||||
|
import { By } from '@angular/platform-browser'
|
||||||
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
|
import { environment } from 'src/environments/environment'
|
||||||
|
import { ProcessedMailsDialogComponent } from './processed-mails-dialog.component'
|
||||||
|
|
||||||
|
describe('ProcessedMailsDialogComponent', () => {
|
||||||
|
let component: ProcessedMailsDialogComponent
|
||||||
|
let fixture: ComponentFixture<ProcessedMailsDialogComponent>
|
||||||
|
let httpTestingController: HttpTestingController
|
||||||
|
let toastService: ToastService
|
||||||
|
|
||||||
|
const rule: any = { id: 10, name: 'Mail Rule' } // minimal rule object for tests
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
ProcessedMailsDialogComponent,
|
||||||
|
FormsModule,
|
||||||
|
NgxBootstrapIconsModule.pick(allIcons),
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
DatePipe,
|
||||||
|
NgbActiveModal,
|
||||||
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
|
provideHttpClientTesting(),
|
||||||
|
],
|
||||||
|
}).compileComponents()
|
||||||
|
|
||||||
|
httpTestingController = TestBed.inject(HttpTestingController)
|
||||||
|
toastService = TestBed.inject(ToastService)
|
||||||
|
fixture = TestBed.createComponent(ProcessedMailsDialogComponent)
|
||||||
|
component = fixture.componentInstance
|
||||||
|
component.rule = rule
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
httpTestingController.verify()
|
||||||
|
})
|
||||||
|
|
||||||
|
function expectListRequest(ruleId: number) {
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
|
`${environment.apiBaseUrl}processed_mail/?page=1&page_size=50&ordering=-processed_at&rule=${ruleId}`
|
||||||
|
)
|
||||||
|
expect(req.request.method).toEqual('GET')
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should load processed mails on init', () => {
|
||||||
|
fixture.detectChanges()
|
||||||
|
const req = expectListRequest(rule.id)
|
||||||
|
const mails = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
rule: rule.id,
|
||||||
|
folder: 'INBOX',
|
||||||
|
uid: 111,
|
||||||
|
subject: 'Subject 1',
|
||||||
|
received: new Date().toISOString(),
|
||||||
|
processed: new Date().toISOString(),
|
||||||
|
status: 'SUCCESS',
|
||||||
|
error: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
rule: rule.id,
|
||||||
|
folder: 'INBOX',
|
||||||
|
uid: 222,
|
||||||
|
subject: 'Subject 2',
|
||||||
|
received: new Date().toISOString(),
|
||||||
|
processed: new Date().toISOString(),
|
||||||
|
status: 'FAILED',
|
||||||
|
error: 'Something went wrong',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
req.flush({ count: 2, results: mails })
|
||||||
|
expect(component.loading).toBeFalsy()
|
||||||
|
expect(component.processedMails).toEqual(mails)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should delete selected mails and reload', () => {
|
||||||
|
fixture.detectChanges()
|
||||||
|
// initial load
|
||||||
|
const initialReq = expectListRequest(rule.id)
|
||||||
|
initialReq.flush({ count: 0, results: [] })
|
||||||
|
|
||||||
|
// select a couple of mails and delete
|
||||||
|
component.selectedMailIds.add(5)
|
||||||
|
component.selectedMailIds.add(6)
|
||||||
|
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
|
||||||
|
component.deleteSelected()
|
||||||
|
|
||||||
|
const delReq = httpTestingController.expectOne(
|
||||||
|
`${environment.apiBaseUrl}processed_mail/bulk_delete/`
|
||||||
|
)
|
||||||
|
expect(delReq.request.method).toEqual('POST')
|
||||||
|
expect(delReq.request.body).toEqual({ mail_ids: [5, 6] })
|
||||||
|
delReq.flush({})
|
||||||
|
|
||||||
|
// reload after delete
|
||||||
|
const reloadReq = expectListRequest(rule.id)
|
||||||
|
reloadReq.flush({ count: 0, results: [] })
|
||||||
|
expect(toastInfoSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle all, toggle selected, and clear selection', () => {
|
||||||
|
fixture.detectChanges()
|
||||||
|
// initial load with two mails
|
||||||
|
const req = expectListRequest(rule.id)
|
||||||
|
const mails = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
rule: rule.id,
|
||||||
|
folder: 'INBOX',
|
||||||
|
uid: 111,
|
||||||
|
subject: 'A',
|
||||||
|
received: new Date().toISOString(),
|
||||||
|
processed: new Date().toISOString(),
|
||||||
|
status: 'SUCCESS',
|
||||||
|
error: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
rule: rule.id,
|
||||||
|
folder: 'INBOX',
|
||||||
|
uid: 222,
|
||||||
|
subject: 'B',
|
||||||
|
received: new Date().toISOString(),
|
||||||
|
processed: new Date().toISOString(),
|
||||||
|
status: 'FAILED',
|
||||||
|
error: 'Oops',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
req.flush({ count: 2, results: mails })
|
||||||
|
fixture.detectChanges()
|
||||||
|
|
||||||
|
// toggle all via header checkbox
|
||||||
|
const inputs = fixture.debugElement.queryAll(
|
||||||
|
By.css('input.form-check-input')
|
||||||
|
)
|
||||||
|
const header = inputs[0].nativeElement as HTMLInputElement
|
||||||
|
header.dispatchEvent(new Event('click'))
|
||||||
|
header.checked = true
|
||||||
|
header.dispatchEvent(new Event('click'))
|
||||||
|
expect(component.selectedMailIds.size).toEqual(mails.length)
|
||||||
|
|
||||||
|
// toggle a single mail
|
||||||
|
component.toggleSelected(mails[0] as any)
|
||||||
|
expect(component.selectedMailIds.has(mails[0].id)).toBeFalsy()
|
||||||
|
component.toggleSelected(mails[0] as any)
|
||||||
|
expect(component.selectedMailIds.has(mails[0].id)).toBeTruthy()
|
||||||
|
|
||||||
|
// clear selection
|
||||||
|
component.clearSelection()
|
||||||
|
expect(component.selectedMailIds.size).toEqual(0)
|
||||||
|
expect(component.toggleAllEnabled).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should close the dialog', () => {
|
||||||
|
const activeModal = TestBed.inject(NgbActiveModal)
|
||||||
|
const closeSpy = jest.spyOn(activeModal, 'close')
|
||||||
|
component.close()
|
||||||
|
expect(closeSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { SlicePipe } from '@angular/common'
|
import { SlicePipe } from '@angular/common'
|
||||||
import { Component, inject, Input } from '@angular/core'
|
import { Component, inject, Input } from '@angular/core'
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
import {
|
import {
|
||||||
NgbActiveModal,
|
NgbActiveModal,
|
||||||
NgbPagination,
|
NgbPagination,
|
||||||
@@ -21,6 +22,8 @@ import { ToastService } from 'src/app/services/toast.service'
|
|||||||
NgbPagination,
|
NgbPagination,
|
||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
NgxBootstrapIconsModule,
|
NgxBootstrapIconsModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
SlicePipe,
|
SlicePipe,
|
||||||
],
|
],
|
||||||
templateUrl: './processed-mails-dialog.component.html',
|
templateUrl: './processed-mails-dialog.component.html',
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
import { HttpTestingController } from '@angular/common/http/testing'
|
||||||
|
import { TestBed } from '@angular/core/testing'
|
||||||
|
import { Subscription } from 'rxjs'
|
||||||
|
import { environment } from 'src/environments/environment'
|
||||||
|
import { commonAbstractPaperlessServiceTests } from './abstract-paperless-service.spec'
|
||||||
|
import { ProcessedMailService } from './processed-mail.service'
|
||||||
|
|
||||||
|
let httpTestingController: HttpTestingController
|
||||||
|
let service: ProcessedMailService
|
||||||
|
let subscription: Subscription
|
||||||
|
const endpoint = 'processed_mail'
|
||||||
|
|
||||||
|
// run common tests
|
||||||
|
commonAbstractPaperlessServiceTests(endpoint, ProcessedMailService)
|
||||||
|
|
||||||
|
describe('Additional service tests for ProcessedMailService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Dont need to setup again
|
||||||
|
|
||||||
|
httpTestingController = TestBed.inject(HttpTestingController)
|
||||||
|
service = TestBed.inject(ProcessedMailService)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
subscription?.unsubscribe()
|
||||||
|
httpTestingController.verify()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should call appropriate api endpoint for bulk delete', () => {
|
||||||
|
const ids = [1, 2, 3]
|
||||||
|
subscription = service.bulk_delete(ids).subscribe()
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
|
`${environment.apiBaseUrl}${endpoint}/bulk_delete/`
|
||||||
|
)
|
||||||
|
expect(req.request.method).toEqual('POST')
|
||||||
|
expect(req.request.body).toEqual({ mail_ids: ids })
|
||||||
|
req.flush({})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Reference in New Issue
Block a user