From 8ea027b1a1fcfe74a601269f2eb78c7de40ea943 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Tue, 26 Nov 2024 12:29:05 +0100 Subject: [PATCH] add unit tests --- .../impl/metadata/ImsAccessTokenCache.java | 9 +- .../ngdm/impl/metadata/MetadataSample.java | 23 ++- ...etadataServiceImpl_ImsAccessTokenTest.java | 141 ++++++++++++++++++ 3 files changed, 162 insertions(+), 11 deletions(-) create mode 100644 src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/NextGenDynamicMediaMetadataServiceImpl_ImsAccessTokenTest.java diff --git a/src/main/java/io/wcm/handler/mediasource/ngdm/impl/metadata/ImsAccessTokenCache.java b/src/main/java/io/wcm/handler/mediasource/ngdm/impl/metadata/ImsAccessTokenCache.java index 46f5a6f3..dc54409c 100644 --- a/src/main/java/io/wcm/handler/mediasource/ngdm/impl/metadata/ImsAccessTokenCache.java +++ b/src/main/java/io/wcm/handler/mediasource/ngdm/impl/metadata/ImsAccessTokenCache.java @@ -92,7 +92,11 @@ public long expireAfterRead(String key, AccessTokenResponse value, long currentT */ public @Nullable String getAccessToken(@NotNull String clientId, @NotNull String clientSecret, @NotNull String scope) { String key = clientId + "::" + scope; - return tokenCache.get(key, k -> createAccessToken(clientId, clientSecret, scope)).accessToken; + AccessTokenResponse accessTokenResponse = tokenCache.get(key, k -> createAccessToken(clientId, clientSecret, scope)); + if (accessTokenResponse != null) { + return accessTokenResponse.accessToken; + } + return null; } private @Nullable AccessTokenResponse createAccessToken(@NotNull String clientId, @NotNull String clientSecret, @NotNull String scope) { @@ -123,9 +127,6 @@ public long expireAfterRead(String key, AccessTokenResponse value, long currentT log.trace("HTTP response for access token reqeust from {} returned a response, expires in {} sec", imsTokenApiUrl, accessTokenResponse.expiresInSec); return accessTokenResponse; - case HttpStatus.SC_NOT_FOUND: - log.trace("HTTP response for access token request from {} returns HTTP 404.", imsTokenApiUrl); - break; default: log.warn("Unexpected HTTP response for access token request from {}: {}", imsTokenApiUrl, response.getStatusLine()); break; diff --git a/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/MetadataSample.java b/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/MetadataSample.java index 422479c8..b8c95f36 100644 --- a/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/MetadataSample.java +++ b/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/MetadataSample.java @@ -66,13 +66,26 @@ public final class MetadataSample { + " }," + " \"assetMetadata\": {" + " \"dam:assetStatus\": \"approved\"," - + " \"dc:description\": \"Test Description\"," - + " \"dc:title\": \"Test Image\"," + " \"tiff:ImageLength\": 800," + " \"tiff:ImageWidth\": 1200" + " }" + "}"; + public static final String METADATA_JSON_IMAGE_FULL = "{" + + " \"assetId\": \"" + SAMPLE_ASSET_ID + "\"," + + " \"repositoryMetadata\": {" + + " \"repo:name\": \"test.jpg\"," + + " \"dc:format\": \"image/jpeg\"" + + " }," + + " \"assetMetadata\": {" + + " \"dam:assetStatus\": \"approved\"," + + " \"dc:description\": \"Test Description\"," + + " \"dc:title\": \"Test Image\"," + + " \"tiff:ImageLength\": 900," + + " \"tiff:ImageWidth\": 1500" + + " }" + + "}"; + public static final String METADATA_JSON_SVG = "{" + " \"assetId\": \"" + SAMPLE_ASSET_ID + "\"," + " \"repositoryMetadata\": {" @@ -81,8 +94,6 @@ public final class MetadataSample { + " }," + " \"assetMetadata\": {" + " \"dam:assetStatus\": \"approved\"," - + " \"dc:description\": \"Test Description\"," - + " \"dc:title\": \"Test Image\"," + " \"tiff:ImageLength\": 600," + " \"tiff:ImageWidth\": 900" + " }" @@ -95,9 +106,7 @@ public final class MetadataSample { + " \"dc:format\": \"application/pdf\"" + " }," + " \"assetMetadata\": {" - + " \"dam:assetStatus\": \"approved\"," - + " \"dc:description\": \"Test Description\"," - + " \"dc:title\": \"Test Document\"" + + " \"dam:assetStatus\": \"approved\"" + " }" + "}"; diff --git a/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/NextGenDynamicMediaMetadataServiceImpl_ImsAccessTokenTest.java b/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/NextGenDynamicMediaMetadataServiceImpl_ImsAccessTokenTest.java new file mode 100644 index 00000000..9ced04fc --- /dev/null +++ b/src/test/java/io/wcm/handler/mediasource/ngdm/impl/metadata/NextGenDynamicMediaMetadataServiceImpl_ImsAccessTokenTest.java @@ -0,0 +1,141 @@ +/* + * #%L + * wcm.io + * %% + * Copyright (C) 2024 wcm.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package io.wcm.handler.mediasource.ngdm.impl.metadata; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static io.wcm.handler.mediasource.ngdm.impl.NextGenDynamicMediaReferenceSample.SAMPLE_ASSET_ID; +import static io.wcm.handler.mediasource.ngdm.impl.NextGenDynamicMediaReferenceSample.SAMPLE_REFERENCE; +import static io.wcm.handler.mediasource.ngdm.impl.metadata.MetadataSample.METADATA_JSON_IMAGE; +import static io.wcm.handler.mediasource.ngdm.impl.metadata.MetadataSample.METADATA_JSON_IMAGE_FULL; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; +import com.github.tomakehurst.wiremock.junit5.WireMockTest; + +import io.wcm.handler.media.Dimension; +import io.wcm.handler.media.testcontext.AppAemContext; +import io.wcm.handler.mediasource.ngdm.impl.NextGenDynamicMediaConfigServiceImpl; +import io.wcm.handler.mediasource.ngdm.impl.NextGenDynamicMediaReference; +import io.wcm.testing.mock.aem.dam.ngdm.MockNextGenDynamicMediaConfig; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; +import io.wcm.wcm.commons.contenttype.ContentType; + +@ExtendWith(AemContextExtension.class) +@WireMockTest +class NextGenDynamicMediaMetadataServiceImpl_ImsAccessTokenTest { + + private static final NextGenDynamicMediaReference REFERENCE = NextGenDynamicMediaReference.fromReference(SAMPLE_REFERENCE); + + private static final String AUTHENTICATION_CLIENT_ID = "testClientId"; + private static final String AUTHENTICATION_CLIENT_SECRET = "testClientSecret"; + private static final String AUTHENTICATION_SCOPE = "testScope"; + private static final String ACCESS_TOKEN = "testToken"; + private static final long ACCESS_TOKEN_EXPIRES_SEC = 100; + + private static final String ACCESS_TOKEN_RESPONSE = "{" + + " \"access_token\": \"" + ACCESS_TOKEN + "\"," + + " \"token_type\": \"Bearer\"," + + " \"expires_in\": " + ACCESS_TOKEN_EXPIRES_SEC + + "}"; + + private final AemContext context = AppAemContext.newAemContext(); + + private NextGenDynamicMediaMetadataService underTest; + + @BeforeEach + void setUp(WireMockRuntimeInfo wmRuntimeInfo) { + context.registerInjectActivateService(MockNextGenDynamicMediaConfig.class) + .setRepositoryId("localhost:" + wmRuntimeInfo.getHttpPort()); + context.registerInjectActivateService(NextGenDynamicMediaConfigServiceImpl.class); + underTest = context.registerInjectActivateService(NextGenDynamicMediaMetadataServiceImpl.class, + "enabled", true, + "imsTokenApiUrl", "http://localhost:" + wmRuntimeInfo.getHttpPort() + "/ims/token/v3", + "authenticationClientId", AUTHENTICATION_CLIENT_ID, + "authenticationClientSecret", AUTHENTICATION_CLIENT_SECRET, + "authenticationScope", AUTHENTICATION_SCOPE); + + // without auth + stubFor(get("/adobe/assets/" + SAMPLE_ASSET_ID + "/metadata") + .willReturn(aResponse() + .withStatus(HttpStatus.SC_OK) + .withHeader("Content-Type", ContentType.JSON) + .withBody(METADATA_JSON_IMAGE))); + + // with auth + stubFor(get("/adobe/assets/" + SAMPLE_ASSET_ID + "/metadata") + .withHeader("Authorization", equalTo("Bearer " + ACCESS_TOKEN)) + .willReturn(aResponse() + .withStatus(HttpStatus.SC_OK) + .withHeader("Content-Type", ContentType.JSON) + .withBody(METADATA_JSON_IMAGE_FULL))); + } + + @Test + void testValidToken() { + stubFor(post("/ims/token/v3") + .withFormParam("grant_type", equalTo("client_credentials")) + .withFormParam("client_id", equalTo(AUTHENTICATION_CLIENT_ID)) + .withFormParam("client_secret", equalTo(AUTHENTICATION_CLIENT_SECRET)) + .withFormParam("scope", equalTo(AUTHENTICATION_SCOPE)) + .willReturn(aResponse() + .withStatus(HttpStatus.SC_OK) + .withHeader("Content-Type", ContentType.JSON) + .withBody(ACCESS_TOKEN_RESPONSE))); + + NextGenDynamicMediaMetadata metadata = underTest.fetchMetadata(REFERENCE); + assertNotNull(metadata); + Dimension dimension = metadata.getDimension(); + assertNotNull(dimension); + assertEquals(1500, dimension.getWidth()); + assertEquals(900, dimension.getHeight()); + assertEquals("image/jpeg", metadata.getMimeType()); + } + + @Test + void testInvalidToken_FallbackNoAuth() { + stubFor(post("/ims/token/v3") + .withFormParam("grant_type", equalTo("client_credentials")) + .withFormParam("client_id", equalTo(AUTHENTICATION_CLIENT_ID)) + .withFormParam("client_secret", equalTo(AUTHENTICATION_CLIENT_SECRET)) + .withFormParam("scope", equalTo(AUTHENTICATION_SCOPE)) + .willReturn(aResponse() + .withStatus(HttpStatus.SC_UNAUTHORIZED))); + + NextGenDynamicMediaMetadata metadata = underTest.fetchMetadata(REFERENCE); + assertNotNull(metadata); + Dimension dimension = metadata.getDimension(); + assertNotNull(dimension); + assertEquals(1200, dimension.getWidth()); + assertEquals(800, dimension.getHeight()); + assertEquals("image/jpeg", metadata.getMimeType()); + } + +}