diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/Constraint.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/Constraint.java new file mode 100644 index 0000000000..56925e499c --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/Constraint.java @@ -0,0 +1,5 @@ +package com.appsmith.server.constants; + +public class Constraint { + public static final int ORGANIZATION_LOGO_SIZE_KB = 250; +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/FieldName.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/FieldName.java index 2cd1231f31..3c0461d845 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/FieldName.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/FieldName.java @@ -53,4 +53,5 @@ public class FieldName { public static String ANONYMOUS_USER = "anonymousUser"; public static String USERNAMES = "usernames"; public static String ACTION = "action"; + public static String ASSET = "asset"; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java index 89b05b10d7..127d883681 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java @@ -9,16 +9,17 @@ import com.appsmith.server.services.UserOrganizationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.codec.multipart.Part; -import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; import java.util.List; @@ -37,6 +38,7 @@ public class OrganizationController extends BaseController new ResponseDTO<>(HttpStatus.OK.value(), url, null)); } + @DeleteMapping("/{organizationId}/logo") + public Mono> deleteLogo(@PathVariable String organizationId) { + return service.deleteLogo(organizationId) + .map(organization -> new ResponseDTO<>(HttpStatus.OK.value(), organization, null)); + } + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java index b1d90117a1..faae858660 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java @@ -10,7 +10,6 @@ enum AppsmithErrorAction { } @Getter public enum AppsmithError { - INVALID_PARAMETER(400, 4000, "Please enter a valid parameter {0}.", AppsmithErrorAction.DEFAULT), PLUGIN_NOT_INSTALLED(400, 4001, "Plugin {0} not installed", AppsmithErrorAction.DEFAULT), PLUGIN_ID_NOT_GIVEN(400, 4002, "Missing plugin id. Please enter one.", AppsmithErrorAction.DEFAULT), @@ -69,6 +68,7 @@ public enum AppsmithError { INVALID_CURL_METHOD(400, 4032, "Invalid method in cURL command: {0}.", AppsmithErrorAction.DEFAULT), OAUTH_NOT_AVAILABLE(500, 5006, "Login with {0} is not supported.", AppsmithErrorAction.LOG_EXTERNALLY), MARKETPLACE_NOT_CONFIGURED(500, 5007, "Marketplace is not configured.", AppsmithErrorAction.DEFAULT), + PAYLOAD_TOO_LARGE(413, 4028, "The request payload is too large. Max allowed size for request payload is {0} KB", AppsmithErrorAction.DEFAULT) ; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java index e09a1f98aa..b2dfddc38e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java @@ -20,7 +20,7 @@ public interface OrganizationService extends CrudService { Mono getNextUniqueSlug(String initialSlug); - Mono createPersonal(Organization organization, User user); + Mono createDefault(Organization organization, User user); Mono create(Organization organization, User user); @@ -37,4 +37,6 @@ public interface OrganizationService extends CrudService { Mono> getOrganizationMembers(String orgId); Mono uploadLogo(String organizationId, Part filePart); + + Mono deleteLogo(String organizationId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java index aef7daf353..35d97d4bab 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java @@ -3,6 +3,7 @@ package com.appsmith.server.services; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.acl.AppsmithRole; import com.appsmith.server.acl.RoleGraph; +import com.appsmith.server.constants.Constraint; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Asset; import com.appsmith.server.domains.Organization; @@ -108,16 +109,17 @@ public class OrganizationServiceImpl extends BaseService createPersonal(final Organization organization, User user) { - organization.setName(user.computeFirstName() + "'s Personal Organization"); + public Mono createDefault(final Organization organization, User user) { + organization.setName(user.computeFirstName() + "'s apps"); return create(organization, user); } @@ -130,7 +132,7 @@ public class OrganizationServiceImpl extends BaseService appsmithRoles = roleGraph.generateHierarchicalRoles(roleName); - Map appsmithRolesMap = appsmithRoles + Map appsmithRolesMap = appsmithRoles .stream() .collect(toMap(AppsmithRole::getName, AppsmithRole::getDescription)); @@ -321,17 +323,27 @@ public class OrganizationServiceImpl extends BaseService uploadLogo(String organizationId, Part filePart) { - return Mono - .zip( - repository - .findById(organizationId, MANAGE_ORGANIZATIONS) - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ORGANIZATION, organizationId))), - filePart.content().single() - ) + return repository + .findById(organizationId, MANAGE_ORGANIZATIONS) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ORGANIZATION, organizationId))) + .flatMap(organization -> { + if (filePart != null && filePart.headers().getContentType() != null) { + // Default implementation for the BufferFactory used breaks down the FilePart into chunks of 4KB + // To limit file size to 250KB, we only allow 63 (250/4 = 62.5) such chunks to be derived from the incoming FilePart + return filePart.content().count().flatMap(count -> { + if (count > (int) Math.ceil(Constraint.ORGANIZATION_LOGO_SIZE_KB / 4.0)) { + return Mono.error(new AppsmithException(AppsmithError.PAYLOAD_TOO_LARGE, Constraint.ORGANIZATION_LOGO_SIZE_KB)); + } else { + return Mono.zip(Mono.just(organization), DataBufferUtils.join(filePart.content())); + } + }); + } else { + return Mono.error(new AppsmithException(AppsmithError.VALIDATION_FAILURE, "Please upload a valid image.")); + } + }) .flatMap(tuple -> { final Organization organization = tuple.getT1(); final DataBuffer dataBuffer = tuple.getT2(); - final String prevAssetId = organization.getLogoAssetId(); byte[] data = new byte[dataBuffer.readableByteCount()]; @@ -342,13 +354,40 @@ public class OrganizationServiceImpl extends BaseService { organization.setLogoAssetId(asset.getId()); - return repository.save(organization); + Mono savedOrganization = repository.save(organization); + Mono createdAsset = analyticsService.sendCreateEvent(asset); + return savedOrganization.zipWith(createdAsset); }) - .flatMap(savedOrganization -> - prevAssetId != null - ? assetRepository.deleteById(prevAssetId).thenReturn(savedOrganization) - : Mono.just(savedOrganization) - ); + .flatMap(savedTuple -> { + Organization savedOrganization = savedTuple.getT1(); + if (prevAssetId != null) { + return assetRepository.findById(prevAssetId) + .flatMap(asset -> assetRepository.delete(asset).thenReturn(asset)) + .flatMap(analyticsService::sendDeleteEvent) + .thenReturn(savedOrganization); + } else { + return Mono.just(savedOrganization); + } + }); + }); + } + + @Override + public Mono deleteLogo(String organizationId) { + return repository + .findById(organizationId, MANAGE_ORGANIZATIONS) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ORGANIZATION, organizationId))) + .flatMap(organization -> { + final String prevAssetId = organization.getLogoAssetId(); + if(prevAssetId == null) { + return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ASSET, prevAssetId)); + } + organization.setLogoAssetId(null); + return assetRepository.findById(prevAssetId) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ASSET, prevAssetId))) + .flatMap(asset -> assetRepository.delete(asset).thenReturn(asset)) + .flatMap(analyticsService::sendDeleteEvent) + .then(repository.save(organization)); }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java index 51dce8efd6..7d777f45e2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java @@ -458,10 +458,10 @@ public class UserServiceImpl extends BaseService i final String templateOrganizationId = tuple.getT2(); if (!StringUtils.hasText(templateOrganizationId)) { - // Since template organization is not configured, we create an empty personal organization. + // Since template organization is not configured, we create an empty default organization. final User savedUser = tuple.getT1(); - log.debug("Creating blank personal organization for user '{}'.", savedUser.getEmail()); - return organizationService.createPersonal(new Organization(), savedUser); + log.debug("Creating blank default organization for user '{}'.", savedUser.getEmail()); + return organizationService.createDefault(new Organization(), savedUser); } return Mono.empty(); @@ -472,8 +472,8 @@ public class UserServiceImpl extends BaseService i /** * This function creates a new user in the system. Primarily used by new users signing up for the first time on the - * platform. This flow also ensures that a personal workspace name is created for the user. The new user is then - * given admin permissions to the personal workspace. + * platform. This flow also ensures that a default organization name is created for the user. The new user is then + * given admin permissions to the default organization. *

* For new user invite flow, please {@link UserService#inviteUser(InviteUsersDTO, String)} * @@ -694,7 +694,7 @@ public class UserServiceImpl extends BaseService i // user was invited. newUser.setInviteToken(UUID.randomUUID().toString()); - // Call user service's userCreate function so that the personal organization, etc are also created along with assigning basic permissions. + // Call user service's userCreate function so that the default organization, etc are also created along with assigning basic permissions. return userCreate(newUser) .flatMap(createdUser -> { log.debug("Going to send email for invite user to {}", createdUser.getEmail()); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ExamplesOrganizationCloner.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ExamplesOrganizationCloner.java index 8a5df6b3fe..0a11341449 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ExamplesOrganizationCloner.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ExamplesOrganizationCloner.java @@ -126,7 +126,7 @@ public class ExamplesOrganizationCloner { organization.getUserRoles().clear(); } organization.setSlug(null); - return organizationService.createPersonal(organization, user); + return organizationService.createDefault(organization, user); }) .flatMap(newOrganization -> { User userUpdate = new User(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/OrganizationServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/OrganizationServiceTest.java index 08359816e4..b65eef55e8 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/OrganizationServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/OrganizationServiceTest.java @@ -4,6 +4,7 @@ import com.appsmith.external.models.Policy; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.acl.AppsmithRole; import com.appsmith.server.acl.RoleGraph; +import com.appsmith.server.constants.Constraint; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Asset; @@ -18,17 +19,18 @@ import com.appsmith.server.repositories.AssetRepository; import com.appsmith.server.repositories.DatasourceRepository; import com.appsmith.server.repositories.OrganizationRepository; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.NotImplementedException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.http.codec.multipart.Part; +import org.springframework.http.codec.multipart.FilePart; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.annotation.DirtiesContext; @@ -36,12 +38,10 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import reactor.util.annotation.NonNull; import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; import java.io.IOException; -import java.io.InputStream; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -954,28 +954,70 @@ public class OrganizationServiceTest { @Test @WithUserDetails(value = "api_user") - public void uploadOrganizationLogo() throws IOException { - final InputStream imageResourceStream = getClass().getClassLoader() - .getResourceAsStream("test_assets/OrganizationServiceTest/my_organization_logo.png"); - assertThat(imageResourceStream).isNotNull(); + public void uploadOrganizationLogo_nullFilePart() throws IOException { + Mono createOrganization = organizationService.create(organization).cache(); + final Mono resultMono = createOrganization + .flatMap(organization -> organizationService.uploadLogo(organization.getId(), null)); - final byte[] bytes = imageResourceStream.readAllBytes(); - final InMemoryFilePart filePart = new InMemoryFilePart(bytes, MediaType.IMAGE_PNG); + StepVerifier.create(resultMono) + .expectErrorMatches(throwable -> throwable instanceof AppsmithException && + throwable.getMessage().equals(AppsmithError.VALIDATION_FAILURE.getMessage("Please upload a valid image."))) + .verify(); + } - final String organizationId = organizationRepository - .findByName("Spring Test Organization") - .blockOptional(Duration.ofSeconds(3)) - .map(Organization::getId) - .orElse(null); + @Test + @WithUserDetails(value = "api_user") + public void uploadOrganizationLogo_largeFilePart() throws IOException { + FilePart filepart = Mockito.mock(FilePart.class, Mockito.RETURNS_DEEP_STUBS); + Flux dataBufferFlux = DataBufferUtils + .read(new ClassPathResource("test_assets/OrganizationServiceTest/my_organization_logo_large.png"), new DefaultDataBufferFactory(), 4096); + assertThat(dataBufferFlux.count().block()).isGreaterThan((int) Math.ceil(Constraint.ORGANIZATION_LOGO_SIZE_KB/4.0)); - assertThat(organizationId).isNotNull(); + Mockito.when(filepart.content()).thenReturn(dataBufferFlux); + Mockito.when(filepart.headers().getContentType()).thenReturn(MediaType.IMAGE_PNG); - final Mono> resultMono = organizationService - .uploadLogo(organizationId, filePart) - .flatMap(organizationWithLogo -> Mono.zip( - Mono.just(organizationWithLogo), - assetRepository.findById(organizationWithLogo.getLogoAssetId()) - )); + // The pre-requisite of creating an organization has been blocked for code readability + // The duration sets an upper limit for this test to run + String orgId = organizationService.create(organization).blockOptional(Duration.ofSeconds(3)).map(Organization::getId).orElse(null); + assertThat(orgId).isNotNull(); + + final Mono resultMono = organizationService.uploadLogo(orgId, filepart); + + StepVerifier.create(resultMono) + .expectErrorMatches(throwable -> throwable instanceof AppsmithException && + throwable.getMessage().equals(AppsmithError.PAYLOAD_TOO_LARGE.getMessage(Constraint.ORGANIZATION_LOGO_SIZE_KB))) + .verify(); + } + + @Test + @WithUserDetails(value = "api_user") + public void testDeleteLogo_invalidOrganization() { + Mono deleteLogo = organizationService.deleteLogo(""); + StepVerifier.create(deleteLogo) + .expectErrorMatches(throwable -> throwable instanceof AppsmithException && + throwable.getMessage().equals(AppsmithError.NO_RESOURCE_FOUND.getMessage(FieldName.ORGANIZATION, ""))) + .verify(); + } + + @Test + @WithUserDetails(value = "api_user") + public void testUpdateAndDeleteLogo_validLogo() throws IOException { + FilePart filepart = Mockito.mock(FilePart.class, Mockito.RETURNS_DEEP_STUBS); + Flux dataBufferFlux = DataBufferUtils + .read(new ClassPathResource("test_assets/OrganizationServiceTest/my_organization_logo.png"), new DefaultDataBufferFactory(), 4096).cache(); + assertThat(dataBufferFlux.count().block()).isLessThanOrEqualTo((int) Math.ceil(Constraint.ORGANIZATION_LOGO_SIZE_KB/4.0)); + + Mockito.when(filepart.content()).thenReturn(dataBufferFlux); + Mockito.when(filepart.headers().getContentType()).thenReturn(MediaType.IMAGE_PNG); + + Mono createOrganization = organizationService.create(organization).cache(); + + final Mono> resultMono = createOrganization + .flatMap(organization -> organizationService.uploadLogo(organization.getId(), filepart) + .flatMap(organizationWithLogo -> Mono.zip( + Mono.just(organizationWithLogo), + assetRepository.findById(organizationWithLogo.getLogoAssetId())) + )); StepVerifier.create(resultMono) .assertNext(tuple -> { @@ -985,41 +1027,19 @@ public class OrganizationServiceTest { final Asset asset = tuple.getT2(); assertThat(asset).isNotNull(); - assertThat(asset.getData()).isEqualTo(bytes); + DataBuffer buffer = DataBufferUtils.join(dataBufferFlux).block(Duration.ofSeconds(3)); + byte[] res = new byte[buffer.readableByteCount()]; + buffer.read(res); + assertThat(asset.getData()).isEqualTo(res); + }) + .verifyComplete(); + + Mono deleteLogo = createOrganization.flatMap(organization -> organizationService.deleteLogo(organization.getId())); + StepVerifier.create(deleteLogo) + .assertNext(x -> { + assertThat(x.getLogoAssetId()).isNull(); + log.debug("Deleted logo for org: {}", x.getId()); }) .verifyComplete(); } - - private static class InMemoryFilePart implements Part { - - private final DataBuffer buffer; - private final HttpHeaders headers; - - public InMemoryFilePart(byte[] bytes, MediaType contentType) { - this.buffer = new DefaultDataBufferFactory().wrap(bytes); - headers = new HttpHeaders(); - headers.setContentType(contentType); - } - - @Override - @NonNull - public String name() { - throw new NotImplementedException( - "This is a FilePart made for testing. The name() method is not implemented."); - } - - @Override - @NonNull - public HttpHeaders headers() { - return headers; - } - - @Override - @NonNull - public Flux content() { - return Flux.just(buffer); - } - - } - } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java index 322616f863..bd5819ca4e 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java @@ -171,8 +171,8 @@ public class UserServiceTest { assertThat(user.getName()).isEqualTo("new-user-email@email.com"); assertThat(user.getPolicies()).isNotEmpty(); assertThat(user.getPolicies()).containsAll(Set.of(manageUserPolicy, manageUserOrgPolicy, readUserPolicy, readUserOrgPolicy)); - // Since there is a template organization, the user won't have an empty personal organization. They - // will get a clone of the personal organization when they first login. So, we expect it to be + // Since there is a template organization, the user won't have an empty default organization. They + // will get a clone of the default organization when they first login. So, we expect it to be // empty here. assertThat(user.getOrganizationIds()).isNullOrEmpty(); }) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ExamplesOrganizationClonerTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ExamplesOrganizationClonerTests.java index 46a8c1ea06..73ed60f783 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ExamplesOrganizationClonerTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ExamplesOrganizationClonerTests.java @@ -160,7 +160,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.applications).isEmpty(); @@ -209,7 +209,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.applications).hasSize(1); @@ -268,7 +268,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.applications).hasSize(2); @@ -323,7 +323,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.applications).isEmpty(); @@ -374,7 +374,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.datasources).hasSize(2); @@ -458,7 +458,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.applications).hasSize(2); @@ -610,7 +610,7 @@ public class ExamplesOrganizationClonerTests { .assertNext(data -> { assertThat(data.organization).isNotNull(); assertThat(data.organization.getId()).isNotNull(); - assertThat(data.organization.getName()).isEqualTo("api_user's Personal Organization"); + assertThat(data.organization.getName()).isEqualTo("api_user's apps"); assertThat(data.organization.getPolicies()).isNotEmpty(); assertThat(data.applications).hasSize(2); diff --git a/app/server/appsmith-server/src/test/resources/test_assets/OrganizationServiceTest/my_organization_logo_large.png b/app/server/appsmith-server/src/test/resources/test_assets/OrganizationServiceTest/my_organization_logo_large.png new file mode 100644 index 0000000000..781a0383fd Binary files /dev/null and b/app/server/appsmith-server/src/test/resources/test_assets/OrganizationServiceTest/my_organization_logo_large.png differ