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

Bug/oq 14 select next in line #22

Merged
merged 5 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 2 additions & 2 deletions client/src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ const getTicket = async (service_id:number) => {
return data;
}

const getNextCustomer = async (service_ids: number[]) => {
const getNextCustomer = async () => {
const response = await fetch(`${SERVER_URL}/api/line/next-customer`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ service_ids })
body: JSON.stringify({ })
GiuseppeArbore marked this conversation as resolved.
Show resolved Hide resolved
});
if (!response.ok) {
throw new Error('Network response was not ok');
Expand Down
73 changes: 45 additions & 28 deletions client/src/Components/Counter/OfficeDesk.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,69 @@
import React, { useEffect, useState, useContext } from 'react';
import { Alert, Button, Container, Row, Spinner } from 'react-bootstrap';
import React, { useEffect, useState } from 'react';
import API from '../../API'; // Adjust the import path according to your project structure
import { Alert, Button } from 'react-bootstrap';
import { useParams } from 'react-router-dom';

function OfficeDesk() {
const { number } = useParams<{ number: string }>();
const [ticket_number, setTicketNumber] = useState<string | undefined>(undefined);
const [service_type, setServiceType] = useState<string | undefined>(undefined);
const [showAlert, setShowAlert] = useState(false);
const handleShow = () => setShowAlert(true);
const handleClose = () => setShowAlert(false);


useEffect(() => {
// This effect will run every time ticket_number or service_type changes, but not on the initial render
if (ticket_number !== undefined) {
handleShow();
}
}, [ticket_number, service_type]);

return (
<>
<h1 style={{ textAlign: 'center', marginTop: '1rem' }}>You are the counter {number}</h1>

<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
{showAlert ? (
<Alert variant="success" onClose={handleClose}>
<Alert.Heading className="large-heading">Next Customer is {ticket_number}</Alert.Heading>
<p>
When the customer arrives, please click on the button below to proceed.
</p>
<Alert variant="success" >
{service_type && ticket_number ? (
<>
<Alert.Heading className="large-heading">Next Customer is {ticket_number} for service S-{service_type}</Alert.Heading>
<p>
When the customer arrives, please click on the button below to proceed.
</p>
</>
) : (
<Alert.Heading className="large-heading">There is no customer to serve</Alert.Heading>
)}
<Button onClick={handleClose} variant="outline-success">
Close
</Button>
</Alert>
) : (
<>
{ticket_number && <h2>Current Customer: {ticket_number}</h2>}
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '3rem', justifyContent: 'space-around' }}>
<Button variant="primary" onClick={async () => {
try {
const response = "6"; //await API.getNextCustomer();
if (response /*&& response.ticket_number*/) {
// Assuming you have a way to update the ticket_number in your component state
// You might need to lift the state up or use a context
setTicketNumber(response/*.ticket_number*/);
handleShow();
) : (
<>
{ticket_number && <h2>Current Customer: {ticket_number}</h2>}
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '3rem', justifyContent: 'space-around' }}>
<Button variant="primary" onClick={async () => {
try {
const response = await API.getNextCustomer();
console.log(response);
if (response) {
if(response.ticketNumber==0){
setTicketNumber(undefined);
setServiceType(undefined);
handleShow();
}else{
setTicketNumber(response.ticketNumber);
setServiceType(response.serviceType);
}
}
} catch (error) {
GiuseppeArbore marked this conversation as resolved.
Show resolved Hide resolved
console.error("Failed to fetch next customer", error);
}
} catch (error) {
console.error("Failed to fetch next customer", error);
}
}}>Next Customer</Button>
</div>
</>
)}

}}>Next Customer</Button>
</div>
</>
)}
</div>
</>
);
Expand Down
8 changes: 1 addition & 7 deletions server/src/controllers/lineController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ class LineController {
}

