Skip to content

Commit

Permalink
Merge branch 'master' into snyk-upgrade-5b6262679814d3011d6bbc0696babc17
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Oct 2, 2024
2 parents 8dfa2c0 + dcc6b40 commit de237d0
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 109 deletions.
1 change: 0 additions & 1 deletion migrations/1694620030174_global-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ exports.up = pgm => {
})

}

11 changes: 11 additions & 0 deletions migrations/1725550538880_global.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable camelcase */
const { PgLiteral } = require("node-pg-migrate")
exports.up = pgm => {
pgm.createTable({ schema: "jtl", name: "global" }, {
instance: {
type: "uuid",
"default": new PgLiteral("uuid_generate_v4()"),
notNull: true,
},
})
}
7 changes: 7 additions & 0 deletions migrations/1725551629571_instance-id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

exports.up = async pgm => {
await pgm.db.query({
text: `INSERT INTO jtl.global DEFAULT VALUES;`,
values: [],
})
}
24 changes: 24 additions & 0 deletions migrations/1727852225583_scenario-foreing-keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

exports.up = (pgm) => {
pgm.dropConstraint({ schema: "jtl", name: "notifications" }, "notifications_scenario_id_fkey")
pgm.addConstraint({ schema: "jtl", name: "notifications" }, "notifications_scenario_id_fkey", {
foreignKeys: {
columns: "scenario_id",
references: {
schema: "jtl", name: "scenario", column: "id",
},
onDelete: "CASCADE",
},
})
pgm.dropConstraint({ schema: "jtl", name: "scenario_share_tokens" }, "scenario_share_tokens_scenario_id_fkey")
pgm.addConstraint({ schema: "jtl", name: "scenario_share_tokens" }, "scenario_share_tokens_scenario_id_fkey", {
foreignKeys: {
columns: "scenario_id",
references: {
schema: "jtl", name: "scenario", column: "id",
},
onDelete: "CASCADE",
},
})

}
164 changes: 82 additions & 82 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,96 +21,96 @@ const DEFAULT_PORT = 5000
const PORT = process.env.PORT || DEFAULT_PORT

export class App {
app: express.Application
router: Router = new Router()
private server: http.Server
app: express.Application
router: Router = new Router()
private server: http.Server

constructor() {
this.app = express()
this.config()
this.router.getRoutes(this.app)
this.databaseErrorHandler()
this.errorHandler()
}
constructor() {
this.app = express()
this.config()
this.router.getRoutes(this.app)
this.databaseErrorHandler()
this.errorHandler()
}

private config(): void {
this.app.use(bodyParser.json())
this.app.use(bodyParser.urlencoded({ extended: false }))
this.app.use(compression())
this.app.use(expressWinston.logger({
transports: [
new winston.transports.Console(),
],
meta: false,
expressFormat: true,
colorize: false,
}))
this.app.use(helmet())
private config(): void {
this.app.use(bodyParser.json())
this.app.use(bodyParser.urlencoded({ extended: false }))
this.app.use(compression())
this.app.use(expressWinston.logger({
transports: [
new winston.transports.Console(),
],
meta: false,
expressFormat: true,
colorize: false,
}))
this.app.use(helmet())

this.app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Methods", "*")
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, x-access-token, Content-Type, Accept")
next()
})
}
this.app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Methods", "*")
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, x-access-token, Content-Type, Accept")
next()
})
}

private errorHandler() {
// eslint-disable-next-line no-unused-vars
this.app.use(function (error: Error, req: Request, res: Response, next: NextFunction) {
if (boom.isBoom(error)) {
const { payload: { message } } = error.output
return res.status(error.output.statusCode).json({ message })
}
const errorId = uuidv4()
logger.error(`Unexpected error: ${error}, errorId: ${errorId}`)
AnalyticsEvent.reportUnexpectedError(error)
return res.status(StatusCode.InternalError).json({ message: `Unexpected error occurred: ${errorId}` })
private errorHandler() {
// eslint-disable-next-line no-unused-vars
this.app.use(function (error: Error, req: Request, res: Response, next: NextFunction) {
if (boom.isBoom(error)) {
const { payload: { message } } = error.output
return res.status(error.output.statusCode).json({ message })
}
const errorId = uuidv4()
logger.error(`Unexpected error: ${error}, errorId: ${errorId}`)
AnalyticsEvent.reportUnexpectedError(error)
return res.status(StatusCode.InternalError).json({ message: `Unexpected error occurred: ${errorId}` })

})
}
})
}

private databaseErrorHandler() {
this.app.use(function (error: PgError, req: Request, res: Response, next: NextFunction) {
logger.error(error)
if (error instanceof pgp.errors.QueryResultError) {
return next(boom.notFound())
}
if (error?.code === "ECONNREFUSED") {
return next(boom.serverUnavailable(`Could not connect to the database: ${error.address}:${error.port}`))
}
return next(error)
private databaseErrorHandler() {
this.app.use(function (error: PgError, req: Request, res: Response, next: NextFunction) {
logger.error(error)
if (error instanceof pgp.errors.QueryResultError) {
return next(boom.notFound())
}
if (error?.code === "ECONNREFUSED") {
return next(boom.serverUnavailable(`Could not connect to the database: ${error.address}:${error.port}`))
}
return next(error)

})
}
})
}

