From 7846f13ca9a6326739ca9026c65a8f1f94c078ef Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Wed, 8 Jul 2026 02:53:22 -0700 Subject: [PATCH 1/7] fix(workflow): include coverImage in search and list API responses --- .../dashboard/UnifiedResourceSchema.scala | 6 ++-- .../WorkflowSearchQueryBuilder.scala | 8 ++++-- .../user/workflow/WorkflowResource.scala | 24 ++++++++++------ .../dashboard/file/WorkflowResourceSpec.scala | 28 +++++++++++++++++++ .../card-item/card-item.component.ts | 11 ++------ .../src/app/dashboard/type/dashboard-entry.ts | 1 + .../type/dashboard-workflow.interface.ts | 1 + 7 files changed, 58 insertions(+), 21 deletions(-) diff --git a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala index fb6a8c928a4..ad93dda3b3c 100644 --- a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala +++ b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala @@ -76,7 +76,8 @@ object UnifiedResourceSchema { isDatasetPublic: Field[java.lang.Boolean] = DSL.cast(null, classOf[java.lang.Boolean]), isDatasetDownloadable: Field[java.lang.Boolean] = DSL.cast(null, classOf[java.lang.Boolean]), datasetUserAccess: Field[PrivilegeEnum] = DSL.castNull(classOf[PrivilegeEnum]), - datasetCoverImage: Field[String] = DSL.cast(null, classOf[String]) + datasetCoverImage: Field[String] = DSL.cast(null, classOf[String]), + workflowCoverImage: Field[String] = DSL.cast(null, classOf[String]), ): UnifiedResourceSchema = { new UnifiedResourceSchema( Seq( @@ -102,7 +103,8 @@ object UnifiedResourceSchema { isDatasetPublic -> isDatasetPublic.as("is_dataset_public"), isDatasetDownloadable -> isDatasetDownloadable.as("is_dataset_downloadable"), datasetUserAccess -> datasetUserAccess.as("user_dataset_access"), - datasetCoverImage -> datasetCoverImage.as("cover_image") + datasetCoverImage -> datasetCoverImage.as("cover_image"), + workflowCoverImage -> workflowCoverImage.as("workflow_cover_image") ) ) } diff --git a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/WorkflowSearchQueryBuilder.scala b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/WorkflowSearchQueryBuilder.scala index f39453f651b..9a08742c3e9 100644 --- a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/WorkflowSearchQueryBuilder.scala +++ b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/WorkflowSearchQueryBuilder.scala @@ -52,7 +52,8 @@ object WorkflowSearchQueryBuilder extends SearchQueryBuilder { uid = WORKFLOW_OF_USER.UID, ownerId = WORKFLOW_OF_USER.UID, userName = USER.NAME, - projectsOfWorkflow = groupConcatDistinct(WORKFLOW_OF_PROJECT.PID) + projectsOfWorkflow = groupConcatDistinct(WORKFLOW_OF_PROJECT.PID), + workflowCoverImage = DSL.max(WORKFLOW_COVER_IMAGE.IMAGE).as("workflow_cover_image") ) } @@ -72,6 +73,8 @@ object WorkflowSearchQueryBuilder extends SearchQueryBuilder { .on(WORKFLOW_OF_PROJECT.WID.eq(WORKFLOW.WID)) .leftJoin(PROJECT_USER_ACCESS) .on(PROJECT_USER_ACCESS.PID.eq(WORKFLOW_OF_PROJECT.PID)) + .leftJoin(WORKFLOW_COVER_IMAGE) + .on(WORKFLOW_COVER_IMAGE.WID.eq(WORKFLOW.WID)) var condition: Condition = DSL.trueCondition() if (uid == null) { @@ -162,7 +165,8 @@ object WorkflowSearchQueryBuilder extends SearchQueryBuilder { .map(number => Integer.valueOf(number)) .toList }, - record.into(USER).getUid + record.into(USER).getUid, + Option(record.get("workflow_cover_image", classOf[String])) ) DashboardClickableFileEntry(SearchQueryBuilder.WORKFLOW_RESOURCE_TYPE, workflow = Some(dw)) } diff --git a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala index 02cf836dc84..72d70d5cf74 100644 --- a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala +++ b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala @@ -41,8 +41,8 @@ import org.apache.texera.web.resource.dashboard.hub.EntityType import org.apache.texera.web.resource.dashboard.hub.HubResource.recordCloneAction import org.apache.texera.web.resource.dashboard.user.workflow.WorkflowAccessResource.hasReadAccess import org.apache.texera.web.resource.dashboard.user.workflow.WorkflowResource._ -import org.jooq.impl.DSL.{groupConcatDistinct, noCondition} -import org.jooq.{Condition, DSLContext, Record9, Result, SelectOnConditionStep} +import org.jooq.impl.DSL.{groupConcatDistinct, noCondition, max} +import org.jooq.{Condition, DSLContext, Record10, Result, SelectOnConditionStep} import java.sql.Timestamp import java.util @@ -125,7 +125,8 @@ object WorkflowResource { ownerName: String, workflow: Workflow, projectIDs: List[Integer], - ownerId: Integer + ownerId: Integer, + coverImage: Option[String] ) case class WorkflowWithPrivilege( @@ -191,7 +192,7 @@ object WorkflowResource { } } - def baseWorkflowSelect(): SelectOnConditionStep[Record9[ + def baseWorkflowSelect(): SelectOnConditionStep[Record10[ Integer, String, String, @@ -200,6 +201,7 @@ object WorkflowResource { PrivilegeEnum, Integer, String, + String, String ]] = { context @@ -212,7 +214,8 @@ object WorkflowResource { WORKFLOW_USER_ACCESS.PRIVILEGE, WORKFLOW_OF_USER.UID, USER.NAME, - groupConcatDistinct(WORKFLOW_OF_PROJECT.PID).as("projects") + groupConcatDistinct(WORKFLOW_OF_PROJECT.PID).as("projects"), + max(WORKFLOW_COVER_IMAGE.IMAGE).as("cover_image") ) .from(WORKFLOW) .leftJoin(WORKFLOW_USER_ACCESS) @@ -223,10 +226,12 @@ object WorkflowResource { .on(USER.UID.eq(WORKFLOW_OF_USER.UID)) .leftJoin(WORKFLOW_OF_PROJECT) .on(WORKFLOW.WID.eq(WORKFLOW_OF_PROJECT.WID)) + .leftJoin(WORKFLOW_COVER_IMAGE) + .on(WORKFLOW.WID.eq(WORKFLOW_COVER_IMAGE.WID)) } def mapWorkflowEntries( - workflowEntries: Result[Record9[ + workflowEntries: Result[Record10[ Integer, String, String, @@ -235,6 +240,7 @@ object WorkflowResource { PrivilegeEnum, Integer, String, + String, String ]], uid: Integer @@ -255,7 +261,8 @@ object WorkflowResource { if (workflowRecord.component9() == null) List[Integer]() else workflowRecord.component9().split(',').map(str => Integer.valueOf(str)).toList, - workflowRecord.into(WORKFLOW_OF_USER).getUid + workflowRecord.into(WORKFLOW_OF_USER).getUid, + Option(workflowRecord.get("cover_image", classOf[String])) ) ) .asScala @@ -584,7 +591,8 @@ class WorkflowResource extends LazyLogging { user.getName, workflowDao.fetchOneByWid(workflow.getWid), List[Integer](), - user.getUid + user.getUid, + None ) } diff --git a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala index 385ad6bcf24..8fab9def569 100644 --- a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala +++ b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala @@ -26,6 +26,7 @@ import org.apache.texera.dao.jooq.generated.enums.UserRoleEnum import org.apache.texera.dao.jooq.generated.tables.daos.UserDao import org.apache.texera.dao.jooq.generated.tables.pojos.{Project, User, Workflow} import org.apache.texera.web.resource.dashboard.DashboardResource.SearchQueryParams +import org.apache.texera.web.resource.dashboard.user.workflow.WorkflowResource.CoverImageRequest import org.apache.texera.web.resource.dashboard.user.project.ProjectResource import org.apache.texera.web.resource.dashboard.user.workflow.WorkflowResource import org.apache.texera.web.resource.dashboard.user.workflow.WorkflowResource.{ @@ -806,4 +807,31 @@ class WorkflowResourceSpec assert(resources.results.length == 3) } + it should "include workflow cover image in search results" in { + // Create workflow + workflowResource.persistWorkflow(testWorkflow1, sessionUser1) + + // Set cover image + val workflowId = + workflowResource.retrieveWorkflowsBySessionUser(sessionUser1).head.workflow.getWid + + val coverImage = "data:image/jpeg;base64,/9j/4AAQSkZJRg==" + workflowResource.setCoverImage( + workflowId, CoverImageRequest(coverImage), sessionUser1 + ) + + // Search workflows + val results = + dashboardResource.searchAllResourcesCall( + sessionUser1, + SearchQueryParams(resourceType = "workflow") + ) + + // Verify cover image is included in response + assert(results.results.length == 1) + + val workflowEntry = results.results.head.workflow.get + assert(workflowEntry.coverImage.contains(coverImage)) + } + } diff --git a/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts b/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts index 223bb5191e4..d83046b4911 100644 --- a/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts +++ b/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts @@ -194,7 +194,6 @@ export class CardItemComponent implements OnChanges { } initializeEntry() { - this.coverImageSrc = CardItemComponent.DEFAULT_PREVIEW_IMAGE; if (this.entry.type === "workflow") { if (typeof this.entry.id === "number") { this.disableDelete = !this.entry.workflow.isOwner; @@ -205,14 +204,8 @@ export class CardItemComponent implements OnChanges { this.entryLink = [HUB_WORKFLOW_RESULT_DETAIL, String(this.entry.id)]; } this.size = this.entry.size; - this.workflowCoverService - .getCover(this.entry.id) - .pipe(untilDestroyed(this)) - .subscribe(image => { - this.customImage = image; - this.coverImageSrc = image ?? CardItemComponent.DEFAULT_PREVIEW_IMAGE; - this.cdr.markForCheck(); - }); + this.coverImageSrc = this.entry.coverImageUrl ?? CardItemComponent.DEFAULT_PREVIEW_IMAGE; + this.customImage = this.entry.coverImageUrl ?? undefined; } this.iconType = "project"; } else if (this.entry.type === "project") { diff --git a/frontend/src/app/dashboard/type/dashboard-entry.ts b/frontend/src/app/dashboard/type/dashboard-entry.ts index b2949b080df..71c9a1515f2 100644 --- a/frontend/src/app/dashboard/type/dashboard-entry.ts +++ b/frontend/src/app/dashboard/type/dashboard-entry.ts @@ -83,6 +83,7 @@ export class DashboardEntry { this.likeCount = 0; this.isLiked = false; this.accessibleUserIds = []; + this.coverImageUrl = value.coverImage ?? undefined; } else if (isDashboardProject(value)) { this.type = EntityType.Project; this.id = value.pid; diff --git a/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts b/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts index 1a2a340a0d6..353cf593db3 100644 --- a/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts +++ b/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts @@ -26,4 +26,5 @@ export interface DashboardWorkflow { projectIDs: number[]; accessLevel: string; ownerId: number; + coverImage: string | null } From 7cfb00605e5aa7f1d8f14bc3a1cbacdef6b0290e Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Wed, 8 Jul 2026 18:53:55 -0700 Subject: [PATCH 2/7] fix(frontend): reset cover image state and add missing semicolon --- .../component/user/list-item/card-item/card-item.component.ts | 2 ++ frontend/src/app/dashboard/type/dashboard-workflow.interface.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts b/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts index d83046b4911..7048daec4c7 100644 --- a/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts +++ b/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts @@ -194,6 +194,8 @@ export class CardItemComponent implements OnChanges { } initializeEntry() { + this.coverImageSrc = CardItemComponent.DEFAULT_PREVIEW_IMAGE; + this.customImage = undefined; if (this.entry.type === "workflow") { if (typeof this.entry.id === "number") { this.disableDelete = !this.entry.workflow.isOwner; diff --git a/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts b/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts index 353cf593db3..e984f29ac62 100644 --- a/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts +++ b/frontend/src/app/dashboard/type/dashboard-workflow.interface.ts @@ -26,5 +26,5 @@ export interface DashboardWorkflow { projectIDs: number[]; accessLevel: string; ownerId: number; - coverImage: string | null + coverImage: string | null; } From aaecfc9e9c4388edfb5e8b6ef6a9bcdd922beae6 Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Fri, 10 Jul 2026 03:31:07 -0700 Subject: [PATCH 3/7] fix(frontend): update cover image handling tests --- .../dashboard/UnifiedResourceSchema.scala | 2 +- .../component/user-dashboard-test-fixtures.ts | 8 ++++++++ .../card-item/card-item.component.spec.ts | 15 +++++++++------ .../dashboard/service/user/search.service.spec.ts | 1 + 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala index ad93dda3b3c..aa3681ae1fb 100644 --- a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala +++ b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala @@ -77,7 +77,7 @@ object UnifiedResourceSchema { isDatasetDownloadable: Field[java.lang.Boolean] = DSL.cast(null, classOf[java.lang.Boolean]), datasetUserAccess: Field[PrivilegeEnum] = DSL.castNull(classOf[PrivilegeEnum]), datasetCoverImage: Field[String] = DSL.cast(null, classOf[String]), - workflowCoverImage: Field[String] = DSL.cast(null, classOf[String]), + workflowCoverImage: Field[String] = DSL.cast(null, classOf[String]) ): UnifiedResourceSchema = { new UnifiedResourceSchema( Seq( diff --git a/frontend/src/app/dashboard/component/user-dashboard-test-fixtures.ts b/frontend/src/app/dashboard/component/user-dashboard-test-fixtures.ts index 09a158e336f..d5ae29674f3 100644 --- a/frontend/src/app/dashboard/component/user-dashboard-test-fixtures.ts +++ b/frontend/src/app/dashboard/component/user-dashboard-test-fixtures.ts @@ -138,6 +138,7 @@ export const testWorkflowFileNameConflictEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [1], ownerId: 1, + coverImage: null, }), new DashboardEntry({ workflow: testDownloadWorkflow2, @@ -146,6 +147,7 @@ export const testWorkflowFileNameConflictEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [1, 2], ownerId: 1, + coverImage: null, }), new DashboardEntry({ workflow: testDownloadWorkflow3, @@ -154,6 +156,7 @@ export const testWorkflowFileNameConflictEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [1], ownerId: 2, + coverImage: null, }), ]; @@ -165,6 +168,7 @@ export const testWorkflowEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [1], ownerId: 1, + coverImage: null, }), new DashboardEntry({ workflow: testWorkflow2, @@ -173,6 +177,7 @@ export const testWorkflowEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [1, 2], ownerId: 1, + coverImage: null, }), new DashboardEntry({ workflow: testWorkflow3, @@ -181,6 +186,7 @@ export const testWorkflowEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [1], ownerId: 2, + coverImage: null, }), new DashboardEntry({ workflow: testWorkflow4, @@ -189,6 +195,7 @@ export const testWorkflowEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [3], ownerId: 2, + coverImage: null, }), new DashboardEntry({ workflow: testWorkflow5, @@ -197,6 +204,7 @@ export const testWorkflowEntries: DashboardEntry[] = [ accessLevel: "Write", projectIDs: [3], ownerId: 3, + coverImage: null, }), ]; diff --git a/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts b/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts index fbb55114eea..ff174e93bc4 100644 --- a/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts +++ b/frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts @@ -202,24 +202,27 @@ describe("CardItemComponent", () => { expect(component.canEditCover).toBe(false); }); - it("should load the stored cover on initialization and use it as the preview image", () => { + it("should use the stored cover image on initialization", () => { const cover = "data:image/jpeg;base64,abc"; - workflowCoverService.getCover.mockReturnValue(of(cover)); - component.entry = makeWorkflowEntry({ id: 7 }); + const entry = makeWorkflowEntry({ id: 7 }); + entry.coverImageUrl = cover; + component.entry = entry; component.ngOnChanges({ entry: { currentValue: component.entry } as any }); - expect(workflowCoverService.getCover).toHaveBeenCalledWith(7); + expect(workflowCoverService.getCover).not.toHaveBeenCalled(); expect(component.hasCustomImage).toBe(true); expect(component.coverImageSrc).toBe(cover); }); it("should fall back to the default preview image when no cover is set", () => { - workflowCoverService.getCover.mockReturnValue(of(undefined)); - component.entry = makeWorkflowEntry({ id: 7 }); + const entry = makeWorkflowEntry({ id: 7 }); + entry.coverImageUrl = undefined; + component.entry = entry; component.ngOnChanges({ entry: { currentValue: component.entry } as any }); + expect(workflowCoverService.getCover).not.toHaveBeenCalled(); expect(component.hasCustomImage).toBe(false); expect(component.coverImageSrc).toBe(CardItemComponent.DEFAULT_PREVIEW_IMAGE); }); diff --git a/frontend/src/app/dashboard/service/user/search.service.spec.ts b/frontend/src/app/dashboard/service/user/search.service.spec.ts index c80df0441bd..994169a1ee4 100644 --- a/frontend/src/app/dashboard/service/user/search.service.spec.ts +++ b/frontend/src/app/dashboard/service/user/search.service.spec.ts @@ -71,6 +71,7 @@ function makeWorkflowItem(wid: number, ownerId: number): SearchResultItem { projectIDs: [], accessLevel: "WRITE", ownerId, + coverImage: null, }; return { resourceType: "workflow", workflow }; } From a6436c2590026e9068881994d7b0e4e73e296e17 Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Fri, 10 Jul 2026 04:09:38 -0700 Subject: [PATCH 4/7] Format Scala files --- .../web/resource/dashboard/file/WorkflowResourceSpec.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala index 8fab9def569..4c95831de80 100644 --- a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala +++ b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala @@ -817,7 +817,9 @@ class WorkflowResourceSpec val coverImage = "data:image/jpeg;base64,/9j/4AAQSkZJRg==" workflowResource.setCoverImage( - workflowId, CoverImageRequest(coverImage), sessionUser1 + workflowId, + CoverImageRequest(coverImage), + sessionUser1 ) // Search workflows From c64e9456e6715681a6e8f904b0c2fc536ad4139a Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Fri, 10 Jul 2026 19:22:02 -0700 Subject: [PATCH 5/7] test: add coverage for workflow search without cover image --- .../dashboard/file/WorkflowResourceSpec.scala | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala index 4c95831de80..83266a20d08 100644 --- a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala +++ b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala @@ -836,4 +836,22 @@ class WorkflowResourceSpec assert(workflowEntry.coverImage.contains(coverImage)) } + it should "return no workflow cover image when None is set" in { + // Create workflow + workflowResource.persistWorkflow(testWorkflow1, sessionUser1) + + // Search workflows with no cover + val results = + dashboardResource.searchAllResourcesCall( + sessionUser1, + SearchQueryParams(resourceType = "workflow") + ) + + // Verify cover image is returned without a cover image + assert(results.results.length == 1) + + val workflowEntry = results.results.head.workflow.get + assert(workflowEntry.coverImage.isEmpty) + } + } From 26ed153603c3d225444eb37c027f2ef4eab79f86 Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Fri, 10 Jul 2026 21:15:31 -0700 Subject: [PATCH 6/7] test: add coverage for workflow creation without cover image --- .../dashboard/file/WorkflowResourceSpec.scala | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala index 83266a20d08..714f0720e5d 100644 --- a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala +++ b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala @@ -836,22 +836,11 @@ class WorkflowResourceSpec assert(workflowEntry.coverImage.contains(coverImage)) } - it should "return no workflow cover image when None is set" in { - // Create workflow - workflowResource.persistWorkflow(testWorkflow1, sessionUser1) + it should "create a workflow with coverImage set to None" in { + val result = workflowResource.createWorkflow(testWorkflow1, sessionUser1) - // Search workflows with no cover - val results = - dashboardResource.searchAllResourcesCall( - sessionUser1, - SearchQueryParams(resourceType = "workflow") - ) - - // Verify cover image is returned without a cover image - assert(results.results.length == 1) - - val workflowEntry = results.results.head.workflow.get - assert(workflowEntry.coverImage.isEmpty) + assert(result.workflow.getName == "test_workflow1") + assert(result.coverImage.isEmpty) } } From 52c9e5a65cbf7590e8c13eff1c9bcb61b590c682 Mon Sep 17 00:00:00 2001 From: Martin Vu <22mvu7@gmail.com> Date: Fri, 10 Jul 2026 23:49:22 -0700 Subject: [PATCH 7/7] test: add coverage for workflow creation without cover image --- .../resource/dashboard/file/WorkflowResourceSpec.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala index 714f0720e5d..7e6f9572d33 100644 --- a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala +++ b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala @@ -837,9 +837,13 @@ class WorkflowResourceSpec } it should "create a workflow with coverImage set to None" in { - val result = workflowResource.createWorkflow(testWorkflow1, sessionUser1) + val workflow = new Workflow() + workflow.setName("test_create_workflow") + workflow.setContent(exampleContent) + + val result = workflowResource.createWorkflow(workflow, sessionUser1) - assert(result.workflow.getName == "test_workflow1") + assert(result.workflow.getName == "test_create_workflow") assert(result.coverImage.isEmpty) }