Skip to content

Commit abbce6e

Browse files
committed
source
1 parent 7a682a9 commit abbce6e

File tree

5 files changed

+227
-49
lines changed

5 files changed

+227
-49
lines changed

DOCS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,45 @@ The `benchmark.js` script measures API response times. To run it:
108108
node benchmark.js
109109
```
110110

111+
## Integration Tests
112+
To run the end-to-end integration tests:
113+
1. Ensure the server is running locally.
114+
2. Run the following command:
115+
```bash
116+
npm test
117+
```
118+
3. The tests will simulate the workflow of file upload, preview, processing, and result retrieval.
119+
120+
## User Acceptance Testing (UAT)
121+
Refer to the `UAT_GUIDELINES.md` file for detailed instructions on UAT scenarios and feedback collection.
122+
123+
## Performance Monitoring
124+
To run the performance monitoring script:
125+
1. Ensure the server is running locally.
126+
2. Execute the script:
127+
```bash
128+
node monitor.js
129+
```
130+
3. The script will generate a `performance_report.json` file with response times, memory usage, and CPU load.
131+
132+
## Continuous Improvement Plan
133+
### Key Performance Indicators (KPIs)
134+
- Average response time for API endpoints.
135+
- Memory usage and CPU load under typical and peak loads.
136+
- Error rates and user feedback scores.
137+
138+
### Alert Mechanisms
139+
- Integrate email alerts using SendGrid for high error rates.
140+
- Use Slack notifications for critical performance issues.
141+
142+
### Log Analysis
143+
- Regularly analyze logs for error patterns and performance bottlenecks.
144+
- Use tools like ELK Stack or Datadog for advanced log analysis.
145+
146+
### Feedback Loop
147+
- Collect user feedback via integrated forms and surveys.
148+
- Prioritize enhancements based on feedback and performance metrics.
149+
111150
## Future Extensions and Scalability
112151
### Roadmap
113152
- **Advanced AI Modules**: Integrate machine learning models for data analysis.

UAT_GUIDELINES.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# User Acceptance Testing (UAT) Guidelines
2+
3+
## Purpose
4+
The purpose of this document is to outline the User Acceptance Testing (UAT) process for the Data-Verse project. This ensures that the application meets the requirements and expectations of end-users.
5+
6+
## Key Functionalities to Test
7+
1. **File Upload**
8+
- Verify that users can upload files successfully.
9+
- Ensure error messages are displayed for unsupported file formats.
10+
11+
2. **Data Preview**
12+
- Validate that uploaded data is displayed correctly in the preview.
13+
- Check for responsiveness and usability of the preview interface.
14+
15+
3. **Processing Pipeline**
16+
- Confirm that the processing pipeline can be triggered without errors.
17+
- Ensure that users receive notifications about the processing status.
18+
19+
4. **Results Retrieval**
20+
- Verify that processed results are accurate and displayed correctly.
21+
- Test the interactivity and responsiveness of the results dashboard.
22+
23+
## Test Scenarios
24+
### Scenario 1: Successful File Upload
25+
- **Steps:**
26+
1. Navigate to the upload page.
27+
2. Select a valid file and click upload.
28+
- **Expected Result:**
29+
- File is uploaded successfully, and metadata is displayed.
30+
31+
### Scenario 2: Invalid File Upload
32+
- **Steps:**
33+
1. Navigate to the upload page.
34+
2. Select an invalid file format and click upload.
35+
- **Expected Result:**
36+
- An error message is displayed.
37+
38+
### Scenario 3: Data Preview
39+
- **Steps:**
40+
1. Upload a valid file.
41+
2. Navigate to the preview page.
42+
- **Expected Result:**
43+
- Data is displayed in a tabular format.
44+
45+
### Scenario 4: Processing Pipeline
46+
- **Steps:**
47+
1. Upload a valid file.
48+
2. Trigger the processing pipeline.
49+
- **Expected Result:**
50+
- A job ID is returned, and the processing status is updated.
51+
52+
### Scenario 5: Results Retrieval
53+
- **Steps:**
54+
1. Trigger the processing pipeline.
55+
2. Navigate to the results page.
56+
- **Expected Result:**
57+
- Processed results are displayed accurately.
58+
59+
## Feedback Collection
60+
- Integrate a feedback form on the results page.
61+
- Provide a link to a survey for detailed feedback.
62+
63+
## Reporting Issues
64+
- Users can report issues via the feedback form or by emailing support@dataverse.com.

__tests__/e2e.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const request = require('supertest');
2+
const app = require('../server'); // Assuming server.js exports the app
3+
4+
describe('End-to-End Integration Tests', () => {
5+
let uploadedFileId;
6+
7+
it('should upload a file successfully', async () => {
8+
const response = await request(app)
9+
.post('/api/upload')
10+
.attach('file', '__tests__/testFile.csv');
11+
12+
expect(response.status).toBe(200);
13+
expect(response.body).toHaveProperty('fileId');
14+
uploadedFileId = response.body.fileId;
15+
});
16+
17+
it('should preview the uploaded data', async () => {
18+
const response = await request(app)
19+
.get(`/api/preview?fileId=${uploadedFileId}`);
20+
21+
expect(response.status).toBe(200);
22+
expect(response.body).toHaveProperty('previewData');
23+
});
24+
25+
it('should trigger the processing pipeline', async () => {
26+
const response = await request(app)
27+
.post('/api/process')
28+
.send({ fileId: uploadedFileId });
29+
30+
expect(response.status).toBe(200);
31+
expect(response.body).toHaveProperty('jobId');
32+
});
33+
34+
it('should retrieve the processed results', async () => {
35+
const response = await request(app)
36+
.get(`/api/results?fileId=${uploadedFileId}`);
37+
38+
expect(response.status).toBe(200);
39+
expect(response.body).toHaveProperty('results');
40+
});
41+
});

monitor.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const axios = require('axios');
2+
const os = require('os');
3+
const fs = require('fs');
4+
5+
const endpoints = [
6+
{ name: 'Upload', url: 'http://localhost:5000/api/upload', method: 'POST' },
7+
{ name: 'Preview', url: 'http://localhost:5000/api/preview', method: 'GET' },
8+
{ name: 'Process', url: 'http://localhost:5000/api/process', method: 'POST' },
9+
{ name: 'Results', url: 'http://localhost:5000/api/results', method: 'GET' },
10+
];
11+
12+
async function monitorPerformance() {
13+
const results = [];
14+
15+
for (const endpoint of endpoints) {
16+
const startTime = Date.now();
17+
try {
18+
if (endpoint.method === 'POST') {
19+
await axios.post(endpoint.url, {}); // Add payload if needed
20+
} else {
21+
await axios.get(endpoint.url);
22+
}
23+
const duration = Date.now() - startTime;
24+
results.push({ endpoint: endpoint.name, status: 'Success', responseTime: duration });
25+
} catch (error) {
26+
results.push({ endpoint: endpoint.name, status: 'Error', error: error.message });
27+
}
28+
}
29+
30+
const memoryUsage = process.memoryUsage();
31+
const cpuLoad = os.loadavg();
32+
33+
const report = {
34+
timestamp: new Date().toISOString(),
35+
results,
36+
memoryUsage,
37+
cpuLoad,
38+
};
39+
40+
fs.writeFileSync('performance_report.json', JSON.stringify(report, null, 2));
41+
console.log('Performance report generated:', report);
42+
}
43+
44+
monitorPerformance();

src/pages/Analysis.tsx

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState } from 'react';
22
import { motion, AnimatePresence } from 'framer-motion';
33
import { BarChart2, LineChart, PieChart, TrendingUp, Settings2, Download, Wand2, Brain, Share2, RefreshCw } from 'lucide-react';
44
import Plot from 'react-plotly.js';
5-
import { previewData, startProcess, getResults } from '../apiService';
65

76
const CHART_TYPES = [
87
{ id: 'bar', name: 'Bar Chart', icon: BarChart2, description: 'Compare values across categories' },
@@ -15,39 +14,44 @@ export default function Analysis() {
1514
const [selectedChart, setSelectedChart] = useState('bar');
1615
const [loading, setLoading] = useState(false);
1716
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
18-
const [data, setData] = useState(null);
19-
const [error, setError] = useState(null);
2017

21-
useEffect(() => {
22-
const fetchData = async () => {
23-
try {
24-
setLoading(true);
25-
const preview = await previewData();
26-
console.log('Preview data:', preview); // Debugging log
27-
setData(preview);
28-
} catch (err) {
29-
console.error('Error fetching preview data:', err); // Debugging log
30-
setError('Failed to load data preview.');
31-
} finally {
32-
setLoading(false);
33-
}
34-
};
35-
36-
fetchData();
37-
}, []);
38-
39-
const handleProcess = async () => {
40-
try {
41-
setLoading(true);
42-
const token = localStorage.getItem('token'); // Retrieve token from local storage
43-
const processResponse = await startProcess(token);
44-
const results = await getResults(processResponse.jobId, token);
45-
setData(results);
46-
} catch (err) {
47-
setError('Failed to process data.');
48-
} finally {
49-
setLoading(false);
50-
}
18+
// Mock data for demonstration
19+
const data = {
20+
bar: {
21+
x: ['Category A', 'Category B', 'Category C', 'Category D'],
22+
y: [32, 64, 45, 78],
23+
type: 'bar',
24+
marker: {
25+
color: 'rgb(99, 102, 241)',
26+
opacity: 0.8,
27+
},
28+
},
29+
line: {
30+
x: [1, 2, 3, 4, 5],
31+
y: [2, 5, 3, 8, 4],
32+
type: 'scatter',
33+
mode: 'lines+markers',
34+
marker: { color: 'rgb(99, 102, 241)' },
35+
line: { width: 3 },
36+
},
37+
pie: {
38+
values: [35, 25, 20, 20],
39+
labels: ['Product A', 'Product B', 'Product C', 'Product D'],
40+
type: 'pie',
41+
marker: {
42+
colors: ['rgb(99, 102, 241)', 'rgb(129, 140, 248)', 'rgb(165, 180, 252)', 'rgb(199, 210, 254)'],
43+
},
44+
},
45+
scatter: {
46+
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
47+
y: [2, 4, 3, 5, 4, 7, 6, 8, 7, 9],
48+
mode: 'markers',
49+
type: 'scatter',
50+
marker: {
51+
color: 'rgb(99, 102, 241)',
52+
size: 10,
53+
},
54+
},
5155
};
5256

5357
const handleExport = () => {
@@ -57,20 +61,6 @@ export default function Analysis() {
5761

5862
return (
5963
<div className="space-y-6">
60-
{error && <div className="text-red-500">{error}</div>}
61-
<button
62-
onClick={handleProcess}
63-
disabled={loading}
64-
className="px-4 py-2 bg-blue-500 text-white rounded"
65-
>
66-
{loading ? 'Processing...' : 'Start Processing'}
67-
</button>
68-
{data && (
69-
<div>
70-
<h3>Data Preview:</h3>
71-
<pre>{JSON.stringify(data, null, 2)}</pre>
72-
</div>
73-
)}
7464
<motion.div
7565
initial={{ opacity: 0, y: -20 }}
7666
animate={{ opacity: 1, y: 0 }}
@@ -167,7 +157,7 @@ export default function Analysis() {
167157
</div>
168158
<div className="h-[400px] w-full">
169159
<Plot
170-
data={data && data[selectedChart] ? data[selectedChart] : []} // Fallback to an empty array
160+
data={[data[selectedChart as keyof typeof data]]}
171161
layout={{
172162
margin: { t: 20, r: 20, b: 40, l: 40 },
173163
paper_bgcolor: 'rgba(0,0,0,0)',

0 commit comments

Comments
 (0)