• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 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 */
16import {Component} from '@angular/core';
17import {ComponentFixture, TestBed} from '@angular/core/testing';
18import {MatButtonModule} from '@angular/material/button';
19import {MatDividerModule} from '@angular/material/divider';
20import {MatIconModule} from '@angular/material/icon';
21import {MatTooltipModule} from '@angular/material/tooltip';
22import {assertDefined} from 'common/assert_utils';
23import {TreeNodeUtils} from 'test/unit/tree_node_utils';
24import {ImeAdditionalProperties} from 'viewers/common/ime_additional_properties';
25import {ViewerEvents} from 'viewers/common/viewer_events';
26import {CollapsibleSectionTitleComponent} from './collapsible_section_title_component';
27import {CoordinatesTableComponent} from './coordinates_table_component';
28import {ImeAdditionalPropertiesComponent} from './ime_additional_properties_component';
29
30describe('ImeAdditionalPropertiesComponent', () => {
31  let fixture: ComponentFixture<TestHostComponent>;
32  let component: TestHostComponent;
33  let htmlElement: HTMLElement;
34
35  beforeEach(async () => {
36    await TestBed.configureTestingModule({
37      imports: [
38        MatDividerModule,
39        MatIconModule,
40        MatButtonModule,
41        MatTooltipModule,
42      ],
43      declarations: [
44        ImeAdditionalPropertiesComponent,
45        TestHostComponent,
46        CollapsibleSectionTitleComponent,
47        CoordinatesTableComponent,
48      ],
49    }).compileComponents();
50    fixture = TestBed.createComponent(TestHostComponent);
51    component = fixture.componentInstance;
52    htmlElement = fixture.nativeElement;
53    htmlElement.addEventListener(
54      ViewerEvents.HighlightedNodeChange,
55      component.onHighlightedNodeChange,
56    );
57    htmlElement.addEventListener(
58      ViewerEvents.HighlightedIdChange,
59      component.onHighlightedIdChange,
60    );
61    htmlElement.addEventListener(
62      ViewerEvents.AdditionalPropertySelected,
63      component.onAdditionalPropertySelectedChange,
64    );
65    fixture.detectChanges();
66  });
67
68  it('can be created', () => {
69    expect(component).toBeTruthy();
70  });
71
72  it('shows client or service sf properties', () => {
73    expect(htmlElement.querySelector('.ime-container')).toBeDefined();
74    expect(htmlElement.querySelector('.input-method-surface')).toBeDefined();
75  });
76
77  it('renders placeholder text', () => {
78    component.additionalProperties = undefined;
79    fixture.detectChanges();
80    expect(
81      htmlElement.querySelector('.placeholder-text')?.textContent,
82    ).toContain('No IME entry found.');
83  });
84
85  it('emits update additional property tree event on wm state button click', () => {
86    const button = assertDefined(
87      htmlElement.querySelector('.wm-state-button'),
88    ) as HTMLButtonElement;
89    expect(button.className).not.toContain('selected');
90    button.click();
91    fixture.detectChanges();
92    expect(component.additionalPropertieTreeName).toEqual(
93      'Window Manager State',
94    );
95    expect(button.className).toContain('selected');
96  });
97
98  it('propagates new ime container layer on button click', () => {
99    const button = assertDefined(
100      htmlElement.querySelector('.ime-container-button'),
101    ) as HTMLButtonElement;
102    expect(button.className).not.toContain('selected');
103    button.click();
104    fixture.detectChanges();
105    expect(component.highlightedItem).toEqual('123');
106    expect(button.className).toContain('selected');
107  });
108
109  it('propagates new input method surface layer on button click', () => {
110    const button = assertDefined(
111      htmlElement.querySelector('.input-method-surface-button'),
112    ) as HTMLButtonElement;
113    expect(button.className).not.toContain('selected');
114    button.click();
115    fixture.detectChanges();
116    expect(component.highlightedItem).toEqual('456');
117    expect(button.className).toContain('selected');
118  });
119
120  it('shows ime manager service wm properties', () => {
121    component.isImeManagerService = true;
122    fixture.detectChanges();
123    const imeManagerService = assertDefined(
124      htmlElement.querySelector('.ime-manager-service'),
125    );
126    expect(
127      assertDefined(imeManagerService.querySelector('.wm-state')).textContent,
128    ).toContain('1970-01-01, 00:00:00.000000000');
129    expect(
130      imeManagerService.querySelector('.ime-control-target-button'),
131    ).toBeDefined();
132  });
133
134  it('propagates new property tree node window on button click', () => {
135    component.isImeManagerService = true;
136    fixture.detectChanges();
137    const button = assertDefined(
138      htmlElement.querySelector('.ime-control-target-button'),
139    ) as HTMLButtonElement;
140    expect(button.className).not.toContain('selected');
141    button.click();
142    fixture.detectChanges();
143    expect(component.additionalPropertieTreeName).toEqual('Ime Control Target');
144    expect(button.className).toContain('selected');
145  });
146
147  it('handles collapse button click', () => {
148    expect(component.collapseButtonClicked).toBeFalse();
149    const collapseButton = assertDefined(
150      htmlElement.querySelector('collapsible-section-title button'),
151    ) as HTMLButtonElement;
152    collapseButton.click();
153    fixture.detectChanges();
154    expect(component.collapseButtonClicked).toBeTrue();
155  });
156
157  @Component({
158    selector: 'host-component',
159    template: `
160      <ime-additional-properties
161        [highlightedItem]="highlightedItem"
162        [isImeManagerService]="isImeManagerService"
163        [additionalProperties]="additionalProperties"
164        (collapseButtonClicked)="onCollapseButtonClick()"></ime-additional-properties>
165    `,
166  })
167  class TestHostComponent {
168    isImeManagerService = false;
169
170    additionalProperties: ImeAdditionalProperties | undefined =
171      new ImeAdditionalProperties(
172        {
173          id: 'wmStateId',
174          name: 'wmState',
175          wmStateProperties: {
176            timestamp: '1970-01-01, 00:00:00.000000000',
177            focusedApp: 'exampleFocusedApp',
178            focusedWindow: undefined,
179            focusedActivity: undefined,
180            isInputMethodWindowVisible: false,
181            imeControlTarget: TreeNodeUtils.makePropertyNode(
182              'DisplayContent.inputMethodControlTarget',
183              'inputMethodControlTarget',
184              null,
185            ),
186            imeInputTarget: undefined,
187            imeLayeringTarget: undefined,
188            imeInsetsSourceProvider: undefined,
189          },
190          hierarchyTree: TreeNodeUtils.makeHierarchyNode({
191            name: 'wmStateProto',
192          }),
193        },
194        {
195          id: 'ime',
196          name: 'imeLayers',
197          properties: {
198            imeContainer: {
199              id: '123',
200              zOrderRelativeOfId: -1,
201              z: 0,
202            },
203            inputMethodSurface: {
204              id: '456',
205              isVisible: false,
206            },
207            focusedWindowColor: undefined,
208            root: undefined,
209          },
210          taskLayerOfImeContainer: undefined,
211          taskLayerOfImeSnapshot: undefined,
212        },
213      );
214    highlightedItem = '';
215    additionalPropertieTreeName: string | undefined;
216    collapseButtonClicked = false;
217
218    onHighlightedNodeChange = (event: Event) => {
219      this.highlightedItem = (event as CustomEvent).detail.node.id;
220    };
221    onHighlightedIdChange = (event: Event) => {
222      this.highlightedItem = (event as CustomEvent).detail.id;
223    };
224    onAdditionalPropertySelectedChange = (event: Event) => {
225      this.highlightedItem = (
226        event as CustomEvent
227      ).detail.selectedItem.treeNode.id;
228      this.additionalPropertieTreeName = (
229        event as CustomEvent
230      ).detail.selectedItem.name;
231    };
232
233    onCollapseButtonClick() {
234      this.collapseButtonClicked = true;
235    }
236  }
237});
238