-
Notifications
You must be signed in to change notification settings - Fork 15
[DK TestAI] Add unit tests for requestHandlerLabel #693
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,246 @@ | ||
| import { requestHandlerLabel, UNNAMED_REQUEST_HANDLER } from './requestHandlerLabel' | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [general.broken-references] 🔵 SUGGEST The relative import './requestHandlerLabel' could not be resolved against the repository's current contents. Please double-check that the referenced module is part of this change set or already merged on the target branch. Action: Verify the import path resolves on the target branch, and run the test suite locally ( To dismiss: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Evolvability.Organizational] 🔵 SUGGEST The new test is placed as a sibling of the source module, while the existing convention in this package puts specs under src/service/metrics/tests/ (see clusterMetricsAggregator.test.ts). Mixing both layouts makes tests harder to locate and risks diverging jest Action: Move the file to src/service/metrics/tests/requestHandlerLabel.test.ts to match the existing layout, or confirm the jest config intentionally supports co-located specs. To dismiss: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Functional.Interface] 🔴 BLOCK The test file imports Action: Include To dismiss: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Functional.Support] 🔵 SUGGEST The test is placed at Action: Move the file to To dismiss: |
||
| describe('requestHandlerLabel', () => { | ||
| describe('UNNAMED_REQUEST_HANDLER constant', () => { | ||
| it('should be defined as the string "undefined"', () => { | ||
| // Arrange & Act & Assert | ||
| expect(UNNAMED_REQUEST_HANDLER).toBe('undefined') | ||
| }) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Evolvability.SolutionApproach] 🔵 SUGGEST Tests hardcode the literal 'undefined' for the fallback (line 7 and again at the end of the 'requestHandlerName is undefined' case), duplicating the exported constant they are meant to abstract. Changing UNNAMED_REQUEST_HANDLER to a safer sentinel (e.g. 'unnamed') would break tests for reasons unrelated to behaviour, and the assertion pair Action: Keep a single test that documents the constant's literal value, and assert only against To dismiss: |
||
|
|
||
| it('should be a non-empty string', () => { | ||
| // Arrange & Act & Assert | ||
| expect(typeof UNNAMED_REQUEST_HANDLER).toBe('string') | ||
| expect(UNNAMED_REQUEST_HANDLER.length).toBeGreaterThan(0) | ||
| }) | ||
| }) | ||
|
|
||
| describe('requestHandlerLabel function', () => { | ||
| describe('happy path - defined handler names', () => { | ||
| it('should return the provided handler name when a non-empty string is given', () => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Evolvability.Organizational] 🔵 SUGGEST Large blocks of the suite are duplicated assertions that add no branch coverage over a pure one-line fallback: five 'happy path' cases plus five 'edge case' cases all exercise the same identity return, the 'consistency and determinism' block re-invokes a stateless pure function three times, and the 'type safety' block asserts Action: Collapse the repeated pass-through cases into a single To dismiss: |
||
| // Arrange | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Evolvability.Organizational] 🔵 SUGGEST The 'happy path' and 'edge cases' blocks contain ~10 near-identical tests ('getUser', 'listItems', 'api:v1/getUserById', 'handle_user_v2_request', 'list-active-users', 'a', '000handler', '/api/v1.0/endpoint') that all exercise the same single pass-through branch, plus a 'consistency and determinism' block asserting a pure function is deterministic and a 'type safety' block re-asserting Action: Collapse the pass-through cases into a single To dismiss: |
||
| const handlerName = 'getUser' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('getUser') | ||
| }) | ||
|
|
||
| it('should return handler name for a simple route', () => { | ||
| // Arrange | ||
| const handlerName = 'listItems' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('listItems') | ||
| }) | ||
|
|
||
| it('should return handler name with special characters', () => { | ||
| // Arrange | ||
| const handlerName = 'api:v1/getUserById' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('api:v1/getUserById') | ||
| }) | ||
|
|
||
| it('should return handler name with numbers and underscores', () => { | ||
| // Arrange | ||
| const handlerName = 'handle_user_v2_request' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('handle_user_v2_request') | ||
| }) | ||
|
|
||
| it('should return handler name with hyphens', () => { | ||
| // Arrange | ||
| const handlerName = 'list-active-users' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('list-active-users') | ||
| }) | ||
| }) | ||
|
|
||
| describe('fallback to UNNAMED_REQUEST_HANDLER', () => { | ||
| it('should return UNNAMED_REQUEST_HANDLER when requestHandlerName is undefined', () => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Functional.Check] 🔵 SUGGEST The fallback suite covers Action: Add a case asserting the behaviour for To dismiss: |
||
| // Arrange | ||
| const handlerName = undefined | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe(UNNAMED_REQUEST_HANDLER) | ||
| expect(result).toBe('undefined') | ||
| }) | ||
|
|
||
| it('should return UNNAMED_REQUEST_HANDLER when no argument is provided', () => { | ||
| // Arrange & Act | ||
| const result = requestHandlerLabel() | ||
|
|
||
| // Assert | ||
| expect(result).toBe(UNNAMED_REQUEST_HANDLER) | ||
| }) | ||
|
|
||
| it('should return UNNAMED_REQUEST_HANDLER when an empty string is provided', () => { | ||
| // Arrange | ||
| const handlerName = '' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe(UNNAMED_REQUEST_HANDLER) | ||
| }) | ||
| }) | ||
|
|
||
| describe('edge cases and boundary values', () => { | ||
| it('should return a string with only whitespace as the handler name', () => { | ||
| // Arrange | ||
| const handlerName = ' ' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe(' ') | ||
| expect(result).not.toBe(UNNAMED_REQUEST_HANDLER) | ||
| }) | ||
|
|
||
| it('should return a string with a single space character as the handler name', () => { | ||
| // Arrange | ||
| const handlerName = ' ' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe(' ') | ||
| }) | ||
|
|
||
| it('should return a single character handler name', () => { | ||
| // Arrange | ||
| const handlerName = 'a' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('a') | ||
| }) | ||
|
|
||
| it('should return a very long handler name', () => { | ||
| // Arrange | ||
| const handlerName = 'a'.repeat(1000) | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe(handlerName) | ||
| expect(result.length).toBe(1000) | ||
| }) | ||
|
|
||
| it('should return handler name with leading zeros', () => { | ||
| // Arrange | ||
| const handlerName = '000handler' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('000handler') | ||
| }) | ||
|
|
||
| it('should return handler name with dots and slashes', () => { | ||
| // Arrange | ||
| const handlerName = '/api/v1.0/endpoint' | ||
|
|
||
| // Act | ||
| const result = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result).toBe('/api/v1.0/endpoint') | ||
| }) | ||
| }) | ||
|
|
||
| describe('consistency and determinism', () => { | ||
| it('should return the same value on repeated calls with the same input', () => { | ||
| // Arrange | ||
| const handlerName = 'consistentHandler' | ||
|
|
||
| // Act | ||
| const result1 = requestHandlerLabel(handlerName) | ||
| const result2 = requestHandlerLabel(handlerName) | ||
| const result3 = requestHandlerLabel(handlerName) | ||
|
|
||
| // Assert | ||
| expect(result1).toBe(result2) | ||
| expect(result2).toBe(result3) | ||
| }) | ||
|
|
||
| it('should return UNNAMED_REQUEST_HANDLER consistently for undefined inputs', () => { | ||
| // Arrange & Act | ||
| const result1 = requestHandlerLabel(undefined) | ||
| const result2 = requestHandlerLabel() | ||
| const result3 = requestHandlerLabel(undefined) | ||
|
|
||
| // Assert | ||
| expect(result1).toBe(result2) | ||
| expect(result2).toBe(result3) | ||
| expect(result1).toBe(UNNAMED_REQUEST_HANDLER) | ||
| }) | ||
|
|
||
| it('should return UNNAMED_REQUEST_HANDLER consistently for empty strings', () => { | ||
| // Arrange & Act | ||
| const result1 = requestHandlerLabel('') | ||
| const result2 = requestHandlerLabel('') | ||
|
|
||
| // Assert | ||
| expect(result1).toBe(result2) | ||
| expect(result1).toBe(UNNAMED_REQUEST_HANDLER) | ||
| }) | ||
| }) | ||
|
|
||
| describe('type safety', () => { | ||
| it('should return a string type', () => { | ||
| // Arrange & Act | ||
| const result = requestHandlerLabel('test') | ||
|
|
||
| // Assert | ||
| expect(typeof result).toBe('string') | ||
| }) | ||
|
|
||
| it('should return a string type even when undefined is passed', () => { | ||
| // Arrange & Act | ||
| const result = requestHandlerLabel(undefined) | ||
|
|
||
| // Assert | ||
| expect(typeof result).toBe('string') | ||
| }) | ||
|
|
||
| it('should always return a non-empty string', () => { | ||
| // Arrange & Act | ||
| const result1 = requestHandlerLabel('handler') | ||
| const result2 = requestHandlerLabel('') | ||
| const result3 = requestHandlerLabel(undefined) | ||
|
|
||
| // Assert | ||
| expect(result1.length).toBeGreaterThan(0) | ||
| expect(result2.length).toBeGreaterThan(0) | ||
| expect(result3.length).toBeGreaterThan(0) | ||
| }) | ||
| }) | ||
| }) | ||
| }) | ||
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.
[Functional.Support] 🔴 BLOCK
The test file imports
requestHandlerLabelandUNNAMED_REQUEST_HANDLERfrom './requestHandlerLabel', but no such module exists in src/service/metrics/ (the directory contains only client.ts, clusterMetricsAggregator.ts, metrics.ts, otelRequestMetricsMiddleware.ts and requestMetricsMiddleware.ts), and this PR adds no implementation file. The suite will fail to compile and the build/CI will break.Action: Include src/service/metrics/requestHandlerLabel.ts (exporting
requestHandlerLabelandUNNAMED_REQUEST_HANDLER) in this PR, or point the import at the module that actually holds this helper before merging.Source: https://github.com/vtex/node-vtex-api/tree/master/src/service/metrics
To dismiss:
/dk-review dismiss 3f8c1a92-6d47-4b0e-9c15-72ae4d0b8f31 [reason]