Skip to content

Commit

Permalink
1491 adding transaction versioning (#1493)
Browse files Browse the repository at this point in the history
  • Loading branch information
xoscar committed Nov 15, 2022
1 parent 357c8c5 commit 315ca36
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 21 deletions.
5 changes: 5 additions & 0 deletions server/testdb/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ func (td *postgresDB) GetTransactionVersion(ctx context.Context, id id.ID, versi
return model.Transaction{}, err
}

transaction.Steps, err = td.getTransactionSteps(ctx, transaction)
if err != nil {
return model.Transaction{}, err
}

return transaction, nil
}

Expand Down
12 changes: 9 additions & 3 deletions web/src/pages/Transaction/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Button} from 'antd';
import {useMemo} from 'react';
import {useCallback, useMemo} from 'react';
import {useNavigate} from 'react-router-dom';

import PaginatedList from 'components/PaginatedList';
Expand All @@ -9,13 +9,19 @@ import {useTransaction} from 'providers/Transaction/Transaction.provider';
import {useGetTransactionRunsQuery} from 'redux/apis/TraceTest.api';
import {TTransactionRun} from 'types/TransactionRun.types';
import ExperimentalFeature from 'utils/ExperimentalFeature';
import useTransactionCrud from 'providers/Transaction/hooks/useTransactionCrud';
import * as S from './Transaction.styled';

