Enable creating an API using Spring Web #5

Merged
niat8586 merged 39 commits from spring into develop 2024-11-06 11:23:29 +01:00
2 changed files with 106 additions and 39 deletions
Showing only changes of commit 375b9663dc - Show all commits

View File

@ -135,6 +135,12 @@
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>

View File

@ -1,67 +1,67 @@
package se.su.dsv.scipro.test; package se.su.dsv.scipro.test;
import com.google.inject.AbstractModule; import com.google.common.eventbus.EventBus;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.persist.PersistService; import jakarta.inject.Provider;
import com.google.inject.persist.UnitOfWork;
import com.google.inject.persist.jpa.JpaPersistModule;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction; import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import jakarta.inject.Inject; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import jakarta.inject.Provider; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import se.su.dsv.scipro.forum.AbstractThreadRepositoryImpl;
import se.su.dsv.scipro.grading.GradingHistory;
import se.su.dsv.scipro.grading.GradingHistoryEventRepository;
import se.su.dsv.scipro.oauth.OAuthSettings;
import se.su.dsv.scipro.security.auth.LocalAuthentication;
import se.su.dsv.scipro.sukat.Sukat;
import se.su.dsv.scipro.system.CurrentUser;
import se.su.dsv.scipro.system.PasswordService;
import se.su.dsv.scipro.system.UserService;
import java.time.Clock; import java.time.Clock;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public abstract class GuiceTest { public abstract class GuiceTest {
@Inject private EntityManager entityManager;
private UnitOfWork unitOfWork; private EntityManagerFactory entityManagerFactory;
@Inject
private PersistService persistService;
@Inject
private Provider<EntityManager> entityManager;
@BeforeEach @BeforeEach
public final void prepareGuice() { public final void prepareGuice() {
Injector injector = Guice.createInjector( entityManagerFactory = Persistence.createEntityManagerFactory("testPersistenceUnit");
new JpaPersistModule("testPersistenceUnit"), this.entityManager = entityManagerFactory.createEntityManager();
new AbstractModule() { EntityTransaction transaction = entityManager.getTransaction();
@Override
protected void configure() {
final MutableFixedClock clock = new MutableFixedClock(Clock.systemDefaultZone());
bind(Clock.class).toInstance(clock);
bind(MutableFixedClock.class).toInstance(clock);
}
},
moduleUnderTest());
// Have to start the PersistService and UnitOfWork manually since they are no longer
// automatically started as an EntityManager is injected
injector.getInstance(PersistService.class).start();
injector.getInstance(UnitOfWork.class).begin();
injector.injectMembers(this);
persistService.start();
EntityTransaction transaction = entityManager.get().getTransaction();
transaction.begin(); transaction.begin();
transaction.setRollbackOnly(); transaction.setRollbackOnly();
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(TestContext.class);
annotationConfigApplicationContext.getBeanFactory()
.registerSingleton("entityManager", this.entityManager);
annotationConfigApplicationContext.refresh();
annotationConfigApplicationContext.getAutowireCapableBeanFactory()
.autowireBean(this);
} }
protected abstract Module moduleUnderTest(); protected abstract Module moduleUnderTest();
@AfterEach @AfterEach
public final void shutDownPersistence() { public final void shutDownPersistence() {
entityManager.get().getTransaction().rollback(); entityManager.getTransaction().rollback();
unitOfWork.end(); entityManager.close();
persistService.stop(); entityManagerFactory.close();
} }
protected <T> T save(T entity) { protected <T> T save(T entity) {
EntityManager em = entityManager.get(); EntityManager em = entityManager;
if (em.contains(entity)) { if (em.contains(entity)) {
return em.merge(entity); return em.merge(entity);
} }
@ -70,4 +70,65 @@ public abstract class GuiceTest {
return entity; return entity;
} }
} }
@Configuration(proxyBeanMethods = false)
@ComponentScan(
basePackages = "se.su.dsv.scipro",
includeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Impl$"),
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = {
".*Abstract.*",
".*[Dd]aisy.*",
".*GradingServiceImpl"
}))
public static class TestContext {
@Bean
public EventBus eventBus() {
return new EventBus();
}
@Bean
public InMemoryFileStore inMemoryFileStore() {
return new InMemoryFileStore();
}
@Bean
public MutableFixedClock clock() {
return new MutableFixedClock(Clock.systemDefaultZone());
}
@Bean
public GradingHistory gradingHistory(GradingHistoryEventRepository gradingHistoryEventRepository) {
return new GradingHistory(gradingHistoryEventRepository);
}
@Bean
public AbstractThreadRepositoryImpl abstractThreadRepository(Provider<EntityManager> em) {
return new AbstractThreadRepositoryImpl(em);
}
@Bean
public OAuthSettings oAuthSettings() {
return new OAuthSettings("uri", "redirectUri", "clientId", "clientSecret");
}
@Bean
public Sukat sukat() {
return (username) -> Optional.empty();
}
@Bean
public ScheduledExecutorService scheduledExecutorService() {
return Executors.newSingleThreadScheduledExecutor();
}
@Bean
public CurrentUser currentUser() {
return () -> null;
}
@Bean
public LocalAuthentication localAuthentication(UserService userService, PasswordService passwordService) {
return new LocalAuthentication(userService, passwordService);
}
}
} }