Skip to content

Commit

Permalink
console: allow configuring session_argument for custom functions (close
Browse files Browse the repository at this point in the history
  • Loading branch information
soorajshankar authored Jun 11, 2020
1 parent 2f79136 commit cb3252c
Show file tree
Hide file tree
Showing 12 changed files with 455 additions and 44 deletions.
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

0 comments on commit cb3252c

Please sign in to comment.