package documentService import ( "bytes" "encoding/json" "errors" "github.com/gojuno/minimock/v3" "github.com/google/uuid" "github.com/spf13/viper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "houston/common/util" "houston/logger" "houston/mocks" "houston/model" "io" "net/http" "testing" "time" ) type DocumentServiceClientSuite struct { suite.Suite baseURL string customerId string serviceToken string downloadPreSignedURLGeneratorPath string uploadPreSignedURLGeneratorPath string defaultTimeout time.Duration } func (suite *DocumentServiceClientSuite) SetupSuite() { logger.InitLogger() viper.Set("DOCUMENT_SERVICE_BASEURL", "https://qa-document-service.np.navi-sa.in") viper.Set("DOCUMENT_SERVICE_CUSTOMER_ID", uuid.NewString()) viper.Set("DOCUMENT_SERVICE_TOKEN", "TOKEN") viper.Set("DOCUMENT_SERVICE_DOWNLOAD_PRE_SIGNED_URL_GENERATOR_PATH", "/document-service/s3/presigned-url") viper.Set("DOCUMENT_SERVICE_UPLOAD_PRE_SIGNED_URL_GENERATOR_PATH", "/document-service/s3/generate-presigned-url") viper.Set("DEFAULT_DOCUMENT_SERVICE_TIMEOUT", 10*time.Second) suite.baseURL = viper.GetString("DOCUMENT_SERVICE_BASEURL") suite.customerId = viper.GetString("DOCUMENT_SERVICE_CUSTOMER_ID") suite.serviceToken = viper.GetString("DOCUMENT_SERVICE_TOKEN") suite.downloadPreSignedURLGeneratorPath = viper.GetString("DOCUMENT_SERVICE_DOWNLOAD_PRE_SIGNED_URL_GENERATOR_PATH") suite.uploadPreSignedURLGeneratorPath = viper.GetString("DOCUMENT_SERVICE_UPLOAD_PRE_SIGNED_URL_GENERATOR_PATH") suite.defaultTimeout = viper.GetDuration("DEFAULT_DOCUMENT_SERVICE_TIMEOUT") } func TestDocumentService(t *testing.T) { suite.Run(t, new(DocumentServiceClientSuite)) } func (suite *DocumentServiceClientSuite) Test_GenerateFileUploadPreSignedURL_FailureCase() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } documentDownloadURL := suite.baseURL + suite.uploadPreSignedURLGeneratorPath fileUploadURLRequestPayload := model.FileUploadURLRequest{ CustomerId: suite.customerId, FileType: "fileType", FlowId: "flowId", } payload, err := json.Marshal(fileUploadURLRequestPayload) restActions.PostWithTimeoutMock.When(documentDownloadURL, *bytes.NewBuffer(payload), headers, suite.defaultTimeout, nil). Then(nil, errors.New("error while generating pre-signed url")) documentServiceImpl := NewActionsImpl(restActions) _, err = documentServiceImpl.GenerateFileUploadPreSignedURL("fileType", "flowId") suite.Equal("error while generating pre-signed url", err.Error()) } func (suite *DocumentServiceClientSuite) Test_GenerateFileUploadPreSignedURL_NilBodyCase() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } documentDownloadURL := suite.baseURL + suite.uploadPreSignedURLGeneratorPath fileUploadURLRequestPayload := model.FileUploadURLRequest{ CustomerId: suite.customerId, FileType: "fileType", FlowId: "flowId", } payload, err := json.Marshal(fileUploadURLRequestPayload) restActions.PostWithTimeoutMock.When(documentDownloadURL, *bytes.NewBuffer(payload), headers, suite.defaultTimeout, nil). Then(&http.Response{StatusCode: http.StatusOK, Body: nil}, nil) documentServiceImpl := NewActionsImpl(restActions) fileUploadResponse, err := documentServiceImpl.GenerateFileUploadPreSignedURL("fileType", "flowId") assert.Nil(suite.T(), fileUploadResponse) assert.Equal(suite.T(), err.Error(), "response body is nil") } func (suite *DocumentServiceClientSuite) Test_GenerateFileUploadPreSignedURL_ResponseBodyUnmarshalErrorCase() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } documentDownloadURL := suite.baseURL + suite.uploadPreSignedURLGeneratorPath fileUploadURLRequestPayload := model.FileUploadURLRequest{ CustomerId: suite.customerId, FileType: "fileType", FlowId: "flowId", } payload, err := json.Marshal(fileUploadURLRequestPayload) responseBody, _ := json.Marshal(fileUploadURLRequestPayload) restActions.PostWithTimeoutMock.When(documentDownloadURL, *bytes.NewBuffer(payload), headers, suite.defaultTimeout, nil).Then(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(string(responseBody))), }, nil) documentServiceImpl := NewActionsImpl(restActions) fileUploadResponse, err := documentServiceImpl.GenerateFileUploadPreSignedURL("fileType", "flowId") assert.Nil(suite.T(), fileUploadResponse) assert.Equal(suite.T(), err.Error(), "file upload URL is empty") } func (suite *DocumentServiceClientSuite) Test_GenerateFileUploadPreSignedURL_SuccessCase() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } documentDownloadURL := suite.baseURL + suite.uploadPreSignedURLGeneratorPath fileUploadURLRequestPayload := model.FileUploadURLRequest{ CustomerId: suite.customerId, FileType: "fileType", FlowId: "flowId", } payload, err := json.Marshal(fileUploadURLRequestPayload) response := &model.FileUploadURLGeneratorResponse{ Url: "https://s3.ap-south-1.amazonaws.com/navi-qa-document-service-android-file-upload", FormData: model.FormData{ Bucket: "bucket", Policy: "policy", XAmzDate: "date", XAmzAlgorithm: "algorithm", XAmzSignature: "signature", XAmzCredential: "credential", Key: "key", XAmzSecurityToken: "token", }, } responseBody, _ := json.Marshal(response) restActions.PostWithTimeoutMock.When(documentDownloadURL, *bytes.NewBuffer(payload), headers, suite. defaultTimeout, nil).Then(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(string(responseBody))), }, nil) documentServiceImpl := NewActionsImpl(restActions) fileUploadResponse, err := documentServiceImpl.GenerateFileUploadPreSignedURL("fileType", "flowId") assert.Nil(suite.T(), err) assert.Equal(suite.T(), fileUploadResponse, response) } func (suite *DocumentServiceClientSuite) Test_GenerateFileDownloadPreSignedURL_FailureCase() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) fileDownloadPreSignedURLRequest := model.FileDownloadPreSignedURLRequest{ FlowId: "flowId", IdentifierKey: "identifierKey", } headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } params := map[string]string{ "customerId": suite.customerId, "flowId": fileDownloadPreSignedURLRequest.FlowId, "identifierKey": fileDownloadPreSignedURLRequest.IdentifierKey, } documentDownloadURL := suite.baseURL + suite.downloadPreSignedURLGeneratorPath restActions.GetWithTimeoutMock.When(documentDownloadURL, params, headers, suite.defaultTimeout, false). Then(nil, errors.New("error while generating pre-signed url")) documentServiceImpl := NewActionsImpl(restActions) resp, err := documentServiceImpl.GenerateFileDownloadPreSignedURL(fileDownloadPreSignedURLRequest) suite.Equal("error while generating pre-signed url", err.Error()) suite.Equal(resp, "") } func (suite *DocumentServiceClientSuite) Test_GenerateFileDownloadPreSignedURL_EmptyURLCase() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) fileDownloadPreSignedURLRequest := model.FileDownloadPreSignedURLRequest{ FlowId: "flowId", IdentifierKey: "identifierKey", } headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } params := map[string]string{ "customerId": suite.customerId, "flowId": fileDownloadPreSignedURLRequest.FlowId, "identifierKey": fileDownloadPreSignedURLRequest.IdentifierKey, } var response model.FileDownloadURLResponse response.Data.Url = "" response.Errors = nil response.StatusCode = 200 responseBody, _ := json.Marshal(response) finalResponse := http.Response{ StatusCode: 200, Body: io.NopCloser(bytes.NewBufferString(string(responseBody))), } documentDownloadURL := suite.baseURL + suite.downloadPreSignedURLGeneratorPath restActions.GetWithTimeoutMock.When(documentDownloadURL, params, headers, suite.defaultTimeout, false). Then(&finalResponse, nil) documentServiceImpl := NewActionsImpl(restActions) resp, err := documentServiceImpl.GenerateFileDownloadPreSignedURL(fileDownloadPreSignedURLRequest) suite.Equal("file download URL generation failed", err.Error()) suite.Equal(resp, "") } func (suite *DocumentServiceClientSuite) Test_GenerateFileDownloadPreSignedURL_Non200Case() { controller := minimock.NewController(suite.T()) suite.T().Cleanup(controller.Finish) restActions := mocks.NewHttpRestClientMock(controller) fileDownloadPreSignedURLRequest := model.FileDownloadPreSignedURLRequest{ FlowId: "flowId", IdentifierKey: "identifierKey", } headers := map[string]string{ "Authorization": "Basic " + suite.serviceToken, "X-Service": "houston", "X-Source": "HOUSTON", "Content-Type": util.ContentTypeJSON, } params := map[string]string{ "customerId": suite.customerId, "flowId": fileDownloadPreSignedURLRequest.FlowId, "identifierKey": fileDownloadPreSignedURLRequest.IdentifierKey, } var response model.FileDownloadURLResponse response.Data.Url = "" response.Errors = nil response.StatusCode = 500 responseBody, _ := json.Marshal(response) finalResponse := http.Response{ StatusCode: 500, Body: io.NopCloser(bytes.NewBufferString(string(responseBody))), } documentDownloadURL := suite.baseURL + suite.downloadPreSignedURLGeneratorPath restActions.GetWithTimeoutMock.When(documentDownloadURL, params, headers, suite.defaultTimeout, false). Then(&finalResponse, nil) documentServiceImpl := NewActionsImpl(restActions) resp, err := documentServiceImpl.GenerateFileDownloadPreSignedURL(fileDownloadPreSignedURLRequest) suite.Equal("file download URL generation failed", err.Error()) suite.Equal(resp, "") }