Skip to content

Commit

Permalink
Merge pull request #37 from kiwijos/codebase-cleanup
Browse files Browse the repository at this point in the history
Codebase cleanup
  • Loading branch information
Jolpango authored Sep 27, 2023
2 parents 49eaa11 + 7ae2175 commit e774753
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 110 deletions.
71 changes: 0 additions & 71 deletions src/app.ts

This file was deleted.

23 changes: 23 additions & 0 deletions src/config/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import express, { Express } from "express";
import cors from "cors";
import bodyParser from "body-parser";

import delayed from "../routes/delayed";
import tickets from "../routes/tickets";
import codes from "../routes/codes";

const app: Express = express();

app.use(cors());
app.options("*", cors());

app.disable("x-powered-by");

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

app.use("/delayed", delayed);
app.use("/tickets", tickets);
app.use("/codes", codes);

export default app;
13 changes: 13 additions & 0 deletions src/config/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import mongoose from "mongoose";

async function startDb() {
let uri = `mongodb+srv://${process.env.ATLAS_USERNAME}:${process.env.ATLAS_PASSWORD}@trains.9gkcdmg.mongodb.net/?retryWrites=true&w=majority`;

if (process.env.NODE_ENV === "test") {
uri = process.env.MONGO_URI_TEST;
}

await mongoose.connect(uri, { dbName: "trains" });
}

export default startDb;
42 changes: 42 additions & 0 deletions src/config/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import app from "./app";

import http from "http";
import { Server } from "socket.io";

const server = http.createServer(app);

interface ServerToClientEvents {
noArg: () => void;
basicEmit: (a: number, b: string, c: Buffer) => void;
withAck: (d: string, callback: (e: number) => void) => void;
}

interface ClientToServerEvents {
hello: () => void;
}

interface InterServerEvents {
ping: () => void;
}

interface SocketData {
name: string;
age: number;
}

const io = new Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>(
server,
{
cors: {
origin: [
"http://localhost:9000",
"http://localhost:5173",
"https://localhost:5000",
"https://master--fastidious-sunburst-6bd3ae.netlify.app/"
],
methods: ["GET", "POST", "PUT", "DELETE"]
}
}
);

export { server, io };
23 changes: 19 additions & 4 deletions src/controllers/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,21 @@ import ErrorResponse from "../models/ErrorResponse.model";

const API_URL = "https://api.trafikinfo.trafikverket.se/v2/data.json";

// Create a simple in-memory cache
const cache = new Map();

