|
4 | 4 | package mailratelimit |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "strings" |
7 | 8 | "testing" |
8 | 9 | "time" |
9 | 10 | ) |
@@ -35,6 +36,13 @@ func TestCanonicalize(t *testing.T) { |
35 | 36 | want: "/open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages/:message_id", |
36 | 37 | wantMatch: true, |
37 | 38 | }, |
| 39 | + { |
| 40 | + name: "relative path query and fragment canonicalize", |
| 41 | + method: "GET", |
| 42 | + path: "/open-apis/mail/v1/user_mailboxes/me/messages/msg_1?format=metadata#body", |
| 43 | + want: "/open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages/:message_id", |
| 44 | + wantMatch: true, |
| 45 | + }, |
38 | 46 | { |
39 | 47 | name: "concrete batch get canonicalizes", |
40 | 48 | method: "POST", |
@@ -77,34 +85,66 @@ func TestCanonicalize(t *testing.T) { |
77 | 85 | } |
78 | 86 |
|
79 | 87 | func TestBuiltinRulesUseConfirmedThreshold(t *testing.T) { |
80 | | - want := map[string]bool{ |
81 | | - "GET /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages/:message_id": false, |
82 | | - "POST /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages/batch_get": false, |
83 | | - "GET /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages": false, |
84 | | - "POST /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/search": false, |
| 88 | + type threshold struct { |
| 89 | + window time.Duration |
| 90 | + limit int |
85 | 91 | } |
86 | | - if len(builtinRules) != len(want) { |
87 | | - t.Fatalf("builtinRules len = %d, want %d", len(builtinRules), len(want)) |
| 92 | + want := map[string][]threshold{ |
| 93 | + "GET /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages/:message_id": { |
| 94 | + {window: time.Minute, limit: 100}, |
| 95 | + }, |
| 96 | + "POST /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages/batch_get": { |
| 97 | + {window: time.Second, limit: 10}, |
| 98 | + }, |
| 99 | + "GET /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/messages": { |
| 100 | + {window: time.Second, limit: 10}, |
| 101 | + }, |
| 102 | + "POST /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/search": { |
| 103 | + {window: time.Minute, limit: 1000}, |
| 104 | + {window: time.Second, limit: 50}, |
| 105 | + }, |
88 | 106 | } |
| 107 | + seen := make(map[string][]threshold) |
89 | 108 | for _, rule := range builtinRules { |
90 | 109 | key := rule.Method + " " + rule.CanonicalPath |
91 | 110 | if _, ok := want[key]; !ok { |
92 | 111 | t.Fatalf("unexpected builtin rule %s", key) |
93 | 112 | } |
94 | | - if rule.Window != time.Minute { |
95 | | - t.Fatalf("%s window = %s, want 1m", key, rule.Window) |
| 113 | + if rule.Window <= 0 { |
| 114 | + t.Fatalf("%s window must be positive", key) |
96 | 115 | } |
97 | | - if rule.Limit != 180 { |
98 | | - t.Fatalf("%s limit = %d, want 180", key, rule.Limit) |
| 116 | + if rule.Limit <= 0 { |
| 117 | + t.Fatalf("%s limit must be positive", key) |
99 | 118 | } |
100 | 119 | if rule.Scope != ScopeApp { |
101 | 120 | t.Fatalf("%s scope = %q, want %q", key, rule.Scope, ScopeApp) |
102 | 121 | } |
103 | | - want[key] = true |
| 122 | + if rule.Method == "" { |
| 123 | + t.Fatalf("%s method must not be empty", key) |
| 124 | + } |
| 125 | + if !strings.HasPrefix(rule.CanonicalPath, "/open-apis/mail/") { |
| 126 | + t.Fatalf("%s canonical path must be under /open-apis/mail/", key) |
| 127 | + } |
| 128 | + seen[key] = append(seen[key], threshold{window: rule.Window, limit: rule.Limit}) |
| 129 | + } |
| 130 | + if len(builtinRules) != 5 { |
| 131 | + t.Fatalf("builtinRules len = %d, want 5", len(builtinRules)) |
104 | 132 | } |
105 | | - for key, seen := range want { |
106 | | - if !seen { |
| 133 | + for key, thresholds := range want { |
| 134 | + if len(seen[key]) != len(thresholds) { |
107 | 135 | t.Fatalf("missing builtin rule %s", key) |
108 | 136 | } |
| 137 | + for _, threshold := range thresholds { |
| 138 | + found := false |
| 139 | + for _, got := range seen[key] { |
| 140 | + if got == threshold { |
| 141 | + found = true |
| 142 | + break |
| 143 | + } |
| 144 | + } |
| 145 | + if !found { |
| 146 | + t.Fatalf("%s missing threshold window=%s limit=%d; got %#v", key, threshold.window, threshold.limit, seen[key]) |
| 147 | + } |
| 148 | + } |
109 | 149 | } |
110 | 150 | } |
0 commit comments