From 65ee3ac6e062bd2a1c0e599599c37a5818c8181e Mon Sep 17 00:00:00 2001 From: Guillermo Castro Date: Sun, 7 Apr 2024 18:25:12 -0600 Subject: [PATCH] More testing and code refactorings --- .../workflows/codacy-coverage-reporter.yml | 22 +++++++ .github/workflows/java-build.yml | 10 +-- pom.xml | 65 +++++++++---------- .../jfed/activitystreams/NaturalValue.java | 11 +++- .../jfed/activitystreams/ObjectParser.java | 20 ------ .../dev/jfed/activitystreams/core/Link.java | 21 ++++-- .../jfed/activitystreams/JsonTestUtil.java | 46 +++++++++++++ .../activitystreams/core/ASObjectTest.java | 59 +++++++++++++---- .../jfed/activitystreams/core/LinkTest.java | 44 ++++++------- .../resources/test/core-ex11b-jsonld.json | 7 ++ .../resources/test/core-ex11c-jsonld.json | 10 +++ 11 files changed, 212 insertions(+), 103 deletions(-) create mode 100644 .github/workflows/codacy-coverage-reporter.yml delete mode 100644 src/main/java/dev/jfed/activitystreams/ObjectParser.java create mode 100644 src/test/java/dev/jfed/activitystreams/JsonTestUtil.java create mode 100644 src/test/resources/test/core-ex11b-jsonld.json create mode 100644 src/test/resources/test/core-ex11c-jsonld.json diff --git a/.github/workflows/codacy-coverage-reporter.yml b/.github/workflows/codacy-coverage-reporter.yml new file mode 100644 index 0000000..f1c6ac2 --- /dev/null +++ b/.github/workflows/codacy-coverage-reporter.yml @@ -0,0 +1,22 @@ +name: Codacy Coverage Reporter + +on: + push: + branches: + - main + +jobs: + codacy-coverage-reporter: + runs-on: ubuntu-latest + name: codacy-coverage-reporter + steps: + - uses: actions/checkout@v4 + - name: Run codacy-coverage-reporter + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + # or + # api-token: ${{ secrets.CODACY_API_TOKEN }} + coverage-reports: target/site/jacoco/jacoco.xml + # or a comma-separated list for multiple reports + # coverage-reports: , \ No newline at end of file diff --git a/.github/workflows/java-build.yml b/.github/workflows/java-build.yml index 82e2e75..af2f004 100644 --- a/.github/workflows/java-build.yml +++ b/.github/workflows/java-build.yml @@ -10,22 +10,22 @@ jobs: name: Build and analyze runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' # Alternative distribution options are available. - name: Cache SonarCloud packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -34,4 +34,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: mvn -B -Pcoverage verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=jfed-dev_jfed-activitystreams \ No newline at end of file + run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=jfed-dev_jfed-activitystreams \ No newline at end of file diff --git a/pom.xml b/pom.xml index d2dbb43..877791d 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ com.apicatalog titanium-json-ld - 1.3.1 + 1.4.0 @@ -114,37 +114,32 @@ - - - coverage - - - - org.jacoco - jacoco-maven-plugin - 0.8.12 - - - prepare-agent - - prepare-agent - - - - report - - report - - - - XML - - - - - - - - - - + + + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + XML + + + + + + + + \ No newline at end of file diff --git a/src/main/java/dev/jfed/activitystreams/NaturalValue.java b/src/main/java/dev/jfed/activitystreams/NaturalValue.java index e9db61d..29e789f 100644 --- a/src/main/java/dev/jfed/activitystreams/NaturalValue.java +++ b/src/main/java/dev/jfed/activitystreams/NaturalValue.java @@ -29,11 +29,12 @@ * @see AS2#naturalLanguageValues */ public class NaturalValue { + public static final String UNDEFINED = "und"; private final Locale locale; private final Map valueMap; public static NaturalValueBuilder builder() { - return new NaturalValueBuilder(Locale.getDefault()); + return new NaturalValueBuilder(Locale.ROOT); } public static NaturalValueBuilder builder(Locale locale) { @@ -72,7 +73,7 @@ public String getValue() { } public String getValue(String language) { - return getValue(Locale.forLanguageTag(language)); + return getValue(UNDEFINED.equalsIgnoreCase(language) ? Locale.ROOT : Locale.forLanguageTag(language)); } public String getValue(Locale locale) { @@ -84,13 +85,17 @@ public void setValue(String value) { } public void setValue(String language, String text) { - setValue(Locale.forLanguageTag(language), text); + setValue(UNDEFINED.equalsIgnoreCase(language) ? Locale.ROOT : Locale.forLanguageTag(language), text); } public void setValue(Locale locale, String text) { valueMap.put(locale, text); } + public Locale getLocale() { + return locale; + } + public boolean hasValueForLanguage(Locale locale) { return valueMap.containsKey(locale); } diff --git a/src/main/java/dev/jfed/activitystreams/ObjectParser.java b/src/main/java/dev/jfed/activitystreams/ObjectParser.java deleted file mode 100644 index 92d15d1..0000000 --- a/src/main/java/dev/jfed/activitystreams/ObjectParser.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2022-2024 Guillermo Castro - * - * 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 dev.jfed.activitystreams; - -public class ObjectParser { - -} diff --git a/src/main/java/dev/jfed/activitystreams/core/Link.java b/src/main/java/dev/jfed/activitystreams/core/Link.java index 2e760bc..4222161 100644 --- a/src/main/java/dev/jfed/activitystreams/core/Link.java +++ b/src/main/java/dev/jfed/activitystreams/core/Link.java @@ -189,28 +189,35 @@ public static Optional fromJsonObject(final JsonObject jsonObject) { } private static void processEntry(final LinkBuilder builder, final Map.Entry property) { - String value = ((JsonString)property.getValue()).getString(); + var value = property.getValue(); switch(property.getKey()) { case Keywords.CONTEXT, Keywords.TYPE, ASProperties.TYPE, ASProperties.HREF: // ignore break; case ASProperties.NAME: - builder.name(NaturalValue.builder().withValue(value).build()); + final var name = ((JsonString)value).getString(); + builder.name(NaturalValue.builder().withValue(name).build()); + break; + case ASProperties.NAME_MAP: + final var valueBuilder = NaturalValue.builder(); + property.getValue().asJsonObject() + .forEach((k, v) -> valueBuilder.withValue(k, ((JsonString)v).getString())); + builder.name(valueBuilder.build()); break; case ASProperties.REL: - builder.rel(value); + builder.rel(((JsonString)value).getString()); break; case ASProperties.MEDIA_TYPE: - builder.mediaType(value); + builder.mediaType(((JsonString)value).getString()); break; case ASProperties.HREFLANG: - builder.hreflang(value); + builder.hreflang(((JsonString)value).getString()); break; case ASProperties.HEIGHT: - builder.height(Integer.parseInt(value)); + builder.height(Integer.parseInt(((JsonString)value).getString())); break; case ASProperties.WIDTH: - builder.width(Integer.parseInt(value)); + builder.width(Integer.parseInt(((JsonString)value).getString())); break; default: log.atWarn().setMessage("Property not found: key={}, value={}").addArgument(property.getKey()).addArgument(property.getValue()).log(); diff --git a/src/test/java/dev/jfed/activitystreams/JsonTestUtil.java b/src/test/java/dev/jfed/activitystreams/JsonTestUtil.java new file mode 100644 index 0000000..c2353db --- /dev/null +++ b/src/test/java/dev/jfed/activitystreams/JsonTestUtil.java @@ -0,0 +1,46 @@ +/* + * Copyright 2022-2024 Guillermo Castro + * + * 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 dev.jfed.activitystreams; + +import com.apicatalog.jsonld.JsonLd; +import com.apicatalog.jsonld.JsonLdError; +import com.apicatalog.jsonld.document.JsonDocument; +import com.apicatalog.jsonld.http.media.MediaType; +import jakarta.json.JsonObject; + +import java.net.URI; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * @author Guillermo Castro + * @since 0.0.1 + */ +public class JsonTestUtil { + private JsonTestUtil() {} + + public static JsonObject getJsonObject(String name) throws JsonLdError { + var document = JsonDocument.of(MediaType.of("application", "activity+json"), JsonTestUtil.class.getClassLoader().getResourceAsStream(name)); + assertNotNull(document); + assertFalse(document.getJsonContent().isEmpty()); + var object = JsonLd.compact(document, URI.create(ASType.CONTEXT_VALUE)).get(); + assertNotNull(object); + return object; + } + +} diff --git a/src/test/java/dev/jfed/activitystreams/core/ASObjectTest.java b/src/test/java/dev/jfed/activitystreams/core/ASObjectTest.java index d78620c..16ee7a5 100644 --- a/src/test/java/dev/jfed/activitystreams/core/ASObjectTest.java +++ b/src/test/java/dev/jfed/activitystreams/core/ASObjectTest.java @@ -14,9 +14,9 @@ package dev.jfed.activitystreams.core; -import com.apicatalog.jsonld.document.JsonDocument; +import com.apicatalog.jsonld.JsonLdError; +import dev.jfed.activitystreams.JsonTestUtil; import dev.jfed.activitystreams.NaturalValue; -import jakarta.json.JsonObject; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.JSONAssert; @@ -39,6 +39,7 @@ class ASObjectTest { private static final String TEST_ID = "https://test.example.com/object/1"; private static final String TEST_NAME = "Test Object"; + private static final String TEST_NAME_ES = "Objeto de Prueba"; @Test void testMinimal() throws JSONException { @@ -59,24 +60,34 @@ void testAllProperties() throws Exception { var result = obj.toJson(); assertNotNull(result); + log.atInfo().setMessage("test json: {}").addArgument(result).log(); + JSONAssert.assertEquals("{'@context': 'https://www.w3.org/ns/activitystreams'}", result, false); JSONAssert.assertEquals("{'type': 'Object'}", result, false); JSONAssert.assertEquals("{'id': '" + TEST_ID + "'}", result, false); JSONAssert.assertEquals("{'name': '" + TEST_NAME + "'}", result, false); + } + + @Test + void testWithNameMap() throws Exception { + var result = ASObject.builder() + .withId(URI.create(TEST_ID)) + .withName(NaturalValue.builder() + .withValue("en", TEST_NAME) + .withValue("es", TEST_NAME_ES) + .build()) + .build().toJson(); + assertNotNull(result); log.atInfo().setMessage("test json: {}").addArgument(result).log(); + + JSONAssert.assertEquals("{'id': '" + TEST_ID + "'}", result, false); + JSONAssert.assertEquals("{'nameMap': {'en': '" + TEST_NAME + "', 'es': '" + TEST_NAME_ES + "'}}", result, false); } @Test - void testFromJson() throws Exception { - JsonDocument document = JsonDocument.of(getClass().getClassLoader().getResourceAsStream("test/core-ex8-jsonld.json")); - assertNotNull(document); - assertFalse(document.getJsonContent().isEmpty()); - JsonObject object = document.getJsonContent().get().asJsonObject(); - assertNotNull(object); - final var result = ASObject.fromJsonObject(object); - assertFalse(result.isEmpty()); - var testObject = result.get(); + void testNameMap() throws Exception { + var testObject = getAsObject("test/core-ex8-jsonld.json"); assertTrue(testObject.getName().hasMultipleLanguages()); assertEquals("This is the title", testObject.getName().getValue("en")); @@ -86,4 +97,30 @@ void testFromJson() throws Exception { log.atInfo().setMessage("test Object: {}").addArgument(testObject).log(); } + @Test + void testUndefinedNameMap() throws Exception { + var testObject = getAsObject("test/core-ex11b-jsonld.json"); + + assertFalse(testObject.getName().hasMultipleLanguages()); + assertEquals("This is the title", testObject.getName().getValue(NaturalValue.UNDEFINED)); + assertEquals("This is the title", testObject.getName().getValue()); + } + + @Test + void testLanguageInContext() throws Exception { + var testObject = getAsObject("test/core-ex11c-jsonld.json"); + + assertFalse(testObject.getName().hasMultipleLanguages()); + assertEquals("This is the title", testObject.getName().getValue("en")); + } + + private ASObject getAsObject(String name) throws JsonLdError { + var jsonObject = JsonTestUtil.getJsonObject(name); + assertNotNull(jsonObject); + assertFalse(jsonObject.isEmpty()); + var result = ASObject.fromJsonObject(jsonObject); + assertNotNull(result); + assertFalse(result.isEmpty()); + return result.get(); + } } \ No newline at end of file diff --git a/src/test/java/dev/jfed/activitystreams/core/LinkTest.java b/src/test/java/dev/jfed/activitystreams/core/LinkTest.java index cdc0379..209f95b 100644 --- a/src/test/java/dev/jfed/activitystreams/core/LinkTest.java +++ b/src/test/java/dev/jfed/activitystreams/core/LinkTest.java @@ -1,16 +1,18 @@ -// Copyright 2022-2024 Guillermo Castro -// -// 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. +/* + * Copyright 2022-2024 Guillermo Castro + * + * 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 dev.jfed.activitystreams.core; @@ -21,6 +23,7 @@ import java.net.URI; import java.util.Optional; +import dev.jfed.activitystreams.JsonTestUtil; import dev.jfed.activitystreams.NaturalValue; import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.JSONAssert; @@ -43,7 +46,7 @@ class LinkTest { private static final int TEST_WIDTH = 600; @Test - public void testMinimal() throws Exception { + void testMinimal() throws Exception { Link link = new Link.LinkBuilder(URI.create(TEST_HREF)).build(); String result = link.toJson(); @@ -54,7 +57,7 @@ public void testMinimal() throws Exception { } @Test - public void testAllProperties() throws Exception { + void testAllProperties() throws Exception { Link link = new Link.LinkBuilder(URI.create(TEST_HREF)) .rel(TEST_REL) .mediaType(TEST_MEDIA_TYPE) @@ -80,14 +83,11 @@ public void testAllProperties() throws Exception { } @Test - public void testFromJson() throws Exception { + void testFromJson() throws Exception { - JsonDocument document = JsonDocument.of(getClass().getClassLoader().getResourceAsStream("test/vocabulary-ex2-jsonld.json")); - assertNotNull(document); - assertFalse(document.getJsonContent().isEmpty()); - JsonObject object = document.getJsonContent().get().asJsonObject(); - assertNotNull(object); - Optional result = Link.fromJsonObject(object); + JsonObject jsonObject = JsonTestUtil.getJsonObject("test/vocabulary-ex2-jsonld.json"); + assertNotNull(jsonObject); + Optional result = Link.fromJsonObject(jsonObject); assertFalse(result.isEmpty()); Link testLink = result.get(); assertEquals("http://example.org/abc", testLink.getHref().toString()); diff --git a/src/test/resources/test/core-ex11b-jsonld.json b/src/test/resources/test/core-ex11b-jsonld.json new file mode 100644 index 0000000..7a5d453 --- /dev/null +++ b/src/test/resources/test/core-ex11b-jsonld.json @@ -0,0 +1,7 @@ +{ + "@context": "https://www.w3.org/ns/activitystreams", + "type": "Object", + "nameMap": { + "und": "This is the title" + } +} \ No newline at end of file diff --git a/src/test/resources/test/core-ex11c-jsonld.json b/src/test/resources/test/core-ex11c-jsonld.json new file mode 100644 index 0000000..95969a3 --- /dev/null +++ b/src/test/resources/test/core-ex11c-jsonld.json @@ -0,0 +1,10 @@ + +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "@language": "en" + }], + "type": "Object", + "name": "This is the title" +}