diff options
Diffstat (limited to 'hotline/access_test.go')
| -rw-r--r-- | hotline/access_test.go | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/hotline/access_test.go b/hotline/access_test.go index f2755f3..fa2f6f6 100644 --- a/hotline/access_test.go +++ b/hotline/access_test.go @@ -2,6 +2,9 @@ package hotline import ( "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" + "strings" "testing" ) @@ -37,3 +40,407 @@ func Test_accessBitmap_IsSet(t *testing.T) { }) } } + +func Test_accessBitmap_UnmarshalYAML(t *testing.T) { + // Test direct method call for explicit coverage + t.Run("direct method call", func(t *testing.T) { + var bits AccessBitmap + err := bits.UnmarshalYAML(func(v interface{}) error { + switch ptr := v.(type) { + case *interface{}: + *ptr = map[string]interface{}{ + "DownloadFile": true, + "UploadFile": true, + } + } + return nil + }) + require.NoError(t, err) + assert.True(t, bits.IsSet(AccessDownloadFile)) + assert.True(t, bits.IsSet(AccessUploadFile)) + }) + + // Original YAML unmarshaling tests + tests := []struct { + name string + yamlData string + expected AccessBitmap + wantErr bool + }{ + { + name: "unmarshal array format (legacy)", + yamlData: "access: [96, 112, 12, 32, 3, 128, 0, 0]", + expected: AccessBitmap{96, 112, 12, 32, 3, 128, 0, 0}, + wantErr: false, + }, + { + name: "unmarshal map format with true values", + yamlData: `access: + DownloadFile: true + UploadFile: true + DeleteFile: true`, + expected: func() AccessBitmap { + var bits AccessBitmap + bits.Set(AccessDownloadFile) + bits.Set(AccessUploadFile) + bits.Set(AccessDeleteFile) + return bits + }(), + wantErr: false, + }, + { + name: "unmarshal map format with false values", + yamlData: `access: + DownloadFile: false + UploadFile: false + DeleteFile: false`, + expected: AccessBitmap{}, + wantErr: false, + }, + { + name: "unmarshal map format with mixed values", + yamlData: `access: + DownloadFile: true + UploadFile: false + DeleteFile: true + CreateFolder: true`, + expected: func() AccessBitmap { + var bits AccessBitmap + bits.Set(AccessDownloadFile) + bits.Set(AccessDeleteFile) + bits.Set(AccessCreateFolder) + return bits + }(), + wantErr: false, + }, + { + name: "unmarshal map format with all permissions", + yamlData: `access: + DeleteFile: true + UploadFile: true + DownloadFile: true + RenameFile: true + MoveFile: true + CreateFolder: true + DeleteFolder: true + RenameFolder: true + MoveFolder: true + ReadChat: true + SendChat: true + OpenChat: true + CloseChat: true + ShowInList: true + CreateUser: true + DeleteUser: true + OpenUser: true + ModifyUser: true + ChangeOwnPass: true + NewsReadArt: true + NewsPostArt: true + DisconnectUser: true + CannotBeDisconnected: true + GetClientInfo: true + UploadAnywhere: true + AnyName: true + NoAgreement: true + SetFileComment: true + SetFolderComment: true + ViewDropBoxes: true + MakeAlias: true + Broadcast: true + NewsDeleteArt: true + NewsCreateCat: true + NewsDeleteCat: true + NewsCreateFldr: true + NewsDeleteFldr: true + SendPrivMsg: true + UploadFolder: true + DownloadFolder: true`, + expected: func() AccessBitmap { + var bits AccessBitmap + bits.Set(AccessDeleteFile) + bits.Set(AccessUploadFile) + bits.Set(AccessDownloadFile) + bits.Set(AccessRenameFile) + bits.Set(AccessMoveFile) + bits.Set(AccessCreateFolder) + bits.Set(AccessDeleteFolder) + bits.Set(AccessRenameFolder) + bits.Set(AccessMoveFolder) + bits.Set(AccessReadChat) + bits.Set(AccessSendChat) + bits.Set(AccessOpenChat) + bits.Set(AccessCloseChat) + bits.Set(AccessShowInList) + bits.Set(AccessCreateUser) + bits.Set(AccessDeleteUser) + bits.Set(AccessOpenUser) + bits.Set(AccessModifyUser) + bits.Set(AccessChangeOwnPass) + bits.Set(AccessNewsReadArt) + bits.Set(AccessNewsPostArt) + bits.Set(AccessDisconUser) + bits.Set(AccessCannotBeDiscon) + bits.Set(AccessGetClientInfo) + bits.Set(AccessUploadAnywhere) + bits.Set(AccessAnyName) + bits.Set(AccessNoAgreement) + bits.Set(AccessSetFileComment) + bits.Set(AccessSetFolderComment) + bits.Set(AccessViewDropBoxes) + bits.Set(AccessMakeAlias) + bits.Set(AccessBroadcast) + bits.Set(AccessNewsDeleteArt) + bits.Set(AccessNewsCreateCat) + bits.Set(AccessNewsDeleteCat) + bits.Set(AccessNewsCreateFldr) + bits.Set(AccessNewsDeleteFldr) + bits.Set(AccessSendPrivMsg) + bits.Set(AccessUploadFolder) + bits.Set(AccessDownloadFolder) + return bits + }(), + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var data struct { + Access AccessBitmap `yaml:"access"` + } + + err := yaml.Unmarshal([]byte(tt.yamlData), &data) + + if tt.wantErr { + require.Error(t, err) + return + } + + require.NoError(t, err) + assert.Equal(t, tt.expected, data.Access) + }) + } +} + +func Test_accessBitmap_MarshalYAML(t *testing.T) { + tests := []struct { + name string + bits AccessBitmap + expected string + }{ + { + name: "empty access bitmap", + bits: AccessBitmap{}, + expected: ` DownloadFile: false + DownloadFolder: false + UploadFile: false + UploadFolder: false + DeleteFile: false + RenameFile: false + MoveFile: false + CreateFolder: false + DeleteFolder: false + RenameFolder: false + MoveFolder: false + ReadChat: false + SendChat: false + OpenChat: false + CloseChat: false + ShowInList: false + CreateUser: false + DeleteUser: false + OpenUser: false + ModifyUser: false + ChangeOwnPass: false + NewsReadArt: false + NewsPostArt: false + DisconnectUser: false + CannotBeDisconnected: false + GetClientInfo: false + UploadAnywhere: false + AnyName: false + NoAgreement: false + SetFileComment: false + SetFolderComment: false + ViewDropBoxes: false + MakeAlias: false + Broadcast: false + NewsDeleteArt: false + NewsCreateCat: false + NewsDeleteCat: false + NewsCreateFldr: false + NewsDeleteFldr: false + SendPrivMsg: false +`, + }, + { + name: "access bitmap with some permissions", + bits: func() AccessBitmap { + var bits AccessBitmap + bits.Set(AccessDownloadFile) + bits.Set(AccessUploadFile) + bits.Set(AccessCreateFolder) + bits.Set(AccessReadChat) + return bits + }(), + expected: ` DownloadFile: true + DownloadFolder: false + UploadFile: true + UploadFolder: false + DeleteFile: false + RenameFile: false + MoveFile: false + CreateFolder: true + DeleteFolder: false + RenameFolder: false + MoveFolder: false + ReadChat: true + SendChat: false + OpenChat: false + CloseChat: false + ShowInList: false + CreateUser: false + DeleteUser: false + OpenUser: false + ModifyUser: false + ChangeOwnPass: false + NewsReadArt: false + NewsPostArt: false + DisconnectUser: false + CannotBeDisconnected: false + GetClientInfo: false + UploadAnywhere: false + AnyName: false + NoAgreement: false + SetFileComment: false + SetFolderComment: false + ViewDropBoxes: false + MakeAlias: false + Broadcast: false + NewsDeleteArt: false + NewsCreateCat: false + NewsDeleteCat: false + NewsCreateFldr: false + NewsDeleteFldr: false + SendPrivMsg: false +`, + }, + { + name: "access bitmap with all permissions", + bits: func() AccessBitmap { + var bits AccessBitmap + bits.Set(AccessDeleteFile) + bits.Set(AccessUploadFile) + bits.Set(AccessDownloadFile) + bits.Set(AccessRenameFile) + bits.Set(AccessMoveFile) + bits.Set(AccessCreateFolder) + bits.Set(AccessDeleteFolder) + bits.Set(AccessRenameFolder) + bits.Set(AccessMoveFolder) + bits.Set(AccessReadChat) + bits.Set(AccessSendChat) + bits.Set(AccessOpenChat) + bits.Set(AccessCloseChat) + bits.Set(AccessShowInList) + bits.Set(AccessCreateUser) + bits.Set(AccessDeleteUser) + bits.Set(AccessOpenUser) + bits.Set(AccessModifyUser) + bits.Set(AccessChangeOwnPass) + bits.Set(AccessNewsReadArt) + bits.Set(AccessNewsPostArt) + bits.Set(AccessDisconUser) + bits.Set(AccessCannotBeDiscon) + bits.Set(AccessGetClientInfo) + bits.Set(AccessUploadAnywhere) + bits.Set(AccessAnyName) + bits.Set(AccessNoAgreement) + bits.Set(AccessSetFileComment) + bits.Set(AccessSetFolderComment) + bits.Set(AccessViewDropBoxes) + bits.Set(AccessMakeAlias) + bits.Set(AccessBroadcast) + bits.Set(AccessNewsDeleteArt) + bits.Set(AccessNewsCreateCat) + bits.Set(AccessNewsDeleteCat) + bits.Set(AccessNewsCreateFldr) + bits.Set(AccessNewsDeleteFldr) + bits.Set(AccessSendPrivMsg) + bits.Set(AccessUploadFolder) + bits.Set(AccessDownloadFolder) + return bits + }(), + expected: ` DownloadFile: true + DownloadFolder: true + UploadFile: true + UploadFolder: true + DeleteFile: true + RenameFile: true + MoveFile: true + CreateFolder: true + DeleteFolder: true + RenameFolder: true + MoveFolder: true + ReadChat: true + SendChat: true + OpenChat: true + CloseChat: true + ShowInList: true + CreateUser: true + DeleteUser: true + OpenUser: true + ModifyUser: true + ChangeOwnPass: true + NewsReadArt: true + NewsPostArt: true + DisconnectUser: true + CannotBeDisconnected: true + GetClientInfo: true + UploadAnywhere: true + AnyName: true + NoAgreement: true + SetFileComment: true + SetFolderComment: true + ViewDropBoxes: true + MakeAlias: true + Broadcast: true + NewsDeleteArt: true + NewsCreateCat: true + NewsDeleteCat: true + NewsCreateFldr: true + NewsDeleteFldr: true + SendPrivMsg: true +`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Test via YAML marshaling + yamlData, err := yaml.Marshal(struct { + Access AccessBitmap `yaml:"access"` + }{Access: tt.bits}) + + require.NoError(t, err) + + // Extract just the access portion + lines := strings.Split(string(yamlData), "\n") + var accessLines []string + inAccess := false + for _, line := range lines { + if strings.HasPrefix(line, "access:") { + inAccess = true + continue + } + if inAccess && strings.HasPrefix(line, " ") { + accessLines = append(accessLines, line) + } + } + + actualAccess := strings.Join(accessLines, "\n") + "\n" + assert.Equal(t, tt.expected, actualAccess) + }) + } +} |