这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4f6f9b8
use session var arg as SQL function arg #4499
soorajshankar May 28, 2020
9017a8d
Merge branch 'master' of https://github.com/hasura/graphql-engine
soorajshankar May 28, 2020
5cb419c
functions >session argument tests #4499
soorajshankar May 28, 2020
054c31a
changelog #4499
soorajshankar May 29, 2020
33b3343
Merge branch 'master' into feature/session_argument-as-sql-function-a…
soorajshankar May 29, 2020
798b4bd
Merge branch 'master' of https://github.com/hasura/graphql-engine int…
soorajshankar Jun 8, 2020
8bde531
Merge branch 'feature/session_argument-as-sql-function-argument-#4499…
soorajshankar Jun 8, 2020
63a2179
review comments v1
soorajshankar Jun 8, 2020
2bb4a5a
session arguments
soorajshankar Jun 8, 2020
fe37b34
Session Arguments
soorajshankar Jun 8, 2020
f2d97e7
better function naming
soorajshankar Jun 8, 2020
85f5a74
more test coverage
soorajshankar Jun 9, 2020
18fca1a
UI changes
soorajshankar Jun 9, 2020
a3af353
Merge branch 'master' of https://github.com/hasura/graphql-engine int…
soorajshankar Jun 9, 2020
da9260f
lint cleanup
soorajshankar Jun 9, 2020
5ba23f8
Merge branch 'master' into feature/session_argument-as-sql-function-a…
Jun 10, 2020
f6a3404
Update CHANGELOG.md
Jun 10, 2020
88bf6b6
down migration, untrack function with version 2
soorajshankar Jun 11, 2020
19e1ffa
Merge branch 'master' of https://github.com/hasura/graphql-engine int…
soorajshankar Jun 11, 2020
392f789
Merge branch 'master' into feature/session_argument-as-sql-function-a…
Jun 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ Read more about the session argument for computed fields in the [docs](https://h
- console: add new sidebar icon that separates enums from tables (fix #4984) (#4992)
- console: fix "Cannot read property 'foldable'" runtime error in `Browse Rows` page (fix #4907) (#5016)
- console: respect read-only mode in actions pages (fix #4656) (#4764)
- console: allow configuring session_argument for custom functions (close #4499) (#4922)
- console: fix listen update column config selection for event trigger (close #5042) (#5043)
- cli: list all available commands in root command help (fix #4623) (#4628)
- cli: fix bug with squashing event triggers (close #4883)
Expand Down
65 changes: 62 additions & 3 deletions console/cypress/helpers/dataHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,43 @@ export const testCustomFunctionSQL = (i: number) => {
};
};

export const testCustomFunctionSQLWithSessArg = (
name = 'customFunctionWithSessionArg'
) => {
return {
type: 'bulk',
args: [
{
type: 'run_sql',
args: {
sql: `CREATE OR REPLACE FUNCTION ${name}(
hasura_session json, name text
) RETURNS SETOF text_result LANGUAGE sql STABLE AS $$
SELECT
q.*
FROM
(
VALUES
(hasura_session ->> 'x-hasura-role')
) q $$`,
cascade: false,
},
},
],
};
};
export const getTrackFnPayload = (name = 'customfunctionwithsessionarg') => ({
type: 'bulk',
args: [
{
type: 'track_function',
args: {
name,
schema: 'public',
},
},
],
});
export const createTable = () => {
return {
type: 'bulk',
Expand All @@ -119,18 +156,40 @@ export const createTable = () => {
],
};
};

export const dropTable = () => {
export const createTableSessVar = () => {
return {
type: 'bulk',
args: [
{
type: 'run_sql',
args: {
sql: 'DROP table post;',
sql: `CREATE TABLE text_result(
result text
);`,
cascade: false,
},
},
{
type: 'add_existing_table_or_view',
args: {
name: 'text_result',
schema: 'public',
},
},
],
};
};
export const dropTable = (table = 'post', cascade = false) => {
return {
type: 'bulk',
args: [
{
type: 'run_sql',
args: {
sql: `DROP table ${table}${cascade ? ' CASCADE;' : ';'}`,
cascade,
},
},
],
};
};
Expand Down
52 changes: 49 additions & 3 deletions console/cypress/integration/data/functions/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
testCustomFunctionSQL,
createTable,
dropTable,
createTableSessVar,
testCustomFunctionSQLWithSessArg,
getTrackFnPayload,
} from '../../../helpers/dataHelpers';

import {
Expand All @@ -14,6 +17,8 @@ import {
validateCFunc,
validateUntrackedFunc,
ResultType,
createFunctionRequest,
trackFunctionRequest,
} from '../../validators/validators';
import { setPromptValue } from '../../../helpers/common';

Expand Down Expand Up @@ -53,6 +58,49 @@ export const trackFunction = () => {
validateCFunc(getCustomFunctionName(1), getSchema(), ResultType.SUCCESS);
cy.wait(5000);
};
export const testSessVariable = () => {
// Round about way to create a function
const fN = 'customFunctionWithSessionArg'.toLowerCase(); // for reading
dataRequest(createTableSessVar(), ResultType.SUCCESS);
createFunctionRequest(
testCustomFunctionSQLWithSessArg(fN),
ResultType.SUCCESS
);
cy.wait(1500);
trackFunctionRequest(getTrackFnPayload(fN), ResultType.SUCCESS);
cy.wait(1500);
cy.visit(`data/schema/public/functions/${fN}/modify`);
cy.get(getElementFromAlias(`${fN}-session-argument-btn`), {
timeout: 5000,
}).click();

// invalid data should fail
cy.get(getElementFromAlias(`${fN}-edit-sessvar-function-field`))
.clear()
.type('invalid');
cy.get(getElementFromAlias(`${fN}-session-argument-save`)).click();
cy.get('.notification-error', { timeout: 5000 })
.should('be.visible')
.and('contain', 'Updating Session argument variable failed');

cy.get(getElementFromAlias(`${fN}-session-argument-btn`), {
timeout: 1000,
}).click();
cy.get(getElementFromAlias(`${fN}-edit-sessvar-function-field`))
.clear()
.type('hasura_session');
cy.get(getElementFromAlias(`${fN}-session-argument-save`)).click();
cy.wait(2000);
cy.get(getElementFromAlias(fN)).should('be.visible');
cy.visit(`data/schema/public/functions/${fN}/modify`);
cy.wait(3000);
cy.get(getElementFromAlias(`${fN}-session-argument`)).should(
'contain',
'hasura_session'
);
dropTableRequest(dropTable('text_result', true), ResultType.SUCCESS);
cy.wait(2000);
};

export const verifyPermissionTab = () => {
cy.get(getElementFromAlias('functions-data-permissions')).click();
Expand All @@ -69,9 +117,7 @@ export const deleteCustomFunction = () => {
setPromptValue(getCustomFunctionName(1));

cy.get(getElementFromAlias('custom-function-edit-delete-btn')).click();
cy.window()
.its('prompt')
.should('be.called');
cy.window().its('prompt').should('be.called');
cy.wait(5000);
cy.get(getElementFromAlias('delete-confirmation-error')).should('not.exist');
cy.url().should('eq', `${baseUrl}/data/schema/public`);
Expand Down
2 changes: 2 additions & 0 deletions console/cypress/integration/data/functions/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
unTrackFunction,
trackFunction,
verifyPermissionTab,
testSessVariable,
} from './spec';

const setup = () => {
Expand All @@ -28,6 +29,7 @@ export const runCreateCustomFunctionsTableTests = () => {
it('Track custom function', trackFunction);
it('Verify permission tab', verifyPermissionTab);
it('Delete custom function', deleteCustomFunction);
it('Test custom function with Session Argument', testSessVariable);
});
};

Expand Down
32 changes: 32 additions & 0 deletions console/cypress/integration/validators/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,38 @@ export const dataRequest = (reqBody: RequestBody, result: ResultType) => {
});
};

export const createFunctionRequest = (
reqBody: RequestBody,
result: ResultType
) => {
const requestOptions = makeDataAPIOptions(dataApiUrl, adminSecret, reqBody);
cy.request(requestOptions).then(response => {
if (result === ResultType.SUCCESS) {
expect(
response.body.length > 0 && response.body[0].result_type === 'CommandOk'
).to.be.true;
} else {
expect(
response.body.length > 0 && response.body[0].result_type === 'CommandOk'
).to.be.false;
}
});
};

export const trackFunctionRequest = (
reqBody: RequestBody,
result: ResultType
) => {
const requestOptions = makeDataAPIOptions(dataApiUrl, adminSecret, reqBody);
cy.request(requestOptions).then(response => {
if (result === ResultType.SUCCESS) {
expect(response.body[0].message === ResultType.SUCCESS).to.be.true;
} else {
expect(response.body[0].message === ResultType.SUCCESS).to.be.false;
}
});
};

/**
* Drop a table request
* @param reqBody
Expand Down
2 changes: 1 addition & 1 deletion console/src/components/Common/Common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ code {

.tooltip {
cursor: pointer;
color: #4D4D4D;
color: #4d4d4d;
}

.hiddenMoreWidth {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import styles from './ModifyCustomFunction.scss';

export interface EditorInputProps {
value: string | number;
label: string | number;
placeholder?: string;
testID?: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

const EditorInput: React.FC<EditorInputProps> = ({
value,
onChange,
label,
placeholder,
testID,
}) => (
<div className={`${styles.display_flex} form-group`}>
<label className="col-xs-4">{label}</label>
<div className="col-xs-6">
<input
className="input-sm form-control"
value={value}
onChange={onChange}
placeholder={placeholder || ''}
type="text"
data-test={`${testID}-edit-sessvar-function-field`}
/>
</div>
</div>
);

export default EditorInput;
Loading