package mock import ( "context" "strings" "testing" "time" "tera-clone/services/tera-api/internal/directstream" "tera-clone/services/tera-api/internal/domain" ) func TestDirectTicketAuthorityConsumesAuditsAndAppliesVerifiedLifecycle(t *testing.T) { store := NewStore(time.Now) ctx := domain.WithActor(context.Background(), domain.Actor{Name: "admin"}) session, err := store.OpenDirectSession(ctx, "CH01", domain.DirectSessionRequest{Access: directstream.AccessWriter}) if err != nil { t.Fatalf("open direct session: %v", err) } authority := NewDirectTicketAuthority(store) claims, err := authority.ConsumeTicket(context.Background(), session.StreamTicket, directstream.TicketBinding{ SessionID: session.SessionID, Channel: session.Channel, }) if err != nil { t.Fatalf("consume ticket: %v", err) } if claims.Actor != "admin" || claims.Access != directstream.AccessWriter { t.Fatalf("claims = %#v", claims) } store.mu.Lock() store.runningRetention.LocalOperationEnabled = false store.mu.Unlock() connected := directstream.SessionEvent{ Type: directstream.SessionEventConnected, Source: "192.168.0.10", Timestamp: time.Date(2026, 8, 13, 3, 4, 5, 0, time.UTC), } if err := authority.RecordConsumedStreamEvent(context.Background(), claims, connected); err != nil { t.Fatalf("record connected stream event: %v", err) } disconnected := directstream.SessionEvent{ Type: directstream.SessionEventDisconnected, Source: connected.Source, Timestamp: connected.Timestamp.Add(time.Minute), } if err := authority.RecordConsumedStreamEvent(context.Background(), claims, disconnected); err != nil { t.Fatalf("record disconnected stream event: %v", err) } if err := authority.ReleaseConsumedWriter(context.Background(), claims); err != nil { t.Fatalf("release writer: %v", err) } if err := authority.CloseConsumedStream(context.Background(), claims); err != nil { t.Fatalf("close stream: %v", err) } events, err := store.AuditEvents(context.Background()) if err != nil { t.Fatal(err) } correlated := map[string]bool{ "direct.session.open": false, "direct.stream.ticket.consume": false, "direct.writer.release": false, "direct.session.close": false, } for _, event := range events { if _, required := correlated[event.Action]; required && event.Actor == "admin" && event.Result == "succeeded" && strings.Contains(event.Message, session.SessionID) { correlated[event.Action] = true } } for action, found := range correlated { if !found { t.Fatalf("%s audit is not correlated by session %s: %#v", action, session.SessionID, events) } } portEvents, err := store.PortLogEvents(context.Background(), domain.PortLogFilter{Channel: "CH01", EventType: "session"}) if err != nil { t.Fatal(err) } wantWelcomeLog := strings.Join(strings.Fields(directstream.SessionEventMessage(claims, connected)), " ") if len(portEvents) != 2 || portEvents[0].Actor != "admin/"+session.SessionID || portEvents[0].Message != wantWelcomeLog { t.Fatalf("port session events = %#v", portEvents) } if !strings.Contains(portEvents[1].Message, "session disconnected") || !strings.Contains(portEvents[1].Message, "Serial channel: CH01") { t.Fatalf("disconnect port event = %#v", portEvents[1]) } }