Skip to content

Commit 1f554c5

Browse files
committed
migrate notifications to gql status objects
1 parent 323e84c commit 1f554c5

File tree

8 files changed

+623
-58
lines changed

8 files changed

+623
-58
lines changed

src/browser/modules/Stream/CypherFrame/WarningsView.test.tsx

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,22 @@ describe('WarningsViews', () => {
3636
// Then
3737
expect(container).toMatchSnapshot()
3838
})
39+
3940
test('does displays a warning', () => {
4041
// Given
4142
const props = {
4243
result: {
4344
summary: {
4445
notifications: [
4546
{
46-
severity: 'WARNING xx0',
47+
severity: 'WARNING',
4748
title: 'My xx1 warning',
4849
description: 'This is xx2 warning',
4950
position: {
5051
offset: 7,
5152
line: 1
52-
}
53+
},
54+
code: 'xx3.Warning'
5355
}
5456
],
5557
query: {
@@ -65,29 +67,66 @@ describe('WarningsViews', () => {
6567
// Then
6668
expect(container).toMatchSnapshot()
6769
})
68-
test('does displays multiple warnings', () => {
70+
71+
test('does display a warning for GQL status codes', () => {
72+
// Given
73+
const props = {
74+
result: {
75+
summary: {
76+
server: {
77+
protocolVersion: 5.6
78+
},
79+
gqlStatusObjects: [
80+
{
81+
severity: 'WARNING',
82+
gqlStatus: '03N90',
83+
statusDescription:
84+
"info: cartesian product. The disconnected pattern 'p = ()--(), q = ()--()' builds a cartesian product. A cartesian product may produce a large amount of data and slow down query processing.",
85+
position: {
86+
offset: 7,
87+
line: 1
88+
}
89+
}
90+
],
91+
query: {
92+
text: 'MATCH p=()--(), q=()--() RETURN p, q'
93+
}
94+
}
95+
}
96+
}
97+
98+
// When
99+
const { container } = render(<WarningsView {...props} />)
100+
101+
// Then
102+
expect(container).toMatchSnapshot()
103+
})
104+
105+
test('does display multiple warnings', () => {
69106
// Given
70107
const props = {
71108
result: {
72109
summary: {
73110
notifications: [
74111
{
75-
severity: 'WARNING xx0',
112+
severity: 'WARNING',
76113
title: 'My xx1 warning',
77114
description: 'This is xx2 warning',
78115
position: {
79116
offset: 7,
80117
line: 1
81-
}
118+
},
119+
code: 'xx3.Warning'
82120
},
83121
{
84-
severity: 'WARNING yy0',
122+
severity: 'WARNING',
85123
title: 'My yy1 warning',
86124
description: 'This is yy2 warning',
87125
position: {
88126
offset: 3,
89127
line: 1
90-
}
128+
},
129+
code: 'yy3.Warning'
91130
}
92131
],
93132
query: {
@@ -103,5 +142,49 @@ describe('WarningsViews', () => {
103142
// Then
104143
expect(container).toMatchSnapshot()
105144
})
145+
146+
test('does display multiple warnings for GQL status codes', () => {
147+
// Given
148+
const props = {
149+
result: {
150+
summary: {
151+
server: {
152+
protocolVersion: 5.6
153+
},
154+
gqlStatusObjects: [
155+
{
156+
severity: 'WARNING',
157+
gqlStatus: '03N90',
158+
statusDescription:
159+
"info: cartesian product. The disconnected pattern 'p = ()--(), q = ()--()' builds a cartesian product. A cartesian product may produce a large amount of data and slow down query processing.",
160+
position: {
161+
offset: 7,
162+
line: 1
163+
}
164+
},
165+
{
166+
severity: 'WARNING',
167+
gqlStatus: '01N50',
168+
statusDescription:
169+
'warn: label does not exist. The label `A` does not exist. Verify that the spelling is correct.',
170+
position: {
171+
offset: 3,
172+
line: 1
173+
}
174+
}
175+
],
176+
query: {
177+
text: 'MATCH p=()--(), q=()--() RETURN p, q'
178+
}
179+
}
180+
}
181+
}
182+
183+
// When
184+
const { container } = render(<WarningsView {...props} />)
185+
186+
// Then
187+
expect(container).toMatchSnapshot()
188+
})
106189
})
107190
})

src/browser/modules/Stream/CypherFrame/WarningsView.tsx

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ import {
3434
StyledCypherInfoMessage
3535
} from '../styled'
3636
import { deepEquals } from 'neo4j-arc/common'
37+
import {
38+
formatNotificationsFromSummary,
39+
FormattedNotification
40+
} from './warningUtilts'
41+
import { NotificationSeverityLevel } from 'neo4j-driver-core'
3742

38-
const getWarningComponent = (severity: any) => {
43+
const getWarningComponent = (severity?: string | NotificationSeverityLevel) => {
3944
if (severity === 'ERROR') {
4045
return <StyledCypherErrorMessage>{severity}</StyledCypherErrorMessage>
4146
} else if (severity === 'WARNING') {
@@ -56,43 +61,47 @@ export class WarningsView extends Component<any> {
5661
render() {
5762
if (this.props.result === undefined) return null
5863
const { summary = {} } = this.props.result
59-
const { notifications = [], query = {} } = summary
64+
const { query = {} } = summary
65+
const notifications = formatNotificationsFromSummary(summary)
6066
const { text: cypher = '' } = query
6167
if (!notifications || !cypher) {
6268
return null
6369
}
6470
const cypherLines = cypher.split('\n')
65-
const notificationsList = notifications.map((notification: any) => {
66-
// Detect generic warning without position information
67-
const position = Object.keys(notification.position).length
68-
? notification.position
69-
: { line: 1, offset: 0 }
70-
return (
71-
<StyledHelpContent
72-
key={notification.title + position.line + position.offset}
73-
>
74-
<StyledHelpDescription>
75-
{getWarningComponent(notification.severity)}
76-
<StyledH4>{notification.title}</StyledH4>
77-
</StyledHelpDescription>
78-
<StyledDiv>
71+
const notificationsList = notifications.map(
72+
(notification: FormattedNotification) => {
73+
// Detect generic warning without position information
74+
const { code, description, severity } = notification
75+
const position = notification.position ?? { line: 1, offset: 0 }
76+
const title = notification.title ?? ''
77+
const line = position.line ?? 1
78+
const offset = position.offset ?? 0
79+
80+
return (
81+
<StyledHelpContent key={title + line + position.offset}>
7982
<StyledHelpDescription>
80-
{notification.description}
83+
{getWarningComponent(severity)}
84+
<StyledH4>{title}</StyledH4>
8185
</StyledHelpDescription>
8286
<StyledDiv>
83-
<StyledPreformattedArea>
84-
{cypherLines[position.line - 1]}
85-
<StyledBr />
86-
{Array(position.offset + 1).join(' ')}^
87-
</StyledPreformattedArea>
87+
<StyledHelpDescription>{description}</StyledHelpDescription>
88+
<StyledDiv>
89+
<StyledPreformattedArea>
90+
{cypherLines[line - 1]}
91+
<StyledBr />
92+
{Array(offset + 1).join(' ')}^
93+
</StyledPreformattedArea>
94+
</StyledDiv>
8895
</StyledDiv>
89-
</StyledDiv>
90-
<StyledDiv style={{ marginTop: '10px' }}>
91-
Status code: <StyledCode>{notification.code}</StyledCode>
92-
</StyledDiv>
93-
</StyledHelpContent>
94-
)
95-
})
96+
{code && (
97+
<StyledDiv style={{ marginTop: '10px' }}>
98+
Status code: <StyledCode>{code}</StyledCode>
99+
</StyledDiv>
100+
)}
101+
</StyledHelpContent>
102+
)
103+
}
104+
)
96105
return <StyledHelpFrame>{notificationsList}</StyledHelpFrame>
97106
}
98107
}

0 commit comments

Comments
 (0)