Add param to Wiki REST endpoint to retrieve different page versions

In this MR we're introducing the param `version` to thet GET
page REST endpoint, to allow retrieving different versions of the
page.

Changelog: added
parent 52dd49ab
...@@ -181,7 +181,8 @@ module MarkupHelper ...@@ -181,7 +181,8 @@ module MarkupHelper
wiki: wiki, wiki: wiki,
repository: wiki.repository, repository: wiki.repository,
page_slug: wiki_page.slug, page_slug: wiki_page.slug,
issuable_reference_expansion_enabled: true issuable_reference_expansion_enabled: true,
requested_path: wiki_page.path
).merge(render_wiki_content_context_container(wiki)) ).merge(render_wiki_content_context_container(wiki))
end end
...@@ -263,7 +264,7 @@ module MarkupHelper ...@@ -263,7 +264,7 @@ module MarkupHelper
end end
def asciidoc_unsafe(text, context = {}) def asciidoc_unsafe(text, context = {})
context.merge!( context.reverse_merge!(
commit: @commit, commit: @commit,
ref: @ref, ref: @ref,
requested_path: @path requested_path: @path
......
...@@ -10,6 +10,7 @@ type: reference, api ...@@ -10,6 +10,7 @@ type: reference, api
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5.
> - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9. > - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9.
> - The `render_html` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9. > - The `render_html` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
> - The `version` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
The [group wikis](../user/project/wiki/group.md) API is available only in APIv4. The [group wikis](../user/project/wiki/group.md) API is available only in APIv4.
An API for [project wikis](wikis.md) is also available. An API for [project wikis](wikis.md) is also available.
...@@ -71,6 +72,7 @@ GET /groups/:id/wikis/:slug ...@@ -71,6 +72,7 @@ GET /groups/:id/wikis/:slug
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) | | `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
| `slug` | string | yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name` | | `slug` | string | yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name` |
| `render_html` | boolean | no | Return the rendered HTML of the wiki page | | `render_html` | boolean | no | Return the rendered HTML of the wiki page |
| `version` | string | no | Wiki page version sha |
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/home" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/home"
......
...@@ -8,6 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -8,6 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9. > - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9.
> - The `render_html` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9. > - The `render_html` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
> - The `version` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
The project [wikis](../user/project/wiki/index.md) API is available only in APIv4. The project [wikis](../user/project/wiki/index.md) API is available only in APIv4.
An API for [group wikis](group_wikis.md) is also available. An API for [group wikis](group_wikis.md) is also available.
...@@ -69,6 +70,7 @@ GET /projects/:id/wikis/:slug ...@@ -69,6 +70,7 @@ GET /projects/:id/wikis/:slug
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
| `slug` | string | yes | URLencoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name` | | `slug` | string | yes | URLencoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name` |
| `render_html` | boolean | no | Return the rendered HTML of the wiki page | | `render_html` | boolean | no | Return the rendered HTML of the wiki page |
| `version` | string | no | Wiki page version sha |
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/wikis/home" curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/wikis/home"
......
...@@ -179,8 +179,6 @@ RSpec.describe API::Wikis do ...@@ -179,8 +179,6 @@ RSpec.describe API::Wikis do
context 'when user is developer' do context 'when user is developer' do
before do before do
group.add_developer(user) group.add_developer(user)
get api(url, user), params: params
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -188,6 +186,10 @@ RSpec.describe API::Wikis do ...@@ -188,6 +186,10 @@ RSpec.describe API::Wikis do
context 'when page does not exist' do context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" } let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
get api(url, user), params: params
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -195,8 +197,6 @@ RSpec.describe API::Wikis do ...@@ -195,8 +197,6 @@ RSpec.describe API::Wikis do
context 'when user is maintainer' do context 'when user is maintainer' do
before do before do
group.add_maintainer(user) group.add_maintainer(user)
get api(url, user), params: params
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -204,6 +204,10 @@ RSpec.describe API::Wikis do ...@@ -204,6 +204,10 @@ RSpec.describe API::Wikis do
context 'when page does not exist' do context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" } let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
get api(url, user), params: params
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -221,8 +225,6 @@ RSpec.describe API::Wikis do ...@@ -221,8 +225,6 @@ RSpec.describe API::Wikis do
context 'when user is developer' do context 'when user is developer' do
before do before do
group.add_developer(user) group.add_developer(user)
get api(url, user), params: params
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -230,6 +232,10 @@ RSpec.describe API::Wikis do ...@@ -230,6 +232,10 @@ RSpec.describe API::Wikis do
context 'when page does not exist' do context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" } let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
get api(url, user), params: params
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -237,8 +243,6 @@ RSpec.describe API::Wikis do ...@@ -237,8 +243,6 @@ RSpec.describe API::Wikis do
context 'when user is maintainer' do context 'when user is maintainer' do
before do before do
group.add_maintainer(user) group.add_maintainer(user)
get api(url, user), params: params
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -246,6 +250,10 @@ RSpec.describe API::Wikis do ...@@ -246,6 +250,10 @@ RSpec.describe API::Wikis do
context 'when page does not exist' do context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" } let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
get api(url, user), params: params
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
......
...@@ -6,7 +6,7 @@ module API ...@@ -6,7 +6,7 @@ module API
include ::MarkupHelper include ::MarkupHelper
expose :content do |wiki_page, options| expose :content do |wiki_page, options|
options[:render_html] ? render_wiki_content(wiki_page) : wiki_page.content options[:render_html] ? render_wiki_content(wiki_page, ref: wiki_page.version.id) : wiki_page.content
end end
expose :encoding do |wiki_page| expose :encoding do |wiki_page|
......
...@@ -13,8 +13,8 @@ module API ...@@ -13,8 +13,8 @@ module API
raise "Unknown wiki container #{kind}" raise "Unknown wiki container #{kind}"
end end
def wiki_page def wiki_page(version = nil)
Wiki.for_container(container, current_user).find_page(params[:slug]) || not_found!('Wiki Page') Wiki.for_container(container, current_user).find_page(params[:slug], version.presence) || not_found!('Wiki Page')
end end
def commit_params(attrs) def commit_params(attrs)
......
...@@ -45,12 +45,13 @@ module API ...@@ -45,12 +45,13 @@ module API
end end
params do params do
requires :slug, type: String, desc: 'The slug of a wiki page' requires :slug, type: String, desc: 'The slug of a wiki page'
optional :version, type: String, desc: 'The version hash of a wiki page'
optional :render_html, type: Boolean, default: false, desc: 'Render content to HTML' optional :render_html, type: Boolean, default: false, desc: 'Render content to HTML'
end end
get ':id/wikis/:slug' do get ':id/wikis/:slug' do
authorize! :read_wiki, container authorize! :read_wiki, container
present wiki_page, with: Entities::WikiPage, render_html: params[:render_html] present wiki_page(params[:version]), with: Entities::WikiPage, render_html: params[:render_html]
end end
desc 'Create a wiki page' do desc 'Create a wiki page' do
......
...@@ -318,13 +318,14 @@ RSpec.describe MarkupHelper do ...@@ -318,13 +318,14 @@ RSpec.describe MarkupHelper do
let(:wiki) { build(:wiki, container: project) } let(:wiki) { build(:wiki, container: project) }
let(:content) { 'wiki content' } let(:content) { 'wiki content' }
let(:slug) { 'nested/page' } let(:slug) { 'nested/page' }
let(:wiki_page) { double('WikiPage', path: "file.#{extension}", content: content, slug: slug, wiki: wiki) } let(:path) { "file.#{extension}" }
let(:wiki_page) { double('WikiPage', path: path, content: content, slug: slug, wiki: wiki) }
let(:context) do let(:context) do
{ {
pipeline: :wiki, project: project, wiki: wiki, pipeline: :wiki, project: project, wiki: wiki,
page_slug: slug, issuable_reference_expansion_enabled: true, page_slug: slug, issuable_reference_expansion_enabled: true,
repository: wiki.repository repository: wiki.repository, requested_path: path
} }
end end
......
...@@ -29,6 +29,20 @@ RSpec.describe API::Entities::WikiPage do ...@@ -29,6 +29,20 @@ RSpec.describe API::Entities::WikiPage do
it 'returns the wiki page content rendered' do it 'returns the wiki page content rendered' do
expect(subject[:content]).to eq "<p data-sourcepos=\"1:1-1:#{wiki_page.content.size}\" dir=\"auto\">#{wiki_page.content}</p>" expect(subject[:content]).to eq "<p data-sourcepos=\"1:1-1:#{wiki_page.content.size}\" dir=\"auto\">#{wiki_page.content}</p>"
end end
it 'includes the wiki page version in the render context' do
expect(entity).to receive(:render_wiki_content).with(anything, hash_including(ref: wiki_page.version.id)).and_call_original
subject[:content]
end
context 'when page is an Ascii document' do
let(:wiki_page) { create(:wiki_page, content: "*Test* _content_", format: :asciidoc) }
it 'renders the page without errors' do
expect(subject[:content]).to eq("<div>&#x000A;<p><strong>Test</strong> <em>content</em></p>&#x000A;</div>")
end
end
end end
context 'when it is false' do context 'when it is false' do
......
...@@ -174,8 +174,6 @@ RSpec.describe API::Wikis do ...@@ -174,8 +174,6 @@ RSpec.describe API::Wikis do
context 'when user is developer' do context 'when user is developer' do
before do before do
project.add_developer(user) project.add_developer(user)
request
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -183,6 +181,10 @@ RSpec.describe API::Wikis do ...@@ -183,6 +181,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" } let(:url) { "/projects/#{project.id}/wikis/unknown" }
before do
request
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -190,8 +192,6 @@ RSpec.describe API::Wikis do ...@@ -190,8 +192,6 @@ RSpec.describe API::Wikis do
context 'when user is maintainer' do context 'when user is maintainer' do
before do before do
project.add_maintainer(user) project.add_maintainer(user)
request
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -199,6 +199,10 @@ RSpec.describe API::Wikis do ...@@ -199,6 +199,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" } let(:url) { "/projects/#{project.id}/wikis/unknown" }
before do
request
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -220,8 +224,6 @@ RSpec.describe API::Wikis do ...@@ -220,8 +224,6 @@ RSpec.describe API::Wikis do
context 'when user is developer' do context 'when user is developer' do
before do before do
project.add_developer(user) project.add_developer(user)
request
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -229,6 +231,10 @@ RSpec.describe API::Wikis do ...@@ -229,6 +231,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" } let(:url) { "/projects/#{project.id}/wikis/unknown" }
before do
request
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -236,8 +242,6 @@ RSpec.describe API::Wikis do ...@@ -236,8 +242,6 @@ RSpec.describe API::Wikis do
context 'when user is maintainer' do context 'when user is maintainer' do
before do before do
project.add_maintainer(user) project.add_maintainer(user)
request
end end
include_examples 'wikis API returns wiki page' include_examples 'wikis API returns wiki page'
...@@ -245,6 +249,10 @@ RSpec.describe API::Wikis do ...@@ -245,6 +249,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" } let(:url) { "/projects/#{project.id}/wikis/unknown" }
before do
request
end
include_examples 'wiki API 404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
......
...@@ -44,7 +44,13 @@ RSpec.shared_examples_for 'wikis API returns list of wiki pages' do ...@@ -44,7 +44,13 @@ RSpec.shared_examples_for 'wikis API returns list of wiki pages' do
end end
RSpec.shared_examples_for 'wikis API returns wiki page' do RSpec.shared_examples_for 'wikis API returns wiki page' do
subject(:request) { get api(url, user), params: params }
shared_examples 'returns wiki page' do shared_examples 'returns wiki page' do
before do
request
end
specify do specify do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(5) expect(json_response.size).to eq(5)
...@@ -71,6 +77,38 @@ RSpec.shared_examples_for 'wikis API returns wiki page' do ...@@ -71,6 +77,38 @@ RSpec.shared_examples_for 'wikis API returns wiki page' do
it_behaves_like 'returns wiki page' it_behaves_like 'returns wiki page'
end end
context 'when wiki page has versions' do
let(:new_content) { 'New content' }
before do
wiki.update_page(page.page, content: new_content, message: 'updated page')
expect(page.count_versions).to eq(2)
request
end
context 'when version param is not present' do
it 'retrieves the last version' do
expect(json_response['content']).to eq(new_content)
end
end
context 'when version param is set' do
let(:params) { { version: page.version.id } }
it 'retrieves the specific page version' do
expect(json_response['content']).to eq(page.content)
end
context 'when version param is not valid or inexistent' do
let(:params) { { version: 'foobar' } }
it_behaves_like 'wiki API 404 Wiki Page Not Found'
end
end
end
end end
RSpec.shared_examples_for 'wikis API creates wiki page' do RSpec.shared_examples_for 'wikis API creates wiki page' do
......
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