diff --git a/sdm/src/test/java/integration/com/sap/cds/sdm/Api.java b/sdm/src/test/java/integration/com/sap/cds/sdm/Api.java index 78d86346..4474b192 100644 --- a/sdm/src/test/java/integration/com/sap/cds/sdm/Api.java +++ b/sdm/src/test/java/integration/com/sap/cds/sdm/Api.java @@ -206,7 +206,7 @@ public String deleteEntityDraft(String appUrl, String entityName, String entityI System.out.println("Delete entity failed. Error : " + response.body().string()); throw new IOException("Could not delete entity"); } - return "Entity Deleted"; + return "Entity Draft Deleted"; } catch (IOException e) { System.out.println("Could not delete entity : " + e); } @@ -676,6 +676,94 @@ public String copyAttachment( } } + public String createLink( + String appUrl, + String entityName, + String facetName, + String entityID, + String linkName, + String linkUrl) + throws IOException { + String url = + "https://" + + appUrl + + "/odata/v4/" + + serviceName + + "/" + + entityName + + "(ID=" + + entityID + + ",IsActiveEntity=false)/" + + facetName + + "/" + + serviceName + + ".createLink"; + + MediaType mediaType = MediaType.parse("application/json"); + + String jsonPayload = + "{" + "\"name\": \"" + linkName + "\"," + "\"url\": \"" + linkUrl + "\"" + "}"; + + RequestBody body = RequestBody.create(mediaType, jsonPayload); + + Request request = + new Request.Builder().url(url).post(body).addHeader("Authorization", token).build(); + + try (Response response = httpClient.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new IOException( + "Could not create link: " + response.code() + " - " + response.body().string()); + } + return "Link created successfully"; + } catch (IOException e) { + System.out.println("Error while creating link: " + e.getMessage()); + throw new IOException(e); + } + } + + public String openAttachment( + String appUrl, String entityName, String facetName, String entityID, String ID) + throws IOException { + String url = + "https://" + + appUrl + + "/odata/v4/" + + serviceName + + "/Books(ID=" + + entityID + + ",IsActiveEntity=true)" + + "/" + + facetName + + "(up__ID=" + + entityID + + ",ID=" + + ID + + ",IsActiveEntity=true)" + + "/" + + serviceName + + ".openAttachment"; + + MediaType mediaType = MediaType.parse("application/json"); + + String jsonPayload = "{}"; + + RequestBody body = RequestBody.create(mediaType, jsonPayload); + + Request request = + new Request.Builder().url(url).post(body).addHeader("Authorization", token).build(); + + try (Response response = httpClient.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new IOException( + "Could not open attachment: " + response.code() + " - " + response.body().string()); + } + return "Attachment opened successfully"; + } catch (IOException e) { + System.out.println("Error while opening attachment: " + e.getMessage()); + throw new IOException(e); + } + } + public Map fetchMetadata( String appUrl, String entityName, String facetName, String entityID, String ID) throws IOException { diff --git a/sdm/src/test/java/integration/com/sap/cds/sdm/ApiInterface.java b/sdm/src/test/java/integration/com/sap/cds/sdm/ApiInterface.java index a53d9ac7..cf412fd7 100644 --- a/sdm/src/test/java/integration/com/sap/cds/sdm/ApiInterface.java +++ b/sdm/src/test/java/integration/com/sap/cds/sdm/ApiInterface.java @@ -73,5 +73,18 @@ public Map fetchMetadata( public List> fetchEntityMetadata( String appUrl, String entityName, String facetName, String entityID) throws IOException; + public String createLink( + String appUrl, + String entityName, + String facetName, + String entityID, + String linkName, + String linkUrl) + throws IOException; + + public String openAttachment( + String appUrl, String entityName, String facetName, String entityID, String ID) + throws IOException; + String deleteEntityDraft(String appUrl, String entityName, String entityID); } diff --git a/sdm/src/test/java/integration/com/sap/cds/sdm/ApiMT.java b/sdm/src/test/java/integration/com/sap/cds/sdm/ApiMT.java index ef17d3b7..e932524e 100644 --- a/sdm/src/test/java/integration/com/sap/cds/sdm/ApiMT.java +++ b/sdm/src/test/java/integration/com/sap/cds/sdm/ApiMT.java @@ -196,7 +196,7 @@ public String deleteEntityDraft(String appUrl, String entityName, String entityI System.out.println("Delete entity failed. Error : " + response.body().string()); throw new IOException("Could not delete entity"); } - return "Entity Deleted"; + return "Entity Draft Deleted"; } catch (IOException e) { System.out.println("Could not delete entity : " + e); } @@ -505,11 +505,6 @@ public String renameAttachment( try (Response renameResponse = httpClient.newCall(request).execute()) { if (renameResponse.code() != 200) { - System.out.println( - "Rename Attachment failed in the " - + facetName - + " section. Error : " - + renameResponse.body().string()); throw new IOException("Attachment was not renamed in section: " + facetName); } return "Renamed"; @@ -640,6 +635,86 @@ public String copyAttachment( } } + public String createLink( + String appUrl, + String entityName, + String facetName, + String entityID, + String linkName, + String linkUrl) + throws IOException { + String url = + "https://" + + appUrl + + "/api/admin/" + + entityName + + "(ID=" + + entityID + + ",IsActiveEntity=false)/" + + facetName + + "/" + + "AdminService.createLink"; + + MediaType mediaType = MediaType.parse("application/json"); + + String jsonPayload = + "{" + "\"name\": \"" + linkName + "\"," + "\"url\": \"" + linkUrl + "\"" + "}"; + + RequestBody body = RequestBody.create(mediaType, jsonPayload); + + Request request = + new Request.Builder().url(url).post(body).addHeader("Authorization", token).build(); + + try (Response response = httpClient.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new IOException( + "Could not create link: " + response.code() + " - " + response.body().string()); + } + return "Link created successfully"; + } + } + + public String openAttachment( + String appUrl, String entityName, String facetName, String entityID, String ID) + throws IOException { + String url = + "https://" + + appUrl + + "/api/admin/" + + entityName + + "(ID=" + + entityID + + ",IsActiveEntity=true)/" + + facetName + + "(up__ID=" + + entityID + + ",ID=" + + ID + + ",IsActiveEntity=true)" + + "/" + + "AdminService.openAttachment"; + + MediaType mediaType = MediaType.parse("application/json"); + + String jsonPayload = "{}"; + + RequestBody body = RequestBody.create(mediaType, jsonPayload); + + Request request = + new Request.Builder().url(url).post(body).addHeader("Authorization", token).build(); + + try (Response response = httpClient.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new IOException( + "Could not open attachment: " + response.code() + " - " + response.body().string()); + } + return "Attachment opened successfully"; + } catch (IOException e) { + System.out.println("Error while opening attachment: " + e.getMessage()); + throw new IOException(e); + } + } + public Map fetchMetadata( String appUrl, String entityName, String facetName, String entityID, String ID) throws IOException { diff --git a/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_MultipleFacet.java b/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_MultipleFacet.java index afee9092..cc024569 100644 --- a/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_MultipleFacet.java +++ b/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_MultipleFacet.java @@ -14,6 +14,7 @@ import java.util.stream.Collectors; import okhttp3.*; import okio.ByteString; +import org.json.JSONObject; import org.junit.jupiter.api.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @@ -52,8 +53,10 @@ class IntegrationTest_MultipleFacet { private static String copyAttachmentSourceEntity; private static String copyAttachmentTargetEntity; private static String copyAttachmentTargetEntityEmpty; + private static String createLinkEntity; private static List sourceObjectIds = new ArrayList<>(); private static List targetAttachmentIds = new ArrayList<>(); + private static List successfullyRenamedAttachments = new ArrayList<>(); @BeforeAll static void setup() throws IOException { @@ -2181,7 +2184,7 @@ void testDiscardDraftWithoutAttachments() { if (!response.equals("Could not create entity")) { entityID6 = response; response = api.deleteEntityDraft(appUrl, entityName, entityID6); - if (response.equals("Entity Deleted")) { + if (response.equals("Entity Draft Deleted")) { testStatus = true; } } @@ -2218,7 +2221,7 @@ void testDiscardDraftWithAttachments() throws IOException { } } response = api.deleteEntityDraft(appUrl, entityName, entityID6); - if ("Entity Deleted".equals(response)) { + if ("Entity Draft Deleted".equals(response)) { testStatus = true; } } @@ -2727,4 +2730,516 @@ void testCopyAttachmentsUnsuccessfulExistingEntity() throws IOException { fail("Could not edit entities"); } } + + @Test + @Order(37) + void testCreateLinkSuccess() throws IOException { + System.out.println("Test (37): Create link in entity"); + List attachments = new ArrayList<>(); + + createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkEntity.equals("Could not create entity")) { + fail("Could not create entity"); + } + + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + for (String facetName : facet) { + String createLinkResponse1 = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + String createLinkResponse2 = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName + "1", linkUrl); + if (!createLinkResponse1.equals("Link created successfully") + || !createLinkResponse2.equals("Link created successfully")) { + fail("Could not create links for facet : " + facetName + createLinkResponse1); + } + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + for (String facetName : facet) { + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + String openAttachmentResponse; + for (String attachment : attachments) { + openAttachmentResponse = + api.openAttachment(appUrl, entityName, facetName, createLinkEntity, attachment); + if (!openAttachmentResponse.equals("Attachment opened successfully")) { + fail("Could not open created link in facet : " + facetName); + } + } + } + } + + @Test + @Order(38) + void testCreateLinkDifferentEntity() throws IOException { + System.out.println("Test (38): Create link with same name in different entity"); + + String createLinkDifferentEntity = + api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkDifferentEntity.equals("Could not edit entity")) { + fail("Could not create entity"); + } + + String linkName = "sample"; + String linkUrl = "https://example.com"; + for (String facetName : facet) { + String createResponse = + api.createLink( + appUrl, entityName, facetName, createLinkDifferentEntity, linkName, linkUrl); + if (!createResponse.equals("Link created successfully")) { + fail("Could not create link in different entity with same name"); + } + } + + String response = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkDifferentEntity); + if (!response.equals("Saved")) { + fail("Could not save entity"); + } + + response = api.deleteEntity(appUrl, entityName, createLinkDifferentEntity); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } + + @Test + @Order(39) + void testCreateLinkFailure() throws IOException { + System.out.println("Test (39): Create link fails due to invalid URL and name"); + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (editEntityResponse.equals("Could not edit entity")) { + fail("Could not edit entity"); + } + for (String facetName : facet) { + String linkName = "sample"; + String linkUrl = "example.com"; + try { + String response = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + fail("Create link did not throw an error for invalid url"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("400018", errorCode); + assertTrue( + errorMessage.equals("Enter a value that is within the expected pattern.") + || errorMessage.equals("Enter a value that matches the expected pattern."), + "Unexpected error message: " + errorMessage); + } + try { + api.createLink( + appUrl, entityName, facetName, createLinkEntity, linkName + "//", "https://" + linkUrl); + fail("Create link did not throw an error for invalid name"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + String expected = + "Link could not be created. The following name(s) contain unsupported characters (/, \\).\n\n" + + " • sample//\n\n" + + "Rename the link and try again."; + assertEquals("500", errorCode); + assertEquals( + expected.replaceAll("\\s+", " ").trim(), errorMessage.replaceAll("\\s+", " ").trim()); + } + try { + api.createLink(appUrl, entityName, facetName, createLinkEntity, "", ""); + fail("Create link did not throw an error for empty name and url"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + String expected = "Provide the missing value."; + assertEquals("409008", errorCode); + assertEquals(expected, errorMessage); + } + try { + api.createLink( + appUrl, entityName, facetName, createLinkEntity, linkName, "https://" + linkUrl); + fail("Create link did not throw an error for duplicate name"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("500", errorCode); + assertEquals("sample already exists.", errorMessage); + } + try { + for (int i = 2; i < 6; i++) { + api.createLink( + appUrl, entityName, facetName, createLinkEntity, linkName + i, "https://" + linkUrl); + } + System.out.println("Created 5 links in facet: " + facetName); + if (!facetName.equals("footnotes")) { + fail("More than 5 links were created in the same entity"); + } + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("500", errorCode); + if (facetName.equals("references")) { + assertEquals("Only 5 attachments allowed.", errorMessage); + } else if (facetName.equals("attachments")) { + assertEquals("Only 4 attachments allowed.", errorMessage); + } + } + } + + String response = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!response.equals("Saved")) { + fail("Could not save entity"); + } + + response = api.deleteEntity(appUrl, entityName, createLinkEntity); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } + + @Test + @Order(40) + void testCreateLinkNoSDMRoles() throws IOException { + System.out.println("Test (40): Create link fails due to no SDM roles assigned"); + + String createLinkEntityNoSDMRoles = + apiNoRoles.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkEntityNoSDMRoles.equals("Could not edit entity")) { + fail("Could not create entity"); + } + + for (String facetName : facet) { + String linkName = "sample27"; + String linkUrl = "https://example.com"; + try { + apiNoRoles.createLink( + appUrl, entityName, facetName, createLinkEntityNoSDMRoles, linkName, linkUrl); + fail("Link got created without SDM roles"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("500", errorCode); + assertEquals( + "You do not have the required permissions to upload attachments. Please contact your administrator for access.", + errorMessage); + } + } + + String response = + apiNoRoles.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntityNoSDMRoles); + if (!response.equals("Saved")) { + fail("Could not save entity"); + } + + response = api.deleteEntity(appUrl, entityName, createLinkEntityNoSDMRoles); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } + + @Test + @Order(41) + void testDeleteLink() throws IOException { + System.out.println("Test (41): Delete link in entity"); + List> attachments = new ArrayList<>(); + + String createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkEntity.equals("Could not create entity")) { + fail("Could not create entity"); + } + + for (String facetName : facet) { + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link for facet : " + facetName); + } + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + for (String facetName : facet) { + attachments.add( + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + } + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + int index = 0; + for (String facetName : facet) { + String deleteLinkResponse = + api.deleteAttachment( + appUrl, entityName, facetName, createLinkEntity, attachments.get(index).get(0)); + System.out.println("Delete response for facet " + facetName + ": " + deleteLinkResponse); + if (!deleteLinkResponse.equals("Deleted")) { + fail("Could not delete created link"); + } + index += 1; + } + + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + index = 0; + attachments.clear(); + for (String facetName : facet) { + attachments.add( + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + System.out.println( + "Attachments after deletion in facet " + facetName + ": " + attachments.get(index)); + if (attachments.get(index).size() != 0) { + fail("Link wasn't deleted"); + } + index += 1; + } + + String response = api.deleteEntity(appUrl, entityName, createLinkEntity); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } + + @Test + @Order(42) + void testRenameLinkSuccess() throws IOException { + System.out.println("Test (42): Rename link in entity"); + List> attachments = new ArrayList<>(); + + createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkEntity.equals("Could not create entity")) { + fail("Could not create entity"); + } + + for (String facetName : facet) { + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link"); + } + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + for (String facetName : facet) { + attachments.add( + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + } + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + int index = 0; + for (String facetName : facet) { + successfullyRenamedAttachments.add(attachments.get(index).get(0)); + String renameLinkResponse = + api.renameAttachment( + appUrl, + entityName, + facetName, + createLinkEntity, + attachments.get(index).get(0), + "sampleRenamed"); + if (!renameLinkResponse.equals("Renamed")) { + fail("Could not Renamed created link"); + } + index += 1; + } + + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + } + + @Test + @Order(43) + void testRenameLinkDuplicate() throws IOException { + System.out.println("Test (43): Rename link in entity fails due to duplicate error"); + List attachments = new ArrayList<>(); + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + int index = 0; + for (String facetName : facet) { + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link"); + } + } + + String saveResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (saveResponse.equals("Could not save entity")) { + fail("Could not save entity"); + } + + index = 0; + List facetAttachments; + for (String facetName : facet) { + int lambdaIndex = index; + facetAttachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .filter( + item -> + !successfullyRenamedAttachments + .get(lambdaIndex) + .equals(item.get("ID"))) // skip unwanted filename + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + index += 1; + attachments.add(facetAttachments.get(0)); + } + + System.out.println("Attachments to be renamed: " + attachments); + String response = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!response.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + index = 0; + for (String facetName : facet) { + api.renameAttachment( + appUrl, entityName, facetName, createLinkEntity, attachments.get(index), "sampleRenamed"); + index += 1; + } + + String saveError = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + String expectedWarning = + "{\"error\":{\"code\":\"400\",\"message\":\"The file(s) sampleRenamed have been added multiple times. Please rename and try again.\",\"details\":[{\"code\":\"\",\"message\":\"The file(s) sampleRenamed have been added multiple times. Please rename and try again.\",\"@Common.numericSeverity\":4},{\"code\":\"\",\"message\":\"The file(s) sampleRenamed have been added multiple times. Please rename and try again.\",\"@Common.numericSeverity\":4}]}}"; + ObjectMapper mapper = new ObjectMapper(); + assertEquals(mapper.readTree(expectedWarning), mapper.readTree(saveError)); + + String deleteEntityResponse = api.deleteEntityDraft(appUrl, entityName, createLinkEntity); + if (!deleteEntityResponse.equals("Entity Draft Deleted")) { + fail("Entity draft not deleted"); + } + } + + @Test + @Order(44) + void testRenameLinkUnsupportedCharacters() throws IOException { + System.out.println( + "Test (44): Rename link in entity fails due to unsupported characters in name"); + List> attachments = new ArrayList<>(); + + createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkEntity.equals("Could not create entity")) { + fail("Could not create entity"); + } + + String linkName = "sample2"; + String linkUrl = "https://www.example.com"; + + for (String facetName : facet) { + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link"); + } + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + for (String facetName : facet) { + attachments.add( + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + } + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + int index = 0; + for (String facetName : facet) { + api.renameAttachment( + appUrl, + entityName, + facetName, + createLinkEntity, + attachments.get(index).get(0), + "sampleRenamed//"); + index += 1; + } + + String warning = + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + String expectedWarning = + "[{\"code\":\"\",\"message\":\"Rename unsuccessful. The following filename(s) contain unsupported characters (/, \\\\). \\n\\n\\t• sampleRenamed//\\n\\nRename the files and try again.\",\"numericSeverity\":3}," + + "{\"code\":\"\",\"message\":\"Rename unsuccessful. The following filename(s) contain unsupported characters (/, \\\\). \\n\\n\\t• sampleRenamed//\\n\\nRename the files and try again.\",\"numericSeverity\":3}," + + "{\"code\":\"\",\"message\":\"Rename unsuccessful. The following filename(s) contain unsupported characters (/, \\\\). \\n\\n\\t• sampleRenamed//\\n\\nRename the files and try again.\",\"numericSeverity\":3}]"; + ObjectMapper mapper = new ObjectMapper(); + assertEquals(mapper.readTree(expectedWarning), mapper.readTree(warning)); + + String deleteEntityResponse = api.deleteEntity(appUrl, entityName, createLinkEntity); + if (!deleteEntityResponse.equals("Entity Deleted")) { + fail("Entity draft not deleted"); + } + } } diff --git a/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_SingleFacet.java b/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_SingleFacet.java index 9b41d708..ca2f4b29 100644 --- a/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_SingleFacet.java +++ b/sdm/src/test/java/integration/com/sap/cds/sdm/IntegrationTest_SingleFacet.java @@ -14,6 +14,7 @@ import java.util.stream.Collectors; import okhttp3.*; import okio.ByteString; +import org.json.JSONObject; import org.junit.jupiter.api.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @@ -50,9 +51,12 @@ class IntegrationTest_SingleFacet { private static String attachmentID6 = ""; private static String attachmentID7 = ""; private static String attachmentID8 = ""; + private static String attachmentID9 = ""; + private static String attachmentID10 = ""; private static String copyAttachmentSourceEntity; private static String copyAttachmentTargetEntity; private static String copyAttachmentTargetEntityEmpty; + private static String createLinkEntity; private static List sourceObjectIds = new ArrayList<>(); private static List targetAttachmentIds = new ArrayList<>(); @@ -2125,19 +2129,15 @@ void testUploadNAttachments() throws IOException { @Order(31) void testDiscardDraftWithoutAttachments() { System.out.println("Test (31) : Discard draft without adding attachments"); - boolean testStatus = false; String response = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); - if (!response.equals("Could not create entity")) { - entityID6 = response; - - response = api.deleteEntityDraft(appUrl, entityName, entityID6); - if (response == "Entity Deleted") { - testStatus = true; - } + if (response.equals("Could not create entity")) { + fail("Could not create entity"); } - if (!testStatus) { + + response = api.deleteEntityDraft(appUrl, entityName, response); + if (!response.equals("Entity Draft Deleted")) { fail("Draft was not discarded properly"); } } @@ -2169,7 +2169,7 @@ void testDiscardDraftWithAttachments() throws IOException { if (check.equals("Attachment created")) { response = api.deleteEntityDraft(appUrl, entityName, entityID7); } - if (response.equals("Entity Deleted")) { + if (response.equals("Entity Draft Deleted")) { testStatus = true; } } @@ -2447,4 +2447,425 @@ void testCopyAttachmentsUnsuccessfulExistingEntity() throws IOException { fail("Could not edit entities"); } } + + @Test + @Order(37) + void testCreateLinkSuccess() throws IOException { + System.out.println("Test (37): Create link in entity"); + List attachments = new ArrayList<>(); + createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (!createLinkEntity.equals("Could not create entity")) { + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse1 = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + String createLinkResponse2 = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName + "1", linkUrl); + if (createLinkResponse1.equals("Link created successfully") + && createLinkResponse2.equals("Link created successfully")) { + String saveEntityResponse = + api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (saveEntityResponse.equals("Saved")) { + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + String openAttachmentResponse; + for (String attachment : attachments) { + openAttachmentResponse = + api.openAttachment(appUrl, entityName, facetName, createLinkEntity, attachment); + System.out.println("openAttachmentResponse: " + openAttachmentResponse); + if (!openAttachmentResponse.equals("Attachment opened successfully")) { + fail("Could not open created link"); + } + } + } else { + fail("Could not save entity"); + } + } else { + fail("Could not create link"); + } + } else { + fail("Could not create entity"); + } + } + + @Test + @Order(38) + void testCreateLinkDifferentEntity() throws IOException { + System.out.println("Test (38): Create link with same name in different entity"); + String createLinkDifferentEntity = + api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (!createLinkDifferentEntity.equals("Could not edit entity")) { + String linkName = "sample"; + String linkUrl = "https://example.com"; + String createResponse = + api.createLink( + appUrl, entityName, facetName, createLinkDifferentEntity, linkName, linkUrl); + if (!createResponse.equals("Link created successfully")) { + fail("Could not create link in different entity with same name"); + } + String response = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkDifferentEntity); + if (!response.equals("Saved")) { + fail("Could not save entity"); + } + response = api.deleteEntity(appUrl, entityName, createLinkDifferentEntity); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } else { + fail("Could not edit entity"); + } + } + + @Test + @Order(39) + void testCreateLinkFailure() throws IOException { + System.out.println("Test (39): Create link fails due to invalid URL and name"); + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Could not edit entity")) { + String linkName = "sample"; + String linkUrl = "example.com"; + try { + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + fail("Create link did not throw an error for invalid url"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("400018", errorCode); + assertTrue( + errorMessage.equals("Enter a value that is within the expected pattern.") + || errorMessage.equals("Enter a value that matches the expected pattern."), + "Unexpected error message: " + errorMessage); + } + try { + api.createLink( + appUrl, entityName, facetName, createLinkEntity, linkName + "//", "https://" + linkUrl); + fail("Create link did not throw an error for invalid name"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + String expected = + "Link could not be created. The following name(s) contain unsupported characters (/, \\).\n\n" + + " • sample//\n\n" + + "Rename the link and try again."; + assertEquals("500", errorCode); + assertEquals( + expected.replaceAll("\\s+", " ").trim(), errorMessage.replaceAll("\\s+", " ").trim()); + } + try { + api.createLink(appUrl, entityName, facetName, createLinkEntity, "", ""); + fail("Create link did not throw an error for empty name and url"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + String expected = "Provide the missing value."; + assertEquals("409008", errorCode); + assertEquals(expected, errorMessage); + } + try { + api.createLink( + appUrl, entityName, facetName, createLinkEntity, linkName, "https://" + linkUrl); + fail("Create link did not throw an error for duplicate name"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("500", errorCode); + assertEquals("sample already exists.", errorMessage); + } + try { + for (int i = 2; i < 5; i++) { + api.createLink( + appUrl, entityName, facetName, createLinkEntity, linkName + i, "https://" + linkUrl); + } + fail("More than 5 links were created in the same entity"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("500", errorCode); + assertEquals("Only 4 attachments allowed.", errorMessage); + } + String response = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!response.equals("Saved")) { + fail("Could not save entity"); + } + response = api.deleteEntity(appUrl, entityName, createLinkEntity); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } else { + fail("Could not edit entity"); + } + } + + @Test + @Order(40) + void testCreateLinkNoSDMRoles() throws IOException { + System.out.println("Test (40): Create link fails due to no SDM roles assigned"); + String createLinkEntityNoSDMRoles = + apiNoRoles.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (!createLinkEntityNoSDMRoles.equals("Could not edit entity")) { + String linkName = "sample27"; + String linkUrl = "https://example.com"; + try { + apiNoRoles.createLink( + appUrl, entityName, facetName, createLinkEntityNoSDMRoles, linkName, linkUrl); + fail("Link got created without SDM roles"); + } catch (IOException e) { + String message = e.getMessage(); + int jsonStart = message.indexOf("{"); + String jsonPart = message.substring(jsonStart); + JSONObject json = new JSONObject(jsonPart); + String errorCode = json.getJSONObject("error").getString("code"); + String errorMessage = json.getJSONObject("error").getString("message"); + assertEquals("500", errorCode); + assertEquals( + "You do not have the required permissions to upload attachments. Please contact your administrator for access.", + errorMessage); + } + String response = + apiNoRoles.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntityNoSDMRoles); + if (!response.equals("Saved")) { + fail("Could not save entity"); + } + response = api.deleteEntity(appUrl, entityName, createLinkEntityNoSDMRoles); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } else { + fail("Could not edit entity"); + } + } + + @Test + @Order(41) + void testDeleteLink() throws IOException { + System.out.println("Test (41): Delete link in entity"); + List attachments = new ArrayList<>(); + String createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (!createLinkEntity.equals("Could not create entity")) { + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (createLinkResponse.equals("Link created successfully")) { + String saveEntityResponse = + api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (saveEntityResponse.equals("Saved")) { + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + String editEntityResponse = + api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + String deleteLinkResponse = + api.deleteAttachment( + appUrl, entityName, facetName, createLinkEntity, attachments.get(0)); + if (!deleteLinkResponse.equals("Deleted")) { + fail("Could not delete created link"); + } else { + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (attachments.size() != 0) { + fail("Link wasn't deleted"); + } + String response = api.deleteEntity(appUrl, entityName, createLinkEntity); + if (!response.equals("Entity Deleted")) { + fail("Could not delete entity"); + } + } + } else { + fail("Could not save entity"); + } + } else { + fail("Could not create link"); + } + } else { + fail("Could not create entity"); + } + } + + @Test + @Order(42) + void testRenameLinkSuccess() throws IOException { + System.out.println("Test (42): Rename link in entity"); + List attachments = new ArrayList<>(); + + createLinkEntity = api.createEntityDraft(appUrl, entityName, entityName2, srvpath); + if (createLinkEntity.equals("Could not create entity")) { + fail("Could not create entity"); + } + + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link"); + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + attachmentID9 = attachments.get(0); + String renameLinkResponse = + api.renameAttachment( + appUrl, entityName, facetName, createLinkEntity, attachments.get(0), "sampleRenamed"); + if (!renameLinkResponse.equals("Renamed")) fail("Could not Renamed created link"); + + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + } + + @Test + @Order(43) + void testRenameLinkDuplicate() throws IOException { + System.out.println("Test (43): Rename link in entity fails due to duplicate error"); + List attachments = new ArrayList<>(); + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + String linkName = "sample"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link"); + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + .filter(item -> !attachmentID9.equals(item.get("ID"))) // skip unwanted filename + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + attachmentID10 = attachments.get(0); + api.renameAttachment( + appUrl, entityName, facetName, createLinkEntity, attachments.get(0), "sampleRenamed"); + + String saveError = + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + String expectedWarning = + "{\"error\":{\"code\":\"400\",\"message\":\"The file(s) sampleRenamed have been added multiple times. Please rename and try again.\"}}"; + ObjectMapper mapper = new ObjectMapper(); + assertEquals(mapper.readTree(expectedWarning), mapper.readTree(saveError)); + + String deleteEntityResponse = api.deleteEntityDraft(appUrl, entityName, createLinkEntity); + if (!deleteEntityResponse.equals("Entity Draft Deleted")) { + fail("Entity draft not deleted"); + } + } + + @Test + @Order(44) + void testRenameLinkUnsupportedCharacters() throws IOException { + System.out.println( + "Test (44): Rename link in entity fails due to unsupported characters in name"); + List attachments = new ArrayList<>(); + + String editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + String linkName = "sample2"; + String linkUrl = "https://www.example.com"; + String createLinkResponse = + api.createLink(appUrl, entityName, facetName, createLinkEntity, linkName, linkUrl); + if (!createLinkResponse.equals("Link created successfully")) { + fail("Could not create link"); + } + + String saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!saveEntityResponse.equals("Saved")) { + fail("Could not save entity"); + } + + attachments = + api.fetchEntityMetadata(appUrl, entityName, facetName, createLinkEntity).stream() + // .filter(item -> "sample2".equals(item.get("filename"))) // skip unwanted filename + .map(item -> (String) item.get("ID")) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + System.out.println("attachments: " + attachments); + + editEntityResponse = api.editEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + if (!editEntityResponse.equals("Entity in draft mode")) { + fail("Could not edit entity"); + } + + api.renameAttachment( + appUrl, entityName, facetName, createLinkEntity, attachments.get(0), "sampleRenamed//"); + String warning = + saveEntityResponse = api.saveEntityDraft(appUrl, entityName, srvpath, createLinkEntity); + String expectedWarning = + "[{\"code\":\"\",\"message\":\"Rename unsuccessful. The following filename(s) contain unsupported characters (/, \\\\). \\n\\n\\t• sampleRenamed//\\n\\nRename the files and try again.\",\"numericSeverity\":3}]"; + ObjectMapper mapper = new ObjectMapper(); + assertEquals(mapper.readTree(expectedWarning), mapper.readTree(warning)); + + String deleteEntityResponse = api.deleteEntity(appUrl, entityName, createLinkEntity); + if (!deleteEntityResponse.equals("Entity Deleted")) { + fail("Entity draft not deleted"); + } + } }