From 59afd760083dc21e74823b78d7d2a5e8ae9174e8 Mon Sep 17 00:00:00 2001 From: Dennis Lloyd Jr Date: Tue, 13 Dec 2016 17:40:46 -0500 Subject: [PATCH] Add support for delete favorite and user withheld --- .../ComplianceActivityUnmarshaller.java | 13 +++---- .../model/compliance/ComplianceActivity.java | 36 +++++++++-------- ...tatusActivity.java => DeleteActivity.java} | 32 ++++++++++++--- .../ComplianceActivityUnmarshallerTest.java | 39 ++++++++++++++++--- 4 files changed, 84 insertions(+), 36 deletions(-) rename core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/{DeleteStatusActivity.java => DeleteActivity.java} (61%) diff --git a/core/src/main/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshaller.java b/core/src/main/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshaller.java index 3b92b321..12327ad1 100644 --- a/core/src/main/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshaller.java +++ b/core/src/main/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshaller.java @@ -15,15 +15,14 @@ */ package com.zaubersoftware.gnip4j.api.impl.formats; -import java.io.IOException; - -import org.codehaus.jackson.map.JsonMappingException; -import org.codehaus.jackson.map.ObjectMapper; - import com.zaubersoftware.gnip4j.api.model.Activity; import com.zaubersoftware.gnip4j.api.model.compliance.ComplianceActivity; import com.zaubersoftware.gnip4j.api.support.logging.LoggerFactory; import com.zaubersoftware.gnip4j.api.support.logging.spi.Logger; +import org.codehaus.jackson.map.ObjectMapper; + +import java.io.IOException; +import java.io.UncheckedIOException; /** * Translates JSON input from the Compliance v2 stream into instances of Activity. @@ -41,11 +40,9 @@ public class ComplianceActivityUnmarshaller implements Unmarshaller { public final Activity unmarshall(final String s) { try { return mapper.readValue(s, ComplianceActivity.class).toActivity(); - } catch (final JsonMappingException e) { + } catch (final IOException | UncheckedIOException e) { logger.warn("Failed to parse compliance activity: " + s, e); return null; - } catch (final IOException e) { - throw new IllegalArgumentException("parsing compliance activity", e); } } } diff --git a/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/ComplianceActivity.java b/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/ComplianceActivity.java index 4bee444a..40873354 100644 --- a/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/ComplianceActivity.java +++ b/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/ComplianceActivity.java @@ -1,12 +1,12 @@ /** * Copyright (c) 2011-2016 Zauber S.A. - * + *

* 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 - * + *

+ * 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. @@ -15,12 +15,11 @@ */ package com.zaubersoftware.gnip4j.api.model.compliance; -import java.io.Serializable; - +import com.zaubersoftware.gnip4j.api.model.Activity; import org.codehaus.jackson.annotate.JsonSubTypes; import org.codehaus.jackson.annotate.JsonTypeInfo; -import com.zaubersoftware.gnip4j.api.model.Activity; +import java.io.Serializable; /** * Activity from the Compliance v2 stream that can be converted to an Activity @@ -28,23 +27,25 @@ * @author Dennis Lloyd Jr * @since Oct 14, 2016 */ -@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) @JsonSubTypes({ - @JsonSubTypes.Type(value=DeleteStatusActivity.class, name=ComplianceActivity.Verb.DELETE), - @JsonSubTypes.Type(value=DeleteUserActivity.class, name=ComplianceActivity.Verb.USER_DELETE), - @JsonSubTypes.Type(value=UndeleteUserActivity.class, name=ComplianceActivity.Verb.USER_UNDELETE), - @JsonSubTypes.Type(value=ScrubGeoActivity.class, name=ComplianceActivity.Verb.SCRUB_GEO), - @JsonSubTypes.Type(value=UserProtectActivity.class, name=ComplianceActivity.Verb.USER_PROTECT), - @JsonSubTypes.Type(value=UserUnprotectActivity.class, name=ComplianceActivity.Verb.USER_UNPROTECT), - @JsonSubTypes.Type(value=UserSuspendActivity.class, name=ComplianceActivity.Verb.USER_SUSPEND), - @JsonSubTypes.Type(value=UserUnsuspendActivity.class, name=ComplianceActivity.Verb.USER_UNSUSPEND), - @JsonSubTypes.Type(value=StatusWithheldActivity.class, name=ComplianceActivity.Verb.STATUS_WITHHELD) + @JsonSubTypes.Type(value = DeleteActivity.class, name = ComplianceActivity.Verb.DELETE), + @JsonSubTypes.Type(value = DeleteUserActivity.class, name = ComplianceActivity.Verb.USER_DELETE), + @JsonSubTypes.Type(value = UndeleteUserActivity.class, name = ComplianceActivity.Verb.USER_UNDELETE), + @JsonSubTypes.Type(value = ScrubGeoActivity.class, name = ComplianceActivity.Verb.SCRUB_GEO), + @JsonSubTypes.Type(value = UserProtectActivity.class, name = ComplianceActivity.Verb.USER_PROTECT), + @JsonSubTypes.Type(value = UserUnprotectActivity.class, name = ComplianceActivity.Verb.USER_UNPROTECT), + @JsonSubTypes.Type(value = UserSuspendActivity.class, name = ComplianceActivity.Verb.USER_SUSPEND), + @JsonSubTypes.Type(value = UserUnsuspendActivity.class, name = ComplianceActivity.Verb.USER_UNSUSPEND), + @JsonSubTypes.Type(value = StatusWithheldActivity.class, name = ComplianceActivity.Verb.STATUS_WITHHELD), + @JsonSubTypes.Type(value = UserWithheldActivity.class, name = ComplianceActivity.Verb.USER_WITHHELD) }) public interface ComplianceActivity extends Serializable { Activity toActivity(); interface Verb { String DELETE = "delete"; + String FAVORITE_DELETE = "favorite_delete"; String USER_DELETE = "user_delete"; String USER_UNDELETE = "user_undelete"; String SCRUB_GEO = "scrub_geo"; @@ -53,5 +54,6 @@ interface Verb { String USER_SUSPEND = "user_suspend"; String USER_UNSUSPEND = "user_unsuspend"; String STATUS_WITHHELD = "status_withheld"; + String USER_WITHHELD = "user_withheld"; } } diff --git a/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/DeleteStatusActivity.java b/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/DeleteActivity.java similarity index 61% rename from core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/DeleteStatusActivity.java rename to core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/DeleteActivity.java index 68c1e49f..62cd927e 100644 --- a/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/DeleteStatusActivity.java +++ b/core/src/main/java/com/zaubersoftware/gnip4j/api/model/compliance/DeleteActivity.java @@ -15,6 +15,7 @@ */ package com.zaubersoftware.gnip4j.api.model.compliance; +import java.io.UncheckedIOException; import java.util.Date; import org.codehaus.jackson.annotate.JsonProperty; @@ -22,6 +23,7 @@ import com.zaubersoftware.gnip4j.api.model.Activity; import com.zaubersoftware.gnip4j.api.model.Actor; +import org.codehaus.jackson.map.JsonMappingException; /** * Represents deleting a status from the Compliance v2 stream @@ -30,9 +32,11 @@ * @since Oct 14, 2016 */ @JsonTypeName(ComplianceActivity.Verb.DELETE) -class DeleteStatusActivity implements ComplianceActivity { +class DeleteActivity implements ComplianceActivity { @JsonProperty("status") private Status status; + @JsonProperty("favorite") + private Favorite favorite; @JsonProperty("timestamp_ms") private String timestamp; @@ -43,13 +47,31 @@ public static class Status { private String userId; } + public static class Favorite { + @JsonProperty("id") + private String id; + @JsonProperty("user_id") + private String userId; + } + @Override public Activity toActivity() { final Activity result = new Activity(); - result.setVerb(ComplianceActivity.Verb.DELETE); - result.setId(status.id); - result.setActor(new Actor()); - result.getActor().setId(status.userId); + + if(status != null) { + result.setVerb(ComplianceActivity.Verb.DELETE); + result.setId(status.id); + result.setActor(new Actor()); + result.getActor().setId(status.userId); + } else if (favorite != null) { + result.setVerb(ComplianceActivity.Verb.FAVORITE_DELETE); + result.setId(favorite.id); + result.setActor(new Actor()); + result.getActor().setId(favorite.userId); + } else { + throw new UncheckedIOException(new JsonMappingException("Expected delete of 'status' or 'favorite'")); + } + result.setUpdated(new Date(Long.parseLong(timestamp))); return result; } diff --git a/core/src/test/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshallerTest.java b/core/src/test/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshallerTest.java index 574d2bc0..0480bc4e 100644 --- a/core/src/test/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshallerTest.java +++ b/core/src/test/java/com/zaubersoftware/gnip4j/api/impl/formats/ComplianceActivityUnmarshallerTest.java @@ -15,16 +15,16 @@ */ package com.zaubersoftware.gnip4j.api.impl.formats; -import static org.junit.Assert.*; +import com.zaubersoftware.gnip4j.api.model.Activity; +import com.zaubersoftware.gnip4j.api.model.compliance.ComplianceActivity; +import org.junit.Before; +import org.junit.Test; import java.util.Arrays; import java.util.Date; -import org.junit.Before; -import org.junit.Test; - -import com.zaubersoftware.gnip4j.api.model.Activity; -import com.zaubersoftware.gnip4j.api.model.compliance.ComplianceActivity; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; /** * @author Dennis Lloyd Jr @@ -48,6 +48,23 @@ public void deleteStatus() { assertEquals(new Date(1432228155593L), result.getUpdated()); } + @Test + public void deleteFavorite() { + final String s = "{\"delete\":{\"favorite\":{\"id\":601430178305220600,\"id_str\":\"601430178305220600\",\"user_id\":3198576760,\"user_id_str\":\"3198576760\"},\"timestamp_ms\":\"1432228155593\"}}"; + final Activity result = unmarshaller.unmarshall(s); + assertEquals(ComplianceActivity.Verb.FAVORITE_DELETE, result.getVerb()); + assertEquals("601430178305220600", result.getId()); + assertEquals("3198576760", result.getActor().getId()); + assertEquals(new Date(1432228155593L), result.getUpdated()); + } + + @Test + public void deleteUnknown() { // What happens when we receive data for a delete that we don't expect + final String s = "{\"delete\":{\"unknown\":{\"id\":601430178305220600,\"id_str\":\"601430178305220600\",\"user_id\":3198576760,\"user_id_str\":\"3198576760\"},\"timestamp_ms\":\"1432228155593\"}}"; + final Activity result = unmarshaller.unmarshall(s); + assertNull(result); + } + @Test public void deleteUser() { final String s = "{\"user_delete\":{\"id\":771136850,\"timestamp_ms\":\"1432228153548\"}}"; @@ -123,6 +140,16 @@ public void statusWithheld() { assertEquals(new Date(1476731813446L), result.getUpdated()); } + @Test + public void userWithheld() { + final String s = "{\"user_withheld\":{\"id\":1375036644,\"timestamp_ms\":\"1481626100690\",\"withheld_in_countries\":[\"TR\"]}}"; + final Activity result = unmarshaller.unmarshall(s); + assertEquals(ComplianceActivity.Verb.USER_WITHHELD, result.getVerb()); + assertEquals("1375036644", result.getActor().getId()); + assertEquals(Arrays.asList("TR"), result.getWithheldInCountries()); + assertEquals(new Date(1481626100690L), result.getUpdated()); + } + @Test public void unrecognizedMesssageType() { final String s = "{\"unknown\":{\"id\":3293130873,\"timestamp_ms\":\"1432228193828\"}}";