Refactor API to remove active status filtering and add song management functionality also remove the uneeded auth check in the get towers route

This commit is contained in:
Lukas Weger 2025-08-01 23:58:50 +02:00
parent fd80051d9e
commit 892eafdac4
9 changed files with 130 additions and 198 deletions

View file

@ -55,16 +55,8 @@ public class RadioStationController {
}
@GetMapping
public ResponseEntity<ApiResponse<List<RadioStation>>> getAllRadioStations(
@RequestParam(defaultValue = "false") boolean activeOnly) {
String currentUserId = AuthUtil.getCurrentUserId();
if (currentUserId == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(ApiResponse.error("User not authenticated"));
}
List<RadioStation> stations = activeOnly ? radioStationService.getActiveRadioStations()
: radioStationService.getAllRadioStations();
public ResponseEntity<ApiResponse<List<RadioStation>>> getAllRadioStations() {
List<RadioStation> stations = radioStationService.getAllRadioStations();
return ResponseEntity.ok(ApiResponse.success(stations));
}

View file

@ -0,0 +1,41 @@
package com.serena.backend.controller;
import com.serena.backend.dto.ApiResponse;
import com.serena.backend.dto.ConnectClientRequest;
import com.serena.backend.dto.AddSongRequest;
import com.serena.backend.dto.AddSongToStationRequest;
import com.serena.backend.service.RadioStationService;
import com.serena.backend.service.JwtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/songs/")
@CrossOrigin(origins = "*")
public class SongController {
@Autowired
private RadioStationService radioStationService;
@Autowired
private JwtService jwtService;
@PostMapping
public ResponseEntity<ApiResponse<Void>> addSong(@RequestBody AddSongRequest request) {
if (request.getSong() == null || request.getRadioStationId() == null) {
return ResponseEntity.badRequest()
.body(new ApiResponse<>(false, "Song data and radio station ID are required", null));
}
boolean success = radioStationService.addSongToQueue(request.getRadioStationId(), request.getSong());
if (success) {
return ResponseEntity.ok(new ApiResponse<>(true, "Song added to queue successfully", null));
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ApiResponse<>(false, "Radio station not found or inactive", null));
}
}
}

View file

@ -0,0 +1,31 @@
package com.serena.backend.dto;
import com.serena.backend.model.Song;
public class AddSongRequest {
private Song song;
private String radioStationId;
public AddSongRequest() {}
public AddSongRequest(Song song, String radioStationId) {
this.song = song;
this.radioStationId = radioStationId;
}
public Song getSong() {
return song;
}
public void setSong(Song song) {
this.song = song;
}
public String getRadioStationId() {
return radioStationId;
}
public void setRadioStationId(String radioStationId) {
this.radioStationId = radioStationId;
}
}

View file

@ -8,12 +8,10 @@ public class Client {
private String username;
private String radioStationId;
private LocalDateTime connectedAt;
private boolean isActive;
public Client() {
this.id = UUID.randomUUID().toString();
this.connectedAt = LocalDateTime.now();
this.isActive = true;
}
public Client(String username, String radioStationId) {
@ -55,11 +53,4 @@ public class Client {
this.connectedAt = connectedAt;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
}

View file

@ -5,6 +5,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.LinkedList;
import java.util.Queue;
public class RadioStation {
private String id;
@ -13,15 +15,15 @@ public class RadioStation {
private String ownerId;
private String joinCode;
private LocalDateTime createdAt;
private boolean isActive;
private List<String> connectedClients;
private Queue<Song> songQueue;
public RadioStation() {
this.id = UUID.randomUUID().toString();
this.joinCode = generateJoinCode();
this.createdAt = LocalDateTime.now();
this.isActive = true;
this.connectedClients = new ArrayList<>();
this.songQueue = new LinkedList<>();
}
public RadioStation(String name, String description, String ownerId) {
@ -91,14 +93,6 @@ public class RadioStation {
this.createdAt = createdAt;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
public List<String> getConnectedClients() {
return connectedClients;
}
@ -107,4 +101,20 @@ public class RadioStation {
this.connectedClients = connectedClients;
}
public Queue<Song> getSongQueue() {
return songQueue;
}
public void setSongQueue(Queue<Song> songQueue) {
this.songQueue = songQueue;
}
public void addSongToQueue(Song song) {
this.songQueue.offer(song);
}
public Song getNextSong() {
return this.songQueue.poll();
}
}

View file

@ -0,0 +1,30 @@
package com.serena.backend.model;
public class Song {
private String id;
private int popularity;
public Song() {}
public Song(String id, int popularity) {
this.id = id;
this.popularity = popularity;
}
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getPopularity() {
return popularity;
}
public void setPopularity(int popularity) {
this.popularity = popularity;
}
}

View file

@ -2,6 +2,7 @@ package com.serena.backend.service;
import com.serena.backend.model.RadioStation;
import com.serena.backend.model.Client;
import com.serena.backend.model.Song;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -29,7 +30,7 @@ public class RadioStationService {
public Optional<RadioStation> getRadioStationByJoinCode(String joinCode) {
return radioStations.values().stream()
.filter(station -> station.getJoinCode().equals(joinCode) && station.isActive())
.filter(station -> station.getJoinCode().equals(joinCode))
.findFirst();
}
@ -39,7 +40,6 @@ public class RadioStationService {
public List<RadioStation> getActiveRadioStations() {
return radioStations.values().stream()
.filter(RadioStation::isActive)
.toList();
}
@ -58,7 +58,6 @@ public class RadioStationService {
public boolean deleteRadioStation(String stationId) {
RadioStation station = radioStations.get(stationId);
if (station != null) {
station.setActive(false);
// Disconnect all clients
station.getConnectedClients().clear();
// Remove from clients map
@ -72,7 +71,7 @@ public class RadioStationService {
// Client Management
public Optional<Client> connectClient(String username, String radioStationId, String joinCode) {
RadioStation station = radioStations.get(radioStationId);
if (station != null && station.isActive() && station.getJoinCode().equals(joinCode)) {
if (station != null && station.getJoinCode().equals(joinCode)) {
Client client = new Client(username, radioStationId);
clients.put(client.getId(), client);
station.getConnectedClients().add(client.getId());

View file

@ -1,154 +0,0 @@
package com.serena.backend.service;
import com.serena.backend.model.RadioStation;
import com.serena.backend.model.Client;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
class RadioStationServiceTest {
private RadioStationService radioStationService;
@BeforeEach
void setUp() {
radioStationService = new RadioStationService();
}
@Test
@DisplayName("Should create radio station with join code")
void shouldCreateRadioStationWithJoinCode() {
// Given
String name = "Test Station";
String description = "Test Description";
String ownerId = "owner123";
// When
RadioStation station = radioStationService.createRadioStation(name, description, ownerId);
// Then
assertNotNull(station);
assertNotNull(station.getId());
assertNotNull(station.getJoinCode());
assertEquals(6, station.getJoinCode().length());
assertEquals(name, station.getName());
assertEquals(description, station.getDescription());
assertEquals(ownerId, station.getOwnerId());
assertTrue(station.isActive());
}
@Test
@DisplayName("Should find radio station by join code")
void shouldFindRadioStationByJoinCode() {
// Given
RadioStation station = radioStationService.createRadioStation("Test Station", "Description", "owner123");
String joinCode = station.getJoinCode();
// When
Optional<RadioStation> foundStation = radioStationService.getRadioStationByJoinCode(joinCode);
// Then
assertTrue(foundStation.isPresent());
assertEquals(station.getId(), foundStation.get().getId());
assertEquals(joinCode, foundStation.get().getJoinCode());
}
@Test
@DisplayName("Should not find radio station with invalid join code")
void shouldNotFindRadioStationWithInvalidJoinCode() {
// Given
radioStationService.createRadioStation("Test Station", "Description", "owner123");
String invalidJoinCode = "INVALID";
// When
Optional<RadioStation> foundStation = radioStationService.getRadioStationByJoinCode(invalidJoinCode);
// Then
assertFalse(foundStation.isPresent());
}
@Test
@DisplayName("Should connect client with valid join code")
void shouldConnectClientWithValidJoinCode() {
// Given
RadioStation station = radioStationService.createRadioStation("Test Station", "Description", "owner123");
String username = "testuser";
String joinCode = station.getJoinCode();
// When
Optional<Client> client = radioStationService.connectClient(username, station.getId(), joinCode);
// Then
assertTrue(client.isPresent());
assertEquals(username, client.get().getUsername());
assertEquals(station.getId(), client.get().getRadioStationId());
assertTrue(station.getConnectedClients().contains(client.get().getId()));
}
@Test
@DisplayName("Should not connect client with invalid join code")
void shouldNotConnectClientWithInvalidJoinCode() {
// Given
RadioStation station = radioStationService.createRadioStation("Test Station", "Description", "owner123");
String username = "testuser";
String invalidJoinCode = "WRONG1";
// When
Optional<Client> client = radioStationService.connectClient(username, station.getId(), invalidJoinCode);
// Then
assertFalse(client.isPresent());
assertTrue(station.getConnectedClients().isEmpty());
}
@Test
@DisplayName("Should connect client using join code only")
void shouldConnectClientUsingJoinCodeOnly() {
// Given
RadioStation station = radioStationService.createRadioStation("Test Station", "Description", "owner123");
String username = "testuser";
String joinCode = station.getJoinCode();
// When
Optional<Client> client = radioStationService.connectClientByJoinCode(username, joinCode);
// Then
assertTrue(client.isPresent());
assertEquals(username, client.get().getUsername());
assertEquals(station.getId(), client.get().getRadioStationId());
assertTrue(station.getConnectedClients().contains(client.get().getId()));
}
@Test
@DisplayName("Should not connect client to inactive radio station")
void shouldNotConnectClientToInactiveRadioStation() {
// Given
RadioStation station = radioStationService.createRadioStation("Test Station", "Description", "owner123");
station.setActive(false);
String username = "testuser";
String joinCode = station.getJoinCode();
// When
Optional<Client> client = radioStationService.connectClient(username, station.getId(), joinCode);
// Then
assertFalse(client.isPresent());
}
@Test
@DisplayName("Should generate unique join codes for different stations")
void shouldGenerateUniqueJoinCodesForDifferentStations() {
// Given & When
RadioStation station1 = radioStationService.createRadioStation("Station 1", "Desc 1", "owner1");
RadioStation station2 = radioStationService.createRadioStation("Station 2", "Desc 2", "owner2");
// Then
assertNotEquals(station1.getJoinCode(), station2.getJoinCode());
assertEquals(6, station1.getJoinCode().length());
assertEquals(6, station2.getJoinCode().length());
}
}