Skip to content

Commit

Permalink
migrate notifications to gql status objects
Browse files Browse the repository at this point in the history
  • Loading branch information
daveajrussell committed Dec 4, 2024
1 parent 323e84c commit 1f554c5
Show file tree
Hide file tree
Showing 8 changed files with 623 additions and 58 deletions.
97 changes: 90 additions & 7 deletions src/browser/modules/Stream/CypherFrame/WarningsView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,22 @@ describe('WarningsViews', () => {
// Then
expect(container).toMatchSnapshot()
})

test('does displays a warning', () => {
// Given
const props = {
result: {
summary: {
notifications: [
{
severity: 'WARNING xx0',
severity: 'WARNING',
title: 'My xx1 warning',
description: 'This is xx2 warning',
position: {
offset: 7,
line: 1
}
},
code: 'xx3.Warning'
}
],
query: {
Expand All @@ -65,29 +67,66 @@ describe('WarningsViews', () => {
// Then
expect(container).toMatchSnapshot()
})
test('does displays multiple warnings', () => {

test('does display a warning for GQL status codes', () => {
// Given
const props = {
result: {
summary: {
server: {
protocolVersion: 5.6
},
gqlStatusObjects: [
{
severity: 'WARNING',
gqlStatus: '03N90',
statusDescription:
"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.",
position: {
offset: 7,
line: 1
}
}
],
query: {
text: 'MATCH p=()--(), q=()--() RETURN p, q'
}
}
}
}

// When
const { container } = render(<WarningsView {...props} />)

// Then
expect(container).toMatchSnapshot()
})

test('does display multiple warnings', () => {
// Given
const props = {
result: {
summary: {
notifications: [
{
severity: 'WARNING xx0',
severity: 'WARNING',
title: 'My xx1 warning',
description: 'This is xx2 warning',
position: {
offset: 7,
line: 1
}
},
code: 'xx3.Warning'
},
{
severity: 'WARNING yy0',
severity: 'WARNING',
title: 'My yy1 warning',
description: 'This is yy2 warning',
position: {
offset: 3,
line: 1
}
},
code: 'yy3.Warning'
}
],
query: {
Expand All @@ -103,5 +142,49 @@ describe('WarningsViews', () => {
// Then
expect(container).toMatchSnapshot()
})

test('does display multiple warnings for GQL status codes', () => {
// Given
const props = {
result: {
summary: {
server: {
protocolVersion: 5.6
},
gqlStatusObjects: [
{
severity: 'WARNING',
gqlStatus: '03N90',
statusDescription:
"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.",
position: {
offset: 7,
line: 1
}
},
{
severity: 'WARNING',
gqlStatus: '01N50',
statusDescription:
'warn: label does not exist. The label `A` does not exist. Verify that the spelling is correct.',
position: {
offset: 3,
line: 1
}
}
],
query: {
text: 'MATCH p=()--(), q=()--() RETURN p, q'
}
}
}
}

// When
const { container } = render(<WarningsView {...props} />)

// Then
expect(container).toMatchSnapshot()
})
})
})
67 changes: 38 additions & 29 deletions src/browser/modules/Stream/CypherFrame/WarningsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ import {
StyledCypherInfoMessage
} from '../styled'
import { deepEquals } from 'neo4j-arc/common'
import {
formatNotificationsFromSummary,
FormattedNotification
} from './warningUtilts'
import { NotificationSeverityLevel } from 'neo4j-driver-core'

const getWarningComponent = (severity: any) => {
const getWarningComponent = (severity?: string | NotificationSeverityLevel) => {
if (severity === 'ERROR') {
return <StyledCypherErrorMessage>{severity}</StyledCypherErrorMessage>
} else if (severity === 'WARNING') {
Expand All @@ -56,43 +61,47 @@ export class WarningsView extends Component<any> {
render() {
if (this.props.result === undefined) return null
const { summary = {} } = this.props.result
const { notifications = [], query = {} } = summary
const { query = {} } = summary
const notifications = formatNotificationsFromSummary(summary)
const { text: cypher = '' } = query
if (!notifications || !cypher) {
return null
}
const cypherLines = cypher.split('\n')
const notificationsList = notifications.map((notification: any) => {
// Detect generic warning without position information
const position = Object.keys(notification.position).length
? notification.position
: { line: 1, offset: 0 }
return (
<StyledHelpContent
key={notification.title + position.line + position.offset}
>
<StyledHelpDescription>
{getWarningComponent(notification.severity)}
<StyledH4>{notification.title}</StyledH4>
</StyledHelpDescription>
<StyledDiv>
const notificationsList = notifications.map(
(notification: FormattedNotification) => {
// Detect generic warning without position information
const { code, description, severity } = notification
const position = notification.position ?? { line: 1, offset: 0 }
const title = notification.title ?? ''
const line = position.line ?? 1
const offset = position.offset ?? 0

return (
<StyledHelpContent key={title + line + position.offset}>
<StyledHelpDescription>
{notification.description}
{getWarningComponent(severity)}
<StyledH4>{title}</StyledH4>
</StyledHelpDescription>
<StyledDiv>
<StyledPreformattedArea>
{cypherLines[position.line - 1]}
<StyledBr />
{Array(position.offset + 1).join(' ')}^
</StyledPreformattedArea>
<StyledHelpDescription>{description}</StyledHelpDescription>
<StyledDiv>
<StyledPreformattedArea>
{cypherLines[line - 1]}
<StyledBr />
{Array(offset + 1).join(' ')}^
</StyledPreformattedArea>
</StyledDiv>
</StyledDiv>
</StyledDiv>
<StyledDiv style={{ marginTop: '10px' }}>
Status code: <StyledCode>{notification.code}</StyledCode>
</StyledDiv>
</StyledHelpContent>
)
})
{code && (
<StyledDiv style={{ marginTop: '10px' }}>
Status code: <StyledCode>{code}</StyledCode>
</StyledDiv>
)}
</StyledHelpContent>
)
}
)
return <StyledHelpFrame>{notificationsList}</StyledHelpFrame>
}
}
Expand Down
Loading

0 comments on commit 1f554c5

Please sign in to comment.