|
1 | 1 | import { ColumnHint, QueryBuilderOptions, QueryType } from 'types/queryBuilder'; |
2 | 2 | import { |
| 3 | + applyTraceSearchFieldConfig, |
3 | 4 | columnLabelToPlaceholder, |
4 | 5 | dataFrameHasLogLabelWithName, |
5 | 6 | isBuilderOptionsRunnable, |
@@ -110,6 +111,116 @@ describe('columnLabelToPlaceholder', () => { |
110 | 111 | }); |
111 | 112 | }); |
112 | 113 |
|
| 114 | +describe('applyTraceSearchFieldConfig', () => { |
| 115 | + const buildTraceSearchRequestResponse = ( |
| 116 | + fields: Field[], |
| 117 | + builderOptions: Partial<QueryBuilderOptions> = {} |
| 118 | + ): [DataQueryRequest<CHQuery>, DataQueryResponse] => { |
| 119 | + const inputQuery: CHBuilderQuery = { |
| 120 | + refId: 'A', |
| 121 | + editorType: EditorType.Builder, |
| 122 | + builderOptions: { |
| 123 | + database: 'default', |
| 124 | + table: 'otel_traces', |
| 125 | + queryType: QueryType.Traces, |
| 126 | + ...builderOptions, |
| 127 | + }, |
| 128 | + pluginVersion: '', |
| 129 | + rawSql: '', |
| 130 | + }; |
| 131 | + |
| 132 | + const request: DataQueryRequest<CHQuery> = { |
| 133 | + requestId: '', |
| 134 | + interval: '', |
| 135 | + intervalMs: 0, |
| 136 | + range: {} as any, |
| 137 | + scopedVars: {} as any, |
| 138 | + targets: [inputQuery], |
| 139 | + timezone: '', |
| 140 | + app: CoreApp.Explore, |
| 141 | + startTime: 0, |
| 142 | + }; |
| 143 | + |
| 144 | + const data: DataFrame[] = [{ |
| 145 | + fields, |
| 146 | + length: 1, |
| 147 | + refId: 'A', |
| 148 | + }]; |
| 149 | + const response: DataQueryResponse = { data }; |
| 150 | + |
| 151 | + return [request, response]; |
| 152 | + }; |
| 153 | + |
| 154 | + it('applies field configs to trace search result fields', () => { |
| 155 | + const fields: Field[] = [ |
| 156 | + { name: 'traceID', type: FieldType.string, config: {}, values: [] }, |
| 157 | + { name: 'serviceName', type: FieldType.string, config: {}, values: [] }, |
| 158 | + { name: 'operationName', type: FieldType.string, config: {}, values: [] }, |
| 159 | + { name: 'startTime', type: FieldType.time, config: {}, values: [] }, |
| 160 | + { name: 'duration', type: FieldType.number, config: {}, values: [] }, |
| 161 | + ]; |
| 162 | + |
| 163 | + const [request, response] = buildTraceSearchRequestResponse(fields); |
| 164 | + applyTraceSearchFieldConfig(request, response); |
| 165 | + |
| 166 | + expect(response.data[0].fields[4].config.unit).toBe('ms'); |
| 167 | + expect(response.data[0].fields[4].config.displayName).toBe('Duration'); |
| 168 | + expect(response.data[0].fields[0].config.displayName).toBe('Trace ID'); |
| 169 | + expect(response.data[0].fields[1].config.displayName).toBe('Service Name'); |
| 170 | + expect(response.data[0].fields[2].config.displayName).toBe('Operation Name'); |
| 171 | + expect(response.data[0].fields[3].config.displayName).toBe('Start Time'); |
| 172 | + }); |
| 173 | + |
| 174 | + it('does not apply field configs to trace ID mode queries', () => { |
| 175 | + const fields: Field[] = [ |
| 176 | + { name: 'duration', type: FieldType.number, config: {}, values: [] }, |
| 177 | + ]; |
| 178 | + |
| 179 | + const [request, response] = buildTraceSearchRequestResponse(fields, { |
| 180 | + meta: { isTraceIdMode: true, traceId: 'abc123' }, |
| 181 | + }); |
| 182 | + applyTraceSearchFieldConfig(request, response); |
| 183 | + |
| 184 | + expect(response.data[0].fields[0].config.unit).toBeUndefined(); |
| 185 | + }); |
| 186 | + |
| 187 | + it('does not apply field configs to non-trace queries', () => { |
| 188 | + const fields: Field[] = [ |
| 189 | + { name: 'duration', type: FieldType.number, config: {}, values: [] }, |
| 190 | + ]; |
| 191 | + |
| 192 | + const [request, response] = buildTraceSearchRequestResponse(fields, { |
| 193 | + queryType: QueryType.Table, |
| 194 | + }); |
| 195 | + applyTraceSearchFieldConfig(request, response); |
| 196 | + |
| 197 | + expect(response.data[0].fields[0].config.unit).toBeUndefined(); |
| 198 | + }); |
| 199 | + |
| 200 | + it('preserves existing field config properties', () => { |
| 201 | + const fields: Field[] = [ |
| 202 | + { name: 'duration', type: FieldType.number, config: { decimals: 2 }, values: [] }, |
| 203 | + ]; |
| 204 | + |
| 205 | + const [request, response] = buildTraceSearchRequestResponse(fields); |
| 206 | + applyTraceSearchFieldConfig(request, response); |
| 207 | + |
| 208 | + expect(response.data[0].fields[0].config.unit).toBe('ms'); |
| 209 | + expect(response.data[0].fields[0].config.decimals).toBe(2); |
| 210 | + }); |
| 211 | + |
| 212 | + it('does not modify fields that have no matching config', () => { |
| 213 | + const fields: Field[] = [ |
| 214 | + { name: 'customColumn', type: FieldType.string, config: {}, values: [] }, |
| 215 | + ]; |
| 216 | + |
| 217 | + const [request, response] = buildTraceSearchRequestResponse(fields); |
| 218 | + applyTraceSearchFieldConfig(request, response); |
| 219 | + |
| 220 | + expect(response.data[0].fields[0].config).toEqual({}); |
| 221 | + }); |
| 222 | +}); |
| 223 | + |
113 | 224 | describe('transformQueryResponseWithTraceAndLogLinks', () => { |
114 | 225 | const buildTestRequestResponse = ( |
115 | 226 | builderOptions: Partial<QueryBuilderOptions> |
|
0 commit comments