Commit 2d124bc4 authored by Peter Hegman's avatar Peter Hegman

Merge branch '345090-corpus-table-pagination' into 'master'

Corpus table pagination

See merge request gitlab-org/gitlab!75607
parents 82253cc6 41dffe1c
<script> <script>
import { GlLoadingIcon, GlLink } from '@gitlab/ui'; import { GlLoadingIcon, GlLink, GlKeysetPagination } from '@gitlab/ui';
import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue'; import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue';
import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue'; import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
...@@ -9,6 +9,7 @@ export default { ...@@ -9,6 +9,7 @@ export default {
components: { components: {
GlLoadingIcon, GlLoadingIcon,
GlLink, GlLink,
GlKeysetPagination,
CorpusTable, CorpusTable,
CorpusUpload, CorpusUpload,
}, },
...@@ -16,12 +17,14 @@ export default { ...@@ -16,12 +17,14 @@ export default {
states: { states: {
query: getCorpusesQuery, query: getCorpusesQuery,
variables() { variables() {
return { return this.queryVariables;
projectPath: this.projectFullPath,
};
}, },
update: (data) => { update: (data) => {
return data; const { pageInfo } = data.project.corpuses;
return {
...data,
pageInfo,
};
}, },
error() { error() {
this.states = null; this.states = null;
...@@ -29,20 +32,67 @@ export default { ...@@ -29,20 +32,67 @@ export default {
}, },
}, },
inject: ['projectFullPath', 'corpusHelpPath'], inject: ['projectFullPath', 'corpusHelpPath'],
data() {
return {
pagination: {
firstPageSize: this.$options.pageSize,
lastPageSize: null,
},
};
},
pageSize: 10,
i18n: { i18n: {
header: s__('CorpusManagement|Fuzz testing corpus management'), header: s__('CorpusManagement|Fuzz testing corpus management'),
subHeader: s__( subHeader: s__(
'CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing.', 'CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing.',
), ),
learnMore: __('Learn More'), learnMore: __('Learn More'),
previousPage: __('Prev'),
nextPage: __('Next'),
}, },
computed: { computed: {
corpuses() { corpuses() {
return this.states?.project.corpuses.nodes || []; return this.states?.project.corpuses.nodes || [];
}, },
pageInfo() {
return this.states?.pageInfo || {};
},
isLoading() { isLoading() {
return this.$apollo.loading; return this.$apollo.loading;
}, },
queryVariables() {
return {
projectPath: this.projectFullPath,
...this.pagination,
};
},
hasPagination() {
return Boolean(this.states) && (this.pageInfo.hasPreviousPage || this.pageInfo.hasNextPage);
},
},
methods: {
fetchCorpuses() {
this.pagination = {
afterCursor: null,
beforeCursor: null,
firstPageSize: this.$options.pageSize,
};
this.$apollo.queries.states.refetch();
},
nextPage() {
this.pagination = {
firstPageSize: this.$options.pageSize,
lastPageSize: null,
afterCursor: this.states.pageInfo.endCursor,
};
},
prevPage() {
this.pagination = {
firstPageSize: null,
lastPageSize: this.$options.pageSize,
beforeCursor: this.states.pageInfo.startCursor,
};
},
}, },
}; };
</script> </script>
...@@ -59,10 +109,21 @@ export default { ...@@ -59,10 +109,21 @@ export default {
</p> </p>
</header> </header>
<gl-loading-icon v-if="isLoading" size="lg" /> <corpus-upload @corpus-added="fetchCorpuses" />
<gl-loading-icon v-if="isLoading" size="lg" class="gl-py-13" />
<template v-else> <template v-else>
<corpus-upload />
<corpus-table :corpuses="corpuses" /> <corpus-table :corpuses="corpuses" />
</template> </template>
<div v-if="hasPagination" class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-keyset-pagination
v-bind="pageInfo"
:prev-text="$options.i18n.previousPage"
:next-text="$options.i18n.nextPage"
@prev="prevPage"
@next="nextPage"
/>
</div>
</div> </div>
</template> </template>
...@@ -52,6 +52,9 @@ export default { ...@@ -52,6 +52,9 @@ export default {
thClass, thClass,
}, },
], ],
i18n: {
emptyTable: s__('CorpusManagement|Currently, there are no uploaded or generated corpuses.'),
},
methods: { methods: {
onDelete({ name }) { onDelete({ name }) {
this.$apollo.mutate({ this.$apollo.mutate({
...@@ -73,7 +76,11 @@ export default { ...@@ -73,7 +76,11 @@ export default {
}; };
</script> </script>
<template> <template>
<gl-table :items="corpuses" :fields="$options.fields"> <gl-table :items="corpuses" :fields="$options.fields" show-empty>
<template #empty>
{{ $options.i18n.emptyTable }}
</template>
<template #cell(name)="{ item }"> <template #cell(name)="{ item }">
<name :corpus="item" /> <name :corpus="item" />
</template> </template>
......
...@@ -5,7 +5,7 @@ import { s__, __ } from '~/locale'; ...@@ -5,7 +5,7 @@ import { s__, __ } from '~/locale';
import addCorpusMutation from '../graphql/mutations/add_corpus.mutation.graphql'; import addCorpusMutation from '../graphql/mutations/add_corpus.mutation.graphql';
import resetCorpus from '../graphql/mutations/reset_corpus.mutation.graphql'; import resetCorpus from '../graphql/mutations/reset_corpus.mutation.graphql';
import uploadCorpus from '../graphql/mutations/upload_corpus.mutation.graphql'; import uploadCorpus from '../graphql/mutations/upload_corpus.mutation.graphql';
import getCorpusesQuery from '../graphql/queries/get_corpuses.query.graphql'; import getUploadState from '../graphql/queries/get_upload_state.query.graphql';
import CorpusUploadForm from './corpus_upload_form.vue'; import CorpusUploadForm from './corpus_upload_form.vue';
export default { export default {
...@@ -26,10 +26,7 @@ export default { ...@@ -26,10 +26,7 @@ export default {
inject: ['projectFullPath'], inject: ['projectFullPath'],
apollo: { apollo: {
states: { states: {
query: getCorpusesQuery, query: getUploadState,
variables() {
return this.queryVariables;
},
update(data) { update(data) {
return data; return data;
}, },
...@@ -76,20 +73,18 @@ export default { ...@@ -76,20 +73,18 @@ export default {
}, },
methods: { methods: {
addCorpus() { addCorpus() {
this.$apollo.mutate({ return this.$apollo
mutation: addCorpusMutation, .mutate({
refetchQueries: [ mutation: addCorpusMutation,
{ variables: {
query: getCorpusesQuery, name: this.$options.i18n.newCorpus,
variables: this.queryVariables, projectPath: this.projectFullPath,
packageId: this.states.uploadState.uploadedPackageId,
}, },
], })
variables: { .then(() => {
name: this.$options.i18n.newCorpus, this.$emit('corpus-added');
projectPath: this.projectFullPath, });
packageId: this.states.uploadState.uploadedPackageId,
},
});
}, },
resetCorpus() { resetCorpus() {
this.$apollo.mutate({ this.$apollo.mutate({
......
fragment UploadState on UploadState {
isUploading
progress
cancelSource
uploadedPackageId
}
query getCorpuses($projectPath: ID!) { #import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
#import "../fragments/uploadState.fragment.graphql"
query getCorpuses(
$projectPath: ID!
$beforeCursor: String = ""
$afterCursor: String = ""
$firstPageSize: Int
$lastPageSize: Int
) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
id id
corpuses { corpuses(
before: $beforeCursor
after: $afterCursor
first: $firstPageSize
last: $lastPageSize
) {
nodes { nodes {
id id
package { package {
...@@ -24,12 +38,12 @@ query getCorpuses($projectPath: ID!) { ...@@ -24,12 +38,12 @@ query getCorpuses($projectPath: ID!) {
} }
} }
} }
pageInfo {
...PageInfo
}
} }
} }
uploadState(projectPath: $projectPath) @client { uploadState @client {
isUploading ...UploadState
progress
cancelSource
uploadedPackageId
} }
} }
#import "../fragments/uploadState.fragment.graphql"
query getUploadState {
uploadState @client {
...UploadState
}
}
...@@ -3,15 +3,14 @@ import { publishPackage } from '~/api/packages_api'; ...@@ -3,15 +3,14 @@ import { publishPackage } from '~/api/packages_api';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { convertToGraphQLId } from '~/graphql_shared/utils'; import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPE_PACKAGES_PACKAGE } from '~/graphql_shared/constants'; import { TYPE_PACKAGES_PACKAGE } from '~/graphql_shared/constants';
import getCorpusesQuery from '../queries/get_corpuses.query.graphql'; import getUploadState from '../queries/get_upload_state.query.graphql';
import updateProgress from '../mutations/update_progress.mutation.graphql'; import updateProgress from '../mutations/update_progress.mutation.graphql';
import uploadComplete from '../mutations/upload_complete.mutation.graphql'; import uploadComplete from '../mutations/upload_complete.mutation.graphql';
import corpusCreate from '../mutations/corpus_create.mutation.graphql'; import corpusCreate from '../mutations/corpus_create.mutation.graphql';
export default { export default {
Query: { Query: {
/* eslint-disable no-unused-vars */ uploadState() {
uploadState(_, { projectPath }) {
return { return {
isUploading: false, isUploading: false,
progress: 0, progress: 0,
...@@ -24,7 +23,7 @@ export default { ...@@ -24,7 +23,7 @@ export default {
Mutation: { Mutation: {
addCorpus: (_, { projectPath, packageId }, { cache, client }) => { addCorpus: (_, { projectPath, packageId }, { cache, client }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -33,7 +32,7 @@ export default { ...@@ -33,7 +32,7 @@ export default {
draftState.uploadState.progress = 0; draftState.uploadState.progress = 0;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
client.mutate({ client.mutate({
mutation: corpusCreate, mutation: corpusCreate,
...@@ -60,7 +59,7 @@ export default { ...@@ -60,7 +59,7 @@ export default {
const source = CancelToken.source(); const source = CancelToken.source();
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -70,7 +69,7 @@ export default { ...@@ -70,7 +69,7 @@ export default {
uploadState.cancelSource = source; uploadState.cancelSource = source;
}); });
cache.writeQuery({ query: getCorpusesQuery, data: targetData, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data: targetData, variables: { projectPath } });
publishPackage( publishPackage(
{ projectPath, name, version: 0, fileName: `${name}.zip`, files }, { projectPath, name, version: 0, fileName: `${name}.zip`, files },
...@@ -83,13 +82,13 @@ export default { ...@@ -83,13 +82,13 @@ export default {
variables: { projectPath, packageId: data.package_id }, variables: { projectPath, packageId: data.package_id },
}); });
}) })
.catch((e) => { .catch(() => {
/* TODO: Error handling */ /* TODO: Error handling */
}); });
}, },
uploadComplete: (_, { projectPath, packageId }, { cache }) => { uploadComplete: (_, { projectPath, packageId }, { cache }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -100,11 +99,11 @@ export default { ...@@ -100,11 +99,11 @@ export default {
uploadState.uploadedPackageId = packageId; uploadState.uploadedPackageId = packageId;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
}, },
updateProgress: (_, { projectPath, progress }, { cache }) => { updateProgress: (_, { projectPath, progress }, { cache }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -114,11 +113,11 @@ export default { ...@@ -114,11 +113,11 @@ export default {
uploadState.progress = progress; uploadState.progress = progress;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
}, },
resetCorpus: (_, { projectPath }, { cache }) => { resetCorpus: (_, { projectPath }, { cache }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -131,7 +130,7 @@ export default { ...@@ -131,7 +130,7 @@ export default {
uploadState.cancelToken = null; uploadState.cancelToken = null;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
}, },
}, },
}; };
import { GlLoadingIcon } from '@gitlab/ui'; import { merge } from 'lodash';
import { GlLoadingIcon, GlKeysetPagination } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import CorpusManagement from 'ee/security_configuration/corpus_management/components/corpus_management.vue'; import CorpusManagement from 'ee/security_configuration/corpus_management/components/corpus_management.vue';
import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue'; import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue';
import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue'; import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue';
import { corpuses } from './mock_data'; import getCorpusesQuery from 'ee/security_configuration/corpus_management/graphql/queries/get_corpuses.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { getCorpusesQueryResponse } from './mock_data';
const TEST_PROJECT_FULL_PATH = '/namespace/project'; const TEST_PROJECT_FULL_PATH = '/namespace/project';
const TEST_CORPUS_HELP_PATH = '/docs/corpus-management'; const TEST_CORPUS_HELP_PATH = '/docs/corpus-management';
...@@ -11,19 +20,49 @@ const TEST_CORPUS_HELP_PATH = '/docs/corpus-management'; ...@@ -11,19 +20,49 @@ const TEST_CORPUS_HELP_PATH = '/docs/corpus-management';
describe('EE - CorpusManagement', () => { describe('EE - CorpusManagement', () => {
let wrapper; let wrapper;
const createComponentFactory = (mountFn = shallowMount) => (options = {}) => { const createMockApolloProvider = ({
const defaultMocks = { getCorpusesQueryRequestHandler = jest.fn().mockResolvedValue(getCorpusesQueryResponse),
$apollo: { } = {}) => {
loading: false, Vue.use(VueApollo);
const requestHandlers = [[getCorpusesQuery, getCorpusesQueryRequestHandler]];
const mockResolvers = {
Query: {
uploadState() {
return {
isUploading: false,
progress: 0,
cancelSource: null,
uploadedPackageId: null,
__typename: 'UploadState',
};
},
}, },
}; };
return createMockApollo(requestHandlers, mockResolvers);
};
const findPagination = () => wrapper.findComponent(GlKeysetPagination);
const nextPage = (cursor) => {
findPagination().vm.$emit('next', cursor);
return findPagination().vm.$nextTick();
};
const prevPage = (cursor) => {
findPagination().vm.$emit('prev', cursor);
return findPagination().vm.$nextTick();
};
const createComponentFactory = (mountFn = shallowMount) => (options = {}) => {
wrapper = mountFn(CorpusManagement, { wrapper = mountFn(CorpusManagement, {
mocks: defaultMocks,
provide: { provide: {
projectFullPath: TEST_PROJECT_FULL_PATH, projectFullPath: TEST_PROJECT_FULL_PATH,
corpusHelpPath: TEST_CORPUS_HELP_PATH, corpusHelpPath: TEST_CORPUS_HELP_PATH,
}, },
apolloProvider: createMockApolloProvider(),
...options, ...options,
}); });
}; };
...@@ -36,39 +75,119 @@ describe('EE - CorpusManagement', () => { ...@@ -36,39 +75,119 @@ describe('EE - CorpusManagement', () => {
describe('corpus management', () => { describe('corpus management', () => {
describe('when loaded', () => { describe('when loaded', () => {
beforeEach(() => { it('bootstraps and renders the component', async () => {
const data = () => { createComponent();
return { states: { project: { corpuses } } }; await waitForPromises();
};
createComponent({ data });
});
it('bootstraps and renders the component', () => {
expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true); expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true);
expect(wrapper.findComponent(CorpusTable).exists()).toBe(true); expect(wrapper.findComponent(CorpusTable).exists()).toBe(true);
expect(wrapper.findComponent(CorpusUpload).exists()).toBe(true); expect(wrapper.findComponent(CorpusUpload).exists()).toBe(true);
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false); expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
}); });
it('renders the correct header', () => { it('renders the correct header', async () => {
createComponent();
await waitForPromises();
const header = wrapper.findComponent(CorpusManagement).find('header'); const header = wrapper.findComponent(CorpusManagement).find('header');
expect(header.element).toMatchSnapshot(); expect(header.element).toMatchSnapshot();
}); });
describe('pagination', () => {
it('hides pagination when no previous or next pages are available', async () => {
createComponent({
apolloProvider: createMockApolloProvider({
getCorpusesQueryRequestHandler: jest.fn().mockResolvedValue(
merge({}, getCorpusesQueryResponse, {
data: {
project: {
corpuses: {
pageInfo: {
hasNextPage: false,
hasPreviousPage: false,
},
},
},
},
}),
),
}),
});
await waitForPromises();
expect(findPagination().exists()).toBe(false);
});
it('passes correct props to GlKeysetPagination', async () => {
createComponent();
await waitForPromises();
expect(findPagination().exists()).toBe(true);
expect(findPagination().props()).toMatchObject({
disabled: false,
endCursor: 'end-cursor',
hasNextPage: true,
hasPreviousPage: true,
nextButtonLink: null,
nextText: 'Next',
prevButtonLink: null,
prevText: 'Prev',
startCursor: 'start-cursor',
});
});
it('updates query variables when going to previous page', async () => {
const getCorpusesQueryRequestHandler = jest
.fn()
.mockResolvedValue(getCorpusesQueryResponse);
createComponent({
apolloProvider: createMockApolloProvider({ getCorpusesQueryRequestHandler }),
});
await waitForPromises();
await prevPage(getCorpusesQueryResponse.data.project.corpuses.pageInfo.startCursor);
expect(getCorpusesQueryRequestHandler).toHaveBeenCalledWith({
beforeCursor: getCorpusesQueryResponse.data.project.corpuses.pageInfo.startCursor,
afterCursor: '',
projectPath: TEST_PROJECT_FULL_PATH,
lastPageSize: 10,
firstPageSize: null,
});
});
it('updates query variables when going to next page', async () => {
const getCorpusesQueryRequestHandler = jest
.fn()
.mockResolvedValue(getCorpusesQueryResponse);
createComponent({
apolloProvider: createMockApolloProvider({ getCorpusesQueryRequestHandler }),
});
await waitForPromises();
await nextPage(getCorpusesQueryResponse.data.project.corpuses.pageInfo.endCursor);
expect(getCorpusesQueryRequestHandler).toHaveBeenLastCalledWith({
afterCursor: getCorpusesQueryResponse.data.project.corpuses.pageInfo.endCursor,
beforeCursor: '',
projectPath: TEST_PROJECT_FULL_PATH,
firstPageSize: 10,
lastPageSize: null,
});
});
});
}); });
describe('when loading', () => { describe('when loading', () => {
it('shows loading state when loading', () => { it('shows loading state when loading', () => {
const mocks = { createComponent();
$apollo: {
loading: jest.fn().mockResolvedValue(true),
},
};
createComponent({ mocks });
expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true); expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true);
expect(wrapper.findComponent(CorpusUpload).exists()).toBe(true);
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true); expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
expect(wrapper.findComponent(CorpusTable).exists()).toBe(false); expect(wrapper.findComponent(CorpusTable).exists()).toBe(false);
expect(wrapper.findComponent(CorpusUpload).exists()).toBe(false);
}); });
}); });
}); });
......
...@@ -60,5 +60,13 @@ describe('Corpus table', () => { ...@@ -60,5 +60,13 @@ describe('Corpus table', () => {
actionComponent.vm.$emit('delete', 'corpus-name'); actionComponent.vm.$emit('delete', 'corpus-name');
expect(mutate).toHaveBeenCalledTimes(1); expect(mutate).toHaveBeenCalledTimes(1);
}); });
describe('with no corpuses', () => {
it('renders the empty state', async () => {
wrapper.setProps({ corpuses: [] });
await wrapper.vm.$nextTick();
expect(wrapper.text()).toContain('Currently, there are no uploaded or generated corpuses');
});
});
}); });
}); });
const pipelines = { const pipelines = {
nodes: [ nodes: [
{ {
id: 'gid://gitlab/Packages::PackagePipelines/1',
ref: 'farias-gl/go-fuzzing-example', ref: 'farias-gl/go-fuzzing-example',
path: 'gitlab-examples/security/security-reports/-/jobs/1107103952', path: 'gitlab-examples/security/security-reports/-/jobs/1107103952',
updatedAt: new Date(2020, 4, 3).toString(), createdAt: new Date(2020, 4, 3).toString(),
}, },
], ],
}; };
...@@ -11,6 +12,7 @@ const pipelines = { ...@@ -11,6 +12,7 @@ const pipelines = {
const packageFiles = { const packageFiles = {
nodes: [ nodes: [
{ {
id: 'gid://gitlab/Packages::PackageFile/1',
downloadPath: '/download-path', downloadPath: '/download-path',
size: 4e8, size: 4e8,
}, },
...@@ -19,7 +21,9 @@ const packageFiles = { ...@@ -19,7 +21,9 @@ const packageFiles = {
export const corpuses = [ export const corpuses = [
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/1',
package: { package: {
id: 'gid://gitlab/Packages::Package/1',
name: 'Corpus-sample-1-13830-23932', name: 'Corpus-sample-1-13830-23932',
updatedAt: new Date(2021, 2, 12).toString(), updatedAt: new Date(2021, 2, 12).toString(),
pipelines, pipelines,
...@@ -27,7 +31,9 @@ export const corpuses = [ ...@@ -27,7 +31,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/2',
package: { package: {
id: 'gid://gitlab/Packages::Package/2',
name: 'Corpus-sample-2-5830-2393', name: 'Corpus-sample-2-5830-2393',
updatedAt: new Date(2021, 3, 12).toString(), updatedAt: new Date(2021, 3, 12).toString(),
pipelines, pipelines,
...@@ -35,7 +41,9 @@ export const corpuses = [ ...@@ -35,7 +41,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/3',
package: { package: {
id: 'gid://gitlab/Packages::Package/3',
name: 'Corpus-sample-3-1431-4425', name: 'Corpus-sample-3-1431-4425',
updatedAt: new Date(2021, 4, 12).toString(), updatedAt: new Date(2021, 4, 12).toString(),
pipelines: { pipelines: {
...@@ -49,6 +57,7 @@ export const corpuses = [ ...@@ -49,6 +57,7 @@ export const corpuses = [
packageFiles: { packageFiles: {
nodes: [ nodes: [
{ {
id: 'gid://gitlab/Packages::PackageFile/1',
downloadPath: '/download-path', downloadPath: '/download-path',
size: 3.21e8, size: 3.21e8,
}, },
...@@ -57,7 +66,9 @@ export const corpuses = [ ...@@ -57,7 +66,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/4',
package: { package: {
id: 'gid://gitlab/Packages::Package/3',
name: 'Corpus-sample-4-5830-1393', name: 'Corpus-sample-4-5830-1393',
updatedAt: new Date(2021, 5, 12).toString(), updatedAt: new Date(2021, 5, 12).toString(),
pipelines, pipelines,
...@@ -65,7 +76,9 @@ export const corpuses = [ ...@@ -65,7 +76,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/5',
package: { package: {
id: 'gid://gitlab/Packages::Package/4',
name: 'Corpus-sample-5-13830-23932', name: 'Corpus-sample-5-13830-23932',
updatedAt: new Date(2021, 6, 12).toString(), updatedAt: new Date(2021, 6, 12).toString(),
pipelines, pipelines,
...@@ -73,7 +86,9 @@ export const corpuses = [ ...@@ -73,7 +86,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/6',
package: { package: {
id: 'gid://gitlab/Packages::Package/5',
name: 'Corpus-sample-6-2450-2393', name: 'Corpus-sample-6-2450-2393',
updatedAt: new Date(2021, 7, 12).toString(), updatedAt: new Date(2021, 7, 12).toString(),
pipelines, pipelines,
...@@ -81,3 +96,20 @@ export const corpuses = [ ...@@ -81,3 +96,20 @@ export const corpuses = [
}, },
}, },
]; ];
export const getCorpusesQueryResponse = {
data: {
project: {
id: 'gid://gitlab/Project/8',
corpuses: {
nodes: corpuses,
pageInfo: {
hasNextPage: true,
hasPreviousPage: true,
startCursor: 'start-cursor',
endCursor: 'end-cursor',
},
},
},
},
};
...@@ -9763,6 +9763,9 @@ msgstr "" ...@@ -9763,6 +9763,9 @@ msgstr ""
msgid "CorpusManagement|Corpus name" msgid "CorpusManagement|Corpus name"
msgstr "" msgstr ""
msgid "CorpusManagement|Currently, there are no uploaded or generated corpuses."
msgstr ""
msgid "CorpusManagement|Fuzz testing corpus management" msgid "CorpusManagement|Fuzz testing corpus management"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment