Commit 99d7917a authored by Illya Klymov's avatar Illya Klymov

Merge branch '208470_03-package-file-ui' into 'master'

Geo Package Files - Setup UI

See merge request gitlab-org/gitlab!33987
parents 6c349487 b7c836e5
......@@ -24,9 +24,9 @@ export default {
},
},
computed: {
...mapState(['isLoading', 'paginationData']),
...mapState(['isLoading', 'replicableItems', 'useGraphQl']),
hasReplicableItems() {
return this.paginationData.total > 0;
return this.replicableItems.length > 0;
},
},
created() {
......@@ -40,7 +40,8 @@ export default {
<template>
<article class="geo-replicable-container">
<geo-replicable-filter-bar class="mb-3" />
<!-- Filtering not currently supported via GraphQl -->
<geo-replicable-filter-bar v-if="!useGraphQl" class="mb-3" />
<gl-loading-icon v-if="isLoading" size="xl" />
<template v-else>
<geo-replicable v-if="hasReplicableItems" />
......
......@@ -10,7 +10,7 @@ export default {
GeoReplicableItem,
},
computed: {
...mapState(['replicableItems', 'paginationData']),
...mapState(['replicableItems', 'paginationData', 'useGraphQl']),
page: {
get() {
return this.paginationData.page;
......@@ -20,12 +20,15 @@ export default {
this.fetchReplicableItems();
},
},
hasReplicableItems() {
return this.paginationData.total > 0;
showRestfulPagination() {
return !this.useGraphQl && this.paginationData.total > 0;
},
},
methods: {
...mapActions(['setPage', 'fetchReplicableItems']),
buildName(item) {
return item.name ? item.name : item.id;
},
},
};
</script>
......@@ -35,15 +38,15 @@ export default {
<geo-replicable-item
v-for="item in replicableItems"
:key="item.id"
:name="item.name"
:name="buildName(item)"
:project-id="item.projectId"
:sync-status="item.state"
:sync-status="item.state.toLowerCase()"
:last-synced="item.lastSyncedAt"
:last-verified="item.lastVerifiedAt"
:last-checked="item.lastCheckedAt"
/>
<gl-pagination
v-if="hasReplicableItems"
v-if="showRestfulPagination"
v-model="page"
:per-page="paginationData.perPage"
:total-items="paginationData.total"
......
......@@ -21,7 +21,8 @@ export default {
},
projectId: {
type: Number,
required: true,
required: false,
default: null,
},
syncStatus: {
type: String,
......@@ -65,6 +66,11 @@ export default {
],
};
},
computed: {
hasProject() {
return Boolean(this.projectId);
},
},
methods: {
...mapActions(['initiateReplicableSync']),
},
......@@ -74,7 +80,7 @@ export default {
<template>
<div class="card">
<div class="card-header d-flex align-center">
<div v-if="hasProject" class="card-header d-flex align-center">
<gl-link class="font-weight-bold" :href="`/${name}`" target="_blank">{{ name }}</gl-link>
<div class="ml-auto">
<gl-button
......@@ -84,6 +90,9 @@ export default {
>
</div>
</div>
<div v-else class="card-header">
<span class="font-weight-bold">{{ name }}</span>
</div>
<div class="card-body">
<div class="d-flex flex-column flex-md-row">
<div class="flex-grow-1">
......
......@@ -52,82 +52,59 @@ describe('GeoReplicableApp', () => {
const findGeoReplicableFilterBar = () =>
findGeoReplicableContainer().find(GeoReplicableFilterBar);
describe('template', () => {
beforeEach(() => {
createComponent();
});
it('renders the replicable container', () => {
expect(findGeoReplicableContainer().exists()).toBe(true);
});
it('renders the filter bar', () => {
expect(findGeoReplicableFilterBar().exists()).toBe(true);
});
describe('when isLoading = true', () => {
beforeEach(() => {
wrapper.vm.$store.state.isLoading = true;
});
it('hides replicable items', () => {
expect(findGeoReplicable().exists()).toBe(false);
});
it('hides empty state', () => {
expect(findGeoReplicableEmptyState().exists()).toBe(false);
});
it('shows loader', () => {
expect(findGlLoadingIcon().exists()).toBe(true);
});
});
describe('when isLoading = false', () => {
describe.each`
isLoading | useGraphQl | replicableItems | showReplicableItems | showEmptyState | showFilterBar | showLoader
${false} | ${false} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${true} | ${false} | ${true} | ${false}
${false} | ${false} | ${[]} | ${false} | ${true} | ${true} | ${false}
${false} | ${true} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${true} | ${false} | ${false} | ${false}
${false} | ${true} | ${[]} | ${false} | ${true} | ${false} | ${false}
${true} | ${false} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${false} | ${false} | ${true} | ${true}
${true} | ${false} | ${[]} | ${false} | ${false} | ${true} | ${true}
${true} | ${true} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${false} | ${false} | ${false} | ${true}
${true} | ${true} | ${[]} | ${false} | ${false} | ${false} | ${true}
`(
`template`,
({
isLoading,
useGraphQl,
replicableItems,
showReplicableItems,
showEmptyState,
showFilterBar,
showLoader,
}) => {
beforeEach(() => {
wrapper.vm.$store.state.isLoading = false;
createComponent();
});
describe('with replicableItems', () => {
describe(`when isLoading is ${isLoading} and useGraphQl is ${useGraphQl}, ${
replicableItems.length ? 'with' : 'without'
} replicableItems`, () => {
beforeEach(() => {
wrapper.vm.$store.state.replicableItems = MOCK_BASIC_FETCH_DATA_MAP;
wrapper.vm.$store.state.paginationData.total =
wrapper.vm.$store.state.replicableItems.length;
});
it('shows replicable items', () => {
expect(findGeoReplicable().exists()).toBe(true);
});
it('hides empty state', () => {
expect(findGeoReplicableEmptyState().exists()).toBe(false);
wrapper.vm.$store.state.isLoading = isLoading;
wrapper.vm.$store.state.useGraphQl = useGraphQl;
wrapper.vm.$store.state.replicableItems = replicableItems;
wrapper.vm.$store.state.paginationData.total = replicableItems.length;
});
it('hides loader', () => {
expect(findGlLoadingIcon().exists()).toBe(false);
it(`${showReplicableItems ? 'shows' : 'hides'} the replicable items`, () => {
expect(findGeoReplicable().exists()).toBe(showReplicableItems);
});
});
describe('with no replicableItems', () => {
beforeEach(() => {
wrapper.vm.$store.state.replicableItems = [];
wrapper.vm.$store.state.paginationData.total = 0;
it(`${showEmptyState ? 'shows' : 'hides'} the empty state`, () => {
expect(findGeoReplicableEmptyState().exists()).toBe(showEmptyState);
});
it('hides replicable items', () => {
expect(findGeoReplicable().exists()).toBe(false);
it(`${showFilterBar ? 'shows' : 'hides'} the filter bar`, () => {
expect(findGeoReplicableFilterBar().exists()).toBe(showFilterBar);
});
it('shows empty state', () => {
expect(findGeoReplicableEmptyState().exists()).toBe(true);
});
it('hides loader', () => {
expect(findGlLoadingIcon().exists()).toBe(false);
it(`${showLoader ? 'shows' : 'hides'} the loader`, () => {
expect(findGlLoadingIcon().exists()).toBe(showLoader);
});
});
});
});
},
);
describe('onCreate', () => {
beforeEach(() => {
......
......@@ -17,7 +17,7 @@ describe('GeoReplicableItem', () => {
initiateReplicableSync: jest.fn(),
};
const propsData = {
const defaultProps = {
name: mockReplicable.name,
projectId: mockReplicable.projectId,
syncStatus: mockReplicable.state,
......@@ -26,11 +26,14 @@ describe('GeoReplicableItem', () => {
lastChecked: null,
};
const createComponent = () => {
const createComponent = (props = {}) => {
wrapper = mount(GeoReplicableItem, {
localVue,
store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData,
propsData: {
...defaultProps,
...props,
},
methods: {
...actionSpies,
},
......@@ -45,6 +48,7 @@ describe('GeoReplicableItem', () => {
const findGlLink = () => findCard().find(GlLink);
const findGlButton = () => findCard().find(GlButton);
const findCardHeader = () => findCard().find('.card-header');
const findTextTitle = () => findCardHeader().find('span');
const findCardBody = () => findCard().find('.card-body');
describe('template', () => {
......@@ -64,22 +68,44 @@ describe('GeoReplicableItem', () => {
expect(findCardBody().exists()).toBe(true);
});
it('GlLink renders', () => {
expect(findGlLink().exists()).toBe(true);
describe('with projectId', () => {
it('GlLink renders correctly', () => {
expect(findGlLink().exists()).toBe(true);
expect(findGlLink().text()).toBe(mockReplicable.name);
});
describe('ReSync Button', () => {
it('renders', () => {
expect(findGlButton().exists()).toBe(true);
});
it('calls initiateReplicableSync when clicked', () => {
findGlButton().trigger('click');
expect(actionSpies.initiateReplicableSync).toHaveBeenCalledWith({
projectId: mockReplicable.projectId,
name: mockReplicable.name,
action: ACTION_TYPES.RESYNC,
});
});
});
});
describe('ReSync Button', () => {
it('renders', () => {
expect(findGlButton().exists()).toBe(true);
describe('without projectId', () => {
beforeEach(() => {
createComponent({ projectId: null });
});
it('calls initiateReplicableSync when clicked', () => {
findGlButton().trigger('click');
expect(actionSpies.initiateReplicableSync).toHaveBeenCalledWith({
projectId: propsData.projectId,
name: propsData.name,
action: ACTION_TYPES.RESYNC,
});
it('Text title renders correctly', () => {
expect(findTextTitle().exists()).toBe(true);
expect(findTextTitle().text()).toBe(mockReplicable.name);
});
it('GlLink does not render', () => {
expect(findGlLink().exists()).toBe(false);
});
it('ReSync Button does not render', () => {
expect(findGlButton().exists()).toBe(false);
});
});
});
......
......@@ -44,27 +44,40 @@ describe('GeoReplicable', () => {
expect(findGeoReplicableContainer().exists()).toBe(true);
});
describe('GlPagination', () => {
describe('when perPage >= total', () => {
beforeEach(() => {
wrapper.vm.$store.state.paginationData.perPage = 2;
wrapper.vm.$store.state.paginationData.total = 1;
describe('when useGraphQl is false', () => {
describe('GlPagination', () => {
describe('when perPage >= total', () => {
beforeEach(() => {
wrapper.vm.$store.state.paginationData.perPage = 2;
wrapper.vm.$store.state.paginationData.total = 1;
});
it('is hidden', () => {
expect(findGlPagination().isEmpty()).toBe(true);
});
});
it('is hidden', () => {
expect(findGlPagination().isEmpty()).toBe(true);
describe('when perPage < total', () => {
beforeEach(() => {
wrapper.vm.$store.state.paginationData.perPage = 1;
wrapper.vm.$store.state.paginationData.total = 2;
});
it('renders', () => {
expect(findGlPagination().html()).not.toBeUndefined();
});
});
});
});
describe('when perPage < total', () => {
beforeEach(() => {
wrapper.vm.$store.state.paginationData.perPage = 1;
wrapper.vm.$store.state.paginationData.total = 2;
});
describe('when useGraphQl is true', () => {
beforeEach(() => {
createComponent();
wrapper.vm.$store.state.useGraphQl = true;
});
it('renders', () => {
expect(findGlPagination().html()).not.toBeUndefined();
});
it('does not render GlPagination', () => {
expect(findGlPagination().exists()).toBeFalsy();
});
});
......@@ -85,17 +98,19 @@ describe('GeoReplicable', () => {
});
describe('changing the page', () => {
beforeEach(() => {
createComponent();
wrapper.vm.page = 2;
});
describe('when useGraphQl is false', () => {
beforeEach(() => {
createComponent();
wrapper.vm.page = 2;
});
it('should call setPage', () => {
expect(actionSpies.setPage).toHaveBeenCalledWith(2);
});
it('should call setPage', () => {
expect(actionSpies.setPage).toHaveBeenCalledWith(2);
});
it('should call fetchReplicableItems', () => {
expect(actionSpies.fetchReplicableItems).toHaveBeenCalled();
it('should call fetchReplicableItems', () => {
expect(actionSpies.fetchReplicableItems).toHaveBeenCalled();
});
});
});
});
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