]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | import { LOCALE_ID, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core'; |
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
3 | import { AbstractControl } from '@angular/forms'; | |
4 | import { By } from '@angular/platform-browser'; | |
5 | ||
6 | import { I18n } from '@ngx-translate/i18n-polyfill'; | |
7 | import * as _ from 'lodash'; | |
8 | ||
9 | import { TableActionsComponent } from '../app/shared/datatable/table-actions/table-actions.component'; | |
10 | import { CdFormGroup } from '../app/shared/forms/cd-form-group'; | |
11 | import { Permission } from '../app/shared/models/permissions'; | |
12 | import { | |
13 | PrometheusAlert, | |
14 | PrometheusNotification, | |
15 | PrometheusNotificationAlert | |
16 | } from '../app/shared/models/prometheus-alerts'; | |
17 | import { _DEV_ } from '../unit-test-configuration'; | |
18 | ||
19 | export function configureTestBed(configuration, useOldMethod?) { | |
20 | if (_DEV_ && !useOldMethod) { | |
21 | const resetTestingModule = TestBed.resetTestingModule; | |
22 | beforeAll((done) => | |
23 | (async () => { | |
24 | TestBed.resetTestingModule(); | |
25 | TestBed.configureTestingModule(configuration); | |
26 | // prevent Angular from resetting testing module | |
27 | TestBed.resetTestingModule = () => TestBed; | |
28 | })() | |
29 | .then(done) | |
30 | .catch(done.fail) | |
31 | ); | |
32 | afterAll(() => { | |
33 | TestBed.resetTestingModule = resetTestingModule; | |
34 | }); | |
35 | } else { | |
36 | beforeEach(async(() => { | |
37 | TestBed.configureTestingModule(configuration); | |
38 | })); | |
39 | } | |
40 | } | |
41 | ||
42 | export class PermissionHelper { | |
43 | tableActions: TableActionsComponent; | |
44 | permission: Permission; | |
45 | getTableActionComponent: () => TableActionsComponent; | |
46 | ||
47 | constructor(permission: Permission, getTableActionComponent: () => TableActionsComponent) { | |
48 | this.permission = permission; | |
49 | this.getTableActionComponent = getTableActionComponent; | |
50 | } | |
51 | ||
52 | setPermissionsAndGetActions( | |
53 | createPerm: number | boolean, | |
54 | updatePerm: number | boolean, | |
55 | deletePerm: number | boolean | |
56 | ): TableActionsComponent { | |
57 | this.permission.create = Boolean(createPerm); | |
58 | this.permission.update = Boolean(updatePerm); | |
59 | this.permission.delete = Boolean(deletePerm); | |
60 | this.tableActions = this.getTableActionComponent(); | |
61 | return this.tableActions; | |
62 | } | |
63 | ||
64 | testScenarios({ | |
65 | fn, | |
66 | empty, | |
67 | single, | |
68 | singleExecuting, | |
69 | multiple | |
70 | }: { | |
71 | fn: () => any; | |
72 | empty: any; | |
73 | single: any; | |
74 | singleExecuting?: any; // uses 'single' if not defined | |
75 | multiple?: any; // uses 'empty' if not defined | |
76 | }) { | |
77 | this.testScenario( | |
78 | // 'multiple selections' | |
79 | [{}, {}], | |
80 | fn, | |
81 | _.isUndefined(multiple) ? empty : multiple | |
82 | ); | |
83 | this.testScenario( | |
84 | // 'select executing item' | |
85 | [{ cdExecuting: 'someAction' }], | |
86 | fn, | |
87 | _.isUndefined(singleExecuting) ? single : singleExecuting | |
88 | ); | |
89 | this.testScenario([{}], fn, single); // 'select non-executing item' | |
90 | this.testScenario([], fn, empty); // 'no selection' | |
91 | } | |
92 | ||
93 | private testScenario(selection: object[], fn: () => any, expected: any) { | |
94 | this.setSelection(selection); | |
95 | expect(fn()).toBe(expected); | |
96 | } | |
97 | ||
98 | setSelection(selection: object[]) { | |
99 | this.tableActions.selection.selected = selection; | |
100 | this.tableActions.selection.update(); | |
101 | } | |
102 | } | |
103 | ||
104 | export class FormHelper { | |
105 | form: CdFormGroup; | |
106 | ||
107 | constructor(form: CdFormGroup) { | |
108 | this.form = form; | |
109 | } | |
110 | ||
111 | /** | |
112 | * Changes multiple values in multiple controls | |
113 | */ | |
114 | setMultipleValues(values: { [controlName: string]: any }, markAsDirty?: boolean) { | |
115 | Object.keys(values).forEach((key) => { | |
116 | this.setValue(key, values[key], markAsDirty); | |
117 | }); | |
118 | } | |
119 | ||
120 | /** | |
121 | * Changes the value of a control | |
122 | */ | |
123 | setValue(control: AbstractControl | string, value: any, markAsDirty?: boolean): AbstractControl { | |
124 | control = this.getControl(control); | |
125 | if (markAsDirty) { | |
126 | control.markAsDirty(); | |
127 | } | |
128 | control.setValue(value); | |
129 | return control; | |
130 | } | |
131 | ||
132 | private getControl(control: AbstractControl | string): AbstractControl { | |
133 | if (typeof control === 'string') { | |
134 | return this.form.get(control); | |
135 | } | |
136 | return control; | |
137 | } | |
138 | ||
139 | /** | |
140 | * Change the value of the control and expect the control to be valid afterwards. | |
141 | */ | |
142 | expectValidChange(control: AbstractControl | string, value: any, markAsDirty?: boolean) { | |
143 | this.expectValid(this.setValue(control, value, markAsDirty)); | |
144 | } | |
145 | ||
146 | /** | |
147 | * Expect that the given control is valid. | |
148 | */ | |
149 | expectValid(control: AbstractControl | string) { | |
150 | // 'isValid' would be false for disabled controls | |
151 | expect(this.getControl(control).errors).toBe(null); | |
152 | } | |
153 | ||
154 | /** | |
155 | * Change the value of the control and expect a specific error. | |
156 | */ | |
157 | expectErrorChange( | |
158 | control: AbstractControl | string, | |
159 | value: any, | |
160 | error: string, | |
161 | markAsDirty?: boolean | |
162 | ) { | |
163 | this.expectError(this.setValue(control, value, markAsDirty), error); | |
164 | } | |
165 | ||
166 | /** | |
167 | * Expect a specific error for the given control. | |
168 | */ | |
169 | expectError(control: AbstractControl | string, error: string) { | |
170 | expect(this.getControl(control).hasError(error)).toBeTruthy(); | |
171 | } | |
172 | } | |
173 | ||
174 | export class FixtureHelper { | |
175 | fixture: ComponentFixture<any>; | |
176 | ||
177 | constructor(fixture: ComponentFixture<any>) { | |
178 | this.fixture = fixture; | |
179 | } | |
180 | ||
181 | /** | |
182 | * Expect a list of id elements to be visible or not. | |
183 | */ | |
184 | expectIdElementsVisible(ids: string[], visibility: boolean) { | |
185 | ids.forEach((css) => { | |
186 | this.expectElementVisible(`#${css}`, visibility); | |
187 | }); | |
188 | } | |
189 | ||
190 | /** | |
191 | * Expect a specific element to be visible or not. | |
192 | */ | |
193 | expectElementVisible(css: string, visibility: boolean) { | |
194 | expect(Boolean(this.getElementByCss(css))).toBe(visibility); | |
195 | } | |
196 | ||
197 | expectFormFieldToBe(css: string, value: string) { | |
198 | const props = this.getElementByCss(css).properties; | |
199 | expect(props['value'] || props['checked'].toString()).toBe(value); | |
200 | } | |
201 | ||
202 | clickElement(css: string) { | |
203 | this.getElementByCss(css).triggerEventHandler('click', null); | |
204 | this.fixture.detectChanges(); | |
205 | } | |
206 | ||
207 | getText(css: string) { | |
208 | const e = this.getElementByCss(css); | |
209 | return e ? e.nativeElement.textContent.trim() : null; | |
210 | } | |
211 | ||
212 | getElementByCss(css: string) { | |
213 | this.fixture.detectChanges(); | |
214 | return this.fixture.debugElement.query(By.css(css)); | |
215 | } | |
216 | } | |
217 | ||
218 | export class PrometheusHelper { | |
219 | createAlert(name, state = 'active', timeMultiplier = 1) { | |
220 | return { | |
221 | fingerprint: name, | |
222 | status: { state }, | |
223 | labels: { | |
224 | alertname: name | |
225 | }, | |
226 | annotations: { | |
227 | summary: `${name} is ${state}` | |
228 | }, | |
229 | generatorURL: `http://${name}`, | |
230 | startsAt: new Date(new Date('2022-02-22').getTime() * timeMultiplier).toString() | |
231 | } as PrometheusAlert; | |
232 | } | |
233 | ||
234 | createNotificationAlert(name, status = 'firing') { | |
235 | return { | |
236 | status: status, | |
237 | labels: { | |
238 | alertname: name | |
239 | }, | |
240 | annotations: { | |
241 | summary: `${name} is ${status}` | |
242 | }, | |
243 | generatorURL: `http://${name}` | |
244 | } as PrometheusNotificationAlert; | |
245 | } | |
246 | ||
247 | createNotification(alertNumber = 1, status = 'firing') { | |
248 | const alerts = []; | |
249 | for (let i = 0; i < alertNumber; i++) { | |
250 | alerts.push(this.createNotificationAlert('alert' + i, status)); | |
251 | } | |
252 | return { alerts, status } as PrometheusNotification; | |
253 | } | |
254 | ||
255 | createLink(url) { | |
256 | return `<a href="${url}" target="_blank"><i class="fa fa-line-chart"></i></a>`; | |
257 | } | |
258 | } | |
259 | ||
260 | const XLIFF = `<?xml version="1.0" encoding="UTF-8" ?> | |
261 | <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> | |
262 | <file source-language="en" datatype="plaintext" original="ng2.template"> | |
263 | <body> | |
264 | </body> | |
265 | </file> | |
266 | </xliff> | |
267 | `; | |
268 | ||
269 | const i18nProviders = [ | |
270 | { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }, | |
271 | { provide: TRANSLATIONS, useValue: XLIFF }, | |
272 | { provide: LOCALE_ID, useValue: 'en' }, | |
273 | I18n | |
274 | ]; | |
275 | ||
276 | export { i18nProviders }; |