Skip to content

Commit

Permalink
Merge main and fix conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
jacoblurie29 committed Apr 6, 2024
2 parents e914906 + 1440bd5 commit d18aa76
Show file tree
Hide file tree
Showing 12 changed files with 403 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .env.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ENVIRONMENT=
HOST=
PORT=
AIRTABLE_API_KEY=
AIRTABLE_API_KEY=
62 changes: 53 additions & 9 deletions src/controllers/FlightRequest.controller.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/* eslint-disable no-irregular-whitespace */
import { createTestFlightLegData } from '../data/test-data';
import logger from '../util/logger';
import { trimFlightLeg, trimRequest } from '../util/trim';
import Airtable from 'airtable';
import dotenv from 'dotenv';
import type { FlightLegData } from '../interfaces/legs/flight-leg.interface';
import type { Request, Response } from 'express';
import type { FlightRequestData } from '../interfaces/requests/flight-request.interface';
dotenv.config();

const base = new Airtable({
apiKey: process.env.AIRTABLE_API_KEY || '',
}).base('appwPsfAb6U8CV3mf');

/**
* This function returns all flight requests for a given user
*
Expand All @@ -23,18 +31,54 @@ export const getAllFlightRequestsForUser = async (
req: Request,
res: Response
) => {
// get the userId from the query parameters
const { userId } = req.query;

if (userId === null) {
if (!userId) {
return res.status(400).json({ error: 'Passenger ID missing' });
} // create a fake array of flight requests
}

try {
// query Airtable for flight requests for the user ID
const flightRequests = await base('Flight Requests (Trips)')
.select({
filterByFormula: `{Patient AirTable Record ID} = "${userId}"`,
})
.all();

const flightRequests = Array.from({ length: 10 }, () =>
createTestFlightLegData()
); // return the flight requests for the user
if (flightRequests.length === 0) {
return res
.status(400)
.json({ error: 'No flight requests found for this user' });
}

const trimmedFlightRequests = flightRequests.map(request =>
trimRequest(request as unknown as FlightRequestData)
);

res.status(200).send(flightRequests);
// Retrieve flight legs for each flight request and format the data
const formattedFlightRequests = await Promise.all(
trimmedFlightRequests.map(async request => {
const flightLegs = await base('Flight Legs')
.select({
filterByFormula: `{Request AirTable Record ID} = "${request.id}"`,
})
.all();

// Format the flight request data and include the corresponding flight legs
return {
...request,
flightLegs: flightLegs.map(leg =>
trimFlightLeg(leg as unknown as FlightLegData)
),
};
})
);

return res.status(200).json(formattedFlightRequests);
} catch (error) {
console.error(error);
return res.status(500).json({ error: 'Error fetching flight requests' });
}
};

/**
Expand Down Expand Up @@ -68,7 +112,7 @@ export const getFlightRequestById = async (req: Request, res: Response) => {
}
);
} catch (err: any) {
console.error(err);
logger.error(err);
return res.status(500).json({ error: 'Error fetching record' });
}
};
Expand Down Expand Up @@ -102,7 +146,7 @@ export const getFlightLegsById = async (req: Request, res: Response) => {
return res.status(400).json({ error: 'No record found' });
}
} catch (err: any) {
console.error(err);
logger.error(err);
return res.status(500).json({ error: 'Error fetching record' });
}

Expand Down
118 changes: 94 additions & 24 deletions src/controllers/Passenger.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,23 @@ export const getAllPassengersForUser = async (req: Request, res: Response) => {
return;
} else {
// get related passengers information
const accompPassengers = [] as Record<FieldSet>[];
const accompanyingPassengersPromise = record._rawJson.fields[
'Related Accompanying Passenger(s)'
].map(async (id: string) => {
// map through the related passengers and get the passenger information for each one
const passenger = await base('Passengers').find(id.toString());
accompPassengers.push(passenger);
});
const accompPassengersPromise = [] as Promise<Record<FieldSet>>[];

record._rawJson.fields['Related Accompanying Passenger(s)']?.map(
async (id: string) => {
// map through the related passengers and get the passenger information for each one
const passenger = base('Passengers').find(id.toString());
accompPassengersPromise.push(passenger);
}
);

// Remove any unnecessary data from the passengers
await Promise.all(accompanyingPassengersPromise);
const trimmedPassengers = accompPassengers.map(
(passenger: Record<FieldSet>) =>
const passengers = await Promise.all(accompPassengersPromise);

const trimmedPassengers =
passengers?.map((passenger: Record<FieldSet>) =>
trimPassenger(passenger._rawJson as unknown as PassengerData)
);
) || [];

// return the passengers for the user
return res.send(trimmedPassengers);
Expand All @@ -65,7 +67,7 @@ export const getAllPassengersForUser = async (req: Request, res: Response) => {
);
} catch (err: any) {
// if that fails return a 500
console.error(err);
logger.error(err);
return res.status(500).json({ error: 'Error fetching record' });
}
};
Expand All @@ -84,7 +86,37 @@ export const getAllPassengersForUser = async (req: Request, res: Response) => {
* @param res - the response object
*/
export const getPassengerById = async (req: Request, res: Response) => {
// const { userId } = req.query;
const { id: userId } = req.params;

if (!userId) {
return res.status(400).json({ error: 'Passenger ID missing' });
}

const base = new Airtable({
apiKey: process.env.AIRTABLE_API_KEY || '',
}).base('appwPsfAb6U8CV3mf');

try {
await base('Passengers').find(
userId.toString(),
async (err: any, record: any | undefined) => {
if (err) {
return res.status(400).send({ error: 'No passenger found' });
} else {
// remove any unnecessary data from the passenger
const trimmedPassenger = trimPassenger(
record._rawJson as unknown as PassengerData
);

// return the passenger
return res.send(trimmedPassenger);
}
}
);
} catch (err: any) {
logger.error(err);
return res.status(500).json({ error: 'Error fetching record' });
}
};

