From 46c81f99a63a12658b8d0668fbb9f2bce7cf451f Mon Sep 17 00:00:00 2001 From: Sofien Haj Chedhli Date: Tue, 16 Apr 2024 11:33:49 +0100 Subject: [PATCH] feat: Implement update draft for existing article service layer - EXO-70381 - Meeds-io/MIPs#119 (#15) (#16) --- .../news/service/impl/NewsServiceImpl.java | 87 ++++++++++++++++++- .../service/impl/NewsServiceImplTest.java | 74 ++++++++++++++++ 2 files changed, 158 insertions(+), 3 deletions(-) diff --git a/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java b/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java index 986f3c2d6..0813da09f 100644 --- a/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java +++ b/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java @@ -279,9 +279,9 @@ public News updateNews(News news, String updater, Boolean post, boolean publish, Set previousMentions = NewsUtils.processMentions(originalNews.getOriginalBody(), spaceService.getSpaceById(news.getSpaceId())); if (NewsObjectType.DRAFT.name().toLowerCase().equals(newsObjectType)) { - news = updateDraftArticleForNewPage(news, updater); + return updateDraftArticleForNewPage(news, updater); } else if (LATEST_DRAFT.name().toLowerCase().equals(newsObjectType)) { - news = createOrUpdateDraftForExistingPage(news, updater); + return createOrUpdateDraftForExistingPage(news, updater); } else if (ARTICLE.name().toLowerCase().equals(newsObjectType)) { // TODO } @@ -1551,7 +1551,7 @@ private News createOrUpdateDraftForExistingPage(News news, String updater) throw if (draftPage == null) { news = createDraftForExistingPage(news, updater, existingPage); } else { - // TODO update draft for existing page + news = updateDraftForExistingPage(news, updater, existingPage, draftPage); } return news; } @@ -1591,11 +1591,13 @@ private News createDraftForExistingPage(News news, String updater, Page page) th .get(0); boolean hasIllustration = false; Long oldIllustrationId = null; + String oldIllustrationUploadId = null; if (metadataItem != null && metadataItem.getProperties() != null && !metadataItem.getProperties().isEmpty()) { hasIllustration = metadataItem.getProperties().containsKey(NEWS_ILLUSTRATION_ID) && StringUtils.isNotEmpty(metadataItem.getProperties().get(NEWS_ILLUSTRATION_ID)); if (hasIllustration) { oldIllustrationId = Long.parseLong(metadataItem.getProperties().get(NEWS_ILLUSTRATION_ID)); + oldIllustrationUploadId = metadataItem.getProperties().get(NEWS_UPLOAD_ID); } } if (StringUtils.isNotEmpty(news.getUploadId())) { @@ -1603,11 +1605,13 @@ private News createDraftForExistingPage(News news, String updater, Page page) th Long newIllustrationId = saveArticleIllustration(news.getUploadId(), null); if (newIllustrationId != null) { draftArticleMetadataItemProperties.put(NEWS_ILLUSTRATION_ID, String.valueOf(newIllustrationId)); + draftArticleMetadataItemProperties.put(NEWS_UPLOAD_ID, news.getUploadId()); setArticleIllustration(news, newIllustrationId, NewsObjectType.DRAFT.name().toLowerCase()); } } else if (news.getUploadId() == null && hasIllustration) { // link the illustration to the newly created draft draftArticleMetadataItemProperties.put(NEWS_ILLUSTRATION_ID, String.valueOf(oldIllustrationId)); + draftArticleMetadataItemProperties.put(NEWS_UPLOAD_ID, oldIllustrationUploadId); setArticleIllustration(news, oldIllustrationId, NewsObjectType.DRAFT.name().toLowerCase()); } } @@ -1615,6 +1619,83 @@ private News createDraftForExistingPage(News news, String updater, Page page) th return news; } + private News updateDraftForExistingPage(News news, String updater, Page page, DraftPage draftPage) { + try { + draftPage.setTitle(news.getTitle()); + draftPage.setContent(news.getBody()); + draftPage.setAuthor(news.getAuthor()); + draftPage.setTargetPageId(page.getId()); + draftPage.setLang(null); + + draftPage = noteService.updateDraftForExistPage(draftPage, page, null, System.currentTimeMillis(), updater); + + news.setDraftUpdateDate(draftPage.getUpdatedDate()); + news.setDraftUpdater(draftPage.getAuthor()); + + NewsLatestDraftObject latestDraftObject = new NewsLatestDraftObject(NEWS_METADATA_LATEST_DRAFT_OBJECT_TYPE, + draftPage.getId(), + page.getId()); + + List latestDraftArticleMetadataItems = + metadataService.getMetadataItemsByMetadataAndObject(NEWS_METADATA_KEY, + latestDraftObject); + if (latestDraftArticleMetadataItems != null && !latestDraftArticleMetadataItems.isEmpty()) { + MetadataItem latestDraftArticleMetadataItem = latestDraftArticleMetadataItems.get(0); + Map latestDraftArticleMetadataItemProperties = latestDraftArticleMetadataItem.getProperties(); + if (latestDraftArticleMetadataItemProperties == null) { + latestDraftArticleMetadataItemProperties = new HashMap<>(); + } + // create or update the illustration + if (StringUtils.isNotEmpty(news.getUploadId())) { + // update the illustration if exist + if (latestDraftArticleMetadataItemProperties.containsKey(NEWS_UPLOAD_ID) + && latestDraftArticleMetadataItemProperties.get(NEWS_UPLOAD_ID) != null + && latestDraftArticleMetadataItemProperties.containsKey(NEWS_ILLUSTRATION_ID) + && latestDraftArticleMetadataItemProperties.get(NEWS_ILLUSTRATION_ID) != null) { + if (!latestDraftArticleMetadataItemProperties.get(NEWS_UPLOAD_ID).equals(news.getUploadId())) { + FileItem draftArticleIllustrationFileItem = + fileService.getFile(Long.parseLong(latestDraftArticleMetadataItemProperties.get(NEWS_ILLUSTRATION_ID))); + Long draftArticleIllustrationId = saveArticleIllustration(news.getUploadId(), + draftArticleIllustrationFileItem.getFileInfo().getId()); + latestDraftArticleMetadataItemProperties.put(NEWS_ILLUSTRATION_ID, String.valueOf(draftArticleIllustrationId)); + setArticleIllustration(news, draftArticleIllustrationId, NewsObjectType.DRAFT.name()); + } + } else { + // create the illustration if not exist + Long draftArticleIllustrationId = saveArticleIllustration(news.getUploadId(), null); + latestDraftArticleMetadataItemProperties.put(NEWS_ILLUSTRATION_ID, String.valueOf(draftArticleIllustrationId)); + latestDraftArticleMetadataItemProperties.put(NEWS_UPLOAD_ID, news.getUploadId()); + setArticleIllustration(news, draftArticleIllustrationId, NewsObjectType.DRAFT.name()); + } + latestDraftArticleMetadataItemProperties.put(NEWS_UPLOAD_ID, news.getUploadId()); + } else { + // if the upload id is empty we should remove the existing illustration + if (latestDraftArticleMetadataItemProperties.containsKey(NEWS_ILLUSTRATION_ID) + && latestDraftArticleMetadataItemProperties.get(NEWS_ILLUSTRATION_ID) != null && news.getUploadId() != null) { + latestDraftArticleMetadataItemProperties.remove(NEWS_UPLOAD_ID); + FileItem draftArticleIllustrationFileItem = + fileService.getFile(Long.parseLong(latestDraftArticleMetadataItemProperties.get(NEWS_ILLUSTRATION_ID))); + latestDraftArticleMetadataItemProperties.remove(NEWS_ILLUSTRATION_ID); + + fileService.deleteFile(draftArticleIllustrationFileItem.getFileInfo().getId()); + } + } + if (StringUtils.isNotEmpty(news.getSummary())) { + latestDraftArticleMetadataItemProperties.put(NEWS_SUMMARY, news.getSummary()); + } + latestDraftArticleMetadataItem.setProperties(latestDraftArticleMetadataItemProperties); + String draftArticleMetadataItemUpdaterIdentityId = identityManager.getOrCreateUserIdentity(updater).getId(); + metadataService.updateMetadataItem(latestDraftArticleMetadataItem, Long.parseLong(draftArticleMetadataItemUpdaterIdentityId)); + } else { + throw new ObjectNotFoundException("No metadata item found for the draft " + news.getId()); + } + } catch (Exception exception) { + return null; + } + return news; + } + + private News buildLatestDraftArticle(String parentPageId, String currentIdentityId) throws Exception { Page parentPage = noteService.getNoteById(parentPageId); if (parentPage == null) { diff --git a/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java b/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java index ce17e1f43..620ef841c 100644 --- a/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java +++ b/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java @@ -596,4 +596,78 @@ public void testCreateDraftArticleForExistingPage() throws Exception { verify(metadataService, times(1)).createMetadataItem(any(NewsLatestDraftObject.class), any(MetadataKey.class), any(Map.class)); } + + @Test + public void testUpdateDraftArticleForExistingPage() throws Exception { + // Given + Page existingPage = mock(Page.class); + when(noteService.getNoteById(anyString())).thenReturn(existingPage); + when(existingPage.getId()).thenReturn("1"); + when(existingPage.getWikiOwner()).thenReturn("/space/groupId"); + + MetadataItem metadataItem = mock(MetadataItem.class); + List metadataItems = new ArrayList<>(); + metadataItems.add(metadataItem); + when(metadataService.getMetadataItemsByMetadataAndObject(any(MetadataKey.class), + any(MetadataObject.class))).thenReturn(metadataItems); + Map properties = new HashMap<>(); + when(metadataItem.getProperties()).thenReturn(properties); + + Space space = mock(Space.class); + when(space.getId()).thenReturn("1"); + when(space.getGroupId()).thenReturn("/space/groupId"); + when(space.getAvatarUrl()).thenReturn("space/avatar/url"); + when(space.getDisplayName()).thenReturn("spaceDisplayName"); + when(space.getVisibility()).thenReturn("public"); + when(spaceService.isSuperManager(anyString())).thenReturn(true); + when(spaceService.getSpaceById(any())).thenReturn(space); + when(spaceService.getSpaceByGroupId(anyString())).thenReturn(space); + + Identity identity = mock(Identity.class); + when(identity.getUserId()).thenReturn("john"); + NEWS_UTILS.when(()-> NewsUtils.getUserIdentity(anyString())).thenReturn(identity); + NEWS_UTILS.when(()-> NewsUtils.canPublishNews(anyString(), any(Identity.class))).thenReturn(false); + NEWS_UTILS.when(()-> NewsUtils.processMentions(anyString(), any())).thenReturn(new HashSet<>()); + when(newsTargetingService.getTargetsByNewsId(anyString())).thenReturn(null); + + DraftPage draftPage = mock(DraftPage.class); + when(draftPage.getUpdatedDate()).thenReturn(new Date()); + when(draftPage.getCreatedDate()).thenReturn(new Date()); + when(draftPage.getAuthor()).thenReturn("john"); + when(draftPage.getId()).thenReturn("1"); + when(draftPage.getContent()).thenReturn("body"); + when(draftPage.getWikiOwner()).thenReturn("/space/groupId"); + when(noteService.getDraftNoteById(anyString(), anyString())).thenReturn(draftPage); + when(noteService.getLatestDraftPageByUserAndTargetPageAndLang(anyLong(), anyString(), nullable(String.class))).thenReturn(draftPage); + + News news = new News(); + news.setAuthor("john"); + news.setTitle("new draft title"); + news.setBody("draft body"); + news.setId("1"); + news.setPublicationState("draft"); + news.setSpaceId("1"); + news.setSummary("news summary"); + news.setOriginalBody("body"); + + // When, Then + assertThrows(IllegalArgumentException.class, () -> newsService.updateNews(news, "john", false, false, "draft")); + + // Given + when(spaceService.canRedactOnSpace(space, identity)).thenReturn(true); + when(spaceService.isSuperManager(anyString())).thenReturn(true); + org.exoplatform.social.core.identity.model.Identity identity1 = mock(org.exoplatform.social.core.identity.model.Identity.class); + when(identityManager.getOrCreateUserIdentity(anyString())).thenReturn(identity1); + when(identity1.getId()).thenReturn("1"); + + when(noteService.updateDraftForExistPage(any(DraftPage.class), any(Page.class), nullable(String.class), anyLong(), anyString())).thenReturn(draftPage); + + // When + newsService.updateNews(news, "john", false, false, "latest_draft"); + + // Then + verify(noteService, times(1)).updateDraftForExistPage(any(DraftPage.class), eq(existingPage), nullable(String.class), anyLong(), anyString()); + verify(metadataService, times(1)).updateMetadataItem(any(MetadataItem.class), anyLong()); + } + }