Skip to content

Commit

Permalink
PFS-130 upload moto card payments report (#16)
Browse files Browse the repository at this point in the history
* PFS-143 Create back-end structure similar to finance-hub

* PFS-143 Create back-end structure similar to finance-hub

* PFS-143 Add test upload file code

* PFS-143 Update makefile and build yml

* PFS-143 Fix linting

* PFS-143 Add localstack for local bucket

* PFS-143 Upload file from form

* PFS-143 Fix linting

* PFS-143 Add SSE to upload

* PFS-143 Add success message, remove test upload type

* PFS-143 Migrate to aws-sdk-go-v2

* PFS-143 Attempt to fix blank endpoint

* PFS-143 Attempt to fix blank endpoint

* PFS-143 Undo previous change

* PFS-143 Move uploads to subfolder in bucket

* PFS-143 Move CSV header validation to back-end

* PFS-143 Add cypress test & api unit tests

* PFS-143 Create ADR

* PFS-143 Fix build

* PFS-143 Code cleanup, move upload type enum to shared

* PFS-143 Change case of upload type enum, undo SSE env var

* PFS-143 Fix cypress test

* PFS-143 Fix cypress test

* PFS-130 Change directory for testing

* PFS-130 Add s3 directory to enum

* PFS-130 Add MOTO card upload type headers

* PFS-130 Add MOTO card filename validation

* PFS-130 Remove validation for other reports

* PFS-130 Update SSE algorithm to use KMS

* PFS-130 Add error catching to upload type filename & add tests
  • Loading branch information
josephsmith0705 authored Oct 21, 2024
1 parent 221b402 commit b70c86d
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 5 deletions.
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ services:
AWS_S3_ENDPOINT: http://localstack:4566
AWS_ACCESS_KEY_ID: localstack
AWS_SECRET_ACCESS_KEY: localstack
S3_ENCRYPTION_KEY: alias/aws/s3
healthcheck:
test: wget -O /dev/null -S 'http://localhost:8080/health-check' 2>&1 | grep 'HTTP/1.1 200 OK' || exit 1
interval: 15s
Expand Down
5 changes: 3 additions & 2 deletions finance-admin-api/api/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ func (s *Server) upload(w http.ResponseWriter, r *http.Request) error {

_, err = s.awsClient.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String(os.Getenv("ASYNC_S3_BUCKET")),
Key: aws.String(fmt.Sprintf("%s/%s", "finance-admin", upload.Filename)),
Key: aws.String(fmt.Sprintf("%s/%s", upload.ReportUploadType.S3Directory(), upload.Filename)),
Body: bytes.NewReader(upload.File),
ServerSideEncryption: "AES256",
ServerSideEncryption: "aws:kms",
SSEKMSKeyId: aws.String(os.Getenv("S3_ENCRYPTION_KEY")),
})

if err != nil {
Expand Down
15 changes: 13 additions & 2 deletions finance-admin/internal/server/post_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/opg-sirius-finance-admin/finance-admin/internal/model"
"github.com/opg-sirius-finance-admin/shared"
"net/http"
"strings"
)

type UploadFormHandler struct {
Expand All @@ -16,7 +17,7 @@ type UploadFormHandler struct {
func (h *UploadFormHandler) render(v AppVars, w http.ResponseWriter, r *http.Request) error {
ctx := getContext(r)

reportUploadType := r.PostFormValue("reportUploadType")
reportUploadType := shared.ParseReportUploadType(r.PostFormValue("reportUploadType"))
uploadDate := r.PostFormValue("uploadDate")
email := r.PostFormValue("email")

Expand All @@ -27,7 +28,17 @@ func (h *UploadFormHandler) render(v AppVars, w http.ResponseWriter, r *http.Req
}
defer file.Close()

data, err := shared.NewUpload(shared.ParseReportUploadType(reportUploadType), uploadDate, email, file, handler.Filename)
expectedFilename, err := reportUploadType.Filename(uploadDate)
if err != nil {
return h.handleError(w, r, "Could not parse upload date", http.StatusBadRequest)
}

if handler.Filename != expectedFilename && expectedFilename != "" {
expectedFilename := strings.Replace(expectedFilename, ":", "/", -1)
return h.handleError(w, r, fmt.Sprintf("Filename should be named \"%s\"", expectedFilename), http.StatusBadRequest)
}

data, err := shared.NewUpload(reportUploadType, uploadDate, email, file, handler.Filename)
if err != nil {
return h.handleError(w, r, "Failed to read file", http.StatusBadRequest)
}
Expand Down
30 changes: 29 additions & 1 deletion shared/upload_type.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package shared

import "encoding/json"
import (
"encoding/json"
"fmt"
"time"
)

var ReportUploadTypes = []ReportUploadType{
ReportTypeUploadPaymentsMOTOCard,
Expand Down Expand Up @@ -76,6 +80,8 @@ func (i ReportUploadType) Key() string {

func (i ReportUploadType) CSVHeaders() []string {
switch i {
case ReportTypeUploadPaymentsMOTOCard:
return []string{"Ordercode", "Date", "Amount"}
case ReportTypeUploadDeputySchedule:
return []string{"Deputy number", "Deputy name", "Case number", "Client forename", "Client surname", "Do not invoice", "Total outstanding"}
case ReportTypeUploadDebtChase:
Expand All @@ -87,6 +93,28 @@ func (i ReportUploadType) CSVHeaders() []string {
}
}

func (i ReportUploadType) S3Directory() string {
switch i {
case ReportTypeUploadPaymentsMOTOCard:
return "moto-card-payments"
default:
return "finance-admin"
}
}

func (i ReportUploadType) Filename(date string) (string, error) {
switch i {
case ReportTypeUploadPaymentsMOTOCard:
parsedDate, err := time.Parse("2006-01-02", date)
if err != nil {
return "", err
}
return fmt.Sprintf("feemoto_%snormal.csv", parsedDate.Format("02:01:2006")), nil
default:
return "", nil
}
}

func ParseReportUploadType(s string) ReportUploadType {
value, ok := reportTypeUploadMap[s]
if !ok {
Expand Down
49 changes: 49 additions & 0 deletions shared/upload_type_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package shared

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestReportUploadType_Filename(t *testing.T) {
tests := []struct {
name string
uploadType ReportUploadType
dateString string
wantErr bool
wantFilename string
}{
{
name: "Non-moto card payments report type",
uploadType: ReportTypeUploadDeputySchedule,
dateString: "02/01/2020",
wantErr: false,
wantFilename: "",
},
{
name: "Moto card payments report type",
uploadType: ReportTypeUploadPaymentsMOTOCard,
dateString: "02/01/2020",
wantErr: false,
wantFilename: "",
},
{
name: "Invalid date",
uploadType: ReportTypeUploadPaymentsMOTOCard,
dateString: "hehe",
wantErr: true,
wantFilename: "",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
filename, err := test.uploadType.Filename(test.dateString)

assert.Equal(t, test.wantFilename, filename)

if test.wantErr {
assert.Error(t, err)
}
})
}
}

0 comments on commit b70c86d

Please sign in to comment.