Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cotlib.go
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,10 @@ func (e *Event) ValidateAt(now time.Time) error {
if err2 := validator.ValidateAgainstSchema("tak-details-__chat", data); err2 != nil {
return fmt.Errorf("chat validation failed: %w", err)
}
} else {
if err := validator.ValidateChat(data); err != nil {
return fmt.Errorf("chat validation failed: %w", err)
}
}
}
if e.Detail.ChatReceipt != nil {
Expand Down Expand Up @@ -2090,6 +2094,11 @@ func (e *Event) ToXML() ([]byte, error) {
buf.WriteString(escapeAttr(e.Detail.Chat.MessageID))
buf.WriteByte('"')
}
if e.Detail.Chat.DeleteChild != "" {
buf.WriteString(` deleteChild="`)
buf.WriteString(escapeAttr(e.Detail.Chat.DeleteChild))
buf.WriteByte('"')
}
if len(e.Detail.Chat.ChatGrps) == 0 && e.Detail.Chat.Hierarchy == nil {
buf.WriteString("/>\n")
} else {
Expand Down
7 changes: 7 additions & 0 deletions detail_extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
SenderCallsign string `xml:"senderCallsign,attr,omitempty"`
Parent string `xml:"parent,attr,omitempty"`
MessageID string `xml:"messageId,attr,omitempty"`
DeleteChild string `xml:"deleteChild,attr,omitempty"`
ChatGrps []ChatGrp `xml:"chatgrp,omitempty"`
Hierarchy *Hierarchy `xml:"hierarchy,omitempty"`
Raw RawMessage `xml:"-"`
Expand Down Expand Up @@ -282,6 +283,10 @@
if err2 := validator.ValidateAgainstSchema("tak-details-__chat", raw); err2 != nil {
return err
}
} else {
if err := validator.ValidateChat(raw); err != nil {
return err
}
}

var helper struct {
Expand All @@ -294,9 +299,10 @@
SenderCallsign string `xml:"senderCallsign,attr,omitempty"`
Parent string `xml:"parent,attr,omitempty"`
MessageID string `xml:"messageId,attr,omitempty"`
DeleteChild string `xml:"deleteChild,attr,omitempty"`
ChatGrps []ChatGrp `xml:"chatgrp"`
Hierarchy *Hierarchy `xml:"hierarchy"`
_ string `xml:",innerxml"`

Check failure on line 305 in detail_extensions.go

View workflow job for this annotation

GitHub Actions / build

struct field _ has xml tag but is not exported

Check failure on line 305 in detail_extensions.go

View workflow job for this annotation

GitHub Actions / build

struct field _ has xml tag but is not exported
}

if err := xml.Unmarshal(raw, &helper); err != nil {
Expand All @@ -312,6 +318,7 @@
c.SenderCallsign = helper.SenderCallsign
c.Parent = helper.Parent
c.MessageID = helper.MessageID
c.DeleteChild = helper.DeleteChild
c.ChatGrps = helper.ChatGrps
c.Hierarchy = helper.Hierarchy
return nil
Expand Down Expand Up @@ -353,7 +360,7 @@
MessageID string `xml:"messageId,attr,omitempty"`
Parent string `xml:"parent,attr,omitempty"`
ChatGrp *ChatGrp `xml:"chatgrp,omitempty"`
_ string `xml:",innerxml"`

Check failure on line 363 in detail_extensions.go

View workflow job for this annotation

GitHub Actions / build

struct field _ has xml tag but is not exported

Check failure on line 363 in detail_extensions.go

View workflow job for this annotation

GitHub Actions / build

struct field _ has xml tag but is not exported
}
if err := xml.Unmarshal(raw, &helper); err != nil {
return err
Expand Down
45 changes: 45 additions & 0 deletions validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,26 @@ func TestHowRelationDescriptors(t *testing.T) {
})
}

func TestChatValidationMissingFields(t *testing.T) {
evt, err := cotlib.NewEvent("C1", "t-x-c", 0, 0, 0)
if err != nil {
t.Fatalf("new event: %v", err)
}
evt.Detail = &cotlib.Detail{Chat: &cotlib.Chat{Message: "", Sender: ""}}
if err := evt.Validate(); err == nil {
t.Fatal("expected error for empty chat sender and message")
}
evt.Detail.Chat.Message = "hi"
if err := evt.Validate(); err == nil {
t.Fatal("expected error for empty chat sender")
}
evt.Detail.Chat.Sender = "A"
if err := evt.Validate(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
cotlib.ReleaseEvent(evt)
}

func TestDetailExtensionsRoundTrip(t *testing.T) {
evt, err := cotlib.NewEvent("X1", "a-f-G", 1, 2, 3)
if err != nil {
Expand Down Expand Up @@ -878,6 +898,31 @@ func TestTAKDetailSchemaValidation(t *testing.T) {
cotlib.ReleaseEvent(evt)
})

t.Run("tak_chat_deletechild", func(t *testing.T) {
now := time.Now().UTC()
xmlData := fmt.Sprintf(`<event version="2.0" uid="U" type="a-f-G" time="%[1]s" start="%[1]s" stale="%[2]s">`+
`<point lat="0" lon="0" hae="0" ce="1" le="1"/>`+
`<detail><__chat chatroom="c" groupOwner="false" id="1" senderCallsign="A" deleteChild="child"><chatgrp id="g" uid0="u0"/></__chat></detail>`+
`</event>`,
now.Format(cotlib.CotTimeFormat),
now.Add(10*time.Second).Format(cotlib.CotTimeFormat))
evt, err := cotlib.UnmarshalXMLEvent(context.Background(), []byte(xmlData))
if err != nil {
t.Fatalf("unmarshal: %v", err)
}
if evt.Detail.Chat.DeleteChild != "child" {
t.Errorf("deleteChild parsed incorrectly: %s", evt.Detail.Chat.DeleteChild)
}
out, err := evt.ToXML()
if err != nil {
t.Fatalf("marshal: %v", err)
}
if !bytes.Contains(out, []byte(`deleteChild="child"`)) {
t.Errorf("expected deleteChild attribute in output")
}
cotlib.ReleaseEvent(evt)
})

t.Run("marti_geochat_roundtrip", func(t *testing.T) {
evt, err := cotlib.NewEvent("M1", "b-t-f", 1, 2, 3)
if err != nil {
Expand Down
Loading