listen() {
if (!config.jwtToken || !config.jwtTokenLogin) {
logger.error("Please provide JWT_TOKEN and JWT_TOKEN_LOGIN env vars")
process.exit(1)
listen() {
if (!config.jwtToken || !config.jwtTokenLogin) {
logger.error("Please provide JWT_TOKEN and JWT_TOKEN_LOGIN env vars")
process.exit(1)
}
this.server = this.app.listen(PORT,
() => {
logger.info("Express server listening on port " + PORT)
bree.start().then(() => {

logger.info("Bree scheduler was started")
if (process.env.OPT_OUT_ANALYTICS === "true") {
bree.stop("analytics-report").then(() => {
logger.info("Analytics task was opted-out")
})
} else {
logger.info("By using this app you agree with the use of analytics" +
" in this app to help improve user experience and the overall functionality of the app.")
}
})
})
return this.server
}
this.server = this.app.listen(PORT,
() => {
logger.info("Express server listening on port " + PORT)
bree.start().then(() => {
process.env.ANALYTICS_IDENTIFIER = uuidv4()
logger.info("Bree scheduler was started")
if (process.env.OPT_OUT_ANALYTICS === "true") {
bree.stop("analytics-report").then(() => {
logger.info("Analytics task was opted-out")
})
} else {
logger.info("By using this app you agree with the use of analytics in this app to help improve" +
" user experience and the overall functionality of the app.")
}
})
})
return this.server
}

close() {
return this.server.close(() => {
logger.info("Server closed")
})
}
close() {
return this.server.close(() => {
logger.info("Server closed")
})
}
}
41 changes: 23 additions & 18 deletions src/server/utils/analytics/analytics-event.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { analytics } from "../analytics"

jest.mock("../analytics")


describe("AnalyticEvents", () => {

beforeEach(() => {
Expand All @@ -29,66 +28,72 @@ describe("AnalyticEvents", () => {
})
})
describe("reportProcessingFinished", () => {
it("should not track the event when analytics disabled", function () {
it("should not track the event when analytics disabled", async function () {
process.env.OPT_OUT_ANALYTICS = "true"
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportProcessingFinished()
await AnalyticsEvent.reportProcessingFinished()
expect(trackMock).not.toHaveBeenCalled()

})
it("should track the event only when analytics enabled", function () {
it("should track the event only when analytics enabled", async function () {
process.env.OPT_OUT_ANALYTICS = "false"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportProcessingFinished()
await AnalyticsEvent.reportProcessingFinished()
expect(trackMock).toHaveBeenCalled()
})
})

describe("reportLabelCount", () => {
it("should not track the event when analytics disabled", function () {
it("should not track the event when analytics disabled", async function () {
process.env.OPT_OUT_ANALYTICS = "true"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportDetails(1, 1)
await AnalyticsEvent.reportDetails(1, 1)
expect(trackMock).not.toHaveBeenCalled()

})
it("should track the event only when analytics enabled", function () {
it("should track the event only when analytics enabled", async function () {
process.env.OPT_OUT_ANALYTICS = "false"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportDetails(1, 1)
await AnalyticsEvent.reportDetails(1, 1)
expect(trackMock).toHaveBeenCalled()
})
})

describe("reportProcessingStarted", () => {
it("should not track the event when analytics disabled", function () {
it("should not track the event when analytics disabled", async function () {
process.env.OPT_OUT_ANALYTICS = "true"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportProcessingStarted()
await AnalyticsEvent.reportProcessingStarted()
expect(trackMock).not.toHaveBeenCalled()

})
it("should track the event only when analytics enabled", function () {
it("should track the event only when analytics enabled", async function () {
process.env.OPT_OUT_ANALYTICS = "false"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportProcessingStarted()
await AnalyticsEvent.reportProcessingStarted()
expect(trackMock).toHaveBeenCalled()
})
})
describe("unexpectedError", () => {
it("should not track the event when analytics disabled", function () {
it("should not track the event when analytics disabled", async function () {
process.env.OPT_OUT_ANALYTICS = "true"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportUnexpectedError(Error("test"))
await AnalyticsEvent.reportUnexpectedError(Error("test"))
expect(trackMock).not.toHaveBeenCalled()

})
it("should track the event only when analytics enabled", function () {
it("should track the event only when analytics enabled", async function () {
process.env.OPT_OUT_ANALYTICS = "false"
jest.spyOn(AnalyticsEvent as any, "getInstanceId").mockResolvedValueOnce("mocked-id")
const trackMock = (analytics.track as any).mockResolvedValueOnce(undefined)
AnalyticsEvent.reportUnexpectedError(Error("test"))
await AnalyticsEvent.reportUnexpectedError(Error("test"))
expect(trackMock).toHaveBeenCalled()
})
})

})
Loading

0 comments on commit de237d0

Please sign in to comment.