Skip to content

Commit e25344a

Browse files
committed
Add check 'skipBeforeDraftCancel' to processBeforeDraftCancel method, this method was possibly called on composition/association entities before
1 parent db8229d commit e25344a

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandler.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public DraftCancelAttachmentsHandler(
5858
@Before
5959
@HandlerOrder(HandlerOrder.LATE)
6060
void processBeforeDraftCancel(DraftCancelEventContext context) {
61-
if (isWhereEmpty(context)) {
61+
if (!skipBeforeDraftCancel(context)) {
6262
logger.debug(
6363
"Processing before {} event for entity {}", context.getEvent(), context.getTarget());
6464

@@ -98,8 +98,22 @@ private Validator buildDeleteContentValidator(
9898
};
9999
}
100100

101-
private boolean isWhereEmpty(DraftCancelEventContext context) {
102-
return context.getCqn().where().isEmpty();
101+
private boolean skipBeforeDraftCancel(DraftCancelEventContext context) {
102+
if (!context.getCqn().where().isEmpty()) {
103+
logger.debug(
104+
"Skipping draft cancel processing for entity {} because this is not a bulk operation (WHERE clause found in context).",
105+
context.getTarget().getQualifiedName());
106+
return true;
107+
}
108+
String entityName = context.getTarget().getName();
109+
if (entityName.contains(".")) {
110+
logger.debug(
111+
"Skipping draft cancel processing for entity {} because this is a composition/association entity (contains dots indicating nested path).",
112+
entityName);
113+
return true;
114+
}
115+
// Do not skip processing for other cases
116+
return false;
103117
}
104118

105119
private List<Attachments> readAttachments(

cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandlerTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.sap.cds.ql.Delete;
2222
import com.sap.cds.ql.cqn.CqnDelete;
2323
import com.sap.cds.reflect.CdsEntity;
24+
import com.sap.cds.reflect.CdsStructuredType;
2425
import com.sap.cds.services.draft.DraftCancelEventContext;
2526
import com.sap.cds.services.draft.Drafts;
2627
import com.sap.cds.services.runtime.CdsRuntime;
@@ -59,6 +60,8 @@ void setup() {
5960
dataArgumentCaptor = ArgumentCaptor.forClass(Attachments.class);
6061
}
6162

63+
// The next test checks that processBeforeDraftCancel is skipped
64+
// if a where condition is included in the context.
6265
@Test
6366
void whereConditionIncludedNothingHappens() {
6467
getEntityAndMockContext(RootTable_.CDS_NAME);
@@ -70,6 +73,28 @@ void whereConditionIncludedNothingHappens() {
7073
verifyNoInteractions(attachmentsReader, deleteContentAttachmentEvent);
7174
}
7275

76+
// The next test checks that processBeforeDraftCancel is skipped
77+
// if a the entity is a composition/association entity.
78+
@Test
79+
void entityNameContainsDotsNothingHappens() {
80+
CdsEntity entityWithDots = mock(CdsEntity.class);
81+
when(entityWithDots.getName()).thenReturn("Books.covers_drafts");
82+
when(entityWithDots.getQualifiedName()).thenReturn("AdminService.Books.covers_drafts");
83+
84+
DraftCancelEventContext context = mock(DraftCancelEventContext.class);
85+
when(context.getTarget()).thenReturn(entityWithDots);
86+
87+
CqnDelete mockDelete = mock(CqnDelete.class);
88+
when(context.getCqn()).thenReturn(mockDelete);
89+
when(mockDelete.where()).thenReturn(Optional.empty()); // No WHERE clause
90+
91+
cut.processBeforeDraftCancel(context);
92+
93+
// Assert - No interactions should happen because entity name contains dots
94+
verifyNoInteractions(attachmentsReader);
95+
verifyNoInteractions(deleteContentAttachmentEvent);
96+
}
97+
7398
@Test
7499
void nothingSelectedNothingToDo() {
75100
getEntityAndMockContext(RootTable_.CDS_NAME);

0 commit comments

Comments
 (0)