~samwhited/xmpp

a4ca2303335f3d2056bb49d9f036d6073f5dbe35 — Sam Whited 2 months ago ec3d2a5
muc: add method to set subject

Signed-off-by: Sam Whited <sam@samwhited.com>
2 files changed, 73 insertions(+), 0 deletions(-)

M muc/room.go
M muc/room_test.go
M muc/room.go => muc/room.go +18 -0
@@ 224,3 224,21 @@ func (c *Channel) JoinPresence(ctx context.Context, p stanza.Presence, opt ...Op

	return nil
}

// Subject attempts to change the room subject.
// It returns immediately after the request has been sent and does not wait to
// see if the request was successful or not.
func (c *Channel) Subject(ctx context.Context, subject string) error {
	return c.SubjectMessage(ctx, subject, stanza.Message{})
}

// SubjectMessage is like Subject except that it allows you to customize the
// message stanza. Changing the receipient or type has no effect.
func (c *Channel) SubjectMessage(ctx context.Context, subject string, m stanza.Message) error {
	m.Type = stanza.GroupChatMessage
	m.To = c.addr.Bare()
	return c.session.Send(ctx, m.Wrap(xmlstream.Wrap(
		xmlstream.Token(xml.CharData(subject)),
		xml.StartElement{Name: xml.Name{Local: "subject"}},
	)))
}

M muc/room_test.go => muc/room_test.go +55 -0
@@ 171,3 171,58 @@ func TestSetAffiliation(t *testing.T) {
		})
	}
}

func TestSetSubject(t *testing.T) {
	j := jid.MustParse("room@example.net/me")
	h := &muc.Client{}
	handled := make(chan string, 1)
	m := mux.New(muc.HandleClient(h))
	server := mux.New(
		mux.PresenceFunc("", xml.Name{Local: "x"}, func(p stanza.Presence, r xmlstream.TokenReadEncoder) error {
			// Send back a self presence, indicating that the join is complete.
			p.To, p.From = p.From, p.To
			_, err := xmlstream.Copy(r, p.Wrap(xmlstream.Wrap(
				nil,
				xml.StartElement{Name: xml.Name{Space: muc.NSUser, Local: "x"}},
			)))
			return err
		}),
		mux.MessageFunc(stanza.GroupChatMessage, xml.Name{Local: "subject"}, func(_ stanza.Message, r xmlstream.TokenReadEncoder) error {
			d := xml.NewTokenDecoder(r)
			// Throw away the <message> token.
			_, err := d.Token()
			if err != nil {
				return nil
			}
			s := struct {
				XMLName xml.Name `xml:"subject"`
				Subject string   `xml:",chardata"`
			}{}
			err = d.Decode(&s)
			if err != nil {
				return err
			}
			handled <- s.Subject
			return nil
		}),
	)
	s := xmpptest.NewClientServer(
		xmpptest.ClientHandler(m),
		xmpptest.ServerHandler(server),
	)

	channel, err := h.Join(context.Background(), j, s.Client)
	if err != nil {
		t.Fatalf("error joining: %v", err)
	}

	const expected = "test"
	err = channel.Subject(context.Background(), expected)
	if err != nil {
		t.Fatalf("error setting subject: %v", err)
	}
	x := <-handled
	if x != expected {
		t.Fatalf("wrong output:\nwant=%s,\n got=%s", expected, x)
	}
}