juice-shop
221 строка · 9.2 Кб
1/*
2* Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors.
3* SPDX-License-Identifier: MIT
4*/
5
6import { TranslateModule, TranslateService } from '@ngx-translate/core'
7import { MatDatepickerModule } from '@angular/material/datepicker'
8import { ConfigurationService } from '../Services/configuration.service'
9import { UserService } from '../Services/user.service'
10import { RecycleService } from '../Services/recycle.service'
11import { HttpClientTestingModule } from '@angular/common/http/testing'
12import { MatCardModule } from '@angular/material/card'
13import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
14import { MatButtonModule } from '@angular/material/button'
15import { MatInputModule } from '@angular/material/input'
16import { type ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'
17
18import { RecycleComponent } from './recycle.component'
19import { MatFormFieldModule } from '@angular/material/form-field'
20import { ReactiveFormsModule } from '@angular/forms'
21import { MatCheckboxModule } from '@angular/material/checkbox'
22import { MatNativeDateModule } from '@angular/material/core'
23import { of, throwError } from 'rxjs'
24import { AddressComponent } from '../address/address.component'
25import { RouterTestingModule } from '@angular/router/testing'
26import { EventEmitter } from '@angular/core'
27import { MatIconModule } from '@angular/material/icon'
28import { MatTableModule } from '@angular/material/table'
29import { MatToolbarModule } from '@angular/material/toolbar'
30import { MatRadioModule } from '@angular/material/radio'
31import { MatTooltipModule } from '@angular/material/tooltip'
32import { MatDialogModule } from '@angular/material/dialog'
33import { MatDividerModule } from '@angular/material/divider'
34import { MatSnackBar } from '@angular/material/snack-bar'
35
36describe('RecycleComponent', () => {
37let component: RecycleComponent
38let fixture: ComponentFixture<RecycleComponent>
39let recycleService: any
40let userService: any
41let configurationService: any
42let translateService
43let snackBar: any
44
45beforeEach(waitForAsync(() => {
46recycleService = jasmine.createSpyObj('RecycleService', ['save', 'find'])
47recycleService.save.and.returnValue(of({}))
48recycleService.find.and.returnValue(of([{}]))
49userService = jasmine.createSpyObj('UserService', ['whoAmI'])
50userService.whoAmI.and.returnValue(of({}))
51configurationService = jasmine.createSpyObj('ConfigurationService', ['getApplicationConfiguration'])
52configurationService.getApplicationConfiguration.and.returnValue(of({}))
53translateService = jasmine.createSpyObj('TranslateService', ['get'])
54translateService.get.and.returnValue(of({}))
55translateService.onLangChange = new EventEmitter()
56translateService.onTranslationChange = new EventEmitter()
57translateService.onDefaultLangChange = new EventEmitter()
58snackBar = jasmine.createSpyObj('MatSnackBar', ['open'])
59
60TestBed.configureTestingModule({
61imports: [
62RouterTestingModule,
63TranslateModule.forRoot(),
64HttpClientTestingModule,
65BrowserAnimationsModule,
66ReactiveFormsModule,
67MatFormFieldModule,
68MatInputModule,
69MatButtonModule,
70MatCardModule,
71MatCheckboxModule,
72MatDatepickerModule,
73MatNativeDateModule,
74MatIconModule,
75MatToolbarModule,
76MatTableModule,
77MatRadioModule,
78MatTooltipModule,
79MatDialogModule,
80MatDividerModule
81],
82declarations: [RecycleComponent, AddressComponent],
83providers: [
84{ provide: RecycleService, useValue: recycleService },
85{ provide: UserService, useValue: userService },
86{ provide: ConfigurationService, useValue: configurationService },
87{ provide: TranslateService, useValue: translateService },
88{ provide: MatSnackBar, useValue: snackBar }
89]
90})
91.compileComponents()
92}))
93
94beforeEach(() => {
95fixture = TestBed.createComponent(RecycleComponent)
96component = fixture.componentInstance
97fixture.detectChanges()
98})
99
100it('should create', () => {
101expect(component).toBeTruthy()
102})
103
104it('should reset the form by calling resetForm', () => {
105component.addressId = '1'
106component.recycleQuantityControl.setValue('100')
107component.pickUpDateControl.setValue('10/7/2018')
108component.pickup.setValue(true)
109component.resetForm()
110expect(component.addressId).toBeUndefined()
111expect(component.recycleQuantityControl.value).toBe('')
112expect(component.recycleQuantityControl.untouched).toBe(true)
113expect(component.recycleQuantityControl.pristine).toBe(true)
114expect(component.pickUpDateControl.value).toBe('')
115expect(component.pickUpDateControl.untouched).toBe(true)
116expect(component.pickUpDateControl.pristine).toBe(true)
117expect(component.pickup.value).toBe(false)
118})
119
120it('should hold the user id of the currently logged in user', () => {
121userService.whoAmI.and.returnValue(of({ id: 42 }))
122component.ngOnInit()
123expect(component.recycle.UserId).toBe(42)
124})
125
126it('should hold no email if current user is not logged in', () => {
127userService.whoAmI.and.returnValue(of({}))
128component.ngOnInit()
129expect(component.userEmail).toBeUndefined()
130})
131
132it('should hold the user email of the currently logged in user', () => {
133userService.whoAmI.and.returnValue(of({ email: 'x@x.xx' }))
134component.ngOnInit()
135expect(component.userEmail).toBe('x@x.xx')
136})
137
138it('should display pickup message and reset recycle form on saving', () => {
139recycleService.save.and.returnValue(of({}))
140userService.whoAmI.and.returnValue(of({}))
141translateService.get.and.returnValue(of('CONFIRM_RECYCLING_BOX'))
142spyOn(component, 'initRecycle')
143spyOn(component.addressComponent, 'load')
144component.addressId = '1'
145component.recycleQuantityControl.setValue(100)
146component.pickup.setValue(false)
147const recycle = { UserId: undefined, AddressId: '1', quantity: 100 }
148component.save()
149expect(recycleService.save.calls.count()).toBe(1)
150expect(recycleService.save.calls.argsFor(0)[0]).toEqual(recycle)
151expect(component.initRecycle).toHaveBeenCalled()
152expect(component.addressComponent.load).toHaveBeenCalled()
153expect(translateService.get).toHaveBeenCalledWith('CONFIRM_RECYCLING_BOX')
154})
155
156it('should display pickup message and reset recycle form on saving when pickup is selected', () => {
157recycleService.save.and.returnValue(of({ isPickup: true, pickupDate: '10/7/2018' }))
158userService.whoAmI.and.returnValue(of({}))
159translateService.get.and.returnValue(of('CONFIRM_RECYCLING_PICKUP'))
160spyOn(component, 'initRecycle')
161spyOn(component.addressComponent, 'load')
162component.addressId = '1'
163component.recycleQuantityControl.setValue(100)
164component.pickup.setValue(true)
165component.pickUpDateControl.setValue('10/7/2018')
166const recycle = { isPickUp: true, date: '10/7/2018', UserId: undefined, AddressId: '1', quantity: 100 }
167component.save()
168expect(recycleService.save.calls.count()).toBe(1)
169expect(recycleService.save.calls.argsFor(0)[0]).toEqual(recycle)
170expect(component.initRecycle).toHaveBeenCalled()
171expect(component.addressComponent.load).toHaveBeenCalled()
172expect(translateService.get).toHaveBeenCalledWith('CONFIRM_RECYCLING_PICKUP', { pickupdate: '10/7/2018' })
173})
174
175it('should hold existing recycles', () => {
176recycleService.find.and.returnValue(of([{ quantity: 1 }, { quantity: 2 }]))
177component.ngOnInit()
178expect(component.recycles.length).toBe(2)
179expect(component.recycles[0].quantity).toBe(1)
180expect(component.recycles[1].quantity).toBe(2)
181})
182
183it('should hold nothing when no recycles exists', () => {
184recycleService.find.and.returnValue(of([]))
185component.ngOnInit()
186expect(component.recycles.length).toBe(0)
187})
188
189it('should hold nothing on error from backend API', () => {
190recycleService.find.and.returnValue(throwError('Error'))
191console.log = jasmine.createSpy('log')
192component.ngOnInit()
193expect(console.log).toHaveBeenCalledWith('Error')
194})
195
196it('should log the error on retrieving the user', fakeAsync(() => {
197userService.whoAmI.and.returnValue(throwError('Error'))
198console.log = jasmine.createSpy('log')
199component.ngOnInit()
200expect(console.log).toHaveBeenCalledWith('Error')
201}))
202
203it('should use a configured product image on top of page', () => {
204configurationService.getApplicationConfiguration.and.returnValue(of({ application: { recyclePage: { topProductImage: 'top.png' } } }))
205component.ngOnInit()
206expect(component.topImage).toEqual('assets/public/images/products/top.png')
207})
208
209it('should use a configured product image on bottom of page', () => {
210configurationService.getApplicationConfiguration.and.returnValue(of({ application: { recyclePage: { topProductImage: 'bottom.png' } } }))
211component.ngOnInit()
212expect(component.topImage).toEqual('assets/public/images/products/bottom.png')
213})
214
215it('should show broken top and bottom image on error retrieving configuration', fakeAsync(() => {
216configurationService.getApplicationConfiguration.and.returnValue(throwError('Error'))
217component.ngOnInit()
218expect(component.topImage).toBeUndefined()
219expect(component.bottomImage).toBeUndefined()
220}))
221})
222