Glos na zywo po stronie serwera, ikona blokady czatu
Deploy PROD / deploy (push) Successful in 26s

Przyznanie i odebranie glosu oraz oba tryby (otwarty mikrofon, wideo dla
wszystkich) zmieniaja uprawnienia uczestnika przez updateParticipant,
bez ponownego wejscia na sale. Odebranie najpierw wycisza sciezke na
serwerze, wiec dziala takze u klienta, ktory nie odebral zdarzenia.
Sala LiveKit ma staly key; mikrofon wlacza sie sam po przyznaniu glosu.

Rola uczestnika liczona w jednym miejscu (VideoService.participantRole)
dla biletu i zmiany na zywo. RoomPermissionTest pilnuje jawnej listy
zrodel publikacji.

Blokada pisania na czacie ma ikone przekreslonego dymku i znacznik
"bez czatu" zamiast przekreslonego mikrofonu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 08:55:24 +02:00
parent e9bb4af59f
commit 515d9a41e2
14 changed files with 465 additions and 75 deletions
@@ -0,0 +1,56 @@
package com.softspm.webinar.video;
import livekit.LivekitModels.TrackSource;
import org.junit.jupiter.api.Test;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Uprawnienia zmieniane na zywo (`RoomPermissionSync`) musza odpowiadac tym
* z tokenu.
*
* Najgrozniejsza pulapka: u LiveKit `canPublish=true` z PUSTA lista zrodel
* znaczy "wszystkie zrodla". Uczestnik z glosem dostalby wtedy kamere
* i udostepnianie ekranu, a blad nie bylby widoczny w interfejsie, dopoki
* ktos nie sprobuje ich wlaczyc.
*/
class RoomPermissionTest {
private final LiveKitVideoProvider provider = new LiveKitVideoProvider(null);
@Test
void viewerCannotPublishAnything() {
var permission = provider.permissionFor(RoomRole.VIEWER);
assertThat(permission.getCanPublish()).isFalse();
assertThat(permission.getCanSubscribe()).isTrue();
}
@Test
void speakerGetsMicrophoneOnly() {
var permission = provider.permissionFor(RoomRole.SPEAKER);
assertThat(permission.getCanPublish()).isTrue();
assertThat(Set.copyOf(permission.getCanPublishSourcesList()))
.containsExactly(TrackSource.MICROPHONE);
}
@Test
void activeParticipantGetsCameraAndMicrophoneButNoScreen() {
var permission = provider.permissionFor(RoomRole.ACTIVE_PARTICIPANT);
assertThat(Set.copyOf(permission.getCanPublishSourcesList()))
.containsExactlyInAnyOrder(TrackSource.CAMERA, TrackSource.MICROPHONE);
}
@Test
void everyPublishingRoleHasExplicitSources() {
for (RoomRole role : RoomRole.values()) {
var permission = provider.permissionFor(role);
if (permission.getCanPublish()) {
assertThat(permission.getCanPublishSourcesList())
.as("rola %s: pusta lista zrodel oznacza u LiveKit wszystkie zrodla", role)
.isNotEmpty();
}
}
}
}