notify_email_entry_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //go:build unit
  2. package service
  3. import (
  4. "testing"
  5. "github.com/stretchr/testify/require"
  6. )
  7. // ---------- ParseNotifyEmails ----------
  8. func TestParseNotifyEmails_EmptyString(t *testing.T) {
  9. result := ParseNotifyEmails("")
  10. require.Nil(t, result)
  11. }
  12. func TestParseNotifyEmails_EmptyArray(t *testing.T) {
  13. result := ParseNotifyEmails("[]")
  14. require.Nil(t, result)
  15. }
  16. func TestParseNotifyEmails_Null(t *testing.T) {
  17. // "null" is valid JSON that unmarshals into a nil string slice.
  18. // The old-format branch then returns an empty (non-nil) slice.
  19. result := ParseNotifyEmails("null")
  20. require.Empty(t, result)
  21. }
  22. func TestParseNotifyEmails_WhitespaceOnly(t *testing.T) {
  23. result := ParseNotifyEmails(" ")
  24. require.Nil(t, result)
  25. }
  26. func TestParseNotifyEmails_OldFormat(t *testing.T) {
  27. raw := `["alice@example.com", "bob@example.com"]`
  28. result := ParseNotifyEmails(raw)
  29. require.Len(t, result, 2)
  30. require.Equal(t, "alice@example.com", result[0].Email)
  31. require.False(t, result[0].Verified, "old format emails should default to unverified")
  32. require.False(t, result[0].Disabled)
  33. require.Equal(t, "bob@example.com", result[1].Email)
  34. require.False(t, result[1].Verified)
  35. require.False(t, result[1].Disabled)
  36. }
  37. func TestParseNotifyEmails_OldFormat_SkipsEmptyEntries(t *testing.T) {
  38. raw := `["alice@example.com", "", " ", "bob@example.com"]`
  39. result := ParseNotifyEmails(raw)
  40. require.Len(t, result, 2)
  41. require.Equal(t, "alice@example.com", result[0].Email)
  42. require.Equal(t, "bob@example.com", result[1].Email)
  43. }
  44. func TestParseNotifyEmails_NewFormat(t *testing.T) {
  45. raw := `[{"email":"alice@example.com","verified":true,"disabled":false},{"email":"bob@example.com","verified":false,"disabled":true}]`
  46. result := ParseNotifyEmails(raw)
  47. require.Len(t, result, 2)
  48. require.Equal(t, "alice@example.com", result[0].Email)
  49. require.True(t, result[0].Verified)
  50. require.False(t, result[0].Disabled)
  51. require.Equal(t, "bob@example.com", result[1].Email)
  52. require.False(t, result[1].Verified)
  53. require.True(t, result[1].Disabled)
  54. }
  55. func TestParseNotifyEmails_NewFormat_SingleEntry(t *testing.T) {
  56. raw := `[{"email":"solo@example.com","verified":true,"disabled":false}]`
  57. result := ParseNotifyEmails(raw)
  58. require.Len(t, result, 1)
  59. require.Equal(t, "solo@example.com", result[0].Email)
  60. require.True(t, result[0].Verified)
  61. }
  62. func TestParseNotifyEmails_InvalidJSON(t *testing.T) {
  63. result := ParseNotifyEmails(`{not valid json`)
  64. require.Nil(t, result)
  65. }
  66. func TestParseNotifyEmails_InvalidJSONObject(t *testing.T) {
  67. // A plain JSON object (not array) should return nil.
  68. result := ParseNotifyEmails(`{"email":"a@b.com"}`)
  69. require.Nil(t, result)
  70. }
  71. func TestParseNotifyEmails_WhitespacePadding(t *testing.T) {
  72. raw := ` ["padded@example.com"] `
  73. result := ParseNotifyEmails(raw)
  74. require.Len(t, result, 1)
  75. require.Equal(t, "padded@example.com", result[0].Email)
  76. }
  77. // ---------- MarshalNotifyEmails ----------
  78. func TestMarshalNotifyEmails_EmptySlice(t *testing.T) {
  79. result := MarshalNotifyEmails([]NotifyEmailEntry{})
  80. require.Equal(t, "[]", result)
  81. }
  82. func TestMarshalNotifyEmails_NilSlice(t *testing.T) {
  83. result := MarshalNotifyEmails(nil)
  84. require.Equal(t, "[]", result)
  85. }
  86. func TestMarshalNotifyEmails_SingleEntry(t *testing.T) {
  87. entries := []NotifyEmailEntry{
  88. {Email: "test@example.com", Verified: true, Disabled: false},
  89. }
  90. result := MarshalNotifyEmails(entries)
  91. require.Contains(t, result, `"email":"test@example.com"`)
  92. require.Contains(t, result, `"verified":true`)
  93. require.Contains(t, result, `"disabled":false`)
  94. // Round-trip: parsing the marshalled result should produce the original entries.
  95. parsed := ParseNotifyEmails(result)
  96. require.Len(t, parsed, 1)
  97. require.Equal(t, entries[0], parsed[0])
  98. }
  99. func TestMarshalNotifyEmails_MultipleEntries(t *testing.T) {
  100. entries := []NotifyEmailEntry{
  101. {Email: "a@example.com", Verified: true, Disabled: false},
  102. {Email: "b@example.com", Verified: false, Disabled: true},
  103. }
  104. result := MarshalNotifyEmails(entries)
  105. // Round-trip verification.
  106. parsed := ParseNotifyEmails(result)
  107. require.Len(t, parsed, 2)
  108. require.Equal(t, entries[0], parsed[0])
  109. require.Equal(t, entries[1], parsed[1])
  110. }
  111. func TestMarshalNotifyEmails_RoundTrip_NewFormat(t *testing.T) {
  112. original := []NotifyEmailEntry{
  113. {Email: "x@example.com", Verified: true, Disabled: true},
  114. {Email: "y@example.com", Verified: false, Disabled: false},
  115. }
  116. marshalled := MarshalNotifyEmails(original)
  117. parsed := ParseNotifyEmails(marshalled)
  118. require.Equal(t, original, parsed)
  119. }
  120. // ---------- isOldStringArrayFormat (indirectly via ParseNotifyEmails) ----------
  121. func TestParseNotifyEmails_MixedOldFormatWithWhitespace(t *testing.T) {
  122. // Emails with leading/trailing whitespace in old format should be trimmed.
  123. raw := `[" alice@example.com "]`
  124. result := ParseNotifyEmails(raw)
  125. require.Len(t, result, 1)
  126. require.Equal(t, "alice@example.com", result[0].Email)
  127. }