Everyone signs in at the one central Quine identity server and is called by username. The caller picks which Jitsi Meet server each call happens on (meet.jit.si by default, or any other deployment), and the invite sends the callee to the same one. Jitsi servers need no credentials from Quple. - server: POST /call takes an optional jitsiUrl (http(s) only, no credentials/query/fragment; default DEFAULT_JITSI) and returns it with the meeting ID; invites carry it. Adds GET /me and per-person contacts with presence (persisted in DATA_DIR), replacing GET /users. - desktop: "On server" field for calls, remembered as the last-used server; incoming calls show which server they're on; open_meeting refuses non-http(s) URLs. meet.jit.si sign-in is now an inline prompt when calling there rather than a gate in front of the whole app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
979 B
Go
39 lines
979 B
Go
package main
|
|
|
|
import "testing"
|
|
|
|
func TestPlaceCallAndDrainInvites(t *testing.T) {
|
|
s := NewStore()
|
|
|
|
inv := s.PlaceCall("bob", Invite{From: "alice", MeetingID: newMeetingID()})
|
|
if inv.CreatedAt.IsZero() {
|
|
t.Fatal("CreatedAt not set")
|
|
}
|
|
|
|
got := s.DrainInvites("bob")
|
|
if len(got) != 1 || got[0].MeetingID != inv.MeetingID {
|
|
t.Fatalf("DrainInvites = %+v, want one invite with meetingId %q", got, inv.MeetingID)
|
|
}
|
|
|
|
// Second drain should be empty: invites are delivered once.
|
|
if got := s.DrainInvites("bob"); len(got) != 0 {
|
|
t.Fatalf("DrainInvites after drain = %+v, want empty", got)
|
|
}
|
|
}
|
|
|
|
func TestMeetingIDsAreDistinct(t *testing.T) {
|
|
if newMeetingID() == newMeetingID() {
|
|
t.Fatal("two meeting IDs collided")
|
|
}
|
|
}
|
|
|
|
func TestPresence(t *testing.T) {
|
|
s := NewStore()
|
|
if s.IsOnline("bob") {
|
|
t.Fatal("unknown user reported online")
|
|
}
|
|
s.DrainInvites("bob") // polling counts as presence
|
|
if !s.IsOnline("bob") {
|
|
t.Fatal("polling user not reported online")
|
|
}
|
|
}
|