Files
go-proton-api/response_test.go
2023-10-17 10:37:18 +02:00

142 lines
3.2 KiB
Go

package proton_test
import (
"context"
"encoding/json"
"errors"
"net"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/stretchr/testify/require"
)
func TestNetError_DropOnWrite(t *testing.T) {
l, err := net.Listen("tcp", ":0")
require.NoError(t, err)
dropListener := proton.NewListener(l, proton.NewDropConn)
// Use a custom listener that drops all writes.
dropListener.SetCanWrite(false)
// Simulate a server that refuses to write.
s := server.New(server.WithListener(dropListener))
defer s.Close()
m := proton.New(proton.WithHostURL(s.GetHostURL()))
defer m.Close()
// This should fail with a URL error.
pingErr := m.Ping(context.Background())
if urlErr := new(url.Error); !errors.As(pingErr, &urlErr) {
t.Fatalf("expected a url.Error, got %T: %v", pingErr, pingErr)
}
}
func TestAPIError_DeserializeWithoutDetails(t *testing.T) {
errJson := `
{
"Status": 400,
"Code": 1000,
"Error": "Foo Bar"
}
`
var err proton.APIError
require.NoError(t, json.Unmarshal([]byte(errJson), &err))
require.Nil(t, err.Details)
}
func TestAPIError_DeserializeWithoutDetailsValue(t *testing.T) {
errJson := `
{
"Status": 400,
"Code": 1000,
"Error": "Foo Bar",
"Details": 20
}
`
var err proton.APIError
require.NoError(t, json.Unmarshal([]byte(errJson), &err))
require.NotNil(t, err.Details)
require.Equal(t, `20`, err.DetailsToString())
}
func TestAPIError_DeserializeWithDetailsObject(t *testing.T) {
errJson := `
{
"Status": 400,
"Code": 1000,
"Error": "Foo Bar",
"Details": {"object2":{"v":20},"foo":"bar"}
}
`
var err proton.APIError
require.NoError(t, json.Unmarshal([]byte(errJson), &err))
require.NotNil(t, err.Details)
require.Equal(t, `{"object2":{"v":20},"foo":"bar"}`, err.DetailsToString())
}
func TestAPIError_DeserializeWithDetailsArray(t *testing.T) {
errJson := `
{
"Status": 400,
"Code": 1000,
"Error": "Foo Bar",
"Details": [{"object2":{"v":20},"foo":"bar"},499,"hello"]
}
`
var err proton.APIError
require.NoError(t, json.Unmarshal([]byte(errJson), &err))
require.NotNil(t, err.Details)
require.Equal(t, `[{"object2":{"v":20},"foo":"bar"},499,"hello"]`, err.DetailsToString())
}
func TestAPIError_DeserializeWithHV(t *testing.T) {
errJson := `
{
"Status": 422,
"Code": 9001,
"Error": "Foo Bar",
"Details": {
"HumanVerificationMethods": ["captcha", "foo"],
"HumanVerificationToken": "token"
}
}
`
var err proton.APIError
require.NoError(t, json.Unmarshal([]byte(errJson), &err))
require.NotNil(t, err.Details)
require.True(t, err.IsHVError())
hv, e := err.GetHVDetails()
require.NoError(t, e)
require.Equal(t, []string{"captcha", "foo"}, hv.Methods)
require.Equal(t, "token", hv.Token)
}
func TestNetError_RouteInErrorMessage(t *testing.T) {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
}))
defer s.Close()
m := proton.New(proton.WithHostURL(s.URL))
defer m.Close()
pingErr := m.Quark(context.Background(), "test/ping")
require.Error(t, pingErr)
require.Contains(t, pingErr.Error(), "GET")
require.Contains(t, pingErr.Error(), "/test/ping")
}