async getNextCustomer(req: Request, res: Response): Promise<void> {
const serviceIds: number[] = req.body.service_ids;

if (!serviceIds || !Array.isArray(serviceIds) || serviceIds.length === 0 || !serviceIds.every(id => typeof id === 'number' && id > 0 && Number.isInteger(id))) {
res.status(400).send({ error: 'Invalid service_ids' });
return;
}

try {
const nextCustomerId = await this.lineDAO.getNextCustomer(serviceIds);
const nextCustomerId = await this.lineDAO.getNextCustomer();
GiuseppeArbore marked this conversation as resolved.
Show resolved Hide resolved
res.status(200).send({ nextCustomerId });
} catch (error) {
const status = (error as any).status || 500;
Expand Down
33 changes: 10 additions & 23 deletions server/src/dao/lineDao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,24 @@ import db from '../db/db';

class LineDAO {

async validateServiceIds(serviceIds: number[]): Promise<void> {
const serviceExistsQuery = 'SELECT id FROM services';
const rows = await db.all(serviceExistsQuery);

const existingServiceIds = rows.map(row => row.id);
const invalidServiceIds = serviceIds.filter(id => !existingServiceIds.includes(id));

if (invalidServiceIds.length > 0) {
const error = new Error(`Invalid service IDs: ${invalidServiceIds.join(', ')}`);
(error as any).status = 404;
throw error;
}
}


async getNextCustomer(service_ids: number[]): Promise<{ serviceType: number, ticketNumber: number }> {
async getNextCustomer(): Promise<{ serviceType: number, ticketNumber: number }> {

const placeholders = service_ids.map(() => '?').join(',');


const selectQuery = `SELECT id, current_number,queue_length FROM services WHERE id IN (${placeholders}) ORDER BY (queue_length - current_number) DESC, service_time ASC LIMIT 1`;
const selectQuery = `SELECT id, current_number,queue_length FROM services ORDER BY (queue_length - current_number) DESC, service_time ASC LIMIT 1`;

const updateQuery = 'UPDATE services SET current_number = current_number + 1 WHERE id = ?';

// Verifica che gli ID di servizio siano validi
await this.validateServiceIds(service_ids);


// Esegui la query per ottenere il servizio con il prossimo cliente
const row = await db.get(selectQuery, [...service_ids]);

const row = await db.get(selectQuery,[]);



// Controlla che sia stato trovato un servizio

if (!row) {
throw new Error('No service found for the provided service IDs');
}
Expand All @@ -45,10 +32,10 @@ class LineDAO {
};
}

// Aggiorna il numero corrente del servizio selezionato

await db.run(updateQuery, [row.id]);

// Restituisci il nuovo valore di current_number + 1

let nextCustomer = row.current_number + 1;
return {
serviceType: row.id,
Expand Down
101 changes: 5 additions & 96 deletions server/test_integration/lineIntegration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,86 +29,13 @@ describe('Line API Integration Tests', () => {

const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [1,2,3] });

expect(response.status).toBe(200);
expect(response.body.nextCustomerId).toStrictEqual({"serviceType": 3, "ticketNumber": 16}); // Based on test data
},10000);

it('Test 2: should return 400 if service_ids is not provided', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({});

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid service_ids');
});

it('Test 3: should return 400 if service_ids is not an array', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: 'not-an-array' });

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid service_ids');
});

it('Test 4: should return 404 if invalid service IDs are provided', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [5] });

expect(response.status).toBe(404);
expect(response.body.message).toBe('Invalid service IDs: 5');
});


it('Test 6: should handle multiple service IDs correctly', async () => {


const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [2, 3, 4] });
.send();

expect(response.status).toBe(200);
expect(response.body.nextCustomerId).toStrictEqual({"serviceType": 4, "ticketNumber": 16}); // Based on test data
});

it('Test 7: should return 404 if no row is found for the given service_id', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [5] });

expect(response.status).toBe(404);
expect(response.body.message).toBe('Invalid service IDs: 5');
});

it('Test 8: should handle empty service_ids array', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [] });

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid service_ids');
});


it('Test 10: should handle invalid JSON in request body', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.set('Content-Type', 'application/json')
.send('invalid-json');

expect(response.status).toBe(400);
});

it('Test 11: should handle missing Content-Type header', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [1, 2, 3] });
},10000);

expect(response.status).toBe(200);
});



it('Test 13: should handle database connection errors', async () => {
Expand All @@ -117,33 +44,15 @@ describe('Line API Integration Tests', () => {

const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [1, 2, 3] });
.send();

expect(response.status).toBe(500);

// Reopen the database for subsequent tests
await db.open();
});

it('Test 14: should handle invalid service_ids with special characters', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: ['@', '#', '$'] });

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid service_ids');
});


it('Test 16: should handle valid service_ids with negative numbers', async () => {
const response = await request(server)
.post('/api/line/next-customer')
.send({ service_ids: [-1, -2, -3] });

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid service_ids');
});



});

Expand Down
Loading
Loading