Dashboard mit Anrufhistorie und Dev-Schalter ergänzt
This commit is contained in:
1 parent
afd6d03a71
commit
373081d33d
11 files changed
+713
-144
No files matched your search
@@ -141,6 +141,12 @@ public class ArchiveService {
|
||||
submit("Anrufdaten", () -> calls.forEach(mongo::save));
|
||||
}
|
||||
|
||||
/** Historie der eingehenden Anrufe, auch aus früheren Browser-Sitzungen. */
|
||||
public List<StoredCall> incomingCalls() {
|
||||
return mongo.find(new Query(Criteria.where("event").is("incoming"))
|
||||
.with(Sort.by(Sort.Direction.DESC, "receivedAt", "id")), StoredCall.class);
|
||||
}
|
||||
|
||||
private void submit(String what, Runnable write) {
|
||||
worker.execute(() -> {
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -37,6 +38,12 @@ public class CallController {
|
||||
this.archive = archive;
|
||||
}
|
||||
|
||||
/** Eingegangene Anrufe, neueste zuerst; Verbindungs- und Ende-Ereignisse zählen nicht erneut. */
|
||||
@GetMapping
|
||||
public List<StoredCall> list() {
|
||||
return archive.incomingCalls();
|
||||
}
|
||||
|
||||
/** Ein Anruf-Ereignis, wie es das Frontend schickt – Felder wie im CallEvent. */
|
||||
public record CallEventBody(
|
||||
Integer line,
|
||||
|
||||
@@ -2,10 +2,15 @@ package de.appcreation.swyxweb;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
|
||||
@@ -15,6 +20,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import de.appcreation.swyxweb.storage.ArchiveService;
|
||||
import de.appcreation.swyxweb.storage.StoredCall;
|
||||
|
||||
/**
|
||||
* Der Endpunkt nimmt die Anruf-Ereignisse der Startseite an und bestätigt nur
|
||||
@@ -31,6 +37,29 @@ class CallControllerTests {
|
||||
@MockitoBean
|
||||
ArchiveService archive;
|
||||
|
||||
@Test
|
||||
void returnsArchivedIncomingCallsWithoutAnActiveTrayConnection() throws Exception {
|
||||
when(archive.incomingCalls()).thenReturn(List.of(new StoredCall(
|
||||
"call-1", Instant.parse("2026-09-20T08:30:00Z"), 1, "incoming", "incoming",
|
||||
"Muster GmbH (+493012345)", "+493012345", "Muster GmbH", "klingelt", "LSRinging")));
|
||||
|
||||
mvc.perform(get("/api/calls"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.length()").value(1))
|
||||
.andExpect(jsonPath("$[0].id").value("call-1"))
|
||||
.andExpect(jsonPath("$[0].receivedAt").value("2026-09-20T08:30:00Z"))
|
||||
.andExpect(jsonPath("$[0].peerNumber").value("+493012345"))
|
||||
.andExpect(jsonPath("$[0].peerName").value("Muster GmbH"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsEmptyHistoryAsAnEmptyArray() throws Exception {
|
||||
when(archive.incomingCalls()).thenReturn(List.of());
|
||||
mvc.perform(get("/api/calls"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.length()").value(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void acceptsEventsAndReturnsCount() throws Exception {
|
||||
mvc.perform(post("/api/calls")
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package de.appcreation.swyxweb;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
import de.appcreation.swyxweb.storage.ArchiveService;
|
||||
import de.appcreation.swyxweb.storage.StoredCall;
|
||||
|
||||
class CallHistoryTests {
|
||||
|
||||
@Test
|
||||
void readsOnlyIncomingEventsInNewestFirstOrder() {
|
||||
MongoTemplate mongo = mock(MongoTemplate.class);
|
||||
new ArchiveService(mongo).incomingCalls();
|
||||
|
||||
ArgumentCaptor<Query> query = ArgumentCaptor.forClass(Query.class);
|
||||
verify(mongo).find(query.capture(), eq(StoredCall.class));
|
||||
// direction=incoming würde auch connected/ended zählen und Anrufe verdreifachen.
|
||||
assertThat(query.getValue().getQueryObject()).containsOnlyKeys("event")
|
||||
.containsEntry("event", "incoming");
|
||||
assertThat(query.getValue().getSortObject()).containsEntry("receivedAt", -1)
|
||||
.containsEntry("id", -1);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user