Commit 27a5ba94 authored by mfluharty's avatar mfluharty

Use pipeline.details.artifacts from cached_widget

We already load the artifacts asynchonously with the pipeline details
Just pass them down to the artifacts dropdown
No loading state needed, we have the pipeline widget's skeleton loader
parent 139a59e6
<script>
import {
GlAlert,
GlDropdown,
GlDropdownItem,
GlDropdownSectionHeader,
GlTooltipDirective,
} from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import { __, s__ } from '~/locale';
import { __ } from '~/locale';
export const i18n = {
artifacts: __('Artifacts'),
artifactSectionHeader: __('Download artifacts'),
artifactsFetchErrorMessage: s__('Pipelines|Could not load artifacts.'),
noArtifacts: s__('Pipelines|No artifacts available'),
};
export default {
......@@ -22,7 +18,6 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: {
GlAlert,
GlDropdown,
GlDropdownItem,
GlDropdownSectionHeader,
......@@ -40,41 +35,15 @@ export default {
type: Number,
required: true,
},
artifacts: {
type: Array,
required: false,
default: () => [],
},
data() {
return {
artifacts: [],
hasError: false,
isLoading: false,
};
},
computed: {
shouldShowDropdown() {
return this.isLoading || this.hasError || this.artifacts?.length;
},
},
mounted() {
this.fetchArtifacts();
},
methods: {
fetchArtifacts() {
this.isLoading = true;
// Replace the placeholder with the ID of the pipeline we are viewing
const endpoint = this.artifactsEndpoint.replace(
this.artifactsEndpointPlaceholder,
this.pipelineId,
);
return axios
.get(endpoint)
.then(({ data }) => {
this.artifacts = data.artifacts;
})
.catch(() => {
this.hasError = true;
})
.finally(() => {
this.isLoading = false;
});
return this.artifacts?.length;
},
},
};
......@@ -87,7 +56,6 @@ export default {
:title="$options.i18n.artifacts"
:text="$options.i18n.artifacts"
:aria-label="$options.i18n.artifacts"
:loading="isLoading"
icon="download"
right
lazy
......@@ -97,10 +65,6 @@ export default {
$options.i18n.artifactSectionHeader
}}</gl-dropdown-section-header>
<gl-alert v-if="hasError" variant="danger" :dismissible="false">
{{ $options.i18n.artifactsFetchErrorMessage }}
</gl-alert>
<gl-dropdown-item
v-for="(artifact, i) in artifacts"
:key="i"
......
......@@ -101,6 +101,9 @@ export default {
? this.pipeline.details.status
: {};
},
artifacts() {
return this.pipeline?.details?.artifacts;
},
hasStages() {
return this.pipeline?.details?.stages?.length > 0;
},
......@@ -285,7 +288,7 @@ export default {
/>
</span>
<linked-pipelines-mini-list v-if="triggered.length" :triggered="triggered" />
<pipeline-artifacts :pipeline-id="pipeline.id" class="gl-ml-3" />
<pipeline-artifacts :pipeline-id="pipeline.id" :artifacts="artifacts" class="gl-ml-3" />
</span>
</div>
</div>
......
......@@ -25411,9 +25411,6 @@ msgstr ""
msgid "Pipelines|More Information"
msgstr ""
msgid "Pipelines|No artifacts available"
msgstr ""
msgid "Pipelines|No triggers have been created yet. Add one using the form above."
msgstr ""
......
import { GlAlert, GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
import { GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import PipelineArtifacts, {
i18n,
} from '~/pipelines/components/pipelines_list/pipelines_artifacts.vue';
import PipelineArtifacts from '~/pipelines/components/pipelines_list/pipelines_artifacts.vue';
describe('Pipelines Artifacts dropdown', () => {
let wrapper;
let mockAxios;
const artifacts = [
{
......@@ -21,23 +15,13 @@ describe('Pipelines Artifacts dropdown', () => {
path: '/download/path-two',
},
];
const artifactsEndpointPlaceholder = ':pipeline_artifacts_id';
const artifactsEndpoint = `endpoint/${artifactsEndpointPlaceholder}/artifacts.json`;
const pipelineId = 108;
const createComponent = ({ mockData = {} } = {}) => {
const createComponent = ({ mockArtifacts = artifacts } = {}) => {
wrapper = shallowMount(PipelineArtifacts, {
provide: {
artifactsEndpoint,
artifactsEndpointPlaceholder,
},
propsData: {
pipelineId,
},
data() {
return {
...mockData,
};
artifacts: mockArtifacts,
},
stubs: {
GlSprintf,
......@@ -45,68 +29,31 @@ describe('Pipelines Artifacts dropdown', () => {
});
};
const findAlert = () => wrapper.findComponent(GlAlert);
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findFirstGlDropdownItem = () => wrapper.find(GlDropdownItem);
const findAllGlDropdownItems = () => wrapper.find(GlDropdown).findAll(GlDropdownItem);
beforeEach(() => {
mockAxios = new MockAdapter(axios);
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('when artifacts are loading', () => {
it('should render the dropdown with loading status', () => {
createComponent({ mockData: { isLoading: true } });
expect(findDropdown().exists()).toBe(true);
expect(findDropdown().attributes('loading')).toBe('true');
});
});
it('should fetch artifacts on mount', async () => {
const endpoint = artifactsEndpoint.replace(artifactsEndpointPlaceholder, pipelineId);
mockAxios.onGet(endpoint).replyOnce(200, { artifacts });
createComponent();
await waitForPromises();
expect(mockAxios.history.get).toHaveLength(1);
expect(wrapper.vm.artifacts).toEqual(artifacts);
});
it('should render a dropdown with all the provided artifacts', () => {
createComponent({ mockData: { artifacts } });
createComponent();
expect(findAllGlDropdownItems()).toHaveLength(artifacts.length);
});
it('should render a link with the provided path', () => {
createComponent({ mockData: { artifacts } });
createComponent();
expect(findFirstGlDropdownItem().attributes('href')).toBe(artifacts[0].path);
expect(findFirstGlDropdownItem().text()).toBe(artifacts[0].name);
});
describe('with a failing request', () => {
it('should render an error message', async () => {
const endpoint = artifactsEndpoint.replace(artifactsEndpointPlaceholder, pipelineId);
mockAxios.onGet(endpoint).replyOnce(500);
createComponent();
await waitForPromises();
const error = findAlert();
expect(error.exists()).toBe(true);
expect(error.text()).toBe(i18n.artifactsFetchErrorMessage);
});
});
describe('with no artifacts received', () => {
describe('with no artifacts', () => {
it('should not render the dropdown', () => {
createComponent({ mockData: { artifacts: [] } });
createComponent({ mockArtifacts: [] });
expect(findDropdown().exists()).toBe(false);
});
......
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