juice-shop
158 строк · 6.4 Кб
1/*
2* Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors.
3* SPDX-License-Identifier: MIT
4*/
5
6import { type ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
7import { TwoFactorAuthComponent } from './two-factor-auth.component'
8
9import { ReactiveFormsModule } from '@angular/forms'
10import { HttpClientTestingModule } from '@angular/common/http/testing'
11import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
12
13import { TranslateModule } from '@ngx-translate/core'
14
15import { MatCardModule } from '@angular/material/card'
16import { MatFormFieldModule } from '@angular/material/form-field'
17import { MatButtonModule } from '@angular/material/button'
18import { MatInputModule } from '@angular/material/input'
19import { MatCheckboxModule } from '@angular/material/checkbox'
20import { MatIconModule } from '@angular/material/icon'
21import { MatTableModule } from '@angular/material/table'
22import { MatPaginatorModule } from '@angular/material/paginator'
23import { MatDialogModule } from '@angular/material/dialog'
24import { MatDividerModule } from '@angular/material/divider'
25import { MatSnackBarModule } from '@angular/material/snack-bar'
26import { MatTooltipModule } from '@angular/material/tooltip'
27
28import { QRCodeModule } from 'anuglar2-qrcode'
29import { of } from 'rxjs'
30import { ConfigurationService } from '../Services/configuration.service'
31import { TwoFactorAuthService } from '../Services/two-factor-auth-service'
32import { throwError } from 'rxjs/internal/observable/throwError'
33
34describe('TwoFactorAuthComponent', () => {
35let component: TwoFactorAuthComponent
36let fixture: ComponentFixture<TwoFactorAuthComponent>
37let twoFactorAuthService: any
38let configurationService: any
39
40beforeEach(waitForAsync(() => {
41twoFactorAuthService = jasmine.createSpyObj('TwoFactorAuthService', ['status', 'setup', 'disable'])
42configurationService = jasmine.createSpyObj('ConfigurationService', ['getApplicationConfiguration'])
43configurationService.getApplicationConfiguration.and.returnValue(of({ application: { } }))
44TestBed.configureTestingModule({
45declarations: [TwoFactorAuthComponent],
46imports: [
47HttpClientTestingModule,
48ReactiveFormsModule,
49TranslateModule.forRoot(),
50BrowserAnimationsModule,
51MatCheckboxModule,
52MatFormFieldModule,
53MatCardModule,
54MatIconModule,
55MatInputModule,
56MatTableModule,
57MatPaginatorModule,
58MatDialogModule,
59MatDividerModule,
60MatButtonModule,
61QRCodeModule,
62MatSnackBarModule,
63MatTooltipModule
64],
65providers: [
66{ provide: ConfigurationService, useValue: configurationService },
67{ provide: TwoFactorAuthService, useValue: twoFactorAuthService }
68]
69}).compileComponents()
70}))
71
72beforeEach(() => {
73fixture = TestBed.createComponent(TwoFactorAuthComponent)
74component = fixture.componentInstance
75fixture.detectChanges()
76})
77
78it('should compile', () => {
79expect(component).toBeTruthy()
80})
81
82it('should set TOTP secret and URL if 2FA is not already set up', () => {
83configurationService.getApplicationConfiguration.and.returnValue(of({ application: { name: 'Test App' } }))
84twoFactorAuthService.status.and.returnValue(of({ setup: false, email: 'email', secret: 'secret', setupToken: '12345' }))
85
86component.updateStatus()
87
88expect(component.setupStatus).toBe(false)
89expect(component.totpUrl).toBe('otpauth://totp/Test%20App:email?secret=secret&issuer=Test%20App')
90expect(component.totpSecret).toBe('secret')
91})
92
93it('should not set TOTP secret and URL if 2FA is already set up', () => {
94configurationService.getApplicationConfiguration.and.returnValue(of({ application: { name: 'Test App' } }))
95twoFactorAuthService.status.and.returnValue(of({ setup: true, email: 'email', secret: 'secret', setupToken: '12345' }))
96
97component.updateStatus()
98
99expect(component.setupStatus).toBe(true)
100expect(component.totpUrl).toBe(undefined)
101expect(component.totpSecret).toBe(undefined)
102})
103
104it('should confirm successful setup of 2FA', () => {
105twoFactorAuthService.setup.and.returnValue(of({}))
106component.setupStatus = false
107component.twoFactorSetupForm.get('passwordControl').setValue('password')
108component.twoFactorSetupForm.get('initalTokenControl').setValue('12345')
109
110component.setup()
111
112expect(component.setupStatus).toBe(true)
113expect(twoFactorAuthService.setup).toHaveBeenCalledWith('password', '12345', undefined)
114})
115
116it('should reset and mark form as errored when 2FA setup fails', () => {
117twoFactorAuthService.setup.and.returnValue(throwError(new Error('Error')))
118component.setupStatus = false
119component.errored = false
120component.twoFactorSetupForm.get('passwordControl').markAsDirty()
121component.twoFactorSetupForm.get('initalTokenControl').markAsDirty()
122
123expect(component.twoFactorSetupForm.get('passwordControl').pristine).toBe(false)
124expect(component.twoFactorSetupForm.get('initalTokenControl').pristine).toBe(false)
125component.setup()
126
127expect(component.setupStatus).toBe(false)
128expect(component.errored).toBe(true)
129expect(component.twoFactorSetupForm.get('passwordControl').pristine).toBe(true)
130expect(component.twoFactorSetupForm.get('initalTokenControl').pristine).toBe(true)
131})
132
133it('should confirm successfully disabling 2FA', () => {
134twoFactorAuthService.status.and.returnValue(of({ setup: true, email: 'email', secret: 'secret', setupToken: '12345' }))
135twoFactorAuthService.disable.and.returnValue(of({}))
136component.setupStatus = true
137component.twoFactorDisableForm.get('passwordControl').setValue('password')
138
139component.disable()
140
141expect(component.setupStatus).toBe(false)
142expect(twoFactorAuthService.disable).toHaveBeenCalledWith('password')
143})
144
145it('should reset and mark form as errored when disabling 2FA fails', () => {
146twoFactorAuthService.disable.and.returnValue(throwError(new Error('Error')))
147component.setupStatus = true
148component.errored = false
149component.twoFactorDisableForm.get('passwordControl').markAsDirty()
150
151expect(component.twoFactorDisableForm.get('passwordControl').pristine).toBe(false)
152component.disable()
153
154expect(component.setupStatus).toBe(true)
155expect(component.errored).toBe(true)
156expect(component.twoFactorDisableForm.get('passwordControl').pristine).toBe(true)
157})
158})
159