mirror of
https://github.com/SigNoz/signoz.git
synced 2026-04-28 14:40:32 +01:00
Compare commits
5 Commits
fix/recurr
...
nv/10890
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a6539bd80 | ||
|
|
7d2457d305 | ||
|
|
71351b2856 | ||
|
|
018c78f4ff | ||
|
|
31e2c1b585 |
56
.github/CODEOWNERS
vendored
56
.github/CODEOWNERS
vendored
@@ -52,49 +52,49 @@ go.mod @therealpandey
|
||||
|
||||
# Querier Owners
|
||||
|
||||
/pkg/querier/ @srikanthccv @therealpandey
|
||||
/pkg/variables/ @srikanthccv @therealpandey
|
||||
/pkg/types/querybuildertypes/ @srikanthccv @therealpandey
|
||||
/pkg/types/telemetrytypes/ @srikanthccv @therealpandey
|
||||
/pkg/querybuilder/ @srikanthccv @therealpandey
|
||||
/pkg/telemetrylogs/ @srikanthccv @therealpandey
|
||||
/pkg/telemetrymetadata/ @srikanthccv @therealpandey
|
||||
/pkg/telemetrymetrics/ @srikanthccv @therealpandey
|
||||
/pkg/telemetrytraces/ @srikanthccv @therealpandey
|
||||
/pkg/querier/ @srikanthccv
|
||||
/pkg/variables/ @srikanthccv
|
||||
/pkg/types/querybuildertypes/ @srikanthccv
|
||||
/pkg/types/telemetrytypes/ @srikanthccv
|
||||
/pkg/querybuilder/ @srikanthccv
|
||||
/pkg/telemetrylogs/ @srikanthccv
|
||||
/pkg/telemetrymetadata/ @srikanthccv
|
||||
/pkg/telemetrymetrics/ @srikanthccv
|
||||
/pkg/telemetrytraces/ @srikanthccv
|
||||
|
||||
# Metrics
|
||||
|
||||
/pkg/types/metrictypes/ @srikanthccv @therealpandey
|
||||
/pkg/types/metricsexplorertypes/ @srikanthccv @therealpandey
|
||||
/pkg/modules/metricsexplorer/ @srikanthccv @therealpandey
|
||||
/pkg/prometheus/ @srikanthccv @therealpandey
|
||||
/pkg/types/metrictypes/ @srikanthccv
|
||||
/pkg/types/metricsexplorertypes/ @srikanthccv
|
||||
/pkg/modules/metricsexplorer/ @srikanthccv
|
||||
/pkg/prometheus/ @srikanthccv
|
||||
|
||||
# APM
|
||||
|
||||
/pkg/types/servicetypes/ @srikanthccv @therealpandey
|
||||
/pkg/types/apdextypes/ @srikanthccv @therealpandey
|
||||
/pkg/modules/apdex/ @srikanthccv @therealpandey
|
||||
/pkg/modules/services/ @srikanthccv @therealpandey
|
||||
/pkg/types/servicetypes/ @srikanthccv
|
||||
/pkg/types/apdextypes/ @srikanthccv
|
||||
/pkg/modules/apdex/ @srikanthccv
|
||||
/pkg/modules/services/ @srikanthccv
|
||||
|
||||
# Dashboard
|
||||
|
||||
/pkg/types/dashboardtypes/ @srikanthccv @therealpandey
|
||||
/pkg/modules/dashboard/ @srikanthccv @therealpandey
|
||||
/pkg/types/dashboardtypes/ @srikanthccv
|
||||
/pkg/modules/dashboard/ @srikanthccv
|
||||
|
||||
# Rule/Alertmanager
|
||||
|
||||
/pkg/types/ruletypes/ @srikanthccv @therealpandey
|
||||
/pkg/types/alertmanagertypes @srikanthccv @therealpandey
|
||||
/pkg/alertmanager/ @srikanthccv @therealpandey
|
||||
/pkg/ruler/ @srikanthccv @therealpandey
|
||||
/pkg/modules/rulestatehistory/ @srikanthccv @therealpandey
|
||||
/pkg/types/rulestatehistorytypes/ @srikanthccv @therealpandey
|
||||
/pkg/types/ruletypes/ @srikanthccv
|
||||
/pkg/types/alertmanagertypes @srikanthccv
|
||||
/pkg/alertmanager/ @srikanthccv
|
||||
/pkg/ruler/ @srikanthccv
|
||||
/pkg/modules/rulestatehistory/ @srikanthccv
|
||||
/pkg/types/rulestatehistorytypes/ @srikanthccv
|
||||
|
||||
# Correlation-adjacent
|
||||
|
||||
/pkg/contextlinks/ @srikanthccv @therealpandey
|
||||
/pkg/types/parsertypes/ @srikanthccv @therealpandey
|
||||
/pkg/queryparser/ @srikanthccv @therealpandey
|
||||
/pkg/contextlinks/ @srikanthccv
|
||||
/pkg/types/parsertypes/ @srikanthccv
|
||||
/pkg/queryparser/ @srikanthccv
|
||||
|
||||
# AuthN / AuthZ Owners
|
||||
|
||||
|
||||
3
.github/workflows/integrationci.yaml
vendored
3
.github/workflows/integrationci.yaml
vendored
@@ -51,7 +51,6 @@ jobs:
|
||||
- role
|
||||
- rootuser
|
||||
- serviceaccount
|
||||
- querier_json_body
|
||||
- ttl
|
||||
sqlstore-provider:
|
||||
- postgres
|
||||
@@ -62,7 +61,7 @@ jobs:
|
||||
- 25.5.6
|
||||
- 25.12.5
|
||||
schema-migrator-version:
|
||||
- v0.144.3
|
||||
- v0.142.0
|
||||
postgres-version:
|
||||
- 15
|
||||
if: |
|
||||
|
||||
@@ -167,7 +167,7 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
azureCloudProviderModule := implcloudprovider.NewAzureCloudProvider(defStore)
|
||||
azureCloudProviderModule := implcloudprovider.NewAzureCloudProvider()
|
||||
cloudProvidersMap := map[cloudintegrationtypes.CloudProviderType]cloudintegration.CloudProviderModule{
|
||||
cloudintegrationtypes.CloudProviderTypeAWS: awsCloudProviderModule,
|
||||
cloudintegrationtypes.CloudProviderTypeAzure: azureCloudProviderModule,
|
||||
|
||||
@@ -2474,97 +2474,6 @@ components:
|
||||
- requiredMetricsCheck
|
||||
- endTimeBeforeRetention
|
||||
type: object
|
||||
InframonitoringtypesPodPhase:
|
||||
enum:
|
||||
- pending
|
||||
- running
|
||||
- succeeded
|
||||
- failed
|
||||
- unknown
|
||||
- ""
|
||||
type: string
|
||||
InframonitoringtypesPodRecord:
|
||||
properties:
|
||||
failedPodCount:
|
||||
type: integer
|
||||
meta:
|
||||
additionalProperties: {}
|
||||
nullable: true
|
||||
type: object
|
||||
pendingPodCount:
|
||||
type: integer
|
||||
podAge:
|
||||
format: int64
|
||||
type: integer
|
||||
podCPU:
|
||||
format: double
|
||||
type: number
|
||||
podCPULimit:
|
||||
format: double
|
||||
type: number
|
||||
podCPURequest:
|
||||
format: double
|
||||
type: number
|
||||
podMemory:
|
||||
format: double
|
||||
type: number
|
||||
podMemoryLimit:
|
||||
format: double
|
||||
type: number
|
||||
podMemoryRequest:
|
||||
format: double
|
||||
type: number
|
||||
podPhase:
|
||||
$ref: '#/components/schemas/InframonitoringtypesPodPhase'
|
||||
podUID:
|
||||
type: string
|
||||
runningPodCount:
|
||||
type: integer
|
||||
succeededPodCount:
|
||||
type: integer
|
||||
unknownPodCount:
|
||||
type: integer
|
||||
required:
|
||||
- podUID
|
||||
- podCPU
|
||||
- podCPURequest
|
||||
- podCPULimit
|
||||
- podMemory
|
||||
- podMemoryRequest
|
||||
- podMemoryLimit
|
||||
- podPhase
|
||||
- pendingPodCount
|
||||
- runningPodCount
|
||||
- succeededPodCount
|
||||
- failedPodCount
|
||||
- unknownPodCount
|
||||
- podAge
|
||||
- meta
|
||||
type: object
|
||||
InframonitoringtypesPods:
|
||||
properties:
|
||||
endTimeBeforeRetention:
|
||||
type: boolean
|
||||
records:
|
||||
items:
|
||||
$ref: '#/components/schemas/InframonitoringtypesPodRecord'
|
||||
nullable: true
|
||||
type: array
|
||||
requiredMetricsCheck:
|
||||
$ref: '#/components/schemas/InframonitoringtypesRequiredMetricsCheck'
|
||||
total:
|
||||
type: integer
|
||||
type:
|
||||
$ref: '#/components/schemas/InframonitoringtypesResponseType'
|
||||
warning:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5QueryWarnData'
|
||||
required:
|
||||
- type
|
||||
- records
|
||||
- total
|
||||
- requiredMetricsCheck
|
||||
- endTimeBeforeRetention
|
||||
type: object
|
||||
InframonitoringtypesPostableHosts:
|
||||
properties:
|
||||
end:
|
||||
@@ -2591,32 +2500,6 @@ components:
|
||||
- end
|
||||
- limit
|
||||
type: object
|
||||
InframonitoringtypesPostablePods:
|
||||
properties:
|
||||
end:
|
||||
format: int64
|
||||
type: integer
|
||||
filter:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5Filter'
|
||||
groupBy:
|
||||
items:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5GroupByKey'
|
||||
nullable: true
|
||||
type: array
|
||||
limit:
|
||||
type: integer
|
||||
offset:
|
||||
type: integer
|
||||
orderBy:
|
||||
$ref: '#/components/schemas/Querybuildertypesv5OrderBy'
|
||||
start:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- start
|
||||
- end
|
||||
- limit
|
||||
type: object
|
||||
InframonitoringtypesRequiredMetricsCheck:
|
||||
properties:
|
||||
missingMetrics:
|
||||
@@ -3050,8 +2933,8 @@ components:
|
||||
type: object
|
||||
PromotetypesWrappedIndex:
|
||||
properties:
|
||||
fieldDataType:
|
||||
$ref: '#/components/schemas/TelemetrytypesFieldDataType'
|
||||
column_type:
|
||||
type: string
|
||||
granularity:
|
||||
type: integer
|
||||
type:
|
||||
@@ -4613,184 +4496,6 @@ components:
|
||||
type: object
|
||||
Sigv4SigV4Config:
|
||||
type: object
|
||||
SpantypesFieldContext:
|
||||
enum:
|
||||
- attribute
|
||||
- resource
|
||||
type: string
|
||||
SpantypesGettableSpanMapperGroups:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroup'
|
||||
type: array
|
||||
required:
|
||||
- items
|
||||
type: object
|
||||
SpantypesPostableSpanMapper:
|
||||
properties:
|
||||
config:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperConfig'
|
||||
enabled:
|
||||
type: boolean
|
||||
field_context:
|
||||
$ref: '#/components/schemas/SpantypesFieldContext'
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- field_context
|
||||
- config
|
||||
type: object
|
||||
SpantypesPostableSpanMapperGroup:
|
||||
properties:
|
||||
category:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroupCategory'
|
||||
condition:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroupCondition'
|
||||
enabled:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- category
|
||||
- condition
|
||||
type: object
|
||||
SpantypesSpanMapper:
|
||||
properties:
|
||||
config:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperConfig'
|
||||
createdAt:
|
||||
format: date-time
|
||||
type: string
|
||||
createdBy:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
field_context:
|
||||
$ref: '#/components/schemas/SpantypesFieldContext'
|
||||
group_id:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
updatedAt:
|
||||
format: date-time
|
||||
type: string
|
||||
updatedBy:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- group_id
|
||||
- name
|
||||
- field_context
|
||||
- config
|
||||
- enabled
|
||||
type: object
|
||||
SpantypesSpanMapperConfig:
|
||||
properties:
|
||||
sources:
|
||||
items:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperSource'
|
||||
nullable: true
|
||||
type: array
|
||||
required:
|
||||
- sources
|
||||
type: object
|
||||
SpantypesSpanMapperGroup:
|
||||
properties:
|
||||
category:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroupCategory'
|
||||
condition:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroupCondition'
|
||||
createdAt:
|
||||
format: date-time
|
||||
type: string
|
||||
createdBy:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
orgId:
|
||||
type: string
|
||||
updatedAt:
|
||||
format: date-time
|
||||
type: string
|
||||
updatedBy:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- orgId
|
||||
- name
|
||||
- category
|
||||
- condition
|
||||
- enabled
|
||||
type: object
|
||||
SpantypesSpanMapperGroupCategory:
|
||||
type: object
|
||||
SpantypesSpanMapperGroupCondition:
|
||||
properties:
|
||||
attributes:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
resource:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
required:
|
||||
- attributes
|
||||
- resource
|
||||
type: object
|
||||
SpantypesSpanMapperOperation:
|
||||
enum:
|
||||
- move
|
||||
- copy
|
||||
type: string
|
||||
SpantypesSpanMapperSource:
|
||||
properties:
|
||||
context:
|
||||
$ref: '#/components/schemas/SpantypesFieldContext'
|
||||
key:
|
||||
type: string
|
||||
operation:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperOperation'
|
||||
priority:
|
||||
type: integer
|
||||
required:
|
||||
- key
|
||||
- context
|
||||
- operation
|
||||
- priority
|
||||
type: object
|
||||
SpantypesUpdatableSpanMapper:
|
||||
properties:
|
||||
config:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperConfig'
|
||||
enabled:
|
||||
nullable: true
|
||||
type: boolean
|
||||
field_context:
|
||||
$ref: '#/components/schemas/SpantypesFieldContext'
|
||||
type: object
|
||||
SpantypesUpdatableSpanMapperGroup:
|
||||
properties:
|
||||
condition:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroupCondition'
|
||||
enabled:
|
||||
nullable: true
|
||||
type: boolean
|
||||
name:
|
||||
nullable: true
|
||||
type: string
|
||||
type: object
|
||||
TelemetrytypesFieldContext:
|
||||
enum:
|
||||
- metric
|
||||
@@ -9533,487 +9238,6 @@ paths:
|
||||
summary: Updates my service account
|
||||
tags:
|
||||
- serviceaccount
|
||||
/api/v1/span_mapper_groups:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns all span attribute mapping groups for the authenticated
|
||||
org.
|
||||
operationId: ListSpanMapperGroups
|
||||
parameters:
|
||||
- explode: true
|
||||
in: query
|
||||
name: category
|
||||
schema:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroupCategory'
|
||||
style: deepObject
|
||||
- in: query
|
||||
name: enabled
|
||||
schema:
|
||||
nullable: true
|
||||
type: boolean
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/SpantypesGettableSpanMapperGroups'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: List span attribute mapping groups
|
||||
tags:
|
||||
- spanmapper
|
||||
post:
|
||||
deprecated: false
|
||||
description: Creates a new span attribute mapping group for the org.
|
||||
operationId: CreateSpanMapperGroup
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SpantypesPostableSpanMapperGroup'
|
||||
responses:
|
||||
"201":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapperGroup'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: Created
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"409":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Conflict
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Create a span attribute mapping group
|
||||
tags:
|
||||
- spanmapper
|
||||
/api/v1/span_mapper_groups/{groupId}:
|
||||
delete:
|
||||
deprecated: false
|
||||
description: Hard-deletes a mapping group and cascades to all its mappers.
|
||||
operationId: DeleteSpanMapperGroup
|
||||
parameters:
|
||||
- in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Delete a span attribute mapping group
|
||||
tags:
|
||||
- spanmapper
|
||||
patch:
|
||||
deprecated: false
|
||||
description: Partially updates an existing mapping group's name, condition,
|
||||
or enabled state.
|
||||
operationId: UpdateSpanMapperGroup
|
||||
parameters:
|
||||
- in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SpantypesUpdatableSpanMapperGroup'
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Update a span attribute mapping group
|
||||
tags:
|
||||
- spanmapper
|
||||
/api/v1/span_mapper_groups/{groupId}/span_mappers:
|
||||
get:
|
||||
deprecated: false
|
||||
description: Returns all mappers belonging to a mapping group.
|
||||
operationId: ListSpanMappers
|
||||
parameters:
|
||||
- in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/SpantypesGettableSpanMapperGroups'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: List span mappers for a group
|
||||
tags:
|
||||
- spanmapper
|
||||
post:
|
||||
deprecated: false
|
||||
description: Adds a new mapper to the specified mapping group.
|
||||
operationId: CreateSpanMapper
|
||||
parameters:
|
||||
- in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SpantypesPostableSpanMapper'
|
||||
responses:
|
||||
"201":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/SpantypesSpanMapper'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: Created
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"409":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Conflict
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Create a span mapper
|
||||
tags:
|
||||
- spanmapper
|
||||
/api/v1/span_mapper_groups/{groupId}/span_mappers/{mapperId}:
|
||||
delete:
|
||||
deprecated: false
|
||||
description: Hard-deletes a mapper from a mapping group.
|
||||
operationId: DeleteSpanMapper
|
||||
parameters:
|
||||
- in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: mapperId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Delete a span mapper
|
||||
tags:
|
||||
- spanmapper
|
||||
patch:
|
||||
deprecated: false
|
||||
description: Partially updates an existing mapper's field context, config, or
|
||||
enabled state.
|
||||
operationId: UpdateSpanMapper
|
||||
parameters:
|
||||
- in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: mapperId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SpantypesUpdatableSpanMapper'
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- ADMIN
|
||||
- tokenizer:
|
||||
- ADMIN
|
||||
summary: Update a span mapper
|
||||
tags:
|
||||
- spanmapper
|
||||
/api/v1/testChannel:
|
||||
post:
|
||||
deprecated: true
|
||||
@@ -11003,9 +10227,7 @@ paths:
|
||||
five metrics, and pagination via offset/limit. The response type is ''list''
|
||||
for the default host.name grouping or ''grouped_list'' for custom groupBy
|
||||
keys. Also reports missing required metrics and whether the requested time
|
||||
range falls before the data retention boundary. Numeric metric fields (cpu,
|
||||
memory, wait, load15, diskUsage) return -1 as a sentinel when no data is available
|
||||
for that field.'
|
||||
range falls before the data retention boundary.'
|
||||
operationId: ListHosts
|
||||
requestBody:
|
||||
content:
|
||||
@@ -11059,79 +10281,6 @@ paths:
|
||||
summary: List Hosts for Infra Monitoring
|
||||
tags:
|
||||
- inframonitoring
|
||||
/api/v2/infra_monitoring/pods:
|
||||
post:
|
||||
deprecated: false
|
||||
description: 'Returns a paginated list of Kubernetes pods with key metrics:
|
||||
CPU usage, CPU request/limit utilization, memory working set, memory request/limit
|
||||
utilization, current pod phase (pending/running/succeeded/failed/unknown),
|
||||
and pod age (ms since start time). Each pod includes metadata attributes (namespace,
|
||||
node, workload owner such as deployment/statefulset/daemonset/job/cronjob,
|
||||
cluster). Supports filtering via a filter expression, custom groupBy to aggregate
|
||||
pods by any attribute, ordering by any of the six metrics (cpu, cpu_request,
|
||||
cpu_limit, memory, memory_request, memory_limit), and pagination via offset/limit.
|
||||
The response type is ''list'' for the default k8s.pod.uid grouping (each row
|
||||
is one pod with its current phase) or ''grouped_list'' for custom groupBy
|
||||
keys (each row aggregates pods in the group with per-phase counts: pendingPodCount,
|
||||
runningPodCount, succeededPodCount, failedPodCount, unknownPodCount derived
|
||||
from each pod''s latest phase in the window). Also reports missing required
|
||||
metrics and whether the requested time range falls before the data retention
|
||||
boundary. Numeric metric fields (podCPU, podCPURequest, podCPULimit, podMemory,
|
||||
podMemoryRequest, podMemoryLimit, podAge) return -1 as a sentinel when no
|
||||
data is available for that field.'
|
||||
operationId: ListPods
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InframonitoringtypesPostablePods'
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/InframonitoringtypesPods'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- VIEWER
|
||||
- tokenizer:
|
||||
- VIEWER
|
||||
summary: List Pods for Infra Monitoring
|
||||
tags:
|
||||
- inframonitoring
|
||||
/api/v2/livez:
|
||||
get:
|
||||
deprecated: false
|
||||
|
||||
@@ -18,7 +18,6 @@ func NewAWSCloudProvider(defStore cloudintegrationtypes.ServiceDefinitionStore)
|
||||
return &awscloudprovider{serviceDefinitions: defStore}, nil
|
||||
}
|
||||
|
||||
// TODO: move URL construction logic to cloudintegrationtypes and add unit tests for it.
|
||||
func (provider *awscloudprovider) GetConnectionArtifact(ctx context.Context, account *cloudintegrationtypes.Account, req *cloudintegrationtypes.GetConnectionArtifactRequest) (*cloudintegrationtypes.ConnectionArtifact, error) {
|
||||
baseURL := fmt.Sprintf(cloudintegrationtypes.CloudFormationQuickCreateBaseURL.StringValue(), req.Config.AWS.DeploymentRegion)
|
||||
u, _ := url.Parse(baseURL)
|
||||
|
||||
@@ -2,48 +2,27 @@ package implcloudprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
|
||||
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
|
||||
)
|
||||
|
||||
type azurecloudprovider struct {
|
||||
serviceDefinitions cloudintegrationtypes.ServiceDefinitionStore
|
||||
}
|
||||
type azurecloudprovider struct{}
|
||||
|
||||
func NewAzureCloudProvider(defStore cloudintegrationtypes.ServiceDefinitionStore) cloudintegration.CloudProviderModule {
|
||||
return &azurecloudprovider{
|
||||
serviceDefinitions: defStore,
|
||||
}
|
||||
func NewAzureCloudProvider() cloudintegration.CloudProviderModule {
|
||||
return &azurecloudprovider{}
|
||||
}
|
||||
|
||||
func (provider *azurecloudprovider) GetConnectionArtifact(ctx context.Context, account *cloudintegrationtypes.Account, req *cloudintegrationtypes.GetConnectionArtifactRequest) (*cloudintegrationtypes.ConnectionArtifact, error) {
|
||||
connectionArtifact, err := cloudintegrationtypes.NewAzureConnectionArtifact(account.ID, req.Config.AgentVersion, req.Credentials, req.Config.Azure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cloudintegrationtypes.ConnectionArtifact{
|
||||
Azure: connectionArtifact,
|
||||
}, nil
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (provider *azurecloudprovider) ListServiceDefinitions(ctx context.Context) ([]*cloudintegrationtypes.ServiceDefinition, error) {
|
||||
return provider.serviceDefinitions.List(ctx, cloudintegrationtypes.CloudProviderTypeAzure)
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (provider *azurecloudprovider) GetServiceDefinition(ctx context.Context, serviceID cloudintegrationtypes.ServiceID) (*cloudintegrationtypes.ServiceDefinition, error) {
|
||||
serviceDef, err := provider.serviceDefinitions.Get(ctx, cloudintegrationtypes.CloudProviderTypeAzure, serviceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// override cloud integration dashboard id.
|
||||
for index, dashboard := range serviceDef.Assets.Dashboards {
|
||||
serviceDef.Assets.Dashboards[index].ID = cloudintegrationtypes.GetCloudIntegrationDashboardID(cloudintegrationtypes.CloudProviderTypeAzure, serviceID.StringValue(), dashboard.ID)
|
||||
}
|
||||
|
||||
return serviceDef, nil
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (provider *azurecloudprovider) BuildIntegrationConfig(
|
||||
@@ -51,56 +30,5 @@ func (provider *azurecloudprovider) BuildIntegrationConfig(
|
||||
account *cloudintegrationtypes.Account,
|
||||
services []*cloudintegrationtypes.StorableCloudIntegrationService,
|
||||
) (*cloudintegrationtypes.ProviderIntegrationConfig, error) {
|
||||
sort.Slice(services, func(i, j int) bool {
|
||||
return services[i].Type.StringValue() < services[j].Type.StringValue()
|
||||
})
|
||||
|
||||
var strategies []*cloudintegrationtypes.AzureTelemetryCollectionStrategy
|
||||
|
||||
for _, storedSvc := range services {
|
||||
svcCfg, err := cloudintegrationtypes.NewServiceConfigFromJSON(cloudintegrationtypes.CloudProviderTypeAzure, storedSvc.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
svcDef, err := provider.GetServiceDefinition(ctx, storedSvc.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
strategy := svcDef.TelemetryCollectionStrategy.Azure
|
||||
if strategy == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
logsEnabled := svcCfg.IsLogsEnabled(cloudintegrationtypes.CloudProviderTypeAzure)
|
||||
metricsEnabled := svcCfg.IsMetricsEnabled(cloudintegrationtypes.CloudProviderTypeAzure)
|
||||
|
||||
if !logsEnabled && !metricsEnabled {
|
||||
continue
|
||||
}
|
||||
|
||||
entry := &cloudintegrationtypes.AzureTelemetryCollectionStrategy{
|
||||
ResourceProvider: strategy.ResourceProvider,
|
||||
ResourceType: strategy.ResourceType,
|
||||
}
|
||||
|
||||
if metricsEnabled && strategy.Metrics != nil {
|
||||
entry.Metrics = strategy.Metrics
|
||||
}
|
||||
|
||||
if logsEnabled && strategy.Logs != nil {
|
||||
entry.Logs = strategy.Logs
|
||||
}
|
||||
|
||||
strategies = append(strategies, entry)
|
||||
}
|
||||
|
||||
return &cloudintegrationtypes.ProviderIntegrationConfig{
|
||||
Azure: cloudintegrationtypes.NewAzureIntegrationConfig(
|
||||
account.Config.Azure.DeploymentRegion,
|
||||
account.Config.Azure.ResourceGroups,
|
||||
strategies,
|
||||
),
|
||||
}, nil
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -429,14 +429,10 @@ func (module *module) Collect(ctx context.Context, orgID valuer.UUID) (map[strin
|
||||
stats["cloudintegration.aws.connectedaccounts.count"] = awsAccountsCount
|
||||
}
|
||||
|
||||
// get connected accounts for Azure
|
||||
azureAccountsCount, err := module.store.CountConnectedAccounts(ctx, orgID, cloudintegrationtypes.CloudProviderTypeAzure)
|
||||
if err == nil {
|
||||
stats["cloudintegration.azure.connectedaccounts.count"] = azureAccountsCount
|
||||
}
|
||||
|
||||
// NOTE: not adding stats for services for now.
|
||||
|
||||
// TODO: add more cloud providers when supported
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/knip@5/schema.json",
|
||||
"project": ["src/**/*.ts", "src/**/*.tsx"],
|
||||
"ignore": ["src/api/generated/**/*.ts"]
|
||||
}
|
||||
@@ -212,9 +212,9 @@
|
||||
"msw": "1.3.2",
|
||||
"npm-run-all": "latest",
|
||||
"orval": "7.18.0",
|
||||
"oxfmt": "0.47.0",
|
||||
"oxlint": "1.62.0",
|
||||
"oxlint-tsgolint": "0.22.1",
|
||||
"oxfmt": "0.46.0",
|
||||
"oxlint": "1.61.0",
|
||||
"oxlint-tsgolint": "0.21.1",
|
||||
"portfinder-sync": "^0.0.2",
|
||||
"postcss": "8.5.6",
|
||||
"postcss-scss": "4.0.9",
|
||||
@@ -238,12 +238,9 @@
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(js|jsx|ts|tsx)": [
|
||||
"oxlint --fix",
|
||||
"oxfmt --write",
|
||||
"oxfmt --check",
|
||||
"oxlint --quiet",
|
||||
"sh scripts/typecheck-staged.sh"
|
||||
],
|
||||
"*.(scss|css)": [
|
||||
"stylelint"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('getFieldKeys API', () => {
|
||||
const result = await getFieldKeys('traces');
|
||||
|
||||
// Verify the returned structure matches SuccessResponseV2 format
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
httpStatusCode: 200,
|
||||
data: mockSuccessResponse.data.data,
|
||||
});
|
||||
|
||||
@@ -199,7 +199,7 @@ describe('getFieldValues API', () => {
|
||||
const result = await getFieldValues('traces', 'service.name');
|
||||
|
||||
// Verify the returned structure matches SuccessResponseV2 format
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
httpStatusCode: 200,
|
||||
data: expect.objectContaining({
|
||||
values: expect.any(Object),
|
||||
|
||||
@@ -13,9 +13,7 @@ import type {
|
||||
|
||||
import type {
|
||||
InframonitoringtypesPostableHostsDTO,
|
||||
InframonitoringtypesPostablePodsDTO,
|
||||
ListHosts200,
|
||||
ListPods200,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
@@ -23,7 +21,7 @@ import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { ErrorType, BodyType } from '../../../generatedAPIInstance';
|
||||
|
||||
/**
|
||||
* Returns a paginated list of hosts with key infrastructure metrics: CPU usage (%), memory usage (%), I/O wait (%), disk usage (%), and 15-minute load average. Each host includes its current status (active/inactive based on metrics reported in the last 10 minutes) and metadata attributes (e.g., os.type). Supports filtering via a filter expression, filtering by host status, custom groupBy to aggregate hosts by any attribute, ordering by any of the five metrics, and pagination via offset/limit. The response type is 'list' for the default host.name grouping or 'grouped_list' for custom groupBy keys. Also reports missing required metrics and whether the requested time range falls before the data retention boundary. Numeric metric fields (cpu, memory, wait, load15, diskUsage) return -1 as a sentinel when no data is available for that field.
|
||||
* Returns a paginated list of hosts with key infrastructure metrics: CPU usage (%), memory usage (%), I/O wait (%), disk usage (%), and 15-minute load average. Each host includes its current status (active/inactive based on metrics reported in the last 10 minutes) and metadata attributes (e.g., os.type). Supports filtering via a filter expression, filtering by host status, custom groupBy to aggregate hosts by any attribute, ordering by any of the five metrics, and pagination via offset/limit. The response type is 'list' for the default host.name grouping or 'grouped_list' for custom groupBy keys. Also reports missing required metrics and whether the requested time range falls before the data retention boundary.
|
||||
* @summary List Hosts for Infra Monitoring
|
||||
*/
|
||||
export const listHosts = (
|
||||
@@ -106,87 +104,3 @@ export const useListHosts = <
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* Returns a paginated list of Kubernetes pods with key metrics: CPU usage, CPU request/limit utilization, memory working set, memory request/limit utilization, current pod phase (pending/running/succeeded/failed/unknown), and pod age (ms since start time). Each pod includes metadata attributes (namespace, node, workload owner such as deployment/statefulset/daemonset/job/cronjob, cluster). Supports filtering via a filter expression, custom groupBy to aggregate pods by any attribute, ordering by any of the six metrics (cpu, cpu_request, cpu_limit, memory, memory_request, memory_limit), and pagination via offset/limit. The response type is 'list' for the default k8s.pod.uid grouping (each row is one pod with its current phase) or 'grouped_list' for custom groupBy keys (each row aggregates pods in the group with per-phase counts: pendingPodCount, runningPodCount, succeededPodCount, failedPodCount, unknownPodCount derived from each pod's latest phase in the window). Also reports missing required metrics and whether the requested time range falls before the data retention boundary. Numeric metric fields (podCPU, podCPURequest, podCPULimit, podMemory, podMemoryRequest, podMemoryLimit, podAge) return -1 as a sentinel when no data is available for that field.
|
||||
* @summary List Pods for Infra Monitoring
|
||||
*/
|
||||
export const listPods = (
|
||||
inframonitoringtypesPostablePodsDTO: BodyType<InframonitoringtypesPostablePodsDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<ListPods200>({
|
||||
url: `/api/v2/infra_monitoring/pods`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: inframonitoringtypesPostablePodsDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListPodsMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof listPods>>,
|
||||
TError,
|
||||
{ data: BodyType<InframonitoringtypesPostablePodsDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof listPods>>,
|
||||
TError,
|
||||
{ data: BodyType<InframonitoringtypesPostablePodsDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['listPods'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof listPods>>,
|
||||
{ data: BodyType<InframonitoringtypesPostablePodsDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return listPods(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type ListPodsMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listPods>>
|
||||
>;
|
||||
export type ListPodsMutationBody =
|
||||
BodyType<InframonitoringtypesPostablePodsDTO>;
|
||||
export type ListPodsMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary List Pods for Infra Monitoring
|
||||
*/
|
||||
export const useListPods = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof listPods>>,
|
||||
TError,
|
||||
{ data: BodyType<InframonitoringtypesPostablePodsDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof listPods>>,
|
||||
TError,
|
||||
{ data: BodyType<InframonitoringtypesPostablePodsDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getListPodsMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
|
||||
@@ -3243,108 +3243,6 @@ export interface InframonitoringtypesHostsDTO {
|
||||
warning?: Querybuildertypesv5QueryWarnDataDTO;
|
||||
}
|
||||
|
||||
export enum InframonitoringtypesPodPhaseDTO {
|
||||
pending = 'pending',
|
||||
running = 'running',
|
||||
succeeded = 'succeeded',
|
||||
failed = 'failed',
|
||||
unknown = 'unknown',
|
||||
'' = '',
|
||||
}
|
||||
/**
|
||||
* @nullable
|
||||
*/
|
||||
export type InframonitoringtypesPodRecordDTOMeta = {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
|
||||
export interface InframonitoringtypesPodRecordDTO {
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
failedPodCount: number;
|
||||
/**
|
||||
* @type object
|
||||
* @nullable true
|
||||
*/
|
||||
meta: InframonitoringtypesPodRecordDTOMeta;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
pendingPodCount: number;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
podAge: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
podCPU: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
podCPULimit: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
podCPURequest: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
podMemory: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
podMemoryLimit: number;
|
||||
/**
|
||||
* @type number
|
||||
* @format double
|
||||
*/
|
||||
podMemoryRequest: number;
|
||||
podPhase: InframonitoringtypesPodPhaseDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
podUID: string;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
runningPodCount: number;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
succeededPodCount: number;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
unknownPodCount: number;
|
||||
}
|
||||
|
||||
export interface InframonitoringtypesPodsDTO {
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
endTimeBeforeRetention: boolean;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
records: InframonitoringtypesPodRecordDTO[] | null;
|
||||
requiredMetricsCheck: InframonitoringtypesRequiredMetricsCheckDTO;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
total: number;
|
||||
type: InframonitoringtypesResponseTypeDTO;
|
||||
warning?: Querybuildertypesv5QueryWarnDataDTO;
|
||||
}
|
||||
|
||||
export interface InframonitoringtypesPostableHostsDTO {
|
||||
/**
|
||||
* @type integer
|
||||
@@ -3373,34 +3271,6 @@ export interface InframonitoringtypesPostableHostsDTO {
|
||||
start: number;
|
||||
}
|
||||
|
||||
export interface InframonitoringtypesPostablePodsDTO {
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
end: number;
|
||||
filter?: Querybuildertypesv5FilterDTO;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
groupBy?: Querybuildertypesv5GroupByKeyDTO[] | null;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
limit: number;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
offset?: number;
|
||||
orderBy?: Querybuildertypesv5OrderByDTO;
|
||||
/**
|
||||
* @type integer
|
||||
* @format int64
|
||||
*/
|
||||
start: number;
|
||||
}
|
||||
|
||||
export interface InframonitoringtypesRequiredMetricsCheckDTO {
|
||||
/**
|
||||
* @type array
|
||||
@@ -3831,7 +3701,10 @@ export interface PromotetypesPromotePathDTO {
|
||||
}
|
||||
|
||||
export interface PromotetypesWrappedIndexDTO {
|
||||
fieldDataType?: TelemetrytypesFieldDataTypeDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
column_type?: string;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
@@ -5602,187 +5475,6 @@ export interface Sigv4SigV4ConfigDTO {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export enum SpantypesFieldContextDTO {
|
||||
attribute = 'attribute',
|
||||
resource = 'resource',
|
||||
}
|
||||
export interface SpantypesGettableSpanMapperGroupsDTO {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
items: SpantypesSpanMapperGroupDTO[];
|
||||
}
|
||||
|
||||
export interface SpantypesPostableSpanMapperDTO {
|
||||
config: SpantypesSpanMapperConfigDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
enabled?: boolean;
|
||||
field_context: SpantypesFieldContextDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SpantypesPostableSpanMapperGroupDTO {
|
||||
category: SpantypesSpanMapperGroupCategoryDTO;
|
||||
condition: SpantypesSpanMapperGroupConditionDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SpantypesSpanMapperDTO {
|
||||
config: SpantypesSpanMapperConfigDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
createdAt?: Date;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
createdBy?: string;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
enabled: boolean;
|
||||
field_context: SpantypesFieldContextDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
group_id: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
updatedAt?: Date;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
updatedBy?: string;
|
||||
}
|
||||
|
||||
export interface SpantypesSpanMapperConfigDTO {
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
sources: SpantypesSpanMapperSourceDTO[] | null;
|
||||
}
|
||||
|
||||
export interface SpantypesSpanMapperGroupDTO {
|
||||
category: SpantypesSpanMapperGroupCategoryDTO;
|
||||
condition: SpantypesSpanMapperGroupConditionDTO;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
createdAt?: Date;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
createdBy?: string;
|
||||
/**
|
||||
* @type boolean
|
||||
*/
|
||||
enabled: boolean;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
orgId: string;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
updatedAt?: Date;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
updatedBy?: string;
|
||||
}
|
||||
|
||||
export interface SpantypesSpanMapperGroupCategoryDTO {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface SpantypesSpanMapperGroupConditionDTO {
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
attributes: string[] | null;
|
||||
/**
|
||||
* @type array
|
||||
* @nullable true
|
||||
*/
|
||||
resource: string[] | null;
|
||||
}
|
||||
|
||||
export enum SpantypesSpanMapperOperationDTO {
|
||||
move = 'move',
|
||||
copy = 'copy',
|
||||
}
|
||||
export interface SpantypesSpanMapperSourceDTO {
|
||||
context: SpantypesFieldContextDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
key: string;
|
||||
operation: SpantypesSpanMapperOperationDTO;
|
||||
/**
|
||||
* @type integer
|
||||
*/
|
||||
priority: number;
|
||||
}
|
||||
|
||||
export interface SpantypesUpdatableSpanMapperDTO {
|
||||
config?: SpantypesSpanMapperConfigDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
* @nullable true
|
||||
*/
|
||||
enabled?: boolean | null;
|
||||
field_context?: SpantypesFieldContextDTO;
|
||||
}
|
||||
|
||||
export interface SpantypesUpdatableSpanMapperGroupDTO {
|
||||
condition?: SpantypesSpanMapperGroupConditionDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
* @nullable true
|
||||
*/
|
||||
enabled?: boolean | null;
|
||||
/**
|
||||
* @type string
|
||||
* @nullable true
|
||||
*/
|
||||
name?: string | null;
|
||||
}
|
||||
|
||||
export enum TelemetrytypesFieldContextDTO {
|
||||
metric = 'metric',
|
||||
log = 'log',
|
||||
@@ -7233,71 +6925,6 @@ export type GetMyServiceAccount200 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type ListSpanMapperGroupsParams = {
|
||||
/**
|
||||
* @description undefined
|
||||
*/
|
||||
category?: SpantypesSpanMapperGroupCategoryDTO;
|
||||
/**
|
||||
* @type boolean
|
||||
* @nullable true
|
||||
* @description undefined
|
||||
*/
|
||||
enabled?: boolean | null;
|
||||
};
|
||||
|
||||
export type ListSpanMapperGroups200 = {
|
||||
data: SpantypesGettableSpanMapperGroupsDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type CreateSpanMapperGroup201 = {
|
||||
data: SpantypesSpanMapperGroupDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type DeleteSpanMapperGroupPathParameters = {
|
||||
groupId: string;
|
||||
};
|
||||
export type UpdateSpanMapperGroupPathParameters = {
|
||||
groupId: string;
|
||||
};
|
||||
export type ListSpanMappersPathParameters = {
|
||||
groupId: string;
|
||||
};
|
||||
export type ListSpanMappers200 = {
|
||||
data: SpantypesGettableSpanMapperGroupsDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type CreateSpanMapperPathParameters = {
|
||||
groupId: string;
|
||||
};
|
||||
export type CreateSpanMapper201 = {
|
||||
data: SpantypesSpanMapperDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type DeleteSpanMapperPathParameters = {
|
||||
groupId: string;
|
||||
mapperId: string;
|
||||
};
|
||||
export type UpdateSpanMapperPathParameters = {
|
||||
groupId: string;
|
||||
mapperId: string;
|
||||
};
|
||||
export type ListUsersDeprecated200 = {
|
||||
/**
|
||||
* @type array
|
||||
@@ -7480,14 +7107,6 @@ export type ListHosts200 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type ListPods200 = {
|
||||
data: InframonitoringtypesPodsDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type Livez200 = {
|
||||
data: FactoryResponseDTO;
|
||||
/**
|
||||
|
||||
@@ -1,787 +0,0 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'yarn generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
CreateSpanMapper201,
|
||||
CreateSpanMapperGroup201,
|
||||
CreateSpanMapperPathParameters,
|
||||
DeleteSpanMapperGroupPathParameters,
|
||||
DeleteSpanMapperPathParameters,
|
||||
ListSpanMapperGroups200,
|
||||
ListSpanMapperGroupsParams,
|
||||
ListSpanMappers200,
|
||||
ListSpanMappersPathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
SpantypesPostableSpanMapperDTO,
|
||||
SpantypesPostableSpanMapperGroupDTO,
|
||||
SpantypesUpdatableSpanMapperDTO,
|
||||
SpantypesUpdatableSpanMapperGroupDTO,
|
||||
UpdateSpanMapperGroupPathParameters,
|
||||
UpdateSpanMapperPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { ErrorType, BodyType } from '../../../generatedAPIInstance';
|
||||
|
||||
/**
|
||||
* Returns all span attribute mapping groups for the authenticated org.
|
||||
* @summary List span attribute mapping groups
|
||||
*/
|
||||
export const listSpanMapperGroups = (
|
||||
params?: ListSpanMapperGroupsParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<ListSpanMapperGroups200>({
|
||||
url: `/api/v1/span_mapper_groups`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListSpanMapperGroupsQueryKey = (
|
||||
params?: ListSpanMapperGroupsParams,
|
||||
) => {
|
||||
return [`/api/v1/span_mapper_groups`, ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getListSpanMapperGroupsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listSpanMapperGroups>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
params?: ListSpanMapperGroupsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSpanMapperGroups>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getListSpanMapperGroupsQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof listSpanMapperGroups>>
|
||||
> = ({ signal }) => listSpanMapperGroups(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSpanMapperGroups>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type ListSpanMapperGroupsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listSpanMapperGroups>>
|
||||
>;
|
||||
export type ListSpanMapperGroupsQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary List span attribute mapping groups
|
||||
*/
|
||||
|
||||
export function useListSpanMapperGroups<
|
||||
TData = Awaited<ReturnType<typeof listSpanMapperGroups>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
params?: ListSpanMapperGroupsParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSpanMapperGroups>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getListSpanMapperGroupsQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary List span attribute mapping groups
|
||||
*/
|
||||
export const invalidateListSpanMapperGroups = async (
|
||||
queryClient: QueryClient,
|
||||
params?: ListSpanMapperGroupsParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getListSpanMapperGroupsQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new span attribute mapping group for the org.
|
||||
* @summary Create a span attribute mapping group
|
||||
*/
|
||||
export const createSpanMapperGroup = (
|
||||
spantypesPostableSpanMapperGroupDTO: BodyType<SpantypesPostableSpanMapperGroupDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<CreateSpanMapperGroup201>({
|
||||
url: `/api/v1/span_mapper_groups`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: spantypesPostableSpanMapperGroupDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCreateSpanMapperGroupMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSpanMapperGroup>>,
|
||||
TError,
|
||||
{ data: BodyType<SpantypesPostableSpanMapperGroupDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSpanMapperGroup>>,
|
||||
TError,
|
||||
{ data: BodyType<SpantypesPostableSpanMapperGroupDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['createSpanMapperGroup'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof createSpanMapperGroup>>,
|
||||
{ data: BodyType<SpantypesPostableSpanMapperGroupDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return createSpanMapperGroup(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CreateSpanMapperGroupMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createSpanMapperGroup>>
|
||||
>;
|
||||
export type CreateSpanMapperGroupMutationBody =
|
||||
BodyType<SpantypesPostableSpanMapperGroupDTO>;
|
||||
export type CreateSpanMapperGroupMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Create a span attribute mapping group
|
||||
*/
|
||||
export const useCreateSpanMapperGroup = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSpanMapperGroup>>,
|
||||
TError,
|
||||
{ data: BodyType<SpantypesPostableSpanMapperGroupDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createSpanMapperGroup>>,
|
||||
TError,
|
||||
{ data: BodyType<SpantypesPostableSpanMapperGroupDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getCreateSpanMapperGroupMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* Hard-deletes a mapping group and cascades to all its mappers.
|
||||
* @summary Delete a span attribute mapping group
|
||||
*/
|
||||
export const deleteSpanMapperGroup = ({
|
||||
groupId,
|
||||
}: DeleteSpanMapperGroupPathParameters) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/span_mapper_groups/${groupId}`,
|
||||
method: 'DELETE',
|
||||
});
|
||||
};
|
||||
|
||||
export const getDeleteSpanMapperGroupMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSpanMapperGroup>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperGroupPathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSpanMapperGroup>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperGroupPathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['deleteSpanMapperGroup'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof deleteSpanMapperGroup>>,
|
||||
{ pathParams: DeleteSpanMapperGroupPathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return deleteSpanMapperGroup(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type DeleteSpanMapperGroupMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteSpanMapperGroup>>
|
||||
>;
|
||||
|
||||
export type DeleteSpanMapperGroupMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Delete a span attribute mapping group
|
||||
*/
|
||||
export const useDeleteSpanMapperGroup = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSpanMapperGroup>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperGroupPathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteSpanMapperGroup>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperGroupPathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getDeleteSpanMapperGroupMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* Partially updates an existing mapping group's name, condition, or enabled state.
|
||||
* @summary Update a span attribute mapping group
|
||||
*/
|
||||
export const updateSpanMapperGroup = (
|
||||
{ groupId }: UpdateSpanMapperGroupPathParameters,
|
||||
spantypesUpdatableSpanMapperGroupDTO: BodyType<SpantypesUpdatableSpanMapperGroupDTO>,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/span_mapper_groups/${groupId}`,
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: spantypesUpdatableSpanMapperGroupDTO,
|
||||
});
|
||||
};
|
||||
|
||||
export const getUpdateSpanMapperGroupMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSpanMapperGroup>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperGroupPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperGroupDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSpanMapperGroup>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperGroupPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperGroupDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['updateSpanMapperGroup'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof updateSpanMapperGroup>>,
|
||||
{
|
||||
pathParams: UpdateSpanMapperGroupPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperGroupDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
|
||||
return updateSpanMapperGroup(pathParams, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateSpanMapperGroupMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateSpanMapperGroup>>
|
||||
>;
|
||||
export type UpdateSpanMapperGroupMutationBody =
|
||||
BodyType<SpantypesUpdatableSpanMapperGroupDTO>;
|
||||
export type UpdateSpanMapperGroupMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Update a span attribute mapping group
|
||||
*/
|
||||
export const useUpdateSpanMapperGroup = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSpanMapperGroup>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperGroupPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperGroupDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateSpanMapperGroup>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperGroupPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperGroupDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getUpdateSpanMapperGroupMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* Returns all mappers belonging to a mapping group.
|
||||
* @summary List span mappers for a group
|
||||
*/
|
||||
export const listSpanMappers = (
|
||||
{ groupId }: ListSpanMappersPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<ListSpanMappers200>({
|
||||
url: `/api/v1/span_mapper_groups/${groupId}/span_mappers`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListSpanMappersQueryKey = ({
|
||||
groupId,
|
||||
}: ListSpanMappersPathParameters) => {
|
||||
return [`/api/v1/span_mapper_groups/${groupId}/span_mappers`] as const;
|
||||
};
|
||||
|
||||
export const getListSpanMappersQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listSpanMappers>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ groupId }: ListSpanMappersPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSpanMappers>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getListSpanMappersQueryKey({ groupId });
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listSpanMappers>>> = ({
|
||||
signal,
|
||||
}) => listSpanMappers({ groupId }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!groupId,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSpanMappers>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type ListSpanMappersQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listSpanMappers>>
|
||||
>;
|
||||
export type ListSpanMappersQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary List span mappers for a group
|
||||
*/
|
||||
|
||||
export function useListSpanMappers<
|
||||
TData = Awaited<ReturnType<typeof listSpanMappers>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ groupId }: ListSpanMappersPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listSpanMappers>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getListSpanMappersQueryOptions({ groupId }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
query.queryKey = queryOptions.queryKey;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary List span mappers for a group
|
||||
*/
|
||||
export const invalidateListSpanMappers = async (
|
||||
queryClient: QueryClient,
|
||||
{ groupId }: ListSpanMappersPathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getListSpanMappersQueryKey({ groupId }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a new mapper to the specified mapping group.
|
||||
* @summary Create a span mapper
|
||||
*/
|
||||
export const createSpanMapper = (
|
||||
{ groupId }: CreateSpanMapperPathParameters,
|
||||
spantypesPostableSpanMapperDTO: BodyType<SpantypesPostableSpanMapperDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<CreateSpanMapper201>({
|
||||
url: `/api/v1/span_mapper_groups/${groupId}/span_mappers`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: spantypesPostableSpanMapperDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCreateSpanMapperMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesPostableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesPostableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['createSpanMapper'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof createSpanMapper>>,
|
||||
{
|
||||
pathParams: CreateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesPostableSpanMapperDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
|
||||
return createSpanMapper(pathParams, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CreateSpanMapperMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createSpanMapper>>
|
||||
>;
|
||||
export type CreateSpanMapperMutationBody =
|
||||
BodyType<SpantypesPostableSpanMapperDTO>;
|
||||
export type CreateSpanMapperMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Create a span mapper
|
||||
*/
|
||||
export const useCreateSpanMapper = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesPostableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesPostableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getCreateSpanMapperMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* Hard-deletes a mapper from a mapping group.
|
||||
* @summary Delete a span mapper
|
||||
*/
|
||||
export const deleteSpanMapper = ({
|
||||
groupId,
|
||||
mapperId,
|
||||
}: DeleteSpanMapperPathParameters) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/span_mapper_groups/${groupId}/span_mappers/${mapperId}`,
|
||||
method: 'DELETE',
|
||||
});
|
||||
};
|
||||
|
||||
export const getDeleteSpanMapperMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSpanMapper>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperPathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSpanMapper>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperPathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['deleteSpanMapper'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof deleteSpanMapper>>,
|
||||
{ pathParams: DeleteSpanMapperPathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return deleteSpanMapper(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type DeleteSpanMapperMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteSpanMapper>>
|
||||
>;
|
||||
|
||||
export type DeleteSpanMapperMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Delete a span mapper
|
||||
*/
|
||||
export const useDeleteSpanMapper = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteSpanMapper>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperPathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteSpanMapper>>,
|
||||
TError,
|
||||
{ pathParams: DeleteSpanMapperPathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getDeleteSpanMapperMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
/**
|
||||
* Partially updates an existing mapper's field context, config, or enabled state.
|
||||
* @summary Update a span mapper
|
||||
*/
|
||||
export const updateSpanMapper = (
|
||||
{ groupId, mapperId }: UpdateSpanMapperPathParameters,
|
||||
spantypesUpdatableSpanMapperDTO: BodyType<SpantypesUpdatableSpanMapperDTO>,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/span_mapper_groups/${groupId}/span_mappers/${mapperId}`,
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: spantypesUpdatableSpanMapperDTO,
|
||||
});
|
||||
};
|
||||
|
||||
export const getUpdateSpanMapperMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['updateSpanMapper'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof updateSpanMapper>>,
|
||||
{
|
||||
pathParams: UpdateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
|
||||
return updateSpanMapper(pathParams, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateSpanMapperMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateSpanMapper>>
|
||||
>;
|
||||
export type UpdateSpanMapperMutationBody =
|
||||
BodyType<SpantypesUpdatableSpanMapperDTO>;
|
||||
export type UpdateSpanMapperMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Update a span mapper
|
||||
*/
|
||||
export const useUpdateSpanMapper = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateSpanMapper>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateSpanMapperPathParameters;
|
||||
data: BodyType<SpantypesUpdatableSpanMapperDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationOptions = getUpdateSpanMapperMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions);
|
||||
};
|
||||
@@ -76,10 +76,10 @@ describe('interceptorRejected', () => {
|
||||
}
|
||||
|
||||
const mockAxiosFn = axios as unknown as jest.Mock;
|
||||
expect(mockAxiosFn.mock.calls).toHaveLength(1);
|
||||
expect(mockAxiosFn.mock.calls.length).toBe(1);
|
||||
const retryCallConfig = mockAxiosFn.mock.calls[0][0];
|
||||
expect(Array.isArray(JSON.parse(retryCallConfig.data))).toBe(true);
|
||||
expect(JSON.parse(retryCallConfig.data)).toStrictEqual(arrayPayload);
|
||||
expect(JSON.parse(retryCallConfig.data)).toEqual(arrayPayload);
|
||||
});
|
||||
|
||||
it('should preserve object payload structure when retrying a 401 request', async () => {
|
||||
@@ -112,9 +112,9 @@ describe('interceptorRejected', () => {
|
||||
}
|
||||
|
||||
const mockAxiosFn = axios as unknown as jest.Mock;
|
||||
expect(mockAxiosFn.mock.calls).toHaveLength(1);
|
||||
expect(mockAxiosFn.mock.calls.length).toBe(1);
|
||||
const retryCallConfig = mockAxiosFn.mock.calls[0][0];
|
||||
expect(JSON.parse(retryCallConfig.data)).toStrictEqual(objectPayload);
|
||||
expect(JSON.parse(retryCallConfig.data)).toEqual(objectPayload);
|
||||
});
|
||||
|
||||
it('should handle undefined data gracefully when retrying', async () => {
|
||||
@@ -145,7 +145,7 @@ describe('interceptorRejected', () => {
|
||||
}
|
||||
|
||||
const mockAxiosFn = axios as unknown as jest.Mock;
|
||||
expect(mockAxiosFn.mock.calls).toHaveLength(1);
|
||||
expect(mockAxiosFn.mock.calls.length).toBe(1);
|
||||
const retryCallConfig = mockAxiosFn.mock.calls[0][0];
|
||||
expect(retryCallConfig.data).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -99,7 +99,7 @@ describe('convertV5ResponseToLegacy', () => {
|
||||
const q = result.payload.data.result[0];
|
||||
expect(q.queryName).toBe('A');
|
||||
expect(q.legend).toBe('{{service.name}}');
|
||||
expect(q.series?.[0]).toStrictEqual(
|
||||
expect(q.series?.[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
labels: { 'service.name': 'adservice' },
|
||||
values: [
|
||||
@@ -186,7 +186,7 @@ describe('convertV5ResponseToLegacy', () => {
|
||||
|
||||
expect(result.payload.data.resultType).toBe('scalar');
|
||||
const [tableEntry] = result.payload.data.result;
|
||||
expect(tableEntry.table?.columns).toStrictEqual([
|
||||
expect(tableEntry.table?.columns).toEqual([
|
||||
{
|
||||
name: 'service.name',
|
||||
queryName: 'A',
|
||||
@@ -202,7 +202,7 @@ describe('convertV5ResponseToLegacy', () => {
|
||||
},
|
||||
{ name: 'F1', queryName: 'F1', isValueColumn: true, id: 'F1' },
|
||||
]);
|
||||
expect(tableEntry.table?.rows?.[0]).toStrictEqual({
|
||||
expect(tableEntry.table?.rows?.[0]).toEqual({
|
||||
data: {
|
||||
'service.name': 'adservice',
|
||||
'A.count()': 606,
|
||||
@@ -257,7 +257,7 @@ describe('convertV5ResponseToLegacy', () => {
|
||||
|
||||
expect(result.payload.data.resultType).toBe('scalar');
|
||||
const [tableEntry] = result.payload.data.result;
|
||||
expect(tableEntry.table?.columns).toStrictEqual([
|
||||
expect(tableEntry.table?.columns).toEqual([
|
||||
{
|
||||
name: 'service.name',
|
||||
queryName: 'A',
|
||||
@@ -267,7 +267,7 @@ describe('convertV5ResponseToLegacy', () => {
|
||||
// Single aggregation: name resolves to legend, id resolves to queryName
|
||||
{ name: '{{service.name}}', queryName: 'A', isValueColumn: true, id: 'A' },
|
||||
]);
|
||||
expect(tableEntry.table?.rows?.[0]).toStrictEqual({
|
||||
expect(tableEntry.table?.rows?.[0]).toEqual({
|
||||
data: {
|
||||
'service.name': 'adservice',
|
||||
A: 580,
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: { A: 'Legend A', F1: 'Formula Legend' },
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -154,10 +154,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
);
|
||||
|
||||
// Legend map combines builder and formulas
|
||||
expect(result.legendMap).toStrictEqual({
|
||||
A: 'Legend A',
|
||||
F1: 'Formula Legend',
|
||||
});
|
||||
expect(result.legendMap).toEqual({ A: 'Legend A', F1: 'Formula Legend' });
|
||||
|
||||
const payload: QueryRangePayloadV5 = result.queryPayload;
|
||||
|
||||
@@ -169,10 +166,10 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
expect(payload.formatOptions?.fillGaps).toBe(true);
|
||||
|
||||
// Variables mapped as { key: { value } }
|
||||
expect(payload.variables).toStrictEqual({
|
||||
svc: { value: 'api', type: undefined },
|
||||
count: { value: 5, type: undefined },
|
||||
flag: { value: true, type: undefined },
|
||||
expect(payload.variables).toEqual({
|
||||
svc: { value: 'api' },
|
||||
count: { value: 5 },
|
||||
flag: { value: true },
|
||||
});
|
||||
|
||||
// Queries include one builder_query and one builder_formula
|
||||
@@ -229,7 +226,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: { A: 'LP' },
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -258,7 +255,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.legendMap).toStrictEqual({ A: 'LP' });
|
||||
expect(result.legendMap).toEqual({ A: 'LP' });
|
||||
|
||||
const payload: QueryRangePayloadV5 = result.queryPayload;
|
||||
expect(payload.requestType).toBe('time_series');
|
||||
@@ -299,7 +296,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: { Q: 'LC' },
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -327,7 +324,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.legendMap).toStrictEqual({ Q: 'LC' });
|
||||
expect(result.legendMap).toEqual({ Q: 'LC' });
|
||||
|
||||
const payload: QueryRangePayloadV5 = result.queryPayload;
|
||||
expect(payload.requestType).toBe('scalar');
|
||||
@@ -356,7 +353,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: {},
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -400,7 +397,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: { A: 'Legend A' },
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -474,7 +471,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: { A: 'Legend A' },
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -588,7 +585,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result).toStrictEqual(
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
legendMap: { A: '{{service.name}}' },
|
||||
queryPayload: expect.objectContaining({
|
||||
@@ -687,7 +684,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
const result = prepareQueryRangePayloadV5(props);
|
||||
|
||||
expect(result.legendMap).toStrictEqual({ A: 'Legend A' });
|
||||
expect(result.legendMap).toEqual({ A: 'Legend A' });
|
||||
expect(result.queryPayload.compositeQuery.queries).toHaveLength(1);
|
||||
|
||||
const builderQuery = result.queryPayload.compositeQuery.queries.find(
|
||||
@@ -697,7 +694,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
|
||||
expect(logSpec.name).toBe('A');
|
||||
expect(logSpec.signal).toBe('logs');
|
||||
expect(logSpec.filter).toStrictEqual({
|
||||
expect(logSpec.filter).toEqual({
|
||||
expression:
|
||||
"service.name = 'payment-service' AND http.status_code >= 400 AND message contains 'error'",
|
||||
});
|
||||
@@ -734,9 +731,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
(q) => q.type === 'builder_query',
|
||||
) as QueryEnvelope;
|
||||
const logSpec = builderQuery.spec as LogBuilderQuery;
|
||||
expect(logSpec.filter).toStrictEqual({
|
||||
expression: 'http.status_code >= 500',
|
||||
});
|
||||
expect(logSpec.filter).toEqual({ expression: 'http.status_code >= 500' });
|
||||
});
|
||||
|
||||
it('derives expression from filters when filter is undefined', () => {
|
||||
@@ -780,9 +775,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
(q) => q.type === 'builder_query',
|
||||
) as QueryEnvelope;
|
||||
const logSpec = builderQuery.spec as LogBuilderQuery;
|
||||
expect(logSpec.filter).toStrictEqual({
|
||||
expression: "service.name = 'checkout'",
|
||||
});
|
||||
expect(logSpec.filter).toEqual({ expression: "service.name = 'checkout'" });
|
||||
});
|
||||
|
||||
it('prefers filter.expression over filters when both are present', () => {
|
||||
@@ -826,9 +819,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
(q) => q.type === 'builder_query',
|
||||
) as QueryEnvelope;
|
||||
const logSpec = builderQuery.spec as LogBuilderQuery;
|
||||
expect(logSpec.filter).toStrictEqual({
|
||||
expression: "service.name = 'frontend'",
|
||||
});
|
||||
expect(logSpec.filter).toEqual({ expression: "service.name = 'frontend'" });
|
||||
});
|
||||
|
||||
it('returns empty expression when neither filter nor filters provided', () => {
|
||||
@@ -862,7 +853,7 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
(q) => q.type === 'builder_query',
|
||||
) as QueryEnvelope;
|
||||
const logSpec = builderQuery.spec as LogBuilderQuery;
|
||||
expect(logSpec.filter).toStrictEqual({ expression: '' });
|
||||
expect(logSpec.filter).toEqual({ expression: '' });
|
||||
});
|
||||
|
||||
it('returns empty expression when filters provided with empty items', () => {
|
||||
@@ -896,6 +887,6 @@ describe('prepareQueryRangePayloadV5', () => {
|
||||
(q) => q.type === 'builder_query',
|
||||
) as QueryEnvelope;
|
||||
const logSpec = builderQuery.spec as LogBuilderQuery;
|
||||
expect(logSpec.filter).toStrictEqual({ expression: '' });
|
||||
expect(logSpec.filter).toEqual({ expression: '' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -213,7 +213,7 @@ describe.each([
|
||||
const callArgs = mockDownloadExportData.mock.calls[0][0];
|
||||
const query = callArgs.body.compositeQuery.queries[0];
|
||||
expect(query.spec.groupBy).toBeUndefined();
|
||||
expect(query.spec.having).toStrictEqual({ expression: '' });
|
||||
expect(query.spec.having).toEqual({ expression: '' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -238,7 +238,7 @@ describe.each([
|
||||
expect(mockDownloadExportData).toHaveBeenCalledTimes(1);
|
||||
const callArgs = mockDownloadExportData.mock.calls[0][0];
|
||||
const query = callArgs.body.compositeQuery.queries[0];
|
||||
expect(query.spec.selectFields).toStrictEqual([
|
||||
expect(query.spec.selectFields).toEqual([
|
||||
expect.objectContaining({
|
||||
name: 'http.status',
|
||||
fieldDataType: 'int64',
|
||||
|
||||
@@ -6,39 +6,39 @@ jest.mock('react-dnd', () => ({
|
||||
}));
|
||||
|
||||
describe('Utils testing of DraggableTableRow component', () => {
|
||||
it('Should dropHandler return true', () => {
|
||||
test('Should dropHandler return true', () => {
|
||||
const monitor = {
|
||||
isOver: jest.fn().mockReturnValueOnce(true),
|
||||
} as never;
|
||||
const dropDataTruthy = dropHandler(monitor);
|
||||
|
||||
expect(dropDataTruthy).toStrictEqual({ isOver: true });
|
||||
expect(dropDataTruthy).toEqual({ isOver: true });
|
||||
});
|
||||
|
||||
it('Should dropHandler return false', () => {
|
||||
test('Should dropHandler return false', () => {
|
||||
const monitor = {
|
||||
isOver: jest.fn().mockReturnValueOnce(false),
|
||||
} as never;
|
||||
const dropDataFalsy = dropHandler(monitor);
|
||||
|
||||
expect(dropDataFalsy).toStrictEqual({ isOver: false });
|
||||
expect(dropDataFalsy).toEqual({ isOver: false });
|
||||
});
|
||||
|
||||
it('Should dragHandler return true', () => {
|
||||
test('Should dragHandler return true', () => {
|
||||
const monitor = {
|
||||
isDragging: jest.fn().mockReturnValueOnce(true),
|
||||
} as never;
|
||||
const dragDataTruthy = dragHandler(monitor);
|
||||
|
||||
expect(dragDataTruthy).toStrictEqual({ isDragging: true });
|
||||
expect(dragDataTruthy).toEqual({ isDragging: true });
|
||||
});
|
||||
|
||||
it('Should dragHandler return false', () => {
|
||||
test('Should dragHandler return false', () => {
|
||||
const monitor = {
|
||||
isDragging: jest.fn().mockReturnValueOnce(false),
|
||||
} as never;
|
||||
const dragDataFalsy = dragHandler(monitor);
|
||||
|
||||
expect(dragDataFalsy).toStrictEqual({ isDragging: false });
|
||||
expect(dragDataFalsy).toEqual({ isDragging: false });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -361,9 +361,9 @@ describe('EditMemberDrawer', () => {
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /delete member/i }));
|
||||
|
||||
await expect(
|
||||
screen.findByText(/are you sure you want to delete/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText(/are you sure you want to delete/i),
|
||||
).toBeInTheDocument();
|
||||
|
||||
const confirmBtns = screen.getAllByRole('button', { name: /delete member/i });
|
||||
await user.click(confirmBtns[confirmBtns.length - 1]);
|
||||
@@ -441,9 +441,9 @@ describe('EditMemberDrawer', () => {
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /revoke invite/i }));
|
||||
|
||||
await expect(
|
||||
screen.findByText(/Are you sure you want to revoke the invite/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText(/Are you sure you want to revoke the invite/i),
|
||||
).toBeInTheDocument();
|
||||
|
||||
const confirmBtns = screen.getAllByRole('button', { name: /revoke invite/i });
|
||||
await user.click(confirmBtns[confirmBtns.length - 1]);
|
||||
|
||||
@@ -64,7 +64,7 @@ export const legend = (id: string, isLonger: boolean): Plugin<ChartType> => ({
|
||||
// li.style.marginTop = '5px';
|
||||
|
||||
li.onclick = (): void => {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
const { type } = chart.config;
|
||||
if (type === 'pie' || type === 'doughnut') {
|
||||
// Pie and doughnut charts only have a single dataset and visibility is per item
|
||||
|
||||
@@ -9,65 +9,65 @@ describe('xAxisConfig for Chart', () => {
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'millisecond');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.millisecond);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.millisecond,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'second');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.second);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.second,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'minute');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.minute);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.minute,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'hour');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.hour);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.hour,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'day');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.day);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.day,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'week');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.week);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.week,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'month');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.month);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.month,
|
||||
);
|
||||
}
|
||||
{
|
||||
const start = dayjs();
|
||||
const end = start.add(10, 'year');
|
||||
|
||||
expect(
|
||||
convertTimeRange(start.valueOf(), end.valueOf()).unitName,
|
||||
).toStrictEqual(TIME_UNITS.year);
|
||||
expect(convertTimeRange(start.valueOf(), end.valueOf()).unitName).toEqual(
|
||||
TIME_UNITS.year,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ const testFullPrecisionGetYAxisFormattedValue = (
|
||||
): string => getYAxisFormattedValue(value, format, PrecisionOptionsEnum.FULL);
|
||||
|
||||
describe('getYAxisFormattedValue - none (full precision legacy assertions)', () => {
|
||||
it('large integers and decimals', () => {
|
||||
test('large integers and decimals', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('250034', 'none')).toBe(
|
||||
'250034',
|
||||
);
|
||||
@@ -22,7 +22,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves leading zeros after decimal until first non-zero', () => {
|
||||
test('preserves leading zeros after decimal until first non-zero', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1.0000234', 'none')).toBe(
|
||||
'1.0000234',
|
||||
);
|
||||
@@ -31,7 +31,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('trims to three significant decimals and removes trailing zeros', () => {
|
||||
test('trims to three significant decimals and removes trailing zeros', () => {
|
||||
expect(
|
||||
testFullPrecisionGetYAxisFormattedValue('0.000000250034', 'none'),
|
||||
).toBe('0.000000250034');
|
||||
@@ -55,7 +55,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
).toBe('0.00000025');
|
||||
});
|
||||
|
||||
it('whole numbers normalize', () => {
|
||||
test('whole numbers normalize', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1000', 'none')).toBe('1000');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('99.5458', 'none')).toBe(
|
||||
'99.5458',
|
||||
@@ -68,7 +68,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('strip redundant decimal zeros', () => {
|
||||
test('strip redundant decimal zeros', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1000.000', 'none')).toBe(
|
||||
'1000',
|
||||
);
|
||||
@@ -78,7 +78,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1.000', 'none')).toBe('1');
|
||||
});
|
||||
|
||||
it('edge values', () => {
|
||||
test('edge values', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0', 'none')).toBe('0');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('-0', 'none')).toBe('0');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('Infinity', 'none')).toBe('∞');
|
||||
@@ -92,7 +92,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('abc123', 'none')).toBe('NaN');
|
||||
});
|
||||
|
||||
it('small decimals keep precision as-is', () => {
|
||||
test('small decimals keep precision as-is', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0.0001', 'none')).toBe(
|
||||
'0.0001',
|
||||
);
|
||||
@@ -104,7 +104,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('simple decimals preserved', () => {
|
||||
test('simple decimals preserved', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0.1', 'none')).toBe('0.1');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0.2', 'none')).toBe('0.2');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0.3', 'none')).toBe('0.3');
|
||||
@@ -115,7 +115,7 @@ describe('getYAxisFormattedValue - none (full precision legacy assertions)', ()
|
||||
});
|
||||
|
||||
describe('getYAxisFormattedValue - units (full precision legacy assertions)', () => {
|
||||
it('ms', () => {
|
||||
test('ms', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1500', 'ms')).toBe('1.5 s');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('500', 'ms')).toBe('500 ms');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('60000', 'ms')).toBe('1 min');
|
||||
@@ -127,19 +127,19 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('s', () => {
|
||||
test('s', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('90', 's')).toBe('1.5 mins');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('30', 's')).toBe('30 s');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('3600', 's')).toBe('1 hour');
|
||||
});
|
||||
|
||||
it('m', () => {
|
||||
test('m', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('90', 'm')).toBe('1.5 hours');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('30', 'm')).toBe('30 min');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1440', 'm')).toBe('1 day');
|
||||
});
|
||||
|
||||
it('bytes', () => {
|
||||
test('bytes', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1024', 'bytes')).toBe(
|
||||
'1 KiB',
|
||||
);
|
||||
@@ -149,7 +149,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('mbytes', () => {
|
||||
test('mbytes', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1024', 'mbytes')).toBe(
|
||||
'1 GiB',
|
||||
);
|
||||
@@ -161,7 +161,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('kbytes', () => {
|
||||
test('kbytes', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1024', 'kbytes')).toBe(
|
||||
'1 MiB',
|
||||
);
|
||||
@@ -173,7 +173,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('short', () => {
|
||||
test('short', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1000', 'short')).toBe('1 K');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('1500', 'short')).toBe(
|
||||
'1.5 K',
|
||||
@@ -201,7 +201,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('percent', () => {
|
||||
test('percent', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0.15', 'percent')).toBe(
|
||||
'0.15%',
|
||||
);
|
||||
@@ -235,7 +235,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
).toBe('1.005555555595959%');
|
||||
});
|
||||
|
||||
it('ratio', () => {
|
||||
test('ratio', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0.5', 'ratio')).toBe(
|
||||
'0.5 ratio',
|
||||
);
|
||||
@@ -247,7 +247,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('temperature units', () => {
|
||||
test('temperature units', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('25', 'celsius')).toBe(
|
||||
'25 °C',
|
||||
);
|
||||
@@ -267,13 +267,13 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
);
|
||||
});
|
||||
|
||||
it('ms edge cases', () => {
|
||||
test('ms edge cases', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0', 'ms')).toBe('0 ms');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('-1500', 'ms')).toBe('-1.5 s');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('Infinity', 'ms')).toBe('∞');
|
||||
});
|
||||
|
||||
it('bytes edge cases', () => {
|
||||
test('bytes edge cases', () => {
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('0', 'bytes')).toBe('0 B');
|
||||
expect(testFullPrecisionGetYAxisFormattedValue('-1024', 'bytes')).toBe(
|
||||
'-1 KiB',
|
||||
@@ -282,7 +282,7 @@ describe('getYAxisFormattedValue - units (full precision legacy assertions)', ()
|
||||
});
|
||||
|
||||
describe('getYAxisFormattedValue - precision option tests', () => {
|
||||
it('precision 0 drops decimal part', () => {
|
||||
test('precision 0 drops decimal part', () => {
|
||||
expect(getYAxisFormattedValue('1.2345', 'none', 0)).toBe('1');
|
||||
expect(getYAxisFormattedValue('0.9999', 'none', 0)).toBe('0');
|
||||
expect(getYAxisFormattedValue('12345.6789', 'none', 0)).toBe('12345');
|
||||
@@ -294,7 +294,7 @@ describe('getYAxisFormattedValue - precision option tests', () => {
|
||||
// with unit
|
||||
expect(getYAxisFormattedValue('4353.81', 'ms', 0)).toBe('4 s');
|
||||
});
|
||||
it('precision 1,2,3,4 decimals', () => {
|
||||
test('precision 1,2,3,4 decimals', () => {
|
||||
expect(getYAxisFormattedValue('1.2345', 'none', 1)).toBe('1.2');
|
||||
expect(getYAxisFormattedValue('1.2345', 'none', 2)).toBe('1.23');
|
||||
expect(getYAxisFormattedValue('1.2345', 'none', 3)).toBe('1.234');
|
||||
@@ -345,7 +345,7 @@ describe('getYAxisFormattedValue - precision option tests', () => {
|
||||
expect(getYAxisFormattedValue('0.123456', 'percent', 4)).toBe('0.1235%'); // approximation
|
||||
});
|
||||
|
||||
it('precision full uses up to DEFAULT_SIGNIFICANT_DIGITS significant digits', () => {
|
||||
test('precision full uses up to DEFAULT_SIGNIFICANT_DIGITS significant digits', () => {
|
||||
expect(
|
||||
getYAxisFormattedValue(
|
||||
'0.00002625429914148441',
|
||||
|
||||
@@ -90,11 +90,11 @@ describe('InviteMembersModal', () => {
|
||||
screen.getByRole('button', { name: /invite team members/i }),
|
||||
);
|
||||
|
||||
await expect(
|
||||
screen.findByText(
|
||||
expect(
|
||||
await screen.findByText(
|
||||
'Please enter valid emails and select roles for team members',
|
||||
),
|
||||
).resolves.toBeInTheDocument();
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows email-only message when email is invalid but role is selected', async () => {
|
||||
@@ -112,9 +112,9 @@ describe('InviteMembersModal', () => {
|
||||
screen.getByRole('button', { name: /invite team members/i }),
|
||||
);
|
||||
|
||||
await expect(
|
||||
screen.findByText('Please enter valid emails for team members'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText('Please enter valid emails for team members'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows role-only message when email is valid but role is missing', async () => {
|
||||
@@ -130,9 +130,9 @@ describe('InviteMembersModal', () => {
|
||||
screen.getByRole('button', { name: /invite team members/i }),
|
||||
);
|
||||
|
||||
await expect(
|
||||
screen.findByText('Please select roles for team members'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText('Please select roles for team members'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import cx from 'classnames';
|
||||
import { LogType } from 'components/Logs/LogStateIndicator/LogStateIndicator';
|
||||
import QuerySearch from 'components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch';
|
||||
import { convertExpressionToFilters } from 'components/QueryBuilderV2/utils';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
||||
@@ -47,7 +46,6 @@ import {
|
||||
TextSelect,
|
||||
X,
|
||||
} from 'lucide-react';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
||||
@@ -81,10 +79,6 @@ function LogDetailInner({
|
||||
const [selectedView, setSelectedView] = useState<VIEWS>(selectedTab);
|
||||
|
||||
const [isFilterVisible, setIsFilterVisible] = useState<boolean>(false);
|
||||
const { featureFlags } = useAppContext();
|
||||
const isBodyJsonQueryEnabled =
|
||||
featureFlags?.find((flag) => flag.name === FeatureKeys.BODY_JSON_ENABLED)
|
||||
?.active || false;
|
||||
|
||||
const [filters, setFilters] = useState<TagFilter | null>(null);
|
||||
const [isEdit, setIsEdit] = useState<boolean>(false);
|
||||
@@ -214,29 +208,11 @@ function LogDetailInner({
|
||||
}
|
||||
};
|
||||
|
||||
const logBody = useMemo(() => {
|
||||
if (!isBodyJsonQueryEnabled) {
|
||||
return log?.body || '';
|
||||
}
|
||||
|
||||
try {
|
||||
const json = JSON.parse(log?.body || '');
|
||||
|
||||
if (typeof json?.message === 'string' && json.message !== '') {
|
||||
return json.message;
|
||||
}
|
||||
|
||||
return log?.body || '';
|
||||
} catch (error) {
|
||||
return log?.body || '';
|
||||
}
|
||||
}, [isBodyJsonQueryEnabled, log?.body]);
|
||||
|
||||
const htmlBody = useMemo(
|
||||
() => ({
|
||||
__html: getSanitizedLogBody(logBody || '', { shouldEscapeHtml: true }),
|
||||
__html: getSanitizedLogBody(log?.body || '', { shouldEscapeHtml: true }),
|
||||
}),
|
||||
[logBody],
|
||||
[log?.body],
|
||||
);
|
||||
|
||||
const handleJSONCopy = (): void => {
|
||||
@@ -442,7 +418,7 @@ function LogDetailInner({
|
||||
<div className="log-detail-drawer__log">
|
||||
<Divider type="vertical" className={cx('log-type-indicator', logType)} />
|
||||
<Tooltip
|
||||
title={removeEscapeCharacters(logBody)}
|
||||
title={removeEscapeCharacters(log?.body)}
|
||||
placement="left"
|
||||
mouseLeaveDelay={0}
|
||||
>
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('getLogIndicatorType', () => {
|
||||
expect(getLogIndicatorType(log)).toBe('TRACE');
|
||||
});
|
||||
|
||||
it('severity_text should be used when severity_number is absent', () => {
|
||||
it('severity_text should be used when severity_number is absent ', () => {
|
||||
const log = {
|
||||
date: '2024-02-29T12:34:46Z',
|
||||
timestamp: 1646115296,
|
||||
|
||||
@@ -75,7 +75,7 @@ function OptionsMenu({
|
||||
};
|
||||
|
||||
const handleSearchValueChange = useDebouncedFn((event): void => {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
const value = event?.target?.value || '';
|
||||
|
||||
if (addColumn && addColumn?.onSearch) {
|
||||
|
||||
@@ -50,7 +50,7 @@ function Code({
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
return !inline && match ? (
|
||||
<SyntaxHighlighter
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
style={a11yDark}
|
||||
language={match[1]}
|
||||
PreTag="div"
|
||||
@@ -115,7 +115,7 @@ function MarkdownRenderer({
|
||||
className={className}
|
||||
rehypePlugins={[rehypeRaw as any]}
|
||||
components={{
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
a: Link,
|
||||
pre: ({ children }) =>
|
||||
Pre({
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 1. CUSTOM VALUES SUPPORT =====
|
||||
describe('Custom Values Support (CS)', () => {
|
||||
it('CS-01: Custom values persist in selected state', async () => {
|
||||
test('CS-01: Custom values persist in selected state', async () => {
|
||||
const { rerender } = renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -87,7 +87,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(screen.getByText('another-custom')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('CS-02: Partial matches create custom values', async () => {
|
||||
test('CS-02: Partial matches create custom values', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -129,7 +129,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('CS-03: Exact match filtering behavior', async () => {
|
||||
test('CS-03: Exact match filtering behavior', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -176,7 +176,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('CS-04: Search filtering with "end" pattern', async () => {
|
||||
test('CS-04: Search filtering with "end" pattern', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -234,7 +234,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('CS-05: Comma-separated values behavior', async () => {
|
||||
test('CS-05: Comma-separated values behavior', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -281,7 +281,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 2. SEARCH AND FILTERING =====
|
||||
describe('Search and Filtering (SF)', () => {
|
||||
it('SF-01: Selected values pushed to top', async () => {
|
||||
test('SF-01: Selected values pushed to top', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -305,7 +305,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SF-02: Filtering with search text', async () => {
|
||||
test('SF-02: Filtering with search text', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -350,7 +350,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SF-03: Highlighting search matches', async () => {
|
||||
test('SF-03: Highlighting search matches', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -381,7 +381,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SF-04: Search with no results', async () => {
|
||||
test('SF-04: Search with no results', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -424,7 +424,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 3. KEYBOARD NAVIGATION =====
|
||||
describe('Keyboard Navigation (KN)', () => {
|
||||
it('KN-01: Arrow key navigation in dropdown', async () => {
|
||||
test('KN-01: Arrow key navigation in dropdown', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -465,7 +465,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('KN-02: Tab navigation to dropdown', async () => {
|
||||
test('KN-02: Tab navigation to dropdown', async () => {
|
||||
renderWithVirtuoso(
|
||||
<div>
|
||||
<input data-testid="prev-input" />
|
||||
@@ -515,7 +515,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('KN-03: Enter selection in dropdown', async () => {
|
||||
test('KN-03: Enter selection in dropdown', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -540,7 +540,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(mockOnChange).toHaveBeenCalledWith(['frontend'], ['frontend']);
|
||||
});
|
||||
|
||||
it('KN-04: Chip deletion with keyboard', async () => {
|
||||
test('KN-04: Chip deletion with keyboard', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -586,7 +586,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 5. UI/UX BEHAVIORS =====
|
||||
describe('UI/UX Behaviors (UI)', () => {
|
||||
it('UI-01: Loading state does not block interaction', async () => {
|
||||
test('UI-01: Loading state does not block interaction', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -603,7 +603,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('UI-02: Component remains editable in all states', async () => {
|
||||
test('UI-02: Component remains editable in all states', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -634,7 +634,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('UI-03: Toggle/Only labels in dropdown', async () => {
|
||||
test('UI-03: Toggle/Only labels in dropdown', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -656,7 +656,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('UI-04: Should display values with loading info at bottom', async () => {
|
||||
test('UI-04: Should display values with loading info at bottom', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -677,7 +677,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('UI-05: Error state display in footer', async () => {
|
||||
test('UI-05: Error state display in footer', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -696,7 +696,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('UI-06: No data state display', async () => {
|
||||
test('UI-06: No data state display', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={[]}
|
||||
@@ -716,7 +716,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 6. CLEAR ACTIONS =====
|
||||
describe('Clear Actions (CA)', () => {
|
||||
it('CA-01: Ctrl+A selects all chips', async () => {
|
||||
test('CA-01: Ctrl+A selects all chips', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -760,7 +760,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('CA-02: Clear icon removes all selections', async () => {
|
||||
test('CA-02: Clear icon removes all selections', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -777,7 +777,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('CA-03: Individual chip removal', async () => {
|
||||
test('CA-03: Individual chip removal', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -790,7 +790,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
const removeButtons = document.querySelectorAll(
|
||||
'.ant-select-selection-item-remove',
|
||||
);
|
||||
expect(removeButtons).toHaveLength(2);
|
||||
expect(removeButtons.length).toBe(2);
|
||||
|
||||
await user.click(removeButtons[1] as Element);
|
||||
|
||||
@@ -804,7 +804,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 7. SAVE AND SELECTION TRIGGERS =====
|
||||
describe('Save and Selection Triggers (ST)', () => {
|
||||
it('ST-01: ESC triggers save action', async () => {
|
||||
test('ST-01: ESC triggers save action', async () => {
|
||||
const mockDropdownChange = jest.fn();
|
||||
|
||||
renderWithVirtuoso(
|
||||
@@ -837,7 +837,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('ST-02: Mouse selection works', async () => {
|
||||
test('ST-02: Mouse selection works', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -859,7 +859,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('ST-03: ENTER in input field creates custom value', async () => {
|
||||
test('ST-03: ENTER in input field creates custom value', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -892,7 +892,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('ST-04: Search text persistence', async () => {
|
||||
test('ST-04: Search text persistence', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -932,7 +932,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 8. SPECIAL OPTIONS AND STATES =====
|
||||
describe('Special Options and States (SO)', () => {
|
||||
it('SO-01: ALL option appears first and separated', async () => {
|
||||
test('SO-01: ALL option appears first and separated', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -954,7 +954,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SO-02: ALL selection behavior', async () => {
|
||||
test('SO-02: ALL selection behavior', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -981,7 +981,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('SO-03: ALL tag display when all selected', () => {
|
||||
test('SO-03: ALL tag display when all selected', () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -996,7 +996,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(screen.queryByText('frontend')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('SO-04: Footer information display', async () => {
|
||||
test('SO-04: Footer information display', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1017,7 +1017,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== GROUPED OPTIONS SUPPORT =====
|
||||
describe('Grouped Options Support', () => {
|
||||
it('handles grouped options correctly', async () => {
|
||||
test('handles grouped options correctly', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockGroupedOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1041,7 +1041,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== ACCESSIBILITY TESTS =====
|
||||
describe('Accessibility', () => {
|
||||
it('has proper ARIA attributes', async () => {
|
||||
test('has proper ARIA attributes', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1058,7 +1058,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('supports screen reader navigation', async () => {
|
||||
test('supports screen reader navigation', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1079,7 +1079,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 9. ADVANCED KEYBOARD NAVIGATION =====
|
||||
describe('Advanced Keyboard Navigation (AKN)', () => {
|
||||
it('AKN-01: Shift + Arrow + Del chip deletion', async () => {
|
||||
test('AKN-01: Shift + Arrow + Del chip deletion', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -1137,7 +1137,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).toHaveFocus();
|
||||
});
|
||||
|
||||
it('AKN-03: Mouse out closes dropdown', async () => {
|
||||
test('AKN-03: Mouse out closes dropdown', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1164,7 +1164,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 10. ADVANCED FILTERING AND HIGHLIGHTING =====
|
||||
describe('Advanced Filtering and Highlighting (AFH)', () => {
|
||||
it('AFH-01: Highlighted values pushed to top', async () => {
|
||||
test('AFH-01: Highlighted values pushed to top', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1220,7 +1220,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('AFH-02: Distinction between selection Enter and save Enter', async () => {
|
||||
test('AFH-02: Distinction between selection Enter and save Enter', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1267,7 +1267,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 11. ADVANCED CLEAR ACTIONS =====
|
||||
describe('Advanced Clear Actions (ACA)', () => {
|
||||
it('ACA-01: Clear action waiting behavior', async () => {
|
||||
test('ACA-01: Clear action waiting behavior', async () => {
|
||||
const mockOnChangeWithDelay = jest.fn().mockImplementation(
|
||||
() =>
|
||||
new Promise<void>((resolve) => {
|
||||
@@ -1300,7 +1300,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 12. ADVANCED UI STATES =====
|
||||
describe('Advanced UI States (AUS)', () => {
|
||||
it('AUS-01: No data with previous value selected', async () => {
|
||||
test('AUS-01: No data with previous value selected', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={[]}
|
||||
@@ -1322,7 +1322,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(screen.getByText('previous-value')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('AUS-02: Always editable accessibility', async () => {
|
||||
test('AUS-02: Always editable accessibility', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -1338,7 +1338,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('AUS-03: Sufficient space for search value', async () => {
|
||||
test('AUS-03: Sufficient space for search value', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -1372,7 +1372,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 13. REGEX AND CUSTOM VALUES =====
|
||||
describe('Regex and Custom Values (RCV)', () => {
|
||||
it('RCV-01: Regex pattern support', async () => {
|
||||
test('RCV-01: Regex pattern support', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect
|
||||
options={mockOptions}
|
||||
@@ -1418,7 +1418,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('RCV-02: Custom values treated as normal dropdown values', async () => {
|
||||
test('RCV-02: Custom values treated as normal dropdown values', async () => {
|
||||
const customOptions = [
|
||||
...mockOptions,
|
||||
{ label: 'custom-value', value: 'custom-value', type: 'custom' as const },
|
||||
@@ -1456,7 +1456,7 @@ describe('CustomMultiSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 14. DROPDOWN PERSISTENCE =====
|
||||
describe('Dropdown Persistence (DP)', () => {
|
||||
it('DP-01: Dropdown stays open for non-save actions', async () => {
|
||||
test('DP-01: Dropdown stays open for non-save actions', async () => {
|
||||
renderWithVirtuoso(
|
||||
<CustomMultiSelect options={mockOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 1. CUSTOM VALUES SUPPORT =====
|
||||
describe('Custom Values Support (CS)', () => {
|
||||
it('CS-02: Partial matches create custom values', async () => {
|
||||
test('CS-02: Partial matches create custom values', async () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={mockOptions}
|
||||
@@ -110,7 +110,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('CS-03: Exact match behavior', async () => {
|
||||
test('CS-03: Exact match behavior', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -161,7 +161,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 2. SEARCH AND FILTERING =====
|
||||
describe('Search and Filtering (SF)', () => {
|
||||
it('SF-01: Selected values pushed to top', async () => {
|
||||
test('SF-01: Selected values pushed to top', async () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={mockOptions}
|
||||
@@ -185,7 +185,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SF-02: Real-time search filtering', async () => {
|
||||
test('SF-02: Real-time search filtering', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -228,7 +228,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SF-03: Search highlighting', async () => {
|
||||
test('SF-03: Search highlighting', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -257,7 +257,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('SF-04: Search with partial matches', async () => {
|
||||
test('SF-04: Search with partial matches', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -298,7 +298,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 3. KEYBOARD NAVIGATION =====
|
||||
describe('Keyboard Navigation (KN)', () => {
|
||||
it('KN-01: Arrow key navigation in dropdown', async () => {
|
||||
test('KN-01: Arrow key navigation in dropdown', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -329,7 +329,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('KN-02: Tab navigation to dropdown', async () => {
|
||||
test('KN-02: Tab navigation to dropdown', async () => {
|
||||
render(
|
||||
<div>
|
||||
<input data-testid="prev-input" />
|
||||
@@ -355,7 +355,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('KN-03: Enter selection in dropdown', async () => {
|
||||
test('KN-03: Enter selection in dropdown', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -376,7 +376,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('KN-04: Space key selection', async () => {
|
||||
test('KN-04: Space key selection', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -396,7 +396,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('KN-05: Tab navigation within dropdown', async () => {
|
||||
test('KN-05: Tab navigation within dropdown', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -417,7 +417,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 4. UI/UX BEHAVIORS =====
|
||||
describe('UI/UX Behaviors (UI)', () => {
|
||||
it('UI-01: Loading state does not block interaction', async () => {
|
||||
test('UI-01: Loading state does not block interaction', async () => {
|
||||
render(
|
||||
<CustomSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -429,7 +429,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).toHaveFocus();
|
||||
});
|
||||
|
||||
it('UI-02: Component remains editable in all states', () => {
|
||||
test('UI-02: Component remains editable in all states', () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={mockOptions}
|
||||
@@ -444,7 +444,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('UI-03: Loading state display in footer', async () => {
|
||||
test('UI-03: Loading state display in footer', async () => {
|
||||
render(
|
||||
<CustomSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -458,7 +458,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('UI-04: Error state display in footer', async () => {
|
||||
test('UI-04: Error state display in footer', async () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={mockOptions}
|
||||
@@ -477,7 +477,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('UI-05: No data state display', async () => {
|
||||
test('UI-05: No data state display', async () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={[]}
|
||||
@@ -497,7 +497,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 6. SAVE AND SELECTION TRIGGERS =====
|
||||
describe('Save and Selection Triggers (ST)', () => {
|
||||
it('ST-01: Mouse selection works', async () => {
|
||||
test('ST-01: Mouse selection works', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -520,7 +520,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 7. GROUPED OPTIONS SUPPORT =====
|
||||
describe('Grouped Options Support', () => {
|
||||
it('handles grouped options correctly', async () => {
|
||||
test('handles grouped options correctly', async () => {
|
||||
render(
|
||||
<CustomSelect options={mockGroupedOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -541,7 +541,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('grouped option selection works', async () => {
|
||||
test('grouped option selection works', async () => {
|
||||
render(
|
||||
<CustomSelect options={mockGroupedOptions} onChange={mockOnChange} />,
|
||||
);
|
||||
@@ -566,7 +566,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 8. ACCESSIBILITY =====
|
||||
describe('Accessibility', () => {
|
||||
it('has proper ARIA attributes', async () => {
|
||||
test('has proper ARIA attributes', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -580,7 +580,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('supports screen reader navigation', async () => {
|
||||
test('supports screen reader navigation', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -596,7 +596,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('has proper focus management', async () => {
|
||||
test('has proper focus management', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -617,7 +617,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 10. EDGE CASES =====
|
||||
describe('Edge Cases', () => {
|
||||
it('handles special characters in options', async () => {
|
||||
test('handles special characters in options', async () => {
|
||||
const specialOptions = [
|
||||
{ label: 'Option with spaces', value: 'option-with-spaces' },
|
||||
{ label: 'Option-with-dashes', value: 'option-with-dashes' },
|
||||
@@ -638,7 +638,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('handles extremely long option labels', async () => {
|
||||
test('handles extremely long option labels', async () => {
|
||||
const longLabelOptions = [
|
||||
{
|
||||
label:
|
||||
@@ -663,7 +663,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 11. ADVANCED KEYBOARD NAVIGATION =====
|
||||
describe('Advanced Keyboard Navigation (AKN)', () => {
|
||||
it('AKN-01: Mouse out closes dropdown', async () => {
|
||||
test('AKN-01: Mouse out closes dropdown', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -684,7 +684,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('AKN-02: TAB navigation from input to dropdown', async () => {
|
||||
test('AKN-02: TAB navigation from input to dropdown', async () => {
|
||||
render(
|
||||
<div>
|
||||
<input data-testid="prev-input" />
|
||||
@@ -722,7 +722,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 12. ADVANCED FILTERING AND HIGHLIGHTING =====
|
||||
describe('Advanced Filtering and Highlighting (AFH)', () => {
|
||||
it('AFH-01: Highlighted values pushed to top', async () => {
|
||||
test('AFH-01: Highlighted values pushed to top', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -776,7 +776,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('AFH-02: Distinction between selection Enter and save Enter', async () => {
|
||||
test('AFH-02: Distinction between selection Enter and save Enter', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -830,7 +830,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 13. ADVANCED CLEAR ACTIONS =====
|
||||
describe('Advanced Clear Actions (ACA)', () => {
|
||||
it('ACA-01: Clear action waiting behavior', async () => {
|
||||
test('ACA-01: Clear action waiting behavior', async () => {
|
||||
const mockOnChangeWithDelay = jest.fn().mockImplementation(
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
@@ -860,7 +860,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
expect(mockOnChangeWithDelay).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ACA-02: Single select clear behavior like text input', async () => {
|
||||
test('ACA-02: Single select clear behavior like text input', async () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={mockOptions}
|
||||
@@ -883,7 +883,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 14. ADVANCED UI STATES =====
|
||||
describe('Advanced UI States (AUS)', () => {
|
||||
it('AUS-01: No data with previous value selected', async () => {
|
||||
test('AUS-01: No data with previous value selected', async () => {
|
||||
render(
|
||||
<CustomSelect
|
||||
options={[]}
|
||||
@@ -905,7 +905,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
expect(screen.getAllByText('previous-value')).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('AUS-02: Always editable accessibility', async () => {
|
||||
test('AUS-02: Always editable accessibility', async () => {
|
||||
render(
|
||||
<CustomSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -921,7 +921,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
expect(combobox).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('AUS-03: Sufficient space for search value', async () => {
|
||||
test('AUS-03: Sufficient space for search value', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -950,7 +950,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('AUS-04: No spinners blocking user interaction', async () => {
|
||||
test('AUS-04: No spinners blocking user interaction', async () => {
|
||||
render(
|
||||
<CustomSelect options={mockOptions} onChange={mockOnChange} loading />,
|
||||
);
|
||||
@@ -976,7 +976,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 15. REGEX AND CUSTOM VALUES =====
|
||||
describe('Regex and Custom Values (RCV)', () => {
|
||||
it('RCV-01: Regex pattern support', async () => {
|
||||
test('RCV-01: Regex pattern support', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
@@ -1019,7 +1019,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('RCV-02: Custom values treated as normal dropdown values', async () => {
|
||||
test('RCV-02: Custom values treated as normal dropdown values', async () => {
|
||||
const customOptions = [
|
||||
...mockOptions,
|
||||
{ label: 'custom-value', value: 'custom-value', type: 'custom' as const },
|
||||
@@ -1051,7 +1051,7 @@ describe('CustomSelect - Comprehensive Tests', () => {
|
||||
|
||||
// ===== 16. DROPDOWN PERSISTENCE =====
|
||||
describe('Dropdown Persistence (DP)', () => {
|
||||
it('DP-01: Dropdown closes only on save actions', async () => {
|
||||
test('DP-01: Dropdown closes only on save actions', async () => {
|
||||
render(<CustomSelect options={mockOptions} onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole('combobox');
|
||||
|
||||
@@ -86,7 +86,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 1. INTEGRATION WITH CUSTOMSELECT =====
|
||||
describe('CustomSelect Integration (VI)', () => {
|
||||
it('VI-01: Single select variable integration', async () => {
|
||||
test('VI-01: Single select variable integration', async () => {
|
||||
const variable = createMockVariable({
|
||||
multiSelect: false,
|
||||
type: 'CUSTOM',
|
||||
@@ -130,7 +130,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 2. INTEGRATION WITH CUSTOMMULTISELECT =====
|
||||
describe('CustomMultiSelect Integration (VI)', () => {
|
||||
it('VI-02: Multi select variable integration', async () => {
|
||||
test('VI-02: Multi select variable integration', async () => {
|
||||
const variable = createMockVariable({
|
||||
multiSelect: true,
|
||||
type: 'CUSTOM',
|
||||
@@ -174,7 +174,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 3. TEXTBOX VARIABLE TYPE =====
|
||||
describe('Textbox Variable Integration', () => {
|
||||
it('VI-03: Textbox variable handling', async () => {
|
||||
test('VI-03: Textbox variable handling', async () => {
|
||||
const variable = createMockVariable({
|
||||
type: 'TEXTBOX',
|
||||
selectedValue: 'initial-value',
|
||||
@@ -219,7 +219,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 4. VALUE PERSISTENCE AND STATE MANAGEMENT =====
|
||||
describe('Value Persistence and State Management', () => {
|
||||
it('VI-04: All selected state handling', () => {
|
||||
test('VI-04: All selected state handling', () => {
|
||||
const variable = createMockVariable({
|
||||
multiSelect: true,
|
||||
type: 'CUSTOM',
|
||||
@@ -243,7 +243,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
expect(screen.getByText('ALL')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('VI-05: Dropdown behavior with temporary selections', async () => {
|
||||
test('VI-05: Dropdown behavior with temporary selections', async () => {
|
||||
const variable = createMockVariable({
|
||||
multiSelect: true,
|
||||
type: 'CUSTOM',
|
||||
@@ -277,7 +277,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 6. ACCESSIBILITY AND USER EXPERIENCE =====
|
||||
describe('Accessibility and User Experience', () => {
|
||||
it('VI-06: Variable description tooltip', async () => {
|
||||
test('VI-06: Variable description tooltip', async () => {
|
||||
const variable = createMockVariable({
|
||||
description: 'This variable controls the service selection',
|
||||
type: 'CUSTOM',
|
||||
@@ -310,7 +310,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('VI-07: Variable name display', () => {
|
||||
test('VI-07: Variable name display', () => {
|
||||
const variable = createMockVariable({
|
||||
name: 'service_name',
|
||||
type: 'CUSTOM',
|
||||
@@ -331,7 +331,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
expect(screen.getByText('$service_name')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('VI-08: Max tag count behavior', async () => {
|
||||
test('VI-08: Max tag count behavior', async () => {
|
||||
const variable = createMockVariable({
|
||||
multiSelect: true,
|
||||
type: 'CUSTOM',
|
||||
@@ -365,7 +365,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 8. SEARCH INTERACTION TESTS =====
|
||||
describe('Search Interaction Tests', () => {
|
||||
it('VI-14: Search persistence across dropdown open/close', async () => {
|
||||
test('VI-14: Search persistence across dropdown open/close', async () => {
|
||||
const variable = createMockVariable({
|
||||
type: 'CUSTOM',
|
||||
customValue: 'option1,option2,option3',
|
||||
@@ -417,7 +417,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 9. ADVANCED KEYBOARD NAVIGATION =====
|
||||
describe('Advanced Keyboard Navigation (VI)', () => {
|
||||
it('VI-15: Shift + Arrow + Del chip deletion in multiselect', async () => {
|
||||
test('VI-15: Shift + Arrow + Del chip deletion in multiselect', async () => {
|
||||
const variable = createMockVariable({
|
||||
type: 'CUSTOM',
|
||||
customValue: 'option1,option2,option3',
|
||||
@@ -461,7 +461,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 11. ADVANCED UI STATES =====
|
||||
describe('Advanced UI States (VI)', () => {
|
||||
it('VI-19: No data with previous value selected in variable', async () => {
|
||||
test('VI-19: No data with previous value selected in variable', async () => {
|
||||
const variable = createMockVariable({
|
||||
type: 'CUSTOM',
|
||||
customValue: '',
|
||||
@@ -499,7 +499,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
expect(combobox).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('VI-20: Always editable accessibility in variable', async () => {
|
||||
test('VI-20: Always editable accessibility in variable', async () => {
|
||||
const variable = createMockVariable({
|
||||
type: 'CUSTOM',
|
||||
customValue: 'option1,option2',
|
||||
@@ -530,7 +530,7 @@ describe('VariableItem Integration Tests', () => {
|
||||
|
||||
// ===== 13. DROPDOWN PERSISTENCE =====
|
||||
describe('Dropdown Persistence (VI)', () => {
|
||||
it('VI-24: Dropdown stays open for non-save actions in variable', async () => {
|
||||
test('VI-24: Dropdown stays open for non-save actions in variable', async () => {
|
||||
const variable = createMockVariable({
|
||||
type: 'CUSTOM',
|
||||
customValue: 'option1,option2,option3',
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('OverflowInputToolTip', () => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('shows tooltip when content overflows and input is clamped at maxAutoWidth', async () => {
|
||||
test('shows tooltip when content overflows and input is clamped at maxAutoWidth', async () => {
|
||||
mockOverflow(150, 250); // clientWidth >= maxAutoWidth (150), scrollWidth > clientWidth
|
||||
|
||||
render(<OverflowInputToolTip value="Very long overflowing text" />);
|
||||
@@ -64,7 +64,7 @@ describe('OverflowInputToolTip', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does NOT show tooltip when content does not overflow', async () => {
|
||||
test('does NOT show tooltip when content does not overflow', async () => {
|
||||
mockOverflow(150, 100); // content fits (scrollWidth <= clientWidth)
|
||||
|
||||
render(<OverflowInputToolTip value="Short text" />);
|
||||
@@ -76,7 +76,7 @@ describe('OverflowInputToolTip', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does NOT show tooltip when content overflows but input is NOT at maxAutoWidth', async () => {
|
||||
test('does NOT show tooltip when content overflows but input is NOT at maxAutoWidth', async () => {
|
||||
mockOverflow(100, 250); // clientWidth < maxAutoWidth (150), scrollWidth > clientWidth
|
||||
|
||||
render(<OverflowInputToolTip value="Long but input not clamped" />);
|
||||
@@ -88,7 +88,7 @@ describe('OverflowInputToolTip', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('uncontrolled input allows typing', async () => {
|
||||
test('uncontrolled input allows typing', async () => {
|
||||
render(<OverflowInputToolTip defaultValue="Init" />);
|
||||
|
||||
const input = screen.getByRole('textbox') as HTMLInputElement;
|
||||
@@ -97,7 +97,7 @@ describe('OverflowInputToolTip', () => {
|
||||
expect(input).toHaveValue('InitABC');
|
||||
});
|
||||
|
||||
it('disabled input never shows tooltip even if overflowing', async () => {
|
||||
test('disabled input never shows tooltip even if overflowing', async () => {
|
||||
mockOverflow(150, 300);
|
||||
|
||||
render(<OverflowInputToolTip value="Overflowing!" disabled />);
|
||||
@@ -109,7 +109,7 @@ describe('OverflowInputToolTip', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('renders mirror span and input correctly (structural assertions instead of snapshot)', () => {
|
||||
test('renders mirror span and input correctly (structural assertions instead of snapshot)', () => {
|
||||
const { container } = render(<OverflowInputToolTip value="Snapshot" />);
|
||||
const mirror = container.querySelector('.overflow-input-mirror');
|
||||
const input = container.querySelector('input') as HTMLInputElement | null;
|
||||
|
||||
@@ -29,7 +29,7 @@ describe('traceOperatorContextUtils', () => {
|
||||
null,
|
||||
);
|
||||
|
||||
expect(context).toStrictEqual({
|
||||
expect(context).toEqual({
|
||||
tokenType: TraceOperatorGrammarLexer.IDENTIFIER,
|
||||
text: 'test',
|
||||
start: 0,
|
||||
@@ -62,7 +62,7 @@ describe('traceOperatorContextUtils', () => {
|
||||
false,
|
||||
);
|
||||
|
||||
expect(context).toStrictEqual({
|
||||
expect(context).toEqual({
|
||||
tokenType: TraceOperatorGrammarLexer.IDENTIFIER,
|
||||
text: 'test',
|
||||
start: 0,
|
||||
@@ -193,7 +193,7 @@ describe('traceOperatorContextUtils', () => {
|
||||
it('should return default context for empty query', () => {
|
||||
const result = getTraceOperatorContextAtCursor('', 0);
|
||||
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
tokenType: -1,
|
||||
text: '',
|
||||
start: 0,
|
||||
@@ -211,7 +211,7 @@ describe('traceOperatorContextUtils', () => {
|
||||
it('should return default context for null query', () => {
|
||||
const result = getTraceOperatorContextAtCursor(null as any, 0);
|
||||
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
tokenType: -1,
|
||||
text: '',
|
||||
start: 0,
|
||||
@@ -229,7 +229,7 @@ describe('traceOperatorContextUtils', () => {
|
||||
it('should return default context for undefined query', () => {
|
||||
const result = getTraceOperatorContextAtCursor(undefined as any, 0);
|
||||
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
tokenType: -1,
|
||||
text: '',
|
||||
start: 0,
|
||||
|
||||
@@ -8,21 +8,21 @@ const makeTraceOperator = (expression: string): IBuilderTraceOperator =>
|
||||
describe('getInvolvedQueriesInTraceOperator', () => {
|
||||
it('returns empty array for empty input', () => {
|
||||
const result = getInvolvedQueriesInTraceOperator([]);
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('extracts identifiers from expression', () => {
|
||||
const result = getInvolvedQueriesInTraceOperator([
|
||||
makeTraceOperator('A => B'),
|
||||
]);
|
||||
expect(result).toStrictEqual(['A', 'B']);
|
||||
expect(result).toEqual(['A', 'B']);
|
||||
});
|
||||
|
||||
it('extracts identifiers from complex expression', () => {
|
||||
const result = getInvolvedQueriesInTraceOperator([
|
||||
makeTraceOperator('A => (NOT B || C)'),
|
||||
]);
|
||||
expect(result).toStrictEqual(['A', 'B', 'C']);
|
||||
expect(result).toEqual(['A', 'B', 'C']);
|
||||
});
|
||||
|
||||
it('filters out querynames from complex expression', () => {
|
||||
@@ -31,7 +31,7 @@ describe('getInvolvedQueriesInTraceOperator', () => {
|
||||
'(A1 && (NOT B2 || (C3 -> (D4 && E5)))) => ((F6 || G7) && (NOT (H8 -> I9)))',
|
||||
),
|
||||
]);
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
'A1',
|
||||
'B2',
|
||||
'C3',
|
||||
|
||||
@@ -85,7 +85,7 @@ describe('previousQuery.utils', () => {
|
||||
saveAsPreviousQuery(key, sampleQuery);
|
||||
|
||||
const fromStore = getPreviousQueryFromKey(key);
|
||||
expect(fromStore).toStrictEqual(sampleQuery);
|
||||
expect(fromStore).toEqual(sampleQuery);
|
||||
});
|
||||
|
||||
it('saveAsPreviousQuery merges multiple entries and removeKeyFromPreviousQuery deletes one', () => {
|
||||
|
||||
@@ -22,20 +22,18 @@ describe('convertFiltersToExpression', () => {
|
||||
|
||||
it('should handle empty, null, and undefined inputs', () => {
|
||||
// Test null and undefined
|
||||
expect(convertFiltersToExpression(null as any)).toStrictEqual({
|
||||
expression: '',
|
||||
});
|
||||
expect(convertFiltersToExpression(undefined as any)).toStrictEqual({
|
||||
expect(convertFiltersToExpression(null as any)).toEqual({ expression: '' });
|
||||
expect(convertFiltersToExpression(undefined as any)).toEqual({
|
||||
expression: '',
|
||||
});
|
||||
|
||||
// Test empty filters
|
||||
expect(convertFiltersToExpression({ items: [], op: 'AND' })).toStrictEqual({
|
||||
expect(convertFiltersToExpression({ items: [], op: 'AND' })).toEqual({
|
||||
expression: '',
|
||||
});
|
||||
expect(
|
||||
convertFiltersToExpression({ items: undefined, op: 'AND' } as any),
|
||||
).toStrictEqual({ expression: '' });
|
||||
).toEqual({ expression: '' });
|
||||
});
|
||||
|
||||
it('should convert basic comparison operators with proper value formatting', () => {
|
||||
@@ -94,7 +92,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"service = 'api-gateway' AND status != 'error' AND duration > 100 AND count <= 50 AND is_active = true AND enabled = false AND count = 0 AND regex REGEXP '.*'",
|
||||
});
|
||||
@@ -126,7 +124,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"message = 'user\\'s data' AND description = '' AND path = '/api/v1/users'",
|
||||
});
|
||||
@@ -164,7 +162,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"service in ['api-gateway', 'user-service', 'auth-service'] AND status in ['success'] AND tags in [] AND name in ['John\\'s', 'Mary\\'s', 'Bob']",
|
||||
});
|
||||
@@ -226,7 +224,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"service NOT IN ['api-gateway', 'user-service'] AND message NOT LIKE 'error' AND path NOT REGEXP '/api/.*' AND service NOT IN ['api-gateway'] AND user_id NOT EXISTS AND description NOT CONTAINS 'error' AND NOT has(tags, 'production') AND NOT hasAny(labels, ['env:prod', 'service:api'])",
|
||||
});
|
||||
@@ -270,7 +268,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"user_id exists AND user_id exists AND has(tags, 'production') AND hasAny(tags, ['production', 'staging']) AND hasAll(tags, ['production', 'monitoring'])",
|
||||
});
|
||||
@@ -314,7 +312,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"service = 'api-gateway' AND status = 'success' AND service in ['api-gateway']",
|
||||
});
|
||||
@@ -364,7 +362,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"service in ['api-gateway', 'user-service'] AND user_id exists AND has(tags, 'production') AND duration > 100 AND status NOT IN ['error', 'timeout'] AND method = 'POST'",
|
||||
});
|
||||
@@ -414,7 +412,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"count = 0 AND score > 100 AND limit >= 50 AND threshold < 1000 AND max_value <= 999 AND values in ['1', '2', '3', '4', '5']",
|
||||
});
|
||||
@@ -458,7 +456,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"is_active = true AND is_deleted = false AND email = 'user@example.com' AND description = 'Contains \"quotes\" and \\'apostrophes\\'' AND path = '/api/v1/users/123?filter=true'",
|
||||
});
|
||||
@@ -508,7 +506,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"has(tags, 'production') AND hasAny(labels, ['env:prod', 'service:api']) AND hasAll(metadata, ['version:1.0', 'team:backend']) AND services in ['api-gateway', 'user-service', 'auth-service', 'payment-service'] AND excluded_services NOT IN ['legacy-service', 'deprecated-service'] AND status_codes in ['200', '201', '400', '500']",
|
||||
});
|
||||
@@ -546,7 +544,7 @@ describe('convertFiltersToExpression', () => {
|
||||
};
|
||||
|
||||
const result = convertFiltersToExpression(filters);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
expression:
|
||||
"user_id NOT EXISTS AND description NOT CONTAINS 'error' AND NOT has(tags, 'production') AND NOT hasAny(labels, ['env:prod', 'service:api'])",
|
||||
});
|
||||
@@ -570,7 +568,7 @@ describe('convertFiltersToExpression', () => {
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(result.filters).toStrictEqual(filters);
|
||||
expect(result.filters).toEqual(filters);
|
||||
expect(result.filter.expression).toBe("service.name = 'test-service'");
|
||||
});
|
||||
|
||||
@@ -585,7 +583,7 @@ describe('convertFiltersToExpression', () => {
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(result.filters).toStrictEqual(filters);
|
||||
expect(result.filters).toEqual(filters);
|
||||
expect(result.filter.expression).toBe('');
|
||||
});
|
||||
|
||||
@@ -613,7 +611,7 @@ describe('convertFiltersToExpression', () => {
|
||||
expect(result.filter).toBeDefined();
|
||||
expect(result.filter.expression).toBe("service.name = 'updated-service'");
|
||||
// Ensure parser can parse the existing query
|
||||
expect(extractQueryPairs(existingQuery)).toStrictEqual(
|
||||
expect(extractQueryPairs(existingQuery)).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
key: 'service.name',
|
||||
@@ -807,7 +805,7 @@ describe('convertAggregationToExpression', () => {
|
||||
temporality: 'delta',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
metricName: 'test_metric',
|
||||
timeAggregation: 'avg',
|
||||
@@ -827,11 +825,9 @@ describe('convertAggregationToExpression', () => {
|
||||
spaceAggregation: 'noop',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
metricName: 'test_metric',
|
||||
reduceTo: undefined,
|
||||
temporality: undefined,
|
||||
timeAggregation: 'count',
|
||||
spaceAggregation: 'count',
|
||||
},
|
||||
@@ -845,11 +841,9 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.METRICS,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
metricName: '',
|
||||
reduceTo: undefined,
|
||||
temporality: undefined,
|
||||
timeAggregation: 'sum',
|
||||
spaceAggregation: 'sum',
|
||||
},
|
||||
@@ -864,7 +858,7 @@ describe('convertAggregationToExpression', () => {
|
||||
alias: 'trace_alias',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
expression: 'count(test_metric)',
|
||||
alias: 'trace_alias',
|
||||
@@ -880,7 +874,7 @@ describe('convertAggregationToExpression', () => {
|
||||
alias: 'log_alias',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
expression: 'avg(test_metric)',
|
||||
alias: 'log_alias',
|
||||
@@ -895,7 +889,7 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.TRACES,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
expression: 'count()',
|
||||
},
|
||||
@@ -909,7 +903,7 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.LOGS,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
expression: 'sum(test_metric)',
|
||||
},
|
||||
@@ -923,11 +917,9 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.METRICS,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
metricName: 'test_metric',
|
||||
reduceTo: undefined,
|
||||
temporality: undefined,
|
||||
timeAggregation: 'max',
|
||||
spaceAggregation: 'max',
|
||||
},
|
||||
@@ -941,7 +933,7 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.METRICS,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
metricName: 'test_metric',
|
||||
timeAggregation: 'sum',
|
||||
@@ -959,7 +951,7 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.TRACES,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
expression: 'count()',
|
||||
},
|
||||
@@ -973,7 +965,7 @@ describe('convertAggregationToExpression', () => {
|
||||
dataSource: DataSource.LOGS,
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{
|
||||
expression: 'count()',
|
||||
},
|
||||
|
||||
@@ -471,6 +471,6 @@ describe('CheckboxFilter - User Flows', () => {
|
||||
|
||||
expect(filterForServiceName.key.key).toBe(SERVICE_NAME_KEY);
|
||||
expect(filterForServiceName.op).toBe('in');
|
||||
expect(filterForServiceName.value).toStrictEqual(['mq-kafka', 'otel-demo']);
|
||||
expect(filterForServiceName.value).toEqual(['mq-kafka', 'otel-demo']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -323,9 +323,7 @@ describe('Quick Filters with custom filters', () => {
|
||||
const settingsButton = icon.closest('button') ?? icon;
|
||||
await user.click(settingsButton);
|
||||
|
||||
await expect(
|
||||
screen.findByText('Edit quick filters'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('Edit quick filters')).toBeInTheDocument();
|
||||
|
||||
const addedSection = screen.getByText(ADDED_FILTERS_LABEL).parentElement!;
|
||||
expect(addedSection).toContainElement(
|
||||
@@ -456,7 +454,7 @@ describe('Quick Filters with custom filters', () => {
|
||||
});
|
||||
|
||||
const requestBody = putHandler.mock.calls[0][0];
|
||||
expect(requestBody.filters).toStrictEqual(
|
||||
expect(requestBody.filters).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.not.objectContaining({ key: FILTER_OS_DESCRIPTION }),
|
||||
]),
|
||||
@@ -537,16 +535,12 @@ describe('Quick Filters refetch behavior', () => {
|
||||
);
|
||||
|
||||
const { unmount } = render(<TestQuickFilters signal={SIGNAL} />);
|
||||
await expect(
|
||||
screen.findByText(FILTER_SERVICE_NAME),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(FILTER_SERVICE_NAME)).toBeInTheDocument();
|
||||
|
||||
unmount();
|
||||
|
||||
render(<TestQuickFilters signal={SIGNAL} />);
|
||||
await expect(
|
||||
screen.findByText(FILTER_SERVICE_NAME),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(FILTER_SERVICE_NAME)).toBeInTheDocument();
|
||||
|
||||
expect(getCalls).toBe(2);
|
||||
});
|
||||
@@ -584,9 +578,7 @@ describe('Quick Filters refetch behavior', () => {
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<TestQuickFilters signal={SIGNAL} />);
|
||||
|
||||
await expect(
|
||||
screen.findByText(FILTER_SERVICE_NAME),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(FILTER_SERVICE_NAME)).toBeInTheDocument();
|
||||
|
||||
const icon = await screen.findByTestId(SETTINGS_ICON_TEST_ID);
|
||||
const settingsButton = icon.closest('button') ?? icon;
|
||||
@@ -636,9 +628,7 @@ describe('Quick Filters refetch behavior', () => {
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<TestQuickFilters signal={SIGNAL} />);
|
||||
|
||||
await expect(
|
||||
screen.findByText(FILTER_SERVICE_NAME),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(FILTER_SERVICE_NAME)).toBeInTheDocument();
|
||||
|
||||
const icon = await screen.findByTestId(SETTINGS_ICON_TEST_ID);
|
||||
const settingsButton = icon.closest('button') ?? icon;
|
||||
@@ -667,8 +657,6 @@ describe('Quick Filters refetch behavior', () => {
|
||||
|
||||
render(<TestQuickFilters signal={SIGNAL} config={[]} />);
|
||||
|
||||
await expect(
|
||||
screen.findByText('No filters found'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('No filters found')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ const testRoutes: RouteTabProps['routes'] = [
|
||||
];
|
||||
|
||||
describe('RouteTab component', () => {
|
||||
it('renders correctly', () => {
|
||||
test('renders correctly', () => {
|
||||
const history = createMemoryHistory();
|
||||
render(
|
||||
<Router history={history}>
|
||||
@@ -39,7 +39,7 @@ describe('RouteTab component', () => {
|
||||
expect(screen.getByRole('tab', { name: 'Tab2' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correct number of tabs', () => {
|
||||
test('renders correct number of tabs', () => {
|
||||
const history = createMemoryHistory();
|
||||
render(
|
||||
<Router history={history}>
|
||||
@@ -47,10 +47,10 @@ describe('RouteTab component', () => {
|
||||
</Router>,
|
||||
);
|
||||
const tabs = screen.getAllByRole('tab');
|
||||
expect(tabs).toHaveLength(testRoutes.length);
|
||||
expect(tabs.length).toBe(testRoutes.length);
|
||||
});
|
||||
|
||||
it('sets provided activeKey as active tab', () => {
|
||||
test('sets provided activeKey as active tab', () => {
|
||||
const history = createMemoryHistory();
|
||||
render(
|
||||
<Router history={history}>
|
||||
@@ -62,7 +62,7 @@ describe('RouteTab component', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('navigates to correct route on tab click', () => {
|
||||
test('navigates to correct route on tab click', () => {
|
||||
const history = createMemoryHistory();
|
||||
render(
|
||||
<Router history={history}>
|
||||
@@ -74,7 +74,7 @@ describe('RouteTab component', () => {
|
||||
expect(history.location.pathname).toBe('/tab2');
|
||||
});
|
||||
|
||||
it('calls onChangeHandler on tab change', () => {
|
||||
test('calls onChangeHandler on tab change', () => {
|
||||
const onChangeHandler = jest.fn();
|
||||
const history = createMemoryHistory();
|
||||
render(
|
||||
|
||||
@@ -70,9 +70,9 @@ describe('EditKeyModal (URL-controlled)', () => {
|
||||
it('renders key data from prop when edit-key param is set', async () => {
|
||||
renderModal();
|
||||
|
||||
await expect(
|
||||
screen.findByDisplayValue('Original Key Name'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByDisplayValue('Original Key Name'),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /Save Changes/i })).toBeDisabled();
|
||||
});
|
||||
|
||||
@@ -111,7 +111,7 @@ describe('EditKeyModal (URL-controlled)', () => {
|
||||
|
||||
const latestUrlUpdate =
|
||||
onUrlUpdate.mock.calls[onUrlUpdate.mock.calls.length - 1]?.[0];
|
||||
expect(latestUrlUpdate).toStrictEqual(
|
||||
expect(latestUrlUpdate).toEqual(
|
||||
expect.objectContaining({
|
||||
queryString: expect.any(String),
|
||||
}),
|
||||
@@ -134,9 +134,9 @@ describe('EditKeyModal (URL-controlled)', () => {
|
||||
await user.click(screen.getByRole('button', { name: /Revoke Key/i }));
|
||||
|
||||
// Same dialog, now showing revoke confirmation
|
||||
await expect(
|
||||
screen.findByRole('dialog', { name: /Revoke Original Key Name/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('dialog', { name: /Revoke Original Key Name/i }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Revoking this key will permanently invalidate it/i),
|
||||
).toBeInTheDocument();
|
||||
|
||||
@@ -104,9 +104,7 @@ describe('ServiceAccountDrawer', () => {
|
||||
it('renders Overview tab by default: editable name input, locked email, Save disabled when not dirty', async () => {
|
||||
renderDrawer();
|
||||
|
||||
await expect(
|
||||
screen.findByDisplayValue('CI Bot'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByDisplayValue('CI Bot')).toBeInTheDocument();
|
||||
expect(screen.getByText('ci-bot@signoz.io')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /Save Changes/i })).toBeDisabled();
|
||||
});
|
||||
@@ -274,11 +272,11 @@ describe('ServiceAccountDrawer', () => {
|
||||
|
||||
renderDrawer();
|
||||
|
||||
await expect(
|
||||
screen.findByText(
|
||||
expect(
|
||||
await screen.findByText(
|
||||
/An unexpected error occurred while fetching service account details/i,
|
||||
),
|
||||
).resolves.toBeInTheDocument();
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -351,11 +349,11 @@ describe('ServiceAccountDrawer – save-error UX', () => {
|
||||
await waitFor(() => expect(saveBtn).not.toBeDisabled());
|
||||
await user.click(saveBtn);
|
||||
|
||||
await expect(
|
||||
screen.findByText(/Name update.*name update failed/i, undefined, {
|
||||
expect(
|
||||
await screen.findByText(/Name update.*name update failed/i, undefined, {
|
||||
timeout: 5000,
|
||||
}),
|
||||
).resolves.toBeInTheDocument();
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('role add failure shows SaveErrorItem with the role name context', async () => {
|
||||
@@ -387,11 +385,15 @@ describe('ServiceAccountDrawer – save-error UX', () => {
|
||||
await waitFor(() => expect(saveBtn).not.toBeDisabled());
|
||||
await user.click(saveBtn);
|
||||
|
||||
await expect(
|
||||
screen.findByText(/Role 'signoz-viewer'.*role assign failed/i, undefined, {
|
||||
timeout: 5000,
|
||||
}),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText(
|
||||
/Role 'signoz-viewer'.*role assign failed/i,
|
||||
undefined,
|
||||
{
|
||||
timeout: 5000,
|
||||
},
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('role add retries on 429 then succeeds without showing an error', async () => {
|
||||
|
||||
@@ -63,9 +63,7 @@ describe('TanStackCustomTableRow', () => {
|
||||
</tbody>
|
||||
</table>,
|
||||
);
|
||||
await expect(
|
||||
screen.findByTestId('mocked-row-cells'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByTestId('mocked-row-cells')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('applies active class when isRowActive returns true', () => {
|
||||
|
||||
@@ -183,7 +183,7 @@ describe('TanStackRowCells', () => {
|
||||
</tbody>
|
||||
</table>,
|
||||
);
|
||||
await expect(screen.findByText('expanded-r1')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('expanded-r1')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('new tab click', () => {
|
||||
|
||||
@@ -36,7 +36,7 @@ describe('useColumnState', () => {
|
||||
renderHook(() => useColumnState({ storageKey: TEST_KEY, columns }));
|
||||
|
||||
const state = useColumnStore.getState().tables[TEST_KEY];
|
||||
expect(state.hiddenColumnIds).toStrictEqual(['b']);
|
||||
expect(state.hiddenColumnIds).toEqual(['b']);
|
||||
});
|
||||
|
||||
it('does not initialize without storageKey', () => {
|
||||
@@ -61,7 +61,7 @@ describe('useColumnState', () => {
|
||||
useColumnState({ storageKey: TEST_KEY, columns }),
|
||||
);
|
||||
|
||||
expect(result.current.columnVisibility).toStrictEqual({ b: false });
|
||||
expect(result.current.columnVisibility).toEqual({ b: false });
|
||||
});
|
||||
|
||||
it('applies visibilityBehavior for grouped state', () => {
|
||||
@@ -79,15 +79,13 @@ describe('useColumnState', () => {
|
||||
const { result: notGrouped } = renderHook(() =>
|
||||
useColumnState({ storageKey: TEST_KEY, columns, isGrouped: false }),
|
||||
);
|
||||
expect(notGrouped.current.columnVisibility).toStrictEqual({
|
||||
grouped: false,
|
||||
});
|
||||
expect(notGrouped.current.columnVisibility).toEqual({ grouped: false });
|
||||
|
||||
// Grouped
|
||||
const { result: grouped } = renderHook(() =>
|
||||
useColumnState({ storageKey: TEST_KEY, columns, isGrouped: true }),
|
||||
);
|
||||
expect(grouped.current.columnVisibility).toStrictEqual({ ungrouped: false });
|
||||
expect(grouped.current.columnVisibility).toEqual({ ungrouped: false });
|
||||
});
|
||||
|
||||
it('combines store hidden + visibilityBehavior', () => {
|
||||
@@ -105,10 +103,7 @@ describe('useColumnState', () => {
|
||||
useColumnState({ storageKey: TEST_KEY, columns, isGrouped: true }),
|
||||
);
|
||||
|
||||
expect(result.current.columnVisibility).toStrictEqual({
|
||||
a: false,
|
||||
b: false,
|
||||
});
|
||||
expect(result.current.columnVisibility).toEqual({ a: false, b: false });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -124,7 +119,7 @@ describe('useColumnState', () => {
|
||||
useColumnState({ storageKey: TEST_KEY, columns }),
|
||||
);
|
||||
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toStrictEqual([
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toEqual([
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
@@ -143,7 +138,7 @@ describe('useColumnState', () => {
|
||||
useColumnState({ storageKey: TEST_KEY, columns }),
|
||||
);
|
||||
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toStrictEqual([
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toEqual([
|
||||
'c',
|
||||
'a',
|
||||
'b',
|
||||
@@ -162,7 +157,7 @@ describe('useColumnState', () => {
|
||||
useColumnState({ storageKey: TEST_KEY, columns }),
|
||||
);
|
||||
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toStrictEqual([
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toEqual([
|
||||
'pinned',
|
||||
'b',
|
||||
'a',
|
||||
@@ -186,7 +181,7 @@ describe('useColumnState', () => {
|
||||
result.current.hideColumn('a');
|
||||
});
|
||||
|
||||
expect(result.current.columnVisibility).toStrictEqual({ a: false });
|
||||
expect(result.current.columnVisibility).toEqual({ a: false });
|
||||
});
|
||||
|
||||
it('showColumn shows a column', () => {
|
||||
@@ -200,13 +195,13 @@ describe('useColumnState', () => {
|
||||
useColumnState({ storageKey: TEST_KEY, columns }),
|
||||
);
|
||||
|
||||
expect(result.current.columnVisibility).toStrictEqual({ a: false });
|
||||
expect(result.current.columnVisibility).toEqual({ a: false });
|
||||
|
||||
act(() => {
|
||||
result.current.showColumn('a');
|
||||
});
|
||||
|
||||
expect(result.current.columnVisibility).toStrictEqual({});
|
||||
expect(result.current.columnVisibility).toEqual({});
|
||||
});
|
||||
|
||||
it('setColumnSizing updates sizing', () => {
|
||||
@@ -224,7 +219,7 @@ describe('useColumnState', () => {
|
||||
result.current.setColumnSizing({ a: 200 });
|
||||
});
|
||||
|
||||
expect(result.current.columnSizing).toStrictEqual({ a: 200 });
|
||||
expect(result.current.columnSizing).toEqual({ a: 200 });
|
||||
});
|
||||
|
||||
it('setColumnOrder updates order from column array', () => {
|
||||
@@ -242,7 +237,7 @@ describe('useColumnState', () => {
|
||||
result.current.setColumnOrder([col('c'), col('a'), col('b')]);
|
||||
});
|
||||
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toStrictEqual([
|
||||
expect(result.current.sortedColumns.map((c) => c.id)).toEqual([
|
||||
'c',
|
||||
'a',
|
||||
'b',
|
||||
|
||||
@@ -29,9 +29,9 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const state = useColumnStore.getState().tables[TEST_KEY];
|
||||
expect(state.hiddenColumnIds).toStrictEqual(['b']);
|
||||
expect(state.columnOrder).toStrictEqual([]);
|
||||
expect(state.columnSizing).toStrictEqual({});
|
||||
expect(state.hiddenColumnIds).toEqual(['b']);
|
||||
expect(state.columnOrder).toEqual([]);
|
||||
expect(state.columnSizing).toEqual({});
|
||||
});
|
||||
|
||||
it('does not reinitialize if already exists', () => {
|
||||
@@ -124,9 +124,7 @@ describe('useColumnStore', () => {
|
||||
.getState()
|
||||
.setColumnSizing(TEST_KEY, { col1: 200, col2: 300 });
|
||||
});
|
||||
expect(
|
||||
useColumnStore.getState().tables[TEST_KEY].columnSizing,
|
||||
).toStrictEqual({
|
||||
expect(useColumnStore.getState().tables[TEST_KEY].columnSizing).toEqual({
|
||||
col1: 200,
|
||||
col2: 300,
|
||||
});
|
||||
@@ -146,9 +144,11 @@ describe('useColumnStore', () => {
|
||||
.getState()
|
||||
.setColumnOrder(TEST_KEY, ['col2', 'col1', 'col3']);
|
||||
});
|
||||
expect(useColumnStore.getState().tables[TEST_KEY].columnOrder).toStrictEqual(
|
||||
['col2', 'col1', 'col3'],
|
||||
);
|
||||
expect(useColumnStore.getState().tables[TEST_KEY].columnOrder).toEqual([
|
||||
'col2',
|
||||
'col1',
|
||||
'col3',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -172,9 +172,9 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const state = useColumnStore.getState().tables[TEST_KEY];
|
||||
expect(state.hiddenColumnIds).toStrictEqual(['a']);
|
||||
expect(state.columnOrder).toStrictEqual([]);
|
||||
expect(state.columnSizing).toStrictEqual({});
|
||||
expect(state.hiddenColumnIds).toEqual(['a']);
|
||||
expect(state.columnOrder).toEqual([]);
|
||||
expect(state.columnSizing).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -195,7 +195,7 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const state = useColumnStore.getState().tables[TEST_KEY];
|
||||
expect(state.hiddenColumnIds).toStrictEqual(['col1', 'col3']);
|
||||
expect(state.hiddenColumnIds).toEqual(['col1', 'col3']);
|
||||
expect(state.hiddenColumnIds).not.toContain('col2');
|
||||
});
|
||||
|
||||
@@ -216,7 +216,7 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const stateAfter = useColumnStore.getState().tables[TEST_KEY];
|
||||
expect(stateAfter.hiddenColumnIds).toStrictEqual(hiddenBefore);
|
||||
expect(stateAfter.hiddenColumnIds).toEqual(hiddenBefore);
|
||||
});
|
||||
|
||||
it('does nothing for unknown storage key', () => {
|
||||
@@ -242,7 +242,7 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useHiddenColumnIds(TEST_KEY));
|
||||
expect(result.current).toStrictEqual(['a']);
|
||||
expect(result.current).toEqual(['a']);
|
||||
});
|
||||
|
||||
it('useHiddenColumnIds returns a stable snapshot for persisted state', () => {
|
||||
@@ -270,7 +270,7 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useColumnSizing(TEST_KEY));
|
||||
expect(result.current).toStrictEqual({ col1: 150 });
|
||||
expect(result.current).toEqual({ col1: 150 });
|
||||
});
|
||||
|
||||
it('useColumnOrder returns order', () => {
|
||||
@@ -280,7 +280,7 @@ describe('useColumnStore', () => {
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useColumnOrder(TEST_KEY));
|
||||
expect(result.current).toStrictEqual(['c', 'b', 'a']);
|
||||
expect(result.current).toEqual(['c', 'b', 'a']);
|
||||
});
|
||||
|
||||
it('returns empty defaults for unknown storageKey', () => {
|
||||
@@ -288,9 +288,9 @@ describe('useColumnStore', () => {
|
||||
const { result: sizing } = renderHook(() => useColumnSizing('unknown'));
|
||||
const { result: order } = renderHook(() => useColumnOrder('unknown'));
|
||||
|
||||
expect(hidden.current).toStrictEqual([]);
|
||||
expect(sizing.current).toStrictEqual({});
|
||||
expect(order.current).toStrictEqual([]);
|
||||
expect(hidden.current).toEqual([]);
|
||||
expect(sizing.current).toEqual({});
|
||||
expect(order.current).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -80,10 +80,7 @@ describe('useTableParams (local mode — enableQueryParams not set)', () => {
|
||||
act(() => {
|
||||
result.current.setOrderBy({ columnName: 'cpu', order: 'desc' });
|
||||
});
|
||||
expect(result.current.orderBy).toStrictEqual({
|
||||
columnName: 'cpu',
|
||||
order: 'desc',
|
||||
});
|
||||
expect(result.current.orderBy).toEqual({ columnName: 'cpu', order: 'desc' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -146,10 +143,7 @@ describe('useTableParams (URL mode — enableQueryParams set)', () => {
|
||||
const orderBy = JSON.stringify({ columnName: 'name', order: 'desc' });
|
||||
const wrapper = createNuqsWrapper({ order_by: orderBy });
|
||||
const { result } = renderHook(() => useTableParams(true), { wrapper });
|
||||
expect(result.current.orderBy).toStrictEqual({
|
||||
columnName: 'name',
|
||||
order: 'desc',
|
||||
});
|
||||
expect(result.current.orderBy).toEqual({ columnName: 'name', order: 'desc' });
|
||||
});
|
||||
|
||||
it('updates URL when setPage is called', () => {
|
||||
@@ -184,7 +178,7 @@ describe('useTableParams (URL mode — enableQueryParams set)', () => {
|
||||
.filter(Boolean)
|
||||
.pop();
|
||||
expect(lastOrderBy).toBeDefined();
|
||||
expect(JSON.parse(lastOrderBy!)).toStrictEqual({
|
||||
expect(JSON.parse(lastOrderBy!)).toEqual({
|
||||
columnName: 'value',
|
||||
order: 'asc',
|
||||
});
|
||||
@@ -213,7 +207,7 @@ describe('useTableParams (URL mode — enableQueryParams set)', () => {
|
||||
result.current.setExpanded({ 'row-1': true });
|
||||
});
|
||||
|
||||
expect(result.current.expanded).toStrictEqual({ 'row-1': true });
|
||||
expect(result.current.expanded).toEqual({ 'row-1': true });
|
||||
});
|
||||
|
||||
it('toggles sort order correctly: null → asc → desc → null', () => {
|
||||
@@ -228,19 +222,13 @@ describe('useTableParams (URL mode — enableQueryParams set)', () => {
|
||||
act(() => {
|
||||
result.current.setOrderBy({ columnName: 'id', order: 'asc' });
|
||||
});
|
||||
expect(result.current.orderBy).toStrictEqual({
|
||||
columnName: 'id',
|
||||
order: 'asc',
|
||||
});
|
||||
expect(result.current.orderBy).toEqual({ columnName: 'id', order: 'asc' });
|
||||
|
||||
// Second click: asc → desc
|
||||
act(() => {
|
||||
result.current.setOrderBy({ columnName: 'id', order: 'desc' });
|
||||
});
|
||||
expect(result.current.orderBy).toStrictEqual({
|
||||
columnName: 'id',
|
||||
order: 'desc',
|
||||
});
|
||||
expect(result.current.orderBy).toEqual({ columnName: 'id', order: 'desc' });
|
||||
|
||||
// Third click: desc → null
|
||||
act(() => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { formatUniversalUnit } from '../formatter';
|
||||
|
||||
describe('formatUniversalUnit', () => {
|
||||
describe('Time', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Days
|
||||
[31, UniversalYAxisUnit.DAYS, '4.43 weeks'],
|
||||
[7, UniversalYAxisUnit.DAYS, '1 week'],
|
||||
@@ -48,7 +48,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Data', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Bytes
|
||||
[864, UniversalYAxisUnit.BYTES, '864 B'],
|
||||
[1000, UniversalYAxisUnit.BYTES, '1 kB'],
|
||||
@@ -91,7 +91,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Data rate', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Bytes/second
|
||||
[864, UniversalYAxisUnit.BYTES_SECOND, '864 B/s'],
|
||||
[1000, UniversalYAxisUnit.BYTES_SECOND, '1 kB/s'],
|
||||
@@ -134,7 +134,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Bit', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Bits
|
||||
[1, UniversalYAxisUnit.BITS, '1 b'],
|
||||
[250, UniversalYAxisUnit.BITS, '250 b'],
|
||||
@@ -186,7 +186,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Bit rate', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Bits/second
|
||||
[512, UniversalYAxisUnit.BITS_SECOND, '512 b/s'],
|
||||
[1000, UniversalYAxisUnit.BITS_SECOND, '1 kb/s'],
|
||||
@@ -236,7 +236,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Count', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[100, UniversalYAxisUnit.COUNT, '100'],
|
||||
[875, UniversalYAxisUnit.COUNT, '875'],
|
||||
[1000, UniversalYAxisUnit.COUNT, '1 K'],
|
||||
@@ -256,7 +256,7 @@ describe('formatUniversalUnit', () => {
|
||||
expect(formatUniversalUnit(value, unit)).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
test.each([
|
||||
[100, UniversalYAxisUnit.COUNT_SECOND, '100 c/s'],
|
||||
[875, UniversalYAxisUnit.COUNT_SECOND, '875 c/s'],
|
||||
[1000, UniversalYAxisUnit.COUNT_SECOND, '1K c/s'],
|
||||
@@ -267,7 +267,7 @@ describe('formatUniversalUnit', () => {
|
||||
expect(formatUniversalUnit(value, unit)).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
test.each([
|
||||
[100, UniversalYAxisUnit.COUNT_MINUTE, '100 c/m'],
|
||||
[875, UniversalYAxisUnit.COUNT_MINUTE, '875 c/m'],
|
||||
[1000, UniversalYAxisUnit.COUNT_MINUTE, '1K c/m'],
|
||||
@@ -280,7 +280,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Operations units', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[780, UniversalYAxisUnit.OPS_SECOND, '780 ops/s'],
|
||||
[1000, UniversalYAxisUnit.OPS_SECOND, '1K ops/s'],
|
||||
[520, UniversalYAxisUnit.OPS_MINUTE, '520 ops/m'],
|
||||
@@ -297,7 +297,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Request units', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[615, UniversalYAxisUnit.REQUESTS_SECOND, '615 req/s'],
|
||||
[1000, UniversalYAxisUnit.REQUESTS_SECOND, '1K req/s'],
|
||||
[480, UniversalYAxisUnit.REQUESTS_MINUTE, '480 req/m'],
|
||||
@@ -311,7 +311,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Read/Write units', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[505, UniversalYAxisUnit.READS_SECOND, '505 rd/s'],
|
||||
[1000, UniversalYAxisUnit.READS_SECOND, '1K rd/s'],
|
||||
[610, UniversalYAxisUnit.WRITES_SECOND, '610 wr/s'],
|
||||
@@ -335,7 +335,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('IO Operations units', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[777, UniversalYAxisUnit.IOOPS_SECOND, '777 io/s'],
|
||||
[1000, UniversalYAxisUnit.IOOPS_SECOND, '1K io/s'],
|
||||
[2500, UniversalYAxisUnit.IOOPS_SECOND, '2.5K io/s'],
|
||||
@@ -363,7 +363,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Time (additional)', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[900, UniversalYAxisUnit.DURATION_MS, '900 milliseconds'],
|
||||
[1000, UniversalYAxisUnit.DURATION_MS, '1 second'],
|
||||
[1, UniversalYAxisUnit.DURATION_MS, '1 millisecond'],
|
||||
@@ -388,7 +388,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Data (IEC/Binary)', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Bytes
|
||||
[900, UniversalYAxisUnit.BYTES_IEC, '900 B'],
|
||||
[1024, UniversalYAxisUnit.BYTES_IEC, '1 KiB'],
|
||||
@@ -430,7 +430,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Data Rate (IEC/Binary)', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Kibibytes/second
|
||||
[900, UniversalYAxisUnit.KIBIBYTES_SECOND, '900 KiB/s'],
|
||||
[1024, UniversalYAxisUnit.KIBIBYTES_SECOND, '1 MiB/s'],
|
||||
@@ -473,7 +473,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Bits (IEC)', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[900, UniversalYAxisUnit.BITS_IEC, '900 b'],
|
||||
[1024, UniversalYAxisUnit.BITS_IEC, '1 Kib'],
|
||||
[1080, UniversalYAxisUnit.BITS_IEC, '1.05 Kib'],
|
||||
@@ -483,7 +483,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Hash Rate', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// Hashes/second
|
||||
[412, UniversalYAxisUnit.HASH_RATE_HASHES_PER_SECOND, '412 H/s'],
|
||||
[1000, UniversalYAxisUnit.HASH_RATE_HASHES_PER_SECOND, '1 kH/s'],
|
||||
@@ -518,7 +518,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Miscellaneous', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[742, UniversalYAxisUnit.MISC_STRING, '742'],
|
||||
[688, UniversalYAxisUnit.MISC_SHORT, '688'],
|
||||
[555, UniversalYAxisUnit.MISC_HUMIDITY, '555 %H'],
|
||||
@@ -534,7 +534,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Acceleration', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[
|
||||
875,
|
||||
UniversalYAxisUnit.ACCELERATION_METERS_PER_SECOND_SQUARED,
|
||||
@@ -553,7 +553,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Angular', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[415, UniversalYAxisUnit.ANGULAR_DEGREE, '415 °'],
|
||||
[732, UniversalYAxisUnit.ANGULAR_RADIAN, '732 rad'],
|
||||
[128, UniversalYAxisUnit.ANGULAR_GRADIAN, '128 grad'],
|
||||
@@ -565,7 +565,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Area', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[210, UniversalYAxisUnit.AREA_SQUARE_METERS, '210 m²'],
|
||||
[152, UniversalYAxisUnit.AREA_SQUARE_FEET, '152 ft²'],
|
||||
[64, UniversalYAxisUnit.AREA_SQUARE_MILES, '64 mi²'],
|
||||
@@ -575,7 +575,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('FLOPs', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
// FLOPS
|
||||
[150, UniversalYAxisUnit.FLOPS_FLOPS, '150 FLOPS'],
|
||||
[1000, UniversalYAxisUnit.FLOPS_FLOPS, '1 kFLOPS'],
|
||||
@@ -613,7 +613,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Concentration', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[415, UniversalYAxisUnit.CONCENTRATION_PPM, '415 ppm'],
|
||||
[1000, UniversalYAxisUnit.CONCENTRATION_PPM, '1000 ppm'],
|
||||
[732, UniversalYAxisUnit.CONCENTRATION_PPB, '732 ppb'],
|
||||
@@ -650,7 +650,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Currency', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[812, UniversalYAxisUnit.CURRENCY_USD, '$812'],
|
||||
[645, UniversalYAxisUnit.CURRENCY_GBP, '£645'],
|
||||
[731, UniversalYAxisUnit.CURRENCY_EUR, '€731'],
|
||||
@@ -688,7 +688,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Power/Electrical', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[715, UniversalYAxisUnit.POWER_WATT, '715 W'],
|
||||
[1000, UniversalYAxisUnit.POWER_WATT, '1 kW'],
|
||||
[1080, UniversalYAxisUnit.POWER_WATT, '1.08 kW'],
|
||||
@@ -744,7 +744,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Flow', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[512, UniversalYAxisUnit.FLOW_GALLONS_PER_MINUTE, '512 gpm'],
|
||||
[1000, UniversalYAxisUnit.FLOW_GALLONS_PER_MINUTE, '1000 gpm'],
|
||||
[678, UniversalYAxisUnit.FLOW_CUBIC_METERS_PER_SECOND, '678 cms'],
|
||||
@@ -766,7 +766,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Force', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[845, UniversalYAxisUnit.FORCE_NEWTON_METERS, '845 Nm'],
|
||||
[1000, UniversalYAxisUnit.FORCE_NEWTON_METERS, '1 kNm'],
|
||||
[1080, UniversalYAxisUnit.FORCE_NEWTON_METERS, '1.08 kNm'],
|
||||
@@ -782,7 +782,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Mass', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[120, UniversalYAxisUnit.MASS_MILLIGRAM, '120 mg'],
|
||||
[120000, UniversalYAxisUnit.MASS_MILLIGRAM, '120 g'],
|
||||
[987, UniversalYAxisUnit.MASS_GRAM, '987 g'],
|
||||
@@ -796,7 +796,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Length', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[88, UniversalYAxisUnit.LENGTH_MILLIMETER, '88 mm'],
|
||||
[100, UniversalYAxisUnit.LENGTH_MILLIMETER, '100 mm'],
|
||||
[1000, UniversalYAxisUnit.LENGTH_MILLIMETER, '1 m'],
|
||||
@@ -812,7 +812,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Pressure', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[45, UniversalYAxisUnit.PRESSURE_MILLIBAR, '45 mbar'],
|
||||
[1013, UniversalYAxisUnit.PRESSURE_MILLIBAR, '1.01 bar'],
|
||||
[27, UniversalYAxisUnit.PRESSURE_BAR, '27 bar'],
|
||||
@@ -828,7 +828,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Radiation', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[452, UniversalYAxisUnit.RADIATION_BECQUEREL, '452 Bq'],
|
||||
[37, UniversalYAxisUnit.RADIATION_CURIE, '37 Ci'],
|
||||
[128, UniversalYAxisUnit.RADIATION_GRAY, '128 Gy'],
|
||||
@@ -849,7 +849,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Rotation Speed', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[345, UniversalYAxisUnit.ROTATION_SPEED_REVOLUTIONS_PER_MINUTE, '345 rpm'],
|
||||
[789, UniversalYAxisUnit.ROTATION_SPEED_HERTZ, '789 Hz'],
|
||||
[789000, UniversalYAxisUnit.ROTATION_SPEED_HERTZ, '789 kHz'],
|
||||
@@ -861,7 +861,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Temperature', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[37, UniversalYAxisUnit.TEMPERATURE_CELSIUS, '37 °C'],
|
||||
[451, UniversalYAxisUnit.TEMPERATURE_FAHRENHEIT, '451 °F'],
|
||||
[310, UniversalYAxisUnit.TEMPERATURE_KELVIN, '310 K'],
|
||||
@@ -871,7 +871,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Velocity', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[900, UniversalYAxisUnit.VELOCITY_METERS_PER_SECOND, '900 m/s'],
|
||||
[456, UniversalYAxisUnit.VELOCITY_KILOMETERS_PER_HOUR, '456 km/h'],
|
||||
[789, UniversalYAxisUnit.VELOCITY_MILES_PER_HOUR, '789 mph'],
|
||||
@@ -882,7 +882,7 @@ describe('formatUniversalUnit', () => {
|
||||
});
|
||||
|
||||
describe('Volume', () => {
|
||||
it.each([
|
||||
test.each([
|
||||
[1200, UniversalYAxisUnit.VOLUME_MILLILITER, '1.2 L'],
|
||||
[9000000, UniversalYAxisUnit.VOLUME_MILLILITER, '9 kL'],
|
||||
[9, UniversalYAxisUnit.VOLUME_LITER, '9 L'],
|
||||
|
||||
@@ -16,8 +16,8 @@ describe('YAxisUnitSelector utils', () => {
|
||||
|
||||
it('returns null or self for unknown units', () => {
|
||||
expect(mapMetricUnitToUniversalUnit('unknown_unit')).toBe('unknown_unit');
|
||||
expect(mapMetricUnitToUniversalUnit('')).toBeNull();
|
||||
expect(mapMetricUnitToUniversalUnit(undefined)).toBeNull();
|
||||
expect(mapMetricUnitToUniversalUnit('')).toBe(null);
|
||||
expect(mapMetricUnitToUniversalUnit(undefined)).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -62,7 +62,7 @@ describe('YAxisUnitSelector utils', () => {
|
||||
},
|
||||
];
|
||||
const mergedCategories = mergeCategories(categories1, categories2);
|
||||
expect(mergedCategories).toStrictEqual([
|
||||
expect(mergedCategories).toEqual([
|
||||
{
|
||||
name: YAxisCategoryNames.Data,
|
||||
units: [
|
||||
|
||||
@@ -149,7 +149,7 @@ describe('CmdKPalette', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders navigation and settings groups and items', () => {
|
||||
test('renders navigation and settings groups and items', () => {
|
||||
render(<CmdKPalette userRole="ADMIN" />);
|
||||
|
||||
expect(screen.getByText('Navigation')).toBeInTheDocument();
|
||||
@@ -160,7 +160,7 @@ describe('CmdKPalette', () => {
|
||||
expect(screen.getByText('Switch to Dark Mode')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('clicking a navigation item calls history.push with correct route', async () => {
|
||||
test('clicking a navigation item calls history.push with correct route', async () => {
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<CmdKPalette userRole="ADMIN" />);
|
||||
|
||||
@@ -170,14 +170,14 @@ describe('CmdKPalette', () => {
|
||||
expect(history.push).toHaveBeenCalledWith(ROUTES.HOME);
|
||||
});
|
||||
|
||||
it('role-based filtering (basic smoke)', () => {
|
||||
test('role-based filtering (basic smoke)', () => {
|
||||
render(<CmdKPalette userRole="VIEWER" />);
|
||||
|
||||
// VIEWER still sees basic navigation items
|
||||
expect(screen.getByText(HOME_LABEL)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('keyboard shortcut opens palette via setOpen', () => {
|
||||
test('keyboard shortcut opens palette via setOpen', () => {
|
||||
render(<CmdKPalette userRole="ADMIN" />);
|
||||
|
||||
const event = new KeyboardEvent('keydown', { key: 'k', ctrlKey: true });
|
||||
@@ -186,7 +186,7 @@ describe('CmdKPalette', () => {
|
||||
expect(mockSetOpen).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('items render with icons when provided', () => {
|
||||
test('items render with icons when provided', () => {
|
||||
render(<CmdKPalette userRole="ADMIN" />);
|
||||
|
||||
const iconHolders = document.querySelectorAll('.cmd-item-icon');
|
||||
@@ -194,7 +194,7 @@ describe('CmdKPalette', () => {
|
||||
expect(screen.getByText(HOME_LABEL)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('closing the palette via handleInvoke sets open to false', async () => {
|
||||
test('closing the palette via handleInvoke sets open to false', async () => {
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<CmdKPalette userRole="ADMIN" />);
|
||||
|
||||
|
||||
@@ -9,5 +9,4 @@ export enum FeatureKeys {
|
||||
ANOMALY_DETECTION = 'anomaly_detection',
|
||||
ONBOARDING_V3 = 'onboarding_v3',
|
||||
DOT_METRICS_ENABLED = 'dot_metrics_enabled',
|
||||
BODY_JSON_ENABLED = 'body_json_enabled',
|
||||
}
|
||||
|
||||
@@ -34,13 +34,13 @@ describe('Alert Channels Settings List page', () => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
describe('Should display the Alert Channels page properly', () => {
|
||||
it('Should check if "The alerts will be sent to all the configured channels." is visible', () => {
|
||||
it('Should check if "The alerts will be sent to all the configured channels." is visible ', () => {
|
||||
expect(screen.getByText('sending_channels_note')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if "New Alert Channel" Button is visble', () => {
|
||||
it('Should check if "New Alert Channel" Button is visble ', () => {
|
||||
expect(screen.getByText('button_new_channel')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if the help icon is visible and displays "tooltip_notification_channels', async () => {
|
||||
it('Should check if the help icon is visible and displays "tooltip_notification_channels ', async () => {
|
||||
const helpIcon = screen.getByLabelText('question-circle');
|
||||
|
||||
fireEvent.mouseOver(helpIcon);
|
||||
|
||||
@@ -38,7 +38,7 @@ describe('Alert Channels Settings List page (Normal User)', () => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
describe('Should display the Alert Channels page properly', () => {
|
||||
it('Should check if "The alerts will be sent to all the configured channels." is visible', async () => {
|
||||
it('Should check if "The alerts will be sent to all the configured channels." is visible ', async () => {
|
||||
await waitFor(() =>
|
||||
expect(screen.getByText('sending_channels_note')).toBeInTheDocument(),
|
||||
);
|
||||
@@ -51,7 +51,7 @@ describe('Alert Channels Settings List page (Normal User)', () => {
|
||||
await waitFor(() => expect(newAlertButton).toBeInTheDocument());
|
||||
expect(newAlertButton).toBeDisabled();
|
||||
});
|
||||
it('Should check if the help icon is visible and displays "tooltip_notification_channels', async () => {
|
||||
it('Should check if the help icon is visible and displays "tooltip_notification_channels ', async () => {
|
||||
const helpIcon = screen.getByLabelText('question-circle');
|
||||
fireEvent.mouseOver(helpIcon);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('Create Alert Channel', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
describe('Should check if the new alert channel is properly displayed with the cascading fields of slack channel', () => {
|
||||
describe('Should check if the new alert channel is properly displayed with the cascading fields of slack channel ', () => {
|
||||
beforeEach(() => {
|
||||
render(<CreateAlertChannels preType={ChannelType.Slack} />);
|
||||
});
|
||||
@@ -54,13 +54,13 @@ describe('Create Alert Channel', () => {
|
||||
it('Should check if the title is "New Notification Channels"', () => {
|
||||
expect(screen.getByText('page_title_create')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if the name label and textbox are displayed properly', () => {
|
||||
it('Should check if the name label and textbox are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_channel_name',
|
||||
testId: 'channel-name-textbox',
|
||||
});
|
||||
});
|
||||
it('Should check if Send resolved alerts label and checkbox are displayed properly', () => {
|
||||
it('Should check if Send resolved alerts label and checkbox are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_send_resolved',
|
||||
testId: 'field-send-resolved-checkbox',
|
||||
@@ -76,13 +76,13 @@ describe('Create Alert Channel', () => {
|
||||
it('Should check if the selected item in the type dropdown has text "Slack"', () => {
|
||||
expect(screen.getByText('Slack')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if Webhook URL label and input are displayed properly', () => {
|
||||
it('Should check if Webhook URL label and input are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_url',
|
||||
testId: 'webhook-url-textbox',
|
||||
});
|
||||
});
|
||||
it('Should check if Recepient label, input, and help text are displayed properly', () => {
|
||||
it('Should check if Recepient label, input, and help text are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_recipient',
|
||||
testId: 'slack-channel-textbox',
|
||||
@@ -90,7 +90,7 @@ describe('Create Alert Channel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Title label and text area are displayed properly', () => {
|
||||
it('Should check if Title label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_title',
|
||||
testId: 'title-textarea',
|
||||
@@ -101,7 +101,7 @@ describe('Create Alert Channel', () => {
|
||||
|
||||
expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue);
|
||||
});
|
||||
it('Should check if Description label and text area are displayed properly', () => {
|
||||
it('Should check if Description label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_description',
|
||||
testId: 'description-textarea',
|
||||
@@ -177,13 +177,13 @@ describe('Create Alert Channel', () => {
|
||||
it('Should check if the selected item in the type dropdown has text "Webhook"', () => {
|
||||
expect(screen.getByText('Webhook')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if Webhook URL label and input are displayed properly', () => {
|
||||
it('Should check if Webhook URL label and input are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_url',
|
||||
testId: 'webhook-url-textbox',
|
||||
});
|
||||
});
|
||||
it('Should check if Webhook User Name label, input, and help text are displayed properly', () => {
|
||||
it('Should check if Webhook User Name label, input, and help text are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_username',
|
||||
testId: 'webhook-username-textbox',
|
||||
@@ -321,7 +321,7 @@ describe('Create Alert Channel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Message contains the default template', () => {
|
||||
it('Should check if Message contains the default template ', () => {
|
||||
const messageTextArea = screen.getByTestId('opsgenie-message-textarea');
|
||||
|
||||
expect(messageTextArea).toHaveValue(opsGenieMessageDefaultValue);
|
||||
@@ -387,14 +387,14 @@ describe('Create Alert Channel', () => {
|
||||
expect(screen.getByText('Microsoft Teams')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should check if Webhook URL label and input are displayed properly', () => {
|
||||
it('Should check if Webhook URL label and input are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_url',
|
||||
testId: 'webhook-url-textbox',
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Title label and text area are displayed properly', () => {
|
||||
it('Should check if Title label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_title',
|
||||
testId: 'title-textarea',
|
||||
@@ -406,7 +406,7 @@ describe('Create Alert Channel', () => {
|
||||
|
||||
expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue);
|
||||
});
|
||||
it('Should check if Description label and text area are displayed properly', () => {
|
||||
it('Should check if Description label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_description',
|
||||
testId: 'description-textarea',
|
||||
|
||||
@@ -23,20 +23,20 @@ describe('Create Alert Channel (Normal User)', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
describe('Should check if the new alert channel is properly displayed with the cascading fields of slack channel', () => {
|
||||
describe('Should check if the new alert channel is properly displayed with the cascading fields of slack channel ', () => {
|
||||
beforeEach(() => {
|
||||
render(<CreateAlertChannels preType={ChannelType.Slack} />);
|
||||
});
|
||||
it('Should check if the title is "New Notification Channels"', () => {
|
||||
expect(screen.getByText('page_title_create')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if the name label and textbox are displayed properly', () => {
|
||||
it('Should check if the name label and textbox are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_channel_name',
|
||||
testId: 'channel-name-textbox',
|
||||
});
|
||||
});
|
||||
it('Should check if Send resolved alerts label and checkbox are displayed properly', () => {
|
||||
it('Should check if Send resolved alerts label and checkbox are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_send_resolved',
|
||||
testId: 'field-send-resolved-checkbox',
|
||||
@@ -52,13 +52,13 @@ describe('Create Alert Channel (Normal User)', () => {
|
||||
it('Should check if the selected item in the type dropdown has text "Slack"', () => {
|
||||
expect(screen.getByText('Slack')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if Webhook URL label and input are displayed properly', () => {
|
||||
it('Should check if Webhook URL label and input are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_url',
|
||||
testId: 'webhook-url-textbox',
|
||||
});
|
||||
});
|
||||
it('Should check if Recepient label, input, and help text are displayed properly', () => {
|
||||
it('Should check if Recepient label, input, and help text are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_recipient',
|
||||
testId: 'slack-channel-textbox',
|
||||
@@ -66,7 +66,7 @@ describe('Create Alert Channel (Normal User)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Title label and text area are displayed properly', () => {
|
||||
it('Should check if Title label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_title',
|
||||
testId: 'title-textarea',
|
||||
@@ -77,7 +77,7 @@ describe('Create Alert Channel (Normal User)', () => {
|
||||
|
||||
expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue);
|
||||
});
|
||||
it('Should check if Description label and text area are displayed properly', () => {
|
||||
it('Should check if Description label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_description',
|
||||
testId: 'description-textarea',
|
||||
@@ -103,13 +103,13 @@ describe('Create Alert Channel (Normal User)', () => {
|
||||
it('Should check if the selected item in the type dropdown has text "Webhook"', () => {
|
||||
expect(screen.getByText('Webhook')).toBeInTheDocument();
|
||||
});
|
||||
it('Should check if Webhook URL label and input are displayed properly', () => {
|
||||
it('Should check if Webhook URL label and input are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_url',
|
||||
testId: 'webhook-url-textbox',
|
||||
});
|
||||
});
|
||||
it('Should check if Webhook User Name label, input, and help text are displayed properly', () => {
|
||||
it('Should check if Webhook User Name label, input, and help text are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_username',
|
||||
testId: 'webhook-username-textbox',
|
||||
@@ -247,7 +247,7 @@ describe('Create Alert Channel (Normal User)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Message contains the default template', () => {
|
||||
it('Should check if Message contains the default template ', () => {
|
||||
const messageTextArea = screen.getByTestId('opsgenie-message-textarea');
|
||||
|
||||
expect(messageTextArea).toHaveValue(opsGenieMessageDefaultValue);
|
||||
|
||||
@@ -24,7 +24,7 @@ jest.mock('components/MarkdownRenderer/MarkdownRenderer', () => ({
|
||||
MarkdownRenderer: jest.fn(() => <div>Mocked MarkdownRenderer</div>),
|
||||
}));
|
||||
|
||||
describe('Should check if the edit alert channel is properly displayed', () => {
|
||||
describe('Should check if the edit alert channel is properly displayed ', () => {
|
||||
beforeEach(() => {
|
||||
render(<EditAlertChannels initialValue={editAlertChannelInitialValue} />);
|
||||
});
|
||||
@@ -35,14 +35,14 @@ describe('Should check if the edit alert channel is properly displayed', () => {
|
||||
expect(screen.getByText('page_title_edit')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should check if the name label and textbox are displayed properly', () => {
|
||||
it('Should check if the name label and textbox are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_channel_name',
|
||||
testId: 'channel-name-textbox',
|
||||
value: 'Dummy-Channel',
|
||||
});
|
||||
});
|
||||
it('Should check if Send resolved alerts label and checkbox are displayed properly and the checkbox is checked', () => {
|
||||
it('Should check if Send resolved alerts label and checkbox are displayed properly and the checkbox is checked ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_send_resolved',
|
||||
testId: 'field-send-resolved-checkbox',
|
||||
@@ -61,7 +61,7 @@ describe('Should check if the edit alert channel is properly displayed', () => {
|
||||
expect(screen.getByText('Slack')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should check if Webhook URL label and input are displayed properly', () => {
|
||||
it('Should check if Webhook URL label and input are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_webhook_url',
|
||||
testId: 'webhook-url-textbox',
|
||||
@@ -70,7 +70,7 @@ describe('Should check if the edit alert channel is properly displayed', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Recepient label, input, and help text are displayed properly', () => {
|
||||
it('Should check if Recepient label, input, and help text are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_recipient',
|
||||
testId: 'slack-channel-textbox',
|
||||
@@ -79,7 +79,7 @@ describe('Should check if the edit alert channel is properly displayed', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should check if Title label and text area are displayed properly', () => {
|
||||
it('Should check if Title label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_title',
|
||||
testId: 'title-textarea',
|
||||
@@ -92,7 +92,7 @@ describe('Should check if the edit alert channel is properly displayed', () => {
|
||||
expect(titleTextArea).toHaveTextContent(slackTitleDefaultValue);
|
||||
});
|
||||
|
||||
it('Should check if Description label and text area are displayed properly', () => {
|
||||
it('Should check if Description label and text area are displayed properly ', () => {
|
||||
testLabelInputAndHelpValue({
|
||||
labelText: 'field_slack_description',
|
||||
testId: 'description-textarea',
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from './utils';
|
||||
|
||||
describe('Error utils', () => {
|
||||
it('Valid OrderBy Params', () => {
|
||||
test('Valid OrderBy Params', () => {
|
||||
expect(isOrderParams('serviceName')).toBe(true);
|
||||
expect(isOrderParams('exceptionCount')).toBe(true);
|
||||
expect(isOrderParams('lastSeen')).toBe(true);
|
||||
@@ -20,24 +20,24 @@ describe('Error utils', () => {
|
||||
expect(isOrderParams('exceptionType')).toBe(true);
|
||||
});
|
||||
|
||||
it('Invalid OrderBy Params', () => {
|
||||
test('Invalid OrderBy Params', () => {
|
||||
expect(isOrderParams('invalid')).toBe(false);
|
||||
expect(isOrderParams(null)).toBe(false);
|
||||
expect(isOrderParams('')).toBe(false);
|
||||
});
|
||||
|
||||
it('Valid Order', () => {
|
||||
test('Valid Order', () => {
|
||||
expect(isOrder('ascending')).toBe(true);
|
||||
expect(isOrder('descending')).toBe(true);
|
||||
});
|
||||
|
||||
it('Invalid Order', () => {
|
||||
test('Invalid Order', () => {
|
||||
expect(isOrder('invalid')).toBe(false);
|
||||
expect(isOrder(null)).toBe(false);
|
||||
expect(isOrder('')).toBe(false);
|
||||
});
|
||||
|
||||
it('Default Order', () => {
|
||||
test('Default Order', () => {
|
||||
const OrderBy: OrderBy[] = [
|
||||
'exceptionCount',
|
||||
'exceptionType',
|
||||
@@ -57,7 +57,7 @@ describe('Error utils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Limit', () => {
|
||||
test('Limit', () => {
|
||||
expect(getLimit(null)).toBe(10);
|
||||
expect(getLimit('')).toBe(10);
|
||||
expect(getLimit('0')).toBe(0);
|
||||
@@ -68,7 +68,7 @@ describe('Error utils', () => {
|
||||
expect(getLimit('101')).toBe(101);
|
||||
});
|
||||
|
||||
it('Update Page Size', () => {
|
||||
test('Update Page Size', () => {
|
||||
expect(getUpdatePageSize(null)).toBe(10);
|
||||
expect(getUpdatePageSize('')).toBe(10);
|
||||
expect(getUpdatePageSize('0')).toBe(0);
|
||||
@@ -79,7 +79,7 @@ describe('Error utils', () => {
|
||||
expect(getUpdatePageSize('101')).toBe(101);
|
||||
});
|
||||
|
||||
it('Order Params', () => {
|
||||
test('Order Params', () => {
|
||||
expect(getOrderParams(null)).toBe('serviceName');
|
||||
expect(getOrderParams('')).toBe('serviceName');
|
||||
expect(getOrderParams('serviceName')).toBe('serviceName');
|
||||
@@ -89,7 +89,7 @@ describe('Error utils', () => {
|
||||
expect(getOrderParams('exceptionType')).toBe('exceptionType');
|
||||
});
|
||||
|
||||
it('OffSet', () => {
|
||||
test('OffSet', () => {
|
||||
expect(getOffSet(null)).toBe(0);
|
||||
expect(getOffSet('')).toBe(0);
|
||||
expect(getOffSet('0')).toBe(0);
|
||||
@@ -100,7 +100,7 @@ describe('Error utils', () => {
|
||||
expect(getOffSet('101')).toBe(101);
|
||||
});
|
||||
|
||||
it('Order', () => {
|
||||
test('Order', () => {
|
||||
expect(getOrder(null)).toBe('ascending');
|
||||
expect(getOrder('')).toBe('ascending');
|
||||
expect(getOrder('ascending')).toBe('ascending');
|
||||
|
||||
@@ -30,18 +30,18 @@ function UplotChart({
|
||||
|
||||
useEffect(() => {
|
||||
if (plotInstance.current) {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
plotInstance.current.destroy();
|
||||
}
|
||||
|
||||
if (data && data.length > 0) {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
plotInstance.current = new uPlot(options, data, chartRef.current);
|
||||
}
|
||||
|
||||
return (): void => {
|
||||
if (plotInstance.current) {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
plotInstance.current.destroy();
|
||||
}
|
||||
};
|
||||
@@ -275,7 +275,7 @@ function AnomalyAlertEvaluationView({
|
||||
};
|
||||
|
||||
const handleSearchValueChange = useDebouncedFn((event): void => {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
const value = event?.target?.value || '';
|
||||
|
||||
handleSearch(value);
|
||||
|
||||
@@ -233,7 +233,7 @@ describe('DomainMetrics - V5 Query Payload Tests', () => {
|
||||
// Wait for skeletons to disappear
|
||||
await waitFor(() => {
|
||||
const skeletons = document.querySelectorAll('.ant-skeleton-button');
|
||||
expect(skeletons).toHaveLength(0);
|
||||
expect(skeletons.length).toBe(0);
|
||||
});
|
||||
|
||||
// Verify all metric labels are displayed
|
||||
@@ -272,7 +272,7 @@ describe('DomainMetrics - V5 Query Payload Tests', () => {
|
||||
|
||||
await waitFor(() => {
|
||||
const skeletons = document.querySelectorAll('.ant-skeleton-button');
|
||||
expect(skeletons).toHaveLength(0);
|
||||
expect(skeletons.length).toBe(0);
|
||||
});
|
||||
|
||||
// When no data, all values should show "-"
|
||||
|
||||
@@ -303,7 +303,7 @@ describe('EndPointMetrics - V5 Query Payload Tests', () => {
|
||||
// Wait for skeletons to disappear
|
||||
await waitFor(() => {
|
||||
const skeletons = document.querySelectorAll('.ant-skeleton-button');
|
||||
expect(skeletons).toHaveLength(0);
|
||||
expect(skeletons.length).toBe(0);
|
||||
});
|
||||
|
||||
// Verify all metric labels are displayed
|
||||
@@ -342,7 +342,7 @@ describe('EndPointMetrics - V5 Query Payload Tests', () => {
|
||||
|
||||
await waitFor(() => {
|
||||
const skeletons = document.querySelectorAll('.ant-skeleton-button');
|
||||
expect(skeletons).toHaveLength(0);
|
||||
expect(skeletons.length).toBe(0);
|
||||
});
|
||||
|
||||
// When no data, all values should show "-"
|
||||
|
||||
@@ -303,7 +303,7 @@ describe('API Monitoring Utils', () => {
|
||||
const result = extractPortAndEndpoint(url);
|
||||
|
||||
// Assert
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
port: '8080',
|
||||
endpoint: '/api/endpoint?param=value',
|
||||
});
|
||||
@@ -317,7 +317,7 @@ describe('API Monitoring Utils', () => {
|
||||
const result = extractPortAndEndpoint(url);
|
||||
|
||||
// Assert
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
port: '-',
|
||||
endpoint: '/api/endpoint',
|
||||
});
|
||||
@@ -331,7 +331,7 @@ describe('API Monitoring Utils', () => {
|
||||
const result = extractPortAndEndpoint(nonUrl);
|
||||
|
||||
// Assert
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
port: '-',
|
||||
endpoint: nonUrl,
|
||||
});
|
||||
@@ -379,7 +379,7 @@ describe('API Monitoring Utils', () => {
|
||||
const result = getFormattedEndPointDropDownData([]);
|
||||
|
||||
// Assert
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle undefined input', () => {
|
||||
@@ -392,7 +392,7 @@ describe('API Monitoring Utils', () => {
|
||||
// Assert
|
||||
// If the implementation doesn't handle undefined, just check that it returns something predictable
|
||||
// Based on the error, it seems the function returns undefined for undefined input
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle items without URL path', () => {
|
||||
@@ -460,7 +460,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result.length).toBe(2);
|
||||
|
||||
// Check first item
|
||||
expect(result[0].statusCode).toBe('200');
|
||||
@@ -493,7 +493,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result.length).toBe(1);
|
||||
expect(result[0].statusCode).toBe('-');
|
||||
expect(result[0].count).toBe('-');
|
||||
expect(result[0].p99Latency).toBe('-');
|
||||
@@ -506,7 +506,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle undefined input', () => {
|
||||
@@ -518,7 +518,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle mixed status code formats and preserve order', () => {
|
||||
@@ -555,7 +555,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(3);
|
||||
expect(result.length).toBe(3);
|
||||
|
||||
// Check order preservation - should maintain the same order as input
|
||||
expect(result[0].statusCode).toBe('404');
|
||||
@@ -675,7 +675,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result.data.result).toStrictEqual([]);
|
||||
expect(result.data.result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle empty result array', () => {
|
||||
@@ -695,7 +695,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result.data.result).toStrictEqual([]);
|
||||
expect(result.data.result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -779,7 +779,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result.length).toBe(2);
|
||||
|
||||
// Should have two filters, one for >= start code and one for <= end code
|
||||
const startRangeFilter = result.find((item) => item.op === '>=');
|
||||
@@ -811,7 +811,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result.length).toBe(2);
|
||||
|
||||
const startRangeFilter = result.find((item) => item.op === '>=');
|
||||
const endRangeFilter = result.find((item) => item.op === '<=');
|
||||
@@ -832,7 +832,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle empty metric object', () => {
|
||||
@@ -841,7 +841,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle metric without response_status_code', () => {
|
||||
@@ -855,7 +855,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle unsupported status code range', () => {
|
||||
@@ -869,7 +869,7 @@ describe('API Monitoring Utils', () => {
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result.length).toBe(2);
|
||||
|
||||
// Should still have two filters
|
||||
const startRangeFilter = result.find((item) => item.op === '>=');
|
||||
|
||||
@@ -61,29 +61,25 @@ describe('AllEndpointsWidget - V5 Migration Validation', () => {
|
||||
// Query A: count()
|
||||
expect(queryA.aggregations).toBeDefined();
|
||||
expect(Array.isArray(queryA.aggregations)).toBe(true);
|
||||
expect(queryA.aggregations).toStrictEqual([{ expression: 'count()' }]);
|
||||
expect(queryA.aggregations).toEqual([{ expression: 'count()' }]);
|
||||
expect(queryA).not.toHaveProperty('aggregateAttribute');
|
||||
|
||||
// Query B: p99(duration_nano)
|
||||
expect(queryB.aggregations).toBeDefined();
|
||||
expect(Array.isArray(queryB.aggregations)).toBe(true);
|
||||
expect(queryB.aggregations).toStrictEqual([
|
||||
{ expression: 'p99(duration_nano)' },
|
||||
]);
|
||||
expect(queryB.aggregations).toEqual([{ expression: 'p99(duration_nano)' }]);
|
||||
expect(queryB).not.toHaveProperty('aggregateAttribute');
|
||||
|
||||
// Query C: max(timestamp)
|
||||
expect(queryC.aggregations).toBeDefined();
|
||||
expect(Array.isArray(queryC.aggregations)).toBe(true);
|
||||
expect(queryC.aggregations).toStrictEqual([
|
||||
{ expression: 'max(timestamp)' },
|
||||
]);
|
||||
expect(queryC.aggregations).toEqual([{ expression: 'max(timestamp)' }]);
|
||||
expect(queryC).not.toHaveProperty('aggregateAttribute');
|
||||
|
||||
// Query D: count() (disabled, for errors)
|
||||
expect(queryD.aggregations).toBeDefined();
|
||||
expect(Array.isArray(queryD.aggregations)).toBe(true);
|
||||
expect(queryD.aggregations).toStrictEqual([{ expression: 'count()' }]);
|
||||
expect(queryD.aggregations).toEqual([{ expression: 'count()' }]);
|
||||
expect(queryD).not.toHaveProperty('aggregateAttribute');
|
||||
});
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ describe('EndpointDropdown - V5 Migration Validation', () => {
|
||||
// V5 Aggregation format: aggregations array (not aggregateAttribute)
|
||||
expect(queryA.aggregations).toBeDefined();
|
||||
expect(Array.isArray(queryA.aggregations)).toBe(true);
|
||||
expect(queryA.aggregations?.[0]).toStrictEqual({
|
||||
expect(queryA.aggregations?.[0]).toEqual({
|
||||
expression: 'count()',
|
||||
});
|
||||
expect(queryA).not.toHaveProperty('aggregateAttribute');
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('API Monitoring Query Params', () => {
|
||||
describe('getApiMonitoringParams', () => {
|
||||
it('returns default params when no query param exists', () => {
|
||||
const search = '';
|
||||
expect(getApiMonitoringParams(search)).toStrictEqual(DEFAULT_PARAMS);
|
||||
expect(getApiMonitoringParams(search)).toEqual(DEFAULT_PARAMS);
|
||||
});
|
||||
|
||||
it('parses URL query params correctly', () => {
|
||||
@@ -52,7 +52,7 @@ describe('API Monitoring Query Params', () => {
|
||||
urlParams.set('apiMonitoringParams', 'invalid-json');
|
||||
const search = `?${urlParams.toString()}`;
|
||||
|
||||
expect(getApiMonitoringParams(search)).toStrictEqual(DEFAULT_PARAMS);
|
||||
expect(getApiMonitoringParams(search)).toEqual(DEFAULT_PARAMS);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ window.ResizeObserver =
|
||||
describe('BillingContainer', () => {
|
||||
jest.setTimeout(30000);
|
||||
|
||||
it('Component should render', async () => {
|
||||
test('Component should render', async () => {
|
||||
render(<BillingContainer />);
|
||||
|
||||
const dataInjection = screen.getByRole('columnheader', {
|
||||
@@ -61,7 +61,7 @@ describe('BillingContainer', () => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('OnTrail', async () => {
|
||||
test('OnTrail', async () => {
|
||||
// Pin "now" so trial end (20 Oct 2023) is tomorrow => "1 days_remaining"
|
||||
|
||||
render(
|
||||
@@ -73,19 +73,17 @@ describe('BillingContainer', () => {
|
||||
// If the component schedules any setTimeout on mount, flush them:
|
||||
jest.runOnlyPendingTimers();
|
||||
|
||||
await expect(screen.findByText('Free Trial')).resolves.toBeInTheDocument();
|
||||
await expect(screen.findByText('billing')).resolves.toBeInTheDocument();
|
||||
await expect(screen.findByText(/\$0/i)).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('Free Trial')).toBeInTheDocument();
|
||||
expect(await screen.findByText('billing')).toBeInTheDocument();
|
||||
expect(await screen.findByText(/\$0/i)).toBeInTheDocument();
|
||||
|
||||
await expect(
|
||||
screen.findByText(
|
||||
expect(
|
||||
await screen.findByText(
|
||||
/You are in free trial period. Your free trial will end on 20 Oct 2023/i,
|
||||
),
|
||||
).resolves.toBeInTheDocument();
|
||||
).toBeInTheDocument();
|
||||
|
||||
await expect(
|
||||
screen.findByText(/1 days_remaining/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/1 days_remaining/i)).toBeInTheDocument();
|
||||
|
||||
const upgradeButtons = await screen.findAllByRole('button', {
|
||||
name: /upgrade_plan/i,
|
||||
@@ -93,15 +91,13 @@ describe('BillingContainer', () => {
|
||||
expect(upgradeButtons).toHaveLength(2);
|
||||
expect(upgradeButtons[1]).toBeInTheDocument();
|
||||
|
||||
await expect(
|
||||
screen.findByText(/checkout_plans/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
await expect(
|
||||
screen.findByRole('link', { name: /here/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/checkout_plans/i)).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('link', { name: /here/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('OnTrail but trialConvertedToSubscription', async () => {
|
||||
test('OnTrail but trialConvertedToSubscription', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<BillingContainer />,
|
||||
@@ -141,7 +137,7 @@ describe('BillingContainer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Not on ontrail', async () => {
|
||||
test('Not on ontrail', async () => {
|
||||
const { findByText } = render(
|
||||
<BillingContainer />,
|
||||
{},
|
||||
|
||||
@@ -242,7 +242,7 @@ describe('utils', () => {
|
||||
);
|
||||
|
||||
expect(rrulestr).toHaveBeenCalledWith(FREQ_DAILY);
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
new Date(MOCK_DATE_STRING),
|
||||
new Date('2024-01-16T10:30:00Z'),
|
||||
new Date('2024-01-17T10:30:00Z'),
|
||||
@@ -300,7 +300,7 @@ describe('utils', () => {
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-01-2024 10:30:00',
|
||||
'01-02-2024 10:30:00',
|
||||
'15-02-2024 10:30:00',
|
||||
@@ -319,7 +319,7 @@ describe('utils', () => {
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-01-2024 12:30:00',
|
||||
'19-01-2024 12:30:00',
|
||||
'22-01-2024 12:30:00',
|
||||
@@ -339,7 +339,7 @@ describe('utils', () => {
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
// today included (15-01-2024 00:30:00)
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-01-2024 10:30:00',
|
||||
'19-01-2024 10:30:00',
|
||||
'22-01-2024 10:30:00',
|
||||
@@ -359,7 +359,7 @@ describe('utils', () => {
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
// today excluded (15-01-2024 00:30:00)
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'19-01-2024 00:00:00',
|
||||
'22-01-2024 00:00:00',
|
||||
'26-01-2024 00:00:00',
|
||||
@@ -379,7 +379,7 @@ describe('utils', () => {
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
// today excluded (15-01-2024 00:30:00)
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'19-01-2024 00:30:00',
|
||||
'22-01-2024 00:30:00',
|
||||
'26-01-2024 00:30:00',
|
||||
@@ -398,7 +398,7 @@ describe('utils', () => {
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
// today included (15-01-2024 10:30:00)
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-01-2024 10:30:00',
|
||||
'15-02-2024 10:30:00',
|
||||
'15-03-2024 10:30:00',
|
||||
@@ -417,7 +417,7 @@ describe('utils', () => {
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
// today excluded (15-01-2024 10:30:00)
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-02-2024 00:00:00',
|
||||
'15-03-2024 00:00:00',
|
||||
'15-04-2024 00:00:00',
|
||||
@@ -436,7 +436,7 @@ describe('utils', () => {
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
// today excluded (15-01-2024 10:30:00)
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-02-2024 00:30:00',
|
||||
'15-03-2024 00:30:00',
|
||||
'15-04-2024 00:30:00',
|
||||
@@ -455,7 +455,7 @@ describe('utils', () => {
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'29-01-2024 10:30:00',
|
||||
'29-02-2024 10:30:00',
|
||||
'29-03-2024 10:30:00',
|
||||
@@ -474,7 +474,7 @@ describe('utils', () => {
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'31-01-2024 10:30:00',
|
||||
'31-03-2024 10:30:00',
|
||||
'31-05-2024 10:30:00',
|
||||
@@ -511,7 +511,7 @@ describe('utils', () => {
|
||||
5,
|
||||
);
|
||||
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'29-01-2023 10:30:00',
|
||||
'29-03-2023 10:30:00',
|
||||
'29-04-2023 10:30:00',
|
||||
@@ -529,7 +529,7 @@ describe('utils', () => {
|
||||
);
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-01-2024 10:40:00',
|
||||
'16-01-2024 10:40:00',
|
||||
'17-01-2024 10:40:00',
|
||||
@@ -547,7 +547,7 @@ describe('utils', () => {
|
||||
);
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'16-01-2024 00:00:00',
|
||||
'17-01-2024 00:00:00',
|
||||
'18-01-2024 00:00:00',
|
||||
@@ -565,7 +565,7 @@ describe('utils', () => {
|
||||
);
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'16-01-2024 00:30:00',
|
||||
'17-01-2024 00:30:00',
|
||||
'18-01-2024 00:30:00',
|
||||
@@ -583,7 +583,7 @@ describe('utils', () => {
|
||||
);
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'15-01-2024 10:30:00',
|
||||
'16-01-2024 10:30:00',
|
||||
'17-01-2024 10:30:00',
|
||||
@@ -621,7 +621,7 @@ describe('utils', () => {
|
||||
);
|
||||
expect(result).toBeDefined();
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result?.map((res) => formatDate(res))).toStrictEqual([
|
||||
expect(result?.map((res) => formatDate(res))).toEqual([
|
||||
'31-01-2024 10:30:00',
|
||||
'01-02-2024 10:30:00',
|
||||
'02-02-2024 10:30:00',
|
||||
|
||||
@@ -333,7 +333,7 @@ describe('QuerySection', () => {
|
||||
|
||||
const result = mockUseQueryBuilder.redirectWithQueryBuilderData.mock.calls[0];
|
||||
|
||||
expect(result[0]).toStrictEqual({
|
||||
expect(result[0]).toEqual({
|
||||
id: MOCK_UUID,
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
unit: undefined,
|
||||
@@ -351,7 +351,7 @@ describe('QuerySection', () => {
|
||||
clickhouse_sql: [initialClickHouseData],
|
||||
});
|
||||
|
||||
expect(result[1]).toStrictEqual({
|
||||
expect(result[1]).toEqual({
|
||||
[QueryParams.alertType]: AlertTypes.METRICS_BASED_ALERT,
|
||||
[QueryParams.ruleType]: AlertDetectionTypes.THRESHOLD_ALERT,
|
||||
});
|
||||
@@ -371,7 +371,7 @@ describe('QuerySection', () => {
|
||||
const [queryArg] =
|
||||
mockUseQueryBuilder.redirectWithQueryBuilderData.mock.calls[0];
|
||||
|
||||
expect(queryArg).toStrictEqual({
|
||||
expect(queryArg).toEqual({
|
||||
...mockUseQueryBuilder.currentQuery,
|
||||
queryType: EQueryType.PROM,
|
||||
});
|
||||
@@ -425,7 +425,7 @@ describe('QuerySection', () => {
|
||||
const [queryArg] =
|
||||
mockUseQueryBuilder.redirectWithQueryBuilderData.mock.calls[0];
|
||||
|
||||
expect(queryArg).toStrictEqual({
|
||||
expect(queryArg).toEqual({
|
||||
...mockCurrentQueryWithPromQL,
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
});
|
||||
@@ -479,7 +479,7 @@ describe('QuerySection', () => {
|
||||
const [queryArg] =
|
||||
mockUseQueryBuilder.redirectWithQueryBuilderData.mock.calls[0];
|
||||
|
||||
expect(queryArg).toStrictEqual({
|
||||
expect(queryArg).toEqual({
|
||||
...mockCurrentQueryWithClickhouseSQL,
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
});
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_ALERT_NAME',
|
||||
payload: 'Test Alert',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_STATE,
|
||||
name: 'Test Alert',
|
||||
});
|
||||
@@ -66,7 +66,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_ALERT_LABELS',
|
||||
payload: labels,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_STATE,
|
||||
labels,
|
||||
});
|
||||
@@ -77,7 +77,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_Y_AXIS_UNIT',
|
||||
payload: 'ms',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_STATE,
|
||||
yAxisUnit: 'ms',
|
||||
});
|
||||
@@ -90,7 +90,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
yAxisUnit: 'ms',
|
||||
};
|
||||
const result = alertCreationReducer(modifiedState, { type: 'RESET' });
|
||||
expect(result).toStrictEqual(INITIAL_ALERT_STATE);
|
||||
expect(result).toEqual(INITIAL_ALERT_STATE);
|
||||
});
|
||||
|
||||
it(TEST_SET_INITIAL_STATE_FROM_PAYLOAD, () => {
|
||||
@@ -103,7 +103,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_INITIAL_STATE',
|
||||
payload: newState,
|
||||
});
|
||||
expect(result).toStrictEqual(newState);
|
||||
expect(result).toEqual(newState);
|
||||
});
|
||||
|
||||
it(TEST_RETURN_STATE_FOR_UNKNOWN_ACTION, () => {
|
||||
@@ -112,7 +112,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
|
||||
{ type: UNKNOWN_ACTION_TYPE } as any,
|
||||
);
|
||||
expect(result).toStrictEqual(INITIAL_ALERT_STATE);
|
||||
expect(result).toEqual(INITIAL_ALERT_STATE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -211,7 +211,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_SELECTED_QUERY',
|
||||
payload: 'B',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_THRESHOLD_STATE,
|
||||
selectedQuery: 'B',
|
||||
});
|
||||
@@ -222,7 +222,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_OPERATOR',
|
||||
payload: AlertThresholdOperator.IS_BELOW,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_THRESHOLD_STATE,
|
||||
operator: AlertThresholdOperator.IS_BELOW,
|
||||
});
|
||||
@@ -233,7 +233,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_MATCH_TYPE',
|
||||
payload: AlertThresholdMatchType.ALL_THE_TIME,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_THRESHOLD_STATE,
|
||||
matchType: AlertThresholdMatchType.ALL_THE_TIME,
|
||||
});
|
||||
@@ -255,7 +255,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_THRESHOLDS',
|
||||
payload: newThresholds,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ALERT_THRESHOLD_STATE,
|
||||
thresholds: newThresholds,
|
||||
});
|
||||
@@ -272,7 +272,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
thresholds: [],
|
||||
};
|
||||
const result = alertThresholdReducer(modifiedState, { type: 'RESET' });
|
||||
expect(result).toStrictEqual(INITIAL_ALERT_THRESHOLD_STATE);
|
||||
expect(result).toEqual(INITIAL_ALERT_THRESHOLD_STATE);
|
||||
});
|
||||
|
||||
it(TEST_SET_INITIAL_STATE_FROM_PAYLOAD, () => {
|
||||
@@ -289,7 +289,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_INITIAL_STATE',
|
||||
payload: newState,
|
||||
});
|
||||
expect(result).toStrictEqual(newState);
|
||||
expect(result).toEqual(newState);
|
||||
});
|
||||
|
||||
it(TEST_RETURN_STATE_FOR_UNKNOWN_ACTION, () => {
|
||||
@@ -298,7 +298,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
|
||||
{ type: UNKNOWN_ACTION_TYPE } as any,
|
||||
);
|
||||
expect(result).toStrictEqual(INITIAL_ALERT_THRESHOLD_STATE);
|
||||
expect(result).toEqual(INITIAL_ALERT_THRESHOLD_STATE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -308,7 +308,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_SEND_NOTIFICATION_IF_DATA_IS_MISSING',
|
||||
payload: { toleranceLimit: 21, timeUnit: UniversalYAxisUnit.HOURS },
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
sendNotificationIfDataIsMissing: {
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE.sendNotificationIfDataIsMissing,
|
||||
@@ -323,7 +323,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'TOGGLE_SEND_NOTIFICATION_IF_DATA_IS_MISSING',
|
||||
payload: true,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
sendNotificationIfDataIsMissing: {
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE.sendNotificationIfDataIsMissing,
|
||||
@@ -337,7 +337,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_ENFORCE_MINIMUM_DATAPOINTS',
|
||||
payload: { minimumDatapoints: 10 },
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
enforceMinimumDatapoints: {
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE.enforceMinimumDatapoints,
|
||||
@@ -351,7 +351,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'TOGGLE_ENFORCE_MINIMUM_DATAPOINTS',
|
||||
payload: true,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
enforceMinimumDatapoints: {
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE.enforceMinimumDatapoints,
|
||||
@@ -365,7 +365,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_DELAY_EVALUATION',
|
||||
payload: { delay: 10, timeUnit: UniversalYAxisUnit.HOURS },
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
delayEvaluation: { delay: 10, timeUnit: UniversalYAxisUnit.HOURS },
|
||||
});
|
||||
@@ -386,7 +386,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_EVALUATION_CADENCE',
|
||||
payload: newCadence,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
evaluationCadence: {
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE.evaluationCadence,
|
||||
@@ -400,7 +400,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_EVALUATION_CADENCE_MODE',
|
||||
payload: 'custom',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE,
|
||||
evaluationCadence: {
|
||||
...INITIAL_ADVANCED_OPTIONS_STATE.evaluationCadence,
|
||||
@@ -415,7 +415,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
delayEvaluation: { delay: 10, timeUnit: UniversalYAxisUnit.HOURS },
|
||||
};
|
||||
const result = advancedOptionsReducer(modifiedState, { type: 'RESET' });
|
||||
expect(result).toStrictEqual(INITIAL_ADVANCED_OPTIONS_STATE);
|
||||
expect(result).toEqual(INITIAL_ADVANCED_OPTIONS_STATE);
|
||||
});
|
||||
|
||||
it(TEST_SET_INITIAL_STATE_FROM_PAYLOAD, () => {
|
||||
@@ -431,7 +431,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_INITIAL_STATE',
|
||||
payload: newState,
|
||||
});
|
||||
expect(result).toStrictEqual(newState);
|
||||
expect(result).toEqual(newState);
|
||||
});
|
||||
|
||||
it(TEST_RETURN_STATE_FOR_UNKNOWN_ACTION, () => {
|
||||
@@ -440,7 +440,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
|
||||
{ type: UNKNOWN_ACTION_TYPE } as any,
|
||||
);
|
||||
expect(result).toStrictEqual(INITIAL_ADVANCED_OPTIONS_STATE);
|
||||
expect(result).toEqual(INITIAL_ADVANCED_OPTIONS_STATE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -455,7 +455,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_WINDOW_TYPE',
|
||||
payload: 'rolling',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
windowType: 'rolling',
|
||||
timeframe: INITIAL_EVALUATION_WINDOW_STATE.timeframe,
|
||||
startingAt: INITIAL_EVALUATION_WINDOW_STATE.startingAt,
|
||||
@@ -467,7 +467,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_WINDOW_TYPE',
|
||||
payload: 'cumulative',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
windowType: 'cumulative',
|
||||
timeframe: 'currentHour',
|
||||
startingAt: INITIAL_EVALUATION_WINDOW_STATE.startingAt,
|
||||
@@ -479,7 +479,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_TIMEFRAME',
|
||||
payload: '10m0s',
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_EVALUATION_WINDOW_STATE,
|
||||
timeframe: '10m0s',
|
||||
});
|
||||
@@ -496,7 +496,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_STARTING_AT',
|
||||
payload: newStartingAt,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_EVALUATION_WINDOW_STATE,
|
||||
startingAt: newStartingAt,
|
||||
});
|
||||
@@ -514,7 +514,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
},
|
||||
};
|
||||
const result = evaluationWindowReducer(modifiedState, { type: 'RESET' });
|
||||
expect(result).toStrictEqual(INITIAL_EVALUATION_WINDOW_STATE);
|
||||
expect(result).toEqual(INITIAL_EVALUATION_WINDOW_STATE);
|
||||
});
|
||||
|
||||
it(TEST_SET_INITIAL_STATE_FROM_PAYLOAD, () => {
|
||||
@@ -532,7 +532,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_INITIAL_STATE',
|
||||
payload: newState,
|
||||
});
|
||||
expect(result).toStrictEqual(newState);
|
||||
expect(result).toEqual(newState);
|
||||
});
|
||||
|
||||
it(TEST_RETURN_STATE_FOR_UNKNOWN_ACTION, () => {
|
||||
@@ -541,7 +541,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
|
||||
{ type: UNKNOWN_ACTION_TYPE } as any,
|
||||
);
|
||||
expect(result).toStrictEqual(INITIAL_EVALUATION_WINDOW_STATE);
|
||||
expect(result).toEqual(INITIAL_EVALUATION_WINDOW_STATE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -555,7 +555,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
payload: notifications,
|
||||
},
|
||||
);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
multipleNotifications: notifications,
|
||||
});
|
||||
@@ -570,7 +570,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
type: 'SET_MULTIPLE_NOTIFICATIONS',
|
||||
payload: null,
|
||||
});
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...modifiedState,
|
||||
multipleNotifications: null,
|
||||
});
|
||||
@@ -590,7 +590,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
payload: reNotification,
|
||||
},
|
||||
);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
reNotification,
|
||||
});
|
||||
@@ -605,7 +605,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
payload: description,
|
||||
},
|
||||
);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
description,
|
||||
});
|
||||
@@ -619,7 +619,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
payload: true,
|
||||
},
|
||||
);
|
||||
expect(result).toStrictEqual({
|
||||
expect(result).toEqual({
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
routingPolicies: true,
|
||||
});
|
||||
@@ -640,7 +640,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
const result = notificationSettingsReducer(modifiedState, {
|
||||
type: 'RESET',
|
||||
});
|
||||
expect(result).toStrictEqual(INITIAL_NOTIFICATION_SETTINGS_STATE);
|
||||
expect(result).toEqual(INITIAL_NOTIFICATION_SETTINGS_STATE);
|
||||
});
|
||||
|
||||
it(TEST_SET_INITIAL_STATE_FROM_PAYLOAD, () => {
|
||||
@@ -662,7 +662,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
payload: newState,
|
||||
},
|
||||
);
|
||||
expect(result).toStrictEqual(newState);
|
||||
expect(result).toEqual(newState);
|
||||
});
|
||||
|
||||
it(TEST_RETURN_STATE_FOR_UNKNOWN_ACTION, () => {
|
||||
@@ -671,7 +671,7 @@ describe('CreateAlertV2 Context Utils', () => {
|
||||
|
||||
{ type: UNKNOWN_ACTION_TYPE } as any,
|
||||
);
|
||||
expect(result).toStrictEqual(INITIAL_NOTIFICATION_SETTINGS_STATE);
|
||||
expect(result).toEqual(INITIAL_NOTIFICATION_SETTINGS_STATE);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -113,7 +113,7 @@ describe('CustomDomainSettings', () => {
|
||||
await user.click(screen.getByRole('button', { name: /apply changes/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(capturedBody).toStrictEqual({ name: 'myteam' });
|
||||
expect(capturedBody).toEqual({ name: 'myteam' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -143,9 +143,9 @@ describe('CustomDomainSettings', () => {
|
||||
await user.type(input, 'myteam');
|
||||
await user.click(screen.getByRole('button', { name: /apply changes/i }));
|
||||
|
||||
await expect(
|
||||
screen.findByRole('button', { name: /contact support/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('button', { name: /contact support/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows validation error when subdomain is less than 3 characters', async () => {
|
||||
@@ -255,7 +255,7 @@ describe('CustomDomainSettings', () => {
|
||||
},
|
||||
});
|
||||
|
||||
await expect(screen.findByText('My Org Name')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('My Org Name')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('falls back to customDomainSubdomain when org displayName is missing', async () => {
|
||||
@@ -269,7 +269,7 @@ describe('CustomDomainSettings', () => {
|
||||
appContextOverrides: { org: [] },
|
||||
});
|
||||
|
||||
await expect(screen.findByText('custom-host')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('custom-host')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('falls back to activeHost.name when neither org name nor custom domain exists', async () => {
|
||||
@@ -294,9 +294,7 @@ describe('CustomDomainSettings', () => {
|
||||
});
|
||||
|
||||
// 'accepted-starfish' is the default host's name
|
||||
await expect(
|
||||
screen.findByText('accepted-starfish'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('accepted-starfish')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render the card name row if workspaceName is totally falsy', async () => {
|
||||
|
||||
@@ -155,7 +155,7 @@ describe('VariableItem Component', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders without crashing', () => {
|
||||
test('renders without crashing', () => {
|
||||
renderVariableItem();
|
||||
|
||||
expect(screen.getByText(TEXT.ALL_VARIABLES)).toBeInTheDocument();
|
||||
@@ -165,7 +165,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
describe('Variable Name Validation', () => {
|
||||
it('shows error when variable name already exists', () => {
|
||||
test('shows error when variable name already exists', () => {
|
||||
// Set validateName to return false (name exists)
|
||||
const mockValidateName = jest.fn().mockReturnValue(false);
|
||||
|
||||
@@ -181,7 +181,7 @@ describe('VariableItem Component', () => {
|
||||
// We won't check for button disabled state as it might be inconsistent in tests
|
||||
});
|
||||
|
||||
it('allows save when current variable name is used', () => {
|
||||
test('allows save when current variable name is used', () => {
|
||||
// Mock validate to return false for all other names but true for own name
|
||||
const mockValidateName = jest
|
||||
.fn()
|
||||
@@ -197,7 +197,7 @@ describe('VariableItem Component', () => {
|
||||
expect(screen.queryByText(TEXT.VARIABLE_EXISTS)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows error when variable name contains whitespace', () => {
|
||||
test('shows error when variable name contains whitespace', () => {
|
||||
renderVariableItem({ ...basicVariableData, name: '' });
|
||||
|
||||
// Enter a name with whitespace
|
||||
@@ -212,7 +212,7 @@ describe('VariableItem Component', () => {
|
||||
expect(saveButton).toBeDisabled();
|
||||
});
|
||||
|
||||
it('allows variable name without whitespace', () => {
|
||||
test('allows variable name without whitespace', () => {
|
||||
renderVariableItem({ ...basicVariableData, name: '' });
|
||||
|
||||
// Enter a valid name without whitespace
|
||||
@@ -223,7 +223,7 @@ describe('VariableItem Component', () => {
|
||||
expect(screen.queryByText(TEXT.VARIABLE_WHITESPACE)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('validates whitespace in auto-generated name for dynamic variables', () => {
|
||||
test('validates whitespace in auto-generated name for dynamic variables', () => {
|
||||
// Create a dynamic variable with empty name
|
||||
const dynamicVariable: IDashboardVariable = {
|
||||
...basicVariableData,
|
||||
@@ -241,7 +241,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
describe('Dynamic Variable Attribute Key Validation', () => {
|
||||
it('shows error when attribute key already exists', async () => {
|
||||
test('shows error when attribute key already exists', async () => {
|
||||
// Mock validateAttributeKey to return false (attribute key exists)
|
||||
const mockValidateAttributeKey = jest.fn().mockReturnValue(false);
|
||||
|
||||
@@ -277,7 +277,7 @@ describe('VariableItem Component', () => {
|
||||
expect(saveButton).toBeDisabled();
|
||||
});
|
||||
|
||||
it('allows saving when attribute key is unique', async () => {
|
||||
test('allows saving when attribute key is unique', async () => {
|
||||
// Mock validateAttributeKey to return true (attribute key is unique)
|
||||
const mockValidateAttributeKey = jest.fn().mockReturnValue(true);
|
||||
|
||||
@@ -315,7 +315,7 @@ describe('VariableItem Component', () => {
|
||||
expect(saveButton).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('allows same attribute key for current variable being edited', async () => {
|
||||
test('allows same attribute key for current variable being edited', async () => {
|
||||
// Mock validateAttributeKey to return true for same variable
|
||||
const mockValidateAttributeKey = jest.fn().mockImplementation(
|
||||
(attributeKey, currentVariableId) =>
|
||||
@@ -348,7 +348,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not validate attribute key for non-dynamic variables', async () => {
|
||||
test('does not validate attribute key for non-dynamic variables', async () => {
|
||||
// Mock validateAttributeKey to return false (would show error for dynamic)
|
||||
const mockValidateAttributeKey = jest.fn().mockReturnValue(false);
|
||||
|
||||
@@ -377,7 +377,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
describe('Variable Type Switching', () => {
|
||||
it('switches to CUSTOM variable type correctly', () => {
|
||||
test('switches to CUSTOM variable type correctly', () => {
|
||||
renderVariableItem();
|
||||
|
||||
// Find the Query button
|
||||
@@ -401,7 +401,7 @@ describe('VariableItem Component', () => {
|
||||
expect(screen.getByText(TEXT.OPTIONS)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('switches to TEXTBOX variable type correctly', () => {
|
||||
test('switches to TEXTBOX variable type correctly', () => {
|
||||
renderVariableItem();
|
||||
|
||||
// Find and click Textbox button
|
||||
@@ -424,7 +424,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
describe('MultiSelect and ALL Option', () => {
|
||||
it('enables ALL option only when multiSelect is enabled', async () => {
|
||||
test('enables ALL option only when multiSelect is enabled', async () => {
|
||||
renderVariableItem();
|
||||
|
||||
// Initially, ALL option should not be visible
|
||||
@@ -457,7 +457,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('disables ALL option when multiSelect is disabled', async () => {
|
||||
test('disables ALL option when multiSelect is disabled', async () => {
|
||||
// Create variable with multiSelect and showALLOption both enabled
|
||||
const variable: IDashboardVariable = {
|
||||
...basicVariableData,
|
||||
@@ -501,7 +501,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
describe('Cancel and Navigation', () => {
|
||||
it('calls onCancel when clicking All Variables button', () => {
|
||||
test('calls onCancel when clicking All Variables button', () => {
|
||||
renderVariableItem();
|
||||
|
||||
// Click All variables button
|
||||
@@ -511,7 +511,7 @@ describe('VariableItem Component', () => {
|
||||
expect(onCancel).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('calls onCancel when clicking Discard button', () => {
|
||||
test('calls onCancel when clicking Discard button', () => {
|
||||
renderVariableItem();
|
||||
|
||||
// Click Discard button
|
||||
@@ -550,7 +550,7 @@ describe('VariableItem Component', () => {
|
||||
};
|
||||
|
||||
// Test for cyclic dependency detection
|
||||
it('detects circular dependency and shows error message', async () => {
|
||||
test('detects circular dependency and shows error message', async () => {
|
||||
// Create variables with circular dependency
|
||||
const variable1 = createVariable(
|
||||
TEST_VAR_IDS.VAR1,
|
||||
@@ -577,7 +577,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
// Test for saving with no circular dependency
|
||||
it('allows saving when no circular dependency exists', async () => {
|
||||
test('allows saving when no circular dependency exists', async () => {
|
||||
// Create variables without circular dependency
|
||||
const variable1 = createVariable(
|
||||
TEST_VAR_IDS.VAR1,
|
||||
@@ -608,7 +608,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
// Test with multiple variable formats in query
|
||||
it('detects circular dependency with different variable formats', async () => {
|
||||
test('detects circular dependency with different variable formats', async () => {
|
||||
// Create variables with circular dependency using different formats
|
||||
const variable1 = createVariable(
|
||||
TEST_VAR_IDS.VAR1,
|
||||
@@ -645,7 +645,7 @@ describe('VariableItem Component', () => {
|
||||
});
|
||||
|
||||
describe('Textbox Variable Default Value Handling', () => {
|
||||
it('saves textbox variable with defaultValue and selectedValue set to textboxValue', async () => {
|
||||
test('saves textbox variable with defaultValue and selectedValue set to textboxValue', async () => {
|
||||
const user = userEvent.setup();
|
||||
const textboxVariable: IDashboardVariable = {
|
||||
id: TEST_VAR_IDS.VAR1,
|
||||
@@ -676,7 +676,7 @@ describe('VariableItem Component', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('saves textbox variable with empty values when textboxValue is empty', async () => {
|
||||
test('saves textbox variable with empty values when textboxValue is empty', async () => {
|
||||
const user = userEvent.setup();
|
||||
const textboxVariable: IDashboardVariable = {
|
||||
id: TEST_VAR_IDS.VAR1,
|
||||
@@ -707,7 +707,7 @@ describe('VariableItem Component', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('updates textbox defaultValue and selectedValue when user changes textboxValue input', async () => {
|
||||
test('updates textbox defaultValue and selectedValue when user changes textboxValue input', async () => {
|
||||
const user = userEvent.setup();
|
||||
const textboxVariable: IDashboardVariable = {
|
||||
id: TEST_VAR_IDS.VAR1,
|
||||
@@ -745,7 +745,7 @@ describe('VariableItem Component', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('non-textbox variables use variableDefaultValue instead of textboxValue', async () => {
|
||||
test('non-textbox variables use variableDefaultValue instead of textboxValue', async () => {
|
||||
const user = userEvent.setup();
|
||||
const queryVariable: IDashboardVariable = {
|
||||
id: TEST_VAR_IDS.VAR1,
|
||||
@@ -780,7 +780,7 @@ describe('VariableItem Component', () => {
|
||||
expect(savedVariable.defaultValue).not.toBe('should-not-be-used');
|
||||
});
|
||||
|
||||
it('switching to textbox type sets defaultValue and selectedValue correctly on save', async () => {
|
||||
test('switching to textbox type sets defaultValue and selectedValue correctly on save', async () => {
|
||||
const user = userEvent.setup();
|
||||
// Start with a QUERY variable
|
||||
const queryVariable: IDashboardVariable = {
|
||||
|
||||
@@ -38,7 +38,7 @@ function TableRow({ children, ...props }: RowProps): JSX.Element {
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
id: props['data-row-key'],
|
||||
});
|
||||
|
||||
@@ -148,7 +148,7 @@ function VariablesSettings({
|
||||
});
|
||||
|
||||
if (name) {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
variableNamesMap[name] = name;
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ function VariablesSettings({
|
||||
const variableName = updatedVariables[index].name;
|
||||
|
||||
if (variableName) {
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
reArrangedVariables[variableName] = {
|
||||
...updatedVariables[index],
|
||||
order: index,
|
||||
|
||||
@@ -109,13 +109,11 @@ describe('PublicDashboardSetting', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(
|
||||
screen.findByRole('checkbox', { name: /enable time range/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('checkbox', { name: /enable time range/i }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
await expect(
|
||||
screen.findByText(/default time range/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/default time range/i)).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText(/Last 30 minutes/i)).toBeInTheDocument();
|
||||
|
||||
@@ -125,9 +123,9 @@ describe('PublicDashboardSetting', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(
|
||||
screen.findByRole('button', { name: /publish dashboard/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('button', { name: /publish dashboard/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -151,9 +149,9 @@ describe('PublicDashboardSetting', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(
|
||||
screen.findByRole('checkbox', { name: /enable time range/i }),
|
||||
).resolves.toBeChecked();
|
||||
expect(
|
||||
await screen.findByRole('checkbox', { name: /enable time range/i }),
|
||||
).toBeChecked();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/default time range/i)).toBeInTheDocument();
|
||||
@@ -165,13 +163,13 @@ describe('PublicDashboardSetting', () => {
|
||||
expect(screen.getByText(/Public Dashboard URL/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(
|
||||
screen.findByRole('button', { name: /update published dashboard/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('button', { name: /update published dashboard/i }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
await expect(
|
||||
screen.findByRole('button', { name: /unpublish dashboard/i }),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('button', { name: /unpublish dashboard/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -251,7 +249,7 @@ describe('PublicDashboardSetting', () => {
|
||||
rest.post(publicDashboardURL, async (req, res, ctx) => {
|
||||
const body = await req.json();
|
||||
createApiCalled = true;
|
||||
expect(body).toStrictEqual({
|
||||
expect(body).toEqual({
|
||||
timeRangeEnabled: true,
|
||||
defaultTimeRange: DEFAULT_TIME_RANGE,
|
||||
});
|
||||
@@ -320,7 +318,7 @@ describe('PublicDashboardSetting', () => {
|
||||
|
||||
await waitFor(() => {
|
||||
expect(updateApiCalled).toBe(true);
|
||||
expect(capturedRequestBody).toStrictEqual({
|
||||
expect(capturedRequestBody).toEqual({
|
||||
timeRangeEnabled: true,
|
||||
defaultTimeRange: DEFAULT_TIME_RANGE,
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('VariableItem', () => {
|
||||
useEffectSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('renders component with default props', () => {
|
||||
test('renders component with default props', () => {
|
||||
render(
|
||||
<MockQueryClientProvider>
|
||||
<VariableItem
|
||||
@@ -54,7 +54,7 @@ describe('VariableItem', () => {
|
||||
expect(screen.getByText('$testVariable')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders Input when the variable type is TEXTBOX', () => {
|
||||
test('renders Input when the variable type is TEXTBOX', () => {
|
||||
render(
|
||||
<MockQueryClientProvider>
|
||||
<VariableItem
|
||||
@@ -69,7 +69,7 @@ describe('VariableItem', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls onValueUpdate when Input value changes and blurs', async () => {
|
||||
test('calls onValueUpdate when Input value changes and blurs', async () => {
|
||||
render(
|
||||
<MockQueryClientProvider>
|
||||
<VariableItem
|
||||
@@ -102,7 +102,7 @@ describe('VariableItem', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('renders a Select element when variable type is CUSTOM', () => {
|
||||
test('renders a Select element when variable type is CUSTOM', () => {
|
||||
render(
|
||||
<MockQueryClientProvider>
|
||||
<VariableItem
|
||||
@@ -117,7 +117,7 @@ describe('VariableItem', () => {
|
||||
expect(screen.getByTestId('variable-select')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders a Select element with all selected', async () => {
|
||||
test('renders a Select element with all selected', async () => {
|
||||
const customVariableData = {
|
||||
...mockCustomVariableData,
|
||||
allSelected: true,
|
||||
@@ -138,7 +138,7 @@ describe('VariableItem', () => {
|
||||
expect(screen.getByText('ALL')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls useEffect when the component mounts', () => {
|
||||
test('calls useEffect when the component mounts', () => {
|
||||
render(
|
||||
<MockQueryClientProvider>
|
||||
<VariableItem
|
||||
|
||||
@@ -272,7 +272,7 @@ describe('DashboardVariableSelection', () => {
|
||||
);
|
||||
});
|
||||
|
||||
expect(callOrder).toStrictEqual([
|
||||
expect(callOrder).toEqual([
|
||||
'updateDashboardVariablesStore',
|
||||
'enqueueDescendantsOfVariable',
|
||||
]);
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('VariableItem Default Value Selection Behavior', () => {
|
||||
});
|
||||
|
||||
describe('Single Select Variables', () => {
|
||||
it('should keep previous selection value', async () => {
|
||||
test('should keep previous selection value', async () => {
|
||||
const variable: IDashboardVariable = {
|
||||
id: TEST_VARIABLE_ID,
|
||||
name: TEST_VARIABLE_NAME,
|
||||
@@ -51,10 +51,10 @@ describe('VariableItem Default Value Selection Behavior', () => {
|
||||
expect(screen.getByTestId(VARIABLE_SELECT_TESTID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(screen.findByText('option1')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('option1')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should auto-select first option when no previous and no default', async () => {
|
||||
test('should auto-select first option when no previous and no default', async () => {
|
||||
const variable: IDashboardVariable = {
|
||||
id: TEST_VARIABLE_ID,
|
||||
name: TEST_VARIABLE_NAME,
|
||||
@@ -74,12 +74,12 @@ describe('VariableItem Default Value Selection Behavior', () => {
|
||||
});
|
||||
|
||||
// With the new variable select strategy, the first option is auto-selected
|
||||
await expect(screen.findByText('option1')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('option1')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Multi Select Variables with ALL enabled', () => {
|
||||
it('should show ALL when all options are selected', async () => {
|
||||
test('should show ALL when all options are selected', async () => {
|
||||
const variable: IDashboardVariable = {
|
||||
id: TEST_VARIABLE_ID,
|
||||
name: TEST_VARIABLE_NAME,
|
||||
@@ -99,12 +99,12 @@ describe('VariableItem Default Value Selection Behavior', () => {
|
||||
expect(screen.getByTestId(VARIABLE_SELECT_TESTID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(screen.findByText('ALL')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('ALL')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Multi Select Variables with ALL disabled', () => {
|
||||
it('should show placeholder when no selection', async () => {
|
||||
test('should show placeholder when no selection', async () => {
|
||||
const variable: IDashboardVariable = {
|
||||
id: TEST_VARIABLE_ID,
|
||||
name: TEST_VARIABLE_NAME,
|
||||
@@ -123,7 +123,7 @@ describe('VariableItem Default Value Selection Behavior', () => {
|
||||
expect(screen.getByTestId(VARIABLE_SELECT_TESTID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(screen.findByText('Select value')).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText('Select value')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
},
|
||||
];
|
||||
|
||||
it.each(testCases)(
|
||||
test.each(testCases)(
|
||||
'should update variable node when $scenario',
|
||||
({ nodeToUpdate, expected }) => {
|
||||
const updatedVariables: string[] = [];
|
||||
@@ -57,7 +57,7 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
|
||||
onUpdateVariableNode(nodeToUpdate, graph, topologicalOrder, callback);
|
||||
|
||||
expect(updatedVariables).toStrictEqual(expected);
|
||||
expect(updatedVariables).toEqual(expected);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -66,7 +66,7 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
onUpdateVariableNode('http_status_code', graph, [], (node) =>
|
||||
updatedVariables.push(node),
|
||||
);
|
||||
expect(updatedVariables).toStrictEqual([]);
|
||||
expect(updatedVariables).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -87,11 +87,11 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
environment: [],
|
||||
};
|
||||
|
||||
expect(buildParentDependencyGraph(graph)).toStrictEqual(expected);
|
||||
expect(buildParentDependencyGraph(graph)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle empty graph', () => {
|
||||
expect(buildParentDependencyGraph({})).toStrictEqual({});
|
||||
expect(buildParentDependencyGraph({})).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -142,13 +142,13 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
},
|
||||
};
|
||||
|
||||
expect(buildDependencyGraph(graph)).toStrictEqual(expected);
|
||||
expect(buildDependencyGraph(graph)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return empty transitiveDescendants for an empty graph', () => {
|
||||
const result = buildDependencyGraph({});
|
||||
expect(result.transitiveDescendants).toStrictEqual({});
|
||||
expect(result.order).toStrictEqual([]);
|
||||
expect(result.transitiveDescendants).toEqual({});
|
||||
expect(result.order).toEqual([]);
|
||||
expect(result.hasCycle).toBe(false);
|
||||
});
|
||||
|
||||
@@ -159,7 +159,7 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
c: [],
|
||||
};
|
||||
const result = buildDependencyGraph(linearGraph);
|
||||
expect(result.transitiveDescendants).toStrictEqual({
|
||||
expect(result.transitiveDescendants).toEqual({
|
||||
a: ['b', 'c'],
|
||||
b: ['c'],
|
||||
c: [],
|
||||
@@ -174,13 +174,13 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
d: [],
|
||||
};
|
||||
const result = buildDependencyGraph(diamondGraph);
|
||||
expect(result.transitiveDescendants.a).toStrictEqual(
|
||||
expect(result.transitiveDescendants.a).toEqual(
|
||||
expect.arrayContaining(['b', 'c', 'd']),
|
||||
);
|
||||
expect(result.transitiveDescendants.a).toHaveLength(3);
|
||||
expect(result.transitiveDescendants.b).toStrictEqual(['d']);
|
||||
expect(result.transitiveDescendants.c).toStrictEqual(['d']);
|
||||
expect(result.transitiveDescendants.d).toStrictEqual([]);
|
||||
expect(result.transitiveDescendants.b).toEqual(['d']);
|
||||
expect(result.transitiveDescendants.c).toEqual(['d']);
|
||||
expect(result.transitiveDescendants.d).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle disconnected components in transitiveDescendants', () => {
|
||||
@@ -191,10 +191,10 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
y: [],
|
||||
};
|
||||
const result = buildDependencyGraph(disconnectedGraph);
|
||||
expect(result.transitiveDescendants.a).toStrictEqual(['b']);
|
||||
expect(result.transitiveDescendants.b).toStrictEqual([]);
|
||||
expect(result.transitiveDescendants.x).toStrictEqual(['y']);
|
||||
expect(result.transitiveDescendants.y).toStrictEqual([]);
|
||||
expect(result.transitiveDescendants.a).toEqual(['b']);
|
||||
expect(result.transitiveDescendants.b).toEqual([]);
|
||||
expect(result.transitiveDescendants.x).toEqual(['y']);
|
||||
expect(result.transitiveDescendants.y).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return empty transitiveDescendants for all leaf nodes', () => {
|
||||
@@ -204,7 +204,7 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
c: [],
|
||||
};
|
||||
const result = buildDependencyGraph(leafOnlyGraph);
|
||||
expect(result.transitiveDescendants).toStrictEqual({
|
||||
expect(result.transitiveDescendants).toEqual({
|
||||
a: [],
|
||||
b: [],
|
||||
c: [],
|
||||
@@ -225,11 +225,11 @@ describe('dashboardVariables - utilities and processors', () => {
|
||||
environment: [],
|
||||
};
|
||||
|
||||
expect(buildDependencies(variables)).toStrictEqual(expected);
|
||||
expect(buildDependencies(variables)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle empty variables array', () => {
|
||||
expect(buildDependencies([])).toStrictEqual({});
|
||||
expect(buildDependencies([])).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ export const convertVariablesToDbFormat = (
|
||||
variblesArr.reduce((result, obj: IDashboardVariable) => {
|
||||
const { id } = obj;
|
||||
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
result[id] = obj;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
@@ -81,7 +81,7 @@ describe('onUpdateVariableNode', () => {
|
||||
|
||||
onUpdateVariableNode('deployment', graph, topologicalOrder, callback);
|
||||
|
||||
expect(visited).toStrictEqual(['deployment', 'namespace', 'service', 'pod']);
|
||||
expect(visited).toEqual(['deployment', 'namespace', 'service', 'pod']);
|
||||
});
|
||||
|
||||
it('should call callback starting from a middle node', () => {
|
||||
@@ -92,7 +92,7 @@ describe('onUpdateVariableNode', () => {
|
||||
|
||||
onUpdateVariableNode('namespace', graph, topologicalOrder, callback);
|
||||
|
||||
expect(visited).toStrictEqual(['namespace', 'service', 'pod']);
|
||||
expect(visited).toEqual(['namespace', 'service', 'pod']);
|
||||
});
|
||||
|
||||
it('should only call callback for the leaf node when updating leaf', () => {
|
||||
@@ -103,7 +103,7 @@ describe('onUpdateVariableNode', () => {
|
||||
|
||||
onUpdateVariableNode('pod', graph, topologicalOrder, callback);
|
||||
|
||||
expect(visited).toStrictEqual(['pod']);
|
||||
expect(visited).toEqual(['pod']);
|
||||
});
|
||||
|
||||
it('should handle CUSTOM variable not in topologicalOrder by updating its children', () => {
|
||||
@@ -116,7 +116,7 @@ describe('onUpdateVariableNode', () => {
|
||||
onUpdateVariableNode('customVar', graph, topologicalOrder, callback);
|
||||
|
||||
// Should process namespace and its descendants (service, pod)
|
||||
expect(visited).toStrictEqual(['namespace', 'service', 'pod']);
|
||||
expect(visited).toEqual(['namespace', 'service', 'pod']);
|
||||
});
|
||||
|
||||
it('should handle node not in graph gracefully', () => {
|
||||
@@ -128,7 +128,7 @@ describe('onUpdateVariableNode', () => {
|
||||
onUpdateVariableNode('unknownNode', graph, topologicalOrder, callback);
|
||||
|
||||
// Should not call callback for any node since unknownNode has no children
|
||||
expect(visited).toStrictEqual([]);
|
||||
expect(visited).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle empty graph', () => {
|
||||
@@ -140,7 +140,7 @@ describe('onUpdateVariableNode', () => {
|
||||
onUpdateVariableNode('deployment', {}, topologicalOrder, callback);
|
||||
|
||||
// deployment is in topologicalOrder, so callback is called for it
|
||||
expect(visited).toStrictEqual(['deployment']);
|
||||
expect(visited).toEqual(['deployment']);
|
||||
});
|
||||
|
||||
it('should handle empty topologicalOrder', () => {
|
||||
@@ -151,7 +151,7 @@ describe('onUpdateVariableNode', () => {
|
||||
|
||||
onUpdateVariableNode('deployment', graph, [], callback);
|
||||
|
||||
expect(visited).toStrictEqual([]);
|
||||
expect(visited).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle CUSTOM variable with multiple children', () => {
|
||||
@@ -173,7 +173,7 @@ describe('onUpdateVariableNode', () => {
|
||||
);
|
||||
|
||||
// Should process namespace, service, and pod (descendants)
|
||||
expect(visited).toStrictEqual(['namespace', 'service', 'pod']);
|
||||
expect(visited).toEqual(['namespace', 'service', 'pod']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -200,15 +200,11 @@ function makeDynamicVar(
|
||||
|
||||
describe('mergeUniqueStrings', () => {
|
||||
it('should merge two arrays and deduplicate', () => {
|
||||
expect(mergeUniqueStrings(['a', 'b'], ['b', 'c'])).toStrictEqual([
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
]);
|
||||
expect(mergeUniqueStrings(['a', 'b'], ['b', 'c'])).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('should convert numbers and booleans to strings', () => {
|
||||
expect(mergeUniqueStrings([1, true, 'hello'], [2, false])).toStrictEqual([
|
||||
expect(mergeUniqueStrings([1, true, 'hello'], [2, false])).toEqual([
|
||||
'1',
|
||||
'true',
|
||||
'hello',
|
||||
@@ -218,15 +214,15 @@ describe('mergeUniqueStrings', () => {
|
||||
});
|
||||
|
||||
it('should deduplicate when number and its string form both appear', () => {
|
||||
expect(mergeUniqueStrings([42], ['42'])).toStrictEqual(['42']);
|
||||
expect(mergeUniqueStrings([42], ['42'])).toEqual(['42']);
|
||||
});
|
||||
|
||||
it('should handle a single array', () => {
|
||||
expect(mergeUniqueStrings(['x', 'y', 'x'])).toStrictEqual(['x', 'y']);
|
||||
expect(mergeUniqueStrings(['x', 'y', 'x'])).toEqual(['x', 'y']);
|
||||
});
|
||||
|
||||
it('should handle three or more arrays', () => {
|
||||
expect(mergeUniqueStrings(['a'], ['b'], ['c'], ['a', 'c'])).toStrictEqual([
|
||||
expect(mergeUniqueStrings(['a'], ['b'], ['c'], ['a', 'c'])).toEqual([
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
@@ -234,19 +230,15 @@ describe('mergeUniqueStrings', () => {
|
||||
});
|
||||
|
||||
it('should return empty array when no arrays are provided', () => {
|
||||
expect(mergeUniqueStrings()).toStrictEqual([]);
|
||||
expect(mergeUniqueStrings()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return empty array when all input arrays are empty', () => {
|
||||
expect(mergeUniqueStrings([], [], [])).toStrictEqual([]);
|
||||
expect(mergeUniqueStrings([], [], [])).toEqual([]);
|
||||
});
|
||||
|
||||
it('should preserve order of first occurrence', () => {
|
||||
expect(mergeUniqueStrings(['c', 'a'], ['b', 'a'])).toStrictEqual([
|
||||
'c',
|
||||
'a',
|
||||
'b',
|
||||
]);
|
||||
expect(mergeUniqueStrings(['c', 'a'], ['b', 'a'])).toEqual(['c', 'a', 'b']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ describe('Panel Management Tests', () => {
|
||||
);
|
||||
|
||||
// Should return dashboard unchanged
|
||||
expect(updatedDashboard).toStrictEqual(dashboard);
|
||||
expect(updatedDashboard).toEqual(dashboard);
|
||||
});
|
||||
|
||||
it('should handle undefined dashboard gracefully', () => {
|
||||
|
||||
@@ -33,7 +33,6 @@ export default function ChartWrapper({
|
||||
children,
|
||||
layoutChildren,
|
||||
yAxisUnit,
|
||||
groupBy,
|
||||
customTooltip,
|
||||
pinnedTooltipElement,
|
||||
'data-testid': testId,
|
||||
@@ -69,9 +68,8 @@ export default function ChartWrapper({
|
||||
const syncMetadata = useMemo(
|
||||
() => ({
|
||||
yAxisUnit,
|
||||
groupBy,
|
||||
}),
|
||||
[yAxisUnit, groupBy],
|
||||
[yAxisUnit],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
DashboardCursorSync,
|
||||
TooltipClickData,
|
||||
} from 'lib/uPlotV2/plugins/TooltipPlugin/types';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
interface BaseChartProps {
|
||||
width: number;
|
||||
@@ -39,7 +38,6 @@ interface UPlotBasedChartProps {
|
||||
interface UPlotChartDataProps {
|
||||
yAxisUnit?: string;
|
||||
decimalPrecision?: PrecisionOption;
|
||||
groupBy?: BaseAutocompleteData[];
|
||||
}
|
||||
|
||||
export interface TimeSeriesChartProps
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('stackUtils', () => {
|
||||
[4, 5, 6],
|
||||
];
|
||||
const { data: result } = stack(data, neverOmit);
|
||||
expect(result[0]).toStrictEqual([100, 200, 300]);
|
||||
expect(result[0]).toEqual([100, 200, 300]);
|
||||
});
|
||||
|
||||
it('stacks value series cumulatively (last = raw, first = total)', () => {
|
||||
@@ -26,9 +26,9 @@ describe('stackUtils', () => {
|
||||
];
|
||||
const { data: result } = stack(data, neverOmit);
|
||||
// result[1] = s1+s2+s3, result[2] = s2+s3, result[3] = s3
|
||||
expect(result[1]).toStrictEqual([12, 15, 18]); // 1+4+7, 2+5+8, 3+6+9
|
||||
expect(result[2]).toStrictEqual([11, 13, 15]); // 4+7, 5+8, 6+9
|
||||
expect(result[3]).toStrictEqual([7, 8, 9]);
|
||||
expect(result[1]).toEqual([12, 15, 18]); // 1+4+7, 2+5+8, 3+6+9
|
||||
expect(result[2]).toEqual([11, 13, 15]); // 4+7, 5+8, 6+9
|
||||
expect(result[3]).toEqual([7, 8, 9]);
|
||||
});
|
||||
|
||||
it('treats null values as 0 when stacking', () => {
|
||||
@@ -38,8 +38,8 @@ describe('stackUtils', () => {
|
||||
[null, 10],
|
||||
];
|
||||
const { data: result } = stack(data, neverOmit);
|
||||
expect(result[1]).toStrictEqual([1, 10]); // total
|
||||
expect(result[2]).toStrictEqual([0, 10]); // last series with null→0
|
||||
expect(result[1]).toEqual([1, 10]); // total
|
||||
expect(result[2]).toEqual([0, 10]); // last series with null→0
|
||||
});
|
||||
|
||||
it('copies omitted series as-is without accumulating', () => {
|
||||
@@ -53,9 +53,9 @@ describe('stackUtils', () => {
|
||||
const omitSeries2 = (i: number): boolean => i === 2;
|
||||
const { data: result } = stack(data, omitSeries2);
|
||||
// series 3 raw: [1, 2]; series 2 omitted: [100, 200] as-is; series 1 stacked with s3: [11, 22]
|
||||
expect(result[1]).toStrictEqual([11, 22]); // 10+1, 20+2
|
||||
expect(result[2]).toStrictEqual([100, 200]); // copied, not stacked
|
||||
expect(result[3]).toStrictEqual([1, 2]);
|
||||
expect(result[1]).toEqual([11, 22]); // 10+1, 20+2
|
||||
expect(result[2]).toEqual([100, 200]); // copied, not stacked
|
||||
expect(result[3]).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('returns bands between consecutive visible series when none omitted', () => {
|
||||
@@ -66,7 +66,7 @@ describe('stackUtils', () => {
|
||||
[5, 6],
|
||||
];
|
||||
const { bands } = stack(data, neverOmit);
|
||||
expect(bands).toStrictEqual([{ series: [1, 2] }, { series: [2, 3] }]);
|
||||
expect(bands).toEqual([{ series: [1, 2] }, { series: [2, 3] }]);
|
||||
});
|
||||
|
||||
it('returns bands only between visible series when some are omitted', () => {
|
||||
@@ -74,7 +74,7 @@ describe('stackUtils', () => {
|
||||
const data: AlignedData = [[0], [1], [2], [3], [4]];
|
||||
const omitSeries2 = (i: number): boolean => i === 2;
|
||||
const { bands } = stack(data, omitSeries2);
|
||||
expect(bands).toStrictEqual([{ series: [1, 3] }, { series: [3, 4] }]);
|
||||
expect(bands).toEqual([{ series: [1, 3] }, { series: [3, 4] }]);
|
||||
});
|
||||
|
||||
it('returns empty bands when only one value series', () => {
|
||||
@@ -83,30 +83,30 @@ describe('stackUtils', () => {
|
||||
[1, 2],
|
||||
];
|
||||
const { bands } = stack(data, neverOmit);
|
||||
expect(bands).toStrictEqual([]);
|
||||
expect(bands).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getInitialStackedBands', () => {
|
||||
it('returns one band between each consecutive pair for seriesCount 3', () => {
|
||||
expect(getInitialStackedBands(3)).toStrictEqual([
|
||||
expect(getInitialStackedBands(3)).toEqual([
|
||||
{ series: [1, 2] },
|
||||
{ series: [2, 3] },
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns empty array for seriesCount 0 or 1', () => {
|
||||
expect(getInitialStackedBands(0)).toStrictEqual([]);
|
||||
expect(getInitialStackedBands(1)).toStrictEqual([]);
|
||||
expect(getInitialStackedBands(0)).toEqual([]);
|
||||
expect(getInitialStackedBands(1)).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns single band for seriesCount 2', () => {
|
||||
expect(getInitialStackedBands(2)).toStrictEqual([{ series: [1, 2] }]);
|
||||
expect(getInitialStackedBands(2)).toEqual([{ series: [1, 2] }]);
|
||||
});
|
||||
|
||||
it('returns bands [1,2], [2,3], ..., [n-1, n] for seriesCount n', () => {
|
||||
const bands = getInitialStackedBands(5);
|
||||
expect(bands).toStrictEqual([
|
||||
expect(bands).toEqual([
|
||||
{ series: [1, 2] },
|
||||
{ series: [2, 3] },
|
||||
{ series: [3, 4] },
|
||||
|
||||
@@ -119,9 +119,9 @@ describe('useBarChartStacking', () => {
|
||||
}),
|
||||
);
|
||||
// Still returns stacked data (computed in useMemo); no hooks registered
|
||||
expect(result.current[0]).toStrictEqual([0, 1]);
|
||||
expect(result.current[1]).toStrictEqual([5, 7]); // stacked
|
||||
expect(result.current[2]).toStrictEqual([4, 5]);
|
||||
expect(result.current[0]).toEqual([0, 1]);
|
||||
expect(result.current[1]).toEqual([5, 7]); // stacked
|
||||
expect(result.current[2]).toEqual([4, 5]);
|
||||
});
|
||||
|
||||
it('returns stacked data when isStackedBarChart is true and multiple value series', () => {
|
||||
@@ -138,10 +138,10 @@ describe('useBarChartStacking', () => {
|
||||
config: null,
|
||||
}),
|
||||
);
|
||||
expect(result.current[0]).toStrictEqual([0, 1, 2]);
|
||||
expect(result.current[1]).toStrictEqual([12, 15, 18]); // s1+s2+s3
|
||||
expect(result.current[2]).toStrictEqual([11, 13, 15]); // s2+s3
|
||||
expect(result.current[3]).toStrictEqual([7, 8, 9]);
|
||||
expect(result.current[0]).toEqual([0, 1, 2]);
|
||||
expect(result.current[1]).toEqual([12, 15, 18]); // s1+s2+s3
|
||||
expect(result.current[2]).toEqual([11, 13, 15]); // s2+s3
|
||||
expect(result.current[3]).toEqual([7, 8, 9]);
|
||||
});
|
||||
|
||||
it('returns data as-is when only one value series (no stacking needed)', () => {
|
||||
@@ -156,7 +156,7 @@ describe('useBarChartStacking', () => {
|
||||
config: null,
|
||||
}),
|
||||
);
|
||||
expect(result.current).toStrictEqual(data);
|
||||
expect(result.current).toEqual(data);
|
||||
});
|
||||
|
||||
it('registers setData and setSeries hooks when isStackedBarChart and config provided', () => {
|
||||
|
||||
@@ -113,10 +113,6 @@ function BarPanel(props: PanelWrapperProps): JSX.Element {
|
||||
uPlotRef.current = plot;
|
||||
}, []);
|
||||
|
||||
const groupBy = useMemo(() => {
|
||||
return widget.query.builder.queryData[0].groupBy;
|
||||
}, [widget.query]);
|
||||
|
||||
return (
|
||||
<div className="panel-container" ref={graphRef}>
|
||||
{containerDimensions.width > 0 && containerDimensions.height > 0 && (
|
||||
@@ -132,7 +128,6 @@ function BarPanel(props: PanelWrapperProps): JSX.Element {
|
||||
width={containerDimensions.width}
|
||||
height={containerDimensions.height}
|
||||
layoutChildren={layoutChildren}
|
||||
groupBy={groupBy}
|
||||
isStackedBarChart={widget.stackedBarChart ?? false}
|
||||
yAxisUnit={widget.yAxisUnit}
|
||||
decimalPrecision={widget.decimalPrecision}
|
||||
|
||||
@@ -105,7 +105,6 @@ export function prepareBarPanelConfig({
|
||||
colorMapping: widget.customLegendColors ?? {},
|
||||
isDarkMode,
|
||||
stepInterval: currentStepInterval,
|
||||
metric: series.metric,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -104,10 +104,6 @@ function TimeSeriesPanel(props: PanelWrapperProps): JSX.Element {
|
||||
widget.decimalPrecision,
|
||||
]);
|
||||
|
||||
const groupBy = useMemo(() => {
|
||||
return widget.query.builder.queryData[0].groupBy;
|
||||
}, [widget.query]);
|
||||
|
||||
return (
|
||||
<div className="panel-container" ref={graphRef}>
|
||||
{containerDimensions.width > 0 && containerDimensions.height > 0 && (
|
||||
@@ -121,7 +117,6 @@ function TimeSeriesPanel(props: PanelWrapperProps): JSX.Element {
|
||||
yAxisUnit={widget.yAxisUnit}
|
||||
decimalPrecision={widget.decimalPrecision}
|
||||
data={chartData as uPlot.AlignedData}
|
||||
groupBy={groupBy}
|
||||
width={containerDimensions.width}
|
||||
height={containerDimensions.height}
|
||||
layoutChildren={layoutChildren}
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('TimeSeriesPanel utils', () => {
|
||||
const data = prepareChartData(apiResponse);
|
||||
|
||||
expect(data).toHaveLength(1);
|
||||
expect(data[0]).toStrictEqual([]);
|
||||
expect(data[0]).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns timestamps and one series of y values for single series', () => {
|
||||
@@ -102,8 +102,8 @@ describe('TimeSeriesPanel utils', () => {
|
||||
const data = prepareChartData(apiResponse);
|
||||
|
||||
expect(data).toHaveLength(2);
|
||||
expect(data[0]).toStrictEqual([1000, 2000]);
|
||||
expect(data[1]).toStrictEqual([10, 20]);
|
||||
expect(data[0]).toEqual([1000, 2000]);
|
||||
expect(data[1]).toEqual([10, 20]);
|
||||
});
|
||||
|
||||
it('merges timestamps and fills missing values with null for multiple series', () => {
|
||||
@@ -128,11 +128,11 @@ describe('TimeSeriesPanel utils', () => {
|
||||
|
||||
const data = prepareChartData(apiResponse);
|
||||
|
||||
expect(data[0]).toStrictEqual([1000, 2000, 3000]);
|
||||
expect(data[0]).toEqual([1000, 2000, 3000]);
|
||||
// First series: 1, null, 3
|
||||
expect(data[1]).toStrictEqual([1, null, 3]);
|
||||
expect(data[1]).toEqual([1, null, 3]);
|
||||
// Second series: 10, 20, null
|
||||
expect(data[2]).toStrictEqual([10, 20, null]);
|
||||
expect(data[2]).toEqual([10, 20, null]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ export const prepareUPlotConfig = ({
|
||||
pointSize: 5,
|
||||
fillMode: widget.fillMode || FillMode.None,
|
||||
isDarkMode,
|
||||
metric: series.metric,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ describe('legendVisibilityUtils', () => {
|
||||
const result = getStoredSeriesVisibility('widget-1');
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{ label: 'CPU', show: true },
|
||||
{ label: 'Memory', show: false },
|
||||
]);
|
||||
@@ -85,7 +85,7 @@ describe('legendVisibilityUtils', () => {
|
||||
const result = getStoredSeriesVisibility('widget-1');
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result).toStrictEqual([
|
||||
expect(result).toEqual([
|
||||
{ label: 'CPU', show: true },
|
||||
{ label: 'CPU', show: false },
|
||||
{ label: 'Memory', show: false },
|
||||
@@ -128,7 +128,7 @@ describe('legendVisibilityUtils', () => {
|
||||
const stored = getStoredSeriesVisibility('widget-1');
|
||||
|
||||
expect(stored).not.toBeNull();
|
||||
expect(stored).toStrictEqual([
|
||||
expect(stored).toEqual([
|
||||
{ label: 'CPU', show: true },
|
||||
{ label: 'Memory', show: false },
|
||||
]);
|
||||
@@ -150,7 +150,7 @@ describe('legendVisibilityUtils', () => {
|
||||
const stored = getStoredSeriesVisibility('widget-new');
|
||||
|
||||
expect(stored).not.toBeNull();
|
||||
expect(stored).toStrictEqual([{ label: 'CPU', show: false }]);
|
||||
expect(stored).toEqual([{ label: 'CPU', show: false }]);
|
||||
});
|
||||
|
||||
it('updates existing widget visibility when entry already exists', () => {
|
||||
@@ -176,7 +176,7 @@ describe('legendVisibilityUtils', () => {
|
||||
const stored = getStoredSeriesVisibility('widget-1');
|
||||
|
||||
expect(stored).not.toBeNull();
|
||||
expect(stored).toStrictEqual([
|
||||
expect(stored).toEqual([
|
||||
{ label: 'CPU', show: false },
|
||||
{ label: 'Memory', show: true },
|
||||
]);
|
||||
@@ -202,7 +202,7 @@ describe('legendVisibilityUtils', () => {
|
||||
|
||||
const stored = getStoredSeriesVisibility('widget-1');
|
||||
expect(stored).not.toBeNull();
|
||||
expect(stored).toStrictEqual([
|
||||
expect(stored).toEqual([
|
||||
{ label: 'x-axis', show: true },
|
||||
{ label: 'CPU', show: false },
|
||||
]);
|
||||
@@ -232,10 +232,10 @@ describe('legendVisibilityUtils', () => {
|
||||
{ label: 'B', show: true },
|
||||
]);
|
||||
|
||||
expect(getStoredSeriesVisibility('widget-a')).toStrictEqual([
|
||||
expect(getStoredSeriesVisibility('widget-a')).toEqual([
|
||||
{ label: 'A', show: true },
|
||||
]);
|
||||
expect(getStoredSeriesVisibility('widget-b')).toStrictEqual([
|
||||
expect(getStoredSeriesVisibility('widget-b')).toEqual([
|
||||
{ label: 'B', show: true },
|
||||
]);
|
||||
});
|
||||
@@ -252,7 +252,7 @@ describe('legendVisibilityUtils', () => {
|
||||
);
|
||||
const [_, value] = (localStorage.setItem as jest.Mock).mock.calls[0];
|
||||
expect((): void => JSON.parse(value)).not.toThrow();
|
||||
expect(JSON.parse(value)).toStrictEqual([
|
||||
expect(JSON.parse(value)).toEqual([
|
||||
{ name: 'widget-1', dataIndex: [{ label: 'CPU', show: true }] },
|
||||
]);
|
||||
});
|
||||
@@ -263,7 +263,7 @@ describe('legendVisibilityUtils', () => {
|
||||
const raw = localStorage.getItem(storageKey);
|
||||
expect(raw).not.toBeNull();
|
||||
const parsed = JSON.parse(raw ?? '[]');
|
||||
expect(parsed).toStrictEqual([{ name: 'widget-1', dataIndex: [] }]);
|
||||
expect(parsed).toEqual([{ name: 'widget-1', dataIndex: [] }]);
|
||||
expect(getStoredSeriesVisibility('widget-1')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -188,9 +188,7 @@ describe('ForgotPassword Component', () => {
|
||||
const submitButton = screen.getByTestId('forgot-password-submit');
|
||||
await user.click(submitButton);
|
||||
|
||||
await expect(
|
||||
screen.findByText(/check your email/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/check your email/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/we've sent a password reset link/i),
|
||||
).toBeInTheDocument();
|
||||
@@ -210,9 +208,7 @@ describe('ForgotPassword Component', () => {
|
||||
const submitButton = screen.getByTestId('forgot-password-submit');
|
||||
await user.click(submitButton);
|
||||
|
||||
await expect(
|
||||
screen.findByTestId('back-to-login'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByTestId('back-to-login')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('redirects to login when clicking back to login on success screen', async () => {
|
||||
@@ -229,9 +225,7 @@ describe('ForgotPassword Component', () => {
|
||||
const submitButton = screen.getByTestId('forgot-password-submit');
|
||||
await user.click(submitButton);
|
||||
|
||||
await expect(
|
||||
screen.findByTestId('back-to-login'),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByTestId('back-to-login')).toBeInTheDocument();
|
||||
|
||||
const backToLoginButton = screen.getByTestId('back-to-login');
|
||||
await user.click(backToLoginButton);
|
||||
@@ -256,9 +250,7 @@ describe('ForgotPassword Component', () => {
|
||||
const submitButton = screen.getByTestId('forgot-password-submit');
|
||||
await user.click(submitButton);
|
||||
|
||||
await expect(
|
||||
screen.findByText(/user not found/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/user not found/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('displays error message when API returns server error', async () => {
|
||||
@@ -271,9 +263,9 @@ describe('ForgotPassword Component', () => {
|
||||
const submitButton = screen.getByTestId('forgot-password-submit');
|
||||
await user.click(submitButton);
|
||||
|
||||
await expect(
|
||||
screen.findByText(/internal server error occurred/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText(/internal server error occurred/i),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('clears error message on new submission attempt', async () => {
|
||||
@@ -303,9 +295,7 @@ describe('ForgotPassword Component', () => {
|
||||
const submitButton = screen.getByTestId('forgot-password-submit');
|
||||
await user.click(submitButton);
|
||||
|
||||
await expect(
|
||||
screen.findByText(/user not found/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/user not found/i)).toBeInTheDocument();
|
||||
|
||||
// Click submit again
|
||||
await user.click(submitButton);
|
||||
@@ -313,9 +303,7 @@ describe('ForgotPassword Component', () => {
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/user not found/i)).not.toBeInTheDocument();
|
||||
});
|
||||
await expect(
|
||||
screen.findByText(/check your email/i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/check your email/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -348,9 +336,7 @@ describe('ForgotPassword Component', () => {
|
||||
await user.click(submitButton);
|
||||
|
||||
// Button should show loading state
|
||||
await expect(
|
||||
screen.findByText(/sending\.\.\./i),
|
||||
).resolves.toBeInTheDocument();
|
||||
expect(await screen.findByText(/sending\.\.\./i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('disables submit button during loading', async () => {
|
||||
|
||||
@@ -139,8 +139,8 @@ function ChartPreview({
|
||||
if (startTime && endTime && startTime !== endTime) {
|
||||
dispatch(
|
||||
UpdateTimeInterval('custom', [
|
||||
Number.parseInt(getTimeString(startTime), 10),
|
||||
Number.parseInt(getTimeString(endTime), 10),
|
||||
parseInt(getTimeString(startTime), 10),
|
||||
parseInt(getTimeString(endTime), 10),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('usePrefillAlertConditions', () => {
|
||||
builder: { queryData: [{ reduceTo: 'p90' }] },
|
||||
} as any),
|
||||
);
|
||||
expect(result.current.matchType).toBeNull();
|
||||
expect(result.current.matchType).toBe(null);
|
||||
});
|
||||
|
||||
it('returns the correct matchType for multiple queries with same time aggregation', () => {
|
||||
@@ -112,7 +112,7 @@ describe('usePrefillAlertConditions', () => {
|
||||
},
|
||||
} as any),
|
||||
);
|
||||
expect(result.current.matchType).toBeNull();
|
||||
expect(result.current.matchType).toBe(null);
|
||||
});
|
||||
|
||||
it('returns the correct op, target, targetUnit from the higher priority threshold for multiple thresholds', () => {
|
||||
|
||||
@@ -370,7 +370,7 @@ function FormAlertRules({
|
||||
// onQueryCategoryChange handles changes to query category
|
||||
// in state as well as sets additional defaults
|
||||
const onQueryCategoryChange = (val: EQueryType): void => {
|
||||
const element = document.querySelector('#top');
|
||||
const element = document.getElementById('top');
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import { getUpdatedStepInterval } from './utils';
|
||||
describe('getUpdatedStepInterval', () => {
|
||||
it('should return 60', () => {
|
||||
const result = getUpdatedStepInterval('5m0s');
|
||||
expect(result).toBe(60);
|
||||
expect(result).toEqual(60);
|
||||
});
|
||||
it('should return 60 for 10m0s', () => {
|
||||
const result = getUpdatedStepInterval('10m0s');
|
||||
expect(result).toBe(60);
|
||||
expect(result).toEqual(60);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('Table Panel utils', () => {
|
||||
expect(getQueryLegend(query, 'A')).toBe('p99');
|
||||
|
||||
// should return undefined when legend not present
|
||||
expect(getQueryLegend(query, 'B')).toBeUndefined();
|
||||
expect(getQueryLegend(query, 'B')).toBe(undefined);
|
||||
});
|
||||
|
||||
it('sorter function for table sorting', () => {
|
||||
|
||||
@@ -108,7 +108,7 @@ describe('EntityLogs', () => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(capturedQueryRangePayloads).toHaveLength(1);
|
||||
expect(capturedQueryRangePayloads.length).toBe(1);
|
||||
});
|
||||
|
||||
await waitFor(async () => {
|
||||
@@ -131,7 +131,7 @@ describe('EntityLogs', () => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(capturedQueryRangePayloads).toHaveLength(2);
|
||||
expect(capturedQueryRangePayloads.length).toBe(2);
|
||||
});
|
||||
|
||||
const firstPayload = capturedQueryRangePayloads[0];
|
||||
|
||||
@@ -149,7 +149,7 @@ describe('ServiceDetails for S3 Sync service', () => {
|
||||
expect(capturedPayload).not.toBeNull();
|
||||
});
|
||||
|
||||
expect(capturedPayload).toStrictEqual({
|
||||
expect(capturedPayload).toEqual({
|
||||
config: {
|
||||
aws: {
|
||||
logs: {
|
||||
|
||||
@@ -68,12 +68,12 @@ describe('filterAlerts', () => {
|
||||
|
||||
it('should return all alerts when filter is empty', () => {
|
||||
const result = filterAlerts(mockAlerts, '');
|
||||
expect(result).toStrictEqual(mockAlerts);
|
||||
expect(result).toEqual(mockAlerts);
|
||||
});
|
||||
|
||||
it('should return all alerts when filter is only whitespace', () => {
|
||||
const result = filterAlerts(mockAlerts, ' ');
|
||||
expect(result).toStrictEqual(mockAlerts);
|
||||
expect(result).toEqual(mockAlerts);
|
||||
});
|
||||
|
||||
it('should filter alerts by alert name', () => {
|
||||
|
||||
@@ -8,19 +8,8 @@ import {
|
||||
OPERATORS,
|
||||
QUERY_BUILDER_FUNCTIONS,
|
||||
} from 'constants/antlrQueryConstants';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { useActiveLog } from 'hooks/logs/useActiveLog';
|
||||
import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { ICurrentQueryData } from 'hooks/useHandleExplorerTabChange';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import { ExplorerViews } from 'pages/LogsExplorer/utils';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import {
|
||||
BaseAutocompleteData,
|
||||
DataTypes,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
import { TitleWrapper } from './BodyTitleRenderer.styles';
|
||||
import { DROPDOWN_KEY } from './constant';
|
||||
@@ -36,32 +25,17 @@ function BodyTitleRenderer({
|
||||
parentIsArray = false,
|
||||
nodeKey,
|
||||
value,
|
||||
handleChangeSelectedView,
|
||||
}: BodyTitleRendererProps): JSX.Element {
|
||||
const { onAddToQuery } = useActiveLog();
|
||||
const { stagedQuery, updateQueriesData } = useQueryBuilder();
|
||||
|
||||
const { featureFlags } = useAppContext();
|
||||
const [, setCopy] = useCopyToClipboard();
|
||||
const { notifications } = useNotifications();
|
||||
const viewName = useGetSearchQueryParam(QueryParams.viewName) || '';
|
||||
|
||||
const cleanedNodeKey = removeObjectFromString(nodeKey);
|
||||
const isBodyJsonQueryEnabled =
|
||||
featureFlags?.find((flag) => flag.name === FeatureKeys.BODY_JSON_ENABLED)
|
||||
?.active || false;
|
||||
|
||||
// Group by is supported only for body json query enabled and not for array elements
|
||||
const isGroupBySupported =
|
||||
isBodyJsonQueryEnabled && !cleanedNodeKey.includes('[]');
|
||||
|
||||
const filterHandler = (isFilterIn: boolean) => (): void => {
|
||||
if (parentIsArray) {
|
||||
onAddToQuery(
|
||||
generateFieldKeyForArray(
|
||||
cleanedNodeKey,
|
||||
removeObjectFromString(nodeKey),
|
||||
getDataTypes(value),
|
||||
isBodyJsonQueryEnabled,
|
||||
),
|
||||
`${value}`,
|
||||
isFilterIn
|
||||
@@ -71,7 +45,7 @@ function BodyTitleRenderer({
|
||||
);
|
||||
} else {
|
||||
onAddToQuery(
|
||||
`body.${cleanedNodeKey}`,
|
||||
`body.${removeObjectFromString(nodeKey)}`,
|
||||
`${value}`,
|
||||
isFilterIn ? OPERATORS['='] : OPERATORS['!='],
|
||||
getDataTypes(value),
|
||||
@@ -79,67 +53,10 @@ function BodyTitleRenderer({
|
||||
}
|
||||
};
|
||||
|
||||
const groupByHandler = useCallback((): void => {
|
||||
if (!stagedQuery) {
|
||||
return;
|
||||
}
|
||||
|
||||
const groupByKey = parentIsArray
|
||||
? generateFieldKeyForArray(
|
||||
cleanedNodeKey,
|
||||
getDataTypes(value),
|
||||
isBodyJsonQueryEnabled,
|
||||
)
|
||||
: `body.${cleanedNodeKey}`;
|
||||
|
||||
const fieldDataType = getDataTypes(value);
|
||||
const normalizedDataType: DataTypes | undefined = Object.values(
|
||||
DataTypes,
|
||||
).includes(fieldDataType as DataTypes)
|
||||
? (fieldDataType as DataTypes)
|
||||
: undefined;
|
||||
|
||||
const updatedQuery = updateQueriesData(
|
||||
stagedQuery,
|
||||
'queryData',
|
||||
(item, index) => {
|
||||
if (index === 0) {
|
||||
const newGroupByItem: BaseAutocompleteData = {
|
||||
key: groupByKey,
|
||||
type: '',
|
||||
dataType: normalizedDataType,
|
||||
};
|
||||
|
||||
return { ...item, groupBy: [...(item.groupBy || []), newGroupByItem] };
|
||||
}
|
||||
|
||||
return item;
|
||||
},
|
||||
);
|
||||
|
||||
const queryData: ICurrentQueryData = {
|
||||
name: viewName,
|
||||
id: updatedQuery.id,
|
||||
query: updatedQuery,
|
||||
};
|
||||
|
||||
handleChangeSelectedView?.(ExplorerViews.TIMESERIES, queryData);
|
||||
}, [
|
||||
cleanedNodeKey,
|
||||
handleChangeSelectedView,
|
||||
isBodyJsonQueryEnabled,
|
||||
parentIsArray,
|
||||
stagedQuery,
|
||||
updateQueriesData,
|
||||
value,
|
||||
viewName,
|
||||
]);
|
||||
|
||||
const onClickHandler: MenuProps['onClick'] = (props): void => {
|
||||
const mapper = {
|
||||
[DROPDOWN_KEY.FILTER_IN]: filterHandler(true),
|
||||
[DROPDOWN_KEY.FILTER_OUT]: filterHandler(false),
|
||||
[DROPDOWN_KEY.GROUP_BY]: groupByHandler,
|
||||
};
|
||||
|
||||
const handler = mapper[props.key];
|
||||
@@ -159,14 +76,6 @@ function BodyTitleRenderer({
|
||||
key: DROPDOWN_KEY.FILTER_OUT,
|
||||
label: `Filter out ${value}`,
|
||||
},
|
||||
...(isGroupBySupported
|
||||
? [
|
||||
{
|
||||
key: DROPDOWN_KEY.GROUP_BY,
|
||||
label: `Group by ${nodeKey}`,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
onClick: onClickHandler,
|
||||
};
|
||||
@@ -175,6 +84,7 @@ function BodyTitleRenderer({
|
||||
(e: React.MouseEvent): void => {
|
||||
// Prevent tree node expansion/collapse
|
||||
e.stopPropagation();
|
||||
const cleanedKey = removeObjectFromString(nodeKey);
|
||||
let copyText: string;
|
||||
|
||||
// Check if value is an object or array
|
||||
@@ -196,8 +106,8 @@ function BodyTitleRenderer({
|
||||
|
||||
if (copyText) {
|
||||
const notificationMessage = isObject
|
||||
? `${cleanedNodeKey} object copied to clipboard`
|
||||
: `${cleanedNodeKey} copied to clipboard`;
|
||||
? `${cleanedKey} object copied to clipboard`
|
||||
: `${cleanedKey} copied to clipboard`;
|
||||
|
||||
notifications.success({
|
||||
message: notificationMessage,
|
||||
@@ -205,7 +115,7 @@ function BodyTitleRenderer({
|
||||
});
|
||||
}
|
||||
},
|
||||
[cleanedNodeKey, parentIsArray, setCopy, value, notifications],
|
||||
[nodeKey, parentIsArray, setCopy, value, notifications],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -251,20 +251,20 @@ describe('ContextLogRenderer', () => {
|
||||
const afterQuery = (afterPayload.compositeQuery as any).queries[0].spec;
|
||||
|
||||
// Verify timestamps remain constant
|
||||
expect(afterStart).toStrictEqual(initialPayload.start);
|
||||
expect(afterEnd).toStrictEqual(initialPayload.end);
|
||||
expect(afterStart).toEqual(initialPayload.start);
|
||||
expect(afterEnd).toEqual(initialPayload.end);
|
||||
|
||||
// Verify offset changes
|
||||
expect(initialQuery.offset).toBe(0);
|
||||
expect(afterQuery.offset).toBe(10);
|
||||
expect(initialQuery.offset).toEqual(0);
|
||||
expect(afterQuery.offset).toEqual(10);
|
||||
|
||||
// Verify filter changes
|
||||
expect(initialQuery.filter.expression).toContain(expectedOpChange.before);
|
||||
expect(afterQuery.filter.expression).toContain(expectedOpChange.after);
|
||||
|
||||
// Verify query structure remains consistent
|
||||
expect(initialQuery.name).toStrictEqual(afterQuery.name);
|
||||
expect(initialQuery.signal).toStrictEqual(afterQuery.signal);
|
||||
expect(initialQuery.name).toEqual(afterQuery.name);
|
||||
expect(initialQuery.signal).toEqual(afterQuery.signal);
|
||||
};
|
||||
|
||||
it('should keep the start and end timestamps constant on clicking load more (prev / next) pages', async () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ChangeViewFunctionType } from 'container/ExplorerOptions/types';
|
||||
import { MetricsType } from 'container/MetricsApplication/constant';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
|
||||
@@ -7,7 +6,6 @@ export interface BodyTitleRendererProps {
|
||||
nodeKey: string;
|
||||
value: unknown;
|
||||
parentIsArray?: boolean;
|
||||
handleChangeSelectedView?: ChangeViewFunctionType;
|
||||
}
|
||||
|
||||
export type AnyObject = { [key: string]: any };
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user