feat: implement Milestone 3 integration points
Add comprehensive integration capabilities to Pop CLI: - Multi-account support with named profiles - Webhook management with signature verification - External PGP key management (import/export/encrypt/decrypt/sign/verify) - CLI plugin system for extensibility - Complete documentation in README.md All compilation errors fixed and build verified CLEAN. Security review delegated to FRE-5202. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -32,22 +32,25 @@ func newMockServer(t *testing.T) *mockServer {
|
||||
server: srv,
|
||||
}
|
||||
|
||||
mux.HandleFunc("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
mux.HandleFunc("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
mux.HandleFunc("POST /api/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
mux.HandleFunc("POST /mail/v4/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
mux.HandleFunc("POST /api/messages/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
mux.HandleFunc("GET /mail/v4/messages/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
mux.HandleFunc("POST /api/messages/{id}/movetotrash", func(w http.ResponseWriter, r *http.Request) {
|
||||
mux.HandleFunc("PUT /mail/v4/messages/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
mux.HandleFunc("POST /api/messages/{id}/delete", func(w http.ResponseWriter, r *http.Request) {
|
||||
mux.HandleFunc("PUT /mail/v4/messages/{id}/trash", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
mux.HandleFunc("POST /api/messages/{id}/send", func(w http.ResponseWriter, r *http.Request) {
|
||||
mux.HandleFunc("DELETE /mail/v4/messages/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
mux.HandleFunc("POST /mail/v4/messages/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
resolveHandler(ms, w, r)
|
||||
})
|
||||
|
||||
@@ -72,8 +75,8 @@ func resolveHandler(ms *mockServer, w http.ResponseWriter, r *http.Request) {
|
||||
handler.(http.HandlerFunc)(w, r)
|
||||
return
|
||||
}
|
||||
// When POST /api/messages is called, it matches both list and send/draft.
|
||||
// The generic handler for POST /api/messages catches all unmatched POST /api/messages calls.
|
||||
// When POST /mail/v4/messages is called, it matches both list and send/draft.
|
||||
// The generic handler for POST /mail/v4/messages catches all unmatched POST /mail/v4/messages calls.
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
fmt.Fprintf(w, `{"Code":404,"Message":"not found"}`)
|
||||
}
|
||||
@@ -129,7 +132,7 @@ func TestListMessages_Success(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Page"] != float64(1) {
|
||||
t.Errorf("expected page 1, got %v", body["Page"])
|
||||
@@ -167,7 +170,7 @@ func TestListMessages_WithFolderFilter(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Type"] != float64(FolderSent) {
|
||||
t.Errorf("expected Type=3 (sent), got %v", body["Type"])
|
||||
@@ -191,7 +194,7 @@ func TestListMessages_InboxOmitsType(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if _, ok := body["Type"]; ok {
|
||||
t.Error("Inbox should omit Type field")
|
||||
@@ -216,7 +219,7 @@ func TestListMessages_WithStarredFilter(t *testing.T) {
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
starred := true
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Starred"] != true {
|
||||
t.Errorf("expected Starred=true, got %v", body["Starred"])
|
||||
@@ -242,7 +245,7 @@ func TestListMessages_WithReadFilter(t *testing.T) {
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
unread := false
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Read"] != false {
|
||||
t.Errorf("expected Read=false, got %v", body["Read"])
|
||||
@@ -268,7 +271,7 @@ func TestListMessages_WithSinceFilter(t *testing.T) {
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
since := int64(1700000000)
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Since"] != float64(since) {
|
||||
t.Errorf("expected Since=%d, got %v", since, body["Since"])
|
||||
@@ -293,7 +296,7 @@ func TestListMessages_APIError(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
fmt.Fprintf(w, `{"Code":403,"Message":"invalid token"}`)
|
||||
})
|
||||
@@ -316,7 +319,7 @@ func TestListMessages_BadJSON(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprint(w, `{"bad json`)
|
||||
})
|
||||
@@ -348,12 +351,8 @@ func TestGetMessage_Success(t *testing.T) {
|
||||
Body: "Decrypted body content",
|
||||
}
|
||||
|
||||
srv.Handle("POST /api/messages/msg-42", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Passphrase"] != "pass" {
|
||||
t.Errorf("expected passphrase pass, got %v", body["Passphrase"])
|
||||
}
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{"Data": expectedMsg})
|
||||
srv.Handle("GET /mail/v4/messages/msg-42", func(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{"Message": expectedMsg})
|
||||
})
|
||||
|
||||
msg, err := client.GetMessage("msg-42", "pass")
|
||||
@@ -377,8 +376,8 @@ func TestGetMessage_URLEscape(t *testing.T) {
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
msgID := "msg/with/slashes"
|
||||
srv.Handle("POST /api/messages/msg/with/slashes", func(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{"Data": Message{MessageID: msgID}})
|
||||
srv.Handle("GET /mail/v4/messages/msg/with/slashes", func(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{"Message": Message{MessageID: msgID}})
|
||||
})
|
||||
|
||||
msg, err := client.GetMessage(msgID, "pass")
|
||||
@@ -395,7 +394,7 @@ func TestGetMessage_NotFound(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/msg-999", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("GET /mail/v4/messages/msg-999", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
fmt.Fprintf(w, `{"Code":404,"Message":"message not found"}`)
|
||||
})
|
||||
@@ -437,8 +436,8 @@ func TestGetMessage_DecryptBody(t *testing.T) {
|
||||
BodyEnc: encryptedBody,
|
||||
}
|
||||
|
||||
srv.Handle("POST /api/messages/msg-enc", func(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{"Data": msgWithEncryptedBody})
|
||||
srv.Handle("GET /mail/v4/messages/msg-enc", func(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{"Message": msgWithEncryptedBody})
|
||||
})
|
||||
|
||||
msg, err := client.GetMessage("msg-enc", pass)
|
||||
@@ -457,7 +456,7 @@ func TestSend_Success(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Subject"] != "Test Subject" {
|
||||
t.Errorf("expected subject Test Subject, got %v", body["Subject"])
|
||||
@@ -496,7 +495,7 @@ func TestSend_WithPGP(t *testing.T) {
|
||||
client := NewClient(apiClient)
|
||||
client.SetPGPService(svc)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
// When PGP service is set, BodyEnc should be present instead of Body
|
||||
if _, hasBody := body["Body"]; hasBody {
|
||||
@@ -524,7 +523,7 @@ func TestSend_WithCC(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
cc, ok := body["CC"].([]interface{})
|
||||
if !ok || len(cc) != 1 {
|
||||
@@ -549,7 +548,7 @@ func TestSend_WithBCC(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
bcc, ok := body["BCC"].([]interface{})
|
||||
if !ok || len(bcc) != 1 {
|
||||
@@ -574,7 +573,7 @@ func TestSend_HTTPError(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, `{"Code":400,"Message":"invalid recipient"}`)
|
||||
})
|
||||
@@ -598,7 +597,7 @@ func TestSend_CreatedStatus(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
fmt.Fprintf(w, `{"Data":{"MessageID":"created-1"}}`)
|
||||
})
|
||||
@@ -620,13 +619,13 @@ func TestMoveToTrash_Success(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/msg-1/movetotrash", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
|
||||
t.Error("expected form-urlencoded content type")
|
||||
srv.Handle("PUT /mail/v4/messages/msg-1/trash", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Content-Type") != "application/json" {
|
||||
t.Error("expected json content type")
|
||||
}
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
if !strings.Contains(string(body), "Passphrase=pass") {
|
||||
t.Errorf("expected Passphrase in form body, got %s", body)
|
||||
if !strings.Contains(string(body), `"Passphrase":"pass"`) {
|
||||
t.Errorf("expected Passphrase in json body, got %s", body)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
@@ -642,7 +641,7 @@ func TestMoveToTrash_Error(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/msg-1/movetotrash", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("PUT /mail/v4/messages/msg-1/trash", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, "server error")
|
||||
})
|
||||
@@ -663,7 +662,7 @@ func TestPermanentlyDelete_Success(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/msg-1/delete", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("DELETE /mail/v4/messages/msg-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
@@ -678,7 +677,7 @@ func TestPermanentlyDelete_Error(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/msg-1/delete", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("DELETE /mail/v4/messages/msg-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
fmt.Fprintf(w, `{"Code":404,"Message":"not found"}`)
|
||||
})
|
||||
@@ -699,7 +698,7 @@ func TestPermanentlyDelete_URLEscape(t *testing.T) {
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
msgID := "msg/with/slashes"
|
||||
srv.Handle("POST /api/messages/msg/with/slashes/delete", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("DELETE /mail/v4/messages/msg/with/slashes", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
@@ -716,7 +715,7 @@ func TestSaveDraft_Success(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Type"] != MessageTypeDraft {
|
||||
t.Errorf("expected Type=%s, got %v", MessageTypeDraft, body["Type"])
|
||||
@@ -725,7 +724,7 @@ func TestSaveDraft_Success(t *testing.T) {
|
||||
t.Errorf("expected subject Draft Subject, got %v", body["Subject"])
|
||||
}
|
||||
writeJSON(t, w, http.StatusOK, map[string]interface{}{
|
||||
"Data": map[string]string{"MessageID": "draft-1"},
|
||||
"Message": map[string]string{"MessageID": "draft-1"},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -747,7 +746,7 @@ func TestSaveDraft_WithCC(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if _, ok := body["CC"]; !ok {
|
||||
t.Error("expected CC field")
|
||||
@@ -777,7 +776,7 @@ func TestSaveDraft_Error(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, `{"Code":400,"Message":"invalid recipient"}`)
|
||||
})
|
||||
@@ -797,7 +796,7 @@ func TestSaveDraft_BadJSON(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprint(w, `{"bad json`)
|
||||
})
|
||||
@@ -822,10 +821,11 @@ func TestUpdateDraft_Success(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("PUT /mail/v4/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Subject"] != "Updated Subject" {
|
||||
t.Errorf("expected Updated Subject, got %v", body["Subject"])
|
||||
msg := body["Message"].(map[string]interface{})
|
||||
if msg["Subject"] != "Updated Subject" {
|
||||
t.Errorf("expected Updated Subject, got %v", msg["Subject"])
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
@@ -845,9 +845,10 @@ func TestUpdateDraft_WithCC(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("PUT /mail/v4/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if _, ok := body["CC"]; !ok {
|
||||
msg := body["Message"].(map[string]interface{})
|
||||
if _, ok := msg["CC"]; !ok {
|
||||
t.Error("expected CC field in update")
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
@@ -869,7 +870,7 @@ func TestUpdateDraft_Error(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("PUT /mail/v4/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
fmt.Fprintf(w, `{"Code":409,"Message":"draft locked"}`)
|
||||
})
|
||||
@@ -895,13 +896,13 @@ func TestSendDraft_Success(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/draft-1/send", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
|
||||
t.Error("expected form-urlencoded content type")
|
||||
srv.Handle("POST /mail/v4/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Content-Type") != "application/json" {
|
||||
t.Error("expected json content type")
|
||||
}
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
if !strings.Contains(string(body), "Passphrase=pass") {
|
||||
t.Errorf("expected Passphrase in form, got %s", body)
|
||||
if !strings.Contains(string(body), `"Passphrase":"pass"`) {
|
||||
t.Errorf("expected Passphrase in json, got %s", body)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
@@ -917,7 +918,7 @@ func TestSendDraft_Error(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/draft-1/send", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages/draft-1", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
fmt.Fprint(w, "not found")
|
||||
})
|
||||
@@ -945,7 +946,7 @@ func TestListDrafts_Success(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Type"] != float64(FolderDraft) {
|
||||
t.Errorf("expected Type=2 (draft), got %v", body["Type"])
|
||||
@@ -978,7 +979,7 @@ func TestSearchMessages_Success(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
srv.Handle("POST /api/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Query"] != "invoice" {
|
||||
t.Errorf("expected query invoice, got %v", body["Query"])
|
||||
@@ -1014,7 +1015,7 @@ func TestSearchMessages_EmptyResults(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(t, w, http.StatusOK, SearchResponse{Total: 0, Messages: []Message{}})
|
||||
})
|
||||
|
||||
@@ -1037,7 +1038,7 @@ func TestSearchMessages_APIError(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusTooManyRequests)
|
||||
fmt.Fprintf(w, `{"Code":429,"Message":"rate limited"}`)
|
||||
})
|
||||
@@ -1061,7 +1062,7 @@ func TestSearchMessages_BadJSON(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprint(w, `not json at all`)
|
||||
})
|
||||
@@ -1097,7 +1098,7 @@ func TestAuthHeader_Propagated(t *testing.T) {
|
||||
client := NewClient(apiClient)
|
||||
|
||||
var capturedAuth string
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
capturedAuth = r.Header.Get("Authorization")
|
||||
writeJSON(t, w, http.StatusOK, ListMessagesResponse{})
|
||||
})
|
||||
@@ -1120,7 +1121,7 @@ func TestContentTypes_JSON(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
ct := r.Header.Get("Content-Type")
|
||||
if ct != "application/json" {
|
||||
t.Errorf("expected application/json, got %s", ct)
|
||||
@@ -1140,10 +1141,10 @@ func TestContentTypes_FormUrlEncoded(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages/msg-1/movetotrash", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("PUT /mail/v4/messages/msg-1/trash", func(w http.ResponseWriter, r *http.Request) {
|
||||
ct := r.Header.Get("Content-Type")
|
||||
if ct != "application/x-www-form-urlencoded" {
|
||||
t.Errorf("expected application/x-www-form-urlencoded, got %s", ct)
|
||||
if ct != "application/json" {
|
||||
t.Errorf("expected application/json, got %s", ct)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
@@ -1161,7 +1162,7 @@ func TestListMessages_Concurrent(t *testing.T) {
|
||||
var mu sync.Mutex
|
||||
callCount := 0
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
mu.Lock()
|
||||
callCount++
|
||||
mu.Unlock()
|
||||
@@ -1267,7 +1268,7 @@ func TestSetPGPService(t *testing.T) {
|
||||
svc, _, _ := newTestService(t)
|
||||
client.SetPGPService(svc)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
// PGP service should cause BodyEnc instead of Body
|
||||
if _, hasBody := body["Body"]; hasBody {
|
||||
@@ -1294,7 +1295,7 @@ func TestSend_WithoutBody(t *testing.T) {
|
||||
defer srv.Close()
|
||||
client := newTestClient(t, srv)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if _, hasBody := body["Body"]; hasBody {
|
||||
t.Error("Body should be omitted when empty")
|
||||
@@ -1331,7 +1332,7 @@ func TestListMessages_Timeout(t *testing.T) {
|
||||
apiClient.SetAuthHeader("test-token")
|
||||
client := NewClient(apiClient)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
time.Sleep(2 * time.Second)
|
||||
writeJSON(t, w, http.StatusOK, ListMessagesResponse{})
|
||||
})
|
||||
@@ -1357,7 +1358,7 @@ func TestListMessages_CombinedFilters(t *testing.T) {
|
||||
unread := false
|
||||
since := int64(1700000000)
|
||||
|
||||
srv.Handle("POST /api/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
srv.Handle("POST /mail/v4/messages", func(w http.ResponseWriter, r *http.Request) {
|
||||
body := readJSON(t, r)
|
||||
if body["Type"] != float64(FolderSent) {
|
||||
t.Errorf("expected Type=3, got %v", body["Type"])
|
||||
|
||||
Reference in New Issue
Block a user