github.com/companieshouse/insolvency-api@v0.0.0-20231024103413-440c973d9e9b/service/attachment_test.go (about)

     1  package service
     2  
     3  import (
     4  	"fmt"
     5  	"mime/multipart"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"net/textproto"
     9  	"testing"
    10  
    11  	"github.com/companieshouse/insolvency-api/constants"
    12  	"github.com/companieshouse/insolvency-api/mocks"
    13  	"github.com/companieshouse/insolvency-api/models"
    14  	"github.com/golang/mock/gomock"
    15  	"github.com/jarcoal/httpmock"
    16  	. "github.com/smartystreets/goconvey/convey"
    17  )
    18  
    19  func TestUnitValidateAttachmentDetails(t *testing.T) {
    20  
    21  	Convey("Invalid attachment details - invalid attachment type", t, func() {
    22  		mockCtrl := gomock.NewController(t)
    23  		defer mockCtrl.Finish()
    24  
    25  		mockService := mocks.NewMockService(mockCtrl)
    26  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(make([]models.AttachmentResourceDao, 0), nil)
    27  
    28  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "invalid", createHeader())
    29  		So(validationErrs, ShouldEqual, "attachment_type is invalid")
    30  		So(err, ShouldBeNil)
    31  	})
    32  
    33  	Convey("Error when validating attachment details - error retrieving attachments", t, func() {
    34  		mockCtrl := gomock.NewController(t)
    35  		defer mockCtrl.Finish()
    36  
    37  		mockService := mocks.NewMockService(mockCtrl)
    38  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(nil, fmt.Errorf("error getting attachments for transaction ID [%s]", transactionID))
    39  
    40  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "resolution", createHeader())
    41  		So(validationErrs, ShouldBeEmpty)
    42  		So(err.Error(), ShouldContainSubstring, "error getting attachments for transaction ID")
    43  	})
    44  
    45  	Convey("Invalid attachment details - attempt to file attachment with type that has already been filed", t, func() {
    46  		mockCtrl := gomock.NewController(t)
    47  		defer mockCtrl.Finish()
    48  
    49  		mockService := mocks.NewMockService(mockCtrl)
    50  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(generateAttachment(), nil)
    51  
    52  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "resolution", createHeader())
    53  		So(validationErrs, ShouldEqual, fmt.Sprintf("attachment of type [%s] has already been filed for insolvency case with transaction ID [%s]", "resolution", transactionID))
    54  		So(err, ShouldBeNil)
    55  	})
    56  
    57  	Convey("Invalid attachment details - statement of affairs liquidator filed for case", t, func() {
    58  		mockCtrl := gomock.NewController(t)
    59  		defer mockCtrl.Finish()
    60  
    61  		attachmentResources := generateAttachment()
    62  		attachmentResources[0].Type = constants.StatementOfAffairsLiquidator.String()
    63  
    64  		mockService := mocks.NewMockService(mockCtrl)
    65  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(attachmentResources, nil)
    66  
    67  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "resolution", createHeader())
    68  		So(validationErrs, ShouldEqual, fmt.Sprintf("attachment of type [%s] has been filed for insolvency case with transaction ID [%s] - no other attachments can be filed for this case", constants.StatementOfAffairsLiquidator.String(), transactionID))
    69  		So(err, ShouldBeNil)
    70  	})
    71  
    72  	Convey("Invalid attachment details - attempt to file statement of affairs liquidator for case that already has attachments", t, func() {
    73  		mockCtrl := gomock.NewController(t)
    74  		defer mockCtrl.Finish()
    75  
    76  		attachmentResources := generateAttachment()
    77  		attachmentResources[0].Type = constants.Resolution.String()
    78  
    79  		mockService := mocks.NewMockService(mockCtrl)
    80  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(attachmentResources, nil)
    81  
    82  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, constants.StatementOfAffairsLiquidator.String(), createHeader())
    83  		So(validationErrs, ShouldEqual, fmt.Sprintf("attachment of type [%s] cannot be filed for insolvency case with transaction ID [%s] - other attachments have already been filed for this case", constants.StatementOfAffairsLiquidator.String(), transactionID))
    84  		So(err, ShouldBeNil)
    85  	})
    86  
    87  	Convey("Invalid attachment details - invalid file format in header and name", t, func() {
    88  		mockCtrl := gomock.NewController(t)
    89  		defer mockCtrl.Finish()
    90  
    91  		mockService := mocks.NewMockService(mockCtrl)
    92  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(make([]models.AttachmentResourceDao, 0), nil)
    93  
    94  		header := createHeader()
    95  		header.Header.Set("Content-Type", "invalid")
    96  		header.Filename = "test.txt"
    97  
    98  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "resolution", header)
    99  		So(validationErrs, ShouldEqual, "attachment file format should be pdf")
   100  		So(err, ShouldBeNil)
   101  	})
   102  
   103  	Convey("Invalid attachment details - invalid file format in header and name", t, func() {
   104  		mockCtrl := gomock.NewController(t)
   105  		defer mockCtrl.Finish()
   106  
   107  		mockService := mocks.NewMockService(mockCtrl)
   108  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(make([]models.AttachmentResourceDao, 0), nil)
   109  
   110  		header := createHeader()
   111  		header.Size = 10000000000
   112  
   113  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "resolution", header)
   114  		So(validationErrs, ShouldEqual, "attachment file size is too large to be processed")
   115  		So(err, ShouldBeNil)
   116  	})
   117  
   118  	Convey("Valid attachment details - with existing attachments filed", t, func() {
   119  		mockCtrl := gomock.NewController(t)
   120  		defer mockCtrl.Finish()
   121  
   122  		attachmentResources := generateAttachment()
   123  		attachmentResources[0].Type = constants.Resolution.String()
   124  
   125  		mockService := mocks.NewMockService(mockCtrl)
   126  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(attachmentResources, nil)
   127  
   128  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, constants.StatementOfAffairsDirector.String(), createHeader())
   129  		So(validationErrs, ShouldBeEmpty)
   130  		So(err, ShouldBeNil)
   131  	})
   132  
   133  	Convey("Valid attachment details - without existing attachments filed", t, func() {
   134  		mockCtrl := gomock.NewController(t)
   135  		defer mockCtrl.Finish()
   136  
   137  		mockService := mocks.NewMockService(mockCtrl)
   138  		mockService.EXPECT().GetAttachmentResources(transactionID).Return(make([]models.AttachmentResourceDao, 0), nil)
   139  
   140  		validationErrs, err := ValidateAttachmentDetails(mockService, transactionID, "resolution", createHeader())
   141  		So(validationErrs, ShouldBeEmpty)
   142  		So(err, ShouldBeNil)
   143  	})
   144  }
   145  
   146  func createHeader() *multipart.FileHeader {
   147  	return &multipart.FileHeader{
   148  		Filename: "test.pdf",
   149  		Header: textproto.MIMEHeader{
   150  			"Content-Type": []string{
   151  				"application/pdf",
   152  			},
   153  		},
   154  		Size: 1,
   155  	}
   156  }
   157  
   158  func generateAttachment() []models.AttachmentResourceDao {
   159  	return []models.AttachmentResourceDao{
   160  		{
   161  			ID:     "1111",
   162  			Type:   "resolution",
   163  			Status: "submitted",
   164  			Links: models.AttachmentResourceLinksDao{
   165  				Self:     "/transaction/" + transactionID + "/insolvency/attachments/1111",
   166  				Download: "/transaction/" + transactionID + "/insolvency/attachments/1111/download",
   167  			},
   168  		},
   169  	}
   170  }
   171  
   172  func TestUnitDownloadAttachment(t *testing.T) {
   173  	attachmentID := "123"
   174  
   175  	Convey("Download attachment - no response", t, func() {
   176  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   177  		w := httptest.NewRecorder()
   178  		responseType, err := DownloadAttachment(attachmentID, req, w)
   179  		So(responseType, ShouldEqual, Error)
   180  		So(err.Error(), ShouldEqual, "error communicating with the File Transfer API: [error downloading file, no response]")
   181  	})
   182  
   183  	Convey("Download attachment - success", t, func() {
   184  		httpmock.Activate()
   185  		defer httpmock.DeactivateAndReset()
   186  		httpmock.RegisterResponder(http.MethodGet, `=~.*`, httpmock.NewStringResponder(http.StatusOK, `{"id": "12345"}`))
   187  
   188  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   189  		w := httptest.NewRecorder()
   190  
   191  		responseType, err := DownloadAttachment(attachmentID, req, w)
   192  		So(responseType, ShouldEqual, Success)
   193  		So(err, ShouldBeNil)
   194  	})
   195  }