-
Notifications
You must be signed in to change notification settings - Fork 113
chore: drop sinon as devDep: all mocks are now through nock. #173
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
Conversation
WalkthroughDocumentation updated ( Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Test as Mocha Test
participant Client as Strava Client
participant Nock as Nock (HTTP Mock)
Note over Test,Nock: Tests use async/await and nock for HTTP interception
Test->>Client: await strava.method(args)
Client->>Nock: HTTP request (Authorization when expected)
Nock-->>Client: mocked response (200/401/204/...)
Client-->>Test: Promise resolves/rejects with parsed payload
rect rgba(200,230,255,0.6)
Note over Client: Upload flow (polled)
Test->>Client: await strava.uploads.create(gpx)
Client->>Nock: POST /api/v3/uploads
Nock-->>Client: { id_str, status }
loop poll until complete
Client->>Nock: GET /api/v3/uploads/:id
Nock-->>Client: status update (processing/completed)
end
Client-->>Test: final upload status
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
README.md(2 hunks)package.json(0 hunks)test/_helper.js(0 hunks)test/activities.js(3 hunks)
💤 Files with no reviewable changes (2)
- package.json
- test/_helper.js
🧰 Additional context used
🧬 Code graph analysis (1)
test/activities.js (3)
test/oauth.js (3)
nock(5-5)strava(4-4)payload(66-66)index.js (2)
require(18-18)strava(21-21)lib/oauth.js (1)
require(2-2)
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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
test/client.js(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/client.js (2)
test/oauth.js (4)
should(1-1)nock(5-5)strava(4-4)payload(66-66)index.js (2)
require(18-18)strava(21-21)
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: 1
🧹 Nitpick comments (3)
test/activities.js (3)
8-11: Assert mocks are consumed and prevent accidental live network.
- Add nock.isDone() verification to catch unconsumed interceptors.
- Disable outbound network in this suite and restore afterward to guard against real calls.
Apply this diff:
before(function () { // Set a default test activity to use in tests testActivity = { id: 123456789, resource_state: 3, name: 'Sample Activity' } + // Prevent accidental live network in this suite (restored in `after`) + nock.disableNetConnect() }) - afterEach(function () { - // Clean all nock interceptors after each test - nock.cleanAll() - }) + afterEach(function () { + // Assert all expected HTTP mocks were used + const done = nock.isDone() + const pending = done ? [] : nock.pendingMocks() + nock.cleanAll() + if (!done) { + throw new Error('Not all expected HTTP mocks were called: ' + pending.join(', ')) + } + }) + + after(function () { + // Restore network behavior for other suites + nock.enableNetConnect() + })Also applies to: 13-16
50-66: Avoid inter-test coupling on testActivity.id.These tests depend on the prior create() test mutating testActivity. Prefer per-test known IDs or reset state in a beforeEach to make tests independent.
68-83: Duplicate of the previous get() test.This repeats the same Promise flow and assertions. Consider removing to keep the suite lean.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
test/activities.js(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/activities.js (2)
test/client.js (4)
nock(3-3)require(4-4)strava(5-5)should(2-2)test/oauth.js (4)
nock(5-5)strava(4-4)payload(66-66)should(1-1)
🔇 Additional comments (5)
test/activities.js (5)
2-2: Adopting nock for HTTP mocking looks good.Import and usage are consistent with the new mocking approach.
85-100: Good verification of explicit token handling.Precise header match ensures access_token passthrough is tested.
111-120: Update flow mock and assertions look correct.Covers both resource_state and name.
Also applies to: 121-125
28-41: Nice end-to-end create() mock. Consider stabilizing token source.Right now, most tests match any Bearer token. To make tests fully self-contained, either:
- pass an explicit access_token in the call and match exactly in nock, or
- seed STRAVA_ACCESS_TOKEN only when unset and restore it after (suite-level).
If you prefer the env approach, verify whether any suite already sets STRAVA_ACCESS_TOKEN. You can run:
#!/bin/bash # Inspect tests for env token handling rg -n -C2 -g '!**/node_modules/**' -P 'process\.env\.STRAVA_ACCESS_TOKEN' testAlso applies to: 42-47
170-178: LGTM on laps/comments/kudos mocks.Clean, minimal responses with header checks; combined with the isDone() assertion, these will be reliable.
Also applies to: 179-183, 187-194, 195-199, 205-210, 211-215
|
I think Code Rabbit flagged a real bug here, which is that we have docs and a code comment that says we reject non-2xx responses with an error of type StatusCodeError, but it appears we don't actually do so... but it's not as simple a fix as just starting to do so, because we also have code about updating rate limits... which suggests in fact maybe there are some rate-limited HTTP response codes which we should maybe also treat as success instead of a status code error? Also, now we have >50% of the test suite running without a live Strava API key, which means we could set up Github Actions to have it at at least run the tests that pass with mocks, then we can continue to work on mock'ing the API until we can run 100% of the test suite on mocks. Mocks have their downsides, but the reality is that often now we don't run the tests at all due to the live API key requirement. I think with Nock there may be a way that once we are completely mocked, there may a way we can enable people to disable all the mocks globally and use a real API key if they want to. |
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: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
test/client.js(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/client.js (1)
test/oauth.js (4)
should(1-1)nock(5-5)strava(4-4)payload(66-66)
🪛 Biome (2.1.2)
test/client.js
[error] 76-76: Expected a catch clause but instead found ')'.
Expected a catch clause here.
(parse)
[error] 78-78: expected a name for the function in a function declaration, but found none
(parse)
🔇 Additional comments (5)
test/client.js (5)
7-9: LGTM!Explicit test tokens improve test isolation and eliminate file system dependencies.
12-15: LGTM!The
afterEachhook withnock.cleanAll()ensures proper cleanup of HTTP mocks between tests, preventing test interference.
20-35: LGTM!The test correctly verifies that non-2xx responses are rejected with
StatusCodeError. Theshould.fail()guard on Line 30 ensures the test cannot false-pass if the rejection doesn't occur.
37-56: LGTM!The test correctly mocks a successful athlete data retrieval and validates the response payload structure.
78-99: LGTM once the syntax error is fixed.This test correctly validates successful athlete data retrieval with a different mock response. It will function properly once the duplicate
trystatement on Line 67 is removed.
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: 0
🧹 Nitpick comments (2)
test/activities.js (2)
68-83: Remove redundant promise-based test.Both
#get()tests now use the same promise-based pattern after the Sinon-to-nock migration. The "(Promise API)" label is misleading since both tests are promise-based. Consider removing this duplicate test to reduce maintenance overhead.
19-215: Consider verifying nock interceptors were used.While the tests correctly clean up nock with
cleanAll(), they don't verify that all mocked requests were actually made. Callingscope.done()after each test assertion helps catch scenarios where expected HTTP calls never occurred.Based on learnings
Example pattern for one test:
it('should create an activity', function () { var args = { name: 'Most Epic Ride EVER!!!', elapsed_time: 18373, distance: 1557840, start_date_local: '2013-10-23T10:02:13Z', type: 'Ride' } // Mock the create activity API call - nock('https://www.strava.com') + const scope = nock('https://www.strava.com') .post('/api/v3/activities') .matchHeader('authorization', /Bearer .+/) .reply(201, { id: 987654321, resource_state: 3, name: 'Most Epic Ride EVER!!!', elapsed_time: 18373, distance: 1557840, start_date_local: '2013-10-23T10:02:13Z', type: 'Ride' }) return strava.activities.create(args) .then(function (payload) { testActivity = payload; (payload.resource_state).should.be.exactly(3) + scope.done() }) })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
test/activities.js(3 hunks)
🔇 Additional comments (1)
test/activities.js (1)
8-16: LGTM! Proper test setup and cleanup.The before hook initializes a concrete test activity, and the afterEach hook correctly cleans up nock interceptors between tests.
|
@wesleyschlenker I get failures here for the athletes tests. Do they pass for you? |
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: 0
🧹 Nitpick comments (5)
test/client.js (5)
12-15: Consider strengthening mock isolation with network controls.The
afterEachcleanup is good, but tests could accidentally hit the real Strava API if nock mocks fail to match requests.Add
nock.disableNetConnect()in abeforeEachhook to ensure tests never make real network calls:describe('client_test', function () { + beforeEach(() => { + // Prevent any real network requests + nock.disableNetConnect() + }) + afterEach(() => { // Clean up after each test nock.cleanAll() })Based on learnings: "Use nock.disableNetConnect() to ensure tests never make real network calls" and "Keep mocks isolated per-test and call nock.cleanAll() in test teardown."
20-35: Verify mock consumption to catch test logic errors.The test correctly asserts error behavior, but doesn't verify the nock mock was actually consumed. If the mock fails to match, the test might hit unexpected code paths.
Capture the nock scope and verify it was consumed:
it('Should reject promise with StatusCodeError for non-2xx response', async function () { // Mock athlete endpoint for BAD token -> 401 - nock('https://www.strava.com') + const scope = nock('https://www.strava.com') .get('/api/v3/athlete') .matchHeader('authorization', 'Bearer ' + BAD_TOKEN) .reply(401, { message: 'Authorization Error', errors: [{ resource: 'Application', code: 'invalid' }] }) const badClient = new strava.client(BAD_TOKEN) try { await badClient.athlete.get({}) should.fail('Expected athlete.get to reject with StatusCodeError') } catch (err) { should(err).be.instanceOf(StatusCodeError) should(err.statusCode).equal(401) } + + // Verify the mock was consumed + scope.done() })Based on learnings: "Use scope.done() or nock.isDone() in teardown to assert expected requests were made."
37-56: Verify mock consumption for test correctness.Same issue: without verifying the mock was consumed, the test could pass even if the mock wasn't used as expected.
Apply this pattern:
it('should return detailed athlete information about athlete associated to access_token', function () { // Mock athlete endpoint for GOOD token -> 200 - nock('https://www.strava.com') + const scope = nock('https://www.strava.com') .get('/api/v3/athlete') .matchHeader('authorization', 'Bearer ' + GOOD_TOKEN) .reply(200, { resource_state: 3, id: 12345, firstname: 'Test', lastname: 'User' }) const client = new strava.client(GOOD_TOKEN) return client.athlete.get({}) .then((payload) => { should(payload).be.ok() should(payload.resource_state).equal(3) should(payload.id).equal(12345) + + // Verify the mock was consumed + scope.done() }) })
58-75: Verify mock consumption.it('Should reject promise with StatusCodeError when using bad token', async function () { // Mock athlete endpoint for BAD token -> 401 // Testing with a second interceptor to ensure nock works correctly - nock('https://www.strava.com') + const scope = nock('https://www.strava.com') .get('/api/v3/athlete') .matchHeader('authorization', 'Bearer ' + BAD_TOKEN) .reply(401, { message: 'Authorization Error' }) const badClient = new strava.client(BAD_TOKEN) try { await badClient.athlete.get({}) should.fail('Expected athlete.get to reject with StatusCodeError') } catch (err) { should(err).be.instanceOf(StatusCodeError) should(err.statusCode).equal(401) should(err.data.message).equal('Authorization Error') } + + scope.done() })
77-98: Verify mock consumption.it('Should successfully return athlete data with valid token', function () { // Mock athlete endpoint for GOOD token -> 200 // Testing a second successful request to verify client instances work correctly - nock('https://www.strava.com') + const scope = nock('https://www.strava.com') .get('/api/v3/athlete') .matchHeader('authorization', 'Bearer ' + GOOD_TOKEN) .reply(200, { resource_state: 3, id: 67890, firstname: 'Another', lastname: 'Athlete' }) const client = new strava.client(GOOD_TOKEN) return client.athlete.get({}) .then((payload) => { should(payload).be.ok() should(payload.resource_state).equal(3) should(payload.id).equal(67890) should(payload.firstname).equal('Another') + + scope.done() }) })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
test/_helper.js(1 hunks)test/client.js(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-26T14:09:38.947Z
Learnt from: markstos
PR: node-strava/node-strava-v3#173
File: README.md:390-392
Timestamp: 2025-09-26T14:09:38.947Z
Learning: The node-strava-v3 repository contains a script at `scripts/generate-access-token.js` that helps users generate access tokens for testing purposes.
Applied to files:
test/_helper.js
🧬 Code graph analysis (1)
test/client.js (1)
test/oauth.js (4)
should(1-1)nock(5-5)strava(4-4)payload(66-66)
🔇 Additional comments (3)
test/client.js (2)
2-3: LGTM! Proper imports for nock-based testing.The addition of
shouldandnockimports supports the migration to promise-based mocking.
7-9: LGTM! Explicit test tokens improve test clarity.Using explicit token constants instead of file-based loading makes tests more isolated and easier to understand.
test/_helper.js (1)
1-1: LGTM! Clean migration from file-based token loading; no remaining getAccessToken() references in test files.
|
The Code Rabbit "nitpick" feedback here looks like a good quality improvement. |
|
@markstos I get failures starting in the I hadn't realized you've assigned this PR to me, so I will try to carve out some time later. |
|
The tests should pass on this branch are the ones that are modified and mocked, which are test/client.js and test/actitivites.js, but I currently get test failures in the client test. Looks like we are now throwing errors a different way that the test suite is not expecting. |
Also, remove dead test function for getting an access token.
- Added Wesley Schlenker to the list of contributors. - Updated README to reflect the use of `yarn test` instead of `npm test` for running the test suite.
So no live Strava API key is required.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
And from reading the Changelog, it's not clear it ever existed.
This endpoint does not exist.
- There is no "types" field - The BaseStream includes original_size, resolution and series_type Ref: https://developers.strava.com/docs/reference/#api-models-BaseStream
Mocks are based on sample API responses documented by Strava. Now we can readily run tests locally and via CI. - four devDeps are no longer needed: - sinon, env-restorer, should, mock-fs - Add CI workflow to start running tests for every PR - Process found several places where tests and code were out sync with current API, so tests, code or README were updated as needed.
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
♻️ Duplicate comments (1)
test/activities.js (1)
9-14: Implement token preservation in setupMockAuth and cleanupAuth.The verification reveals that
testHelper.setupMockAuth()does not implement the save/restore pattern forSTRAVA_ACCESS_TOKEN. The current implementation directly sets hardcoded test values without saving the original token, andcleanupAuth()only callsauthenticator.purge()without restoring it. This will clobber any existing token for integration tests.Update
test/_helper.jsto:
- Save the original
STRAVA_ACCESS_TOKENenvironment variable insetupMockAuth()- Restore it in
cleanupAuth()after purging
🧹 Nitpick comments (3)
.github/workflows/on-pull-request.yml (1)
31-33: Consider removingcontinue-on-erroronce tests are stable.While
continue-on-error: trueallows the workflow to proceed despite test failures, it prevents CI from catching regressions. Given the PR comments mention ongoing test failures, this may be intentional for incremental rollout, but it should be removed once the test suite is fully stabilized.Would you like me to help track which tests are still failing so you can prioritize fixing them before removing this flag?
test/athletes.js (1)
7-17: Consider aligning setup/teardown pattern with other test files.This file uses
before/afterfor auth setup/cleanup, while other migrated test files (e.g., test/clubs.js, test/uploads.js, test/segments.js) usebeforeEach/afterEachfor both nock and auth. For consistency and to ensure test isolation, consider usingbeforeEach/afterEachhere as well.Apply this diff for consistency:
- before(function () { + beforeEach(function () { testHelper.setupMockAuth() }) afterEach(function () { nock.cleanAll() + testHelper.cleanupAuth() }) - after(function () { - testHelper.cleanupAuth() - })test/activities.js (1)
152-165: Skipped tests for premium features are appropriately marked.The
listZonesandlistPhotostests remain skipped (xit) as they require premium accounts. This is fine for now, but consider adding mocked versions of these tests to verify the API client code paths work correctly, even if you can't test against the live API.If you'd like, I can help generate mocked versions of these tests that would at least verify the client code handles the endpoints correctly.
Also applies to: 212-225
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (26)
.github/workflows/on-pull-request.yml(1 hunks)README.md(3 hunks)axiosUtility.js(1 hunks)lib/athlete.js(0 hunks)lib/athletes.js(0 hunks)lib/httpClient.js(1 hunks)lib/streams.js(2 hunks)lib/uploads.js(1 hunks)package.json(2 hunks)test/_helper.js(2 hunks)test/activities.js(4 hunks)test/athlete.js(1 hunks)test/athletes.js(1 hunks)test/authenticator.js(1 hunks)test/client.js(1 hunks)test/clubs.js(1 hunks)test/config.js(2 hunks)test/gear.js(1 hunks)test/oauth.js(3 hunks)test/pushSubscriptions.js(3 hunks)test/rateLimiting.js(3 hunks)test/routes.js(1 hunks)test/segmentEfforts.js(1 hunks)test/segments.js(1 hunks)test/streams.js(1 hunks)test/uploads.js(1 hunks)
💤 Files with no reviewable changes (2)
- lib/athlete.js
- lib/athletes.js
✅ Files skipped from review due to trivial changes (1)
- lib/uploads.js
🚧 Files skipped from review as they are similar to previous changes (1)
- README.md
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-26T14:09:38.947Z
Learnt from: markstos
Repo: node-strava/node-strava-v3 PR: 173
File: README.md:390-392
Timestamp: 2025-09-26T14:09:38.947Z
Learning: The node-strava-v3 repository contains a script at `scripts/generate-access-token.js` that helps users generate access tokens for testing purposes.
Applied to files:
test/oauth.jstest/client.jstest/authenticator.jstest/activities.jstest/_helper.jstest/config.js
📚 Learning: 2025-09-25T18:49:53.763Z
Learnt from: wesleyschlenker
Repo: node-strava/node-strava-v3 PR: 172
File: package.json:34-49
Timestamp: 2025-09-25T18:49:53.763Z
Learning: ESLint v8.57.1 can work with eslint-config-standard v12.0.0 in the node-strava-v3 project, despite theoretical version incompatibility warnings.
Applied to files:
package.json
🧬 Code graph analysis (10)
test/uploads.js (2)
lib/uploads.js (1)
require(1-1)test/_helper.js (2)
strava(1-1)payload(63-63)
test/athletes.js (1)
test/_helper.js (2)
strava(1-1)payload(63-63)
test/streams.js (3)
test/activities.js (4)
assert(1-1)strava(3-3)nock(2-2)testHelper(4-4)test/routes.js (4)
assert(1-1)strava(2-2)nock(3-3)testHelper(4-4)test/_helper.js (1)
strava(1-1)
test/athlete.js (4)
test/activities.js (4)
assert(1-1)strava(3-3)nock(2-2)testHelper(4-4)test/athletes.js (4)
assert(1-1)strava(2-2)nock(3-3)testHelper(4-4)test/clubs.js (4)
assert(1-1)strava(2-2)nock(3-3)testHelper(4-4)test/_helper.js (1)
strava(1-1)
test/routes.js (1)
test/_helper.js (2)
strava(1-1)payload(63-63)
lib/httpClient.js (1)
axiosUtility.js (1)
response(39-51)
test/rateLimiting.js (2)
index.js (2)
require(17-17)rateLimiting(14-14)lib/httpClient.js (1)
rateLimiting(5-5)
test/_helper.js (3)
test/config.js (1)
authenticator(3-3)index.js (2)
require(17-17)authenticator(3-3)test/authenticator.js (1)
authenticator(2-2)
test/config.js (4)
test/activities.js (1)
assert(1-1)test/authenticator.js (2)
assert(1-1)authenticator(2-2)test/oauth.js (2)
assert(1-1)authenticator(2-2)index.js (2)
require(17-17)authenticator(3-3)
axiosUtility.js (2)
lib/httpClient.js (1)
options(40-45)lib/oauth.js (3)
options(50-60)options(71-81)options(107-118)
🪛 GitHub Actions: Test Suite
lib/streams.js
[error] 10-10: ESLint: Unexpected trailing comma. (comma-dangle)
🪛 GitHub Check: test (20.x)
lib/streams.js
[failure] 10-10:
Unexpected trailing comma
🪛 GitHub Check: test (22.x)
lib/streams.js
[failure] 10-10:
Unexpected trailing comma
🪛 Gitleaks (8.28.0)
test/oauth.js
[high] 83-83: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 86-86: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 92-92: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 95-95: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (32)
test/_helper.js (1)
6-17: LGTM! Clean test helper API.The new
setupMockAuth()andcleanupAuth()methods provide a clean, explicit way to manage test authentication state, aligning well with the migration to nock-based mocking and async/await patterns.test/config.js (1)
1-18: LGTM! Clean migration to assert.The migration from Should.js to Node's built-in
assertmodule is straightforward and maintains the same test semantics.axiosUtility.js (1)
50-50: LGTM! Explicit 2xx validation aligns with StatusCodeError handling.The explicit
validateStatuspredicate correctly enforces 2xx-only success whenoptions.simpleis notfalse, ensuring non-2xx responses trigger the error path that throwsStatusCodeError(lines 54-61).test/client.js (2)
7-15: LGTM! Clean test setup with explicit tokens and nock cleanup.The explicit token constants and
afterEachcleanup provide good test isolation, aligning well with the nock-based mocking approach.
20-37: LGTM! Proper error handling test with assert.fail guard.The test correctly verifies that non-2xx responses result in a
StatusCodeError, and theassert.fail()ensures the test won't silently pass if no error is thrown.test/gear.js (2)
7-17: LGTM! Proper test lifecycle with mock auth setup and cleanup.The
before/afterhooks correctly initialize and clean up mock authentication, whileafterEachensures nock interceptors are cleaned up between tests.
20-48: LGTM! Clean async test with nock-based mocking.The test properly mocks the HTTP request with authorization header validation and uses
assert.strictEqualfor clear, explicit assertions.test/rateLimiting.js (1)
2-78: LGTM! Thorough migration to assert with preserved test semantics.The migration from Should.js to Node's
assertmodule is comprehensive and maintains all test semantics. The explicitconst headersdeclarations andassert.strictEqualcomparisons make the tests more readable.test/uploads.js (2)
7-16: LGTM: Proper test isolation setup.The beforeEach/afterEach hooks correctly clean nock interceptors and manage mock authentication state, ensuring tests are properly isolated.
19-88: LGTM: Comprehensive upload flow test.The test properly simulates the multi-step polling sequence with three distinct API responses (initial upload, first status check, second status check) and verifies both the callback invocation count and final payload structure.
test/pushSubscriptions.js (2)
7-10: LGTM: Proper nock cleanup.The afterEach hook ensures interceptors are cleaned between tests, maintaining test isolation.
56-58: LGTM: Good defensive testing.The tests properly validate that the API throws when required parameters are missing, helping catch client-side errors early.
Also applies to: 102-104
test/clubs.js (2)
7-16: LGTM: Consistent test isolation pattern.The setup/teardown hooks follow the same pattern as other migrated test files, ensuring proper isolation and cleanup.
19-72: LGTM: Comprehensive club details test.The test validates multiple fields including activity_types array, admin/owner flags, and membership status, providing good coverage of the API response structure.
test/athletes.js (1)
20-139: LGTM: Comprehensive stats validation.The test thoroughly validates the structure of athlete stats, including all total categories (recent/ytd/all) and activity types (ride/run/swim), with both type checks and specific value assertions.
lib/streams.js (1)
42-44: LGTM: Cleaner query string handling.The refactored endpoint construction uses
getQSto build query parameters, which is more maintainable than the previous approach.test/authenticator.js (2)
8-36: LGTM: Thorough environment management.The setup/teardown properly saves, clears, and restores environment variables while also managing the authenticator cache, ensuring complete test isolation.
58-74: LGTM: Comprehensive console.log verification.The test properly validates both the return value (undefined) and the logging behavior when the client ID is missing, ensuring users receive appropriate feedback.
test/segments.js (2)
7-15: LGTM: Consistent test isolation.The setup/teardown pattern matches other migrated test files, ensuring proper cleanup and isolation.
179-219: LGTM: Thorough date range validation.The test properly validates that returned efforts fall within the specified date range, ensuring the API filtering works correctly.
package.json (1)
48-48: No action required—timeout reduction is appropriate.All HTTP-dependent tests use nock for mocking (client.js, uploads.js, streams.js). Tests without nock (rateLimiting.js, config.js, authenticator.js) test pure functions and configuration, requiring no network calls. The reduced 5-second timeout is safe for this fully-mocked test suite and aligns with the test infrastructure improvements mentioned in the PR.
test/routes.js (3)
1-17: LGTM: Clean test setup with proper isolation.The test lifecycle hooks correctly establish mock authentication and clean up nock interceptors between tests, ensuring test isolation.
19-64: LGTM: Comprehensive route test with thorough assertions.The test properly mocks the route endpoint with a complete data structure and validates both the response structure and data types.
66-146: LGTM: Export file tests validate XML structure appropriately.Both GPX and TCX export tests properly mock the responses with correct Content-Type headers and validate the presence of expected XML elements.
test/oauth.js (1)
1-99: LGTM: OAuth tests properly migrated to async/await with nock.The test suite comprehensively covers OAuth flows including deauthorization, token retrieval, and token refresh. The static analysis warnings about API keys on lines 83, 86, 92, and 95 are false positives—these are clearly mock tokens used only in test scenarios.
test/streams.js (1)
1-190: LGTM: Streams tests comprehensively validate data structures.The test suite properly validates all stream types (activity, effort, segment, route) with appropriate assertions for array structure and data presence. The use of
findandmapto validate specific stream types is a good pattern.test/segmentEfforts.js (1)
1-90: LGTM: Detailed segment effort test with comprehensive validation.The test properly validates nested data structures including segment details and athlete stats. The use of
before/afterinstead ofbeforeEach/afterEachis appropriate since there's only one test in this suite.test/athlete.js (1)
1-384: LGTM: Comprehensive athlete endpoint coverage with detailed mocks.The test suite thoroughly covers all athlete-related endpoints with realistic, detailed mock data. The listActivities test is particularly thorough with complete activity payloads. Good use of both simple field assertions and array structure validations.
test/activities.js (4)
21-50: LGTM: Activity creation test properly mocked.The test correctly mocks the POST endpoint and validates the response structure.
52-100: LGTM: Get activity tests cover multiple scenarios.Good coverage of the standard flow, Promise API, and explicit access token usage. All three variants properly validate authorization headers.
102-150: LGTM: Update tests validate both name and sport_type changes.Both update tests properly mock the PUT endpoint and validate the response fields match the updates.
167-210: LGTM: List operations properly test array responses.The tests for
listLaps,listComments, andlistKudoscorrectly mock their respective endpoints and validate array responses.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Test Results (Node 20.x)0 tests 0 ✅ 0s ⏱️ For more details on these parsing errors, see this check. Results for commit 4cfb1da. |
This saves us from future dependabot alerts about vulerable deps.
It does not appear to be used anywhere.
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: 1
🧹 Nitpick comments (2)
scripts/generate-access-token.js (2)
60-60: Useconstinstead ofvarfor variables that are not reassigned.Lines 60, 66, and 78 declare variables with
varthat are never reassigned. Modern JavaScript style prefersconstfor immutability.Apply this diff:
- var content = fs.readFileSync(stravaConfigTemplate) + const content = fs.readFileSync(stravaConfigTemplate)- var config = JSON.parse(content) + const config = JSON.parse(content)- var url = strava.oauth.getRequestAccessURL({ + const url = strava.oauth.getRequestAccessURL({Also applies to: 66-66, 78-78
88-89:rl.close()beforeprocess.exit()is redundant.
process.exit()terminates the process immediately, so the precedingrl.close()may not complete. Sinceprocess.exit()cleans up resources, the explicit close is unnecessary here.Apply this diff:
if (!code) { console.log('no code provided') - rl.close() process.exit() }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
package.json(2 hunks)scripts/generate-access-token.js(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-26T14:09:38.947Z
Learnt from: markstos
Repo: node-strava/node-strava-v3 PR: 173
File: README.md:390-392
Timestamp: 2025-09-26T14:09:38.947Z
Learning: The node-strava-v3 repository contains a script at `scripts/generate-access-token.js` that helps users generate access tokens for testing purposes.
Applied to files:
scripts/generate-access-token.js
📚 Learning: 2025-09-25T18:49:53.763Z
Learnt from: wesleyschlenker
Repo: node-strava/node-strava-v3 PR: 172
File: package.json:34-49
Timestamp: 2025-09-25T18:49:53.763Z
Learning: ESLint v8.57.1 can work with eslint-config-standard v12.0.0 in the node-strava-v3 project, despite theoretical version incompatibility warnings.
Applied to files:
package.json
🧬 Code graph analysis (1)
scripts/generate-access-token.js (1)
test/oauth.js (1)
url(29-31)
🔇 Additional comments (4)
scripts/generate-access-token.js (1)
92-104: LGTM: Error handling is well-structured.The try-catch blocks properly handle errors during token exchange, and the top-level catch ensures
rl.close()is called before exit. Good defensive coding.Also applies to: 106-110
package.json (3)
22-23: LGTM: Contributor list updated appropriately.
43-43: Verify nock version compatibility before upgrading.The latest nock version is 14.0.10, while the code uses 11.9.1. This represents a 2+ major version jump. Before upgrading, verify:
- Whether breaking changes exist between versions
- Whether the older version was intentionally pinned for compatibility
- Whether code changes are required for the newer version
If upgrading, test thoroughly to ensure mock behavior remains consistent.
46-46: Timeout reduction is appropriate; all tests use mocks.Code review confirms the 5000ms timeout is suitable. The test suite has been successfully migrated to mocked API calls via nock—all 18 test files use
.reply()patterns for HTTP mocking. The unmocked helper functions intest/_helper.js(getSampleActivity, getSampleClub, etc.) are unused legacy code and won't execute. Mocked tests complete well within 5 seconds, making the timeout reduction from 20000ms safe and aligned with the faster test execution.
wesleyschlenker
left a comment
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.
Looks good, works well. The release notes are going to be fun lol. I also noticed some eslint errors. Now that we have CI up and running, we should lint and add it to the workflow.
This started as a small, focused PR then snowballed as I worked on getting the tests to pass. Now what's included here includes:
After merging this, we should do a version bump and release.
Summary by CodeRabbit
Breaking Changes
Documentation
Chores
Tests