Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend File Validation #2690

Merged
merged 22 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
08b4be9
- small grammar fix
elipe17 Aug 24, 2023
9fd0630
- Fix lint suggestions
elipe17 Aug 28, 2023
29a9463
- updated message
elipe17 Aug 28, 2023
66b87f4
- Fixed lint errors
elipe17 Aug 28, 2023
6ead8b4
- Added correct extension to datafiles without one
elipe17 Aug 31, 2023
153472a
- Adding cherry picks for file extension error handling
elipe17 Aug 31, 2023
e2b1551
- Updated regex
elipe17 Sep 5, 2023
457c1ca
Merge branch 'develop' of https://github.com/raft-tech/TANF-app into …
elipe17 Sep 5, 2023
4897d13
Merge branch 'develop' of https://github.com/raft-tech/TANF-app into …
elipe17 Sep 13, 2023
1520097
- updating to keep file in dropbox in event of error to help user cor…
elipe17 Sep 19, 2023
0a5bae7
Merge branch 'develop' of https://github.com/raft-tech/TANF-app into …
elipe17 Sep 19, 2023
bb678c3
Merge branch 'develop' into 2664-ext-msg-2
ADPennington Sep 22, 2023
c997c69
- Fix icon rendering incorrectly
elipe17 Sep 27, 2023
bd8f1d4
Merge branch 'develop' of https://github.com/raft-tech/TANF-app into …
elipe17 Sep 27, 2023
db95f4f
Merge branch 'develop' into 2664-ext-msg-2
reitermb Sep 29, 2023
6a056a8
update test file extensions
jtimpe Sep 29, 2023
b4b3512
- making timeout longer
elipe17 Oct 3, 2023
2ab881b
Merge branch '2664-ext-msg-2' of https://github.com/raft-tech/TANF-ap…
elipe17 Oct 3, 2023
46acf0a
- Resolved issue causing test failure
elipe17 Oct 3, 2023
55bdc1c
- passing param
elipe17 Oct 3, 2023
41221b4
Merge branch 'develop' into 2664-ext-msg-2
ADPennington Oct 4, 2023
4d0ae48
Merge branch 'develop' of https://github.com/raft-tech/TANF-app into …
elipe17 Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tdrs-backend/tdpservice/data_files/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
def _get_unsupported_msg(_type, value, supported_options):
"""Construct a message to convey an unsupported operation."""
return (
f'Unsupported {_type}: {value}, supported {pluralize(_type)} '
f'Unsupported {_type}: supported {pluralize(_type)} '
f'are: {supported_options}'
)

Expand Down
18 changes: 9 additions & 9 deletions tdrs-backend/tdpservice/parsers/test/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

@pytest.fixture
def test_datafile(stt_user, stt):
"""Fixture for small_correct_file."""
return create_test_datafile('small_correct_file', stt_user, stt)
"""Fixture for small_correct_file.txt."""
return create_test_datafile('small_correct_file.txt', stt_user, stt)


@pytest.mark.django_db()
def test_parse_small_correct_file(test_datafile):
"""Test parsing of small_correct_file."""
"""Test parsing of small_correct_file.txt."""
errors = parse.parse_datafile(test_datafile)
errors = ParserError.objects.filter(file=test_datafile)
assert errors.count() == 0
Expand All @@ -44,7 +44,7 @@ def test_parse_small_correct_file(test_datafile):

@pytest.mark.django_db()
def test_parse_section_mismatch(test_datafile):
"""Test parsing of small_correct_file where the DataFile section doesn't match the rawfile section."""
"""Test parsing of small_correct_file.txt where the DataFile section doesn't match the rawfile section."""
test_datafile.section = 'Closed Case Data'
test_datafile.save()

Expand All @@ -67,7 +67,7 @@ def test_parse_section_mismatch(test_datafile):

