s3api_object_handlers_test.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package s3api
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
  6. "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
  7. "github.com/stretchr/testify/assert"
  8. )
  9. // mockAccountManager implements AccountManager for testing
  10. type mockAccountManager struct {
  11. accounts map[string]string
  12. }
  13. func (m *mockAccountManager) GetAccountNameById(id string) string {
  14. if name, exists := m.accounts[id]; exists {
  15. return name
  16. }
  17. return ""
  18. }
  19. func (m *mockAccountManager) GetAccountIdByEmail(email string) string {
  20. return ""
  21. }
  22. func TestNewListEntryOwnerDisplayName(t *testing.T) {
  23. // Create mock IAM with test accounts
  24. iam := &mockAccountManager{
  25. accounts: map[string]string{
  26. "testid": "M. Tester",
  27. "userid123": "John Doe",
  28. },
  29. }
  30. // Create test entry with owner metadata
  31. entry := &filer_pb.Entry{
  32. Name: "test-object",
  33. Attributes: &filer_pb.FuseAttributes{
  34. Mtime: time.Now().Unix(),
  35. FileSize: 1024,
  36. },
  37. Extended: map[string][]byte{
  38. s3_constants.ExtAmzOwnerKey: []byte("testid"),
  39. },
  40. }
  41. // Test that display name is correctly looked up from IAM
  42. listEntry := newListEntry(entry, "", "dir", "test-object", "/buckets/test/", true, false, false, iam)
  43. assert.NotNil(t, listEntry.Owner, "Owner should be set when fetchOwner is true")
  44. assert.Equal(t, "testid", listEntry.Owner.ID, "Owner ID should match stored owner")
  45. assert.Equal(t, "M. Tester", listEntry.Owner.DisplayName, "Display name should be looked up from IAM")
  46. // Test with owner that doesn't exist in IAM (should fallback to ID)
  47. entry.Extended[s3_constants.ExtAmzOwnerKey] = []byte("unknown-user")
  48. listEntry = newListEntry(entry, "", "dir", "test-object", "/buckets/test/", true, false, false, iam)
  49. assert.Equal(t, "unknown-user", listEntry.Owner.ID, "Owner ID should match stored owner")
  50. assert.Equal(t, "unknown-user", listEntry.Owner.DisplayName, "Display name should fallback to ID when not found in IAM")
  51. // Test with no owner metadata (should use anonymous)
  52. entry.Extended = make(map[string][]byte)
  53. listEntry = newListEntry(entry, "", "dir", "test-object", "/buckets/test/", true, false, false, iam)
  54. assert.Equal(t, s3_constants.AccountAnonymousId, listEntry.Owner.ID, "Should use anonymous ID when no owner metadata")
  55. assert.Equal(t, "anonymous", listEntry.Owner.DisplayName, "Should use anonymous display name when no owner metadata")
  56. // Test with fetchOwner false (should not set owner)
  57. listEntry = newListEntry(entry, "", "dir", "test-object", "/buckets/test/", false, false, false, iam)
  58. assert.Nil(t, listEntry.Owner, "Owner should not be set when fetchOwner is false")
  59. }
  60. func TestRemoveDuplicateSlashes(t *testing.T) {
  61. tests := []struct {
  62. name string
  63. path string
  64. expectedResult string
  65. }{
  66. {
  67. name: "empty",
  68. path: "",
  69. expectedResult: "",
  70. },
  71. {
  72. name: "slash",
  73. path: "/",
  74. expectedResult: "/",
  75. },
  76. {
  77. name: "object",
  78. path: "object",
  79. expectedResult: "object",
  80. },
  81. {
  82. name: "correct path",
  83. path: "/path/to/object",
  84. expectedResult: "/path/to/object",
  85. },
  86. {
  87. name: "path with duplicates",
  88. path: "///path//to/object//",
  89. expectedResult: "/path/to/object/",
  90. },
  91. }
  92. for _, tst := range tests {
  93. t.Run(tst.name, func(t *testing.T) {
  94. obj := removeDuplicateSlashes(tst.path)
  95. assert.Equal(t, tst.expectedResult, obj)
  96. })
  97. }
  98. }
  99. func TestS3ApiServer_toFilerUrl(t *testing.T) {
  100. tests := []struct {
  101. name string
  102. args string
  103. want string
  104. }{
  105. {
  106. "simple",
  107. "/uploads/eaf10b3b-3b3a-4dcd-92a7-edf2a512276e/67b8b9bf-7cca-4cb6-9b34-22fcb4d6e27d/Bildschirmfoto 2022-09-19 um 21.38.37.png",
  108. "/uploads/eaf10b3b-3b3a-4dcd-92a7-edf2a512276e/67b8b9bf-7cca-4cb6-9b34-22fcb4d6e27d/Bildschirmfoto%202022-09-19%20um%2021.38.37.png",
  109. },
  110. {
  111. "double prefix",
  112. "//uploads/t.png",
  113. "/uploads/t.png",
  114. },
  115. {
  116. "triple prefix",
  117. "///uploads/t.png",
  118. "/uploads/t.png",
  119. },
  120. {
  121. "empty prefix",
  122. "uploads/t.png",
  123. "/uploads/t.png",
  124. },
  125. }
  126. for _, tt := range tests {
  127. t.Run(tt.name, func(t *testing.T) {
  128. assert.Equalf(t, tt.want, urlEscapeObject(tt.args), "clean %v", tt.args)
  129. })
  130. }
  131. }