diff --git a/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue b/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue index 6cfde1bdd0169d5f6e22c99ac96829c213c6ccae..8811fcef4040d07fbdbeb3f452894eef3da0558f 100644 --- a/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue +++ b/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue @@ -19,6 +19,8 @@ export default { data() { return { readmeHtml: null, + version: '', + useLatestVersion: true, }; }, apollo: { @@ -27,10 +29,14 @@ export default { variables() { return { fullPath: this.resourcePath, + latest_version: this.useLatestVersion, + version: this.version, }; }, update(data) { - return data?.ciCatalogResource?.readmeHtml || null; + return this.useLatestVersion + ? data?.ciCatalogResource?.latestVersion?.readmeHtml + : data?.ciCatalogResource?.versions?.nodes[0]?.readmeHtml || null; }, error() { createAlert({ message: this.$options.i18n.loadingError }); diff --git a/app/assets/javascripts/ci/catalog/graphql/queries/get_ci_catalog_resource_readme.query.graphql b/app/assets/javascripts/ci/catalog/graphql/queries/get_ci_catalog_resource_readme.query.graphql index c1fde8dcb433dc477eb3ec47ccafa72dbc88c175..9938e3fdcbb0789580ffb2335a614a6092289462 100644 --- a/app/assets/javascripts/ci/catalog/graphql/queries/get_ci_catalog_resource_readme.query.graphql +++ b/app/assets/javascripts/ci/catalog/graphql/queries/get_ci_catalog_resource_readme.query.graphql @@ -1,7 +1,20 @@ -query getCiCatalogResourceReadme($fullPath: ID!) { +query getCiCatalogResourceReadme( + $fullPath: ID! + $latest_version: Boolean = true + $version: String +) { ciCatalogResource(fullPath: $fullPath) { id webPath - readmeHtml + versions(name: $version) @skip(if: $latest_version) { + nodes { + id + readmeHtml + } + } + latestVersion @include(if: $latest_version) { + id + readmeHtml + } } } diff --git a/spec/frontend/ci/catalog/components/details/ci_resource_readme_spec.js b/spec/frontend/ci/catalog/components/details/ci_resource_readme_spec.js index ad76b47db574e2a585b0e847bbbdd1a9925a542d..8a8a31cc30c4da0b622e2d24d4a84f1a31cb0170 100644 --- a/spec/frontend/ci/catalog/components/details/ci_resource_readme_spec.js +++ b/spec/frontend/ci/catalog/components/details/ci_resource_readme_spec.js @@ -12,7 +12,8 @@ jest.mock('~/alert'); Vue.use(VueApollo); -const readmeHtml = '<h1>This is a readme file</h1>'; +const versionedReadmeHtml = '<h1>This is version one readme</h1>'; +const latestReadmeHtml = '<h1>This is the lastest version readme</h1>'; const resourceId = 'gid://gitlab/Ci::Catalog::Resource/1'; describe('CiResourceReadme', () => { @@ -24,14 +25,26 @@ describe('CiResourceReadme', () => { ciCatalogResource: { id: resourceId, webPath: 'twitter/project-1', - readmeHtml, + versions: { + nodes: [ + { + id: 'gid://gitlab/Ci::Catalog::Resources::Version/1', + name: '1.0.1', + readmeHtml: versionedReadmeHtml, + }, + ], + }, + latestVersion: { + id: 'gid://gitlab/Ci::Catalog::Resources::Version/2', + readmeHtml: latestReadmeHtml, + }, }, }, }; const defaultProps = { resourcePath: readmeMockData.data.ciCatalogResource.webPath }; - const createComponent = ({ props = {} } = {}) => { + const createComponent = ({ props = {}, data = {} } = {}) => { const handlers = [[getCiCatalogResourceReadme, mockReadmeResponse]]; wrapper = shallowMountExtended(CiResourceReadme, { @@ -39,6 +52,12 @@ describe('CiResourceReadme', () => { ...defaultProps, ...props, }, + data() { + return { + useLatestVersion: true, + ...data, + }; + }, apolloProvider: createMockApollo(handlers), }); }; @@ -57,7 +76,7 @@ describe('CiResourceReadme', () => { it('renders only a loading icon', () => { expect(findLoadingIcon().exists()).toBe(true); - expect(wrapper.html()).not.toContain(readmeHtml); + expect(wrapper.html()).not.toContain(latestReadmeHtml); }); }); @@ -69,14 +88,23 @@ describe('CiResourceReadme', () => { await waitForPromises(); }); - it('renders only the received HTML', () => { + it('renders the latest version readme', () => { expect(findLoadingIcon().exists()).toBe(false); - expect(wrapper.html()).toContain(readmeHtml); + expect(wrapper.html()).toContain(latestReadmeHtml); }); it('does not render an error', () => { expect(createAlert).not.toHaveBeenCalled(); }); + + describe('versioned readme', () => { + it('renders a versioned readme', async () => { + createComponent({ data: { useLatestVersion: false, version: '1.0.1' } }); + await waitForPromises(); + + expect(wrapper.html()).toContain(versionedReadmeHtml); + }); + }); }); describe('when there is an error loading the readme', () => {