round_tripper_test.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package transport
  2. import (
  3. "context"
  4. "io"
  5. "net/http"
  6. "strings"
  7. "testing"
  8. "github.com/stretchr/testify/suite"
  9. "github.com/imgproxy/imgproxy/v3/httpheaders"
  10. "github.com/imgproxy/imgproxy/v3/storage"
  11. )
  12. // mockStorage is a simple mock implementation of storage.Reader
  13. type mockStorage struct {
  14. getObject func(ctx context.Context, reqHeader http.Header, bucket, key, query string) (*storage.ObjectReader, error)
  15. }
  16. func (m *mockStorage) GetObject(ctx context.Context, reqHeader http.Header, bucket, key, query string) (*storage.ObjectReader, error) {
  17. if m.getObject == nil {
  18. return nil, nil
  19. }
  20. return m.getObject(ctx, reqHeader, bucket, key, query)
  21. }
  22. type RoundTripperTestSuite struct {
  23. suite.Suite
  24. }
  25. func (s *RoundTripperTestSuite) TestRoundTripperSuccess() {
  26. // Create mock storage that returns a successful response
  27. mock := &mockStorage{
  28. getObject: func(ctx context.Context, reqHeader http.Header, bucket, key, query string) (*storage.ObjectReader, error) {
  29. s.Equal("test-bucket", bucket)
  30. s.Equal("test-key", key)
  31. s.Equal("version=123", query)
  32. headers := make(http.Header)
  33. headers.Set(httpheaders.ContentType, "image/png")
  34. headers.Set(httpheaders.Etag, "test-etag")
  35. body := io.NopCloser(strings.NewReader("test data"))
  36. return storage.NewObjectOK(headers, body), nil
  37. },
  38. }
  39. rt := NewRoundTripper(mock, "?")
  40. // Create a test request
  41. req, err := http.NewRequest("GET", EscapeURL("s3://test-bucket/test-key?version=123"), nil)
  42. s.Require().NoError(err)
  43. // Execute RoundTrip
  44. resp, err := rt.RoundTrip(req)
  45. s.Require().NoError(err)
  46. s.Require().NotNil(resp)
  47. // Verify response
  48. s.Equal(http.StatusOK, resp.StatusCode)
  49. s.Equal("image/png", resp.Header.Get(httpheaders.ContentType))
  50. s.Equal("test-etag", resp.Header.Get(httpheaders.Etag))
  51. // Read and verify body
  52. defer resp.Body.Close()
  53. data, err := io.ReadAll(resp.Body)
  54. s.Require().NoError(err)
  55. s.Equal("test data", string(data))
  56. }
  57. func (s *RoundTripperTestSuite) TestRoundTripperNotFound() {
  58. // Create mock storage that returns 404
  59. mock := &mockStorage{
  60. getObject: func(ctx context.Context, reqHeader http.Header, bucket, key, query string) (*storage.ObjectReader, error) {
  61. return storage.NewObjectNotFound("object not found"), nil
  62. },
  63. }
  64. rt := NewRoundTripper(mock, "?")
  65. req, err := http.NewRequest("GET", "s3://bucket/key", nil)
  66. s.Require().NoError(err)
  67. resp, err := rt.RoundTrip(req)
  68. s.Require().NoError(err)
  69. s.Require().NotNil(resp)
  70. if resp.Body != nil {
  71. resp.Body.Close()
  72. }
  73. s.Equal(http.StatusNotFound, resp.StatusCode)
  74. }
  75. func TestRoundTripper(t *testing.T) {
  76. suite.Run(t, new(RoundTripperTestSuite))
  77. }