-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: test cases with real file-system operations (#33668)
## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!CAUTION] > If you modify the content in this section, you are likely to disrupt the CI result for your PR. <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No
- Loading branch information
1 parent
5cf5e31
commit 3a8854d
Showing
6 changed files
with
31,417 additions
and
374 deletions.
There are no files selected for viewing
381 changes: 381 additions & 0 deletions
381
...rc/test/java/com/appsmith/server/git/autocommit/ApplicationPageServiceAutoCommitTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,381 @@ | ||
package com.appsmith.server.git.autocommit; | ||
|
||
import com.appsmith.external.dtos.GitLogDTO; | ||
import com.appsmith.external.enums.FeatureFlagEnum; | ||
import com.appsmith.external.git.GitExecutor; | ||
import com.appsmith.external.helpers.AppsmithBeanUtils; | ||
import com.appsmith.server.acl.AclPermission; | ||
import com.appsmith.server.applications.base.ApplicationService; | ||
import com.appsmith.server.domains.Application; | ||
import com.appsmith.server.domains.ApplicationMode; | ||
import com.appsmith.server.domains.ApplicationPage; | ||
import com.appsmith.server.domains.GitArtifactMetadata; | ||
import com.appsmith.server.domains.GitAuth; | ||
import com.appsmith.server.domains.GitProfile; | ||
import com.appsmith.server.domains.Layout; | ||
import com.appsmith.server.domains.NewPage; | ||
import com.appsmith.server.dtos.ApplicationJson; | ||
import com.appsmith.server.dtos.PageDTO; | ||
import com.appsmith.server.helpers.DSLMigrationUtils; | ||
import com.appsmith.server.helpers.GitPrivateRepoHelper; | ||
import com.appsmith.server.helpers.ce.autocommit.AutoCommitEligibiltyHelper; | ||
import com.appsmith.server.migrations.JsonSchemaMigration; | ||
import com.appsmith.server.migrations.JsonSchemaVersions; | ||
import com.appsmith.server.newpages.base.NewPageService; | ||
import com.appsmith.server.services.ApplicationPageService; | ||
import com.appsmith.server.services.CommonGitService; | ||
import com.appsmith.server.services.FeatureFlagService; | ||
import com.appsmith.server.services.UserDataService; | ||
import com.appsmith.server.testhelpers.git.GitFileSystemTestHelper; | ||
import lombok.extern.slf4j.Slf4j; | ||
import net.minidev.json.JSONObject; | ||
import org.eclipse.jgit.api.errors.GitAPIException; | ||
import org.eclipse.jgit.lib.BranchTrackingStatus; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.Mockito; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.boot.test.mock.mockito.SpyBean; | ||
import org.springframework.test.context.junit.jupiter.SpringExtension; | ||
import reactor.core.publisher.Flux; | ||
import reactor.core.publisher.Mono; | ||
import reactor.test.StepVerifier; | ||
|
||
import java.io.IOException; | ||
import java.net.URISyntaxException; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.time.Duration; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
import static com.appsmith.server.solutions.ce.AutoCommitEventHandlerCEImpl.AUTO_COMMIT_MSG_FORMAT; | ||
import static java.lang.Boolean.FALSE; | ||
import static java.lang.Boolean.TRUE; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.ArgumentMatchers.anyBoolean; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.Mockito.doReturn; | ||
|
||
@ExtendWith(SpringExtension.class) | ||
@SpringBootTest | ||
@Slf4j | ||
public class ApplicationPageServiceAutoCommitTest { | ||
|
||
@SpyBean | ||
ApplicationPageService applicationPageService; | ||
|
||
@Autowired | ||
GitFileSystemTestHelper gitFileSystemTestHelper; | ||
|
||
@SpyBean | ||
GitExecutor gitExecutor; | ||
|
||
@MockBean | ||
FeatureFlagService featureFlagService; | ||
|
||
@MockBean | ||
DSLMigrationUtils dslMigrationUtils; | ||
|
||
@MockBean | ||
ApplicationService applicationService; | ||
|
||
@MockBean | ||
NewPageService newPageService; | ||
|
||
@MockBean | ||
CommonGitService commonGitService; | ||
|
||
@MockBean | ||
GitPrivateRepoHelper gitPrivateRepoHelper; | ||
|
||
@SpyBean | ||
AutoCommitEligibiltyHelper autoCommitEligibiltyHelper; | ||
|
||
@MockBean | ||
BranchTrackingStatus branchTrackingStatus; | ||
|
||
@MockBean | ||
UserDataService userDataService; | ||
|
||
@SpyBean | ||
JsonSchemaMigration jsonSchemaMigration; | ||
|
||
Application testApplication; | ||
|
||
Path baseRepoSuffix; | ||
|
||
private static final Integer DSL_VERSION_NUMBER = 88; | ||
private static final String WORKSPACE_ID = "test-workspace"; | ||
private static final String REPO_NAME = "test-repo"; | ||
private static final String BRANCH_NAME = "develop"; | ||
private static final String APP_JSON_NAME = "autocommit.json"; | ||
private static final String APP_NAME = "autocommit"; | ||
private static final Integer WAIT_DURATION_FOR_ASYNC_EVENT = 5; | ||
|
||
private static final String DEFAULT_APP_ID = "default-app-id", DEFAULT_BRANCH_NAME = "master"; | ||
|
||
private Application createApplication() { | ||
Application application = new Application(); | ||
application.setName(APP_NAME); | ||
application.setWorkspaceId(WORKSPACE_ID); | ||
application.setId(DEFAULT_APP_ID); | ||
|
||
ApplicationPage applicationPage = new ApplicationPage(); | ||
applicationPage.setId("testPageId"); | ||
applicationPage.setIsDefault(TRUE); | ||
|
||
application.setPages(List.of(applicationPage)); | ||
GitArtifactMetadata gitArtifactMetadata = new GitArtifactMetadata(); | ||
gitArtifactMetadata.setBranchName(BRANCH_NAME); | ||
gitArtifactMetadata.setDefaultBranchName(DEFAULT_BRANCH_NAME); | ||
gitArtifactMetadata.setRepoName(REPO_NAME); | ||
gitArtifactMetadata.setDefaultApplicationId(DEFAULT_APP_ID); | ||
|
||
GitAuth gitAuth = new GitAuth(); | ||
gitAuth.setPrivateKey("private-key"); | ||
gitAuth.setPublicKey("public-key"); | ||
gitArtifactMetadata.setGitAuth(gitAuth); | ||
|
||
application.setGitApplicationMetadata(gitArtifactMetadata); | ||
return application; | ||
} | ||
|
||
private GitProfile createGitProfile() { | ||
GitProfile gitProfile = new GitProfile(); | ||
gitProfile.setAuthorName("authorName"); | ||
gitProfile.setAuthorEmail("author@domain.xy"); | ||
return gitProfile; | ||
} | ||
|
||
private NewPage createNewPage() { | ||
JSONObject jsonObject = new JSONObject(); | ||
jsonObject.put("key", "value"); | ||
jsonObject.put("version", DSL_VERSION_NUMBER); | ||
|
||
Layout layout1 = new Layout(); | ||
layout1.setId("testLayoutId"); | ||
layout1.setDsl(jsonObject); | ||
|
||
PageDTO pageDTO = new PageDTO(); | ||
pageDTO.setId("testPageId"); | ||
pageDTO.setApplicationId(DEFAULT_APP_ID); | ||
pageDTO.setLayouts(List.of(layout1)); | ||
|
||
NewPage newPage = new NewPage(); | ||
newPage.setId("testPageId"); | ||
newPage.setApplicationId(DEFAULT_APP_ID); | ||
newPage.setUnpublishedPage(pageDTO); | ||
return newPage; | ||
} | ||
|
||
@BeforeEach | ||
public void beforeTest() { | ||
Mockito.when(featureFlagService.check(FeatureFlagEnum.release_git_server_autocommit_feature_enabled)) | ||
.thenReturn(Mono.just(TRUE)); | ||
|
||
Mockito.when(featureFlagService.check(FeatureFlagEnum.release_git_autocommit_feature_enabled)) | ||
.thenReturn(Mono.just(TRUE)); | ||
|
||
Mockito.when(commonGitService.fetchRemoteChanges( | ||
any(Application.class), any(Application.class), anyString(), anyBoolean())) | ||
.thenReturn(Mono.just(branchTrackingStatus)); | ||
|
||
Mockito.when(branchTrackingStatus.getBehindCount()).thenReturn(0); | ||
|
||
doReturn(Mono.just("success")) | ||
.when(gitExecutor) | ||
.pushApplication(any(Path.class), anyString(), anyString(), anyString(), anyString()); | ||
|
||
// create New Pages | ||
NewPage newPage = createNewPage(); | ||
|
||
// create application | ||
testApplication = createApplication(); | ||
baseRepoSuffix = Paths.get(WORKSPACE_ID, DEFAULT_APP_ID, REPO_NAME); | ||
|
||
doReturn(Mono.just(newPage.getUnpublishedPage())) | ||
.when(applicationPageService) | ||
.getPage(any(NewPage.class), anyBoolean()); | ||
|
||
Mockito.when(newPageService.findNewPagesByApplicationId(anyString(), any(AclPermission.class))) | ||
.thenReturn(Flux.just(newPage)); | ||
|
||
Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( | ||
anyString(), anyString(), any(AclPermission.class))) | ||
.thenReturn(Mono.just(testApplication)); | ||
|
||
Mockito.when(applicationService.findById(anyString(), any(AclPermission.class))) | ||
.thenReturn(Mono.just(testApplication)); | ||
|
||
Mockito.when(gitPrivateRepoHelper.isBranchProtected(any(), anyString())).thenReturn(Mono.just(FALSE)); | ||
|
||
Mockito.when(userDataService.getGitProfileForCurrentUser(any())).thenReturn(Mono.just(createGitProfile())); | ||
} | ||
|
||
@AfterEach | ||
public void afterTest() { | ||
gitFileSystemTestHelper.deleteWorkspaceDirectory(WORKSPACE_ID); | ||
} | ||
|
||
@Test | ||
public void testAutoCommit_WhenOnlyServerIsEligibleForMigration_CommitSuccess() | ||
throws URISyntaxException, IOException, GitAPIException { | ||
|
||
ApplicationJson applicationJson = | ||
gitFileSystemTestHelper.getApplicationJson(this.getClass().getResource(APP_JSON_NAME)); | ||
|
||
// server migration as true | ||
doReturn(Mono.just(TRUE)).when(autoCommitEligibiltyHelper).isServerAutoCommitRequired(any(), any()); | ||
Mockito.when(dslMigrationUtils.getLatestDslVersion()).thenReturn(Mono.just(DSL_VERSION_NUMBER)); | ||
|
||
ApplicationJson applicationJson1 = new ApplicationJson(); | ||
AppsmithBeanUtils.copyNewFieldValuesIntoOldObject(applicationJson, applicationJson1); | ||
applicationJson1.setServerSchemaVersion(JsonSchemaVersions.serverVersion + 1); | ||
|
||
doReturn(Mono.just(applicationJson1)) | ||
.when(jsonSchemaMigration) | ||
.migrateApplicationJsonToLatestSchema(any(ApplicationJson.class)); | ||
|
||
gitFileSystemTestHelper.setupGitRepository( | ||
WORKSPACE_ID, DEFAULT_APP_ID, BRANCH_NAME, REPO_NAME, applicationJson); | ||
|
||
// verifying the initial number of commits | ||
StepVerifier.create(gitExecutor.getCommitHistory(baseRepoSuffix)) | ||
.assertNext(gitLogDTOs -> { | ||
assertThat(gitLogDTOs).isNotEmpty(); | ||
assertThat(gitLogDTOs.size()).isEqualTo(2); | ||
|
||
Set<String> commitMessages = | ||
gitLogDTOs.stream().map(GitLogDTO::getCommitMessage).collect(Collectors.toSet()); | ||
assertThat(commitMessages).doesNotContain(String.format(AUTO_COMMIT_MSG_FORMAT, "UNKNOWN")); | ||
}) | ||
.verifyComplete(); | ||
|
||
// this would trigger autocommit | ||
Mono<List<GitLogDTO>> gitlogDTOsMono = applicationPageService | ||
.getPagesBasedOnApplicationMode(testApplication, ApplicationMode.EDIT) | ||
.then(Mono.delay(Duration.ofSeconds(WAIT_DURATION_FOR_ASYNC_EVENT))) | ||
.then(gitExecutor.getCommitHistory(baseRepoSuffix)); | ||
|
||
StepVerifier.create(gitlogDTOsMono) | ||
.assertNext(gitLogDTOs -> { | ||
assertThat(gitLogDTOs).isNotEmpty(); | ||
assertThat(gitLogDTOs.size()).isEqualTo(3); | ||
|
||
Set<String> commitMessages = | ||
gitLogDTOs.stream().map(GitLogDTO::getCommitMessage).collect(Collectors.toSet()); | ||
assertThat(commitMessages).contains(String.format(AUTO_COMMIT_MSG_FORMAT, "UNKNOWN")); | ||
}) | ||
.verifyComplete(); | ||
} | ||
|
||
@Test | ||
public void testAutoCommit_WhenOnlyClientIsEligibleForMigration_CommitSuccess() | ||
throws GitAPIException, IOException, URISyntaxException { | ||
ApplicationJson applicationJson = | ||
gitFileSystemTestHelper.getApplicationJson(this.getClass().getResource(APP_JSON_NAME)); | ||
|
||
int pageDSLNumber = applicationJson | ||
.getPageList() | ||
.get(0) | ||
.getUnpublishedPage() | ||
.getLayouts() | ||
.get(0) | ||
.getDsl() | ||
.getAsNumber("version") | ||
.intValue(); | ||
|
||
// server migration as false | ||
doReturn(Mono.just(FALSE)).when(autoCommitEligibiltyHelper).isServerAutoCommitRequired(any(), any()); | ||
Mockito.when(dslMigrationUtils.getLatestDslVersion()).thenReturn(Mono.just(pageDSLNumber + 1)); | ||
|
||
JSONObject dslAfterMigration = new JSONObject(); | ||
dslAfterMigration.put("key", "after migration"); | ||
|
||
// mock the dsl migration utils to return updated dsl when requested with older dsl | ||
Mockito.when(dslMigrationUtils.migratePageDsl(any(JSONObject.class))).thenReturn(Mono.just(dslAfterMigration)); | ||
|
||
gitFileSystemTestHelper.setupGitRepository( | ||
WORKSPACE_ID, DEFAULT_APP_ID, BRANCH_NAME, REPO_NAME, applicationJson); | ||
|
||
// verifying the initial number of commits | ||
StepVerifier.create(gitExecutor.getCommitHistory(baseRepoSuffix)) | ||
.assertNext(gitLogDTOs -> { | ||
assertThat(gitLogDTOs).isNotEmpty(); | ||
assertThat(gitLogDTOs.size()).isEqualTo(2); | ||
|
||
Set<String> commitMessages = | ||
gitLogDTOs.stream().map(GitLogDTO::getCommitMessage).collect(Collectors.toSet()); | ||
assertThat(commitMessages).doesNotContain(String.format(AUTO_COMMIT_MSG_FORMAT, "UNKNOWN")); | ||
}) | ||
.verifyComplete(); | ||
|
||
// this would trigger autocommit | ||
Mono<List<GitLogDTO>> gitlogDTOsMono = applicationPageService | ||
.getPagesBasedOnApplicationMode(testApplication, ApplicationMode.EDIT) | ||
.then(Mono.delay(Duration.ofSeconds(WAIT_DURATION_FOR_ASYNC_EVENT))) | ||
.then(gitExecutor.getCommitHistory(baseRepoSuffix)); | ||
|
||
StepVerifier.create(gitlogDTOsMono) | ||
.assertNext(gitLogDTOs -> { | ||
assertThat(gitLogDTOs).isNotEmpty(); | ||
assertThat(gitLogDTOs.size()).isEqualTo(3); | ||
|
||
Set<String> commitMessages = | ||
gitLogDTOs.stream().map(GitLogDTO::getCommitMessage).collect(Collectors.toSet()); | ||
assertThat(commitMessages).contains(String.format(AUTO_COMMIT_MSG_FORMAT, "UNKNOWN")); | ||
}) | ||
.verifyComplete(); | ||
} | ||
|
||
@Test | ||
public void testAutoCommit_WhenAutoCommitNotEligible_ReturnsFalse() | ||
throws URISyntaxException, IOException, GitAPIException { | ||
|
||
ApplicationJson applicationJson = | ||
gitFileSystemTestHelper.getApplicationJson(this.getClass().getResource(APP_JSON_NAME)); | ||
|
||
// server migration as false | ||
doReturn(Mono.just(FALSE)).when(autoCommitEligibiltyHelper).isServerAutoCommitRequired(any(), any()); | ||
Mockito.when(dslMigrationUtils.getLatestDslVersion()).thenReturn(Mono.just(DSL_VERSION_NUMBER)); | ||
|
||
gitFileSystemTestHelper.setupGitRepository( | ||
WORKSPACE_ID, DEFAULT_APP_ID, BRANCH_NAME, REPO_NAME, applicationJson); | ||
|
||
// verifying the initial number of commits | ||
StepVerifier.create(gitExecutor.getCommitHistory(baseRepoSuffix)) | ||
.assertNext(gitLogDTOs -> { | ||
assertThat(gitLogDTOs).isNotEmpty(); | ||
assertThat(gitLogDTOs.size()).isEqualTo(2); | ||
|
||
Set<String> commitMessages = | ||
gitLogDTOs.stream().map(GitLogDTO::getCommitMessage).collect(Collectors.toSet()); | ||
assertThat(commitMessages).doesNotContain(String.format(AUTO_COMMIT_MSG_FORMAT, "UNKNOWN")); | ||
}) | ||
.verifyComplete(); | ||
|
||
// this would trigger autocommit | ||
Mono<List<GitLogDTO>> gitlogDTOsMono = applicationPageService | ||
.getPagesBasedOnApplicationMode(testApplication, ApplicationMode.EDIT) | ||
.then(Mono.delay(Duration.ofSeconds(WAIT_DURATION_FOR_ASYNC_EVENT))) | ||
.then(gitExecutor.getCommitHistory(baseRepoSuffix)); | ||
|
||
StepVerifier.create(gitlogDTOsMono) | ||
.assertNext(gitLogDTOs -> { | ||
assertThat(gitLogDTOs).isNotEmpty(); | ||
assertThat(gitLogDTOs.size()).isEqualTo(2); | ||
|
||
Set<String> commitMessages = | ||
gitLogDTOs.stream().map(GitLogDTO::getCommitMessage).collect(Collectors.toSet()); | ||
assertThat(commitMessages).doesNotContain(String.format(AUTO_COMMIT_MSG_FORMAT, "UNKNOWN")); | ||
}) | ||
.verifyComplete(); | ||
} | ||
} |
Oops, something went wrong.