const Content = () => {
const navigate = useNavigate();
const {isLoadingRun, onDelete, onRun, transaction} = useTransaction();
const {onDelete, transaction} = useTransaction();
const {runTransaction, isEditLoading} = useTransactionCrud();
const params = useMemo(() => ({transactionId: transaction.id}), [transaction.id]);

const handleRunTest = useCallback(async () => {
if (transaction.id) runTransaction(transaction.id);
}, [runTransaction, transaction.id]);

return (
<S.Container $isWhite={!ExperimentalFeature.isEnabled('transactions')}>
<TestHeader
Expand All @@ -28,7 +34,7 @@ const Content = () => {

<S.ActionsContainer>
<div />
<Button onClick={onRun} loading={isLoadingRun} type="primary" ghost>
<Button onClick={handleRunTest} loading={isEditLoading} type="primary" ghost>
Run Transaction
</Button>
</S.ActionsContainer>
Expand Down
5 changes: 1 addition & 4 deletions web/src/pages/TransactionRunDetail/TransactionRunDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Layout from 'components/Layout';
import withAnalytics from 'components/WithAnalytics/WithAnalytics';
import TransactionProvider from 'providers/Transaction';
import TransactionRunProvider from 'providers/TransactionRun';
import {useParams} from 'react-router-dom';
import TransactionContent from './Content';
Expand All @@ -10,9 +9,7 @@ const TransactionRunDetail = () => {
return (
<Layout>
<TransactionRunProvider transactionId={transactionId} runId={runId}>
<TransactionProvider transactionId={transactionId}>
<TransactionContent />
</TransactionProvider>
<TransactionContent />
</TransactionRunProvider>
</Layout>
);
Expand Down
83 changes: 70 additions & 13 deletions web/src/providers/Transaction/Transaction.provider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {noop} from 'lodash';
import {createContext, ReactNode, useCallback, useContext, useMemo} from 'react';
import {createContext, ReactNode, useCallback, useContext, useMemo, useState} from 'react';
import {useNavigate} from 'react-router-dom';

import {useGetTransactionByIdQuery} from 'redux/apis/TraceTest.api';
import {useGetTransactionByIdQuery, useGetTransactionVersionByIdQuery} from 'redux/apis/TraceTest.api';
import {TDraftTransaction, TTransaction} from 'types/Transaction.types';
import VersionMismatchModal from 'components/VersionMismatchModal';
import {useConfirmationModal} from '../ConfirmationModal/ConfirmationModal.provider';
import useTransactionCrud from './hooks/useTransactionCrud';

Expand All @@ -16,6 +17,7 @@ interface IContext {
onEdit(draft: TDraftTransaction): void;
onRun(): void;
transaction: TTransaction;
latestTransaction: TTransaction;
}

export const Context = createContext<IContext>({
Expand All @@ -27,24 +29,51 @@ export const Context = createContext<IContext>({
onRun: noop,
onEdit: noop,
transaction: {} as TTransaction,
latestTransaction: {} as TTransaction,
});

interface IProps {
children: ReactNode;
transactionId: string;
version?: number;
}

export const useTransaction = () => useContext(Context);

const TransactionProvider = ({children, transactionId}: IProps) => {
const {data: transaction, isLoading, isError} = useGetTransactionByIdQuery({transactionId});
const TransactionProvider = ({children, transactionId, version = 0}: IProps) => {
const [isVersionModalOpen, setIsVersionModalOpen] = useState(false);
const [action, setAction] = useState<'edit' | 'run'>();
const [draft, setDraft] = useState<TDraftTransaction>({});
const {
data: latestTransaction,
isLoading: isLatestLoading,
isError: isLatestError,
} = useGetTransactionByIdQuery({transactionId});
const {deleteTransaction, runTransaction, isEditLoading, edit} = useTransactionCrud();
const {
data: transaction,
isLoading: isCurrentLoading,
isError: isCurrentError,
} = useGetTransactionVersionByIdQuery({transactionId, version}, {skip: !version});

const isLoading = isLatestLoading || isCurrentLoading;
const isError = isLatestError || isCurrentError;
const currentTransaction = (version ? transaction : latestTransaction)!;
const isLatestVersion = useMemo(
() => Boolean(version) && version === latestTransaction?.version,
[latestTransaction?.version, version]
);

const {onOpen} = useConfirmationModal();
const navigate = useNavigate();

const onRun = useCallback(() => {
runTransaction(transactionId);
}, [runTransaction, transactionId]);
if (isLatestVersion) runTransaction(transactionId);
else {
setAction('run');
setIsVersionModalOpen(true);
}
}, [isLatestVersion, runTransaction, transactionId]);

const onDelete = useCallback(
(id: string, name: string) => {
Expand All @@ -59,12 +88,24 @@ const TransactionProvider = ({children, transactionId}: IProps) => {
);

const onEdit = useCallback(
(draft: TDraftTransaction) => {
edit(transaction!, draft);
(values: TDraftTransaction) => {
if (isLatestVersion) edit(transaction!, values);
else {
setAction('edit');
setDraft(values);
setIsVersionModalOpen(true);
}
},
[edit, transaction]
[edit, isLatestVersion, transaction]
);

const onConfirm = useCallback(() => {
if (action === 'edit') edit(transaction!, draft);
else edit(transaction!, transaction!);

setIsVersionModalOpen(false);
}, [action, draft, edit, transaction]);

const value = useMemo<IContext>(
() => ({
isError,
Expand All @@ -74,13 +115,29 @@ const TransactionProvider = ({children, transactionId}: IProps) => {
onEdit,
onRun,
isEditLoading,
transaction: transaction!,
transaction: currentTransaction!,
latestTransaction: latestTransaction!,
}),
[isEditLoading, isError, isLoading, onDelete, onEdit, onRun, transaction]
[currentTransaction, isEditLoading, isError, isLoading, latestTransaction, onDelete, onEdit, onRun]
);

return transaction ? (
<Context.Provider value={value}>{children}</Context.Provider>
return currentTransaction && latestTransaction ? (
<>
<Context.Provider value={value}>{children}</Context.Provider>
<VersionMismatchModal
description={
action === 'edit'
? 'Editing it will result in a new version that will become the latest.'
: 'Running the test will use the latest version of the transaction.'
}
currentVersion={currentTransaction.version}
isOpen={isVersionModalOpen}
latestVersion={latestTransaction.version}
okText="Run Test"
onCancel={() => setIsVersionModalOpen(false)}
onConfirm={onConfirm}
/>
</>
) : (
<div data-cy="loading-transaction" />
);
Expand Down
7 changes: 6 additions & 1 deletion web/src/providers/TransactionRun/TransactionRunProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {createContext, useContext, useMemo} from 'react';
import {useGetTransactionRunByIdQuery} from 'redux/apis/TraceTest.api';
import {TTransactionRun} from 'types/TransactionRun.types';
import TransactionProvider from '../Transaction/Transaction.provider';

interface IContext {
transactionRun?: TTransactionRun;
Expand All @@ -23,7 +24,11 @@ const TransactionRunProvider = ({children, transactionId, runId}: IProps) => {

const value = useMemo<IContext>(() => ({transactionRun}), [transactionRun]);

return transactionRun ? <Context.Provider value={value}>{children}</Context.Provider> : null;
return transactionRun ? (
<TransactionProvider transactionId={transactionId} version={transactionRun.version}>
<Context.Provider value={value}>{children}</Context.Provider>
</TransactionProvider>
) : null;
};

export default TransactionRunProvider;
1 change: 1 addition & 0 deletions web/src/redux/apis/TraceTest.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const {
useSetTestOutputsMutation,
useGetResourcesQuery,
useRunTransactionMutation,
useGetTransactionVersionByIdQuery,
} = TraceTestAPI;
export const {endpoints} = TraceTestAPI;

Expand Down
6 changes: 6 additions & 0 deletions web/src/redux/apis/endpoints/Transaction.endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ const TransactionEndpoint = (builder: TTestApiEndpointBuilder) => ({
providesTags: result => [{type: TracetestApiTags.TRANSACTION, id: result?.id}],
transformResponse: (rawTransaction: TRawTransaction) => Transaction(rawTransaction),
}),
getTransactionVersionById: builder.query<TTransaction, {transactionId: string; version: number}>({
query: ({transactionId, version}) => `/transactions/${transactionId}/version/${version}`,
providesTags: result => [{type: TracetestApiTags.TRANSACTION, id: `${result?.id}-${result?.version}`}],
transformResponse: (rawTest: TRawTransaction) => Transaction(rawTest),
keepUnusedDataFor: 10,
}),
});

export default TransactionEndpoint;
23 changes: 23 additions & 0 deletions web/src/types/Generated.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export interface paths {
/** delete a transaction */
delete: operations["deleteTransaction"];
};
"/transactions/{transactionId}/version/{version}": {
/** get a transaction specific version */
get: operations["getTransactionVersion"];
};
"/transactions/{transactionId}/run": {
/** Get all runs from a particular transaction */
get: operations["getTransactionRuns"];
Expand Down Expand Up @@ -251,6 +255,25 @@ export interface operations {
204: never;
};
};
/** get a transaction specific version */
getTransactionVersion: {
parameters: {
path: {
transactionId: string;
version: number;
};
};
responses: {
/** successful operation */
200: {
content: {
"application/json": external["transactions.yaml"]["components"]["schemas"]["Transaction"];
};
};
/** problem with getting a test */
500: unknown;
};
};
/** Get all runs from a particular transaction */
getTransactionRuns: {
parameters: {
Expand Down

0 comments on commit 315ca36

Please sign in to comment.