diff --git a/pom.xml b/pom.xml index fd7ffd3..07732a6 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ 17 17 - 7.3.0-0c9c5b24fe + 7.4.7-1876cb3a4a jar @@ -38,6 +38,17 @@ true + + + + org.junit + junit-bom + 5.10.2 + pom + import + + + @@ -45,45 +56,44 @@ uid2-shared ${uid2-shared.version} + + com.fasterxml.jackson.core + jackson-databind + 2.14.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.14.2 + + + com.uid2 + uid2-client + 4.3.2-479d2cb58f + org.assertj assertj-core - 3.24.2 + 3.25.2 test org.junit.jupiter junit-jupiter - 5.9.2 test org.junit.platform junit-platform-suite - 1.9.2 + 1.10.1 test com.squareup.okhttp3 okhttp - 4.10.0 + 4.12.0 test - - com.fasterxml.jackson.core - jackson-databind - 2.14.2 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - 2.14.2 - - - com.uid2 - uid2-client - 4.3.0-3f9bbbefc8 - diff --git a/src/test/java/app/component/Operator.java b/src/test/java/app/component/Operator.java index d416037..3638a28 100644 --- a/src/test/java/app/component/Operator.java +++ b/src/test/java/app/component/Operator.java @@ -136,6 +136,14 @@ public JsonNode v0TokenRefresh(String token) throws Exception { return Mapper.OBJECT_MAPPER.readTree(response); } + public JsonNode v0CheckedTokenRefresh(String token) { + try { + return v0TokenRefresh(token); + } catch (Exception e) { + return Mapper.OBJECT_MAPPER.createObjectNode(); + } + } + public JsonNode v0TokenValidate(String type, String identity, String advertisingToken) throws Exception { String response = HttpClient.get(getBaseUrl() + "/token/validate?" + type + "=" + URLEncoder.encode(identity, StandardCharsets.UTF_8) + "&token=" + URLEncoder.encode(advertisingToken, StandardCharsets.UTF_8), CLIENT_API_KEY); return Mapper.OBJECT_MAPPER.readTree(response); @@ -163,6 +171,14 @@ public JsonNode v1TokenRefresh(String token) throws Exception { return Mapper.OBJECT_MAPPER.readTree(response); } + public JsonNode v1CheckedTokenRefresh(String token) { + try { + return v1TokenRefresh(token); + } catch (Exception e) { + return Mapper.OBJECT_MAPPER.createObjectNode(); + } + } + public JsonNode v1TokenValidate(String type, String identity, String advertisingToken) throws Exception { String response = HttpClient.get(getBaseUrl() + "/v1/token/validate?" + type + "=" + URLEncoder.encode(identity, StandardCharsets.UTF_8) + "&token=" + URLEncoder.encode(advertisingToken, StandardCharsets.UTF_8), CLIENT_API_KEY); return Mapper.OBJECT_MAPPER.readTree(response); diff --git a/src/test/java/app/component/Optout.java b/src/test/java/app/component/Optout.java index b8b54dc..6926333 100644 --- a/src/test/java/app/component/Optout.java +++ b/src/test/java/app/component/Optout.java @@ -6,9 +6,9 @@ import app.common.Mapper; import com.fasterxml.jackson.databind.JsonNode; -public class Optout extends App { +public class OptOut extends App { private static final String CORE_API_TOKEN = EnvUtil.getEnv("UID2_E2E_OPTOUT_TO_CALL_CORE_API_TOKEN"); - public Optout(String host, Integer port, String name) { + public OptOut(String host, Integer port, String name) { super(host, port, name); } diff --git a/src/test/java/suite/E2ELocalFullTestSuite.java b/src/test/java/suite/E2ELocalFullTestSuite.java index 802d3b5..0a665c4 100644 --- a/src/test/java/suite/E2ELocalFullTestSuite.java +++ b/src/test/java/suite/E2ELocalFullTestSuite.java @@ -6,7 +6,7 @@ import suite.core.CoreRefreshTest; import suite.core.CoreTest; import suite.operator.*; -import suite.optout.BeforeOptoutTest; +import suite.optout.OptOutTest; import suite.validator.V0ApiValidatorTest; import suite.validator.V2ApiValidatorTest; @@ -19,7 +19,7 @@ V1ApiOperatorTest.class, V2ApiOperatorTest.class, V2ApiOperatorPublicOnlyTest.class, - BeforeOptoutTest.class, + OptOutTest.class, V0ApiValidatorTest.class, V1ApiOperatorTest.class, V2ApiValidatorTest.class diff --git a/src/test/java/suite/E2EPublicOperatorTestSuite.java b/src/test/java/suite/E2EPublicOperatorTestSuite.java index 95c1f0d..5de669a 100644 --- a/src/test/java/suite/E2EPublicOperatorTestSuite.java +++ b/src/test/java/suite/E2EPublicOperatorTestSuite.java @@ -6,7 +6,7 @@ import suite.core.CoreRefreshTest; import suite.core.CoreTest; import suite.operator.*; -import suite.optout.BeforeOptoutTest; +import suite.optout.OptOutTest; @Suite @SelectClasses({ @@ -17,7 +17,7 @@ V1ApiOperatorTest.class, V2ApiOperatorTest.class, V2ApiOperatorPublicOnlyTest.class, - BeforeOptoutTest.class + OptOutTest.class }) public class E2EPublicOperatorTestSuite { } diff --git a/src/test/java/suite/optout/AfterOptoutTest.java b/src/test/java/suite/optout/AfterOptoutTest.java deleted file mode 100644 index b059346..0000000 --- a/src/test/java/suite/optout/AfterOptoutTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package suite.optout; - -import app.AppsMap; -import app.common.Mapper; -import app.component.Operator; -import com.fasterxml.jackson.databind.JsonNode; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assumptions.assumeThat; - -// Tests in this class are currently run manually -@SuppressWarnings("unused") -public class AfterOptoutTest { - @ParameterizedTest(name = "/v0/token/refresh after {3} generate and {4} logout - {0} - {2}") - @MethodSource({ - "refreshTokenArgs" - }) - public void testV0TokenRefresh(String label, Operator operator, String operatorName, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) throws Exception { - assumeThat(tokenGenerateVersion).isEqualTo("v0"); - - JsonNode response = operator.v0TokenRefresh(refreshToken); - - assertThat(response).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"advertisement_token\":\"\",\"advertising_token\":\"\",\"refresh_token\":\"\"}")); - } - - @ParameterizedTest(name = "/v1/token/refresh after {3} generate and {4} logout - {0} - {2}") - @MethodSource({ - "refreshTokenArgs" - }) - public void testV1TokenRefresh(String label, Operator operator, String operatorName, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) throws Exception { - assumeThat(tokenGenerateVersion).isEqualTo("v1"); - - JsonNode response = operator.v1TokenRefresh(refreshToken); - - assertThat(response).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"status\":\"optout\"}")); - } - - @ParameterizedTest(name = "/v2/token/refresh after {3} generate and {4} logout - {0} - {2}") - @MethodSource({ - "refreshTokenArgs" - }) - public void testV2TokenRefresh(String label, Operator operator, String operatorName, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) throws Exception { - assumeThat(tokenGenerateVersion).isEqualTo("v2"); - - JsonNode response = operator.v2TokenRefresh(refreshToken, refreshResponseKey); - - assertThat(response).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"status\":\"optout\"}")); - } - - private static Set refreshTokenArgs() { - Set operators = AppsMap.getApps(Operator.class); - Set> refreshTokens = Set.of( - // Copy and paste BeforeOptoutTest output here - // WARNING: DO NOT COMMIT ANYTHING PASTED INTO THIS SET - ); - - Set args = new HashSet<>(); - for (Operator operator : operators) { - for (List refreshToken : refreshTokens) { - String operatorNameInTokenGenerate = refreshToken.get(1); - if (!operatorNameInTokenGenerate.equals(operator.getName())) { - continue; - } - - args.add(Arguments.of(refreshToken.get(0), operator, refreshToken.get(1), refreshToken.get(2), refreshToken.get(3), refreshToken.get(4), refreshToken.get(5))); - } - } - return args; - } -} diff --git a/src/test/java/suite/optout/BeforeOptoutTest.java b/src/test/java/suite/optout/OptOutTest.java similarity index 50% rename from src/test/java/suite/optout/BeforeOptoutTest.java rename to src/test/java/suite/optout/OptOutTest.java index 739341b..bbf3742 100644 --- a/src/test/java/suite/optout/BeforeOptoutTest.java +++ b/src/test/java/suite/optout/OptOutTest.java @@ -4,39 +4,39 @@ import app.component.Operator; import com.fasterxml.jackson.databind.JsonNode; import com.uid2.client.IdentityTokens; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; @SuppressWarnings("unused") -public class BeforeOptoutTest { +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class OptOutTest { // TODO: Test failure case private static final int OPTOUT_DELAY_MS = 1000; - private static List outputs; + private static final int OPTOUT_WAIT_SECONDS = 600; + + private static Set outputArgs; @BeforeAll public static void setupAll() { - outputs = new ArrayList<>(); - } - - @AfterAll - public static void teardownAll() { - System.out.println("OUTPUTS - Copy and paste this into AfterLogoutTest"); - System.out.println("=================================================="); - outputs.forEach(System.out::print); + outputArgs = new HashSet<>(); } @ParameterizedTest(name = "/v2/token/logout with /v0/token/generate - {0} - {2}") @MethodSource({ "suite.optout.TestData#tokenEmailArgs" }) + @Order(1) public void testV2LogoutWithV0TokenGenerate(String label, Operator operator, String operatorName, String type, String identity) throws Exception { JsonNode generateResponse = operator.v0TokenGenerate(type, identity); Thread.sleep(OPTOUT_DELAY_MS); @@ -45,7 +45,7 @@ public void testV2LogoutWithV0TokenGenerate(String label, Operator operator, Str assertThat(logoutResponse).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"body\":{\"optout\":\"OK\"},\"status\":\"success\"}")); addToken( label, - operatorName, + operator, "v0", "v2", generateResponse.at("/refresh_token").asText(), @@ -58,6 +58,7 @@ public void testV2LogoutWithV0TokenGenerate(String label, Operator operator, Str "suite.optout.TestData#tokenEmailArgs", "suite.optout.TestData#tokenPhoneArgs" }) + @Order(2) public void testV2LogoutWithV1TokenGenerate(String label, Operator operator, String operatorName, String type, String identity) throws Exception { JsonNode generateResponse = operator.v1TokenGenerate(type, identity); Thread.sleep(OPTOUT_DELAY_MS); @@ -66,7 +67,7 @@ public void testV2LogoutWithV1TokenGenerate(String label, Operator operator, Str assertThat(logoutResponse).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"body\":{\"optout\":\"OK\"},\"status\":\"success\"}")); addToken( label, - operatorName, + operator, "v1", "v2", generateResponse.at("/body/refresh_token").asText(), @@ -79,6 +80,7 @@ public void testV2LogoutWithV1TokenGenerate(String label, Operator operator, Str "suite.optout.TestData#optoutTokenEmailArgs", "suite.optout.TestData#optoutTokenPhoneArgs" }) + @Order(3) public void testV2LogoutWithV2TokenGenerate(String label, Operator operator, String operatorName, String type, String identity) throws Exception { IdentityTokens generateResponse = operator.v2TokenGenerate(type, identity, false).getIdentity(); Thread.sleep(OPTOUT_DELAY_MS); @@ -86,7 +88,7 @@ public void testV2LogoutWithV2TokenGenerate(String label, Operator operator, Str assertThat(logoutResponse).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"body\":{\"optout\":\"OK\"},\"status\":\"success\"}")); addToken( label, - operatorName, + operator, "v2", "v2", generateResponse.getRefreshToken(), @@ -99,6 +101,7 @@ public void testV2LogoutWithV2TokenGenerate(String label, Operator operator, Str "suite.optout.TestData#optoutTokenEmailArgs", "suite.optout.TestData#optoutTokenPhoneArgs" }) + @Order(4) public void testV2LogoutWithV2TokenGenerateOldParticipant(String label, Operator operator, String operatorName, String type, String identity) throws Exception { IdentityTokens generateResponse = operator.v2TokenGenerate(type, identity, true).getIdentity(); Thread.sleep(OPTOUT_DELAY_MS); @@ -106,7 +109,7 @@ public void testV2LogoutWithV2TokenGenerateOldParticipant(String label, Operator assertThat(logoutResponse).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"body\":{\"optout\":\"OK\"},\"status\":\"success\"}")); addToken( "old participant " + label, - operatorName, + operator, "v2", "v2", generateResponse.getRefreshToken(), @@ -114,10 +117,72 @@ public void testV2LogoutWithV2TokenGenerateOldParticipant(String label, Operator ); } - private void addToken(String label, String operatorName, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) { - outputs.add("List.of(\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"),%n".formatted( - label, operatorName, tokenGenerateVersion, tokenLogoutVersion, refreshToken, refreshResponseKey - ) - ); + @Order(5) + @ParameterizedTest(name = "/v0/token/refresh after {3} generate and {4} logout - {0} - {2}") + @MethodSource({ + "newRefreshTokenArgs" + }) + public void testV0TokenRefreshAfterOptOut(String label, Operator operator, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) throws Exception { + assumeThat(tokenGenerateVersion).isEqualTo("v0"); + + JsonNode response = this.waitForOptOutResponse(operator::v0CheckedTokenRefresh, refreshToken, "{\"advertisement_token\":\"\",\"advertising_token\":\"\",\"refresh_token\":\"\"}"); + + assertThat(response).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"advertisement_token\":\"\",\"advertising_token\":\"\",\"refresh_token\":\"\"}")); + } + + @Order(6) + @ParameterizedTest(name = "/v1/token/refresh after {3} generate and {4} logout - {0} - {2}") + @MethodSource({ + "newRefreshTokenArgs" + }) + public void testV1TokenRefreshAfterOptOut(String label, Operator operator, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) throws Exception { + assumeThat(tokenGenerateVersion).isEqualTo("v1"); + + JsonNode response = this.waitForOptOutResponse(operator::v1CheckedTokenRefresh, refreshToken, "{\"status\":\"optout\"}"); + + assertThat(response).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"status\":\"optout\"}")); + } + + @Order(7) + @ParameterizedTest(name = "/v2/token/refresh after {3} generate and {4} logout - {0} - {2}") + @MethodSource({ + "newRefreshTokenArgs" + }) + public void testV2TokenRefreshAfterOptOut(String label, Operator operator, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) throws Exception { + assumeThat(tokenGenerateVersion).isEqualTo("v2"); + + JsonNode response = operator.v2TokenRefresh(refreshToken, refreshResponseKey); + int breakCounter = 0; + while (breakCounter < OPTOUT_WAIT_SECONDS && !response.equals(Mapper.OBJECT_MAPPER.readTree("{\"status\":\"optout\"}"))) { + TimeUnit.SECONDS.sleep(5); + response = operator.v2TokenRefresh(refreshToken, refreshResponseKey); + breakCounter++; + } + + assertThat(breakCounter).isLessThan(OPTOUT_WAIT_SECONDS).withFailMessage("Timed-out getting an Opt Out Response"); + assertThat(response).isEqualTo(Mapper.OBJECT_MAPPER.readTree("{\"status\":\"optout\"}")); + } + + private static Set newRefreshTokenArgs() { + return outputArgs; + } + + private void addToken(String label, Operator operator, String tokenGenerateVersion, String tokenLogoutVersion, String refreshToken, String refreshResponseKey) { + outputArgs.add(Arguments.of(label, operator, tokenGenerateVersion, tokenLogoutVersion, refreshToken, refreshResponseKey)); + } + + private JsonNode waitForOptOutResponse(Function tokenRefreshFunction, String refreshToken, String expectedResponse) { + try { + JsonNode response = tokenRefreshFunction.apply(refreshToken); + int breakCounter = 0; + while (breakCounter < OPTOUT_WAIT_SECONDS && !response.equals(Mapper.OBJECT_MAPPER.readTree(expectedResponse))) { + TimeUnit.SECONDS.sleep(5); + response = tokenRefreshFunction.apply(refreshToken); + breakCounter++; + } + return response; + } catch (Exception e) { + return Mapper.OBJECT_MAPPER.createObjectNode(); + } } }