chrly/internal/http/signer_test.go
2024-03-05 13:07:54 +01:00

147 lines
3.7 KiB
Go

package http
import (
"bytes"
"errors"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
)
type SignerMock struct {
mock.Mock
}
func (m *SignerMock) Sign(data io.Reader) ([]byte, error) {
args := m.Called(data)
var result []byte
if casted, ok := args.Get(0).([]byte); ok {
result = casted
}
return result, args.Error(1)
}
func (m *SignerMock) GetPublicKey(format string) ([]byte, error) {
args := m.Called(format)
var result []byte
if casted, ok := args.Get(0).([]byte); ok {
result = casted
}
return result, args.Error(1)
}
type SignerApiTestSuite struct {
suite.Suite
App *SignerApi
Signer *SignerMock
}
func (t *SignerApiTestSuite) SetupSubTest() {
t.Signer = &SignerMock{}
t.App = &SignerApi{
Signer: t.Signer,
}
}
func (t *SignerApiTestSuite) TearDownSubTest() {
t.Signer.AssertExpectations(t.T())
}
func (t *SignerApiTestSuite) TestSign() {
t.Run("successfully sign", func() {
signature := []byte("mock signature")
t.Signer.On("Sign", mock.Anything).Return(signature, nil).Run(func(args mock.Arguments) {
buf := &bytes.Buffer{}
_, _ = io.Copy(buf, args.Get(0).(io.Reader))
r, _ := io.ReadAll(buf)
t.Equal([]byte("mock body to sign"), r)
})
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader("mock body to sign"))
w := httptest.NewRecorder()
t.App.Handler().ServeHTTP(w, req)
result := w.Result()
t.Equal(http.StatusOK, result.StatusCode)
t.Equal("application/octet-stream+base64", result.Header.Get("Content-Type"))
body, _ := io.ReadAll(result.Body)
t.Equal([]byte{0x62, 0x57, 0x39, 0x6a, 0x61, 0x79, 0x42, 0x7a, 0x61, 0x57, 0x64, 0x75, 0x59, 0x58, 0x52, 0x31, 0x63, 0x6d, 0x55, 0x3d}, body)
})
t.Run("handle error during sign", func() {
t.Signer.On("Sign", mock.Anything).Return(nil, errors.New("mock error"))
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader("mock body to sign"))
w := httptest.NewRecorder()
t.App.Handler().ServeHTTP(w, req)
result := w.Result()
t.Equal(http.StatusInternalServerError, result.StatusCode)
})
}
func (t *SignerApiTestSuite) TestGetPublicKey() {
t.Run("in pem format", func() {
publicKey := []byte("mock public key in pem format")
t.Signer.On("GetPublicKey", "pem").Return(publicKey, nil)
req := httptest.NewRequest("GET", "http://chrly/public-key.pem", nil)
w := httptest.NewRecorder()
t.App.Handler().ServeHTTP(w, req)
result := w.Result()
t.Equal(http.StatusOK, result.StatusCode)
t.Equal("application/x-pem-file", result.Header.Get("Content-Type"))
t.Equal(`attachment; filename="yggdrasil_session_pubkey.pem"`, result.Header.Get("Content-Disposition"))
body, _ := io.ReadAll(result.Body)
t.Equal(publicKey, body)
})
t.Run("in der format", func() {
publicKey := []byte("mock public key in der format")
t.Signer.On("GetPublicKey", "der").Return(publicKey, nil)
req := httptest.NewRequest("GET", "http://chrly/public-key.der", nil)
w := httptest.NewRecorder()
t.App.Handler().ServeHTTP(w, req)
result := w.Result()
t.Equal(http.StatusOK, result.StatusCode)
t.Equal("application/octet-stream", result.Header.Get("Content-Type"))
t.Equal(`attachment; filename="yggdrasil_session_pubkey.der"`, result.Header.Get("Content-Disposition"))
body, _ := io.ReadAll(result.Body)
t.Equal(publicKey, body)
})
t.Run("handle error", func() {
t.Signer.On("GetPublicKey", "pem").Return(nil, errors.New("mock error"))
req := httptest.NewRequest("GET", "http://chrly/public-key.pem", nil)
w := httptest.NewRecorder()
t.App.Handler().ServeHTTP(w, req)
result := w.Result()
t.Equal(http.StatusInternalServerError, result.StatusCode)
})
}
func TestSignerApi(t *testing.T) {
suite.Run(t, new(SignerApiTestSuite))
}