diff --git a/CHANGELOG.md b/CHANGELOG.md index 07e1b15a1f2..3a92a2292df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - server/bigquery: Fix issues related to adding and querying from non-US datasets (closes [6937](https://github.com/hasura/graphql-engine/issues/6937)). - console: add pagination on the Raw SQL results page - console: fix issues with replacing invalid graphql identifiers in table and column names +- console: show error message on inconsistent objects table ## v2.0.3 diff --git a/console/cypress/integration/settings/metadata/spec.ts b/console/cypress/integration/settings/metadata/spec.ts new file mode 100644 index 00000000000..7ff6f501912 --- /dev/null +++ b/console/cypress/integration/settings/metadata/spec.ts @@ -0,0 +1,45 @@ +import { getElementFromAlias, baseUrl } from '../../../helpers/dataHelpers'; + +// fake inconsistentMetadata api response +const inconsistentMetadata = { + is_consistent: false, + inconsistent_objects: [ + { + definition: 'DB2', + reason: 'Inconsistent object: connection error', + name: 'source DB2', + type: 'source', + message: + 'could not translate host name "db" to address: Name or service not known\n', + }, + ], +}; + +export const inconsistentMetadataPage = () => { + // Set first column + cy.visit('/settings/metadata-status?is_redirected=true'); + cy.intercept('/v1/metadata', req => { + // dynamically respond to a request here + + if (req?.body?.type === 'get_inconsistent_metadata') { + // fake inconsistentMetadata api response to test the UI + return req.reply(inconsistentMetadata); + } + + // send all other requests to the destination server + req.reply(); + }); + cy.url().should( + 'eq', + `${baseUrl}/settings/metadata-status?is_redirected=true` + ); + + cy.get(getElementFromAlias('inconsistent_name_0')).contains('DB2'); + cy.get(getElementFromAlias('inconsistent_type_0')).contains('source'); + cy.get(getElementFromAlias('inconsistent_reason_0')).contains( + 'Inconsistent object: connection error' + ); + cy.get(getElementFromAlias('inconsistent_reason_0')).contains( + 'could not translate host name "db" to address: Name or service not known' + ); +}; diff --git a/console/cypress/integration/settings/metadata/test.ts b/console/cypress/integration/settings/metadata/test.ts new file mode 100644 index 00000000000..c0d2f116fcf --- /dev/null +++ b/console/cypress/integration/settings/metadata/test.ts @@ -0,0 +1,16 @@ +import { testMode } from '../../../helpers/common'; + +import { + inconsistentMetadataPage, +} from './spec'; + + +export const testInconsistentMetadatapage = () => { + describe('Inconsistent Metadata', () => { + it('should render inconsistent metadata table with fake data', inconsistentMetadataPage); + }); +}; + +if (testMode !== 'cli') { + testInconsistentMetadatapage(); +} diff --git a/console/src/components/Services/Settings/MetadataStatus/MetadataStatus.js b/console/src/components/Services/Settings/MetadataStatus/MetadataStatus.js index 9472194cdd0..37ac573aadc 100644 --- a/console/src/components/Services/Settings/MetadataStatus/MetadataStatus.js +++ b/console/src/components/Services/Settings/MetadataStatus/MetadataStatus.js @@ -30,58 +30,72 @@ const MetadataStatus = ({ dispatch, metadata }) => { - {metadata.inconsistentObjects.map((ico, _i) => { + {metadata.inconsistentObjects.map((iconsistentObject, _i) => { let name; let definition; - if (ico.type === 'source') { - name = ico.definition; + if (iconsistentObject.type === 'source') { + name = iconsistentObject.definition; } if ( - ico.type === 'object_relation' || - ico.type === 'array_relation' + iconsistentObject.type === 'object_relation' || + iconsistentObject.type === 'array_relation' ) { - name = ico.definition.name; + name = iconsistentObject.definition.name; definition = `relationship of table "${getTableNameFromDef( - ico.definition.table + iconsistentObject.definition.table )}"`; - } else if (ico.type === 'remote_relationship') { - name = ico.definition.name; + } else if (iconsistentObject.type === 'remote_relationship') { + name = iconsistentObject.definition.name; definition = `relationship between table "${getTableNameFromDef( - ico.definition.table - )}" and remote schema "${ico.definition.remote_schema}"`; - } else if (permissionTypes.includes(ico.type)) { - name = `${ico.definition.role}-permission`; - definition = `${ico.type} on table "${getTableNameFromDef( - ico.definition.table - )}"`; - } else if (ico.type === 'table') { - name = getTableNameFromDef(ico.definition); - definition = name; - } else if (ico.type === 'function') { - name = getTableNameFromDef(ico.definition); - definition = name; - } else if (ico.type === 'event_trigger') { - name = ico.definition.configuration.name; - definition = `event trigger on table "${getTableNameFromDef( - ico.definition.table - )}"`; - } else if (ico.type === 'remote_schema') { - name = ico.definition.name; - let url = `"${ - ico.definition.definition.url || - ico.definition.definition.url_from_env + iconsistentObject.definition.table + )}" and remote schema "${ + iconsistentObject.definition.remote_schema }"`; - if (ico.definition.definition.url_from_env) { + } else if (permissionTypes.includes(iconsistentObject.type)) { + name = `${iconsistentObject.definition.role}-permission`; + definition = `${ + iconsistentObject.type + } on table "${getTableNameFromDef( + iconsistentObject.definition.table + )}"`; + } else if (iconsistentObject.type === 'table') { + name = getTableNameFromDef(iconsistentObject.definition); + definition = name; + } else if (iconsistentObject.type === 'function') { + name = getTableNameFromDef(iconsistentObject.definition); + definition = name; + } else if (iconsistentObject.type === 'event_trigger') { + name = iconsistentObject.definition.configuration.name; + definition = `event trigger on table "${getTableNameFromDef( + iconsistentObject.definition.table + )}"`; + } else if (iconsistentObject.type === 'remote_schema') { + name = iconsistentObject.definition.name; + let url = `"${ + iconsistentObject.definition.definition.url || + iconsistentObject.definition.definition.url_from_env + }"`; + if (iconsistentObject.definition.definition.url_from_env) { url = `the url from the value of env var ${url}`; } definition = `remote schema named "${name}" at ${url}`; } return ( - {name} - {ico.type} - {definition} - {ico.reason} + {name} + + {iconsistentObject.type} + + + {definition} + + +
+ {iconsistentObject.reason} +
+ {iconsistentObject.message} +
+ ); })}