Skip to content

Commit

Permalink
MOBILE-4759 test: Fix rendering components on testing
Browse files Browse the repository at this point in the history
  • Loading branch information
crazyserver committed Feb 4, 2025
1 parent 40c185b commit bad6d19
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 57 deletions.
1 change: 1 addition & 0 deletions src/core/components/tests/iframe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('CoreIframeComponent', () => {
const { nativeElement } = await renderTemplate(
CoreIframeComponent,
'<core-iframe src="https://moodle.org/"></core-iframe>',
{ standalone: true },
);

// Assert.
Expand Down
5 changes: 4 additions & 1 deletion src/core/components/tests/user-avatar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ describe('CoreUserAvatarComponent', () => {

it('should render', async () => {
// Act.
const { nativeElement } = await renderComponent(CoreUserAvatarComponent);
const { nativeElement } = await renderComponent(
CoreUserAvatarComponent,
{ standalone: true },
);

// Assert.
expect(nativeElement.innerHTML.trim()).not.toHaveLength(0);
Expand Down
13 changes: 9 additions & 4 deletions src/core/directives/tests/format-text.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ describe('CoreFormatTextDirective', () => {
providers: [
{ provide: IonContent, useValue: null },
],
standalone: true,
};
});

Expand Down Expand Up @@ -79,6 +80,7 @@ describe('CoreFormatTextDirective', () => {
const { nativeElement } = await renderTemplate(
CoreFormatTextDirective,
'<core-format-text text="Lorem ipsum dolor"></core-format-text>',
{ standalone: true },
);

// Assert
Expand Down Expand Up @@ -116,13 +118,15 @@ describe('CoreFormatTextDirective', () => {
});

// Act
const { nativeElement } = await renderTemplate(CoreFormatTextDirective, `
<core-format-text
const { nativeElement } = await renderTemplate(
CoreFormatTextDirective,
`<core-format-text
text="Lorem ipsum dolor"
contextLevel="course"
[contextInstanceId]="42"
></core-format-text>
`);
></core-format-text>`,
{ standalone: true },
);

// Assert
const text = nativeElement.querySelector('core-format-text');
Expand Down Expand Up @@ -180,6 +184,7 @@ describe('CoreFormatTextDirective', () => {
CoreFormatTextDirective,
'core-format-text',
{ text: '<a href="https://anchor-url/">Link</a>' },
{ standalone: true },
);
const anchor = nativeElement.querySelector('a');

Expand Down
2 changes: 2 additions & 0 deletions src/core/directives/tests/link.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('CoreLinkDirective', () => {
const fixture = await renderTemplate(
CoreLinkDirective,
'<a href="https://moodle.org/" core-link [capture]="true">Link</a>',
{ standalone: true },
);

// Assert
Expand All @@ -42,6 +43,7 @@ describe('CoreLinkDirective', () => {
const { nativeElement } = await renderTemplate(
CoreLinkDirective,
'<a href="https://moodle.org/" core-link [capture]="true">Link</a>',
{ standalone: true },
);

const anchor = nativeElement.querySelector('a');
Expand Down
2 changes: 1 addition & 1 deletion src/core/directives/update-non-reactive-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Directive, ElementRef, OnDestroy, OnInit } from '@angular/core';
*
* This is necessary in order to update some attributes that are not reactive, for example aria-label.
*
* @see https://github.com/ionic-team/ionic-framework/issues/21534
* @see https://github.com/ionic-team/ionic-framework/issues/20127
*/
@Directive({
selector: 'ion-button',
Expand Down
4 changes: 2 additions & 2 deletions src/core/features/login/pages/credentials/credentials.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ <h1>{{ 'core.login.login' | translate }}</h1>
</ion-title>

<ion-buttons slot="end">
<ion-button fill="clear" (click)="openSettings()" [ariaLabel]="'core.settings.appsettings' | translate">
<ion-button fill="clear" (click)="openSettings()" [attr.aria-label]="'core.settings.appsettings' | translate">
<ion-icon slot="icon-only" name="fas-gear" aria-hidden="true" />
</ion-button>
<ion-button fill="clear" (click)="showHelp()" [ariaLabel]="'core.help' | translate">
<ion-button fill="clear" (click)="showHelp()" [attr.aria-label]="'core.help' | translate">
<ion-icon slot="icon-only" name="far-circle-question" aria-hidden="true" />
</ion-button>
</ion-buttons>
Expand Down
18 changes: 2 additions & 16 deletions src/core/features/login/tests/credentials.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { CoreSharedModule } from '@/core/shared.module';
import { findElement, mock, mockSingleton, renderPageComponent, requireElement } from '@/testing/utils';
import { CoreLoginError } from '@classes/errors/loginerror';
import CoreLoginCredentialsPage from '@features/login/pages/credentials/credentials';
Expand All @@ -22,9 +21,6 @@ import { Http } from '@singletons';
import { of } from 'rxjs';
import { CoreLoginHelper } from '../services/login-helper';
import { CoreConstants } from '@/core/constants';
import { CoreSiteLogoComponent } from '@components/site-logo/site-logo';
import { CoreLoginExceededAttemptsComponent } from '../components/exceeded-attempts/exceeded-attempts';
import { CoreLoginMethodsComponent } from '../components/login-methods/login-methods';

describe('Credentials page', () => {

Expand Down Expand Up @@ -86,12 +82,7 @@ describe('Credentials page', () => {
// Act.
const fixture = await renderPageComponent(CoreLoginCredentialsPage, {
routeParams: { siteUrl },
imports: [
CoreSharedModule,
CoreSiteLogoComponent,
CoreLoginExceededAttemptsComponent,
CoreLoginMethodsComponent,
],
standalone: true,
});

// Assert.
Expand Down Expand Up @@ -141,12 +132,7 @@ describe('Credentials page', () => {

const fixture = await renderPageComponent(CoreLoginCredentialsPage, {
routeParams: { siteUrl, siteCheck },
imports: [
CoreSharedModule,
CoreSiteLogoComponent,
CoreLoginExceededAttemptsComponent,
CoreLoginMethodsComponent,
],
standalone: true,
});

// Act.
Expand Down
1 change: 1 addition & 0 deletions src/testing/stubs/directives/core-external-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Directive, Input } from '@angular/core';

@Directive({
selector: '[core-external-content]',
standalone: true,
})
export class CoreExternalContentDirectiveStub { // eslint-disable-line @angular-eslint/directive-class-suffix

Expand Down
79 changes: 46 additions & 33 deletions src/testing/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,25 +86,40 @@ const DEFAULT_SERVICE_SINGLETON_MOCKS: [CoreSingletonProxy, unknown][] = [
* @returns A promise that resolves to the testing component fixture.
*/
async function renderAngularComponent<T>(component: Type<T>, config: RenderConfig): Promise<TestingComponentFixture<T>> {
config.declarations.push(component);

TestBed.configureTestingModule({
declarations: [
...getDefaultDeclarations(),
...config.declarations,
],
providers: [
...getDefaultProviders(config),
...config.providers,
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [
BrowserModule,
NoopAnimationsModule,
TranslateModule.forChild(),
...config.imports,
],
});
if (!config.standalone) {
config.declarations.push(component);

TestBed.configureTestingModule({
declarations: [
...config.declarations,
],
providers: [
...getDefaultProviders(config),
...config.providers,
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [
BrowserModule,
NoopAnimationsModule,
TranslateModule.forChild(),
CoreExternalContentDirectiveStub,
...config.imports,
],
});
} else {
TestBed.configureTestingModule({
providers: [
...getDefaultProviders(config),
...config.providers,
],
imports: [
component,
NoopAnimationsModule,
CoreExternalContentDirectiveStub,
...config.imports,
],
});
}

testBedInitialized = true;

Expand All @@ -128,7 +143,13 @@ async function renderAngularComponent<T>(component: Type<T>, config: RenderConfi
* @returns The wrapper component class.
*/
function createWrapperComponent<U>(template: string, componentClass: Type<U>): Type<WrapperComponent<U>> {
@Component({ template })
@Component({
template,
standalone: true,
imports: [
componentClass,
],
})
class HostComponent extends WrapperComponent<U> {

@ViewChild(componentClass) child!: U;
Expand All @@ -138,17 +159,6 @@ function createWrapperComponent<U>(template: string, componentClass: Type<U>): T
return HostComponent;
}

/**
* Gets the default declarations for testing.
*
* @returns An array of default declarations.
*/
function getDefaultDeclarations(): unknown[] {
return [
CoreExternalContentDirectiveStub,
];
}

/**
* Gets the default providers for testing.
*
Expand Down Expand Up @@ -217,6 +227,7 @@ export interface RenderConfig {
providers: unknown[];
imports: unknown[];
translations?: Record<string, string>;
standalone?: boolean;
}

export interface RenderPageConfig extends RenderConfig {
Expand Down Expand Up @@ -447,8 +458,10 @@ export async function renderTemplate<T>(
template: string,
config: Partial<RenderConfig> = {},
): Promise<WrapperComponentFixture<T>> {
config.declarations = config.declarations ?? [];
config.declarations.push(component);
if (!config.standalone) {
config.declarations = config.declarations ?? [];
config.declarations.push(component);
}

return renderAngularComponent(
createWrapperComponent(template, component),
Expand Down

0 comments on commit bad6d19

Please sign in to comment.