github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/client/request_mock.go (about)

     1  package client
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/johnnyeven/libtools/courier"
    11  	"github.com/johnnyeven/libtools/courier/httpx"
    12  	"github.com/johnnyeven/libtools/courier/status_error"
    13  )
    14  
    15  func MetadataWithMocker(mocker *Mocker) courier.Metadata {
    16  	m := courier.Metadata{}
    17  	m.Set(httpx.HeaderRequestID, mocker.RequestID())
    18  	return m
    19  }
    20  
    21  type MockRequest struct {
    22  	MockData
    23  	courier.Result
    24  }
    25  
    26  func (mock *MockRequest) Do() courier.Result {
    27  	r := courier.Result{}
    28  	r.Unmarshal = json.Unmarshal
    29  	r.Data = mock.MockData.Data
    30  	r.Meta = mock.MockData.Meta
    31  	if mock.MockData.Error != nil {
    32  		statusErr := &status_error.StatusError{}
    33  		err := json.Unmarshal(mock.MockData.Error, &statusErr)
    34  		if err == nil {
    35  			r.Err = statusErr
    36  		}
    37  	}
    38  	return r
    39  }
    40  
    41  func ParseMockID(service string, requestID string) (mock *Mocker, err error) {
    42  	requestIDs := strings.Split(requestID, ";")
    43  	mock = Mock(service)
    44  	for _, requestID := range requestIDs {
    45  		prefix := service + ":"
    46  		if strings.HasPrefix(requestID, prefix) {
    47  			mock, err = mock.From(strings.Replace(requestID, prefix, "", 1))
    48  			return
    49  		}
    50  	}
    51  	return nil, fmt.Errorf("no mock")
    52  }
    53  
    54  func Mock(service string) *Mocker {
    55  	return &Mocker{
    56  		Service: service,
    57  		Mocks:   map[string]MockData{},
    58  	}
    59  }
    60  
    61  type MockData struct {
    62  	Data  []byte           `json:"data,omitempty"`
    63  	Error []byte           `json:"error,omitempty"`
    64  	Meta  courier.Metadata `json:"metadata,omitempty"`
    65  }
    66  
    67  type Mocker struct {
    68  	Service string
    69  	Mocks   map[string]MockData
    70  }
    71  
    72  func (mocker Mocker) From(mock string) (*Mocker, error) {
    73  	pair := strings.Split(mock, ":")
    74  	if len(pair) != 2 {
    75  		return nil, fmt.Errorf("invalid request id")
    76  	}
    77  	data, err := base64.StdEncoding.DecodeString(pair[1])
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	m := MockData{}
    82  	errForUnmarshal := json.Unmarshal(data, &m)
    83  	if errForUnmarshal != nil {
    84  		return nil, errForUnmarshal
    85  	}
    86  	return mocker.For(pair[0], m), nil
    87  }
    88  
    89  func (mocker Mocker) For(methodID string, m MockData) *Mocker {
    90  	mocker.Mocks[methodID] = m
    91  	return &mocker
    92  }
    93  
    94  func (mocker *Mocker) RequestID() string {
    95  	buf := new(bytes.Buffer)
    96  	for id, m := range mocker.Mocks {
    97  		data, _ := json.Marshal(m)
    98  		buf.WriteString(fmt.Sprintf("%s:%s:%s;", mocker.Service, id, base64.StdEncoding.EncodeToString(data)))
    99  	}
   100  	return buf.String()
   101  }