| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- package wire
- import (
- "bytes"
- "testing"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
- )
- func TestBARTInfo_HasClearIconHash(t *testing.T) {
- tests := []struct {
- name string
- bartInfo BARTInfo
- want bool
- }{
- {
- bartInfo: BARTInfo{
- Hash: GetClearIconHash(),
- },
- want: true,
- },
- {
- bartInfo: BARTInfo{
- Hash: []byte{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'},
- },
- want: false,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- assert.Equal(t, tt.want, tt.bartInfo.HasClearIconHash())
- })
- }
- }
- func TestSNAC_0x01_0x14_OServiceSetPrivacyFlags_IdleFlag(t *testing.T) {
- type fields struct {
- PrivacyFlags uint32
- }
- tests := []struct {
- name string
- fields fields
- want bool
- }{
- {
- name: "flag is set",
- fields: fields{
- PrivacyFlags: OServicePrivacyFlagIdle | OServicePrivacyFlagMember,
- },
- want: true,
- },
- {
- name: "flag is not set",
- fields: fields{
- PrivacyFlags: OServicePrivacyFlagMember,
- },
- want: false,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- s := SNAC_0x01_0x14_OServiceSetPrivacyFlags{
- PrivacyFlags: tt.fields.PrivacyFlags,
- }
- assert.Equal(t, tt.want, s.IdleFlag())
- })
- }
- }
- func TestSNAC_0x01_0x14_OServiceSetPrivacyFlags_MemberFlag(t *testing.T) {
- type fields struct {
- PrivacyFlags uint32
- }
- tests := []struct {
- name string
- fields fields
- want bool
- }{
- {
- name: "flag is set",
- fields: fields{
- PrivacyFlags: OServicePrivacyFlagIdle | OServicePrivacyFlagMember,
- },
- want: true,
- },
- {
- name: "flag is not set",
- fields: fields{
- PrivacyFlags: OServicePrivacyFlagIdle,
- },
- want: false,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- s := SNAC_0x01_0x14_OServiceSetPrivacyFlags{
- PrivacyFlags: tt.fields.PrivacyFlags,
- }
- assert.Equal(t, tt.want, s.MemberFlag())
- })
- }
- }
- func TestUnmarshalChatMessageText(t *testing.T) {
- tests := []struct {
- name string
- b []byte
- want string
- wantErr string
- }{
- {
- name: "happy path",
- b: func() []byte {
- tlv := TLVRestBlock{
- TLVList: TLVList{
- NewTLVBE(ChatTLVMessageInfoText, "<p>hello world!</p>"),
- },
- }
- b := &bytes.Buffer{}
- err := MarshalBE(tlv, b)
- assert.NoError(t, err)
- return b.Bytes()
- }(),
- want: "<p>hello world!</p>",
- },
- {
- name: "missing ChatTLVMessageInfoText",
- b: func() []byte {
- tlv := TLVRestBlock{TLVList: TLVList{}}
- b := &bytes.Buffer{}
- err := MarshalBE(tlv, b)
- assert.NoError(t, err)
- return b.Bytes()
- }(),
- wantErr: "has no chat msg text TLV",
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- got, err := UnmarshalChatMessageText(tt.b)
- if tt.wantErr != "" {
- assert.ErrorContains(t, err, tt.wantErr)
- } else {
- assert.NoError(t, err)
- assert.Equal(t, tt.want, got)
- }
- })
- }
- }
- func TestTLVUserInfo_IsAway(t *testing.T) {
- tests := []struct {
- name string
- userInfo TLVUserInfo
- want bool
- }{
- {
- name: "flag is set",
- userInfo: TLVUserInfo{
- TLVBlock: TLVBlock{
- TLVList: TLVList{
- NewTLVBE(OServiceUserInfoUserFlags, OServiceUserFlagUnavailable),
- },
- },
- },
- want: true,
- },
- {
- name: "flag is not set",
- userInfo: TLVUserInfo{
- TLVBlock: TLVBlock{
- TLVList: TLVList{
- NewTLVBE(OServiceUserInfoUserFlags, OServiceUserFlagOSCARFree),
- },
- },
- },
- want: false,
- },
- {
- name: "TLV is missing",
- userInfo: TLVUserInfo{
- TLVBlock: TLVBlock{
- TLVList: TLVList{},
- },
- },
- want: false,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- assert.Equal(t, tt.want, tt.userInfo.IsAway())
- })
- }
- }
- func TestTLVUserInfo_IsInvisible(t *testing.T) {
- tests := []struct {
- name string
- userInfo TLVUserInfo
- want bool
- }{
- {
- name: "status mask has invisible bit set",
- userInfo: TLVUserInfo{
- TLVBlock: TLVBlock{
- TLVList: TLVList{
- NewTLVBE(OServiceUserInfoStatus, OServiceUserStatusInvisible),
- },
- },
- },
- want: true,
- },
- {
- name: "status mask does not have invisible bit set",
- userInfo: TLVUserInfo{
- TLVBlock: TLVBlock{
- TLVList: TLVList{
- NewTLVBE(OServiceUserInfoStatus, OServiceUserStatusAvailable),
- },
- },
- },
- want: false,
- },
- {
- name: "TLV is missing",
- userInfo: TLVUserInfo{
- TLVBlock: TLVBlock{
- TLVList: TLVList{},
- },
- },
- want: false,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- assert.Equal(t, tt.want, tt.userInfo.IsInvisible())
- })
- }
- }
- func TestCapabilityUUIDs(t *testing.T) {
- tests := []struct {
- name string
- cap uuid.UUID
- expected string
- }{
- // Original capabilities
- {"CapChat", CapChat, "748f2420-6287-11d1-8222-444553540000"},
- {"CapFileTransfer", CapFileTransfer, "09461343-4c7f-11d1-8222-444553540000"},
- // Short caps
- {"CapShortCaps", CapShortCaps, "09460000-4c7f-11d1-8222-444553540000"},
- {"CapSecureIM", CapSecureIM, "09460001-4c7f-11d1-8222-444553540000"},
- {"CapXHTMLIM", CapXHTMLIM, "09460002-4c7f-11d1-8222-444553540000"},
- {"CapRTCVideo", CapRTCVideo, "09460101-4c7f-11d1-8222-444553540000"},
- {"CapHasCamera", CapHasCamera, "09460102-4c7f-11d1-8222-444553540000"},
- {"CapHasMicrophone", CapHasMicrophone, "09460103-4c7f-11d1-8222-444553540000"},
- {"CapRTCAudio", CapRTCAudio, "09460104-4c7f-11d1-8222-444553540000"},
- {"CapHostStatusTextAware", CapHostStatusTextAware, "0946010a-4c7f-11d1-8222-444553540000"},
- {"CapRTIM", CapRTIM, "0946010b-4c7f-11d1-8222-444553540000"},
- {"CapSmartCaps", CapSmartCaps, "094601ff-4c7f-11d1-8222-444553540000"},
- {"CapVoiceChat", CapVoiceChat, "09461341-4c7f-11d1-8222-444553540000"},
- {"CapDirectPlay", CapDirectPlay, "09461342-4c7f-11d1-8222-444553540000"},
- {"CapRouteFinder", CapRouteFinder, "09461344-4c7f-11d1-8222-444553540000"},
- {"CapDirectICBM", CapDirectICBM, "09461345-4c7f-11d1-8222-444553540000"},
- {"CapAvatarService", CapAvatarService, "09461346-4c7f-11d1-8222-444553540000"},
- {"CapStocksAddins", CapStocksAddins, "09461347-4c7f-11d1-8222-444553540000"},
- {"CapFileSharing", CapFileSharing, "09461348-4c7f-11d1-8222-444553540000"},
- {"CapICQCh2Extended", CapICQCh2Extended, "09461349-4c7f-11d1-8222-444553540000"},
- {"CapGames", CapGames, "0946134a-4c7f-11d1-8222-444553540000"},
- {"CapBuddyListTransfer", CapBuddyListTransfer, "0946134b-4c7f-11d1-8222-444553540000"},
- {"CapSupportICQ", CapSupportICQ, "0946134d-4c7f-11d1-8222-444553540000"},
- {"CapUTF8Messages", CapUTF8Messages, "0946134e-4c7f-11d1-8222-444553540000"},
- // Full UUIDs
- {"CapRTFMessages", CapRTFMessages, "97b12751-243c-4334-ad22-d6abf73f1492"},
- {"CapTrillianSecureIM", CapTrillianSecureIM, "f2e7c7f4-fead-4dfb-b235-36798bdf0000"},
- {"CapXtrazScript", CapXtrazScript, "3b60b3ef-d82a-6c45-a4e0-9c5a5e67e865"},
- // Unknown/Legacy
- {"CapUnknownICQ2001_2002", CapUnknownICQ2001_2002, "a0e93f37-4c7f-11d1-8222-444553540000"},
- {"CapUnknownICQ2002", CapUnknownICQ2002, "10cf40d1-4c7f-11d1-8222-444553540000"},
- {"CapUnknownICQ2001", CapUnknownICQ2001, "2e7a6475-fadf-4dc8-886f-ea3595fdb6df"},
- {"CapUnknownICQLite", CapUnknownICQLite, "563fc809-0b6f-41bd-9f79-422609dfa2f3"},
- {"CapGamesAlt", CapGamesAlt, "0946134a-4c7f-11d1-2282-444553540000"},
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- assert.Equal(t, tt.expected, tt.cap.String())
- })
- }
- }
- func TestShortCapHexToUUID(t *testing.T) {
- tests := []struct {
- name string
- hexStr string
- wantUUID uuid.UUID
- wantOK bool
- }{
- {"1348 -> CapFileSharing", "1348", CapFileSharing, true},
- {"134B -> CapBuddyListTransfer", "134B", CapBuddyListTransfer, true},
- {"1FF -> CapSmartCaps", "1FF", CapSmartCaps, true},
- {"1341 -> CapVoiceChat", "1341", CapVoiceChat, true},
- {"0000 -> CapShortCaps", "0000", CapShortCaps, true},
- {"empty string", "", uuid.Nil, false},
- {"invalid hex", "GGGG", uuid.Nil, false},
- {"too large for uint16", "10000", uuid.Nil, false},
- {"whitespace trimmed", " 1348 ", CapFileSharing, true},
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- got, ok := ShortCapHexToUUID(tt.hexStr)
- assert.Equal(t, tt.wantOK, ok)
- if tt.wantOK {
- assert.Equal(t, tt.wantUUID, got)
- } else {
- assert.Equal(t, uuid.Nil, got)
- }
- })
- }
- }
- func TestFeedbagItem_AppendOrderMembers(t *testing.T) {
- t.Run("creates order TLV when none exists", func(t *testing.T) {
- item := FeedbagItem{ClassID: FeedbagClassIdGroup, GroupID: 1}
- item.AppendOrderMembers(10, 20)
- order, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.True(t, ok)
- assert.Equal(t, []uint16{10, 20}, order)
- })
- t.Run("appends to existing order TLV", func(t *testing.T) {
- item := FeedbagItem{
- ClassID: FeedbagClassIdGroup,
- GroupID: 1,
- TLVLBlock: TLVLBlock{
- TLVList: TLVList{
- NewTLVBE(FeedbagAttributesOrder, []uint16{5, 10}),
- },
- },
- }
- item.AppendOrderMembers(15, 20)
- order, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.True(t, ok)
- assert.Equal(t, []uint16{5, 10, 15, 20}, order)
- })
- t.Run("single member", func(t *testing.T) {
- item := FeedbagItem{ClassID: FeedbagClassIdGroup}
- item.AppendOrderMembers(42)
- order, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.True(t, ok)
- assert.Equal(t, []uint16{42}, order)
- })
- }
- func TestFeedbagItem_RemoveOrderMembers(t *testing.T) {
- t.Run("removes specified members", func(t *testing.T) {
- item := FeedbagItem{
- ClassID: FeedbagClassIdGroup,
- TLVLBlock: TLVLBlock{
- TLVList: TLVList{
- NewTLVBE(FeedbagAttributesOrder, []uint16{5, 10, 15, 20}),
- },
- },
- }
- item.RemoveOrderMembers(10, 20)
- order, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.True(t, ok)
- assert.Equal(t, []uint16{5, 15}, order)
- })
- t.Run("no-op when order TLV does not exist", func(t *testing.T) {
- item := FeedbagItem{ClassID: FeedbagClassIdGroup}
- item.RemoveOrderMembers(10)
- _, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.False(t, ok)
- })
- t.Run("removes all members", func(t *testing.T) {
- item := FeedbagItem{
- ClassID: FeedbagClassIdGroup,
- TLVLBlock: TLVLBlock{
- TLVList: TLVList{
- NewTLVBE(FeedbagAttributesOrder, []uint16{5, 10}),
- },
- },
- }
- item.RemoveOrderMembers(5, 10)
- order, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.True(t, ok)
- assert.Empty(t, order)
- })
- t.Run("ignores IDs not in order", func(t *testing.T) {
- item := FeedbagItem{
- ClassID: FeedbagClassIdGroup,
- TLVLBlock: TLVLBlock{
- TLVList: TLVList{
- NewTLVBE(FeedbagAttributesOrder, []uint16{5, 10}),
- },
- },
- }
- item.RemoveOrderMembers(99)
- order, ok := item.Uint16SliceBE(FeedbagAttributesOrder)
- assert.True(t, ok)
- assert.Equal(t, []uint16{5, 10}, order)
- })
- }
|