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

Kenneth/export #21

Merged
merged 8 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 36 additions & 0 deletions front-end/app/export/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client'
import { useData } from '@/utils/DataContext';
import { Button } from '@trussworks/react-uswds'

import React from 'react';

export default function ExportPage() {
const { data } = useData(); // Access the shared data
const downloadFile = () => {
// Convert the data object to a JSON string
const jsonData = JSON.stringify(data);

// Create a Blob with the JSON data
const blob = new Blob([jsonData], { type: 'application/json' });

// Create a URL for the Blob
const url = URL.createObjectURL(blob);

// Create a temporary anchor element to trigger the download
const a = document.createElement('a');
a.href = url;
a.download = 'data.json';

// Programmatically click the anchor element to trigger the download
a.click();

// Clean up by revoking the URL
URL.revokeObjectURL(url);
};
return (
<div className="margin-3">
<h1>Export Page</h1>
<Button type="button" onClick={downloadFile}>Export</Button>
</div>
);
}
7 changes: 6 additions & 1 deletion front-end/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DataProvider } from "@/utils/DataContext"
import "./global.css"

export const metadata = {
Expand All @@ -12,7 +13,11 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body>{children}</body>
<body>
<DataProvider>
{children}
</DataProvider>
</body>
</html>
)
}
6 changes: 4 additions & 2 deletions front-end/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export default function Home(){
return<h1>Front page</h1>


export default function Home() {
return <h1>Front page</h1>
}
26 changes: 17 additions & 9 deletions front-end/app/upload_file/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
'use client'
import { useData } from '@/utils/DataContext';
import { FileInput, FormGroup, Label, Button } from '@trussworks/react-uswds'
import { useState } from 'react';
import { useRouter } from 'next/navigation';


export default function UploadFile() {
const { setData } = useData();
const router = useRouter();
// We will change this and put it in a constants
// file when orchestration is published
const process_url = 'http://localhost:8080/process'
Expand All @@ -25,21 +29,25 @@ export default function UploadFile() {
body: formData,
});
const data = await response.json();
setData(data);
//We will do something with the data high fidelity version.
console.log(data);
router.push('/export')
} catch (error) {
console.error('Error uploading file', error);
}
}
};

return <div className="margin-3">
<FormGroup>
<Label htmlFor="file-input-single">Input accepts a single file</Label>
<FileInput id="file-input-single"
name="file-input-single" onChange={(addFile)}
/>
<Button type="button" onClick={handleSubmit}>Upload</Button>
</FormGroup>
</div>
return (
<div className="margin-3">
<FormGroup>
<Label htmlFor="file-input-single">Input accepts a single file</Label>
<FileInput id="file-input-single"
name="file-input-single" onChange={(addFile)}
/>
<Button type="button" onClick={handleSubmit}>Upload</Button>
</FormGroup>
</div>
)
}
49 changes: 49 additions & 0 deletions front-end/tests/export.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import "@testing-library/jest-dom";
import ExportPage from '../app/export/page'; // Adjust the import path as needed

// Mock the DataContext module
jest.mock('../utils/DataContext', () => ({
useData: () => ({
data: {
"name": "this is a test"
},
}),
}));

global.URL.createObjectURL = jest.fn();
global.URL.revokeObjectURL = jest.fn();

describe("Export Page", () => {
it("ExportPage component should render page", () => {
render(<ExportPage />);
expect(screen.getByText('Export Page')).toBeInTheDocument();
});
});

test('ExportPage component should render and trigger download', () => {
render(<ExportPage />);

// Assert that the component renders
// Mock the anchor click function to prevent actual navigation
const anchorClickMock = jest.fn();
const originalCreateElement = document.createElement;
document.createElement = (tagName) => {
if (tagName === 'a') {
return {
click: anchorClickMock,
setAttribute: jest.fn(),
removeAttribute: jest.fn(),
};
}
return originalCreateElement(tagName);
};

// Find the "Export" button and click it
const exportButton = screen.getByText('Export');
fireEvent.click(exportButton);

// Assert that the anchor click function was called
expect(anchorClickMock).toHaveBeenCalled();
});
38 changes: 32 additions & 6 deletions front-end/tests/upload.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import UploadFile from "../app/upload_file/page";
import "@testing-library/jest-dom";
import { fireEvent, render, screen } from "@testing-library/react";
import { DataProvider } from '../utils/DataContext'

import { act } from "react-dom/test-utils";


jest.mock("next/navigation", () => ({
useRouter() {
return {
prefetch: () => null,
push: jest.fn(), // Add the push method
};
}
}));

describe("Upload File", () => {
it("renders a upload file page", () => {
render(<UploadFile />);
render(
<DataProvider>
<UploadFile />
</DataProvider>
);
expect(screen.getByText('Input accepts a single file')).toBeInTheDocument();
});
});
Expand All @@ -26,18 +43,27 @@ describe('UploadFile Component', () => {
json: () => Promise.resolve({ success: true }),
})
);
const { getByText, queryByTestId } = render(<UploadFile />);
const { getByText, queryByTestId } = await act(async () => render(
<DataProvider>
<UploadFile />
</DataProvider>)
);

const fileInput = queryByTestId('file-input-input')
const file = new File(['test content'], 'test.txt', { type: 'text/plain' });
const fileList = createFileList([file]);

fireEvent.change(fileInput, {
target: { files: fileList },
})
await act(async () => {
fireEvent.change(fileInput, {
target: { files: fileList },
});
});


const uploadButton = getByText('Upload');
fireEvent.click(uploadButton);
await act(async () => {
fireEvent.click(uploadButton);
});

// Assert that the handleSubmit function has been called
expect(global.fetch).toHaveBeenCalledWith('http://localhost:8080/process', {
Expand Down
27 changes: 27 additions & 0 deletions front-end/utils/DataContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client'
import { createContext, useContext, ReactNode, useState } from 'react';

interface DataContextValue {
data: any; // You can define a specific data type here
setData: (data: any) => void;
}

const DataContext = createContext<DataContextValue | undefined>(undefined);

export function DataProvider({ children }: { children: ReactNode }) {
const [data, setData] = useState<any | null>(null);

return (
<DataContext.Provider value={{ data, setData }}>
{children}
</DataContext.Provider>
);
}

export function useData() {
const context = useContext(DataContext);
if (!context) {
throw new Error('useData must be used within a DataProvider');
}
return context;
}