Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-12-13 12:12:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-12-13 12:12:51 +0300
commitc283bdb7bc86aee27a7ed065fc9fb17e4c4ffee6 (patch)
treec5a33d4145f949ca6be24f09330c32c2a65e2d12 /spec/frontend
parente7b6c527c40962adc6623521ff190771e4ac50e4 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js37
-rw-r--r--spec/frontend/import_entities/import_projects/store/actions_spec.js39
-rw-r--r--spec/frontend/import_entities/import_projects/store/mutations_spec.js10
-rw-r--r--spec/frontend/kubernetes_dashboard/graphql/mock_data.js6
-rw-r--r--spec/frontend/kubernetes_dashboard/graphql/resolvers/kubernetes_spec.js96
-rw-r--r--spec/frontend/kubernetes_dashboard/pages/replica_sets_page_spec.js106
6 files changed, 273 insertions, 21 deletions
diff --git a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
index 92d064846bd..056155a560f 100644
--- a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
@@ -36,6 +36,7 @@ describe('ImportProjectsTable', () => {
.filter((w) => w.props().variant === 'confirm')
.at(0);
const findImportAllModal = () => wrapper.findComponent({ ref: 'importAllModal' });
+ const findIntersectionObserver = () => wrapper.findComponent(GlIntersectionObserver);
const importAllFn = jest.fn();
const importAllModalShowFn = jest.fn();
@@ -203,13 +204,13 @@ describe('ImportProjectsTable', () => {
describe('when paginatable is set to true', () => {
const initState = {
namespaces: [{ fullPath: 'path' }],
- pageInfo: { page: 1, hasNextPage: true },
+ pageInfo: { page: 1, hasNextPage: false },
repositories: [
{ importSource: { id: 1 }, importedProject: null, importStatus: STATUSES.NONE },
],
};
- describe('with hasNextPage true', () => {
+ describe('with hasNextPage false', () => {
beforeEach(() => {
createComponent({
state: initState,
@@ -217,26 +218,14 @@ describe('ImportProjectsTable', () => {
});
});
- it('does not call fetchRepos on mount', () => {
- expect(fetchReposFn).not.toHaveBeenCalled();
- });
-
- it('renders intersection observer component', () => {
- expect(wrapper.findComponent(GlIntersectionObserver).exists()).toBe(true);
- });
-
- it('calls fetchRepos when intersection observer appears', async () => {
- wrapper.findComponent(GlIntersectionObserver).vm.$emit('appear');
-
- await nextTick();
-
- expect(fetchReposFn).toHaveBeenCalled();
+ it('does not render intersection observer component', () => {
+ expect(findIntersectionObserver().exists()).toBe(false);
});
});
- describe('with hasNextPage false', () => {
+ describe('with hasNextPage true', () => {
beforeEach(() => {
- initState.pageInfo.hasNextPage = false;
+ initState.pageInfo.hasNextPage = true;
createComponent({
state: initState,
@@ -244,8 +233,16 @@ describe('ImportProjectsTable', () => {
});
});
- it('does not render intersection observer component', () => {
- expect(wrapper.findComponent(GlIntersectionObserver).exists()).toBe(false);
+ it('renders intersection observer component', () => {
+ expect(findIntersectionObserver().exists()).toBe(true);
+ });
+
+ it('calls fetchRepos again when intersection observer appears', async () => {
+ findIntersectionObserver().vm.$emit('appear');
+
+ await nextTick();
+
+ expect(fetchReposFn).toHaveBeenCalledTimes(2);
});
});
});
diff --git a/spec/frontend/import_entities/import_projects/store/actions_spec.js b/spec/frontend/import_entities/import_projects/store/actions_spec.js
index 3b94db37801..918821dfa59 100644
--- a/spec/frontend/import_entities/import_projects/store/actions_spec.js
+++ b/spec/frontend/import_entities/import_projects/store/actions_spec.js
@@ -17,6 +17,7 @@ import {
SET_PAGE,
SET_FILTER,
SET_PAGE_CURSORS,
+ SET_HAS_NEXT_PAGE,
} from '~/import_entities/import_projects/store/mutation_types';
import state from '~/import_entities/import_projects/store/state';
import axios from '~/lib/utils/axios_utils';
@@ -143,6 +144,44 @@ describe('import_projects store actions', () => {
);
});
});
+
+ describe('when provider is BITBUCKET_SERVER', () => {
+ beforeEach(() => {
+ localState.provider = PROVIDERS.BITBUCKET_SERVER;
+ });
+
+ describe.each`
+ reposLength | expectedHasNextPage
+ ${0} | ${false}
+ ${12} | ${false}
+ ${20} | ${false}
+ ${25} | ${true}
+ `('when reposLength is $reposLength', ({ reposLength, expectedHasNextPage }) => {
+ beforeEach(() => {
+ payload.provider_repos = Array(reposLength).fill({});
+
+ mock.onGet(MOCK_ENDPOINT).reply(HTTP_STATUS_OK, payload);
+ });
+
+ it('commits SET_HAS_NEXT_PAGE', () => {
+ return testAction(
+ fetchRepos,
+ null,
+ localState,
+ [
+ { type: REQUEST_REPOS },
+ { type: SET_PAGE, payload: 1 },
+ { type: SET_HAS_NEXT_PAGE, payload: expectedHasNextPage },
+ {
+ type: RECEIVE_REPOS_SUCCESS,
+ payload: convertObjectPropsToCamelCase(payload, { deep: true }),
+ },
+ ],
+ [],
+ );
+ });
+ });
+ });
});
it('commits REQUEST_REPOS, RECEIVE_REPOS_ERROR mutations on an unsuccessful request', () => {
diff --git a/spec/frontend/import_entities/import_projects/store/mutations_spec.js b/spec/frontend/import_entities/import_projects/store/mutations_spec.js
index 07d247630cc..90053f79bdf 100644
--- a/spec/frontend/import_entities/import_projects/store/mutations_spec.js
+++ b/spec/frontend/import_entities/import_projects/store/mutations_spec.js
@@ -332,6 +332,16 @@ describe('import_projects store mutations', () => {
});
});
+ describe(`${types.SET_HAS_NEXT_PAGE}`, () => {
+ it('sets hasNextPage in pageInfo', () => {
+ const NEW_HAS_NEXT_PAGE = true;
+ state = { pageInfo: { hasNextPage: false } };
+
+ mutations[types.SET_HAS_NEXT_PAGE](state, NEW_HAS_NEXT_PAGE);
+ expect(state.pageInfo.hasNextPage).toBe(NEW_HAS_NEXT_PAGE);
+ });
+ });
+
describe(`${types.CANCEL_IMPORT_SUCCESS}`, () => {
const payload = { repoId: 1 };
diff --git a/spec/frontend/kubernetes_dashboard/graphql/mock_data.js b/spec/frontend/kubernetes_dashboard/graphql/mock_data.js
index 030e801c06d..fe26bf5c600 100644
--- a/spec/frontend/kubernetes_dashboard/graphql/mock_data.js
+++ b/spec/frontend/kubernetes_dashboard/graphql/mock_data.js
@@ -289,3 +289,9 @@ export const mockStatefulSetsTableItems = [
kind: 'StatefulSet',
},
];
+
+export const k8sReplicaSetsMock = [readyStatefulSet, readyStatefulSet, failedStatefulSet];
+
+export const mockReplicaSetsTableItems = mockStatefulSetsTableItems.map((item) => {
+ return { ...item, kind: 'ReplicaSet' };
+});
diff --git a/spec/frontend/kubernetes_dashboard/graphql/resolvers/kubernetes_spec.js b/spec/frontend/kubernetes_dashboard/graphql/resolvers/kubernetes_spec.js
index 5841c73ea71..feee63546dd 100644
--- a/spec/frontend/kubernetes_dashboard/graphql/resolvers/kubernetes_spec.js
+++ b/spec/frontend/kubernetes_dashboard/graphql/resolvers/kubernetes_spec.js
@@ -3,7 +3,13 @@ import { resolvers } from '~/kubernetes_dashboard/graphql/resolvers';
import k8sDashboardPodsQuery from '~/kubernetes_dashboard/graphql/queries/k8s_dashboard_pods.query.graphql';
import k8sDashboardDeploymentsQuery from '~/kubernetes_dashboard/graphql/queries/k8s_dashboard_deployments.query.graphql';
import k8sDashboardStatefulSetsQuery from '~/kubernetes_dashboard/graphql/queries/k8s_dashboard_stateful_sets.query.graphql';
-import { k8sPodsMock, k8sDeploymentsMock, k8sStatefulSetsMock } from '../mock_data';
+import k8sDashboardReplicaSetsQuery from '~/kubernetes_dashboard/graphql/queries/k8s_dashboard_replica_sets.query.graphql';
+import {
+ k8sPodsMock,
+ k8sDeploymentsMock,
+ k8sStatefulSetsMock,
+ k8sReplicaSetsMock,
+} from '../mock_data';
describe('~/frontend/environments/graphql/resolvers', () => {
let mockResolvers;
@@ -276,4 +282,92 @@ describe('~/frontend/environments/graphql/resolvers', () => {
).rejects.toThrow('API error');
});
});
+
+ describe('k8sReplicaSets', () => {
+ const client = { writeQuery: jest.fn() };
+
+ const mockWatcher = WatchApi.prototype;
+ const mockReplicaSetsListWatcherFn = jest.fn().mockImplementation(() => {
+ return Promise.resolve(mockWatcher);
+ });
+
+ const mockOnDataFn = jest.fn().mockImplementation((eventName, callback) => {
+ if (eventName === 'data') {
+ callback([]);
+ }
+ });
+
+ const mockReplicaSetsListFn = jest.fn().mockImplementation(() => {
+ return Promise.resolve({
+ items: k8sReplicaSetsMock,
+ });
+ });
+
+ const mockAllReplicaSetsListFn = jest.fn().mockImplementation(mockReplicaSetsListFn);
+
+ describe('when the ReplicaSets data is present', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(AppsV1Api.prototype, 'listAppsV1ReplicaSetForAllNamespaces')
+ .mockImplementation(mockAllReplicaSetsListFn);
+ jest
+ .spyOn(mockWatcher, 'subscribeToStream')
+ .mockImplementation(mockReplicaSetsListWatcherFn);
+ jest.spyOn(mockWatcher, 'on').mockImplementation(mockOnDataFn);
+ });
+
+ it('should request all ReplicaSets from the cluster_client library and watch the events', async () => {
+ const ReplicaSets = await mockResolvers.Query.k8sReplicaSets(
+ null,
+ {
+ configuration,
+ },
+ { client },
+ );
+
+ expect(mockAllReplicaSetsListFn).toHaveBeenCalled();
+ expect(mockReplicaSetsListWatcherFn).toHaveBeenCalled();
+
+ expect(ReplicaSets).toEqual(k8sReplicaSetsMock);
+ });
+
+ it('should update cache with the new data when received from the library', async () => {
+ await mockResolvers.Query.k8sReplicaSets(
+ null,
+ { configuration, namespace: '' },
+ { client },
+ );
+
+ expect(client.writeQuery).toHaveBeenCalledWith({
+ query: k8sDashboardReplicaSetsQuery,
+ variables: { configuration, namespace: '' },
+ data: { k8sReplicaSets: [] },
+ });
+ });
+ });
+
+ it('should not watch ReplicaSets from the cluster_client library when the ReplicaSets data is not present', async () => {
+ jest.spyOn(AppsV1Api.prototype, 'listAppsV1ReplicaSetForAllNamespaces').mockImplementation(
+ jest.fn().mockImplementation(() => {
+ return Promise.resolve({
+ items: [],
+ });
+ }),
+ );
+
+ await mockResolvers.Query.k8sReplicaSets(null, { configuration }, { client });
+
+ expect(mockReplicaSetsListWatcherFn).not.toHaveBeenCalled();
+ });
+
+ it('should throw an error if the API call fails', async () => {
+ jest
+ .spyOn(AppsV1Api.prototype, 'listAppsV1ReplicaSetForAllNamespaces')
+ .mockRejectedValue(new Error('API error'));
+
+ await expect(
+ mockResolvers.Query.k8sReplicaSets(null, { configuration }, { client }),
+ ).rejects.toThrow('API error');
+ });
+ });
});
diff --git a/spec/frontend/kubernetes_dashboard/pages/replica_sets_page_spec.js b/spec/frontend/kubernetes_dashboard/pages/replica_sets_page_spec.js
new file mode 100644
index 00000000000..0e442ec8328
--- /dev/null
+++ b/spec/frontend/kubernetes_dashboard/pages/replica_sets_page_spec.js
@@ -0,0 +1,106 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { shallowMount } from '@vue/test-utils';
+import waitForPromises from 'helpers/wait_for_promises';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import ReplicaSetsPage from '~/kubernetes_dashboard/pages/replica_sets_page.vue';
+import WorkloadLayout from '~/kubernetes_dashboard/components/workload_layout.vue';
+import { useFakeDate } from 'helpers/fake_date';
+import {
+ k8sReplicaSetsMock,
+ mockStatefulSetsStats,
+ mockReplicaSetsTableItems,
+} from '../graphql/mock_data';
+
+Vue.use(VueApollo);
+
+describe('Kubernetes dashboard replicaSets page', () => {
+ let wrapper;
+
+ const configuration = {
+ basePath: 'kas/tunnel/url',
+ baseOptions: {
+ headers: { 'GitLab-Agent-Id': '1' },
+ },
+ };
+
+ const findWorkloadLayout = () => wrapper.findComponent(WorkloadLayout);
+
+ const createApolloProvider = () => {
+ const mockResolvers = {
+ Query: {
+ k8sReplicaSets: jest.fn().mockReturnValue(k8sReplicaSetsMock),
+ },
+ };
+
+ return createMockApollo([], mockResolvers);
+ };
+
+ const createWrapper = (apolloProvider = createApolloProvider()) => {
+ wrapper = shallowMount(ReplicaSetsPage, {
+ provide: { configuration },
+ apolloProvider,
+ });
+ };
+
+ describe('mounted', () => {
+ it('renders WorkloadLayout component', () => {
+ createWrapper();
+
+ expect(findWorkloadLayout().exists()).toBe(true);
+ });
+
+ it('sets loading prop for the WorkloadLayout', () => {
+ createWrapper();
+
+ expect(findWorkloadLayout().props('loading')).toBe(true);
+ });
+
+ it('removes loading prop from the WorkloadLayout when the list of pods loaded', async () => {
+ createWrapper();
+ await waitForPromises();
+
+ expect(findWorkloadLayout().props('loading')).toBe(false);
+ });
+ });
+
+ describe('when gets pods data', () => {
+ useFakeDate(2023, 10, 23, 10, 10);
+
+ it('sets correct stats object for the WorkloadLayout', async () => {
+ createWrapper();
+ await waitForPromises();
+
+ expect(findWorkloadLayout().props('stats')).toEqual(mockStatefulSetsStats);
+ });
+
+ it('sets correct table items object for the WorkloadLayout', async () => {
+ createWrapper();
+ await waitForPromises();
+
+ expect(findWorkloadLayout().props('items')).toMatchObject(mockReplicaSetsTableItems);
+ });
+ });
+
+ describe('when gets an error from the cluster_client API', () => {
+ const error = new Error('Error from the cluster_client API');
+ const createErroredApolloProvider = () => {
+ const mockResolvers = {
+ Query: {
+ k8sReplicaSets: jest.fn().mockRejectedValueOnce(error),
+ },
+ };
+
+ return createMockApollo([], mockResolvers);
+ };
+
+ beforeEach(async () => {
+ createWrapper(createErroredApolloProvider());
+ await waitForPromises();
+ });
+
+ it('sets errorMessage prop for the WorkloadLayout', () => {
+ expect(findWorkloadLayout().props('errorMessage')).toBe(error.message);
+ });
+ });
+});