const codes = {
getCodes: async function getCodes(req: Request, res: Response): Promise<object | ErrorResponse> {
getCodes: async function getCodes(
req: Request,
res: Response
): Promise<object | ErrorResponse> {
// Use cached codes if they've already been fetched
if (cache.has("codes")) {
return res.json({
data: cache.get("codes")
});
}

const query = `<REQUEST>
<LOGIN authenticationkey="${process.env.TRAFIKVERKET_API_KEY}" />
<QUERY objecttype="ReasonCode" schemaversion="1">
Expand All @@ -23,8 +36,10 @@ const codes = {
headers: { "Content-Type": "text/xml" }
});

const result = await response.json();

const result = await response.json();

cache.set("codes", result.RESPONSE.RESULT[0].ReasonCode);

return res.json({
data: result.RESPONSE.RESULT[0].ReasonCode
});
Expand All @@ -35,7 +50,7 @@ const codes = {
errors: {
status: 500,
source: API_URL,
title: 'Server Error',
title: "Server Error",
message: err.message
}
});
Expand Down
11 changes: 7 additions & 4 deletions src/controllers/delayed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import ErrorResponse from "../models/ErrorResponse.model";
const API_URL = "https://api.trafikinfo.trafikverket.se/v2/data.json";

const delayed = {
getDelayedTrains: async function getDelayedTrains(req: Request, res: Response): Promise<object | ErrorResponse> {
getDelayedTrains: async function getDelayedTrains(
req: Request,
res: Response
): Promise<object | ErrorResponse> {
const query = `<REQUEST>
<LOGIN authenticationkey="${process.env.TRAFIKVERKET_API_KEY}" />
<QUERY objecttype="TrainAnnouncement" orderby='AdvertisedTimeAtLocation' schemaversion="1.8">
Expand Down Expand Up @@ -40,9 +43,9 @@ const delayed = {
body: query,
headers: { "Content-Type": "text/xml" }
});

const result = await response.json();

return res.json({
data: result.RESPONSE.RESULT[0].TrainAnnouncement
});
Expand All @@ -53,7 +56,7 @@ const delayed = {
errors: {
status: 500,
source: API_URL,
title: 'Server Error',
title: "Server Error",
message: err.message
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/tickets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Response, Request } from "express";
import Ticket from "../models/ticket";
import Ticket from "../models/Ticket";
import type ErrorResponse from "../models/ErrorResponse.model";

const tickets = {
Expand Down
6 changes: 4 additions & 2 deletions src/controllers/trains.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import fetch from "node-fetch";
import EventSource from "eventsource";
import type TrainPosition from "../models/TrainPosition.model";
import type TrainPositions from "../models/TrainPositions.model";
import { Server } from "socket.io";

const API_URL = "https://api.trafikinfo.trafikverket.se/v2/data.json";

async function fetchTrainPositions(io): Promise<void> {
async function fetchTrainPositions(io: Server): Promise<void> {
const query = `<REQUEST>
<LOGIN authenticationkey="${process.env.TRAFIKVERKET_API_KEY}" />
<QUERY sseurl="true" namespace="järnväg.trafikinfo" objecttype="TrainPosition" schemaversion="1.0" limit="1" />
</REQUEST>`;

const trainPositions = {};
const trainPositions: TrainPositions = {};

try {
const response = await fetch(API_URL, {
Expand Down
23 changes: 23 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import dotenv from "dotenv";
dotenv.config();

import { server, io } from "./config/server";
import fetchTrainPositions from "./controllers/trains";
import startDb from "./config/database";

const port = process.env.PORT || 1337;

server.listen(port, (): void => {
console.log(`App listening on port ${port}`);
});

startDb().catch((err) => console.log(err));

// Temporary work-around preventing sockets from keeping
// the server alive even after all tests have run
if (process.env.NODE_ENV !== "test") {
fetchTrainPositions(io);
}

// Export listening app for testing
export default server;
12 changes: 6 additions & 6 deletions src/models/ErrorResponse.model.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
interface ErrorResponse {
errors: {
status: number;
source: string;
title: string;
message: string;
status: number;
source: string;
title: string;
message: string;
};
}
}

export default ErrorResponse;
export default ErrorResponse;
File renamed without changes.
2 changes: 1 addition & 1 deletion src/models/TrainPosition.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ interface TrainPosition {
speed: number;
}

export default TrainPosition;
export default TrainPosition;
7 changes: 7 additions & 0 deletions src/models/TrainPositions.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type TrainPosition from "./TrainPosition.model";

interface TrainPositions {
[trainNumber: string]: TrainPosition;
}

export default TrainPositions;
2 changes: 1 addition & 1 deletion test/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ process.env.NODE_ENV = "test";

import chai from "chai";
import chaiHttp from "chai-http";
import server from "../src/app";
import server from "../src/index";

chai.should();
chai.use(chaiHttp);
Expand Down
2 changes: 1 addition & 1 deletion test/delayed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ process.env.NODE_ENV = "test";

import chai from "chai";
import chaiHttp from "chai-http";
import server from "../src/app";
import server from "../src/index";

chai.should();
chai.use(chaiHttp);
Expand Down
40 changes: 21 additions & 19 deletions test/tickets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ process.env.NODE_ENV = "test";

import chai from "chai";
import chaiHttp from "chai-http";
import server from "../src/app";
import server from "../src/index";

chai.should();
chai.use(chaiHttp);
Expand Down Expand Up @@ -76,28 +76,30 @@ describe("tickets", () => {
describe("POST /tickets bad request", () => {
it("empty request result in 500 status code", (done) => {
chai.request(server)
.post("/tickets")
.send({})
.end((err, res) => {
res.should.have.status(500);
done();
});
.post("/tickets")
.send({})
.end((err, res) => {
res.should.have.status(500);
done();
});
});

it("response contains correct json data", (done) => {
chai.request(server)
.post("/tickets")
.send({})
.end((err, res) => {
res.should.have.status(500);
res.should.be.json;
res.body.should.be.a("object");
res.body.should.have.property("errors");
res.body.errors.should.have.property("status").equal(500);
res.body.errors.should.have.property("title").equal("Database Error");
res.body.errors.should.have.property("message").include("Ticket validation failed");
done();
});
.post("/tickets")
.send({})
.end((err, res) => {
res.should.have.status(500);
res.should.be.json;
res.body.should.be.a("object");
res.body.should.have.property("errors");
res.body.errors.should.have.property("status").equal(500);
res.body.errors.should.have.property("title").equal("Database Error");
res.body.errors.should.have
.property("message")
.include("Ticket validation failed");
done();
});
});
});
});

0 comments on commit e774753

Please sign in to comment.