mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-05-01 11:19:32 -05:00
Frontend tests
This commit is contained in:
parent
57ad751008
commit
72764a1ce9
@ -7,7 +7,7 @@ import {
|
|||||||
} from '@angular/forms'
|
} from '@angular/forms'
|
||||||
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgSelectModule } from '@ng-select/ng-select'
|
import { NgSelectModule } from '@ng-select/ng-select'
|
||||||
import { of } from 'rxjs'
|
import { of, throwError } from 'rxjs'
|
||||||
import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
|
import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
|
||||||
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||||
import { GroupService } from 'src/app/services/rest/group.service'
|
import { GroupService } from 'src/app/services/rest/group.service'
|
||||||
@ -21,10 +21,13 @@ import { EditDialogMode } from '../edit-dialog.component'
|
|||||||
import { UserEditDialogComponent } from './user-edit-dialog.component'
|
import { UserEditDialogComponent } from './user-edit-dialog.component'
|
||||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||||
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
|
|
||||||
describe('UserEditDialogComponent', () => {
|
describe('UserEditDialogComponent', () => {
|
||||||
let component: UserEditDialogComponent
|
let component: UserEditDialogComponent
|
||||||
let settingsService: SettingsService
|
let settingsService: SettingsService
|
||||||
|
let toastService: ToastService
|
||||||
let fixture: ComponentFixture<UserEditDialogComponent>
|
let fixture: ComponentFixture<UserEditDialogComponent>
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -71,6 +74,7 @@ describe('UserEditDialogComponent', () => {
|
|||||||
fixture = TestBed.createComponent(UserEditDialogComponent)
|
fixture = TestBed.createComponent(UserEditDialogComponent)
|
||||||
settingsService = TestBed.inject(SettingsService)
|
settingsService = TestBed.inject(SettingsService)
|
||||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||||
|
toastService = TestBed.inject(ToastService)
|
||||||
component = fixture.componentInstance
|
component = fixture.componentInstance
|
||||||
|
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
@ -121,4 +125,28 @@ describe('UserEditDialogComponent', () => {
|
|||||||
component.save()
|
component.save()
|
||||||
expect(component.passwordIsSet).toBeTruthy()
|
expect(component.passwordIsSet).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should support deactivation of TOTP', () => {
|
||||||
|
component.object = { id: 99, username: 'user99' }
|
||||||
|
const deactivateSpy = jest.spyOn(
|
||||||
|
component['service'] as UserService,
|
||||||
|
'deactivateTotp'
|
||||||
|
)
|
||||||
|
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
||||||
|
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
|
||||||
|
deactivateSpy.mockReturnValueOnce(throwError(() => new Error('error')))
|
||||||
|
component.deactivateTotp()
|
||||||
|
expect(deactivateSpy).toHaveBeenCalled()
|
||||||
|
expect(toastErrorSpy).toHaveBeenCalled()
|
||||||
|
|
||||||
|
deactivateSpy.mockReturnValueOnce(of(false))
|
||||||
|
component.deactivateTotp()
|
||||||
|
expect(deactivateSpy).toHaveBeenCalled()
|
||||||
|
expect(toastErrorSpy).toHaveBeenCalled()
|
||||||
|
|
||||||
|
deactivateSpy.mockReturnValueOnce(of(true))
|
||||||
|
component.deactivateTotp()
|
||||||
|
expect(deactivateSpy).toHaveBeenCalled()
|
||||||
|
expect(toastInfoSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -294,4 +294,85 @@ describe('ProfileEditDialogComponent', () => {
|
|||||||
expect(disconnectSpy).toHaveBeenCalled()
|
expect(disconnectSpy).toHaveBeenCalled()
|
||||||
expect(component.socialAccounts).not.toContainEqual(socialAccount)
|
expect(component.socialAccounts).not.toContainEqual(socialAccount)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should get totp settings', () => {
|
||||||
|
const settings = {
|
||||||
|
url: 'http://localhost/',
|
||||||
|
qr_svg: 'svg',
|
||||||
|
secret: 'secret',
|
||||||
|
}
|
||||||
|
const getSpy = jest.spyOn(profileService, 'getTotpSettings')
|
||||||
|
const toastSpy = jest.spyOn(toastService, 'showError')
|
||||||
|
getSpy.mockReturnValueOnce(
|
||||||
|
throwError(() => new Error('failed to get settings'))
|
||||||
|
)
|
||||||
|
component.gettotpSettings()
|
||||||
|
expect(getSpy).toHaveBeenCalled()
|
||||||
|
expect(toastSpy).toHaveBeenCalled()
|
||||||
|
|
||||||
|
getSpy.mockReturnValue(of(settings))
|
||||||
|
component.gettotpSettings()
|
||||||
|
expect(getSpy).toHaveBeenCalled()
|
||||||
|
expect(component.totpSettings).toEqual(settings)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should activate totp', () => {
|
||||||
|
const activateSpy = jest.spyOn(profileService, 'activateTotp')
|
||||||
|
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
||||||
|
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
|
||||||
|
const error = new Error('failed to activate totp')
|
||||||
|
activateSpy.mockReturnValueOnce(throwError(() => error))
|
||||||
|
component.totpSettings = {
|
||||||
|
url: 'http://localhost/',
|
||||||
|
qr_svg: 'svg',
|
||||||
|
secret: 'secret',
|
||||||
|
}
|
||||||
|
component.form.get('totp_code').patchValue('123456')
|
||||||
|
component.activateTotp()
|
||||||
|
expect(activateSpy).toHaveBeenCalledWith(
|
||||||
|
component.totpSettings.secret,
|
||||||
|
component.form.get('totp_code').value
|
||||||
|
)
|
||||||
|
expect(toastErrorSpy).toHaveBeenCalled()
|
||||||
|
|
||||||
|
activateSpy.mockReturnValueOnce(of({ success: false, recovery_codes: [] }))
|
||||||
|
component.activateTotp()
|
||||||
|
expect(toastErrorSpy).toHaveBeenCalledWith('Error activating TOTP', error)
|
||||||
|
|
||||||
|
activateSpy.mockReturnValueOnce(
|
||||||
|
of({ success: true, recovery_codes: ['1', '2', '3'] })
|
||||||
|
)
|
||||||
|
component.activateTotp()
|
||||||
|
expect(toastInfoSpy).toHaveBeenCalled()
|
||||||
|
expect(component.isTotpEnabled).toBeTruthy()
|
||||||
|
expect(component.recoveryCodes).toEqual(['1', '2', '3'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should deactivate totp', () => {
|
||||||
|
const deactivateSpy = jest.spyOn(profileService, 'deactivateTotp')
|
||||||
|
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
||||||
|
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
|
||||||
|
const error = new Error('failed to deactivate totp')
|
||||||
|
deactivateSpy.mockReturnValueOnce(throwError(() => error))
|
||||||
|
component.deactivateTotp()
|
||||||
|
expect(deactivateSpy).toHaveBeenCalled()
|
||||||
|
expect(toastErrorSpy).toHaveBeenCalled()
|
||||||
|
|
||||||
|
deactivateSpy.mockReturnValueOnce(of(false))
|
||||||
|
component.deactivateTotp()
|
||||||
|
expect(toastErrorSpy).toHaveBeenCalledWith('Error deactivating TOTP', error)
|
||||||
|
|
||||||
|
deactivateSpy.mockReturnValueOnce(of(true))
|
||||||
|
component.deactivateTotp()
|
||||||
|
expect(toastInfoSpy).toHaveBeenCalled()
|
||||||
|
expect(component.isTotpEnabled).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should copy recovery codes', fakeAsync(() => {
|
||||||
|
const copySpy = jest.spyOn(clipboard, 'copy')
|
||||||
|
component.recoveryCodes = ['1', '2', '3']
|
||||||
|
component.copyRecoveryCodes()
|
||||||
|
expect(copySpy).toHaveBeenCalledWith('1\n2\n3')
|
||||||
|
tick(3000)
|
||||||
|
}))
|
||||||
})
|
})
|
||||||
|
@ -256,8 +256,6 @@ export class ProfileEditDialogComponent implements OnInit, OnDestroy {
|
|||||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (activationResponse) => {
|
next: (activationResponse) => {
|
||||||
console.log(activationResponse)
|
|
||||||
|
|
||||||
this.totpLoading = false
|
this.totpLoading = false
|
||||||
this.isTotpEnabled = activationResponse.success
|
this.isTotpEnabled = activationResponse.success
|
||||||
this.recoveryCodes = activationResponse.recovery_codes
|
this.recoveryCodes = activationResponse.recovery_codes
|
||||||
|
@ -439,4 +439,25 @@ describe('PermissionsService', () => {
|
|||||||
|
|
||||||
expect(permissionsService.isAdmin()).toBeFalsy()
|
expect(permissionsService.isAdmin()).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('correctly checks superuser status', () => {
|
||||||
|
permissionsService.initialize([], {
|
||||||
|
username: 'testuser',
|
||||||
|
last_name: 'User',
|
||||||
|
first_name: 'Test',
|
||||||
|
id: 1,
|
||||||
|
is_superuser: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(permissionsService.isSuperUser()).toBeTruthy()
|
||||||
|
|
||||||
|
permissionsService.initialize([], {
|
||||||
|
username: 'testuser',
|
||||||
|
last_name: 'User',
|
||||||
|
first_name: 'Test',
|
||||||
|
id: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(permissionsService.isSuperUser()).toBeFalsy()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -72,4 +72,32 @@ describe('ProfileService', () => {
|
|||||||
)
|
)
|
||||||
expect(req.request.method).toEqual('GET')
|
expect(req.request.method).toEqual('GET')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('calls get totp settings endpoint', () => {
|
||||||
|
service.getTotpSettings().subscribe()
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
|
`${environment.apiBaseUrl}profile/totp/`
|
||||||
|
)
|
||||||
|
expect(req.request.method).toEqual('GET')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls activate totp endpoint', () => {
|
||||||
|
service.activateTotp('secret', 'code').subscribe()
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
|
`${environment.apiBaseUrl}profile/totp/`
|
||||||
|
)
|
||||||
|
expect(req.request.method).toEqual('POST')
|
||||||
|
expect(req.request.body).toEqual({
|
||||||
|
secret: 'secret',
|
||||||
|
code: 'code',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls deactivate totp endpoint', () => {
|
||||||
|
service.deactivateTotp().subscribe()
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
|
`${environment.apiBaseUrl}profile/totp/`
|
||||||
|
)
|
||||||
|
expect(req.request.method).toEqual('DELETE')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -160,6 +160,18 @@ const user = {
|
|||||||
commonAbstractNameFilterPaperlessServiceTests(endpoint, UserService)
|
commonAbstractNameFilterPaperlessServiceTests(endpoint, UserService)
|
||||||
|
|
||||||
describe('Additional service tests for UserService', () => {
|
describe('Additional service tests for UserService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Dont need to setup again
|
||||||
|
|
||||||
|
httpTestingController = TestBed.inject(HttpTestingController)
|
||||||
|
service = TestBed.inject(UserService)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
subscription?.unsubscribe()
|
||||||
|
httpTestingController.verify()
|
||||||
|
})
|
||||||
|
|
||||||
it('should retain permissions on update', () => {
|
it('should retain permissions on update', () => {
|
||||||
subscription = service.listAll().subscribe()
|
subscription = service.listAll().subscribe()
|
||||||
let req = httpTestingController.expectOne(
|
let req = httpTestingController.expectOne(
|
||||||
@ -179,15 +191,11 @@ describe('Additional service tests for UserService', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(() => {
|
it('should deactivate totp', () => {
|
||||||
// Dont need to setup again
|
subscription = service.deactivateTotp(user).subscribe()
|
||||||
|
const req = httpTestingController.expectOne(
|
||||||
httpTestingController = TestBed.inject(HttpTestingController)
|
`${environment.apiBaseUrl}${endpoint}/${user.id}/deactivate_totp/`
|
||||||
service = TestBed.inject(UserService)
|
)
|
||||||
})
|
expect(req.request.method).toEqual('POST')
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
subscription?.unsubscribe()
|
|
||||||
httpTestingController.verify()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user