-
Notifications
You must be signed in to change notification settings - Fork 204
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
Feat/be/job queue tests #1035
Feat/be/job queue tests #1035
Conversation
WalkthroughThe pull request introduces modifications to the server's job queue functionality, integrating the Changes
Possibly related PRs
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
🧹 Outside diff range and nitpick comments (5)
Server/index.js (1)
Line range hint
172-189
: Knees weak, cleanup needs strength! 💪The cleanup function could hang indefinitely if
jobQueue.obliterate()
gets stuck. Consider adding a timeout.Here's a suggested improvement:
const cleanup = async () => { if (cleaningUp) { console.log("Already cleaning up"); return; } cleaningUp = true; + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error('Cleanup timeout')), 5000) + ); try { console.log("Shutting down gracefully"); - await jobQueue.obliterate(); + await Promise.race([jobQueue.obliterate(), timeoutPromise]); console.log("Finished cleanup"); } catch (error) { logger.error(errorMessages.JOB_QUEUE_DELETE_JOB, { service: SERVICE_NAME, errorMsg: error.message, }); } process.exit(0); };Server/tests/services/networkService.test.js (1)
311-326
: Yo dawg, let's make this test more realistic! 🍝The test could be improved by:
- Using a more realistic response time instead of hardcoding it to 0
- Actually measuring the timing of the ping operation
Here's a suggested improvement:
it("should handle a successful ping response", async () => { const response = { alive: true }; - const responseTime = 0; + const responseTime = 123; // More realistic response time pingMock.promise.probe.returns(response); + const startTime = Date.now(); logAndStoreCheckStub.resolves(); await networkService.handlePing(job); + const actualResponseTime = Date.now() - startTime; + expect(actualResponseTime).to.be.approximately(responseTime, 100); expect( logAndStoreCheckStub.calledOnceWith({ monitorId: job.data._id, status: response.alive, responseTime, message: successMessages.PING_SUCCESS, }) ).to.be.true; expect(handleStatusUpdateStub.calledOnceWith(job, true)).to.be.true; });Server/tests/services/jobQueue.test.js (3)
4-29
: Stubbing with grace, but let's keep pace.The
QueueStub
class is well-crafted to simulate the queue behavior, but we might want to ensure that all methods expected byJobQueue
are stubbed to prevent any unforeseen errors during tests.Consider reviewing the
QueueStub
methods to ensure completeness.
77-92
: Catch that error before it blows.The test correctly catches an error, but let's make sure we're asserting the error message itself to be thorough and not miss our chance.
Add an assertion for the error message to strengthen the test.
630-670
: Metrics might get hectic.In case of failures when retrieving metrics, consider providing more detailed error information to seize the chance for better debugging.
Enhance the error logging with specific metric operation details.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (5)
- Server/index.js (2 hunks)
- Server/service/jobQueue.js (9 hunks)
- Server/tests/services/jobQueue.test.js (1 hunks)
- Server/tests/services/networkService.test.js (1 hunks)
- Server/tests/services/settingsService.test.js (0 hunks)
💤 Files with no reviewable changes (1)
- Server/tests/services/settingsService.test.js
🧰 Additional context used
🔇 Additional comments (15)
Server/index.js (2)
22-25
: Yo dawg, these imports are straight fire! 🔥The new imports for JobQueue and its bullmq dependencies are well-organized and properly separated with comments. Clean structure!
163-170
: Mom's spaghetti moment: Let's verify error handling! 🍝The JobQueue instantiation looks solid with proper dependency injection. However, let's make sure we're handling potential failures gracefully.
Let's check how errors are handled in the JobQueue implementation:
✅ Verification successful
Yo, the error handling is as clean as mom's kitchen! 🍝
After diving deep into the JobQueue implementation, I can confirm the error handling is robust and well-structured. Here's what's cooking:
- Every major operation is wrapped in try-catch blocks
- Errors are properly enriched with service and method context
- The logger is actively used to track issues, especially in critical paths:
- Job processing errors
- Worker closure failures
- Queue metrics retrieval issues
- Job deletion problems
The implementation follows a consistent pattern where operational errors are logged and then rethrown for upper-level handling, while non-critical errors (like metrics retrieval) are logged but gracefully handled to prevent system disruption.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for error handling patterns in JobQueue implementation rg -A 5 "try|catch|throw" "Server/service/jobQueue.js" # Look for error logging patterns rg "logger\.(error|warn)" "Server/service/jobQueue.js"Length of output: 4576
Server/service/jobQueue.js (9)
80-80
: Harnessing Flexibility: Injected Worker UsageSwitching to
this.Worker
increateWorker
ensures that the worker class used is the one injected, enhancing modularity and testing capabilities.
110-110
: Consistent Logging: Maintenance Window NoticeUsing
this.logger.info
to log when a monitor is in a maintenance window keeps your logging practices consistent and informative.
116-116
: Capturing Errors: Enhanced Error LoggingEmploying
this.logger.error
for logging exceptions during job processing ensures errors don't go unnoticed and can be addressed promptly.
196-206
: Maintaining Stability: Worker Scaling LogicThe adjusted logic in
scaleWorkers
correctly ensures that at least five workers are always active. This prevents over-scaling down and maintains system readiness.
289-289
: Logging Success: Job Deletion ConfirmedLogging successful job deletions with
this.logger.info
enhances transparency and aids in monitoring system operations.
296-296
: Alerting Issues: Job Deletion FailedConsistently using
this.logger.error
to log when a job deletion fails ensures that potential problems are brought to attention quickly.
352-352
: Logging Victory: Queue Obliteration LoggedAcknowledging the successful obliteration of the queue with
this.logger.info
keeps operations transparent and traceable.
46-54
: Seizing Consistency: Updated Factory MethodUpdating
createJobQueue
to acceptlogger
,Queue
, andWorker
aligns it with the constructor changes, maintaining consistency across your codebase. Be sure all calls to this method pass the new dependencies.Run the following script to find all calls to
JobQueue.createJobQueue
and verify they include the new parameters:#!/bin/bash # Description: Verify all calls to JobQueue.createJobQueue use the new signature # Search for 'JobQueue.createJobQueue(' and display the following lines rg -A 5 'JobQueue\.createJobQueue\('
Line range hint
19-36
: Grabbing the Moment: Enhanced Dependency InjectionBy introducing
logger
,Queue
, andWorker
into the constructor, you're boosting the flexibility and testability of theJobQueue
class. Ensure that all instantiations ofJobQueue
are updated to accommodate these new parameters.Run the following script to verify all instances of
JobQueue
are using the updated constructor:✅ Verification successful
Let me generate another script to get a better understanding of how JobQueue is being used.
This will help us see if there's a factory method that's handling the instantiation and if all the dependencies are properly passed through.
Yo, the constructor changes are all good - factory method's got our back!
Looking at the code with sweaty palms, I can confirm that everything's properly wired up. The
JobQueue
class is never instantiated directly withnew JobQueue()
- instead, it's always created through the static factory methodcreateJobQueue()
which handles all the dependency injection properly.The factory method is being used consistently across the codebase (as seen in the previous grep results), passing all required parameters:
- settingsService
- logger
- Queue
- Worker
Plus, the constructor signature matches exactly what the factory method provides.
Knees weak, but standing strong on this verification - no spaghetti code here!
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all instantiations of JobQueue use the new constructor signature # Search for 'new JobQueue(' and display the following lines to check parameters rg -A 5 'new JobQueue\('Length of output: 12329
Script:
#!/bin/bash # Let's check the actual JobQueue class implementation to understand the factory method cat Server/service/jobQueue.jsLength of output: 10379
Server/tests/services/jobQueue.test.js (4)
59-75
: Seize the tests, don't let them escape.The test for creating a new
JobQueue
checks for 4 jobs due to instant execution and enqueuing. Ensure this logic aligns with the actual implementation to avoid knees getting weak over failed tests.Double-check that the expected number of jobs corresponds correctly with the implementation.
150-164
: Maintenance window's closed, but are we exposed?When the maintenance window isn't active, we expect
networkService.getStatus
to be called. Let's make sure we're not missing any calls that could cost us the moment.
165-185
: Active maintenance, but action speaks louder.The test correctly checks that
networkService.getStatus
isn't called during an active maintenance window. We're capturing it perfectly.
339-371
: Fetching jobs, don't let it be a sob.The test for
getJobs
whengetRepeatableJobs
fails is on point, but ensure all possible exceptions are handled so we don't vomit on our code already.
it("should handle a successful response and isAlive === false", async function () { | ||
const response = { alive: false }; | ||
const responseTime = 0; | ||
pingMock.promise.probe.resolves(response); | ||
logAndStoreCheckStub.resolves(); | ||
|
||
await networkService.handlePing(job); | ||
console.log(logAndStoreCheckStub.getCall(0).args[0]); | ||
expect( | ||
logAndStoreCheckStub.calledOnceWith( | ||
{ | ||
monitorId: job.data._id, | ||
status: false, | ||
responseTime, | ||
message: errorMessages.PING_CANNOT_RESOLVE, | ||
}, | ||
networkService.db.createCheck | ||
) | ||
logAndStoreCheckStub.calledOnceWith({ | ||
monitorId: job.data._id, | ||
status: false, | ||
responseTime, | ||
message: errorMessages.PING_CANNOT_RESOLVE, | ||
}) | ||
).to.be.true; | ||
expect(handleStatusUpdateStub.calledOnceWith(job, false)).to.be.true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yo, the test name's got me trippin'! 🍝
The test name suggests a successful response but it's actually testing a failed ping scenario. Let's make it clearer:
Here's how we can improve it:
-it("should handle a successful response and isAlive === false", async function () {
+it("should handle a failed ping when host is unreachable", async function () {
const response = { alive: false };
const responseTime = 0;
pingMock.promise.probe.resolves(response);
logAndStoreCheckStub.resolves();
await networkService.handlePing(job);
expect(
logAndStoreCheckStub.calledOnceWith({
monitorId: job.data._id,
status: false,
responseTime,
- message: errorMessages.PING_CANNOT_RESOLVE,
+ message: errorMessages.PING_HOST_UNREACHABLE, // Use a more specific error message constant
})
).to.be.true;
expect(handleStatusUpdateStub.calledOnceWith(job, false)).to.be.true;
});
Committable suggestion was skipped due to low confidence.
@@ -311,9 +315,10 @@ class JobQueue { | |||
delayed: await this.queue.getDelayedCount(), | |||
repeatableJobs: (await this.queue.getRepeatableJobs()).length, | |||
}; | |||
console.log(metrics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweat the Details: Replace console.log
with this.logger
Using console.log
might slip in under pressure, but switching to this.logger.info
keeps your logging consistent and robust.
Apply this diff to make the change:
- console.log(metrics);
+ this.logger.info(metrics, {
+ service: SERVICE_NAME,
+ });
Committable suggestion was skipped due to low confidence.
return metrics; | ||
} catch (error) { | ||
logger.error("Failed to retrieve job queue metrics", { | ||
this.logger.error("Failed to retrieve job queue metrics", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't Let Errors Slide Away
In getMetrics
, an error is logged but not rethrown or handled further. This could lead to undefined return values. Consider throwing the error or returning a default metrics object to prevent unexpected behavior.
Apply this diff to rethrow the error:
this.logger.error("Failed to retrieve job queue metrics", {
service: SERVICE_NAME,
errorMsg: error.message,
});
+ throw error;
Committable suggestion was skipped due to low confidence.
class WorkerStub { | ||
constructor(QUEUE_NAME, workerTask) { | ||
this.queueName = QUEUE_NAME; | ||
this.workerTask = async () => workerTask({ data: { _id: 1 } }); | ||
} | ||
|
||
async close() { | ||
return true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WorkerStub's on point, but watch the joint.
The WorkerStub
class lacks event handlers that might be used in the actual JobQueue
implementation. Missing these could leave us choking on errors we could've avoided.
Consider adding event handling methods to WorkerStub
if they are utilized in JobQueue
.
it("should construct a new JobQueue with default port and host if not provided", () => { | ||
settingsService.getSettings.returns({}); | ||
const jobQueue = new JobQueue(settingsService, logger, QueueStub, WorkerStub); | ||
expect(jobQueue.connection.host).to.equal("127.0.0.1"); | ||
expect(jobQueue.connection.port).to.equal(6379); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default settings might not be so steady.
Assuming default redisHost
and redisPort
without validating them could make our arms feel heavy if defaults change. Let's ensure defaults are explicitly set in the settings or handled appropriately.
Consider explicitly setting default values or validating them within the constructor.
describe("addJob", async () => { | ||
it("should add a job to the queue", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.addJob("test", { url: "test" }); | ||
expect(jobQueue.queue.jobs.length).to.equal(1); | ||
}); | ||
it("should reject with an error if adding fails", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.queue.add = async () => { | ||
throw new Error("Error adding job"); | ||
}; | ||
try { | ||
await jobQueue.addJob("test", { url: "test" }); | ||
} catch (error) { | ||
expect(error.message).to.equal("Error adding job"); | ||
expect(error.service).to.equal("JobQueue"); | ||
expect(error.method).to.equal("addJob"); | ||
} | ||
}); | ||
it("should reject with an error if adding fails but respect existing error data", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.queue.add = async () => { | ||
const error = new Error("Error adding job"); | ||
error.service = "otherService"; | ||
error.method = "otherMethod"; | ||
throw error; | ||
}; | ||
try { | ||
await jobQueue.addJob("test", { url: "test" }); | ||
} catch (error) { | ||
expect(error.message).to.equal("Error adding job"); | ||
expect(error.service).to.equal("otherService"); | ||
expect(error.method).to.equal("otherMethod"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding jobs shouldn't be a mirage.
The error cases for addJob
are handled, but let's ensure the job isn't partially added in failure scenarios to avoid any heavy arms.
Verify that the queue remains unchanged when addJob
fails.
it("should delete a job from the queue", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.getWorkerStats = sinon.stub().returns({ load: 1, jobs: [{}] }); | ||
jobQueue.scaleWorkers = sinon.stub(); | ||
const monitor = { _id: 1 }; | ||
const job = { data: monitor }; | ||
jobQueue.queue.jobs = [job]; | ||
await jobQueue.deleteJob(monitor); | ||
expect(jobQueue.queue.jobs.length).to.equal(0); | ||
expect(logger.info.calledOnce).to.be.true; | ||
expect(jobQueue.getWorkerStats.calledOnce).to.be.true; | ||
expect(jobQueue.scaleWorkers.calledOnce).to.be.true; | ||
}); | ||
it("should log an error if job is not found", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.getWorkerStats = sinon.stub().returns({ load: 1, jobs: [{}] }); | ||
jobQueue.scaleWorkers = sinon.stub(); | ||
const monitor = { _id: 1 }; | ||
const job = { data: monitor }; | ||
jobQueue.queue.jobs = [job]; | ||
await jobQueue.deleteJob({ id_: 2 }); | ||
expect(logger.error.calledOnce).to.be.true; | ||
}); | ||
it("should reject with an error if removeRepeatable fails", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.queue.removeRepeatable = async () => { | ||
const error = new Error("removeRepeatable error"); | ||
throw error; | ||
}; | ||
|
||
try { | ||
await jobQueue.deleteJob({ _id: 1 }); | ||
} catch (error) { | ||
expect(error.message).to.equal("removeRepeatable error"); | ||
expect(error.service).to.equal("JobQueue"); | ||
expect(error.method).to.equal("deleteJob"); | ||
} | ||
}); | ||
it("should reject with an error if removeRepeatable fails but respect existing error data", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.queue.removeRepeatable = async () => { | ||
const error = new Error("removeRepeatable error"); | ||
error.service = "otherService"; | ||
error.method = "otherMethod"; | ||
throw error; | ||
}; | ||
|
||
try { | ||
await jobQueue.deleteJob({ _id: 1 }); | ||
} catch (error) { | ||
expect(error.message).to.equal("removeRepeatable error"); | ||
expect(error.service).to.equal("otherService"); | ||
expect(error.method).to.equal("otherMethod"); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Deleting jobs, let's not get robbed.
When deleting a job that isn't found, the error is logged, but perhaps we should notify the caller as well to avoid any weak knees.
Throw an error or return a status indicating the job wasn't found.
Modify deleteJob
to handle the not-found case more explicitly.
describe("obliterate", () => { | ||
it("should return true if obliteration is successful", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
jobQueue.queue.pause = async () => true; | ||
jobQueue.getJobs = async () => [{ key: 1, id: 1 }]; | ||
jobQueue.queue.removeRepeatableByKey = async () => true; | ||
jobQueue.queue.remove = async () => true; | ||
jobQueue.queue.obliterate = async () => true; | ||
const obliteration = await jobQueue.obliterate(); | ||
expect(obliteration).to.be.true; | ||
}); | ||
it("should throw an error if obliteration fails", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
|
||
jobQueue.getMetrics = async () => { | ||
throw new Error("Error"); | ||
}; | ||
|
||
try { | ||
await jobQueue.obliterate(); | ||
} catch (error) { | ||
expect(error.service).to.equal("JobQueue"); | ||
expect(error.method).to.equal("obliterate"); | ||
} | ||
}); | ||
it("should throw an error if obliteration fails but respect existing error data", async () => { | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
|
||
jobQueue.getMetrics = async () => { | ||
const error = new Error("Error"); | ||
error.service = "otherService"; | ||
error.method = "otherMethod"; | ||
throw error; | ||
}; | ||
|
||
try { | ||
await jobQueue.obliterate(); | ||
} catch (error) { | ||
expect(error.service).to.equal("otherService"); | ||
expect(error.method).to.equal("otherMethod"); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Obliterate with caution, no room for exhaustion.
The tests for obliterate
handle errors well, but ensuring that resources are properly cleaned up even when errors occur will keep us ready.
Ensure that partial obliterations don't leave lingering data.
Add cleanup steps or transaction mechanisms to maintain consistency.
import sinon from "sinon"; | ||
import JobQueue from "../../service/jobQueue.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hold on a minute, missing imports might make us lose the moment.
The test file imports JobQueue
from "../../service/jobQueue.js"
but doesn't include the necessary assertion library like chai
or expect
. Without importing these, we might let the opportunity slip.
Add the necessary import to ensure assertions work:
+import { expect } from 'chai';
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import sinon from "sinon"; | |
import JobQueue from "../../service/jobQueue.js"; | |
import sinon from "sinon"; | |
import { expect } from 'chai'; | |
import JobQueue from "../../service/jobQueue.js"; |
db.getMaintenanceWindowsByMonitorId.returns([ | ||
{ | ||
active: true, | ||
start: new Date(Date.now() - 10000).toISOString(), | ||
end: new Date(Date.now() + 5000).toISOString(), | ||
repeat: 10000, | ||
}, | ||
]); | ||
const jobQueue = await JobQueue.createJobQueue( | ||
db, | ||
networkService, | ||
settingsService, | ||
logger, | ||
QueueStub, | ||
WorkerStub | ||
); | ||
const worker = jobQueue.createWorker(); | ||
await worker.workerTask(); | ||
// expect(networkService.getStatus.calledOnce).to.be.false; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeating time, but is the rhyme sublime?
The test seems to comment out an expectation on line 205. If we don't assert, we might regret it later.
Uncomment and complete the assertion to ensure the test verifies the intended behavior.
-// expect(networkService.getStatus.calledOnce).to.be.false;
+expect(networkService.getStatus.calledOnce).to.be.false;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
db.getMaintenanceWindowsByMonitorId.returns([ | |
{ | |
active: true, | |
start: new Date(Date.now() - 10000).toISOString(), | |
end: new Date(Date.now() + 5000).toISOString(), | |
repeat: 10000, | |
}, | |
]); | |
const jobQueue = await JobQueue.createJobQueue( | |
db, | |
networkService, | |
settingsService, | |
logger, | |
QueueStub, | |
WorkerStub | |
); | |
const worker = jobQueue.createWorker(); | |
await worker.workerTask(); | |
// expect(networkService.getStatus.calledOnce).to.be.false; | |
}); | |
db.getMaintenanceWindowsByMonitorId.returns([ | |
{ | |
active: true, | |
start: new Date(Date.now() - 10000).toISOString(), | |
end: new Date(Date.now() + 5000).toISOString(), | |
repeat: 10000, | |
}, | |
]); | |
const jobQueue = await JobQueue.createJobQueue( | |
db, | |
networkService, | |
settingsService, | |
logger, | |
QueueStub, | |
WorkerStub | |
); | |
const worker = jobQueue.createWorker(); | |
await worker.workerTask(); | |
expect(networkService.getStatus.calledOnce).to.be.false; | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (1)
Client/src/Utils/NetworkService.js (1)
118-131
: Consider adding input validation for types array.The method handles array parameters well, but could benefit from input validation.
async getMonitorsAndSummaryByTeamId(config) { const params = new URLSearchParams(); if (config.types) { + if (!Array.isArray(config.types)) { + throw new TypeError('config.types must be an array'); + } config.types.forEach((type) => { + if (typeof type !== 'string') { + throw new TypeError('Each type must be a string'); + } params.append("type", type); }); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (4)
- Client/src/App.jsx (2 hunks)
- Client/src/Features/Settings/settingsSlice.js (1 hunks)
- Client/src/Utils/NetworkService.js (2 hunks)
- Server/tests/services/jobQueue.test.js (1 hunks)
✅ Files skipped from review due to trivial changes (1)
- Client/src/Features/Settings/settingsSlice.js
🚧 Files skipped from review as they are similar to previous changes (1)
- Server/tests/services/jobQueue.test.js
🔇 Additional comments (2)
Client/src/App.jsx (1)
39-39
: Yo, what's the connection to JobQueue tests?This change seems to be introducing app settings updates, but I'm not seeing how it relates to the PR's main objective of adding JobQueue tests. Could you help me understand the connection?
Let's check if there are any JobQueue-related changes in the settings:
Client/src/Utils/NetworkService.js (1)
91-116
: LGTM: Well-structured endpoint resolution implementation.The
checkEndpointResolution
method is well-implemented with:
- Clear JSDoc documentation
- Proper parameter handling
- Secure authorization headers
useEffect(() => { | ||
const thing = async () => { | ||
const action = await dispatch( | ||
updateAppSettings({ authToken, settings: { apiBaseUrl: "test" } }) | ||
); | ||
|
||
if (action.payload.success) { | ||
console.log(action.payload.data); | ||
} else { | ||
console.log(action); | ||
} | ||
}; | ||
thing(); | ||
}, [dispatch, authToken]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mom's spaghetti alert! 🍝 This code needs some cleanup
There's quite a bit to unpack here:
- The async function name 'thing' is about as clear as my grandma's cloudy glasses
- We've got a hardcoded "test" value that's more suspicious than a $3 bill
- Those console.logs are hanging around like that one friend who doesn't get the party's over
- Error handling is weaker than my knees right now
Here's a cleaner implementation:
useEffect(() => {
- const thing = async () => {
+ const updateSettings = async () => {
+ try {
const action = await dispatch(
- updateAppSettings({ authToken, settings: { apiBaseUrl: "test" } })
+ updateAppSettings({ authToken, settings: { apiBaseUrl: process.env.REACT_APP_API_BASE_URL } })
);
- if (action.payload.success) {
- console.log(action.payload.data);
- } else {
- console.log(action);
+ if (!action.payload.success) {
+ logger.error('Failed to update app settings:', action.payload);
}
+ } catch (error) {
+ logger.error('Error updating app settings:', error);
+ }
};
- thing();
+ if (authToken) {
+ updateSettings();
+ }
}, [dispatch, authToken]);
Committable suggestion was skipped due to low confidence.
@@ -13,6 +13,7 @@ class NetworkService { | |||
this.setBaseUrl(baseURL); | |||
this.unsubscribe = store.subscribe(() => { | |||
const state = store.getState(); | |||
console.log(state.settings.apiBaseUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or guard the sensitive URL logging statement.
The logging of apiBaseUrl
could potentially expose sensitive information in logs. Consider removing this debug statement or guarding it behind a development-only flag.
-console.log(state.settings.apiBaseUrl);
+if (process.env.NODE_ENV === 'development') {
+ console.log('API Base URL:', state.settings.apiBaseUrl);
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
console.log(state.settings.apiBaseUrl); | |
if (process.env.NODE_ENV === 'development') { | |
console.log('API Base URL:', state.settings.apiBaseUrl); | |
} |
This PR adds tests for the
JobQueue
NetworkService
test suite