From 7d4e463c1f2247c68b4ca13bee9fceb5481a46b8 Mon Sep 17 00:00:00 2001 From: Valentino Giardino <77643678+valentinogiardino@users.noreply.github.com> Date: Thu, 20 Feb 2025 11:41:20 -0300 Subject: [PATCH] fix(ftm): working version of a piece of content can be seen in live mode #31367 (#31431) ### Proposed Changes * Modified `ContentletLoader.java` to ensure the Live page always displays the published version of content, regardless of the Time Machine state. * Added new Karate tests to validate the behavior of future-published content, including cases with VTL code like banners. * Updated existing test scenarios to include banner content and additional edge cases. ### Checklist - [x] Tests - [x] Translations - [x] Security Implications Contemplated (add notes if applicable) ### Additional Info This PR addresses an issue where content authors editing content with future publish dates would see the working version on the Live page instead of the currently published version. The fix ensures that the Live page always displays the correct published content, even when future content is scheduled. --- .../velocity/services/ContentletLoader.java | 3 +- .../java/graphql/ftm/deleteFolder.feature | 12 + .../graphql/ftm/newBannerContentType.feature | 477 ++++++++++++++++++ .../java/graphql/ftm/newContainer.feature | 4 + .../java/graphql/ftm/newContentType.feature | 5 +- .../test/java/graphql/ftm/newFolder.feature | 12 + .../src/test/java/graphql/ftm/newVTL.feature | 29 ++ .../test/java/graphql/ftm/publishPage.feature | 5 + .../src/test/java/graphql/ftm/setup.feature | 23 +- .../src/test/java/resources/ftm/banner.vtl | 113 +++++ .../graphql/ftm/CheckingTimeMachine.feature | 62 ++- 11 files changed, 736 insertions(+), 9 deletions(-) create mode 100644 test-karate/src/test/java/graphql/ftm/deleteFolder.feature create mode 100644 test-karate/src/test/java/graphql/ftm/newBannerContentType.feature create mode 100644 test-karate/src/test/java/graphql/ftm/newFolder.feature create mode 100644 test-karate/src/test/java/graphql/ftm/newVTL.feature create mode 100644 test-karate/src/test/java/resources/ftm/banner.vtl diff --git a/dotCMS/src/main/java/com/dotcms/rendering/velocity/services/ContentletLoader.java b/dotCMS/src/main/java/com/dotcms/rendering/velocity/services/ContentletLoader.java index 67a29e49ac42..5e6209ac17b1 100644 --- a/dotCMS/src/main/java/com/dotcms/rendering/velocity/services/ContentletLoader.java +++ b/dotCMS/src/main/java/com/dotcms/rendering/velocity/services/ContentletLoader.java @@ -646,9 +646,8 @@ public InputStream writeObject(final VelocityResourceKey key) throw new ResourceNotFoundException("cannot find content version info for key: " + key); } - //if time machine is running, we need to force get the latest working version to guarantee the correct rendered content matching the json portion of the response final ContentletVersionInfo contentletVersionInfo = info.get(); - final String inode = (key.mode.showLive && TimeMachineUtil.isNotRunning() ) + final String inode = key.mode.showLive ? contentletVersionInfo.getLiveInode() : contentletVersionInfo.getWorkingInode(); diff --git a/test-karate/src/test/java/graphql/ftm/deleteFolder.feature b/test-karate/src/test/java/graphql/ftm/deleteFolder.feature new file mode 100644 index 000000000000..9554cce5e923 --- /dev/null +++ b/test-karate/src/test/java/graphql/ftm/deleteFolder.feature @@ -0,0 +1,12 @@ +Feature: Delete a Folder + Scenario: Delete a folder on the given path if exists + Given url baseUrl + '/api/v1/folder/default' + And headers commonHeaders + And request + """ + ["#(path)"] + """ + When method DELETE + Then status 200 + * def errors = call extractErrors response + * match errors == [] \ No newline at end of file diff --git a/test-karate/src/test/java/graphql/ftm/newBannerContentType.feature b/test-karate/src/test/java/graphql/ftm/newBannerContentType.feature new file mode 100644 index 000000000000..681b76a516d1 --- /dev/null +++ b/test-karate/src/test/java/graphql/ftm/newBannerContentType.feature @@ -0,0 +1,477 @@ +Feature: Create a Content Type + Background: + * def contentTypeVariable = 'Banner' + + Scenario: Create a content type and expect 200 OK + Given url baseUrl + '/api/v1/contenttype' + And headers commonHeaders + And request + """ + { + "baseType":"CONTENT", + "clazz":"com.dotcms.contenttype.model.type.ImmutableSimpleContentType", + "defaultType":false, + "description":"Hero image used on homepage and landing pages", + "expireDateVar":"expiredDate", + "fields":[ + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableRowField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldContentTypeProperties":[ + + ], + "fieldType":"Row", + "fieldTypeLabel":"Row", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1529965036000, + "id":"5dfdad46-49f4-450f-b66d-33460f645aaf", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"fields-0", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":0, + "unique":false, + "variable":"fields0" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableColumnField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldContentTypeProperties":[ + + ], + "fieldType":"Column", + "fieldTypeLabel":"Column", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1529965036000, + "id":"6ab3fec7-c46b-4c95-b6dd-6f9ea5e2826e", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"fields-1", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":1, + "unique":false, + "variable":"fields1" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableHostFolderField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldType":"Host-Folder", + "fieldTypeLabel":"Site or Folder", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1566840730000, + "id":"3e089676-778a-4f17-905f-7e6b707415b9", + "indexed":true, + "listed":false, + "modDate":1740007777000, + "name":"Host", + "readOnly":false, + "required":true, + "searchable":false, + "sortOrder":2, + "unique":false, + "variable":"host" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableTextField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"TEXT", + "fieldType":"Text", + "fieldTypeLabel":"Text", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1308941149000, + "id":"5c21daa4-1482-4bc9-9d61-04b42d35a6ee", + "indexed":true, + "listed":true, + "modDate":1740007777000, + "name":"Title", + "readOnly":false, + "regexCheck":"[^(<[.\\n]+>)]*", + "required":true, + "searchable":true, + "sortOrder":3, + "unique":false, + "variable":"title" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableCustomField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"LONG_TEXT", + "fieldType":"Custom-Field", + "fieldTypeLabel":"Custom Field", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1555426352000, + "id":"31eb3833-53e6-47cc-af45-221a42a3ebc5", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"styles", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":4, + "unique":false, + "values":"", + "variable":"styles" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableRowField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldContentTypeProperties":[ + + ], + "fieldType":"Row", + "fieldTypeLabel":"Row", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1555000294000, + "id":"b885d71b-2d6c-40ae-9351-b6d58f3c6704", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"fields-2", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":5, + "unique":false, + "variable":"fields9" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableColumnField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldContentTypeProperties":[ + + ], + "fieldType":"Column", + "fieldTypeLabel":"Column", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1555000294000, + "id":"92777b44-e53c-4635-b42a-2ce745d10d6c", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"fields-3", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":6, + "unique":false, + "variable":"fields10" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableCustomField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"LONG_TEXT", + "defaultValue":"1", + "fieldType":"Custom-Field", + "fieldTypeLabel":"Custom Field", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1412016703000, + "id":"c4712e56-ec64-4795-8613-63dff910b34e", + "indexed":true, + "listed":true, + "modDate":1740007777000, + "name":"Layout", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":7, + "unique":false, + "values":"##banner-layout.vtl\r\n#dotParse(\"/dA/54c1cb5e96ca7f179a9d4ce0056c1ee2\")", + "variable":"layout" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableTextField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"TEXT", + "fieldType":"Text", + "fieldTypeLabel":"Text", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1582137456000, + "id":"0eeef3b4-7fc2-45d3-9fda-c99c5b016374", + "indexed":true, + "listed":true, + "modDate":1740007777000, + "name":"Caption", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":8, + "unique":false, + "variable":"caption" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableTextField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"TEXT", + "fieldType":"Text", + "fieldTypeLabel":"Text", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1562795494000, + "id":"814af473-c03d-446d-8609-f82b0d67b7c3", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"Button Text", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":9, + "unique":false, + "variable":"buttonText" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableTextField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"TEXT", + "fieldType":"Text", + "fieldTypeLabel":"Text", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1562795510000, + "id":"f959784b-b2e7-4a09-b004-fe3e67e5fbd6", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"Link", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":10, + "unique":false, + "variable":"link" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableCustomField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"LONG_TEXT", + "defaultValue":"#FFFFFF", + "fieldType":"Custom-Field", + "fieldTypeLabel":"Custom Field", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1555001286000, + "id":"9d859b44-18c5-4b3c-b077-e812a945f255", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"Text Color", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":11, + "unique":false, + "values":"##SET FIELD VARIABLE NAME TO APPLY PICKER TO\r\n\r\n#set($fieldName = \"textColor\")\r\n\r\n##color-picker.vtl\r\n#dotParse(\"/dA/7f494f7ea2cb44717baac7004d974c52\")", + "variable":"textColor" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableTagField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldType":"Tag", + "fieldTypeLabel":"Tag", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1567533022000, + "id":"27499ccb-1bbb-4c02-ab91-c11e01f58ac7", + "indexed":true, + "listed":false, + "modDate":1740007777000, + "name":"Tags", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":12, + "unique":false, + "variable":"tags" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableColumnField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"SYSTEM", + "fieldContentTypeProperties":[ + + ], + "fieldType":"Column", + "fieldTypeLabel":"Column", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1555000294000, + "id":"f735c683-f05e-4138-8056-73d76e80b1aa", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"fields-4", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":13, + "unique":false, + "variable":"fields11" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableImageField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"TEXT", + "fieldType":"Image", + "fieldTypeLabel":"Image", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1717082944000, + "id":"13bf66791d690a89ca05171ecdd5f71c", + "indexed":false, + "listed":false, + "modDate":1740007777000, + "name":"Image", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":14, + "unique":false, + "variable":"image" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableDateTimeField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"DATE", + "fieldType":"Date-and-Time", + "fieldTypeLabel":"Date and Time", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1739980935000, + "id":"492fea0d7e7f1dd4a34af18fca2ed9ab", + "indexed":true, + "listed":false, + "modDate":1740007777000, + "name":"publish date", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":15, + "unique":false, + "variable":"publishDate" + }, + { + "clazz":"com.dotcms.contenttype.model.field.ImmutableDateTimeField", + "contentTypeId":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "dataType":"DATE", + "fieldType":"Date-and-Time", + "fieldTypeLabel":"Date and Time", + "fieldVariables":[ + + ], + "fixed":false, + "forceIncludeInApi":false, + "iDate":1739980959000, + "id":"487af50492627a9b95a49f35253a0dff", + "indexed":true, + "listed":false, + "modDate":1740007777000, + "name":"expired date", + "readOnly":false, + "required":false, + "searchable":false, + "sortOrder":16, + "unique":false, + "variable":"expiredDate" + } + ], + "fixed":false, + "folder":"SYSTEM_FOLDER", + "folderPath":"/", + "host":"SYSTEM_HOST", + "iDate":1489086945734, + "icon":"image_aspect_ratio", + "id":"4c441ada-944a-43af-a653-9bb4f3f0cb2b", + "metadata":{ + "CONTENT_EDITOR2_ENABLED":false + }, + "modDate":1740007777000, + "multilingualable":false, + "name":"Banner", + "publishDateVar":"publishDate", + "siteName":"systemHost", + "sortOrder":0, + "system":false, + "systemActionMappings":{ + + }, + "variable":"#(contentTypeVariable)", + "versionable":true, + "workflow":[ + "d61a59e1-a49c-46f2-a929-db2b4bfa88b2" + ] + } + """ + When method POST + Then status 200 + And match response.entity[0].id != null + And match response.entity[0].variable == contentTypeVariable \ No newline at end of file diff --git a/test-karate/src/test/java/graphql/ftm/newContainer.feature b/test-karate/src/test/java/graphql/ftm/newContainer.feature index 47d6d8212e1c..ebbd6e969afb 100644 --- a/test-karate/src/test/java/graphql/ftm/newContainer.feature +++ b/test-karate/src/test/java/graphql/ftm/newContainer.feature @@ -16,6 +16,10 @@ Feature: Create a Container { "structureId":"#(contentTypeId)", "code":"
$!{dotContentMap.title}
" + }, + { + "structureId":"#(bannerContentTypeId)", + "code":"#dotParse(\"//default/application/containers/banner/banner.vtl\")" } ] } diff --git a/test-karate/src/test/java/graphql/ftm/newContentType.feature b/test-karate/src/test/java/graphql/ftm/newContentType.feature index cba1f9b210ff..3450823d9b6b 100644 --- a/test-karate/src/test/java/graphql/ftm/newContentType.feature +++ b/test-karate/src/test/java/graphql/ftm/newContentType.feature @@ -106,10 +106,7 @@ Feature: Create a Content Type "system":false, "variable":"#(contentTypeVariable)", "versionable":true, - "workflows" : [ { - "id" : "d61a59e1-a49c-46f2-a929-db2b4bfa88b2", - "variableName" : "SystemWorkflow" - } ] + "workflows" : ["d61a59e1-a49c-46f2-a929-db2b4bfa88b2"] } """ When method POST diff --git a/test-karate/src/test/java/graphql/ftm/newFolder.feature b/test-karate/src/test/java/graphql/ftm/newFolder.feature new file mode 100644 index 000000000000..6a2c926c3e83 --- /dev/null +++ b/test-karate/src/test/java/graphql/ftm/newFolder.feature @@ -0,0 +1,12 @@ +Feature: Create a Folder + Scenario: Create a new folder on the given path + Given url baseUrl + '/api/v1/folder/createfolders/default' + And headers commonHeaders + And request + """ + ["#(path)"] + """ + When method POST + Then status 200 + * def errors = call extractErrors response + * match errors == [] \ No newline at end of file diff --git a/test-karate/src/test/java/graphql/ftm/newVTL.feature b/test-karate/src/test/java/graphql/ftm/newVTL.feature new file mode 100644 index 000000000000..8612625f35b5 --- /dev/null +++ b/test-karate/src/test/java/graphql/ftm/newVTL.feature @@ -0,0 +1,29 @@ + Feature: Create a Page + Background: + + * def fileName = __arg.fileName + * def folderidentifier = __arg.folderidentifier + * def jsonPayload = + """ + { + "contentlet": { + "contentType": "FileAsset", + "title": '#(fileName)', + "fileName": '#(fileName)', + "hostFolder": '#(folderidentifier)' + } + } + """ + * def filePath = 'classpath:resources/ftm/' + fileName + + Scenario: Fire PUBLISH action with a file upload + Given url baseUrl + '/api/v1/workflow/actions/default/fire/PUBLISH' + And headers commonHeaders + And header Content-Type = 'multipart/form-data' + And header Accept = '*/*' + And multipart file file = { read: '#(filePath)', contentType: 'application/json'} + And multipart file json = { value: '#(jsonPayload)', contentType: 'application/json'} + When method PUT + Then status 200 + * def errors = call extractErrors response + * match errors == [] \ No newline at end of file diff --git a/test-karate/src/test/java/graphql/ftm/publishPage.feature b/test-karate/src/test/java/graphql/ftm/publishPage.feature index 674ab757fde8..baf3effa915c 100644 --- a/test-karate/src/test/java/graphql/ftm/publishPage.feature +++ b/test-karate/src/test/java/graphql/ftm/publishPage.feature @@ -11,6 +11,11 @@ Feature: Add pieces of content then Publish the Page And request """ [ + { + "contentletsId": "#(banner_content_ids)", + "identifier": "#(container_id)", + "uuid": "1" + }, { "contentletsId": "#(content_ids)", "identifier": "#(container_id)", diff --git a/test-karate/src/test/java/graphql/ftm/setup.feature b/test-karate/src/test/java/graphql/ftm/setup.feature index 1415993a67b7..27f7572eadc8 100644 --- a/test-karate/src/test/java/graphql/ftm/setup.feature +++ b/test-karate/src/test/java/graphql/ftm/setup.feature @@ -4,13 +4,24 @@ Feature: Setting up the Future Time Machine Test * callonce read('classpath:graphql/ftm/helpers.feature') # Make the prefix available to the scenario # Setup required data + * callonce read('classpath:graphql/ftm/deleteFolder.feature') { path: '/application/containers/banner' } + * def follderIdentifierResult = callonce read('classpath:graphql/ftm/newFolder.feature') { path: '/application/containers/banner' } + * def folderIdentifier = follderIdentifierResult.response.entity[0].identifier + * karate.log('Folder Identifier ::', folderIdentifier) + + * callonce read('classpath:graphql/ftm/newVTL.feature') { fileName: 'banner.vtl', folderidentifier: '#(folderIdentifier)' } + # Lets start by creating a new content type, container, template and publish the template # First the Content Type * def contentTypeResult = callonce read('classpath:graphql/ftm/newContentType.feature') * def contentTypeId = contentTypeResult.response.entity[0].id * def contentTypeVariable = contentTypeResult.response.entity[0].variable + + * def bannerContentTypeResult = callonce read('classpath:graphql/ftm/newBannerContentType.feature') + * def bannerContentTypeId = bannerContentTypeResult.response.entity[0].id + # Now the container, template and publish the template - * def containerResult = callonce read('classpath:graphql/ftm/newContainer.feature') { contentTypeId: '#(contentTypeId)' } + * def containerResult = callonce read('classpath:graphql/ftm/newContainer.feature') { contentTypeId: '#(contentTypeId)', bannerContentTypeId: '#(bannerContentTypeId)' } * def containerId = containerResult.response.entity.identifier * def templateResult = callonce read('classpath:graphql/ftm/newTemplate.feature') { containerId: '#(containerId)' } * def templateId = templateResult.response.entity.identifier @@ -27,14 +38,22 @@ Feature: Setting up the Future Time Machine Test * def contentPieceTwoId = contentPieceTwo.map(result => Object.keys(result)[0]) * def contentPieceTwoId = contentPieceTwoId[0] + # Create a couple of new pieces of content + * def createBannerContentPieceOneResult = callonce read('classpath:graphql/ftm/newContent.feature') { contentTypeId: '#(bannerContentTypeId)', title: 'banner 1'} + * def bannerContentPieceOne = createBannerContentPieceOneResult.response.entity.results + * def bannerContentPieceOneId = bannerContentPieceOne.map(result => Object.keys(result)[0]) + * def bannerContentPieceOneId = bannerContentPieceOneId[0] + # Now lets create a new version for each piece of content * def formatter = java.time.format.DateTimeFormatter.ofPattern('yyyy-MM-dd') * def now = java.time.LocalDateTime.now() + * def formattedCurrentDateTime = now.format(formatter) * def futureDateTime = now.plusDays(10) * def formattedFutureDateTime = futureDateTime.format(formatter) * def newContentPiceOneVersion2 = callonce read('classpath:graphql/ftm/newContentVersion.feature') { contentTypeId: '#(contentTypeId)', identifier: '#(contentPieceOneId)', title: 'test 1 v2 (This ver will be publshed in the future)', publishDate: '#(formattedFutureDateTime)' } * def newContentPiceTwoVersion2 = callonce read('classpath:graphql/ftm/newContentVersion.feature') { contentTypeId: '#(contentTypeId)', identifier: '#(contentPieceTwoId)', title: 'test 2 v2' } + * def newContentBannerOneVersion2 = callonce read('classpath:graphql/ftm/newContentVersion.feature') { contentTypeId: '#(bannerContentTypeId)', identifier: '#(bannerContentPieceOneId)', title: 'banner 1 v2', publishDate: '#(formattedFutureDateTime)' } # Lets create a new non-published piece of content wiht a publish date in the future * def nonPublishedPieceResult = callonce read('classpath:graphql/ftm/newContent.feature') { contentTypeId: '#(contentTypeId)', title: 'Working version Only! with publish date', publishDate: '#(formattedFutureDateTime)', action: 'NEW' } @@ -53,7 +72,7 @@ Feature: Setting up the Future Time Machine Test * def pageId = pageId[0] # Now lets add the pieces of content to the page - * def publishPageResult = callonce read('classpath:graphql/ftm/publishPage.feature') { page_id: '#(pageId)', content_ids: ['#(contentPieceOneId)', '#(contentPieceTwoId)', '#(nonPublishedPieceId)'], container_id: '#(containerId)' } + * def publishPageResult = callonce read('classpath:graphql/ftm/publishPage.feature') { page_id: '#(pageId)', banner_content_ids: ['#(bannerContentPieceOneId)'], content_ids: ['#(contentPieceOneId)', '#(contentPieceTwoId)', '#(nonPublishedPieceId)'], container_id: '#(containerId)' } * karate.log('Page created and Published ::', pageUrl) diff --git a/test-karate/src/test/java/resources/ftm/banner.vtl b/test-karate/src/test/java/resources/ftm/banner.vtl new file mode 100644 index 000000000000..4d7f990be4e7 --- /dev/null +++ b/test-karate/src/test/java/resources/ftm/banner.vtl @@ -0,0 +1,113 @@ + +#set($imageURL = "/dA/"+$dotContentMap.identifier+"/image/1200maxw/1200cw/570ch/80q/13ro/"+$dotContentMap.image.name) +#if($layout == 1) +
+
+
+
+ +

