Within our project, we have implemented a feature where user roles can be assigned to various elements in the application. These roles determine whether certain elements should be disabled or not. However, due to additional conditions that may also disable some buttons, our component takes control and disables its child if needed. This design allows us to easily display tooltips when an element is disabled.
// app-role-element
<div matTooltip="{{ tooltipMessage | translate }}" [matTooltipDisabled]="!isDisabled">
<ng-content> </ng-content>
</div>
// .ts
export class AppRoleElement implements AfterConentInit {
@Input('roles') roles: string[];
@ContentChild('roleElement') roleElement: MatButton;
constructor(...){}
ngAfterContentInit(): void {
...
this.setDisabled();
}
setDisabled(): void {
if (this.roleElement) {
if (this.isDisabled) {
this.roleElement.disabled = true; // disable if no role
} else {
this.roleElement.disabled = this.disableCondition; // disable if other condition
}
}
}
}
// usage
<app-role-component
[role]="['required-role']"
[disableCondition]= "isRunning || isUnstable"
[id]="startButtonRoleElem"
>
<button mat-raised-button id="startBtnId" (click)="start()">Start</button>
</app-role-component>
While this approach works as intended, it poses challenges when it comes to unit testing. In the code snippet above, selecting the Start button by ID may bypass the role-element and trigger the remote service even when it shouldn't. Clicking on the button directly does not pass through the role element.
test('to prevent click on a start btn when form is invalid', () => {
spectator.component.runEnabled$ = of(false);
spectator.detectComponentChanges();
const checkExportFolderSpy = jest.spyOn(spectator.component, 'checkExportFolder');
spectator.inject(PreferencesService).validateCurrentExportPath.andReturn(of(VALIDATION_RESULT_OK));
spectator.detectChanges();
spectator.click('#startBtnId');
spectator.detectChanges();
expect(checkExportFolderSpy).not.toHaveBeenCalled();
expect(dispatchSpy).not.toHaveBeenCalled();
});
We are using JEST with Spectator and NgMocks for testing purposes, and I am looking for a way to effectively mock this component. Any suggestions on how to handle this scenario? Should the click event be passed to the child, or should the child be disabled in some way? Your insights and recommendations would be greatly appreciated.