Compare commits

1 Commits

Author SHA1 Message Date
684d46c5b2 test: added activity repo test
All checks were successful
Backend CI / Run Maven Tests (pull_request) Successful in 1m20s
2025-08-11 18:33:54 +00:00
7 changed files with 347 additions and 7 deletions

View File

@@ -81,6 +81,20 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.datafaker</groupId>
<artifactId>datafaker</artifactId>
<version>2.4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
<!-- JSON Processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>

View File

@@ -4,6 +4,7 @@ import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.With;
import lombok.AllArgsConstructor;
import java.time.LocalDateTime;
@@ -15,6 +16,7 @@ import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@With
public class Location {
@Id

View File

@@ -1,5 +1,5 @@
server:
port: 8090
port: 8080
servlet:
context-path: /api
@@ -9,7 +9,7 @@ spring:
# Database Configuration
datasource:
url: jdbc:postgresql://dind:5432/vibing
url: jdbc:postgresql://localhost:5432/vibing
username: vibing
password: vibing
driver-class-name: org.postgresql.Driver

View File

@@ -0,0 +1,277 @@
package com.vibing.backend;
import com.vibing.backend.model.Activity;
import com.vibing.backend.model.Location;
import com.vibing.backend.repository.ActivityRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for Activity entity using H2 database.
* Tests repository operations and database interactions.
*/
@DataJpaTest
@ActiveProfiles("test")
@TestPropertySource(locations = "classpath:application-test.yml")
public class ActivityRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private ActivityRepository activityRepository;
private Location testLocation;
private Activity testActivity;
@BeforeEach
void setUp() {
// Create and persist test location
testLocation = new Location();
testLocation.setName("Test Location");
testLocation.setAddress("123 Test Street");
testLocation.setCity("Test City");
testLocation.setCountry("Test Country");
testLocation.setPostalCode("12345");
testLocation.setLatitude(40.7128);
testLocation.setLongitude(-74.0060);
testLocation = entityManager.persistAndFlush(testLocation);
// Create test activity
testActivity = new Activity();
testActivity.setName("Test Activity");
testActivity.setDescription("A test activity for integration testing");
testActivity.setLocation(testLocation);
testActivity.setPriceRange(3);
testActivity.setTags(Arrays.asList("test", "integration", "fun"));
}
@Test
void shouldSaveAndRetrieveActivity() {
// Given - activity is created in setUp()
// When
Activity savedActivity = activityRepository.save(testActivity);
entityManager.flush();
entityManager.clear();
Optional<Activity> retrievedActivity = activityRepository.findById(savedActivity.getId());
// Then
assertThat(retrievedActivity).isPresent();
assertThat(retrievedActivity.get().getName()).isEqualTo("Test Activity");
assertThat(retrievedActivity.get().getDescription()).isEqualTo("A test activity for integration testing");
assertThat(retrievedActivity.get().getPriceRange()).isEqualTo(3);
assertThat(retrievedActivity.get().getLocation().getName()).isEqualTo("Test Location");
assertThat(retrievedActivity.get().getTags()).containsExactlyInAnyOrder("test", "integration", "fun");
assertThat(retrievedActivity.get().getCreatedAt()).isNotNull();
assertThat(retrievedActivity.get().getUpdatedAt()).isNotNull();
}
@Test
void shouldFindActivitiesByNameContainingIgnoreCase() {
// Given
Activity activity1 = new Activity();
activity1.setName("Beach Volleyball");
activity1.setLocation(testLocation);
activity1.setPriceRange(2);
activity1.setTags(Arrays.asList("sport", "beach"));
Activity activity2 = new Activity();
activity2.setName("Mountain Hiking");
activity2.setLocation(testLocation);
activity2.setPriceRange(1);
activity2.setTags(Arrays.asList("outdoor", "hiking"));
activityRepository.saveAll(Arrays.asList(activity1, activity2));
entityManager.flush();
// When
List<Activity> beachActivities = activityRepository.findByNameContainingIgnoreCase("beach");
List<Activity> mountainActivities = activityRepository.findByNameContainingIgnoreCase("MOUNTAIN");
// Then
assertThat(beachActivities).hasSize(1);
assertThat(beachActivities.get(0).getName()).isEqualTo("Beach Volleyball");
assertThat(mountainActivities).hasSize(1);
assertThat(mountainActivities.get(0).getName()).isEqualTo("Mountain Hiking");
}
@Test
void shouldFindActivitiesByPriceRange() {
// Given
Activity cheapActivity = new Activity();
cheapActivity.setName("Free Walking Tour");
cheapActivity.setLocation(testLocation);
cheapActivity.setPriceRange(1);
cheapActivity.setTags(Arrays.asList("free", "walking"));
Activity expensiveActivity = new Activity();
expensiveActivity.setName("Luxury Spa Day");
expensiveActivity.setLocation(testLocation);
expensiveActivity.setPriceRange(5);
expensiveActivity.setTags(Arrays.asList("luxury", "spa"));
activityRepository.saveAll(Arrays.asList(cheapActivity, expensiveActivity));
entityManager.flush();
// When
List<Activity> cheapActivities = activityRepository.findByPriceRange(1);
List<Activity> expensiveActivities = activityRepository.findByPriceRange(5);
// Then
assertThat(cheapActivities).hasSize(1);
assertThat(cheapActivities.get(0).getName()).isEqualTo("Free Walking Tour");
assertThat(expensiveActivities).hasSize(1);
assertThat(expensiveActivities.get(0).getName()).isEqualTo("Luxury Spa Day");
}
@Test
void shouldFindActivitiesByLocationId() {
// Given
Location anotherLocation = new Location();
anotherLocation.setName("Another Location");
anotherLocation.setCity("Another City");
anotherLocation = entityManager.persistAndFlush(anotherLocation);
Activity activityAtTestLocation = new Activity();
activityAtTestLocation.setName("Activity at Test Location");
activityAtTestLocation.setLocation(testLocation);
activityAtTestLocation.setPriceRange(2);
Activity activityAtAnotherLocation = new Activity();
activityAtAnotherLocation.setName("Activity at Another Location");
activityAtAnotherLocation.setLocation(anotherLocation);
activityAtAnotherLocation.setPriceRange(3);
activityRepository.saveAll(Arrays.asList(activityAtTestLocation, activityAtAnotherLocation));
entityManager.flush();
// When
List<Activity> activitiesAtTestLocation = activityRepository.findByLocationId(testLocation.getId());
List<Activity> activitiesAtAnotherLocation = activityRepository.findByLocationId(anotherLocation.getId());
// Then
assertThat(activitiesAtTestLocation).hasSize(1);
assertThat(activitiesAtTestLocation.get(0).getName()).isEqualTo("Activity at Test Location");
assertThat(activitiesAtAnotherLocation).hasSize(1);
assertThat(activitiesAtAnotherLocation.get(0).getName()).isEqualTo("Activity at Another Location");
}
@Test
void shouldFindActivitiesByTagsContaining() {
// Given
Activity outdoorActivity = new Activity();
outdoorActivity.setName("Rock Climbing");
outdoorActivity.setLocation(testLocation);
outdoorActivity.setPriceRange(3);
outdoorActivity.setTags(Arrays.asList("outdoor", "adventure", "climbing"));
Activity indoorActivity = new Activity();
indoorActivity.setName("Museum Visit");
indoorActivity.setLocation(testLocation);
indoorActivity.setPriceRange(2);
indoorActivity.setTags(Arrays.asList("indoor", "culture", "educational"));
activityRepository.saveAll(Arrays.asList(outdoorActivity, indoorActivity));
entityManager.flush();
// When
List<Activity> outdoorActivities = activityRepository.findByTagsContaining("outdoor");
List<Activity> cultureActivities = activityRepository.findByTagsContaining("culture");
// Then
assertThat(outdoorActivities).hasSize(1);
assertThat(outdoorActivities.get(0).getName()).isEqualTo("Rock Climbing");
assertThat(cultureActivities).hasSize(1);
assertThat(cultureActivities.get(0).getName()).isEqualTo("Museum Visit");
}
@Test
void shouldFindActivitiesByPriceRangeLessThanEqual() {
// Given
Activity cheapActivity = new Activity();
cheapActivity.setName("Budget Activity");
cheapActivity.setLocation(testLocation);
cheapActivity.setPriceRange(1);
Activity moderateActivity = new Activity();
moderateActivity.setName("Moderate Activity");
moderateActivity.setLocation(testLocation);
moderateActivity.setPriceRange(3);
Activity expensiveActivity = new Activity();
expensiveActivity.setName("Expensive Activity");
expensiveActivity.setLocation(testLocation);
expensiveActivity.setPriceRange(5);
activityRepository.saveAll(Arrays.asList(cheapActivity, moderateActivity, expensiveActivity));
entityManager.flush();
// When
List<Activity> budgetActivities = activityRepository.findByPriceRangeLessThanEqual(2);
List<Activity> moderateBudgetActivities = activityRepository.findByPriceRangeLessThanEqual(3);
// Then
assertThat(budgetActivities).hasSize(1);
assertThat(budgetActivities.get(0).getName()).isEqualTo("Budget Activity");
assertThat(moderateBudgetActivities).hasSize(2);
assertThat(moderateBudgetActivities)
.extracting(Activity::getName)
.containsExactlyInAnyOrder("Budget Activity", "Moderate Activity");
}
@Test
void shouldUpdateActivityTimestamps() {
// Given
Activity savedActivity = activityRepository.save(testActivity);
entityManager.flush();
entityManager.clear();
// When
Optional<Activity> retrievedActivity = activityRepository.findById(savedActivity.getId());
assertThat(retrievedActivity).isPresent();
Activity activityToUpdate = retrievedActivity.get();
activityToUpdate.setName("Updated Activity Name");
Activity updatedActivity = activityRepository.save(activityToUpdate);
entityManager.flush();
// Then
assertThat(updatedActivity.getCreatedAt()).isNotNull();
assertThat(updatedActivity.getUpdatedAt()).isNotNull();
assertThat(updatedActivity.getUpdatedAt()).isAfterOrEqualTo(updatedActivity.getCreatedAt());
}
@Test
void shouldDeleteActivity() {
// Given
Activity savedActivity = activityRepository.save(testActivity);
entityManager.flush();
Long activityId = savedActivity.getId();
// When
activityRepository.deleteById(activityId);
entityManager.flush();
// Then
Optional<Activity> deletedActivity = activityRepository.findById(activityId);
assertThat(deletedActivity).isEmpty();
}
}

