mirror of
https://github.com/dedicatedcode/reitti.git
synced 2026-01-09 09:27:58 -05:00
392 feature request improve home detection (#414)
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.6</version>
|
||||
<version>3.5.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.dedicatedcode</groupId>
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.util.*;
|
||||
public class TimelineController {
|
||||
|
||||
private final SignificantPlaceJdbcService placeService;
|
||||
private final SignificantPlaceOverrideJdbcService placeOverrideJdbcService;
|
||||
private final UserJdbcService userJdbcService;
|
||||
|
||||
private final AvatarService avatarService;
|
||||
@@ -42,7 +43,7 @@ public class TimelineController {
|
||||
private final TripJdbcService tripJdbcService;
|
||||
|
||||
@Autowired
|
||||
public TimelineController(SignificantPlaceJdbcService placeService,
|
||||
public TimelineController(SignificantPlaceJdbcService placeService, SignificantPlaceOverrideJdbcService placeOverrideJdbcService,
|
||||
UserJdbcService userJdbcService,
|
||||
AvatarService avatarService,
|
||||
ReittiIntegrationService reittiIntegrationService, UserSharingJdbcService userSharingJdbcService,
|
||||
@@ -51,6 +52,7 @@ public class TimelineController {
|
||||
TransportModeService transportModeService,
|
||||
TripJdbcService tripJdbcService) {
|
||||
this.placeService = placeService;
|
||||
this.placeOverrideJdbcService = placeOverrideJdbcService;
|
||||
this.userJdbcService = userJdbcService;
|
||||
this.avatarService = avatarService;
|
||||
this.reittiIntegrationService = reittiIntegrationService;
|
||||
@@ -102,7 +104,9 @@ public class TimelineController {
|
||||
}
|
||||
}
|
||||
|
||||
User user = this.userJdbcService.findByUsername(principal.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found"));
|
||||
placeService.update(updatedPlace);
|
||||
placeOverrideJdbcService.insertOverride(user, updatedPlace);
|
||||
|
||||
// If we have timeline context, reload the entire timeline with the edited place selected
|
||||
if (date != null) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.dedicatedcode.reitti.model.geocoding.RemoteGeocodeService;
|
||||
import com.dedicatedcode.reitti.model.security.User;
|
||||
import com.dedicatedcode.reitti.repository.GeocodeServiceJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.SignificantPlaceJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.SignificantPlaceOverrideJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.UserJdbcService;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -28,6 +29,7 @@ public class GeoCodingSettingsController {
|
||||
|
||||
private final GeocodeServiceJdbcService geocodeServiceJdbcService;
|
||||
private final SignificantPlaceJdbcService placeJdbcService;
|
||||
private final SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService;
|
||||
private final UserJdbcService userJdbcService;
|
||||
private final RabbitTemplate rabbitTemplate;
|
||||
private final MessageSource messageSource;
|
||||
@@ -37,6 +39,7 @@ public class GeoCodingSettingsController {
|
||||
|
||||
public GeoCodingSettingsController(GeocodeServiceJdbcService geocodeServiceJdbcService,
|
||||
SignificantPlaceJdbcService placeJdbcService,
|
||||
SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService,
|
||||
UserJdbcService userJdbcService,
|
||||
RabbitTemplate rabbitTemplate,
|
||||
MessageSource messageSource,
|
||||
@@ -44,6 +47,7 @@ public class GeoCodingSettingsController {
|
||||
@Value("${reitti.geocoding.max-errors}") int maxErrors) {
|
||||
this.geocodeServiceJdbcService = geocodeServiceJdbcService;
|
||||
this.placeJdbcService = placeJdbcService;
|
||||
this.significantPlaceOverrideJdbcService = significantPlaceOverrideJdbcService;
|
||||
this.userJdbcService = userJdbcService;
|
||||
this.rabbitTemplate = rabbitTemplate;
|
||||
this.messageSource = messageSource;
|
||||
@@ -168,6 +172,7 @@ public class GeoCodingSettingsController {
|
||||
// Clear geocoding data for all places
|
||||
for (SignificantPlace place : allPlaces) {
|
||||
SignificantPlace clearedPlace = place.withGeocoded(false).withAddress(null);
|
||||
this.significantPlaceOverrideJdbcService.clear(currentUser, clearedPlace);
|
||||
placeJdbcService.update(clearedPlace);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.dedicatedcode.reitti.model.geocoding.GeocodingResponse;
|
||||
import com.dedicatedcode.reitti.model.security.User;
|
||||
import com.dedicatedcode.reitti.repository.GeocodingResponseJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.SignificantPlaceJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.SignificantPlaceOverrideJdbcService;
|
||||
import com.dedicatedcode.reitti.service.PlaceService;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -32,15 +33,22 @@ import java.util.stream.Collectors;
|
||||
public class PlacesSettingsController {
|
||||
private final PlaceService placeService;
|
||||
private final SignificantPlaceJdbcService placeJdbcService;
|
||||
private final SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService;
|
||||
private final GeocodingResponseJdbcService geocodingResponseJdbcService;
|
||||
private final RabbitTemplate rabbitTemplate;
|
||||
private final MessageSource messageSource;
|
||||
private final boolean dataManagementEnabled;
|
||||
|
||||
public PlacesSettingsController(PlaceService placeService, SignificantPlaceJdbcService placeJdbcService, GeocodingResponseJdbcService geocodingResponseJdbcService, RabbitTemplate rabbitTemplate, MessageSource messageSource,
|
||||
public PlacesSettingsController(PlaceService placeService,
|
||||
SignificantPlaceJdbcService placeJdbcService,
|
||||
SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService,
|
||||
GeocodingResponseJdbcService geocodingResponseJdbcService,
|
||||
RabbitTemplate rabbitTemplate,
|
||||
MessageSource messageSource,
|
||||
@Value("${reitti.data-management.enabled:false}") boolean dataManagementEnabled) {
|
||||
this.placeService = placeService;
|
||||
this.placeJdbcService = placeJdbcService;
|
||||
this.significantPlaceOverrideJdbcService = significantPlaceOverrideJdbcService;
|
||||
this.geocodingResponseJdbcService = geocodingResponseJdbcService;
|
||||
this.rabbitTemplate = rabbitTemplate;
|
||||
this.messageSource = messageSource;
|
||||
@@ -154,6 +162,7 @@ public class PlacesSettingsController {
|
||||
}
|
||||
|
||||
placeJdbcService.update(updatedPlace);
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, updatedPlace);
|
||||
model.addAttribute("successMessage", getMessage("message.success.place.updated"));
|
||||
return editPlace(placeId, page, authentication, model);
|
||||
} catch (Exception e) {
|
||||
@@ -179,7 +188,7 @@ public class PlacesSettingsController {
|
||||
// Clear geocoding data and mark as not geocoded
|
||||
SignificantPlace clearedPlace = significantPlace.withGeocoded(false).withAddress(null);
|
||||
placeJdbcService.update(clearedPlace);
|
||||
|
||||
significantPlaceOverrideJdbcService.clear(user, clearedPlace);
|
||||
// Send SignificantPlaceCreatedEvent to trigger geocoding
|
||||
SignificantPlaceCreatedEvent event = new SignificantPlaceCreatedEvent(
|
||||
user.getUsername(),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dedicatedcode.reitti.model;
|
||||
|
||||
import com.dedicatedcode.reitti.model.geo.SignificantPlace;
|
||||
|
||||
import java.time.ZoneId;
|
||||
|
||||
public record PlaceInformationOverride(String name, SignificantPlace.PlaceType category, ZoneId timezone) {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dedicatedcode.reitti.repository;
|
||||
|
||||
import com.dedicatedcode.reitti.model.geo.GeoPoint;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.locationtech.jts.geom.Point;
|
||||
@@ -29,4 +30,8 @@ public class PointReaderWriter {
|
||||
public String write(double x, double y) {
|
||||
return geometryFactory.createPoint(new Coordinate(x, y)).toString();
|
||||
}
|
||||
|
||||
public String write(GeoPoint point) {
|
||||
return write(point.longitude(), point.latitude());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.dedicatedcode.reitti.repository;
|
||||
|
||||
import com.dedicatedcode.reitti.model.PlaceInformationOverride;
|
||||
import com.dedicatedcode.reitti.model.geo.GeoPoint;
|
||||
import com.dedicatedcode.reitti.model.geo.GeoUtils;
|
||||
import com.dedicatedcode.reitti.model.geo.SignificantPlace;
|
||||
import com.dedicatedcode.reitti.model.security.User;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class SignificantPlaceOverrideJdbcService {
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PointReaderWriter pointReaderWriter;
|
||||
|
||||
public SignificantPlaceOverrideJdbcService(JdbcTemplate jdbcTemplate, PointReaderWriter pointReaderWriter) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.pointReaderWriter = pointReaderWriter;
|
||||
}
|
||||
|
||||
public Optional<PlaceInformationOverride> findByUserAndPoint(User user, GeoPoint point) {
|
||||
double meterInDegrees = GeoUtils.metersToDegreesAtPosition(5.0, point.latitude())[0];
|
||||
String sql = "SELECT name, category, timezone FROM significant_places_overrides WHERE user_id = ? AND ST_DWithin(geom, ST_GeomFromText(?, '4326'), ?) ORDER BY ST_Distance(geom, ST_GeomFromText(?, '4326')) ASC LIMIT 1";
|
||||
List<PlaceInformationOverride> override = jdbcTemplate.query(sql, (rs, rowNum) -> new PlaceInformationOverride(
|
||||
rs.getString("name"),
|
||||
SignificantPlace.PlaceType.valueOf(rs.getString("category")),
|
||||
java.time.ZoneId.of(rs.getString("timezone"))
|
||||
), user.getId(), pointReaderWriter.write(point), meterInDegrees, pointReaderWriter.write(point));
|
||||
return override.stream().findFirst();
|
||||
}
|
||||
|
||||
public Optional<PlaceInformationOverride> findByUserAndPoint(User user, SignificantPlace place) {
|
||||
return findByUserAndPoint(user, new GeoPoint(place.getLatitudeCentroid(), place.getLongitudeCentroid()));
|
||||
}
|
||||
|
||||
public void insertOverride(User user, SignificantPlace place) {
|
||||
GeoPoint point = new GeoPoint(place.getLatitudeCentroid(), place.getLongitudeCentroid());
|
||||
double meterInDegrees = GeoUtils.metersToDegreesAtPosition(5.0, place.getLatitudeCentroid())[0];
|
||||
this.jdbcTemplate.update("DELETE FROM significant_places_overrides WHERE user_id = ? AND ST_DWithin(geom, ST_GeomFromText(?, '4326'), ?)", user.getId(), pointReaderWriter.write(point), meterInDegrees);
|
||||
String sql = "INSERT INTO significant_places_overrides (user_id, geom, name, category, timezone) VALUES (?, ST_GeomFromText(?, '4326'), ?, ?, ?)";
|
||||
jdbcTemplate.update(sql, user.getId(), pointReaderWriter.write(point), place.getName(), place.getType().name(), place.getTimezone().getId());
|
||||
}
|
||||
|
||||
public void clear(User user, SignificantPlace place) {
|
||||
GeoPoint point = new GeoPoint(place.getLatitudeCentroid(), place.getLongitudeCentroid());
|
||||
this.jdbcTemplate.update("DELETE FROM significant_places_overrides WHERE user_id = ? AND ST_Equals(geom, ST_GeomFromText(?, '4326'))", user.getId(), pointReaderWriter.write(point));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.dedicatedcode.reitti.service.geocoding;
|
||||
|
||||
import com.dedicatedcode.reitti.event.SignificantPlaceCreatedEvent;
|
||||
import com.dedicatedcode.reitti.model.PlaceInformationOverride;
|
||||
import com.dedicatedcode.reitti.model.geo.GeoPoint;
|
||||
import com.dedicatedcode.reitti.model.geo.SignificantPlace;
|
||||
import com.dedicatedcode.reitti.model.security.User;
|
||||
import com.dedicatedcode.reitti.repository.PreviewSignificantPlaceJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.SignificantPlaceJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.SignificantPlaceOverrideJdbcService;
|
||||
import com.dedicatedcode.reitti.repository.UserJdbcService;
|
||||
import com.dedicatedcode.reitti.service.UserNotificationService;
|
||||
import org.slf4j.Logger;
|
||||
@@ -21,17 +24,19 @@ public class ReverseGeocodingListener {
|
||||
private final SignificantPlaceJdbcService significantPlaceJdbcService;
|
||||
private final PreviewSignificantPlaceJdbcService previewSignificantPlaceJdbcService;
|
||||
private final GeocodeServiceManager geocodeServiceManager;
|
||||
private final SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService;
|
||||
private final UserNotificationService userNotificationService;
|
||||
private final UserJdbcService userJdbcService;
|
||||
|
||||
@Autowired
|
||||
public ReverseGeocodingListener(SignificantPlaceJdbcService significantPlaceJdbcService,
|
||||
PreviewSignificantPlaceJdbcService previewSignificantPlaceJdbcService,
|
||||
GeocodeServiceManager geocodeServiceManager,
|
||||
GeocodeServiceManager geocodeServiceManager, SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService,
|
||||
UserNotificationService userNotificationService, UserJdbcService userJdbcService) {
|
||||
this.significantPlaceJdbcService = significantPlaceJdbcService;
|
||||
this.previewSignificantPlaceJdbcService = previewSignificantPlaceJdbcService;
|
||||
this.geocodeServiceManager = geocodeServiceManager;
|
||||
this.significantPlaceOverrideJdbcService = significantPlaceOverrideJdbcService;
|
||||
this.userNotificationService = userNotificationService;
|
||||
this.userJdbcService = userJdbcService;
|
||||
}
|
||||
@@ -72,7 +77,11 @@ public class ReverseGeocodingListener {
|
||||
.withCity(city)
|
||||
.withCountryCode(countryCode);
|
||||
|
||||
|
||||
Optional<PlaceInformationOverride> override = this.significantPlaceOverrideJdbcService.findByUserAndPoint(user, place);
|
||||
if (override.isPresent()) {
|
||||
logger.info("Found override for place ID: {} with name: {}, type: {}, timezone: {}", place.getId(), override.get().name(), override.get().category(), override.get().timezone());
|
||||
place = place.withName(override.get().name()).withType(override.get().category()).withTimezone(override.get().timezone());
|
||||
}
|
||||
if (event.previewId() == null) {
|
||||
significantPlaceJdbcService.update(place.withGeocoded(true));
|
||||
userNotificationService.placeUpdate(user, place);
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.dedicatedcode.reitti.config.RabbitMQConfig;
|
||||
import com.dedicatedcode.reitti.event.ProcessedVisitCreatedEvent;
|
||||
import com.dedicatedcode.reitti.event.SignificantPlaceCreatedEvent;
|
||||
import com.dedicatedcode.reitti.event.VisitUpdatedEvent;
|
||||
import com.dedicatedcode.reitti.model.PlaceInformationOverride;
|
||||
import com.dedicatedcode.reitti.model.geo.*;
|
||||
import com.dedicatedcode.reitti.model.processing.DetectionParameter;
|
||||
import com.dedicatedcode.reitti.model.security.User;
|
||||
@@ -43,6 +44,7 @@ public class VisitMergingService {
|
||||
private final PreviewSignificantPlaceJdbcService previewSignificantPlaceJdbcService;
|
||||
private final RawLocationPointJdbcService rawLocationPointJdbcService;
|
||||
private final PreviewRawLocationPointJdbcService previewRawLocationPointJdbcService;
|
||||
private final SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService;
|
||||
private final GeometryFactory geometryFactory;
|
||||
private final RabbitTemplate rabbitTemplate;
|
||||
private final UserNotificationService userNotificationService;
|
||||
@@ -60,6 +62,7 @@ public class VisitMergingService {
|
||||
PreviewSignificantPlaceJdbcService previewSignificantPlaceJdbcService,
|
||||
RawLocationPointJdbcService rawLocationPointJdbcService,
|
||||
PreviewRawLocationPointJdbcService previewRawLocationPointJdbcService,
|
||||
SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService,
|
||||
GeometryFactory geometryFactory,
|
||||
UserNotificationService userNotificationService,
|
||||
GeoLocationTimezoneService timezoneService,
|
||||
@@ -74,6 +77,7 @@ public class VisitMergingService {
|
||||
this.previewSignificantPlaceJdbcService = previewSignificantPlaceJdbcService;
|
||||
this.rawLocationPointJdbcService = rawLocationPointJdbcService;
|
||||
this.previewRawLocationPointJdbcService = previewRawLocationPointJdbcService;
|
||||
this.significantPlaceOverrideJdbcService = significantPlaceOverrideJdbcService;
|
||||
this.geometryFactory = geometryFactory;
|
||||
this.userNotificationService = userNotificationService;
|
||||
this.timezoneService = timezoneService;
|
||||
@@ -272,6 +276,16 @@ public class VisitMergingService {
|
||||
if (timezone.isPresent()) {
|
||||
significantPlace = significantPlace.withTimezone(timezone.get());
|
||||
}
|
||||
// Check for override
|
||||
GeoPoint point = new GeoPoint(significantPlace.getLatitudeCentroid(), significantPlace.getLongitudeCentroid());
|
||||
Optional<PlaceInformationOverride> override = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point);
|
||||
if (override.isPresent()) {
|
||||
logger.info("Found override for user [{}] and location [{}], using override information: {}", user.getUsername(), point, override.get());
|
||||
significantPlace = significantPlace
|
||||
.withName(override.get().name())
|
||||
.withType(override.get().category())
|
||||
.withTimezone(override.get().timezone());
|
||||
}
|
||||
significantPlace = previewId == null ? this.significantPlaceJdbcService.create(user, significantPlace) : this.previewSignificantPlaceJdbcService.create(user, previewId, significantPlace);
|
||||
publishSignificantPlaceCreatedEvent(user, significantPlace, previewId);
|
||||
return significantPlace;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE significant_places_overrides
|
||||
(
|
||||
user_id BIGINT REFERENCES users (id),
|
||||
geom geometry(POINT, 4326),
|
||||
name VARCHAR(255),
|
||||
category VARCHAR(255),
|
||||
timezone VARCHAR(255),
|
||||
CONSTRAINT unique_user_geom UNIQUE (user_id, geom)
|
||||
);
|
||||
|
||||
INSERT INTO significant_places_overrides SELECT user_id, geom, name, type, timezone FROM significant_places ON CONFLICT DO NOTHING;
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.dedicatedcode.reitti.repository;
|
||||
|
||||
import com.dedicatedcode.reitti.IntegrationTest;
|
||||
import com.dedicatedcode.reitti.model.PlaceInformationOverride;
|
||||
import com.dedicatedcode.reitti.model.geo.GeoPoint;
|
||||
import com.dedicatedcode.reitti.model.geo.SignificantPlace;
|
||||
import com.dedicatedcode.reitti.model.geo.SignificantPlace.PlaceType;
|
||||
import com.dedicatedcode.reitti.model.security.User;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@IntegrationTest
|
||||
class SignificantPlaceOverrideJdbcServiceTest {
|
||||
|
||||
@Autowired
|
||||
private SignificantPlaceOverrideJdbcService significantPlaceOverrideJdbcService;
|
||||
|
||||
@Test
|
||||
void testFindByUserAndPoint_ExistingOverride() {
|
||||
// Create a test user (assuming a user exists or create one; for simplicity, assume user ID 1 exists)
|
||||
User user = new User(1L, "testuser", "password", "Test User", null, null, null, 1L);
|
||||
|
||||
// Create a GeoPoint
|
||||
GeoPoint point = new GeoPoint(40.7128, -74.0060); // Example: New York coordinates
|
||||
|
||||
// Create a SignificantPlace with the override details
|
||||
SignificantPlace place = new SignificantPlace(1L, "Home Override", "123 Main St", "New York", "US", 40.7128, -74.0060, PlaceType.HOME, ZoneId.of("America/New_York"), false, 1L);
|
||||
|
||||
// Insert the override using the service
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, place);
|
||||
|
||||
// Now test the find method
|
||||
Optional<PlaceInformationOverride> result = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals("Home Override", result.get().name());
|
||||
assertEquals(PlaceType.HOME, result.get().category());
|
||||
assertEquals(ZoneId.of("America/New_York"), result.get().timezone());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByUserAndPoint_NoOverride() {
|
||||
// Create a test user
|
||||
User user = new User(1L, "testuser", "password", "Test User", null, null, null, 1L);
|
||||
|
||||
// Create a GeoPoint that doesn't have an override
|
||||
GeoPoint point = new GeoPoint(51.5074, -0.1278); // Example: London coordinates
|
||||
|
||||
// Test the find method
|
||||
Optional<PlaceInformationOverride> result = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsertOverride() {
|
||||
// Create a test user
|
||||
User user = new User(1L, "testuser", "password", "Test User", null, null, null, 1L);
|
||||
|
||||
// Create a SignificantPlace
|
||||
SignificantPlace place = new SignificantPlace(1L, "Test Place", "123 Test St", "Test City", "US", 40.7128, -74.0060, PlaceType.HOME, ZoneId.of("America/New_York"), false, 1L);
|
||||
|
||||
// Insert the override
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, place);
|
||||
|
||||
// Verify by finding it
|
||||
GeoPoint point = new GeoPoint(place.getLatitudeCentroid(), place.getLongitudeCentroid());
|
||||
Optional<PlaceInformationOverride> result = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals("Test Place", result.get().name());
|
||||
assertEquals(PlaceType.HOME, result.get().category());
|
||||
assertEquals(ZoneId.of("America/New_York"), result.get().timezone());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClearOverride() {
|
||||
// Create a test user
|
||||
User user = new User(1L, "testuser", "password", "Test User", null, null, null, 1L);
|
||||
|
||||
// Create a SignificantPlace
|
||||
SignificantPlace place = new SignificantPlace(1L, "Test Place", "123 Test St", "Test City", "US", 40.7128, -74.0060, PlaceType.HOME, ZoneId.of("America/New_York"), false, 1L);
|
||||
|
||||
// Insert the override
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, place);
|
||||
|
||||
// Verify it exists
|
||||
GeoPoint point = new GeoPoint(place.getLatitudeCentroid(), place.getLongitudeCentroid());
|
||||
Optional<PlaceInformationOverride> resultBeforeClear = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point);
|
||||
assertTrue(resultBeforeClear.isPresent());
|
||||
|
||||
// Clear the override
|
||||
significantPlaceOverrideJdbcService.clear(user, place);
|
||||
|
||||
// Verify it no longer exists
|
||||
Optional<PlaceInformationOverride> resultAfterClear = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point);
|
||||
assertFalse(resultAfterClear.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByUserAndPoint_Within5mRadius() {
|
||||
// Create a test user
|
||||
User user = new User(1L, "testuser", "password", "Test User", null, null, null, 1L);
|
||||
|
||||
// Create a SignificantPlace at a specific location
|
||||
SignificantPlace place = new SignificantPlace(1L, "Nearby Override", "456 Nearby St", "Nearby City", "US", 40.7128, -74.0060, PlaceType.WORK, ZoneId.of("America/New_York"), false, 1L);
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, place);
|
||||
|
||||
// Create a GeoPoint very close (within 5m) to the place
|
||||
// Approximate 5m at this latitude: ~0.000045 degrees latitude, ~0.000056 degrees longitude
|
||||
GeoPoint closePoint = new GeoPoint(40.712845, -74.006056); // Approximately 5m away
|
||||
|
||||
// Test that the override is found from the close point
|
||||
Optional<PlaceInformationOverride> result = significantPlaceOverrideJdbcService.findByUserAndPoint(user, closePoint);
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals("Nearby Override", result.get().name());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsertOverride_DropsNearbyOverrides() {
|
||||
// Create a test user
|
||||
User user = new User(1L, "testuser", "password", "Test User", null, null, null, 1L);
|
||||
|
||||
// Insert first override
|
||||
SignificantPlace place1 = new SignificantPlace(1L, "First Override", "123 First St", "First City", "US", 40.7128, -74.0060, PlaceType.HOME, ZoneId.of("America/New_York"), false, 1L);
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, place1);
|
||||
|
||||
// Verify first override exists
|
||||
GeoPoint point1 = new GeoPoint(place1.getLatitudeCentroid(), place1.getLongitudeCentroid());
|
||||
Optional<PlaceInformationOverride> result1 = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point1);
|
||||
assertTrue(result1.isPresent());
|
||||
|
||||
// Insert second override very close (within 5m)
|
||||
SignificantPlace place2 = new SignificantPlace(2L, "Second Override", "456 Second St", "Second City", "US", 40.712845, -74.0060, PlaceType.WORK, ZoneId.of("America/New_York"), false, 1L);
|
||||
significantPlaceOverrideJdbcService.insertOverride(user, place2);
|
||||
|
||||
// Verify first override is dropped (since it's within 5m of the new one)
|
||||
Optional<PlaceInformationOverride> result1AfterInsert = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point1);
|
||||
assertFalse(result1AfterInsert.isPresent());
|
||||
|
||||
// Verify second override exists
|
||||
GeoPoint point2 = new GeoPoint(place2.getLatitudeCentroid(), place2.getLongitudeCentroid());
|
||||
Optional<PlaceInformationOverride> result2 = significantPlaceOverrideJdbcService.findByUserAndPoint(user, point2);
|
||||
assertTrue(result2.isPresent());
|
||||
assertEquals("Second Override", result2.get().name());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user