Fix JS object duplicate name issue (#18198)

This commit is contained in:
subratadeypappu 2022-11-19 09:49:36 +06:00 committed by GitHub
parent 847c3ec11c
commit 4e20b4c496
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 0 deletions

View File

@ -9,6 +9,7 @@ import com.appsmith.external.helpers.MustacheHelper;
import com.appsmith.external.models.ActionDTO;
import com.appsmith.external.models.Datasource;
import com.appsmith.external.models.DefaultResources;
import com.appsmith.external.models.PluginType;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.ActionDependencyEdge;
import com.appsmith.server.domains.Layout;
@ -405,6 +406,23 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
Mono<Set<String>> actionNamesInPageMono = newActionService
.getUnpublishedActions(params)
.flatMap(
actionDTO -> {
/*
This is unexpected. Every action inside a JS collection should have a collectionId.
But there are a few documents found for plugin type JS inside newAction collection that don't have any collectionId.
The reason could be due to the lack of transactional behaviour when multiple inserts/updates that take place
during JS action creation. A detailed RCA is documented here
https://www.notion.so/appsmith/RCA-JSObject-name-already-exists-Please-use-a-different-name-e09c407f0ddb4653bd3974f3703408e6
*/
if (actionDTO.getPluginType().equals(PluginType.JS) && !StringUtils.hasLength(actionDTO.getCollectionId())) {
log.debug("JS Action with Id: {} doesn't have any collection Id under pageId: {}", actionDTO.getId(), pageId);
return Mono.empty();
} else {
return Mono.just(actionDTO);
}
}
)
.map(ActionDTO::getValidName)
.collect(toSet());

View File

@ -1147,4 +1147,36 @@ public class LayoutActionServiceTest {
}
@Test
@WithUserDetails(value = "api_user")
public void jsActionWithoutCollectionIdShouldBeIgnoredDuringNameChecking() {
ActionDTO firstAction = new ActionDTO();
firstAction.setPluginType(PluginType.JS);
firstAction.setName("foo");
firstAction.setFullyQualifiedName("testCollection.foo");
firstAction.setCollectionId("collectionId");
ActionDTO secondAction = new ActionDTO();
secondAction.setPluginType(PluginType.JS);
secondAction.setName("bar");
secondAction.setFullyQualifiedName("testCollection.bar");
secondAction.setCollectionId(null);
Mockito.doReturn(Flux.just(firstAction, secondAction)).when(newActionService).getUnpublishedActions(Mockito.any());
ActionCollectionDTO mockActionCollectionDTO = new ActionCollectionDTO();
mockActionCollectionDTO.setName("testCollection");
mockActionCollectionDTO.setActions(List.of(firstAction, secondAction));
Mockito.when(actionCollectionService.getActionCollectionsByViewMode(Mockito.any(), Mockito.anyBoolean()))
.thenReturn(Flux.just(mockActionCollectionDTO));
Mono<Boolean> nameAllowedMono = layoutActionService.isNameAllowed(testPage.getId(), testPage.getLayouts().get(0).getId(), "testCollection.bar");
StepVerifier.create(nameAllowedMono)
.assertNext(Assertions::assertTrue)
.verifyComplete();
}
}