1/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {ComponentFixture, TestBed} from '@angular/core/testing';
18import {MatButtonModule} from '@angular/material/button';
19import {MatIconModule} from '@angular/material/icon';
20import {assertDefined} from 'common/assert_utils';
21import {TraceType} from 'trace/trace_type';
22import {VISIBLE_CHIP} from 'viewers/common/chip';
23import {UserOptions} from 'viewers/common/user_options';
24import {UserOptionsComponent} from './user_options_component';
25
26describe('UserOptionsComponent', () => {
27  let fixture: ComponentFixture<UserOptionsComponent>;
28  let component: UserOptionsComponent;
29  let htmlElement: HTMLElement;
30  const testEventType = 'TestEventType';
31
32  beforeEach(async () => {
33    await TestBed.configureTestingModule({
34      imports: [MatButtonModule, MatIconModule],
35      declarations: [UserOptionsComponent],
36    }).compileComponents();
37    fixture = TestBed.createComponent(UserOptionsComponent);
38    component = fixture.componentInstance;
39    htmlElement = fixture.nativeElement;
40    component.userOptions = {
41      option1: {
42        name: 'option 1',
43        enabled: false,
44        isUnavailable: false,
45      },
46      optionWithChip: {
47        name: 'option with chip',
48        enabled: false,
49        isUnavailable: false,
50        chip: VISIBLE_CHIP,
51      },
52      optionWithIcon: {
53        name: 'option with icon',
54        enabled: false,
55        isUnavailable: false,
56        icon: 'visibility',
57      },
58    };
59    component.eventType = testEventType;
60    component.traceType = TraceType.SURFACE_FLINGER;
61    fixture.detectChanges();
62  });
63
64  it('can be created', () => {
65    expect(component).toBeTruthy();
66  });
67
68  it('displays options', () => {
69    const options = htmlElement.querySelectorAll('.user-option');
70    expect(options.length).toEqual(3);
71
72    expect(options.item(0).textContent).toContain('option 1');
73    expect(options.item(0).querySelector('.user-option-chip')).toBeNull();
74    expect(options.item(0).querySelector('.mat-icon')).toBeNull();
75
76    expect(options.item(1).textContent).toContain('option with chip');
77    expect(
78      options.item(1).querySelector('.user-option-chip')?.textContent,
79    ).toContain('V');
80    expect(options.item(1).querySelector('.mat-icon')).toBeNull();
81
82    expect(options.item(2).textContent).toContain('option with icon');
83    expect(options.item(2).querySelector('.user-option-chip')).toBeNull();
84    expect(options.item(2).querySelector('.mat-icon')?.textContent).toContain(
85      'visibility',
86    );
87  });
88
89  it('disables option if unavailable', () => {
90    let option = assertDefined(htmlElement.querySelector('.user-option'));
91    expect((option as HTMLButtonElement).disabled).toBeFalse();
92
93    component.userOptions['option1'].isUnavailable = true;
94    fixture.detectChanges();
95    option = assertDefined(htmlElement.querySelector('.user-option'));
96    expect((option as HTMLInputElement).disabled).toBeTrue();
97  });
98
99  it('emits event on user option change', () => {
100    let options: UserOptions | undefined;
101    htmlElement.addEventListener(testEventType, (event) => {
102      options = (event as CustomEvent).detail.userOptions;
103    });
104    const logSpy = spyOn(component, 'logCallback');
105    const option = assertDefined(
106      htmlElement.querySelector('.user-option'),
107    ) as HTMLInputElement;
108    option.click();
109    fixture.detectChanges();
110    expect(assertDefined(options)['option1'].enabled).toBeTrue();
111    expect(logSpy).toHaveBeenCalled();
112  });
113});
114