+ + $!{caption} + + + +

+ + #if($UtilMethods.isSet($link) && $UtilMethods.isSet($buttonText)) + + #end +
+
+
+
+#elseif($layout == 2) +
+
+
+
+
+ +

+ + $!{caption} + + + +

+ #if($UtilMethods.isSet($link) && $UtilMethods.isSet($buttonText)) + + #end +
+
+
+
+
+#elseif($layout == 3) + +#else +
+
+
+
+
+ +

+ + $!{caption} + + + +

+ #if($UtilMethods.isSet($link) && $UtilMethods.isSet($buttonText)) + + #end +
+
+
+
+
+#end \ No newline at end of file diff --git a/test-karate/src/test/java/tests/graphql/ftm/CheckingTimeMachine.feature b/test-karate/src/test/java/tests/graphql/ftm/CheckingTimeMachine.feature index 5f84444a0526..f1bee028fbae 100644 --- a/test-karate/src/test/java/tests/graphql/ftm/CheckingTimeMachine.feature +++ b/test-karate/src/test/java/tests/graphql/ftm/CheckingTimeMachine.feature @@ -5,6 +5,9 @@ Feature: Test Time Machine functionality * def CONTENTLET_ONE_V1 = 'test 1' * def CONTENTLET_ONE_V2 = 'test 1 v2 (This ver will be publshed in the future)' * def CONTENTLET_TWO_V2 = 'test 2 v2' + * def BANNER_CONTENTLET_ONE_V1 = 'banner 1' + * def BANNER_CONTENTLET_ONE_V2 = 'banner 1 v2' + * def NON_PUBLISHED_CONTENTLET = 'Working version Only! with publish date' * callonce read('classpath:graphql/ftm/setup.feature') @@ -20,12 +23,57 @@ Feature: Test Time Machine functionality * match titles contains CONTENTLET_ONE_V1 # This is the second version of the content, This one is already published therefore it should be displayed * match titles contains CONTENTLET_TWO_V2 + # This is the first version of the banner content which is already published therefore it should be displayed + * match titles contains BANNER_CONTENTLET_ONE_V1 + + * match titles !contains CONTENTLET_ONE_V2 + * match titles !contains NON_PUBLISHED_CONTENTLET + * match titles !contains BANNER_CONTENTLET_ONE_V2 + * karate.log('pageContents:', pageContents) # Check the rendered page. The same items included as contentlets should be displayed here too * def rendered = response.entity.page.rendered * karate.log('rendered:', rendered) * match rendered contains CONTENTLET_ONE_V1 * match rendered contains CONTENTLET_TWO_V2 + * match rendered contains BANNER_CONTENTLET_ONE_V1 + + * match rendered !contains NON_PUBLISHED_CONTENTLET + * match rendered !contains CONTENTLET_ONE_V2 + * match rendered !contains BANNER_CONTENTLET_ONE_V2 + + + @smoke @positive @ftm + Scenario: Test Time Machine functionality when publish date is provided with current date + Given url baseUrl + '/api/v1/page/render/'+pageUrl+'?language_id=1&mode=LIVE&publishDate='+formattedCurrentDateTime + And headers commonHeaders + When method GET + Then status 200 + * def pageContents = extractContentlets (response) + * def titles = pageContents.map(x => x.title) + # This is the first version of the content, test 1 v2 as the title says it will be published in the future + * match titles contains CONTENTLET_ONE_V1 + # This is the second version of the content, This one is already published therefore it should be displayed + * match titles contains CONTENTLET_TWO_V2 + # This is the first version of the banner content which is already published therefore it should be displayed + * match titles contains BANNER_CONTENTLET_ONE_V1 + + * match titles !contains CONTENTLET_ONE_V2 + * match titles !contains NON_PUBLISHED_CONTENTLET + * match titles !contains BANNER_CONTENTLET_ONE_V2 + + * karate.log('pageContents:', pageContents) + # Check the rendered page. The same items included as contentlets should be displayed here too + * def rendered = response.entity.page.rendered + * karate.log('rendered:', rendered) + * match rendered contains CONTENTLET_ONE_V1 + * match rendered contains CONTENTLET_TWO_V2 + * match rendered contains BANNER_CONTENTLET_ONE_V1 + + * match rendered !contains CONTENTLET_ONE_V2 + * match rendered !contains NON_PUBLISHED_CONTENTLET + * match rendered !contains BANNER_CONTENTLET_ONE_V2 + @positive @ftm Scenario: Test Time Machine functionality when a publish date is provided expect the future content to be displayed @@ -39,11 +87,23 @@ Feature: Test Time Machine functionality * def titles = pageContents.map(x => x.title) * match titles contains CONTENTLET_ONE_V2 * match titles contains CONTENTLET_TWO_V2 - * def rendered = response.entity.page.rendered + * match titles contains NON_PUBLISHED_CONTENTLET + * match titles contains BANNER_CONTENTLET_ONE_V2 + + * match titles !contains CONTENTLET_ONE_V1 + * match titles !contains BANNER_CONTENTLET_ONE_V1 + + * karate.log('pageContents:', pageContents) # Check the rendered page. The same items included as contentlets should be displayed here too + * def rendered = response.entity.page.rendered + * karate.log('rendered:', rendered) * match rendered contains CONTENTLET_ONE_V2 * match rendered contains CONTENTLET_TWO_V2 + * match rendered contains NON_PUBLISHED_CONTENTLET + + * match rendered contains BANNER_CONTENTLET_ONE_V2 + @smoke @positive @graphql @ftm Scenario: Send GraphQL query to fetch page details no publish date is sent * def graphQLRequestPayLoad = buildGraphQLRequestPayload (pageUrl)