From f6de824c3b4ff3c2aa4069713e77b9830323f0f1 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 09:27:22 +0200 Subject: [PATCH 01/12] feature(CHA-769): add shared locations support --- .../getstream/chat/java/models/Channel.java | 4 + .../getstream/chat/java/models/Message.java | 8 ++ .../chat/java/models/SharedLocation.java | 72 ++++++++++++++++++ .../java/services/SharedLocationService.java | 15 ++++ .../chat/java/SharedLocationTest.java | 76 +++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 src/main/java/io/getstream/chat/java/models/SharedLocation.java create mode 100644 src/main/java/io/getstream/chat/java/services/SharedLocationService.java create mode 100644 src/test/java/io/getstream/chat/java/SharedLocationTest.java diff --git a/src/main/java/io/getstream/chat/java/models/Channel.java b/src/main/java/io/getstream/chat/java/models/Channel.java index 2e4ffd344..333ea6985 100644 --- a/src/main/java/io/getstream/chat/java/models/Channel.java +++ b/src/main/java/io/getstream/chat/java/models/Channel.java @@ -80,6 +80,10 @@ public class Channel { @JsonProperty("messages") private List messages; + @Nullable + @JsonProperty("active_live_locations") + private List activeLiveLocations; + @Nullable @JsonProperty("read") private List read; diff --git a/src/main/java/io/getstream/chat/java/models/Message.java b/src/main/java/io/getstream/chat/java/models/Message.java index f037c063a..57b12e19d 100644 --- a/src/main/java/io/getstream/chat/java/models/Message.java +++ b/src/main/java/io/getstream/chat/java/models/Message.java @@ -168,6 +168,10 @@ public class Message { @JsonProperty("pinned_at") private Date pinnedAt; + @Nullable + @JsonProperty("shared_location") + private SharedLocation sharedLocation; + @NotNull @JsonIgnore private Map additionalFields = new HashMap<>(); @JsonAnyGetter @@ -491,6 +495,10 @@ public static class MessageRequestObject { @JsonProperty("pinned_at") private Date pinnedAt; + @Nullable + @JsonProperty("shared_location") + private SharedLocation sharedLocation; + @Singular @Nullable @JsonIgnore private Map additionalFields; @JsonAnyGetter diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java new file mode 100644 index 000000000..f6df98da8 --- /dev/null +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -0,0 +1,72 @@ +package io.getstream.chat.java.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; + +@Data +@Builder +public class SharedLocation { + @JsonProperty("channel_cid") + private String channelCid; + + @JsonProperty("created_at") + private Date createdAt; + + @JsonProperty("created_by_device_id") + private String createdByDeviceId; + + @JsonProperty("end_at") + private Date endAt; + + private Double latitude; + private Double longitude; + + @JsonProperty("message_id") + private String messageId; + + @JsonProperty("updated_at") + private Date updatedAt; + + @JsonProperty("user_id") + private String userId; + + @Data + @Builder + public static class SharedLocationRequest { + @JsonProperty("created_by_device_id") + private String createdByDeviceId; + + @Nullable + @JsonProperty("end_at") + private String endAt; + + @Nullable + private Double latitude; + + @Nullable + private Double longitude; + } + + @Data + @Builder + public static class SharedLocationResponse { + @JsonProperty("created_by_device_id") + private String createdByDeviceId; + + @JsonProperty("end_at") + private String endAt; + + private Double latitude; + private Double longitude; + } + + @Data + @Builder + public static class ActiveLiveLocationsResponse { + @JsonProperty("active_live_locations") + private List activeLiveLocations; + } +} \ No newline at end of file diff --git a/src/main/java/io/getstream/chat/java/services/SharedLocationService.java b/src/main/java/io/getstream/chat/java/services/SharedLocationService.java new file mode 100644 index 000000000..c10cbb8c9 --- /dev/null +++ b/src/main/java/io/getstream/chat/java/services/SharedLocationService.java @@ -0,0 +1,15 @@ +package io.getstream.chat.java.services; + +import io.getstream.chat.java.models.SharedLocation; +import org.jetbrains.annotations.NotNull; +import retrofit2.Call; +import retrofit2.http.*; + +public interface SharedLocationService { + @GET("users/locations") + Call getLiveLocations(); + + @PUT("users/location") + Call updateLiveLocation( + @NotNull @Body SharedLocation.SharedLocationRequest sharedLocationRequest); +} diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java new file mode 100644 index 000000000..28d3661c2 --- /dev/null +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -0,0 +1,76 @@ +package io.getstream.chat.java; + +import io.getstream.chat.java.exceptions.StreamException; +import io.getstream.chat.java.models.SharedLocation; +import io.getstream.chat.java.models.SharedLocation.SharedLocationRequest; +import io.getstream.chat.java.models.SharedLocation.SharedLocationResponse; +import io.getstream.chat.java.models.SharedLocation.ActiveLiveLocationsResponse; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +public class SharedLocationTest extends BasicTest { + + @DisplayName("Can update and get live location") + @Test + void whenUpdatingLiveLocation_thenNoException() throws StreamException { + String deviceId = "device-" + UUID.randomUUID().toString(); + SharedLocationRequest request = SharedLocationRequest.builder() + .createdByDeviceId(deviceId) + .latitude(40.7128) + .longitude(-74.0060) + .endAt("2024-12-31T23:59:59Z") + .build(); + + SharedLocationResponse response = SharedLocation.updateLocation() + .request(request) + .request(); + + Assertions.assertNotNull(response); + Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); + Assertions.assertEquals(40.7128, response.getLatitude()); + Assertions.assertEquals(-74.0060, response.getLongitude()); + Assertions.assertEquals("2024-12-31T23:59:59Z", response.getEndAt()); + + ActiveLiveLocationsResponse locationsResponse = SharedLocation.getLocations() + .request(); + + Assertions.assertNotNull(locationsResponse); + Assertions.assertNotNull(locationsResponse.getActiveLiveLocations()); + Assertions.assertTrue(locationsResponse.getActiveLiveLocations().size() > 0); + } + + @DisplayName("Can update live location") + @Test + void whenUpdatingLiveLocationWithMinimalData_thenNoException() throws StreamException { + String deviceId = "device-" + UUID.randomUUID().toString(); + SharedLocationRequest request = SharedLocationRequest.builder() + .createdByDeviceId(deviceId) + .latitude(40.7128) + .longitude(-74.0060) + .build(); + + SharedLocationResponse response = SharedLocation.updateLocation() + .request(request) + .request(); + + Assertions.assertNotNull(response); + Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); + Assertions.assertNull(response.getLatitude()); + Assertions.assertNull(response.getLongitude()); + Assertions.assertNull(response.getEndAt()); + } + + @DisplayName("Can get empty live locations list") + @Test + void whenGettingEmptyLiveLocations_thenNoException() throws StreamException { + ActiveLiveLocationsResponse response = SharedLocation.getLocations() + .request(); + + Assertions.assertNotNull(response); + Assertions.assertNotNull(response.getActiveLiveLocations()); + Assertions.assertTrue(response.getActiveLiveLocations().isEmpty()); + } +} \ No newline at end of file From d97af3de288bbc609b40a6cd882107119ce86fb7 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 10:39:07 +0200 Subject: [PATCH 02/12] format --- .../chat/java/models/SharedLocation.java | 117 +++++++++--------- .../chat/java/SharedLocationTest.java | 105 ++++++++-------- 2 files changed, 108 insertions(+), 114 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java index f6df98da8..79f003ed2 100644 --- a/src/main/java/io/getstream/chat/java/models/SharedLocation.java +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -1,72 +1,71 @@ package io.getstream.chat.java.models; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.*; +import java.util.Date; +import java.util.List; import lombok.Builder; import lombok.Data; - -import java.util.Date; +import org.jetbrains.annotations.Nullable; @Data @Builder public class SharedLocation { - @JsonProperty("channel_cid") - private String channelCid; - - @JsonProperty("created_at") - private Date createdAt; - + @JsonProperty("channel_cid") + private String channelCid; + + @JsonProperty("created_at") + private Date createdAt; + + @JsonProperty("created_by_device_id") + private String createdByDeviceId; + + @JsonProperty("end_at") + private Date endAt; + + private Double latitude; + private Double longitude; + + @JsonProperty("message_id") + private String messageId; + + @JsonProperty("updated_at") + private Date updatedAt; + + @JsonProperty("user_id") + private String userId; + + @Data + @Builder + public static class SharedLocationRequest { @JsonProperty("created_by_device_id") private String createdByDeviceId; - + + @Nullable + @JsonProperty("end_at") + private String endAt; + + @Nullable private Double latitude; + + @Nullable private Double longitude; + } + + @Data + @Builder + public static class SharedLocationResponse { + @JsonProperty("created_by_device_id") + private String createdByDeviceId; + @JsonProperty("end_at") - private Date endAt; - + private String endAt; + private Double latitude; private Double longitude; - - @JsonProperty("message_id") - private String messageId; - - @JsonProperty("updated_at") - private Date updatedAt; - - @JsonProperty("user_id") - private String userId; - - @Data - @Builder - public static class SharedLocationRequest { - @JsonProperty("created_by_device_id") - private String createdByDeviceId; - - @Nullable - @JsonProperty("end_at") - private String endAt; - - @Nullable - private Double latitude; - - @Nullable - private Double longitude; - } - - @Data - @Builder - public static class SharedLocationResponse { - @JsonProperty("created_by_device_id") - private String createdByDeviceId; - - @JsonProperty("end_at") - private String endAt; - - private Double latitude; - private Double longitude; - } - - @Data - @Builder - public static class ActiveLiveLocationsResponse { - @JsonProperty("active_live_locations") - private List activeLiveLocations; - } -} \ No newline at end of file + } + + @Data + @Builder + public static class ActiveLiveLocationsResponse { + @JsonProperty("active_live_locations") + private List activeLiveLocations; + } +} diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java index 28d3661c2..a63ddc5e9 100644 --- a/src/test/java/io/getstream/chat/java/SharedLocationTest.java +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -2,75 +2,70 @@ import io.getstream.chat.java.exceptions.StreamException; import io.getstream.chat.java.models.SharedLocation; +import io.getstream.chat.java.models.SharedLocation.ActiveLiveLocationsResponse; import io.getstream.chat.java.models.SharedLocation.SharedLocationRequest; import io.getstream.chat.java.models.SharedLocation.SharedLocationResponse; -import io.getstream.chat.java.models.SharedLocation.ActiveLiveLocationsResponse; +import java.util.UUID; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.UUID; - public class SharedLocationTest extends BasicTest { - @DisplayName("Can update and get live location") - @Test - void whenUpdatingLiveLocation_thenNoException() throws StreamException { - String deviceId = "device-" + UUID.randomUUID().toString(); - SharedLocationRequest request = SharedLocationRequest.builder() - .createdByDeviceId(deviceId) - .latitude(40.7128) - .longitude(-74.0060) - .endAt("2024-12-31T23:59:59Z") - .build(); + @DisplayName("Can update and get live location") + @Test + void whenUpdatingLiveLocation_thenNoException() throws StreamException { + String deviceId = "device-" + UUID.randomUUID().toString(); + SharedLocationRequest request = + SharedLocationRequest.builder() + .createdByDeviceId(deviceId) + .latitude(40.7128) + .longitude(-74.0060) + .endAt("2024-12-31T23:59:59Z") + .build(); - SharedLocationResponse response = SharedLocation.updateLocation() - .request(request) - .request(); + SharedLocationResponse response = SharedLocation.updateLocation().request(request).request(); - Assertions.assertNotNull(response); - Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); - Assertions.assertEquals(40.7128, response.getLatitude()); - Assertions.assertEquals(-74.0060, response.getLongitude()); - Assertions.assertEquals("2024-12-31T23:59:59Z", response.getEndAt()); + Assertions.assertNotNull(response); + Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); + Assertions.assertEquals(40.7128, response.getLatitude()); + Assertions.assertEquals(-74.0060, response.getLongitude()); + Assertions.assertEquals("2024-12-31T23:59:59Z", response.getEndAt()); - ActiveLiveLocationsResponse locationsResponse = SharedLocation.getLocations() - .request(); + ActiveLiveLocationsResponse locationsResponse = SharedLocation.getLocations().request(); - Assertions.assertNotNull(locationsResponse); - Assertions.assertNotNull(locationsResponse.getActiveLiveLocations()); - Assertions.assertTrue(locationsResponse.getActiveLiveLocations().size() > 0); - } + Assertions.assertNotNull(locationsResponse); + Assertions.assertNotNull(locationsResponse.getActiveLiveLocations()); + Assertions.assertTrue(locationsResponse.getActiveLiveLocations().size() > 0); + } - @DisplayName("Can update live location") - @Test - void whenUpdatingLiveLocationWithMinimalData_thenNoException() throws StreamException { - String deviceId = "device-" + UUID.randomUUID().toString(); - SharedLocationRequest request = SharedLocationRequest.builder() - .createdByDeviceId(deviceId) - .latitude(40.7128) - .longitude(-74.0060) - .build(); + @DisplayName("Can update live location") + @Test + void whenUpdatingLiveLocationWithMinimalData_thenNoException() throws StreamException { + String deviceId = "device-" + UUID.randomUUID().toString(); + SharedLocationRequest request = + SharedLocationRequest.builder() + .createdByDeviceId(deviceId) + .latitude(40.7128) + .longitude(-74.0060) + .build(); - SharedLocationResponse response = SharedLocation.updateLocation() - .request(request) - .request(); + SharedLocationResponse response = SharedLocation.updateLocation().request(request).request(); - Assertions.assertNotNull(response); - Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); - Assertions.assertNull(response.getLatitude()); - Assertions.assertNull(response.getLongitude()); - Assertions.assertNull(response.getEndAt()); - } + Assertions.assertNotNull(response); + Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); + Assertions.assertNull(response.getLatitude()); + Assertions.assertNull(response.getLongitude()); + Assertions.assertNull(response.getEndAt()); + } - @DisplayName("Can get empty live locations list") - @Test - void whenGettingEmptyLiveLocations_thenNoException() throws StreamException { - ActiveLiveLocationsResponse response = SharedLocation.getLocations() - .request(); + @DisplayName("Can get empty live locations list") + @Test + void whenGettingEmptyLiveLocations_thenNoException() throws StreamException { + ActiveLiveLocationsResponse response = SharedLocation.getLocations().request(); - Assertions.assertNotNull(response); - Assertions.assertNotNull(response.getActiveLiveLocations()); - Assertions.assertTrue(response.getActiveLiveLocations().isEmpty()); - } -} \ No newline at end of file + Assertions.assertNotNull(response); + Assertions.assertNotNull(response.getActiveLiveLocations()); + Assertions.assertTrue(response.getActiveLiveLocations().isEmpty()); + } +} From 157f106a63855f89e88e17c7b3cc1c4171a56903 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 10:49:20 +0200 Subject: [PATCH 03/12] fix model --- build.gradle | 1 + .../chat/java/models/SharedLocation.java | 50 ++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 58cdae42f..a3b7a09b7 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,7 @@ dependencies { testImplementation 'org.apache.commons:commons-lang3:3.12.0' compileOnly 'org.projectlombok:lombok:1.18.32' annotationProcessor 'org.projectlombok:lombok:1.18.32' + compileOnly 'org.jetbrains:annotations:24.1.0' testCompileOnly 'org.projectlombok:lombok:1.18.32' testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java index 79f003ed2..617851d19 100644 --- a/src/main/java/io/getstream/chat/java/models/SharedLocation.java +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -1,11 +1,15 @@ package io.getstream.chat.java.models; -import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.getstream.chat.java.StreamClient; +import io.getstream.chat.java.exceptions.StreamException; import java.util.Date; import java.util.List; import lombok.Builder; import lombok.Data; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import retrofit2.Response; @Data @Builder @@ -68,4 +72,48 @@ public static class ActiveLiveLocationsResponse { @JsonProperty("active_live_locations") private List activeLiveLocations; } + + public static UpdateLocationRequest updateLocation() { + return new UpdateLocationRequest(); + } + + public static GetLocationsRequest getLocations() { + return new GetLocationsRequest(); + } + + public static class UpdateLocationRequest { + private SharedLocationRequest request; + + public UpdateLocationRequest request(@NotNull SharedLocationRequest request) { + this.request = request; + return this; + } + + public SharedLocationResponse request() throws StreamException { + Response response = + StreamClient.getInstance() + .getSharedLocationService() + .updateLiveLocation(request) + .execute(); + + if (!response.isSuccessful()) { + throw new StreamException("Failed to update live location: " + response.code()); + } + + return response.body(); + } + } + + public static class GetLocationsRequest { + public ActiveLiveLocationsResponse request() throws StreamException { + Response response = + StreamClient.getInstance().getSharedLocationService().getLiveLocations().execute(); + + if (!response.isSuccessful()) { + throw new StreamException("Failed to get live locations: " + response.code()); + } + + return response.body(); + } + } } From 4923ae3c681c8e9f2d01744c798db4c5ff2d8f8d Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 11:02:15 +0200 Subject: [PATCH 04/12] fix import --- src/main/java/io/getstream/chat/java/models/SharedLocation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java index 617851d19..253dbe342 100644 --- a/src/main/java/io/getstream/chat/java/models/SharedLocation.java +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -1,7 +1,6 @@ package io.getstream.chat.java.models; import com.fasterxml.jackson.annotation.JsonProperty; -import io.getstream.chat.java.StreamClient; import io.getstream.chat.java.exceptions.StreamException; import java.util.Date; import java.util.List; From 1453bb7d4e1f420152f97c791433e67b5f762956 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 11:13:25 +0200 Subject: [PATCH 05/12] fix model --- .../chat/java/models/SharedLocation.java | 98 ++++++++++--------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java index 253dbe342..87fafddaa 100644 --- a/src/main/java/io/getstream/chat/java/models/SharedLocation.java +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -1,17 +1,19 @@ package io.getstream.chat.java.models; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.getstream.chat.java.exceptions.StreamException; +import com.fasterxml.jackson.annotation.*; +import io.getstream.chat.java.models.framework.StreamRequest; +import io.getstream.chat.java.models.framework.StreamResponseObject; +import io.getstream.chat.java.services.SharedLocationService; +import io.getstream.chat.java.services.framework.Client; import java.util.Date; import java.util.List; -import lombok.Builder; -import lombok.Data; +import lombok.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import retrofit2.Response; +import retrofit2.Call; @Data -@Builder +@NoArgsConstructor public class SharedLocation { @JsonProperty("channel_cid") private String channelCid; @@ -38,7 +40,7 @@ public class SharedLocation { private String userId; @Data - @Builder + @NoArgsConstructor public static class SharedLocationRequest { @JsonProperty("created_by_device_id") private String createdByDeviceId; @@ -53,8 +55,9 @@ public static class SharedLocationRequest { } @Data - @Builder - public static class SharedLocationResponse { + @NoArgsConstructor + @EqualsAndHashCode(callSuper = true) + public static class SharedLocationResponse extends StreamResponseObject { @JsonProperty("created_by_device_id") private String createdByDeviceId; @@ -66,53 +69,60 @@ public static class SharedLocationResponse { } @Data - @Builder - public static class ActiveLiveLocationsResponse { + @NoArgsConstructor + @EqualsAndHashCode(callSuper = true) + public static class ActiveLiveLocationsResponse extends StreamResponseObject { @JsonProperty("active_live_locations") private List activeLiveLocations; } - public static UpdateLocationRequest updateLocation() { - return new UpdateLocationRequest(); - } - - public static GetLocationsRequest getLocations() { - return new GetLocationsRequest(); - } - - public static class UpdateLocationRequest { + @Builder( + builderClassName = "UpdateLocationRequest", + builderMethodName = "", + buildMethodName = "internalBuild") + public static class UpdateLocationRequestData { + @NotNull + @JsonProperty("request") private SharedLocationRequest request; - public UpdateLocationRequest request(@NotNull SharedLocationRequest request) { - this.request = request; - return this; + public static class UpdateLocationRequest extends StreamRequest { + @Override + protected Call generateCall(Client client) { + return client.create(SharedLocationService.class).updateLiveLocation(this.internalBuild()); + } } + } - public SharedLocationResponse request() throws StreamException { - Response response = - StreamClient.getInstance() - .getSharedLocationService() - .updateLiveLocation(request) - .execute(); - - if (!response.isSuccessful()) { - throw new StreamException("Failed to update live location: " + response.code()); + @Builder( + builderClassName = "GetLocationsRequest", + builderMethodName = "", + buildMethodName = "internalBuild") + public static class GetLocationsRequestData { + public static class GetLocationsRequest extends StreamRequest { + @Override + protected Call generateCall(Client client) { + return client.create(SharedLocationService.class).getLiveLocations(); } - - return response.body(); } } - public static class GetLocationsRequest { - public ActiveLiveLocationsResponse request() throws StreamException { - Response response = - StreamClient.getInstance().getSharedLocationService().getLiveLocations().execute(); - - if (!response.isSuccessful()) { - throw new StreamException("Failed to get live locations: " + response.code()); - } + /** + * Creates an update location request + * + * @return the created request + */ + @NotNull + public static UpdateLocationRequest updateLocation() { + return new UpdateLocationRequest(); + } - return response.body(); - } + /** + * Creates a get locations request + * + * @return the created request + */ + @NotNull + public static GetLocationsRequest getLocations() { + return new GetLocationsRequest(); } } From 4dc3741475e71293f6cdac1435f858479ee01d62 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 12:02:55 +0200 Subject: [PATCH 06/12] fix model and test --- .../chat/java/models/SharedLocation.java | 45 +++++++++++++------ .../chat/java/SharedLocationTest.java | 22 ++++----- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java index 87fafddaa..0231dd0c9 100644 --- a/src/main/java/io/getstream/chat/java/models/SharedLocation.java +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -76,27 +76,46 @@ public static class ActiveLiveLocationsResponse extends StreamResponseObject { private List activeLiveLocations; } - @Builder( - builderClassName = "UpdateLocationRequest", - builderMethodName = "", - buildMethodName = "internalBuild") public static class UpdateLocationRequestData { @NotNull @JsonProperty("request") private SharedLocationRequest request; + public UpdateLocationRequestData() {} + + public UpdateLocationRequestData(SharedLocationRequest request) { + this.request = request; + } + + public SharedLocationRequest getRequest() { + return request; + } + + public void setRequest(SharedLocationRequest request) { + this.request = request; + } + public static class UpdateLocationRequest extends StreamRequest { + private SharedLocationRequest request; + + public UpdateLocationRequest() {} + + public UpdateLocationRequest(SharedLocationRequest request) { + this.request = request; + } + + public UpdateLocationRequest request(SharedLocationRequest request) { + this.request = request; + return this; + } + @Override protected Call generateCall(Client client) { - return client.create(SharedLocationService.class).updateLiveLocation(this.internalBuild()); + return client.create(SharedLocationService.class).updateLiveLocation(request); } } } - @Builder( - builderClassName = "GetLocationsRequest", - builderMethodName = "", - buildMethodName = "internalBuild") public static class GetLocationsRequestData { public static class GetLocationsRequest extends StreamRequest { @Override @@ -112,8 +131,8 @@ protected Call generateCall(Client client) { * @return the created request */ @NotNull - public static UpdateLocationRequest updateLocation() { - return new UpdateLocationRequest(); + public static UpdateLocationRequestData.UpdateLocationRequest updateLocation() { + return new UpdateLocationRequestData.UpdateLocationRequest(); } /** @@ -122,7 +141,7 @@ public static UpdateLocationRequest updateLocation() { * @return the created request */ @NotNull - public static GetLocationsRequest getLocations() { - return new GetLocationsRequest(); + public static GetLocationsRequestData.GetLocationsRequest getLocations() { + return new GetLocationsRequestData.GetLocationsRequest(); } } diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java index a63ddc5e9..78026c8c1 100644 --- a/src/test/java/io/getstream/chat/java/SharedLocationTest.java +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -16,13 +16,11 @@ public class SharedLocationTest extends BasicTest { @Test void whenUpdatingLiveLocation_thenNoException() throws StreamException { String deviceId = "device-" + UUID.randomUUID().toString(); - SharedLocationRequest request = - SharedLocationRequest.builder() - .createdByDeviceId(deviceId) - .latitude(40.7128) - .longitude(-74.0060) - .endAt("2024-12-31T23:59:59Z") - .build(); + SharedLocationRequest request = new SharedLocation.SharedLocationRequest(); + request.setCreatedByDeviceId(deviceId); + request.setLatitude(40.7128); + request.setLongitude(-74.0060); + request.setEndAt("2024-12-31T23:59:59Z"); SharedLocationResponse response = SharedLocation.updateLocation().request(request).request(); @@ -43,12 +41,10 @@ void whenUpdatingLiveLocation_thenNoException() throws StreamException { @Test void whenUpdatingLiveLocationWithMinimalData_thenNoException() throws StreamException { String deviceId = "device-" + UUID.randomUUID().toString(); - SharedLocationRequest request = - SharedLocationRequest.builder() - .createdByDeviceId(deviceId) - .latitude(40.7128) - .longitude(-74.0060) - .build(); + SharedLocationRequest request = new SharedLocation.SharedLocationRequest(); + request.setCreatedByDeviceId(deviceId); + request.setLatitude(40.7128); + request.setLongitude(-74.0060); SharedLocationResponse response = SharedLocation.updateLocation().request(request).request(); From a5f4f24cc85b0579690cbfd42c02401ee62d0ee1 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 13:43:53 +0200 Subject: [PATCH 07/12] fix tests --- .../getstream/chat/java/models/Message.java | 6 + .../chat/java/models/SharedLocation.java | 25 ++- .../java/services/SharedLocationService.java | 4 +- .../chat/java/SharedLocationTest.java | 160 +++++++++++++----- 4 files changed, 153 insertions(+), 42 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/Message.java b/src/main/java/io/getstream/chat/java/models/Message.java index 57b12e19d..7b4f19ac3 100644 --- a/src/main/java/io/getstream/chat/java/models/Message.java +++ b/src/main/java/io/getstream/chat/java/models/Message.java @@ -499,6 +499,12 @@ public static class MessageRequestObject { @JsonProperty("shared_location") private SharedLocation sharedLocation; + @NotNull + public MessageRequestObject setSharedLocation(@Nullable SharedLocation sharedLocation) { + this.sharedLocation = sharedLocation; + return this; + } + @Singular @Nullable @JsonIgnore private Map additionalFields; @JsonAnyGetter diff --git a/src/main/java/io/getstream/chat/java/models/SharedLocation.java b/src/main/java/io/getstream/chat/java/models/SharedLocation.java index 0231dd0c9..32ce19938 100644 --- a/src/main/java/io/getstream/chat/java/models/SharedLocation.java +++ b/src/main/java/io/getstream/chat/java/models/SharedLocation.java @@ -42,6 +42,9 @@ public class SharedLocation { @Data @NoArgsConstructor public static class SharedLocationRequest { + @JsonProperty("message_id") + private String messageId; + @JsonProperty("created_by_device_id") private String createdByDeviceId; @@ -52,6 +55,9 @@ public static class SharedLocationRequest { @Nullable private Double latitude; @Nullable private Double longitude; + + @JsonProperty("user_id") + private String userId; } @Data @@ -97,6 +103,7 @@ public void setRequest(SharedLocationRequest request) { public static class UpdateLocationRequest extends StreamRequest { private SharedLocationRequest request; + private String userId; public UpdateLocationRequest() {} @@ -109,18 +116,32 @@ public UpdateLocationRequest request(SharedLocationRequest request) { return this; } + public UpdateLocationRequest userId(String userId) { + this.userId = userId; + return this; + } + @Override protected Call generateCall(Client client) { - return client.create(SharedLocationService.class).updateLiveLocation(request); + return client.create(SharedLocationService.class).updateLiveLocation(userId, request); } } } public static class GetLocationsRequestData { public static class GetLocationsRequest extends StreamRequest { + private String userId; + + public GetLocationsRequest() {} + + public GetLocationsRequest userId(String userId) { + this.userId = userId; + return this; + } + @Override protected Call generateCall(Client client) { - return client.create(SharedLocationService.class).getLiveLocations(); + return client.create(SharedLocationService.class).getLiveLocations(userId); } } } diff --git a/src/main/java/io/getstream/chat/java/services/SharedLocationService.java b/src/main/java/io/getstream/chat/java/services/SharedLocationService.java index c10cbb8c9..f2725397f 100644 --- a/src/main/java/io/getstream/chat/java/services/SharedLocationService.java +++ b/src/main/java/io/getstream/chat/java/services/SharedLocationService.java @@ -7,9 +7,11 @@ public interface SharedLocationService { @GET("users/locations") - Call getLiveLocations(); + Call getLiveLocations( + @NotNull @Query("user_id") String userId); @PUT("users/location") Call updateLiveLocation( + @NotNull @Query("user_id") String userId, @NotNull @Body SharedLocation.SharedLocationRequest sharedLocationRequest); } diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java index 78026c8c1..99d356638 100644 --- a/src/test/java/io/getstream/chat/java/SharedLocationTest.java +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -1,10 +1,20 @@ package io.getstream.chat.java; import io.getstream.chat.java.exceptions.StreamException; +import io.getstream.chat.java.models.Message; +import io.getstream.chat.java.models.Message.MessageRequestObject; +import io.getstream.chat.java.models.Message.MessageType; import io.getstream.chat.java.models.SharedLocation; import io.getstream.chat.java.models.SharedLocation.ActiveLiveLocationsResponse; import io.getstream.chat.java.models.SharedLocation.SharedLocationRequest; import io.getstream.chat.java.models.SharedLocation.SharedLocationResponse; +import io.getstream.chat.java.models.User.UserRequestObject; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.TimeZone; import java.util.UUID; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -12,56 +22,128 @@ public class SharedLocationTest extends BasicTest { - @DisplayName("Can update and get live location") + @DisplayName("Can send message with shared location and verify") @Test - void whenUpdatingLiveLocation_thenNoException() throws StreamException { + void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() throws StreamException, ParseException { + // Create a unique device ID for this test String deviceId = "device-" + UUID.randomUUID().toString(); - SharedLocationRequest request = new SharedLocation.SharedLocationRequest(); - request.setCreatedByDeviceId(deviceId); - request.setLatitude(40.7128); - request.setLongitude(-74.0060); - request.setEndAt("2024-12-31T23:59:59Z"); + + // Create shared location request + SharedLocationRequest locationRequest = new SharedLocation.SharedLocationRequest(); + locationRequest.setCreatedByDeviceId(deviceId); + locationRequest.setLatitude(40.7128); + locationRequest.setLongitude(-74.0060); + locationRequest.setEndAt("2025-12-31T23:59:59Z"); + locationRequest.setUserId(testUserRequestObject.getId()); - SharedLocationResponse response = SharedLocation.updateLocation().request(request).request(); + // Convert request to SharedLocation + SharedLocation sharedLocation = new SharedLocation(); + sharedLocation.setCreatedByDeviceId(locationRequest.getCreatedByDeviceId()); + sharedLocation.setLatitude(locationRequest.getLatitude()); + sharedLocation.setLongitude(locationRequest.getLongitude()); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + sharedLocation.setEndAt(dateFormat.parse(locationRequest.getEndAt())); - Assertions.assertNotNull(response); - Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); - Assertions.assertEquals(40.7128, response.getLatitude()); - Assertions.assertEquals(-74.0060, response.getLongitude()); - Assertions.assertEquals("2024-12-31T23:59:59Z", response.getEndAt()); + // Send message with shared location + MessageRequestObject messageRequest = MessageRequestObject.builder() + .text("I'm sharing my live location") + .userId(testUserRequestObject.getId()) + .type(MessageType.REGULAR) + .sharedLocation(sharedLocation) + .build(); - ActiveLiveLocationsResponse locationsResponse = SharedLocation.getLocations().request(); + Message message = Message.send(testChannel.getType(), testChannel.getId()) + .message(messageRequest) + .request() + .getMessage(); - Assertions.assertNotNull(locationsResponse); - Assertions.assertNotNull(locationsResponse.getActiveLiveLocations()); - Assertions.assertTrue(locationsResponse.getActiveLiveLocations().size() > 0); + // Verify message was sent with correct shared location + Assertions.assertNotNull(message); + Assertions.assertNotNull(message.getSharedLocation()); + Assertions.assertEquals(deviceId, message.getSharedLocation().getCreatedByDeviceId()); + Assertions.assertEquals(40.7128, message.getSharedLocation().getLatitude()); + Assertions.assertEquals(-74.0060, message.getSharedLocation().getLongitude()); + + // Parse and verify the endAt date + Date expectedEndAt = dateFormat.parse("2025-12-31T23:59:59Z"); + Assertions.assertEquals(expectedEndAt, message.getSharedLocation().getEndAt()); } - @DisplayName("Can update live location") + @DisplayName("Can create live location, update it and verify the update") @Test - void whenUpdatingLiveLocationWithMinimalData_thenNoException() throws StreamException { + void whenUpdatingLiveLocation_thenCanGetUpdatedLocation() throws StreamException, ParseException { + // Create a unique device ID for this test String deviceId = "device-" + UUID.randomUUID().toString(); - SharedLocationRequest request = new SharedLocation.SharedLocationRequest(); - request.setCreatedByDeviceId(deviceId); - request.setLatitude(40.7128); - request.setLongitude(-74.0060); - - SharedLocationResponse response = SharedLocation.updateLocation().request(request).request(); - - Assertions.assertNotNull(response); - Assertions.assertEquals(deviceId, response.getCreatedByDeviceId()); - Assertions.assertNull(response.getLatitude()); - Assertions.assertNull(response.getLongitude()); - Assertions.assertNull(response.getEndAt()); - } + + // Create initial shared location request + SharedLocationRequest initialLocationRequest = new SharedLocation.SharedLocationRequest(); + initialLocationRequest.setCreatedByDeviceId(deviceId); + initialLocationRequest.setLatitude(40.7128); + initialLocationRequest.setLongitude(-74.0060); + initialLocationRequest.setEndAt("2025-12-31T23:59:59Z"); + initialLocationRequest.setUserId(testUserRequestObject.getId()); - @DisplayName("Can get empty live locations list") - @Test - void whenGettingEmptyLiveLocations_thenNoException() throws StreamException { - ActiveLiveLocationsResponse response = SharedLocation.getLocations().request(); + // Convert request to SharedLocation + SharedLocation initialSharedLocation = new SharedLocation(); + initialSharedLocation.setCreatedByDeviceId(initialLocationRequest.getCreatedByDeviceId()); + initialSharedLocation.setLatitude(initialLocationRequest.getLatitude()); + initialSharedLocation.setLongitude(initialLocationRequest.getLongitude()); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + initialSharedLocation.setEndAt(dateFormat.parse(initialLocationRequest.getEndAt())); + + // Send initial message with shared location + MessageRequestObject initialMessageRequest = MessageRequestObject.builder() + .text("I'm sharing my live location") + .userId(testUserRequestObject.getId()) + .type(MessageType.REGULAR) + .sharedLocation(initialSharedLocation) + .build(); + + Message initialMessage = Message.send(testChannel.getType(), testChannel.getId()) + .message(initialMessageRequest) + .request() + .getMessage(); + + // Create updated location request + SharedLocationRequest updatedLocationRequest = new SharedLocation.SharedLocationRequest(); + updatedLocationRequest.setMessageId(initialMessage.getId()); + updatedLocationRequest.setCreatedByDeviceId(deviceId); + updatedLocationRequest.setLatitude(40.7589); // Updated latitude + updatedLocationRequest.setLongitude(-73.9851); // Updated longitude + updatedLocationRequest.setEndAt("2025-12-31T23:59:59Z"); + updatedLocationRequest.setUserId(testUserRequestObject.getId()); + + // Update the location + SharedLocation.SharedLocationResponse updateResponse = SharedLocation.updateLocation() + .userId(testUserRequestObject.getId()) + .request(updatedLocationRequest) + .request(); + + // Get active live locations + ActiveLiveLocationsResponse activeLocations = SharedLocation.getLocations() + .userId(testUserRequestObject.getId()) + .request(); + + // Verify the updated location + Assertions.assertNotNull(activeLocations); + Assertions.assertNotNull(activeLocations.getActiveLiveLocations()); + Assertions.assertFalse(activeLocations.getActiveLiveLocations().isEmpty()); + + // Find our location in the response + SharedLocation updatedLocation = activeLocations.getActiveLiveLocations().stream() + .filter(loc -> deviceId.equals(loc.getCreatedByDeviceId())) + .findFirst() + .orElse(null); - Assertions.assertNotNull(response); - Assertions.assertNotNull(response.getActiveLiveLocations()); - Assertions.assertTrue(response.getActiveLiveLocations().isEmpty()); + Assertions.assertNotNull(updatedLocation); + Assertions.assertEquals(deviceId, updatedLocation.getCreatedByDeviceId()); + Assertions.assertEquals(40.7589, updatedLocation.getLatitude()); + Assertions.assertEquals(-73.9851, updatedLocation.getLongitude()); + + // Verify the endAt date + Date expectedEndAt = dateFormat.parse("2025-12-31T23:59:59Z"); + Assertions.assertEquals(expectedEndAt, updatedLocation.getEndAt()); } } From 48aa8e673285952a7b267c1ed6be9fc4af0c575c Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 13:48:22 +0200 Subject: [PATCH 08/12] format --- .../chat/java/SharedLocationTest.java | 86 ++++++++++--------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java index 99d356638..c694bae4c 100644 --- a/src/test/java/io/getstream/chat/java/SharedLocationTest.java +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -7,13 +7,9 @@ import io.getstream.chat.java.models.SharedLocation; import io.getstream.chat.java.models.SharedLocation.ActiveLiveLocationsResponse; import io.getstream.chat.java.models.SharedLocation.SharedLocationRequest; -import io.getstream.chat.java.models.SharedLocation.SharedLocationResponse; -import io.getstream.chat.java.models.User.UserRequestObject; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.TimeZone; import java.util.UUID; import org.junit.jupiter.api.Assertions; @@ -24,10 +20,11 @@ public class SharedLocationTest extends BasicTest { @DisplayName("Can send message with shared location and verify") @Test - void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() throws StreamException, ParseException { + void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() + throws StreamException, ParseException { // Create a unique device ID for this test String deviceId = "device-" + UUID.randomUUID().toString(); - + // Create shared location request SharedLocationRequest locationRequest = new SharedLocation.SharedLocationRequest(); locationRequest.setCreatedByDeviceId(deviceId); @@ -46,17 +43,19 @@ void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() thro sharedLocation.setEndAt(dateFormat.parse(locationRequest.getEndAt())); // Send message with shared location - MessageRequestObject messageRequest = MessageRequestObject.builder() - .text("I'm sharing my live location") - .userId(testUserRequestObject.getId()) - .type(MessageType.REGULAR) - .sharedLocation(sharedLocation) - .build(); - - Message message = Message.send(testChannel.getType(), testChannel.getId()) - .message(messageRequest) - .request() - .getMessage(); + MessageRequestObject messageRequest = + MessageRequestObject.builder() + .text("I'm sharing my live location") + .userId(testUserRequestObject.getId()) + .type(MessageType.REGULAR) + .sharedLocation(sharedLocation) + .build(); + + Message message = + Message.send(testChannel.getType(), testChannel.getId()) + .message(messageRequest) + .request() + .getMessage(); // Verify message was sent with correct shared location Assertions.assertNotNull(message); @@ -64,7 +63,7 @@ void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() thro Assertions.assertEquals(deviceId, message.getSharedLocation().getCreatedByDeviceId()); Assertions.assertEquals(40.7128, message.getSharedLocation().getLatitude()); Assertions.assertEquals(-74.0060, message.getSharedLocation().getLongitude()); - + // Parse and verify the endAt date Date expectedEndAt = dateFormat.parse("2025-12-31T23:59:59Z"); Assertions.assertEquals(expectedEndAt, message.getSharedLocation().getEndAt()); @@ -75,7 +74,7 @@ void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() thro void whenUpdatingLiveLocation_thenCanGetUpdatedLocation() throws StreamException, ParseException { // Create a unique device ID for this test String deviceId = "device-" + UUID.randomUUID().toString(); - + // Create initial shared location request SharedLocationRequest initialLocationRequest = new SharedLocation.SharedLocationRequest(); initialLocationRequest.setCreatedByDeviceId(deviceId); @@ -94,17 +93,19 @@ void whenUpdatingLiveLocation_thenCanGetUpdatedLocation() throws StreamException initialSharedLocation.setEndAt(dateFormat.parse(initialLocationRequest.getEndAt())); // Send initial message with shared location - MessageRequestObject initialMessageRequest = MessageRequestObject.builder() - .text("I'm sharing my live location") - .userId(testUserRequestObject.getId()) - .type(MessageType.REGULAR) - .sharedLocation(initialSharedLocation) - .build(); - - Message initialMessage = Message.send(testChannel.getType(), testChannel.getId()) - .message(initialMessageRequest) - .request() - .getMessage(); + MessageRequestObject initialMessageRequest = + MessageRequestObject.builder() + .text("I'm sharing my live location") + .userId(testUserRequestObject.getId()) + .type(MessageType.REGULAR) + .sharedLocation(initialSharedLocation) + .build(); + + Message initialMessage = + Message.send(testChannel.getType(), testChannel.getId()) + .message(initialMessageRequest) + .request() + .getMessage(); // Create updated location request SharedLocationRequest updatedLocationRequest = new SharedLocation.SharedLocationRequest(); @@ -116,15 +117,15 @@ void whenUpdatingLiveLocation_thenCanGetUpdatedLocation() throws StreamException updatedLocationRequest.setUserId(testUserRequestObject.getId()); // Update the location - SharedLocation.SharedLocationResponse updateResponse = SharedLocation.updateLocation() - .userId(testUserRequestObject.getId()) - .request(updatedLocationRequest) - .request(); + SharedLocation.SharedLocationResponse updateResponse = + SharedLocation.updateLocation() + .userId(testUserRequestObject.getId()) + .request(updatedLocationRequest) + .request(); // Get active live locations - ActiveLiveLocationsResponse activeLocations = SharedLocation.getLocations() - .userId(testUserRequestObject.getId()) - .request(); + ActiveLiveLocationsResponse activeLocations = + SharedLocation.getLocations().userId(testUserRequestObject.getId()).request(); // Verify the updated location Assertions.assertNotNull(activeLocations); @@ -132,16 +133,17 @@ void whenUpdatingLiveLocation_thenCanGetUpdatedLocation() throws StreamException Assertions.assertFalse(activeLocations.getActiveLiveLocations().isEmpty()); // Find our location in the response - SharedLocation updatedLocation = activeLocations.getActiveLiveLocations().stream() - .filter(loc -> deviceId.equals(loc.getCreatedByDeviceId())) - .findFirst() - .orElse(null); + SharedLocation updatedLocation = + activeLocations.getActiveLiveLocations().stream() + .filter(loc -> deviceId.equals(loc.getCreatedByDeviceId())) + .findFirst() + .orElse(null); Assertions.assertNotNull(updatedLocation); Assertions.assertEquals(deviceId, updatedLocation.getCreatedByDeviceId()); Assertions.assertEquals(40.7589, updatedLocation.getLatitude()); Assertions.assertEquals(-73.9851, updatedLocation.getLongitude()); - + // Verify the endAt date Date expectedEndAt = dateFormat.parse("2025-12-31T23:59:59Z"); Assertions.assertEquals(expectedEndAt, updatedLocation.getEndAt()); From fc18fd583441039afcb20aafab67b6b33532a985 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Sat, 24 May 2025 17:00:02 +0200 Subject: [PATCH 09/12] add test get active live locations from query channels --- .../getstream/chat/java/models/Channel.java | 14 +++- .../chat/java/SharedLocationTest.java | 77 +++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/Channel.java b/src/main/java/io/getstream/chat/java/models/Channel.java index 333ea6985..6c5946c44 100644 --- a/src/main/java/io/getstream/chat/java/models/Channel.java +++ b/src/main/java/io/getstream/chat/java/models/Channel.java @@ -80,9 +80,9 @@ public class Channel { @JsonProperty("messages") private List messages; - @Nullable - @JsonProperty("active_live_locations") - private List activeLiveLocations; + // @Nullable + // @JsonProperty("active_live_locations") + // private List activeLiveLocations; @Nullable @JsonProperty("read") @@ -1234,6 +1234,10 @@ public static class ChannelGetResponse extends StreamResponseObject { @Nullable @JsonProperty("hide_messages_before") private Date hideMessagesBefore; + + @Nullable + @JsonProperty("active_live_locations") + private List activeLiveLocations; } @Data @@ -1729,4 +1733,8 @@ public static ChannelMemberPartialUpdateRequest unarchive( @NotNull String type, @NotNull String id, @NotNull String userId) { return new ChannelMemberPartialUpdateRequest(type, id, userId).setValue("archived", false); } + + // public List getActiveLiveLocations() { + // return activeLiveLocations; + // } } diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java index c694bae4c..97b5e91cd 100644 --- a/src/test/java/io/getstream/chat/java/SharedLocationTest.java +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -1,6 +1,9 @@ package io.getstream.chat.java; import io.getstream.chat.java.exceptions.StreamException; +import io.getstream.chat.java.models.Channel; +import io.getstream.chat.java.models.Channel.ChannelGetResponse; +import io.getstream.chat.java.models.Channel.ChannelRequestObject; import io.getstream.chat.java.models.Message; import io.getstream.chat.java.models.Message.MessageRequestObject; import io.getstream.chat.java.models.Message.MessageType; @@ -148,4 +151,78 @@ void whenUpdatingLiveLocation_thenCanGetUpdatedLocation() throws StreamException Date expectedEndAt = dateFormat.parse("2025-12-31T23:59:59Z"); Assertions.assertEquals(expectedEndAt, updatedLocation.getEndAt()); } + + @DisplayName("Can verify live location in channel") + @Test + void whenQueryingChannel_thenShouldHaveLiveLocation() throws StreamException, ParseException { + // Create a unique device ID for this test + String deviceId = "device-" + UUID.randomUUID().toString(); + + // Create shared location request + SharedLocationRequest locationRequest = new SharedLocation.SharedLocationRequest(); + locationRequest.setCreatedByDeviceId(deviceId); + locationRequest.setLatitude(40.7128); + locationRequest.setLongitude(-74.0060); + locationRequest.setEndAt("2025-12-31T23:59:59Z"); + locationRequest.setUserId(testUserRequestObject.getId()); + + // Convert request to SharedLocation + SharedLocation sharedLocation = new SharedLocation(); + sharedLocation.setCreatedByDeviceId(locationRequest.getCreatedByDeviceId()); + sharedLocation.setLatitude(locationRequest.getLatitude()); + sharedLocation.setLongitude(locationRequest.getLongitude()); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + sharedLocation.setEndAt(dateFormat.parse(locationRequest.getEndAt())); + + // Send message with shared location + MessageRequestObject messageRequest = + MessageRequestObject.builder() + .text("I'm sharing my live location") + .userId(testUserRequestObject.getId()) + .type(MessageType.REGULAR) + .sharedLocation(sharedLocation) + .build(); + + Message message = + Message.send(testChannel.getType(), testChannel.getId()) + .message(messageRequest) + .request() + .getMessage(); + + // Verify message was sent with correct shared location + Assertions.assertNotNull(message); + Assertions.assertNotNull(message.getSharedLocation()); + Assertions.assertEquals(deviceId, message.getSharedLocation().getCreatedByDeviceId()); + Assertions.assertEquals(40.7128, message.getSharedLocation().getLatitude()); + Assertions.assertEquals(-74.0060, message.getSharedLocation().getLongitude()); + + // Parse and verify the endAt date + Date expectedEndAt = dateFormat.parse("2025-12-31T23:59:59Z"); + Assertions.assertEquals(expectedEndAt, message.getSharedLocation().getEndAt()); + + // Query the channel to verify it has the live location + ChannelGetResponse response = + Channel.getOrCreate(testChannel.getType(), testChannel.getId()) + .data(ChannelRequestObject.builder().createdBy(testUserRequestObject).build()) + .request(); + + // Verify the channel has active live locations + Assertions.assertNotNull(response.getActiveLiveLocations()); + Assertions.assertFalse(response.getActiveLiveLocations().isEmpty()); + + // Find our location in the active live locations + SharedLocation channelLocation = + response.getActiveLiveLocations().stream() + .filter(loc -> deviceId.equals(loc.getCreatedByDeviceId())) + .findFirst() + .orElse(null); + + // Verify the location details + Assertions.assertNotNull(channelLocation); + Assertions.assertEquals(deviceId, channelLocation.getCreatedByDeviceId()); + Assertions.assertEquals(40.7128, channelLocation.getLatitude()); + Assertions.assertEquals(-74.0060, channelLocation.getLongitude()); + Assertions.assertEquals(expectedEndAt, channelLocation.getEndAt()); + } } From 3f977d493915864c4bccdc3864742f62a6396419 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Tue, 10 Jun 2025 08:53:22 +0200 Subject: [PATCH 10/12] feat(cha-769): change url name --- .../getstream/chat/java/services/SharedLocationService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/services/SharedLocationService.java b/src/main/java/io/getstream/chat/java/services/SharedLocationService.java index f2725397f..580cb1ca8 100644 --- a/src/main/java/io/getstream/chat/java/services/SharedLocationService.java +++ b/src/main/java/io/getstream/chat/java/services/SharedLocationService.java @@ -6,11 +6,11 @@ import retrofit2.http.*; public interface SharedLocationService { - @GET("users/locations") + @GET("users/live_locations") Call getLiveLocations( @NotNull @Query("user_id") String userId); - @PUT("users/location") + @PUT("users/live_locations") Call updateLiveLocation( @NotNull @Query("user_id") String userId, @NotNull @Body SharedLocation.SharedLocationRequest sharedLocationRequest); From d1937ceb2078e41f4cb56c161e72f2bc79b8632c Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Thu, 3 Jul 2025 16:12:28 +0200 Subject: [PATCH 11/12] fix unit tests --- .../io/getstream/chat/java/models/Channel.java | 4 ++++ .../getstream/chat/java/SharedLocationTest.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/io/getstream/chat/java/models/Channel.java b/src/main/java/io/getstream/chat/java/models/Channel.java index 4b44428ce..9a438824a 100644 --- a/src/main/java/io/getstream/chat/java/models/Channel.java +++ b/src/main/java/io/getstream/chat/java/models/Channel.java @@ -427,6 +427,10 @@ public static class ConfigOverridesRequestObject { @Nullable @JsonProperty("user_message_reminders") private Boolean userMessageReminders; + + @Nullable + @JsonProperty("shared_locations") + private Boolean sharedLocations; } @Builder diff --git a/src/test/java/io/getstream/chat/java/SharedLocationTest.java b/src/test/java/io/getstream/chat/java/SharedLocationTest.java index 97b5e91cd..ee21a7135 100644 --- a/src/test/java/io/getstream/chat/java/SharedLocationTest.java +++ b/src/test/java/io/getstream/chat/java/SharedLocationTest.java @@ -13,14 +13,29 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; import java.util.UUID; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class SharedLocationTest extends BasicTest { + @BeforeAll + static void setupSharedLocations() { + Map configOverrides = new HashMap<>(); + configOverrides.put("shared_locations", true); + + Assertions.assertDoesNotThrow( + () -> + Channel.partialUpdate(testChannel.getType(), testChannel.getId()) + .setValue("config_overrides", configOverrides) + .request()); + } + @DisplayName("Can send message with shared location and verify") @Test void whenSendingMessageWithSharedLocation_thenCanGetThroughUsersLocations() From 777a0cb404cf80b8b5726f004202bc126f027260 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Thu, 3 Jul 2025 20:00:39 +0200 Subject: [PATCH 12/12] clean up --- src/main/java/io/getstream/chat/java/models/Channel.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/Channel.java b/src/main/java/io/getstream/chat/java/models/Channel.java index 9a438824a..4a796a2e5 100644 --- a/src/main/java/io/getstream/chat/java/models/Channel.java +++ b/src/main/java/io/getstream/chat/java/models/Channel.java @@ -80,10 +80,6 @@ public class Channel { @JsonProperty("messages") private List messages; - // @Nullable - // @JsonProperty("active_live_locations") - // private List activeLiveLocations; - @Nullable @JsonProperty("read") private List read; @@ -1741,8 +1737,4 @@ public static ChannelMemberPartialUpdateRequest unarchive( @NotNull String type, @NotNull String id, @NotNull String userId) { return new ChannelMemberPartialUpdateRequest(type, id, userId).setValue("archived", false); } - - // public List getActiveLiveLocations() { - // return activeLiveLocations; - // } }