@pytest.mark.django_db()
def test_parse_wrong_program_type(test_datafile):
"""Test parsing of small_correct_file where the DataFile program type doesn't match the rawfile."""
"""Test parsing of small_correct_file.txt where the DataFile program type doesn't match the rawfile."""
test_datafile.section = 'SSP Active Case Data'
test_datafile.save()

Expand Down Expand Up @@ -457,8 +457,8 @@ def test_parse_super_big_s1_file(super_big_s1_file):

@pytest.fixture
def super_big_s1_rollback_file(stt_user, stt):
"""Fixture for ADS.E2J.NDM1.TS53_fake.rollback."""
return create_test_datafile('ADS.E2J.NDM1.TS53_fake.rollback', stt_user, stt)
"""Fixture for ADS.E2J.NDM1.TS53_fake.rollback.txt."""
return create_test_datafile('ADS.E2J.NDM1.TS53_fake.rollback.txt', stt_user, stt)

@pytest.mark.django_db()
def test_parse_super_big_s1_file_with_rollback(super_big_s1_rollback_file):
Expand Down Expand Up @@ -487,7 +487,7 @@ def test_parse_super_big_s1_file_with_rollback(super_big_s1_rollback_file):
@pytest.fixture
def bad_tanf_s1__row_missing_required_field(stt_user, stt):
"""Fixture for small_tanf_section1."""
return create_test_datafile('small_bad_tanf_s1', stt_user, stt)
return create_test_datafile('small_bad_tanf_s1.txt', stt_user, stt)


