diff --git a/src/main/java/com/spotify/github/v3/checks/Annotation.java b/src/main/java/com/spotify/github/v3/checks/Annotation.java index 6f8465fe..4f055af3 100644 --- a/src/main/java/com/spotify/github/v3/checks/Annotation.java +++ b/src/main/java/com/spotify/github/v3/checks/Annotation.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.Preconditions; import com.spotify.github.GithubStyle; import java.util.Optional; import org.immutables.value.Value; @@ -114,4 +115,23 @@ public interface Annotation { * @return the optional */ Optional endColumn(); + + /** + * Automatically validates the maximum length of properties. + * + * GitHub does not validate these properly on their side (at least in GHE 3.2) + * and returns 5xx HTTP responses instead. To avoid that, let's validate the data + * in this client library. + */ + @Value.Check + @SuppressWarnings("checkstyle:magicnumber") + default void check() { + // max values from https://docs.github.com/en/rest/checks/runs + Preconditions.checkState(title().map(String::length).orElse(0) <= 255, + "'title' exceeded max length of 255"); + Preconditions.checkState(message().length() <= 64 * 1024, + "'message' exceeded max length of 64kB"); + Preconditions.checkState(rawDetails().map(String::length).orElse(0) <= 64 * 1024, + "'rawDetails' exceeded max length of 64kB"); + } } diff --git a/src/main/java/com/spotify/github/v3/checks/CheckRunAction.java b/src/main/java/com/spotify/github/v3/checks/CheckRunAction.java index feb81b3e..f3c93c9b 100644 --- a/src/main/java/com/spotify/github/v3/checks/CheckRunAction.java +++ b/src/main/java/com/spotify/github/v3/checks/CheckRunAction.java @@ -21,6 +21,7 @@ package com.spotify.github.v3.checks; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.Preconditions; import com.spotify.github.GithubStyle; import org.immutables.value.Value; @@ -57,4 +58,23 @@ public interface CheckRunAction { * @return the string */ String description(); + + /** + * Automatically validates the maximum length of properties. + * + * GitHub does not validate these properly on their side (at least in GHE 3.2) + * and returns 5xx HTTP responses instead. To avoid that, let's validate the data + * in this client library. + */ + @Value.Check + @SuppressWarnings("checkstyle:magicnumber") + default void check() { + // max values from https://docs.github.com/en/rest/checks/runs + Preconditions.checkState(label().length() <= 20, + "'label' exceeded max length of 20"); + Preconditions.checkState(identifier().length() <= 20, + "'identifier' exceeded max length of 20"); + Preconditions.checkState(description().length() <= 40, + "'description' exceeded max length of 40"); + } } diff --git a/src/test/java/com/spotify/github/v3/checks/AnnotationTest.java b/src/test/java/com/spotify/github/v3/checks/AnnotationTest.java new file mode 100644 index 00000000..7c48d6b8 --- /dev/null +++ b/src/test/java/com/spotify/github/v3/checks/AnnotationTest.java @@ -0,0 +1,69 @@ +/*- + * -\-\- + * github-client + * -- + * Copyright (C) 2016 - 2022 Spotify AB + * -- + * 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. + * -/-/- + */ + +package com.spotify.github.v3.checks; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.spotify.github.FixtureHelper; +import com.spotify.github.jackson.Json; +import com.spotify.github.v3.checks.ImmutableAnnotation.Builder; +import java.io.IOException; +import java.time.ZonedDateTime; +import org.junit.Test; + +public class AnnotationTest { + private Builder builder() { + return ImmutableAnnotation.builder() + .title("title") + .message("message") + .rawDetails("rawDetails") + .path("path") + .startLine(1) + .endLine(2) + .annotationLevel(AnnotationLevel.notice); + } + + @Test + public void allowsCreationWithinLimits(){ + builder().build(); + + builder() + .title("a".repeat(255)) + .message("a".repeat(64000)) + .rawDetails("a".repeat(64000)) + .build(); + } + + @Test + public void failsCreationWhenMaxLengthExceeded(){ + assertThrows(IllegalStateException.class, () -> + builder().title("a".repeat(256)).build() + ); + assertThrows(IllegalStateException.class, () -> + builder().message("a".repeat(66000)).build() + ); + assertThrows(IllegalStateException.class, () -> + builder().rawDetails("a".repeat(66000)).build() + ); + } +} diff --git a/src/test/java/com/spotify/github/v3/checks/CheckRunActionTest.java b/src/test/java/com/spotify/github/v3/checks/CheckRunActionTest.java new file mode 100644 index 00000000..0646fb7c --- /dev/null +++ b/src/test/java/com/spotify/github/v3/checks/CheckRunActionTest.java @@ -0,0 +1,65 @@ +/*- + * -\-\- + * github-client + * -- + * Copyright (C) 2016 - 2022 Spotify AB + * -- + * 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. + * -/-/- + */ + +package com.spotify.github.v3.checks; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.spotify.github.FixtureHelper; +import com.spotify.github.jackson.Json; +import com.spotify.github.v3.checks.ImmutableCheckRunAction.Builder; +import java.io.IOException; +import java.time.ZonedDateTime; +import org.junit.Test; + +public class CheckRunActionTest { + private Builder builder() { + return ImmutableCheckRunAction.builder() + .label("label") + .identifier("identifier") + .description("description"); + } + + @Test + public void allowsCreationWithinLimits(){ + builder().build(); + + builder() + .label("a".repeat(20)) + .identifier("a".repeat(20)) + .description("a".repeat(40)) + .build(); + } + + @Test + public void failsCreationWhenMaxLengthExceeded(){ + assertThrows(IllegalStateException.class, () -> + builder().label("a".repeat(21)).build() + ); + assertThrows(IllegalStateException.class, () -> + builder().identifier("a".repeat(21)).build() + ); + assertThrows(IllegalStateException.class, () -> + builder().description("a".repeat(41)).build() + ); + } +}