View File

@@ -0,0 +1,46 @@
package com.vibing.backend;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import java.time.LocalDateTime;
import java.util.Random;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import com.vibing.backend.model.Activity;
import com.vibing.backend.model.Location;
import com.vibing.backend.repository.ActivityRepository;
import com.vibing.backend.service.ActivityService;
import net.datafaker.Faker;
@SpringBootTest
@ActiveProfiles("test")
@TestPropertySource(locations = "classpath:application-test.yml")
public class ActivityTestIt {
private Faker faker = new Faker(new Random(123));
@Autowired
private ActivityService activityService;
@Autowired
private ActivityRepository activityRepository;
@Test
void shouldSaveActivity() {
Activity activity = new Activity();
activity.setName(faker.location().publicSpace());
activity.setPriceRange(faker.number().numberBetween(1, 5));
activity.setTags(faker.lorem().words(3));
activity.setLocation(new Location().withName(faker.location().publicSpace()));
activityRepository.save(activity);
assertThat(activityService.findAll(), containsInAnyOrder(activity));
}
}

View File

@@ -1,6 +1,6 @@
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL;INIT=CREATE SCHEMA IF NOT EXISTS vibing
username: sa
password:
driver-class-name: org.h2.Driver
@@ -14,8 +14,12 @@ spring:
ddl-auto: none # Let Flyway handle schema creation
show-sql: true
database-platform: org.hibernate.dialect.H2Dialect
properties:
hibernate:
default_schema: vibing
flyway:
enabled: true
clean-disabled: false # Allow clean in tests
locations: classpath:db/migration
default-schema: vibing

View File

@@ -8,7 +8,4 @@ services:
POSTGRES_PASSWORD: vibing
POSTGRES_DB: vibing
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
- postgres_data:/var/lib/postgresql/data