This is an automated email from the ASF dual-hosted git repository.
Yicong-Huang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 41a8197022 test(frontend): re-enable 4 user-workflow / dashboard /
list-item specs (#4944)
41a8197022 is described below
commit 41a8197022a16b98867a8495b2061d86d771b555
Author: Yicong Huang <[email protected]>
AuthorDate: Tue May 5 17:07:46 2026 -0700
test(frontend): re-enable 4 user-workflow / dashboard / list-item specs
(#4944)
### What changes were proposed in this PR?
Drop 4 entries from the spec exclusion lists in `tsconfig.spec.json` and
`angular.json`'s test target, port their TestBed setups to the
standalone-component shape, and fix one malformed template attribute
that jsdom won't tolerate.
**Specs re-enabled:**
- `dashboard.component.spec.ts` — extends `socialAuthServiceMock` with
`initState` (the Google sign-in directive subscribes to it in its
constructor) and adds an `AdminSettingsService` stub; switches to
`imports: [DashboardComponent]` so its standalone graph carries
`GoogleSigninButtonModule` instead of relying on `NO_ERRORS_SCHEMA`.
- `user-project-list-item.component.spec.ts` — wraps the component in a
`TestHostComponent` template `<nz-list><texera-user-project-list-item
.../></nz-list>` so the `<nz-list-item>`-rooted component finds an
`NzListComponent` provider; adds `provideRouter([])` for the embedded
`[routerLink]`.
- `user-workflow-list-item.component.spec.ts` — same `<nz-list>` host
wrapper.
- `user-workflow.component.spec.ts` — switches `declarations: [...]` to
`imports: [...]` for the now-standalone children; converts
`beforeEach(waitForAsync(...))` to `beforeEach(async () => ...)` so the
setup runs outside the per-`it` ProxyZone wrapper.
**Drive-by template fix:**
`user-workflow.component.html` had a stray `]="true"` line — left over
from #4873's `[nzBorderless]="true"` → `nzVariant="borderless"` rewrite.
Browsers silently tolerate the malformed attribute, but jsdom throws
`InvalidCharacterError: "]" did not match the Name production` during
`setAttribute`, which is why the spec couldn't run under Vitest.
After this PR, the exclude list contains only specs gated on Vitest
browser mode (#4866) or specs whose body is still a placeholder.
### Any related issues, documentation, discussions?
Part of #4880.
### How was this PR tested?
`yarn install && yarn ng test --watch=false` exits 0 locally; `yarn
format:ci` is clean. CI exercises the same test command on the ubuntu /
windows / macos frontend matrices.
```
Test Files 56 passed | 3 skipped (59)
Tests 248 passed | 8 skipped | 2 todo (258)
```
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 4.7 (1M context)
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
frontend/angular.json | 4 ---
.../component/dashboard.component.spec.ts | 20 +++++++----
.../user-project-list-item.component.spec.ts | 39 +++++++++++++++++-----
.../user-workflow-list-item.component.spec.ts | 39 +++++++++++++++++-----
.../user-workflow/user-workflow.component.html | 1 -
.../user-workflow/user-workflow.component.spec.ts | 20 +++++------
frontend/src/tsconfig.spec.json | 13 +-------
7 files changed, 85 insertions(+), 51 deletions(-)
diff --git a/frontend/angular.json b/frontend/angular.json
index 6e840bdb52..fabc6ba8ce 100644
--- a/frontend/angular.json
+++ b/frontend/angular.json
@@ -97,10 +97,6 @@
"**/drag-drop.service.spec.ts",
"**/app/common/formly/preset-wrapper/preset-wrapper.component.spec.ts",
"**/app/common/service/user/config/user-config.service.spec.ts",
- "**/app/dashboard/component/dashboard.component.spec.ts",
-
"**/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts",
-
"**/app/dashboard/component/user/user-workflow/user-workflow-list-item/user-workflow-list-item.component.spec.ts",
-
"**/app/dashboard/component/user/user-workflow/user-workflow.component.spec.ts",
"**/app/workspace/component/code-editor-dialog/code-debugger.component.spec.ts",
"**/app/workspace/component/code-editor-dialog/code-editor.component.spec.ts",
"**/app/workspace/component/codearea-custom-template/codearea-custom-template.component.spec.ts",
diff --git a/frontend/src/app/dashboard/component/dashboard.component.spec.ts
b/frontend/src/app/dashboard/component/dashboard.component.spec.ts
index d5b01934f6..ca6cf086b6 100644
--- a/frontend/src/app/dashboard/component/dashboard.component.spec.ts
+++ b/frontend/src/app/dashboard/component/dashboard.component.spec.ts
@@ -19,13 +19,14 @@
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { DashboardComponent } from "./dashboard.component";
-import { ChangeDetectorRef, EventEmitter, NgZone, NO_ERRORS_SCHEMA } from
"@angular/core";
+import { ChangeDetectorRef, EventEmitter, NgZone } from "@angular/core";
import { By } from "@angular/platform-browser";
-import { of } from "rxjs";
+import { EMPTY, of } from "rxjs";
import { UserService } from "../../common/service/user/user.service";
import { FlarumService } from "../service/user/flarum/flarum.service";
import { SocialAuthService } from "@abacritt/angularx-social-login";
+import { AdminSettingsService } from
"../service/admin/settings/admin-settings.service";
import {
ActivatedRoute,
ActivatedRouteSnapshot,
@@ -50,6 +51,7 @@ describe("DashboardComponent", () => {
let cdrMock: Partial<ChangeDetectorRef>;
let ngZoneMock: Partial<NgZone>;
let socialAuthServiceMock: Partial<SocialAuthService>;
+ let adminSettingsServiceMock: Partial<AdminSettingsService>;
let activatedRouteMock: Partial<ActivatedRoute>;
const activatedRouteSnapshotMock: Partial<ActivatedRouteSnapshot> = {
@@ -105,7 +107,14 @@ describe("DashboardComponent", () => {
};
socialAuthServiceMock = {
- authState: of(),
+ authState: EMPTY,
+ // GoogleSigninButtonDirective subscribes to initState in its
constructor;
+ // EMPTY keeps the subscription open without triggering
google.accounts.id.renderButton.
+ initState: EMPTY,
+ };
+
+ adminSettingsServiceMock = {
+ getSetting: vi.fn().mockReturnValue(EMPTY),
};
activatedRouteMock = {
@@ -113,8 +122,7 @@ describe("DashboardComponent", () => {
};
await TestBed.configureTestingModule({
- declarations: [DashboardComponent],
- imports: [HttpClientTestingModule],
+ imports: [DashboardComponent, HttpClientTestingModule],
providers: [
{ provide: UserService, useValue: userServiceMock },
{ provide: Router, useValue: routerMock },
@@ -122,10 +130,10 @@ describe("DashboardComponent", () => {
{ provide: ChangeDetectorRef, useValue: cdrMock },
{ provide: NgZone, useValue: ngZoneMock },
{ provide: SocialAuthService, useValue: socialAuthServiceMock },
+ { provide: AdminSettingsService, useValue: adminSettingsServiceMock },
{ provide: ActivatedRoute, useValue: activatedRouteMock },
...commonTestProviders,
],
- schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
});
diff --git
a/frontend/src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts
b/frontend/src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts
index 813e556497..1eec8b69b0 100644
---
a/frontend/src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts
+++
b/frontend/src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts
@@ -17,21 +17,42 @@
* under the License.
*/
+import { Component, ViewChild } from "@angular/core";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { UserProjectListItemComponent } from
"./user-project-list-item.component";
import { NotificationService } from
"src/app/common/service/notification/notification.service";
import { UserProjectService } from
"../../../../service/user/project/user-project.service";
import { DashboardProject } from
"../../../../type/dashboard-project.interface";
import { HttpClientTestingModule } from "@angular/common/http/testing";
+import { NzListComponent } from "ng-zorro-antd/list";
import { NzModalService } from "ng-zorro-antd/modal";
+import { provideRouter } from "@angular/router";
import { StubUserService } from
"../../../../../common/service/user/stub-user.service";
import { UserService } from "../../../../../common/service/user/user.service";
-import { HighlightSearchTermsPipe } from
"../../user-workflow/user-workflow-list-item/highlight-search-terms.pipe";
import { commonTestProviders } from "../../../../../common/testing/test-utils";
+// UserProjectListItemComponent is rooted at <nz-list-item>; instantiating it
+// outside an <nz-list> host throws "No provider found for NzListComponent".
+@Component({
+ standalone: true,
+ imports: [NzListComponent, UserProjectListItemComponent],
+ template: `
+ <nz-list>
+ <texera-user-project-list-item
+ [entry]="entry"
+ [editable]="editable"></texera-user-project-list-item>
+ </nz-list>
+ `,
+})
+class TestHostComponent {
+ entry!: DashboardProject;
+ editable = true;
+ @ViewChild(UserProjectListItemComponent, { static: true }) inner!:
UserProjectListItemComponent;
+}
+
describe("UserProjectListItemComponent", () => {
let component: UserProjectListItemComponent;
- let fixture: ComponentFixture<UserProjectListItemComponent>;
+ let hostFixture: ComponentFixture<TestHostComponent>;
const januaryFirst1970 = 28800000; // 1970-01-01 in PST
const testProject: DashboardProject = {
color: null,
@@ -45,24 +66,24 @@ describe("UserProjectListItemComponent", () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
- declarations: [UserProjectListItemComponent, HighlightSearchTermsPipe],
+ imports: [TestHostComponent, HttpClientTestingModule],
providers: [
NotificationService,
UserProjectService,
NzModalService,
{ provide: UserService, useClass: StubUserService },
+ provideRouter([]),
...commonTestProviders,
],
- imports: [HttpClientTestingModule],
}).compileComponents();
});
beforeEach(() => {
- fixture = TestBed.createComponent(UserProjectListItemComponent);
- component = fixture.componentInstance;
- component.entry = testProject;
- component.editable = true;
- fixture.detectChanges();
+ hostFixture = TestBed.createComponent(TestHostComponent);
+ hostFixture.componentInstance.entry = testProject;
+ hostFixture.componentInstance.editable = true;
+ hostFixture.detectChanges();
+ component = hostFixture.componentInstance.inner;
});
it("should create", () => {
diff --git
a/frontend/src/app/dashboard/component/user/user-workflow/user-workflow-list-item/user-workflow-list-item.component.spec.ts
b/frontend/src/app/dashboard/component/user/user-workflow/user-workflow-list-item/user-workflow-list-item.component.spec.ts
index afade00123..a73bffe9d0 100644
---
a/frontend/src/app/dashboard/component/user/user-workflow/user-workflow-list-item/user-workflow-list-item.component.spec.ts
+++
b/frontend/src/app/dashboard/component/user/user-workflow/user-workflow-list-item/user-workflow-list-item.component.spec.ts
@@ -17,6 +17,7 @@
* under the License.
*/
+import { Component, ViewChild } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from
"@angular/core/testing";
import { UserWorkflowListItemComponent } from
"./user-workflow-list-item.component";
import { FileSaverService } from
"../../../../service/user/file/file-saver.service";
@@ -26,34 +27,56 @@ import { StubWorkflowPersistService } from
"../../../../../common/service/workfl
import { WorkflowPersistService } from
"../../../../../common/service/workflow-persist/workflow-persist.service";
import { UserProjectService } from
"../../../../service/user/project/user-project.service";
import { StubUserProjectService } from
"../../../../service/user/project/stub-user-project.service";
+import { NzListComponent } from "ng-zorro-antd/list";
import { NzModalModule } from "ng-zorro-antd/modal";
import { HttpClientTestingModule } from "@angular/common/http/testing";
-import { HighlightSearchTermsPipe } from "./highlight-search-terms.pipe";
+import { provideRouter } from "@angular/router";
+import { DashboardEntry } from "../../../../type/dashboard-entry";
import { NzTooltipModule } from "ng-zorro-antd/tooltip";
import { commonTestProviders } from "../../../../../common/testing/test-utils";
+
+// UserWorkflowListItemComponent is rooted at <nz-list-item>; instantiating it
+// outside an <nz-list> host throws "No provider found for NzListComponent".
+@Component({
+ standalone: true,
+ imports: [NzListComponent, UserWorkflowListItemComponent],
+ template: `
+ <nz-list>
+ <texera-user-workflow-list-item
+ [entry]="entry"
+ [editable]="editable"></texera-user-workflow-list-item>
+ </nz-list>
+ `,
+})
+class TestHostComponent {
+ entry!: DashboardEntry;
+ editable = true;
+ @ViewChild(UserWorkflowListItemComponent, { static: true }) inner!:
UserWorkflowListItemComponent;
+}
+
describe("UserWorkflowListItemComponent", () => {
let component: UserWorkflowListItemComponent;
- let fixture: ComponentFixture<UserWorkflowListItemComponent>;
+ let fixture: ComponentFixture<TestHostComponent>;
const fileSaverServiceSpy = { saveAs: vi.fn() } as any;
beforeEach(async () => {
await TestBed.configureTestingModule({
- imports: [NzModalModule, HttpClientTestingModule, NzTooltipModule],
- declarations: [UserWorkflowListItemComponent, HighlightSearchTermsPipe],
+ imports: [TestHostComponent, NzModalModule, HttpClientTestingModule,
NzTooltipModule],
providers: [
{ provide: WorkflowPersistService, useValue: new
StubWorkflowPersistService(testWorkflowEntries) },
{ provide: UserProjectService, useValue: new StubUserProjectService()
},
{ provide: FileSaverService, useValue: fileSaverServiceSpy },
+ provideRouter([]),
...commonTestProviders,
],
}).compileComponents();
});
beforeEach(() => {
- fixture = TestBed.createComponent(UserWorkflowListItemComponent);
- component = fixture.componentInstance;
- component.entry = testWorkflowEntries[0];
- component.editable = true;
+ fixture = TestBed.createComponent(TestHostComponent);
+ fixture.componentInstance.entry = testWorkflowEntries[0];
+ fixture.componentInstance.editable = true;
fixture.detectChanges();
+ component = fixture.componentInstance.inner;
});
it("should create", () => {
diff --git
a/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.html
b/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.html
index 7f3d431ae9..1873658797 100644
---
a/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.html
+++
b/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.html
@@ -146,7 +146,6 @@
nzMode="tags"
nzPlaceHolder="Search all workflows"
nzVariant="borderless"
- ]="true"
[nzOpen]="false"
ngDefaultControl
[(ngModel)]="filters.masterFilterList"
diff --git
a/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.spec.ts
b/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.spec.ts
index 2e9b111101..4344b5e5a7 100644
---
a/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.spec.ts
+++
b/frontend/src/app/dashboard/component/user/user-workflow/user-workflow.component.spec.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { ComponentFixture, TestBed, waitForAsync } from
"@angular/core/testing";
+import { ComponentFixture, TestBed } from "@angular/core/testing";
import { RouterTestingModule } from "@angular/router/testing";
import { HttpClientTestingModule } from "@angular/common/http/testing";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
@@ -67,17 +67,10 @@ describe("SavedWorkflowSectionComponent", () => {
let downloadServiceSpy: any;
- beforeEach(waitForAsync(() => {
+ beforeEach(async () => {
downloadServiceSpy = { downloadWorkflowsAsZip: vi.fn() } as any;
- TestBed.configureTestingModule({
- declarations: [
- UserWorkflowComponent,
- ShareAccessComponent,
- FiltersComponent,
- UserWorkflowListItemComponent,
- SearchResultsComponent,
- ],
+ await TestBed.configureTestingModule({
providers: [
NzModalService,
{ provide: WorkflowPersistService, useValue: new
StubWorkflowPersistService(testWorkflowEntries) },
@@ -95,6 +88,11 @@ describe("SavedWorkflowSectionComponent", () => {
...commonTestProviders,
],
imports: [
+ UserWorkflowComponent,
+ ShareAccessComponent,
+ FiltersComponent,
+ UserWorkflowListItemComponent,
+ SearchResultsComponent,
FormsModule,
RouterTestingModule,
HttpClientTestingModule,
@@ -114,7 +112,7 @@ describe("SavedWorkflowSectionComponent", () => {
NzButtonModule,
],
}).compileComponents();
- }));
+ });
beforeEach(() => {
fixture = TestBed.createComponent(UserWorkflowComponent);
diff --git a/frontend/src/tsconfig.spec.json b/frontend/src/tsconfig.spec.json
index c0d4dddbb1..474fe72573 100644
--- a/frontend/src/tsconfig.spec.json
+++ b/frontend/src/tsconfig.spec.json
@@ -38,17 +38,6 @@
"**/app/workspace/component/left-panel/time-travel/time-travel.component.spec.ts",
"**/app/workspace/component/left-panel/versions-list/versions-list.component.spec.ts",
"**/app/workspace/component/property-editor/operator-property-edit-frame/operator-property-edit-frame.component.spec.ts",
-
"**/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts",
-
- // Component templates rooted at <nz-list-item>: outside an <nz-list>
- // host these throw `No provider found for NzListComponent`. Need a
- // wrapper TestHostComponent that mounts them inside <nz-list>.
-
"**/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts",
-
"**/app/dashboard/component/user/user-workflow/user-workflow-list-item/user-workflow-list-item.component.spec.ts",
- // user-workflow embeds the list-item above, cascading the same NzList
host issue.
-
"**/app/dashboard/component/user/user-workflow/user-workflow.component.spec.ts",
- // Dashboard renders <asl-google-signin-button> which dereferences fields
on the
- // SocialAuthService stub that our minimal mock doesn't provide.
- "**/app/dashboard/component/dashboard.component.spec.ts"
+
"**/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts"
]
}