@pytest.mark.django_db()
Expand Down Expand Up @@ -528,7 +528,7 @@ def test_parse_bad_tfs1_missing_required(bad_tanf_s1__row_missing_required_field
@pytest.fixture
def bad_ssp_s1__row_missing_required_field(stt_user, stt):
"""Fixture for ssp_section1_datafile."""
return create_test_datafile('small_bad_ssp_s1', stt_user, stt, 'SSP Active Case Data')
return create_test_datafile('small_bad_ssp_s1.txt', stt_user, stt, 'SSP Active Case Data')


@pytest.mark.django_db()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

@pytest.fixture
def test_datafile(stt_user, stt):
"""Fixture for small_correct_file."""
return create_test_datafile('small_correct_file', stt_user, stt)
"""Fixture for small_correct_file.txt."""
return create_test_datafile('small_correct_file.txt', stt_user, stt)


@pytest.mark.django_db
Expand Down
4 changes: 2 additions & 2 deletions tdrs-frontend/cypress/e2e/integration/file_upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Then('{string} can see Data Files page', (username) => {
cy.visit('/data-files')
cy.contains('Data Files').should('exist')
})

Then('{string} can see search form', (username) => {
cy.contains('Fiscal Year').should('exist')
cy.contains('Quarter').should('exist')
Expand All @@ -19,7 +19,7 @@ Then('{string} can browse upload file form', (username) => {

When('{string} uploads a file', (username) => {
cy.get('button').contains('Search').should('exist').click()
cy.get('#closed-case-data').selectFile('../tdrs-backend/tdpservice/parsers/test/data/small_correct_file',{ action: 'drag-drop' })
cy.get('#closed-case-data').selectFile('../tdrs-backend/tdpservice/parsers/test/data/small_correct_file.txt',{ action: 'drag-drop' })
cy.get('button').contains('Submit Data Files').should('exist').click()
})

Expand Down
7 changes: 6 additions & 1 deletion tdrs-frontend/src/actions/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const SET_FILE = 'SET_FILE'
export const CLEAR_FILE = 'CLEAR_FILE'
export const CLEAR_FILE_LIST = 'CLEAR_FILE_LIST'
export const SET_FILE_ERROR = 'SET_FILE_ERROR'
export const FILE_EXT_ERROR = 'FILE_EXT_ERROR'
export const SET_FILE_SUBMITTED = 'SET_FILE_SUBMITTED'
export const CLEAR_ERROR = 'CLEAR_ERROR'

Expand Down Expand Up @@ -254,7 +255,11 @@ export const submit =
setLocalAlertState({
active: true,
type: 'error',
message: error.message,
message: ''.concat(
error.message,
': ',
error.response?.data?.file[0]
),
})
)
}
Expand Down
2 changes: 1 addition & 1 deletion tdrs-frontend/src/actions/reports.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe('actions/reports', () => {
expect(axios.post).toHaveBeenCalledTimes(1)
expect(setLocalAlertState).toHaveBeenCalledWith({
active: true,
message: undefined,
message: 'undefined: undefined',
type: 'error',
})
})
Expand Down
1 change: 0 additions & 1 deletion tdrs-frontend/src/actions/requestAccess.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { SET_AUTH } from './auth'
import axios from 'axios'
import axiosInstance from '../axios-instance'
import { logErrorToServer } from '../utils/eventLogger'

export const PATCH_REQUEST_ACCESS = 'PATCH_REQUEST_ACCESS'
Expand Down
20 changes: 20 additions & 0 deletions tdrs-frontend/src/components/FileUpload/FileUpload.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
clearError,
clearFile,
SET_FILE_ERROR,
FILE_EXT_ERROR,
upload,
download,
} from '../../actions/reports'
Expand All @@ -17,6 +18,9 @@ import { handlePreview, getTargetClassName } from './utils'
const INVALID_FILE_ERROR =
'We can’t process that file format. Please provide a plain text file.'

const INVALID_EXT_ERROR =
'Invalid extension. Accepted file types are: .txt, .ms##, .ts##, or .ts###.'

function FileUpload({ section, setLocalAlertState }) {
// e.g. 'Aggregate Case Data' => 'aggregate-case-data'
// The set of uploaded files in our Redux state
Expand Down Expand Up @@ -89,6 +93,22 @@ function FileUpload({ section, setLocalAlertState }) {
filereader.onloadend = (evt) => {
/* istanbul ignore next */
if (!evt.target.error) {
// Validate file extension before proceeding
const re = /(\.txt|\.ms\d{2}|\.ts\d{2,3})$/i
elipe17 marked this conversation as resolved.
Show resolved Hide resolved
if (!re.exec(file.name)) {
// reject the file and create an error message
createFileInputErrorState(input, dropTarget)

dispatch({
type: FILE_EXT_ERROR,
payload: {
error: { message: INVALID_EXT_ERROR },
section,
},
})
return
}

// Read in the file blob "headers: and create a hex string signature
const uint = new Uint8Array(evt.target.result)
const bytes = []
Expand Down
2 changes: 1 addition & 1 deletion tdrs-frontend/src/components/Paginator/Paginator.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { render, fireEvent, waitFor, screen } from '@testing-library/react'
import { render, fireEvent, screen } from '@testing-library/react'
import Paginator from './Paginator'

describe('Paginator', () => {
Expand Down
1 change: 0 additions & 1 deletion tdrs-frontend/src/components/SiteMap/SiteMap.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import { render } from '@testing-library/react'
import SiteMap from './SiteMap'
import { mount } from 'enzyme'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import configureStore from 'redux-mock-store'
Expand Down
6 changes: 6 additions & 0 deletions tdrs-frontend/src/reducers/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
SET_FILE,
CLEAR_FILE,
SET_FILE_ERROR,
FILE_EXT_ERROR,
CLEAR_ERROR,
SET_SELECTED_YEAR,
SET_SELECTED_STT,
Expand Down Expand Up @@ -175,6 +176,11 @@ const reports = (state = initialState, action) => {
const updatedFiles = getUpdatedFiles({ state, section, error })
return { ...state, submittedFiles: updatedFiles }
}
case FILE_EXT_ERROR: {
const { error, section } = payload
const updatedFiles = getUpdatedFiles({ state, section, error })
return { ...state, submittedFiles: updatedFiles }
}
case CLEAR_ERROR: {
const { section } = payload
const file = getFile(state.submittedFiles, section)
Expand Down