Big Feature and Beautifying Package
This commit is contained in:
parent
87da2a3861
commit
1f2ff67f38
171 changed files with 1286 additions and 663 deletions
|
|
@ -0,0 +1,31 @@
|
|||
package net.javahippie.fitpub;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.javahippie.fitpub.config.TestcontainersConfiguration;
|
||||
import org.apache.hc.client5.http.classic.HttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Main Spring Boot application class for FitPub.
|
||||
* FitPub is a federated fitness tracking platform that integrates with the Fediverse
|
||||
* through the ActivityPub protocol.
|
||||
*/
|
||||
public class FitPubApplicationTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication
|
||||
.from(FitPubApplication::main)
|
||||
.with(TestcontainersConfiguration.class)
|
||||
.run(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package net.javahippie.fitpub.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Development data initializer that creates a demo user for testing.
|
||||
* Only active when the 'dev' profile is enabled.
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("dev")
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class DevDataInitializer {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner initDemoUser() {
|
||||
return args -> {
|
||||
// Check if demo user already exists
|
||||
if (userRepository.findByUsername("demo").isPresent()) {
|
||||
log.info("Demo user already exists, skipping initialization");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Creating demo user for development...");
|
||||
|
||||
try {
|
||||
// Generate RSA key pair for ActivityPub
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(2048);
|
||||
KeyPair keyPair = keyGen.generateKeyPair();
|
||||
|
||||
String publicKey = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()) +
|
||||
"\n-----END PUBLIC KEY-----";
|
||||
|
||||
String privateKey = "-----BEGIN PRIVATE KEY-----\n" +
|
||||
Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()) +
|
||||
"\n-----END PRIVATE KEY-----";
|
||||
|
||||
// Create demo user
|
||||
User demoUser = User.builder()
|
||||
.username("demo")
|
||||
.email("demo@fitpub.local")
|
||||
.passwordHash(passwordEncoder.encode("demo"))
|
||||
.displayName("Demo User")
|
||||
.bio("This is a demo account for testing FitPub features. Upload your FIT files and explore the federated fitness tracking platform!")
|
||||
.publicKey(publicKey)
|
||||
.privateKey(privateKey)
|
||||
.build();
|
||||
|
||||
userRepository.save(demoUser);
|
||||
|
||||
log.info("=".repeat(80));
|
||||
log.info("Demo user created successfully!");
|
||||
log.info("Username: demo");
|
||||
log.info("Password: demo");
|
||||
log.info("Email: demo@fitpub.local");
|
||||
log.info("=".repeat(80));
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.error("Failed to generate RSA key pair for demo user", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.config;
|
||||
package net.javahippie.fitpub.config;
|
||||
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||
|
|
@ -15,6 +15,7 @@ public class TestcontainersConfiguration {
|
|||
|
||||
/**
|
||||
* PostgreSQL container with PostGIS extension for tests.
|
||||
* PostGIS image is treated as a standard PostgreSQL container.
|
||||
* @ServiceConnection automatically configures the datasource from this container.
|
||||
*/
|
||||
@Bean
|
||||
|
|
@ -24,9 +25,8 @@ public class TestcontainersConfiguration {
|
|||
DockerImageName.parse("postgis/postgis:16-3.4")
|
||||
.asCompatibleSubstituteFor("postgres")
|
||||
)
|
||||
.withDatabaseName("fitpub")
|
||||
.withUsername("fitpub")
|
||||
.withPassword("fitpub")
|
||||
.withReuse(true);
|
||||
.withDatabaseName("testdb")
|
||||
.withUsername("test")
|
||||
.withPassword("test");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
package org.operaton.fitpub.controller;
|
||||
package net.javahippie.fitpub.controller;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.operaton.fitpub.model.dto.ActivityDTO;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import org.operaton.fitpub.security.JwtTokenProvider;
|
||||
import org.operaton.fitpub.config.TestcontainersConfiguration;
|
||||
import net.javahippie.fitpub.model.dto.ActivityDTO;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.security.JwtTokenProvider;
|
||||
import net.javahippie.fitpub.config.TestcontainersConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
|
@ -20,6 +20,7 @@ import org.springframework.mock.web.MockMultipartFile;
|
|||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Files;
|
||||
|
|
@ -37,7 +38,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles("test")
|
||||
@Transactional
|
||||
@Import(TestcontainersConfiguration.class)
|
||||
class ActivityControllerIntegrationTest {
|
||||
|
|
@ -1,21 +1,23 @@
|
|||
package org.operaton.fitpub.integration;
|
||||
package net.javahippie.fitpub.integration;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import net.javahippie.fitpub.config.TestcontainersConfiguration;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.operaton.fitpub.model.entity.Follow;
|
||||
import org.operaton.fitpub.model.entity.RemoteActor;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.FollowRepository;
|
||||
import org.operaton.fitpub.repository.RemoteActorRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import org.operaton.fitpub.security.JwtTokenProvider;
|
||||
import net.javahippie.fitpub.model.entity.Follow;
|
||||
import net.javahippie.fitpub.model.entity.RemoteActor;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.FollowRepository;
|
||||
import net.javahippie.fitpub.repository.RemoteActorRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.security.JwtTokenProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
|
@ -41,8 +43,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles("test")
|
||||
@Transactional
|
||||
@Import(TestcontainersConfiguration.class)
|
||||
class FederationFollowFlowIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.security;
|
||||
package net.javahippie.fitpub.security;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
package org.operaton.fitpub.security;
|
||||
package net.javahippie.fitpub.security;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.operaton.fitpub.config.TestcontainersConfiguration;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.config.TestcontainersConfiguration;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
|
|
@ -28,9 +30,10 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||
* Run manually when needed: mvn test -Dtest=KeyPairValidationTest
|
||||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@Transactional
|
||||
@Import(TestcontainersConfiguration.class)
|
||||
@Slf4j
|
||||
@Disabled("Integration test - requires live database with user data. Run manually when needed.")
|
||||
public class KeyPairValidationTest {
|
||||
|
||||
@Autowired
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
|
@ -7,14 +7,13 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.Achievement;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.ActivityMetrics;
|
||||
import org.operaton.fitpub.repository.AchievementRepository;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.model.entity.Achievement;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.ActivityMetrics;
|
||||
import net.javahippie.fitpub.repository.AchievementRepository;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
|
@ -1,22 +1,21 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.operaton.fitpub.config.TestcontainersConfiguration;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.ActivityMetrics;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import org.operaton.fitpub.util.FitParser;
|
||||
import org.operaton.fitpub.util.ParsedActivityData;
|
||||
import net.javahippie.fitpub.config.TestcontainersConfiguration;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.ActivityMetrics;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.util.FitParser;
|
||||
import net.javahippie.fitpub.util.ParsedActivityData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -8,10 +7,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -19,7 +18,6 @@ import java.time.LocalDateTime;
|
|||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
|
|
@ -13,14 +13,14 @@ import org.mockito.InjectMocks;
|
|||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.exception.FitFileProcessingException;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.repository.ActivityMetricsRepository;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.util.FitFileValidator;
|
||||
import org.operaton.fitpub.util.FitParser;
|
||||
import org.operaton.fitpub.util.ParsedActivityData;
|
||||
import org.operaton.fitpub.util.TrackSimplifier;
|
||||
import net.javahippie.fitpub.exception.FitFileProcessingException;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.repository.ActivityMetricsRepository;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.util.FitFileValidator;
|
||||
import net.javahippie.fitpub.util.FitParser;
|
||||
import net.javahippie.fitpub.util.ParsedActivityData;
|
||||
import net.javahippie.fitpub.util.TrackSimplifier;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -378,7 +378,8 @@ class FitFileServiceTest {
|
|||
userId,
|
||||
"New Title",
|
||||
"New Description",
|
||||
Activity.Visibility.PUBLIC
|
||||
Activity.Visibility.PUBLIC,
|
||||
false
|
||||
);
|
||||
|
||||
// Assert
|
||||
|
|
@ -421,7 +422,8 @@ class FitFileServiceTest {
|
|||
userId,
|
||||
"New Title",
|
||||
"New Description",
|
||||
Activity.Visibility.PUBLIC
|
||||
Activity.Visibility.PUBLIC,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -450,7 +452,8 @@ class FitFileServiceTest {
|
|||
differentUserId,
|
||||
"Hacked Title",
|
||||
"Hacked Description",
|
||||
Activity.Visibility.PUBLIC
|
||||
Activity.Visibility.PUBLIC,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -492,7 +495,8 @@ class FitFileServiceTest {
|
|||
userId,
|
||||
"Updated Title",
|
||||
"Updated Description",
|
||||
Activity.Visibility.PUBLIC
|
||||
Activity.Visibility.PUBLIC,
|
||||
false
|
||||
);
|
||||
|
||||
// Assert - verify updated fields
|
||||
|
|
@ -1,21 +1,18 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.locationtech.jts.geom.Point;
|
||||
import org.locationtech.jts.geom.PrecisionModel;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.model.entity.UserHeatmapGrid;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.UserHeatmapGridRepository;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.model.entity.UserHeatmapGrid;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.UserHeatmapGridRepository;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.ActivityMetrics;
|
||||
import org.operaton.fitpub.model.entity.PersonalRecord;
|
||||
import org.operaton.fitpub.repository.PersonalRecordRepository;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.ActivityMetrics;
|
||||
import net.javahippie.fitpub.model.entity.PersonalRecord;
|
||||
import net.javahippie.fitpub.repository.PersonalRecordRepository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import net.javahippie.fitpub.repository.CommentRepository;
|
||||
import net.javahippie.fitpub.repository.LikeRepository;
|
||||
import net.javahippie.fitpub.repository.RemoteActorRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -7,20 +10,21 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.dto.TimelineActivityDTO;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.Follow;
|
||||
import org.operaton.fitpub.model.entity.RemoteActivity;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.FollowRepository;
|
||||
import org.operaton.fitpub.repository.RemoteActivityRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.model.dto.TimelineActivityDTO;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.Follow;
|
||||
import net.javahippie.fitpub.model.entity.RemoteActivity;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.FollowRepository;
|
||||
import net.javahippie.fitpub.repository.RemoteActivityRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -54,13 +58,16 @@ class TimelineServiceTest {
|
|||
private UserRepository userRepository;
|
||||
|
||||
@Mock
|
||||
private org.operaton.fitpub.repository.LikeRepository likeRepository;
|
||||
private LikeRepository likeRepository;
|
||||
|
||||
@Mock
|
||||
private org.operaton.fitpub.repository.CommentRepository commentRepository;
|
||||
private CommentRepository commentRepository;
|
||||
|
||||
@Mock
|
||||
private org.operaton.fitpub.repository.RemoteActorRepository remoteActorRepository;
|
||||
private RemoteActorRepository remoteActorRepository;
|
||||
|
||||
@Mock
|
||||
private TimelineResultMapper timelineResultMapper;
|
||||
|
||||
@InjectMocks
|
||||
private TimelineService timelineService;
|
||||
|
|
@ -93,15 +100,20 @@ class TimelineServiceTest {
|
|||
.thenReturn(follows);
|
||||
when(userRepository.findById(userId)).thenReturn(Optional.of(testUser));
|
||||
|
||||
// Mock local activities
|
||||
List<Activity> localActivities = List.of(
|
||||
createLocalActivity("Morning Run", LocalDateTime.now().minusHours(2))
|
||||
);
|
||||
Page<Activity> localActivitiesPage = new PageImpl<>(localActivities);
|
||||
when(activityRepository.findByUserIdInAndVisibilityInOrderByStartedAtDesc(
|
||||
anyList(), anyList(), any(Pageable.class)))
|
||||
// Mock local activities using Object[] (as returned by native query)
|
||||
Object[] row1 = createTimelineRow("Morning Run", LocalDateTime.now().minusHours(2));
|
||||
List<Object[]> localActivityRows = new ArrayList<>();
|
||||
localActivityRows.add(row1);
|
||||
Page<Object[]> localActivitiesPage = new PageImpl<>(localActivityRows);
|
||||
when(activityRepository.findFederatedTimelineWithStats(
|
||||
anyList(), anyList(), eq(userId), any(Pageable.class)))
|
||||
.thenReturn(localActivitiesPage);
|
||||
|
||||
// Mock the mapper
|
||||
TimelineActivityDTO dto1 = createTimelineDTO("Morning Run", LocalDateTime.now().minusHours(2));
|
||||
when(timelineResultMapper.mapToTimelineActivityDTO(any(Object[].class)))
|
||||
.thenReturn(dto1);
|
||||
|
||||
// Mock remote activities - this should use publishedAt for sorting
|
||||
List<RemoteActivity> remoteActivities = List.of(
|
||||
createRemoteActivity("Remote Run 1", Instant.now().minusSeconds(3600)),
|
||||
|
|
@ -124,8 +136,8 @@ class TimelineServiceTest {
|
|||
assertFalse(result.isEmpty(), "Result should contain activities");
|
||||
|
||||
// Verify that both repositories were called
|
||||
verify(activityRepository).findByUserIdInAndVisibilityInOrderByStartedAtDesc(
|
||||
anyList(), anyList(), any(Pageable.class));
|
||||
verify(activityRepository).findFederatedTimelineWithStats(
|
||||
anyList(), anyList(), eq(userId), any(Pageable.class));
|
||||
verify(remoteActivityRepository).findByRemoteActorUriInAndVisibilityIn(
|
||||
anyList(), anyList(), any(Pageable.class));
|
||||
}
|
||||
|
|
@ -139,14 +151,19 @@ class TimelineServiceTest {
|
|||
when(userRepository.findById(userId)).thenReturn(Optional.of(testUser));
|
||||
|
||||
// Mock local activities only
|
||||
List<Activity> localActivities = List.of(
|
||||
createLocalActivity("Solo Run", LocalDateTime.now())
|
||||
);
|
||||
Page<Activity> localActivitiesPage = new PageImpl<>(localActivities);
|
||||
when(activityRepository.findByUserIdInAndVisibilityInOrderByStartedAtDesc(
|
||||
anyList(), anyList(), any(Pageable.class)))
|
||||
Object[] row1 = createTimelineRow("Solo Run", LocalDateTime.now());
|
||||
List<Object[]> localActivityRows = new ArrayList<>();
|
||||
localActivityRows.add(row1);
|
||||
Page<Object[]> localActivitiesPage = new PageImpl<>(localActivityRows);
|
||||
when(activityRepository.findFederatedTimelineWithStats(
|
||||
anyList(), anyList(), eq(userId), any(Pageable.class)))
|
||||
.thenReturn(localActivitiesPage);
|
||||
|
||||
// Mock the mapper
|
||||
TimelineActivityDTO dto1 = createTimelineDTO("Solo Run", LocalDateTime.now());
|
||||
when(timelineResultMapper.mapToTimelineActivityDTO(any(Object[].class)))
|
||||
.thenReturn(dto1);
|
||||
|
||||
Pageable pageable = PageRequest.of(0, 20);
|
||||
|
||||
// When
|
||||
|
|
@ -173,12 +190,19 @@ class TimelineServiceTest {
|
|||
when(userRepository.findById(userId)).thenReturn(Optional.of(testUser));
|
||||
|
||||
// Local activity
|
||||
Activity localActivity = createLocalActivity("Local Run", LocalDateTime.now().minusHours(1));
|
||||
Page<Activity> localActivitiesPage = new PageImpl<>(List.of(localActivity));
|
||||
when(activityRepository.findByUserIdInAndVisibilityInOrderByStartedAtDesc(
|
||||
anyList(), anyList(), any(Pageable.class)))
|
||||
Object[] row1 = createTimelineRow("Local Run", LocalDateTime.now().minusHours(1));
|
||||
List<Object[]> localActivityRows = new ArrayList<>();
|
||||
localActivityRows.add(row1);
|
||||
Page<Object[]> localActivitiesPage = new PageImpl<>(localActivityRows);
|
||||
when(activityRepository.findFederatedTimelineWithStats(
|
||||
anyList(), anyList(), eq(userId), any(Pageable.class)))
|
||||
.thenReturn(localActivitiesPage);
|
||||
|
||||
// Mock the mapper
|
||||
TimelineActivityDTO dto1 = createTimelineDTO("Local Run", LocalDateTime.now().minusHours(1));
|
||||
when(timelineResultMapper.mapToTimelineActivityDTO(any(Object[].class)))
|
||||
.thenReturn(dto1);
|
||||
|
||||
// Remote activity
|
||||
RemoteActivity remoteActivity = createRemoteActivity("Remote Run", Instant.now().minusSeconds(7200));
|
||||
Page<RemoteActivity> remoteActivitiesPage = new PageImpl<>(List.of(remoteActivity));
|
||||
|
|
@ -210,18 +234,48 @@ class TimelineServiceTest {
|
|||
return follow;
|
||||
}
|
||||
|
||||
private Activity createLocalActivity(String title, LocalDateTime startedAt) {
|
||||
Activity activity = new Activity();
|
||||
activity.setId(UUID.randomUUID());
|
||||
activity.setUserId(userId);
|
||||
activity.setTitle(title);
|
||||
activity.setDescription("Test activity");
|
||||
activity.setActivityType(Activity.ActivityType.RUN);
|
||||
activity.setStartedAt(startedAt);
|
||||
activity.setVisibility(Activity.Visibility.PUBLIC);
|
||||
activity.setTotalDistance(java.math.BigDecimal.valueOf(5000));
|
||||
activity.setTotalDurationSeconds(1800L);
|
||||
return activity;
|
||||
/**
|
||||
* Creates an Object[] representing a row from the native query.
|
||||
* The structure matches what TimelineResultMapper expects.
|
||||
*/
|
||||
private Object[] createTimelineRow(String title, LocalDateTime startedAt) {
|
||||
UUID activityId = UUID.randomUUID();
|
||||
return new Object[]{
|
||||
activityId, // 0: activity_id
|
||||
userId, // 1: user_id
|
||||
"testuser", // 2: username
|
||||
"Test User", // 3: display_name
|
||||
null, // 4: avatar_url
|
||||
title, // 5: title
|
||||
"Test activity", // 6: description
|
||||
"RUN", // 7: activity_type
|
||||
startedAt, // 8: started_at
|
||||
"PUBLIC", // 9: visibility
|
||||
BigDecimal.valueOf(5000), // 10: total_distance
|
||||
1800L, // 11: total_duration_seconds
|
||||
BigDecimal.valueOf(100), // 12: elevation_gain
|
||||
0L, // 13: likes_count
|
||||
0L // 14: comments_count
|
||||
};
|
||||
}
|
||||
|
||||
private TimelineActivityDTO createTimelineDTO(String title, LocalDateTime startedAt) {
|
||||
return TimelineActivityDTO.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.username("testuser")
|
||||
.displayName("Test User")
|
||||
.title(title)
|
||||
.description("Test activity")
|
||||
.activityType("RUN")
|
||||
.startedAt(startedAt)
|
||||
.visibility("PUBLIC")
|
||||
.totalDistance(5000.0)
|
||||
.totalDurationSeconds(1800L)
|
||||
.elevationGain(100.0)
|
||||
.likesCount(0L)
|
||||
.commentsCount(0L)
|
||||
.isLocal(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
private RemoteActivity createRemoteActivity(String title, Instant publishedAt) {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
|
@ -8,14 +8,13 @@ import org.mockito.ArgumentCaptor;
|
|||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.TrainingLoad;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.TrainingLoadRepository;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.TrainingLoad;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.TrainingLoadRepository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
|
@ -7,10 +7,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.FollowRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import org.operaton.fitpub.security.JwtTokenProvider;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.FollowRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.security.JwtTokenProvider;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
|
@ -1,18 +1,17 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.WeatherData;
|
||||
import org.operaton.fitpub.repository.WeatherDataRepository;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.WeatherData;
|
||||
import net.javahippie.fitpub.repository.WeatherDataRepository;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.ResourceAccessException;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.service;
|
||||
package net.javahippie.fitpub.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.javahippie.fitpub.config.TestcontainersConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.model.entity.User;
|
||||
import org.operaton.fitpub.repository.ActivityRepository;
|
||||
import org.operaton.fitpub.repository.UserRepository;
|
||||
import org.operaton.fitpub.service.ActivityFileService;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.User;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.UserRepository;
|
||||
import net.javahippie.fitpub.service.ActivityFileService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -29,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||
*/
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
@Import(TestcontainersConfiguration.class)
|
||||
@Slf4j
|
||||
@Transactional
|
||||
class DatePersistenceTest {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import com.garmin.fit.*;
|
||||
import java.io.FileInputStream;
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.operaton.fitpub.exception.InvalidFitFileException;
|
||||
import net.javahippie.fitpub.exception.InvalidFitFileException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.operaton.fitpub.model.entity.Activity;
|
||||
import org.operaton.fitpub.util.ParsedActivityData.TrackPointData;
|
||||
import org.operaton.fitpub.util.ParsedActivityData.ActivityMetricsData;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.util.ParsedActivityData.TrackPointData;
|
||||
import net.javahippie.fitpub.util.ParsedActivityData.ActivityMetricsData;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.operaton.fitpub.util;
|
||||
package net.javahippie.fitpub.util;
|
||||
|
||||
import com.garmin.fit.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -13,7 +13,6 @@ import java.time.Instant;
|
|||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue