Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/main/java/io/getstream/client/ReactionsClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.getstream.core.utils.Auth.TokenAction;
import io.getstream.core.utils.DefaultOptions;
import java.util.List;
import java.util.Map;
import java8.util.concurrent.CompletableFuture;

public final class ReactionsClient {
Expand Down Expand Up @@ -167,6 +168,12 @@ public CompletableFuture<Reaction> add(String userID, Reaction reaction, FeedID.
return reactions.add(token, userID, reaction, targetFeeds);
}

public CompletableFuture<Reaction> add(String userID, Reaction reaction, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData)
throws StreamException {
final Token token = buildReactionsToken(secret, TokenAction.WRITE);
return reactions.add(token, userID, reaction, targetFeeds, targetFeedsExtraData);
}

public CompletableFuture<Reaction> addChild(
String userID, String kind, String parentID, Iterable<FeedID> targetFeeds)
throws StreamException {
Expand All @@ -180,6 +187,12 @@ public CompletableFuture<Reaction> addChild(
return add(userID, child, targetFeeds);
}

public CompletableFuture<Reaction> addChild(
String userID, String kind, String parentID, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData) throws StreamException {
Reaction child = Reaction.builder().kind(kind).parent(parentID).build();
return add(userID, child, targetFeeds, targetFeedsExtraData);
}

public CompletableFuture<Reaction> addChild(
String userID, String parentID, Reaction reaction, Iterable<FeedID> targetFeeds)
throws StreamException {
Expand All @@ -194,6 +207,13 @@ public CompletableFuture<Reaction> addChild(
return add(userID, child, targetFeeds);
}

public CompletableFuture<Reaction> addChild(
String userID, String parentID, Reaction reaction, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData)
throws StreamException {
Reaction child = Reaction.builder().fromReaction(reaction).parent(parentID).build();
return add(userID, child, targetFeeds, targetFeedsExtraData);
}

public CompletableFuture<Void> update(String id, Iterable<FeedID> targetFeeds)
throws StreamException {
return update(id, Iterables.toArray(targetFeeds, FeedID.class));
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/io/getstream/cloud/CloudReactionsClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.getstream.core.options.Limit;
import io.getstream.core.utils.DefaultOptions;
import java.util.List;
import java.util.Map;
import java8.util.concurrent.CompletableFuture;

public final class CloudReactionsClient {
Expand Down Expand Up @@ -150,6 +151,11 @@ public CompletableFuture<Reaction> add(String userID, Reaction reaction, FeedID.
return reactions.add(token, userID, reaction, targetFeeds);
}

public CompletableFuture<Reaction> add(String userID, Reaction reaction, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData)
throws StreamException {
return reactions.add(token, userID, reaction, targetFeeds, targetFeedsExtraData);
}

public CompletableFuture<Reaction> addChild(
String userID, String kind, String parentID, Iterable<FeedID> targetFeeds)
throws StreamException {
Expand All @@ -163,6 +169,12 @@ public CompletableFuture<Reaction> addChild(
return add(userID, child, targetFeeds);
}

public CompletableFuture<Reaction> addChild(
String userID, String kind, String parentID, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData) throws StreamException {
Reaction child = Reaction.builder().kind(kind).parent(parentID).build();
return add(userID, child, targetFeeds, targetFeedsExtraData);
}

public CompletableFuture<Reaction> addChild(
String userID, String parentID, Reaction reaction, Iterable<FeedID> targetFeeds)
throws StreamException {
Expand All @@ -177,6 +189,13 @@ public CompletableFuture<Reaction> addChild(
return add(userID, child, targetFeeds);
}

public CompletableFuture<Reaction> addChild(
String userID, String parentID, Reaction reaction, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData)
throws StreamException {
Reaction child = Reaction.builder().fromReaction(reaction).parent(parentID).build();
return add(userID, child, targetFeeds, targetFeedsExtraData);
}

public CompletableFuture<Void> update(String id, Iterable<FeedID> targetFeeds)
throws StreamException {
return update(id, Iterables.toArray(targetFeeds, FeedID.class));
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/io/getstream/core/StreamReactions.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ public CompletableFuture<Paginated<Reaction>> paginatedFilter(Token token, Strin

public CompletableFuture<Reaction> add(
Token token, String userID, Reaction reaction, FeedID... targetFeeds) throws StreamException {
return add(token, userID, reaction, targetFeeds, null);
}

public CompletableFuture<Reaction> add(
Token token, String userID, Reaction reaction, FeedID[] targetFeeds, Map<String, Object> targetFeedsExtraData) throws StreamException {
checkNotNull(reaction, "Reaction can't be null");
checkArgument(
reaction.getActivityID() != null || reaction.getParent() != null,
Expand All @@ -227,6 +232,9 @@ public CompletableFuture<Reaction> add(
ImmutableMap.Builder<String, Object> payloadBuilder = ImmutableMap.builder();
payloadBuilder.put("kind", reaction.getKind());
payloadBuilder.put("target_feeds", targetFeedIDs);
if (targetFeedsExtraData != null) {
payloadBuilder.put("target_feeds_extra_data", targetFeedsExtraData);
}
if (reaction.getActivityID() != null) {
payloadBuilder.put("activity_id", reaction.getActivityID());
}
Expand Down
118 changes: 118 additions & 0 deletions src/test/java/io/getstream/client/TargetFeedsExtraDataTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package io.getstream.client;

import io.getstream.core.LookupKind;
import io.getstream.core.models.Activity;
import io.getstream.core.models.FeedID;
import io.getstream.core.models.Reaction;
import org.junit.Test;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class TargetFeedsExtraDataTest {
private static final String apiKey =
System.getenv("STREAM_KEY") != null
? System.getenv("STREAM_KEY")
: System.getProperty("STREAM_KEY");
private static final String secret =
System.getenv("STREAM_SECRET") != null
? System.getenv("STREAM_SECRET")
: System.getProperty("STREAM_SECRET");

@Test
public void testTargetFeedsExtraData() throws Exception {
// Create client
Client client = Client.builder(apiKey, secret).build();

// Use unique user id to avoid conflicts in notification feed
String uniqueId = UUID.randomUUID().toString().replace("-", "");
String userId = "test-user-" + uniqueId;

// 1. Create a test activity
String activityId = UUID.randomUUID().toString();
Activity activity = Activity.builder()
.actor(userId)
.verb("post")
.object("test-object")
.foreignID("test-foreignId-" + activityId)
.time(new Date())
.build();

Activity postedActivity = client.flatFeed("user", userId).addActivity(activity).join();

// 2. Create a comment reaction on the activity
Map<String, Object> commentData = new HashMap<>();
commentData.put("text", "This is a test comment");

Reaction comment = Reaction.builder()
.kind("comment")
.activityID(postedActivity.getID())
.extraField("data", commentData)
.build();

Reaction postedComment = client.reactions().add(userId, comment, new FeedID[0]).join();

// 3. Create a like reaction on the comment with targetFeedsExtraData
Map<String, Object> targetFeedsExtraData = new HashMap<>();
String extraDataValue = "SR:" + postedComment.getId();
targetFeedsExtraData.put("parent_reaction", extraDataValue);

FeedID[] targetFeeds = new FeedID[] {
new FeedID("notification", userId)
};

// The critical part of the test: Can we successfully create a reaction with targetFeedsExtraData
Reaction like = client.reactions().addChild(
"actor-" + uniqueId, // Different user performs the like action
"like",
postedComment.getId(),
targetFeeds,
targetFeedsExtraData
).join();

// 4. Verify that the reaction was created successfully
assertNotNull("Like reaction should not be null", like);
assertEquals("Like reaction should have kind='like'", "like", like.getKind());
assertEquals("Like reaction should have parent ID", postedComment.getId(), like.getParent());

// Check if the reaction has extra data
Map<String, Object> reactionExtra = like.getExtra();
assertNotNull("Reaction should have extra data", reactionExtra);

// Check for targetFeedsExtraData directly
assertTrue("Reaction should contain target_feeds_extra_data",
reactionExtra.containsKey("target_feeds_extra_data"));

// Verify the content of targetFeedsExtraData
Object extraDataObj = reactionExtra.get("target_feeds_extra_data");
assertTrue("target_feeds_extra_data should be a Map", extraDataObj instanceof Map);

Map<String, Object> extraDataMap = (Map<String, Object>) extraDataObj;
assertTrue("target_feeds_extra_data should contain parent_reaction",
extraDataMap.containsKey("parent_reaction"));
assertEquals("parent_reaction value should match what we sent",
extraDataValue, extraDataMap.get("parent_reaction"));

// 5. Get the reactions to verify
List<Reaction> reactions = client.reactions().filter(
LookupKind.REACTION,
postedComment.getId(),
"like"
).join();

assertEquals("Should have one like reaction", 1, reactions.size());
assertEquals("Reaction should match the one we created", like.getId(), reactions.get(0).getId());

// Clean up
client.reactions().delete(like.getId()).join();
client.reactions().delete(postedComment.getId()).join();
client.flatFeed("user", userId).removeActivityByID(postedActivity.getID()).join();
}
}
Loading