/**
Expand Down Expand Up @@ -244,18 +276,56 @@ export const createPassenger = async (req: Request, res: Response) => {
* @param res - the response object
*/
export const updatePassenger = async (req: Request, res: Response) => {
// get the passengerId from the query parameters
// const { passengerId } = req.query;
const { id } = req.params;
const passengerData = req.body;

// get the passenger data from the request body
// const data = req.body;
if (!id) {
return res.status(400).send({ error: 'User ID is required' });
}
if (!passengerData) {
return res.status(400).send({ error: 'Passenger data is required' });
}

// validate the passenger data using Joi
// ...
const schema = Joi.object({
Street: Joi.string().optional(),
City: Joi.string().optional(),
State: Joi.string().optional(),
Country: Joi.string().optional(),
Email: Joi.string().email().optional(),
'Cell Phone': Joi.string().optional(),
'Home Phone': Joi.string().optional(),
Education: Joi.string().optional(),
'Household Income': Joi.number().optional(),
'Household Size': Joi.number().optional(),
'Marital Status': Joi.string().optional(),
Employment: Joi.string().optional,
'Military Service': Joi.string().optional(),
'Military Member': Joi.array().optional(),
});

// create a fake passenger
const passenger = createTestPassengerData();
if (schema.validate(passengerData).error) {
return res.status(400).send({ error: 'Invalid passenger data' });
}

// return the updated passenger
res.status(200).send(passenger);
const base = new Airtable({
apiKey: process.env.AIRTABLE_API_KEY || '',
}).base('appwPsfAb6U8CV3mf');

try {
// make a call to AirTable to update the passenger
await base('Passengers').update(
[{ id, fields: passengerData }],
async (err, records) => {
if (err) {
logger.error(err);
return;
}
res.status(200).send(records);
}
);
} catch (err: any) {
// if that fails return a 500
logger.error(err);
return res.status(500).json({ error: 'Error updating' });
}
};
28 changes: 28 additions & 0 deletions src/data/test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,34 @@ export const createTestPassengerData = (
Created: faker.date.recent().toISOString(),
'Latest Trip': faker.date.recent().toISOString(),
'TS City, State (from Treatment Site Totals 2)': [],
'Cell Phone': faker.phone.number(),
'Home Phone': faker.phone.number(),
Education: faker.helpers.arrayElement([
'Less than high school degree',
'High school degree or equivalent',
'Some college, no degree',
'Associate degree',
"Bachelor's degree",
'Graduate or professional degree',
]),

'Marital Status': faker.helpers.arrayElement([
'Single',
'Married',
'Divorced',
'Widowed',
]),
Employment: faker.helpers.arrayElement([
'Employed, working 40+ hours per week',
'Employed, working 1-39 hours per week',
'Unemployed, looking for work',
'Unemployed, not looking for work',
'Retired',
'Student',
'Homemaker',
'Unable to work',
'Other',
]),
...manualData.fields,
},
...manualData,
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces/passenger/passenger.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ export interface PassengerData {
City: string;
Country: string;
Email: string;
'Cell Phone': string;
'Home Phone': string;
Education: string;
'Household Income': number;
'Household Size': number;
'Marital Status': string;
Employment: string;
Ethnicity: string[];
'Military Service': string;
'Military Member': string[];
Expand Down
6 changes: 6 additions & 0 deletions src/interfaces/passenger/trimmed-passenger.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export interface TrimmedPassenger {
Email: string;
'Household Income': number;
'Household Size': number;
'Cell Phone': string;
'Home Phone': string;
Education: string;
'Marital Status': string;
Employment: string;
Ethnicity: string[];
'Military Service': string;
'Military Member': string[];
Expand All @@ -24,6 +29,7 @@ export interface TrimmedPassenger {
'# of Booked Flight Requests': number;
'Birth Month': string;
'Full Name': string;
'Passenger Names (from All Flight Legs)': string[];
Age: number;
'Latest Trip': string;
}
2 changes: 1 addition & 1 deletion src/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const routes = (app: Express) => {
app.get('/test/retrievePassengers', retrievePassengers);

/* Passenger Controller Routes */
app.get('/passenger/', getAllPassengersForUser);
app.get('/passenger/accompanying', getAllPassengersForUser);
app.get('/passenger/:id', getPassengerById);
app.post('/passenger/:id', createPassenger);
app.put('/passenger/:id', updatePassenger);
Expand Down
43 changes: 43 additions & 0 deletions src/tests/FlightRequest.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,49 @@ after(done => {
done();
});

// Test getAllFlightRequestsForUser
describe('GET /requests/', () => {
it('should return requests with the correct passenger name, flight request ID, and flight leg departure time for a given user', done => {
chai
.request(app)
.get('/requests/?userId=recV1y3bJr9eb2U5W') // Assuming userId is passed as a query parameter
.end((err, res) => {
expect(res).to.have.status(200);
const requests = res.body;

// Assuming we're testing the first request in the array for simplicity
const firstRequest = requests[0];
expect(firstRequest).to.have.property('id').that.is.a('string');
expect(firstRequest)
.to.have.nested.property('Request ID')
.that.is.a('string');
expect(firstRequest)
.to.have.nested.property('Request ID')
.that.equals(
'2022-12-08 | In Progress | Gilchrist, Stormie | 2014-06-21'
);

// Assuming flightLegs is an array and we're testing the first flight leg for simplicity
const firstFlightLeg = firstRequest.flightLegs[0];
expect(firstFlightLeg)
.to.have.nested.property('Departure Date/Time')
.that.equals('2023-02-06');

done();
});
});

it('should return a 400 response for invalid or missing ID', done => {
chai
.request(app)
.get('/requests/?userId=blahblahblah')
.end((err, res) => {
expect(res).to.have.status(400);
done();
});
});
});

// Test getFlightRequestByID
describe('GET /requests', () => {
it('should return the correct request ID, origin airport, destination airport, and passenger name', done => {
Expand Down
Loading

0 comments on commit d18aa76

Please sign in to comment.