Skip to content

Commit

Permalink
fix: Error when deleting local changes. (#13669)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Queyrichon <michael.queyrichon@digdir.no>
  • Loading branch information
Konrad-Simso and mlqn authored Oct 8, 2024
1 parent aae8aef commit d2b2fba
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { ServicesContextProvider } from 'app-shared/contexts/ServicesContext';
import { queriesMock } from 'app-shared/mocks/queriesMock';
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock';
import { QueryKey } from 'app-shared/types/QueryKey';
import { jsonMetadata1Mock } from '../../../packages/schema-editor/test/mocks/metadataMocks';
import {
jsonMetadata1Mock,
xsdMetadata1Mock,
} from '../../../packages/schema-editor/test/mocks/metadataMocks';
import type { QueryClient } from '@tanstack/react-query';
import userEvent from '@testing-library/user-event';
import { createApiErrorMock } from 'app-shared/mocks/apiErrorMock';
Expand Down Expand Up @@ -174,4 +177,13 @@ describe('DataModelling', () => {
expect(screen.getByTitle(textMock('data_modelling.loading'))).toBeInTheDocument();
},
);

it('Should call useAddXsdMutation when Xsd is loaded', async () => {
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.DataModelsXsd, org, app], [xsdMetadata1Mock]);
render({}, queryClient);
await waitForElementToBeRemoved(() => screen.queryByTitle(textMock('data_modelling.loading')));

expect(queriesMock.addXsdFromRepo).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import classes from './SchemaEditorWithToolbar.module.css';
import { TopToolbar } from './TopToolbar';
import { LandingPagePanel } from './LandingPagePanel';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import type { MetadataOption } from '../../../types/MetadataOption';
import { SelectedSchemaEditor } from './SelectedSchemaEditor';
import type { DataModelMetadata } from 'app-shared/types/DataModelMetadata';
import { SchemaGenerationErrorsPanel } from './SchemaGenerationErrorsPanel';
import { useAddXsdMutation } from '../../../hooks/mutations/useAddXsdMutation';
import { isXsdFile } from 'app-shared/utils/filenameUtils';

export interface SchemaEditorWithToolbarProps {
createPathOption?: boolean;
Expand All @@ -19,16 +21,30 @@ export const SchemaEditorWithToolbar = ({
const [createNewOpen, setCreateNewOpen] = useState<boolean>(false);
const [selectedOption, setSelectedOption] = useState<MetadataOption | undefined>(undefined);
const [schemaGenerationErrorMessages, setSchemaGenerationErrorMessages] = useState<string[]>([]);
const { mutate: addXsdFromRepo } = useAddXsdMutation();

const modelPath = selectedOption?.value.repositoryRelativeUrl;
const existingSelectedOption = dataModels.some(
(model) => model.fileName === selectedOption?.value.fileName,
)
? selectedOption
: undefined;
const modelPath = existingSelectedOption?.value?.repositoryRelativeUrl;

useEffect(() => {
dataModels.forEach((model) => {
if (model.repositoryRelativeUrl && isXsdFile(model.repositoryRelativeUrl)) {
addXsdFromRepo(model.repositoryRelativeUrl);
}
});
}, [dataModels, addXsdFromRepo]);

return (
<div className={classes.root}>
<TopToolbar
createNewOpen={createNewOpen}
createPathOption={createPathOption}
dataModels={dataModels}
selectedOption={selectedOption}
selectedOption={existingSelectedOption}
setCreateNewOpen={setCreateNewOpen}
setSelectedOption={setSelectedOption}
onSetSchemaGenerationErrorMessages={(errorMessages: string[]) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function TopToolbar({
onSetSchemaGenerationErrorMessages,
}: TopToolbarProps) {
const modelPath = selectedOption?.value.repositoryRelativeUrl;

const { t } = useTranslation();
const { mutate: createDataModel } = useCreateDataModelMutation();
const prevDataModels = usePrevious(dataModels);
Expand Down
20 changes: 20 additions & 0 deletions frontend/app-development/hooks/mutations/useAddXsdMutation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { waitFor } from '@testing-library/react';
import { renderHookWithProviders } from '../../test/mocks';
import { useAddXsdMutation } from './useAddXsdMutation';
import { queriesMock } from 'app-shared/mocks/queriesMock';
import { app, org } from '@studio/testing/testids';

// Test data:
const modelPath: string = 'modelPath';

describe('useAddXsdMutation', () => {
it('Calls useAddXsdMutation with correct arguments', async () => {
const addDataModelXsd = renderHookWithProviders()(() => useAddXsdMutation()).renderHookResult
.result;
await addDataModelXsd.current.mutateAsync(modelPath);
await waitFor(() => expect(addDataModelXsd.current.isSuccess).toBe(true));

expect(queriesMock.addXsdFromRepo).toHaveBeenCalledTimes(1);
expect(queriesMock.addXsdFromRepo).toHaveBeenCalledWith(org, app, modelPath);
});
});
21 changes: 21 additions & 0 deletions frontend/app-development/hooks/mutations/useAddXsdMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { QueryKey } from 'app-shared/types/QueryKey';
import { useServicesContext } from 'app-shared/contexts/ServicesContext';
import { StringUtils } from '@studio/pure-functions';
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';

export const useAddXsdMutation = () => {
const { addXsdFromRepo } = useServicesContext();
const queryClient = useQueryClient();
const { org, app } = useStudioEnvironmentParams();

return useMutation({
mutationFn: (modelPath: string) =>
addXsdFromRepo(org, app, StringUtils.removeStart(modelPath, '/')),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QueryKey.DataModelsJson, org, app] }).then();
queryClient.invalidateQueries({ queryKey: [QueryKey.DataModelsXsd, org, app] }).then();
queryClient.invalidateQueries({ queryKey: [QueryKey.JsonSchema, org, app] }).then();
},
});
};
16 changes: 0 additions & 16 deletions frontend/app-development/hooks/queries/useSchemaQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { app, org } from '@studio/testing/testids';

// Test data:
const jsonModelPathWithSlash = '/App/models/model.schema.json';
const xsdModelPath = 'App/models/model.xsd';
const xsdModelPathWithSlash = '/' + xsdModelPath;

describe('useSchemaQuery', () => {
afterEach(jest.clearAllMocks);
Expand All @@ -23,19 +21,5 @@ describe('useSchemaQuery', () => {
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(queriesMock.getDataModel).toHaveBeenCalledTimes(1);
expect(queriesMock.getDataModel).toHaveBeenCalledWith(org, app, jsonModelPathWithSlash);
expect(queriesMock.addXsdFromRepo).not.toHaveBeenCalled();
});

it('Calls addXsdFromRepo with correct arguments when XSD', async () => {
const {
renderHookResult: { result },
} = renderHookWithProviders(
{},
createQueryClientMock(),
)(() => useSchemaQuery(xsdModelPathWithSlash));
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(queriesMock.addXsdFromRepo).toHaveBeenCalledTimes(1);
expect(queriesMock.addXsdFromRepo).toHaveBeenCalledWith(org, app, xsdModelPath);
expect(queriesMock.getDataModel).not.toHaveBeenCalled();
});
});
9 changes: 2 additions & 7 deletions frontend/app-development/hooks/queries/useSchemaQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@ import { QueryKey } from 'app-shared/types/QueryKey';
import { useServicesContext } from 'app-shared/contexts/ServicesContext';
import type { AxiosError } from 'axios';
import type { JsonSchema } from 'app-shared/types/JsonSchema';
import { isXsdFile } from 'app-shared/utils/filenameUtils';
import { StringUtils } from '@studio/pure-functions';
import { useStudioEnvironmentParams } from 'app-shared/hooks/useStudioEnvironmentParams';
import type { ApiError } from 'app-shared/types/api/ApiError';

export const useSchemaQuery = (
modelPath: string,
): UseQueryResult<JsonSchema | null, AxiosError<ApiError, any>> => {
const { org, app } = useStudioEnvironmentParams();
const { getDataModel, addXsdFromRepo } = useServicesContext();
const { getDataModel } = useServicesContext();
return useQuery<JsonSchema | null, AxiosError<ApiError, any>>({
queryKey: [QueryKey.JsonSchema, org, app, modelPath],
queryFn: async (): Promise<JsonSchema> =>
isXsdFile(modelPath)
? addXsdFromRepo(org, app, StringUtils.removeStart(modelPath, '/'))
: getDataModel(org, app, modelPath),
queryFn: async (): Promise<JsonSchema> => getDataModel(org, app, modelPath),
structuralSharing: false,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export const useResetRepositoryMutation = (owner: string, app: string) => {
q.invalidateQueries({ queryKey: [QueryKey.FormLayouts, owner, app] }),
q.invalidateQueries({ queryKey: [QueryKey.FormLayoutSettings, owner, app] }),
q.invalidateQueries({ queryKey: [QueryKey.TextResources, owner, app] }),
q.invalidateQueries({ queryKey: [QueryKey.JsonSchema, owner, app] }),
q.invalidateQueries({ queryKey: [QueryKey.DataModelsJson, owner, app] }),
q.invalidateQueries({ queryKey: [QueryKey.DataModelsXsd, owner, app] }),
q.removeQueries({ queryKey: [QueryKey.JsonSchema, owner, app] }),
]),
});
};

0 comments on commit d2b2fba

Please sign in to comment.