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 }