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'
|
||||
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
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 { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
||||
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 { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||
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', () => {
|
||||
let component: UserEditDialogComponent
|
||||
let settingsService: SettingsService
|
||||
let toastService: ToastService
|
||||
let fixture: ComponentFixture<UserEditDialogComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
@ -71,6 +74,7 @@ describe('UserEditDialogComponent', () => {
|
||||
fixture = TestBed.createComponent(UserEditDialogComponent)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
settingsService.currentUser = { id: 99, username: 'user99' }
|
||||
toastService = TestBed.inject(ToastService)
|
||||
component = fixture.componentInstance
|
||||
|
||||
fixture.detectChanges()
|
||||
@ -121,4 +125,28 @@ describe('UserEditDialogComponent', () => {
|
||||
component.save()
|
||||
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(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))
|
||||
.subscribe({
|
||||
next: (activationResponse) => {
|
||||
console.log(activationResponse)
|
||||
|
||||
this.totpLoading = false
|
||||
this.isTotpEnabled = activationResponse.success
|
||||
this.recoveryCodes = activationResponse.recovery_codes
|
||||
|
@ -439,4 +439,25 @@ describe('PermissionsService', () => {
|
||||
|
||||
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')
|
||||
})
|
||||
|
||||
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)
|
||||
|
||||
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', () => {
|
||||
subscription = service.listAll().subscribe()
|
||||
let req = httpTestingController.expectOne(
|
||||
@ -179,15 +191,11 @@ 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 deactivate totp', () => {
|
||||
subscription = service.deactivateTotp(user).subscribe()
|
||||
const req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}${endpoint}/${user.id}/deactivate_totp/`
|
||||
)
|
||||
expect(req.request.method).toEqual('POST')
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user