Skip to content

Commit

Permalink
Add search service skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
Migwel authored and Migwel committed Dec 25, 2023
1 parent 553739c commit f45a207
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/main/java/dev/migwel/sts/model/RadioSearchRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.migwel.sts.model;

public record RadioSearchRequest(String url) implements SearchRequest {}
3 changes: 3 additions & 0 deletions src/main/java/dev/migwel/sts/model/SearchRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.migwel.sts.model;

public sealed interface SearchRequest permits SonosSearchRequest, RadioSearchRequest {}
3 changes: 3 additions & 0 deletions src/main/java/dev/migwel/sts/model/Song.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.migwel.sts.model;

public record Song(String artist, String title) {}
3 changes: 3 additions & 0 deletions src/main/java/dev/migwel/sts/model/SonosSearchRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.migwel.sts.model;

public record SonosSearchRequest(String householdId, String groupId) implements SearchRequest {}
22 changes: 22 additions & 0 deletions src/main/java/dev/migwel/sts/radio/RadioSearchService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.migwel.sts.radio;

import dev.migwel.sts.model.RadioSearchRequest;
import dev.migwel.sts.model.Song;
import dev.migwel.sts.service.SearchService;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class RadioSearchService implements SearchService<RadioSearchRequest> {

@Override
public boolean isRelevant(Class<?> searchRequestType) {
return searchRequestType.isAssignableFrom(RadioSearchRequest.class);
}

@Override
public Optional<Song> search(RadioSearchRequest searchRequest) {
return Optional.empty();
}
}
12 changes: 12 additions & 0 deletions src/main/java/dev/migwel/sts/service/SearchService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dev.migwel.sts.service;

import dev.migwel.sts.model.SearchRequest;
import dev.migwel.sts.model.Song;

import java.util.Optional;

public interface SearchService<T extends SearchRequest> {
boolean isRelevant(Class<?> searchRequestType);

Optional<Song> search(T searchRequest);
}
27 changes: 27 additions & 0 deletions src/main/java/dev/migwel/sts/service/SearchServiceFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.migwel.sts.service;

import dev.migwel.sts.model.SearchRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class SearchServiceFactory {

private final List<SearchService<?>> searchServices;

@Autowired
public SearchServiceFactory(List<SearchService<?>> searchServices) {
this.searchServices = List.copyOf(searchServices);
}

public <T extends SearchRequest> SearchService<T> getSearchService(T searchRequest) {
for (SearchService<?> searchService : searchServices) {
if (searchService.isRelevant(searchRequest.getClass())) {
return (SearchService<T>) searchService;
}
}
throw new IllegalArgumentException("No search service available for this search request");
}
}
22 changes: 22 additions & 0 deletions src/main/java/dev/migwel/sts/sonos/SonosSearchService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.migwel.sts.sonos;

import dev.migwel.sts.model.Song;
import dev.migwel.sts.model.SonosSearchRequest;
import dev.migwel.sts.service.SearchService;

import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class SonosSearchService implements SearchService<SonosSearchRequest> {
@Override
public boolean isRelevant(Class<?> searchRequestType) {
return searchRequestType.isAssignableFrom(SonosSearchRequest.class);
}

@Override
public Optional<Song> search(SonosSearchRequest searchRequest) {
return Optional.empty();
}
}
28 changes: 28 additions & 0 deletions src/test/java/dev/migwel/sts/ApplicationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.migwel.sts;

import static org.junit.jupiter.api.Assertions.*;

import dev.migwel.sts.service.SearchService;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class ApplicationTest {

private final List<SearchService<?>> searchServices;

@Autowired
public ApplicationTest(List<SearchService<?>> searchServices) {
this.searchServices = searchServices;
}

@Test
void loadContexts() {
assertNotNull(searchServices);
assertFalse(searchServices.isEmpty());
}
}
41 changes: 41 additions & 0 deletions src/test/java/dev/migwel/sts/service/SearchServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package dev.migwel.sts.service;

import static org.junit.jupiter.api.Assertions.*;

import dev.migwel.sts.Application;
import dev.migwel.sts.model.SearchRequest;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

import java.util.List;

@SpringJUnitConfig(Application.class)
class SearchServiceTest {

private final List<SearchService<?>> searchServices;

@Autowired
public SearchServiceTest(List<SearchService<?>> searchServices) {
this.searchServices = searchServices;
}

@Test
void isRelevant_onlyOneRelevantServicePerRequestType() {
Class<?>[] permittedSearchRequests = SearchRequest.class.getPermittedSubclasses();
for (Class<?> permittedSearchRequest : permittedSearchRequests) {
int nbRelevantSearchServices = 0;
for (SearchService<?> searchService : searchServices) {
if (searchService.isRelevant(permittedSearchRequest)) {
nbRelevantSearchServices += 1;
}
}
assertEquals(
1,
nbRelevantSearchServices,
"Didn't find exactly one search service for request "
+ permittedSearchRequest.getName());
}
}
}

0 comments on commit f45a207

Please sign in to comment.