Commit 470c68c9 authored by Ash McKenzie's avatar Ash McKenzie

Merge branch 'ajk-group-wiki-attachments' into 'master'

[Group Wiki] Update attachment API to support Group Level Wiki

Closes #212199

See merge request gitlab-org/gitlab!34232
parents ce38822c 2a742324
# Wikis API
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.2.
Available only in APIv4.
## List wiki pages
List all wiki pages for a given group.
```plaintext
GET /groups/:id/wikis
```
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `with_content` | boolean | no | Include pages' content |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis?with_content=1"
```
Example response:
```json
[
{
"content" : "Here is an instruction how to deploy this project.",
"format" : "markdown",
"slug" : "deploy",
"title" : "deploy"
},
{
"content" : "Our development process is described here.",
"format" : "markdown",
"slug" : "development",
"title" : "development"
},{
"content" : "* [Deploy](deploy)\n* [Development](development)",
"format" : "markdown",
"slug" : "home",
"title" : "home"
}
]
```
## Get a wiki page
Get a wiki page for a given group.
```plaintext
GET /groups/:id/wikis/:slug
```
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `slug` | string | yes | The slug (a unique string) of the wiki page |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/home"
```
Example response:
```json
{
"content" : "home page",
"format" : "markdown",
"slug" : "home",
"title" : "home"
}
```
## Create a new wiki page
Create a new wiki page for the given repository with the given title, slug, and content.
```plaintext
POST /projects/:id/wikis
```
| Attribute | Type | Required | Description |
| ------------- | ------- | -------- | ---------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `content` | string | yes | The content of the wiki page |
| `title` | string | yes | The title of the wiki page |
| `format` | string | no | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc` and `org` |
```shell
curl --data "format=rdoc&title=Hello&content=Hello world" \
--header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/groups/1/wikis"
```
Example response:
```json
{
"content" : "Hello world",
"format" : "markdown",
"slug" : "Hello",
"title" : "Hello"
}
```
## Edit an existing wiki page
Update an existing wiki page. At least one parameter is required to update the wiki page.
```plaintext
PUT /groups/:id/wikis/:slug
```
| Attribute | Type | Required | Description |
| --------------- | ------- | --------------------------------- | ------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `content` | string | yes if `title` is not provided | The content of the wiki page |
| `title` | string | yes if `content` is not provided | The title of the wiki page |
| `format` | string | no | The format of the wiki page. Available formats are: `markdown` (default), `rdoc`, `asciidoc` and `org` |
| `slug` | string | yes | The slug (a unique identifier) of the wiki page |
```shell
curl --request PUT --data "format=rdoc&content=documentation&title=Docs" \
--header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/groups/1/wikis/foo"
```
Example response:
```json
{
"content" : "documentation",
"format" : "markdown",
"slug" : "Docs",
"title" : "Docs"
}
```
## Delete a wiki page
Delete a wiki page with a given slug.
```plaintext
DELETE /groups/:id/wikis/:slug
```
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `slug` | string | yes | The slug (a unique identifier) of the wiki page |
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/foo"
```
On success the HTTP status code is `204` and no JSON response is expected.
## Upload an attachment to the wiki repository
Upload a file to the attachment folder inside the wiki's repository. The
attachment folder is the `uploads` folder.
```plaintext
POST /groups/:id/wikis/attachments
```
| Attribute | Type | Required | Description |
| ------------- | ------- | -------- | ---------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `file` | string | yes | The attachment to be uploaded |
| `branch` | string | no | The name of the branch. Defaults to the wiki repository default branch |
To upload a file from your filesystem, use the `--form` argument. This causes
cURL to post data using the header `Content-Type: multipart/form-data`.
The `file=` parameter must point to a file on your filesystem and be preceded
by `@`. For example:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" "https://gitlab.example.com/api/v4/groups/1/wikis/attachments"
```
Example response:
```json
{
"file_name" : "dk.png",
"file_path" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png",
"branch" : "master",
"link" : {
"url" : "uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png",
"markdown" : "![dk](uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png)"
}
}
```
---
title: Add group wiki REST API
merge_request: 34232
author:
type: added
# frozen_string_literal: true
module EE
module API
module Helpers
module WikisHelpers
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
class_methods do
def wiki_resource_kinds
[:groups, *super]
end
end
override :find_container
def find_container(kind)
return user_group if kind == :groups
super
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
# For every API endpoint we test 3 states of wikis:
# - disabled
# - enabled only for team members
# - enabled for everyone who has access
# Every state is tested for 3 user roles:
# - guest
# - developer
# - maintainer
# because they are 3 edge cases of using wiki pages.
describe API::Wikis do
include WorkhorseHelpers
let_it_be(:user) { create(:user) }
let(:group) { create(:group, :internal, :wiki_repo) }
let(:wiki) { create(:group_wiki, container: group, user: user) }
let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } }
let(:expected_keys_with_content) { %w(content format slug title) }
let(:expected_keys_without_content) { %w(format slug title) }
shared_examples_for 'wiki API 404 Group Not Found' do
include_examples 'wiki API 404 Not Found', 'Group'
end
describe 'GET /groups/:id/wikis' do
let(:url) { "/groups/#{group.id}/wikis" }
context 'when group wiki is disabled' do
before do
stub_feature_flags(group_wiki: false)
end
context 'when user is guest' do
before do
get api(url)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
get api(url, user)
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
get api(url, user)
end
include_examples 'wiki API 403 Forbidden'
end
end
# Skipped pending https://gitlab.com/gitlab-org/gitlab/-/issues/208412
xcontext 'when wiki is available only for team members' do
let(:group) { create(:group, :wiki_repo, :wiki_private) }
context 'when user is guest' do
before do
get api(url)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wikis API returns list of wiki pages'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wikis API returns list of wiki pages'
end
end
context 'when wiki is available for everyone with access' do
context 'when user is guest' do
before do
get api(url)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wikis API returns list of wiki pages'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wikis API returns list of wiki pages'
end
end
end
describe 'GET /groups/:id/wikis/:slug' do
let(:page) { create(:wiki_page, wiki: wiki) }
let(:url) { "/groups/#{group.id}/wikis/#{page.slug}" }
context 'when wiki is disabled' do
before do
stub_feature_flags(group_wiki: false)
end
context 'when user is guest' do
before do
get api(url)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
get api(url, user)
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
get api(url, user)
end
include_examples 'wiki API 403 Forbidden'
end
end
# Skipped pending https://gitlab.com/gitlab-org/gitlab/-/issues/208412
xcontext 'when wiki is available only for team members' do
let(:group) { create(:group, :wiki_repo, :wiki_private) }
context 'when user is guest' do
before do
get api(url)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
get api(url, user)
end
include_examples 'wikis API returns wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
get api(url, user)
end
include_examples 'wikis API returns wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
context 'when wiki is available for everyone with access' do
context 'when user is guest' do
before do
get api(url)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
get api(url, user)
end
include_examples 'wikis API returns wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
get api(url, user)
end
include_examples 'wikis API returns wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
end
describe 'POST /groups/:id/wikis' do
let(:payload) { { title: 'title', content: 'content' } }
let(:url) { "/groups/#{group.id}/wikis" }
context 'when wiki is disabled' do
before do
stub_feature_flags(group_wiki: false)
end
context 'when user is guest' do
before do
post(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
post(api(url, user), params: payload)
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
post(api(url, user), params: payload)
end
include_examples 'wiki API 403 Forbidden'
end
end
xcontext 'when wiki is available only for team members' do
let(:group) { create(:group, :wiki_private, :wiki_repo) }
context 'when user is guest' do
before do
post(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wikis API creates wiki page'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wikis API creates wiki page'
end
end
context 'when wiki is available for everyone with access' do
context 'when user is guest' do
before do
post(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wikis API creates wiki page'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wikis API creates wiki page'
end
end
end
describe 'PUT /group/:id/wikis/:slug' do
let(:page) { create(:wiki_page, wiki: wiki) }
let(:payload) { { title: 'new title', content: 'new content' } }
let(:url) { "/groups/#{group.id}/wikis/#{page.slug}" }
context 'when wiki is disabled' do
before do
stub_feature_flags(group_wiki: false)
end
context 'when user is guest' do
before do
put(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
put(api(url, user), params: payload)
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
put(api(url, user), params: payload)
end
include_examples 'wiki API 403 Forbidden'
end
end
xcontext 'when wiki is available only for team members' do
let(:group) { create(:group, :wiki_private, :wiki_repo) }
context 'when user is guest' do
before do
put(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wikis API updates wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
put(api(url, user), params: payload)
end
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wikis API updates wiki page'
context 'when page is not existing' do
let(:url) { "/group/#{group.id}/wikis/unknown" }
before do
put(api(url, user), params: payload)
end
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
context 'when wiki is available for everyone with access' do
context 'when user is guest' do
before do
put(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wikis API updates wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
put(api(url, user), params: payload)
end
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wikis API updates wiki page'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
before do
put(api(url, user), params: payload)
end
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
context 'when user is owner of parent group' do
let(:namespace) { create(:group).tap { |g| g.add_owner(user) } }
let(:group) { create(:group, :wiki_repo, parent: namespace) }
include_examples 'wikis API updates wiki page'
end
end
describe 'DELETE /groups/:id/wikis/:slug' do
let(:page) { create(:wiki_page, wiki: wiki) }
let(:url) { "/groups/#{group.id}/wikis/#{page.slug}" }
context 'when wiki is disabled' do
before do
stub_feature_flags(group_wiki: false)
end
context 'when user is guest' do
before do
delete(api(url))
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
delete(api(url, user))
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
delete(api(url, user))
end
include_examples 'wiki API 403 Forbidden'
end
end
# Skipped pending https://gitlab.com/gitlab-org/gitlab/-/issues/208412
xcontext 'when wiki is available only for team members' do
let(:group) { create(:group, :wiki_repo, :wiki_private) }
context 'when user is guest' do
before do
delete(api(url))
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
delete(api(url, user))
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
delete(api(url, user))
end
include_examples 'wiki API 204 No Content'
end
end
context 'when wiki is available for everyone with access' do
context 'when user is guest' do
before do
delete(api(url))
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
delete(api(url, user))
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
delete(api(url, user))
end
include_examples 'wiki API 204 No Content'
context 'when page does not exist' do
let(:url) { "/groups/#{group.id}/wikis/unknown" }
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
context 'when user is owner of parent group' do
let(:namespace) { create(:group).tap { |g| g.add_owner(user) } }
let(:group) { create(:group, :wiki_repo, parent: namespace) }
before do
delete(api(url, user))
end
include_examples 'wiki API 204 No Content'
end
end
describe 'POST /groups/:id/wikis/attachments' do
let(:payload) { { file: fixture_file_upload('spec/fixtures/dk.png') } }
let(:url) { "/groups/#{group.id}/wikis/attachments" }
let(:file_path) { "#{Wikis::CreateAttachmentService::ATTACHMENT_PATH}/fixed_hex/dk.png" }
let(:result_hash) do
{
file_name: 'dk.png',
file_path: file_path,
branch: 'master',
link: {
url: file_path,
markdown: "![dk](#{file_path})"
}
}
end
context 'when wiki is disabled' do
before do
stub_feature_flags(group_wiki: false)
end
context 'when user is guest' do
before do
post(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
post(api(url, user), params: payload)
end
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
post(api(url, user), params: payload)
end
include_examples 'wiki API 403 Forbidden'
end
end
# Skipped pending https://gitlab.com/gitlab-org/gitlab/-/issues/208412
xcontext 'when wiki is available only for team members' do
let(:group) { create(:group, :wiki_private, :wiki_repo) }
context 'when user is guest' do
before do
post(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wiki API uploads wiki attachment'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wiki API uploads wiki attachment'
end
end
context 'when wiki is available for everyone with access' do
context 'when user is guest' do
before do
post(api(url), params: payload)
end
include_examples 'wiki API 404 Group Not Found'
end
context 'when user is developer' do
before do
group.add_developer(user)
end
include_examples 'wiki API uploads wiki attachment'
end
context 'when user is maintainer' do
before do
group.add_maintainer(user)
end
include_examples 'wiki API uploads wiki attachment'
end
end
end
end
...@@ -79,12 +79,6 @@ module API ...@@ -79,12 +79,6 @@ module API
@project ||= find_project!(params[:id]) @project ||= find_project!(params[:id])
end end
def wiki_page
page = ProjectWiki.new(user_project, current_user).find_page(params[:slug])
page || not_found!('Wiki Page')
end
def available_labels_for(label_parent, include_ancestor_groups: true) def available_labels_for(label_parent, include_ancestor_groups: true)
search_params = { include_ancestor_groups: include_ancestor_groups } search_params = { include_ancestor_groups: include_ancestor_groups }
......
# frozen_string_literal: true
module API
module Helpers
module WikisHelpers
def self.wiki_resource_kinds
[:projects]
end
def find_container(kind)
return user_project if kind == :projects
raise "Unknown wiki container #{kind}"
end
def wiki_page
Wiki.for_container(container, current_user).find_page(params[:slug]) || not_found!('Wiki Page')
end
def commit_params(attrs)
base_params = { branch_name: attrs[:branch] }
file_details = case attrs[:file]
when Hash # legacy format: TODO remove when we drop support for non accelerated uploads
{ file_name: attrs[:file][:filename], file_content: attrs[:file][:tempfile].read }
else
{ file_name: attrs[:file].original_filename, file_content: attrs[:file].read }
end
base_params.merge(file_details)
end
end
end
end
API::Helpers::WikisHelpers.prepend_if_ee('EE::API::Helpers::WikisHelpers')
...@@ -2,24 +2,10 @@ ...@@ -2,24 +2,10 @@
module API module API
class Wikis < Grape::API class Wikis < Grape::API
helpers ::API::Helpers::WikisHelpers
helpers do helpers do
def commit_params(attrs) attr_reader :container
# In order to avoid service disruption this can work with an old workhorse without the acceleration
# the first branch of this if must be removed when we drop support for non accelerated uploads
if attrs[:file].is_a?(Hash)
{
file_name: attrs[:file][:filename],
file_content: attrs[:file][:tempfile].read,
branch_name: attrs[:branch]
}
else
{
file_name: attrs[:file].original_filename,
file_content: attrs[:file].read,
branch_name: attrs[:branch]
}
end
end
params :common_wiki_page_params do params :common_wiki_page_params do
optional :format, optional :format,
...@@ -32,108 +18,118 @@ module API ...@@ -32,108 +18,118 @@ module API
WIKI_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(slug: API::NO_SLASH_URL_PART_REGEX) WIKI_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(slug: API::NO_SLASH_URL_PART_REGEX)
resource :projects, requirements: WIKI_ENDPOINT_REQUIREMENTS do ::API::Helpers::WikisHelpers.wiki_resource_kinds.each do |container_resource|
desc 'Get a list of wiki pages' do resource container_resource, requirements: WIKI_ENDPOINT_REQUIREMENTS do
success Entities::WikiPageBasic after_validation do
end @container = Gitlab::Lazy.new { find_container(container_resource) }
params do end
optional :with_content, type: Boolean, default: false, desc: "Include pages' content"
end
get ':id/wikis' do
authorize! :read_wiki, user_project
entity = params[:with_content] ? Entities::WikiPage : Entities::WikiPageBasic
present user_project.wiki.list_pages(load_content: params[:with_content]), with: entity desc 'Get a list of wiki pages' do
end success Entities::WikiPageBasic
end
params do
optional :with_content, type: Boolean, default: false, desc: "Include pages' content"
end
get ':id/wikis' do
authorize! :read_wiki, container
desc 'Get a wiki page' do entity = params[:with_content] ? Entities::WikiPage : Entities::WikiPageBasic
success Entities::WikiPage
end
params do
requires :slug, type: String, desc: 'The slug of a wiki page'
end
get ':id/wikis/:slug' do
authorize! :read_wiki, user_project
present wiki_page, with: Entities::WikiPage present container.wiki.list_pages(load_content: params[:with_content]), with: entity
end end
desc 'Create a wiki page' do desc 'Get a wiki page' do
success Entities::WikiPage success Entities::WikiPage
end end
params do params do
requires :title, type: String, desc: 'Title of a wiki page' requires :slug, type: String, desc: 'The slug of a wiki page'
requires :content, type: String, desc: 'Content of a wiki page' end
use :common_wiki_page_params get ':id/wikis/:slug' do
end authorize! :read_wiki, container
post ':id/wikis' do
authorize! :create_wiki, user_project
page = WikiPages::CreateService.new(container: user_project, current_user: current_user, params: params).execute present wiki_page, with: Entities::WikiPage
end
if page.valid? desc 'Create a wiki page' do
present page, with: Entities::WikiPage success Entities::WikiPage
else
render_validation_error!(page)
end end
end params do
requires :title, type: String, desc: 'Title of a wiki page'
requires :content, type: String, desc: 'Content of a wiki page'
use :common_wiki_page_params
end
post ':id/wikis' do
authorize! :create_wiki, container
desc 'Update a wiki page' do page = WikiPages::CreateService.new(container: container, current_user: current_user, params: params).execute
success Entities::WikiPage
end
params do
optional :title, type: String, desc: 'Title of a wiki page'
optional :content, type: String, desc: 'Content of a wiki page'
use :common_wiki_page_params
at_least_one_of :content, :title, :format
end
put ':id/wikis/:slug' do
authorize! :create_wiki, user_project
page = WikiPages::UpdateService.new(container: user_project, current_user: current_user, params: params).execute(wiki_page) if page.valid?
present page, with: Entities::WikiPage
else
render_validation_error!(page)
end
end
if page.valid? desc 'Update a wiki page' do
present page, with: Entities::WikiPage success Entities::WikiPage
else end
render_validation_error!(page) params do
optional :title, type: String, desc: 'Title of a wiki page'
optional :content, type: String, desc: 'Content of a wiki page'
use :common_wiki_page_params
at_least_one_of :content, :title, :format
end
put ':id/wikis/:slug' do
authorize! :create_wiki, container
page = WikiPages::UpdateService
.new(container: container, current_user: current_user, params: params)
.execute(wiki_page)
if page.valid?
present page, with: Entities::WikiPage
else
render_validation_error!(page)
end
end end
end
desc 'Delete a wiki page' desc 'Delete a wiki page'
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'
end end
delete ':id/wikis/:slug' do delete ':id/wikis/:slug' do
authorize! :admin_wiki, user_project authorize! :admin_wiki, container
WikiPages::DestroyService.new(container: user_project, current_user: current_user).execute(wiki_page) WikiPages::DestroyService
.new(container: container, current_user: current_user)
.execute(wiki_page)
no_content! no_content!
end end
desc 'Upload an attachment to the wiki repository' do desc 'Upload an attachment to the wiki repository' do
detail 'This feature was introduced in GitLab 11.3.' detail 'This feature was introduced in GitLab 11.3.'
success Entities::WikiAttachment success Entities::WikiAttachment
end end
params do params do
requires :file, types: [::API::Validations::Types::SafeFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded' requires :file, types: [::API::Validations::Types::SafeFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded'
optional :branch, type: String, desc: 'The name of the branch' optional :branch, type: String, desc: 'The name of the branch'
end end
post ":id/wikis/attachments" do post ":id/wikis/attachments" do
authorize! :create_wiki, user_project authorize! :create_wiki, container
result = ::Wikis::CreateAttachmentService.new( result = ::Wikis::CreateAttachmentService.new(
container: user_project, container: container,
current_user: current_user, current_user: current_user,
params: commit_params(declared_params(include_missing: false)) params: commit_params(declared_params(include_missing: false))
).execute ).execute
if result[:status] == :success if result[:status] == :success
status(201) status(201)
present OpenStruct.new(result[:result]), with: Entities::WikiAttachment present OpenStruct.new(result[:result]), with: Entities::WikiAttachment
else else
render_api_error!(result[:message], 400) render_api_error!(result[:message], 400)
end
end end
end end
end end
......
...@@ -21,178 +21,10 @@ RSpec.describe API::Wikis do ...@@ -21,178 +21,10 @@ RSpec.describe API::Wikis do
let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } } let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } }
let(:expected_keys_with_content) { %w(content format slug title) } let(:expected_keys_with_content) { %w(content format slug title) }
let(:expected_keys_without_content) { %w(format slug title) } let(:expected_keys_without_content) { %w(format slug title) }
let(:wiki) { project_wiki }
shared_examples_for 'returns list of wiki pages' do shared_examples_for 'wiki API 404 Project Not Found' do
context 'when wiki has pages' do include_examples 'wiki API 404 Not Found', 'Project'
let!(:pages) do
[create(:wiki_page, wiki: project_wiki, title: 'page1', content: 'content of page1'),
create(:wiki_page, wiki: project_wiki, title: 'page2.with.dot', content: 'content of page2')]
end
it 'returns the list of wiki pages without content' do
get api(url, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
json_response.each_with_index do |page, index|
expect(page.keys).to match_array(expected_keys_without_content)
expect(page['slug']).to eq(pages[index].slug)
expect(page['title']).to eq(pages[index].title)
end
end
it 'returns the list of wiki pages with content' do
get api(url, user), params: { with_content: 1 }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
json_response.each_with_index do |page, index|
expect(page.keys).to match_array(expected_keys_with_content)
expect(page['content']).to eq(pages[index].content)
expect(page['slug']).to eq(pages[index].slug)
expect(page['title']).to eq(pages[index].title)
end
end
end
it 'return the empty list of wiki pages' do
get api(url, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(0)
end
end
shared_examples_for 'returns wiki page' do
it 'returns the wiki page' do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(page.content)
expect(json_response['slug']).to eq(page.slug)
expect(json_response['title']).to eq(page.title)
end
end
shared_examples_for 'creates wiki page' do
it 'creates the wiki page' do
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
expect(json_response['title']).to eq(payload[:title])
expect(json_response['rdoc']).to eq(payload[:rdoc])
end
[:title, :content].each do |part|
it "responds with validation error on empty #{part}" do
payload.delete(part)
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq("#{part} is missing")
end
end
end
shared_examples_for 'updates wiki page' do
it 'updates the wiki page' do
put(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
expect(json_response['title']).to eq(payload[:title])
end
[:title, :content, :format].each do |part|
it "updates with wiki with missing #{part}" do
payload.delete(part)
put(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
shared_examples_for '403 Forbidden' do
it 'returns 403 Forbidden' do
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('403 Forbidden')
end
end
shared_examples_for '404 Wiki Page Not Found' do
it 'returns 404 Wiki Page Not Found' do
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('404 Wiki Page Not Found')
end
end
shared_examples_for '404 Project Not Found' do
it 'returns 404 Project Not Found' do
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('404 Project Not Found')
end
end
shared_examples_for '204 No Content' do
it 'returns 204 No Content' do
expect(response).to have_gitlab_http_status(:no_content)
end
end
shared_examples_for 'uploads wiki attachment' do
it 'pushes attachment to the wiki repository' do
allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
workhorse_post_with_file(api(url, user), file_key: :file, params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to eq result_hash.deep_stringify_keys
end
it 'responds with validation error on empty file' do
payload.delete(:file)
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq('file is missing')
end
it 'responds with validation error on invalid temp file' do
payload[:file] = { tempfile: '/etc/hosts' }
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq('file is invalid')
end
it 'is backward compatible with regular multipart uploads' do
allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to eq result_hash.deep_stringify_keys
end
end end
describe 'GET /projects/:id/wikis' do describe 'GET /projects/:id/wikis' do
...@@ -206,7 +38,7 @@ RSpec.describe API::Wikis do ...@@ -206,7 +38,7 @@ RSpec.describe API::Wikis do
get api(url) get api(url)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -216,7 +48,7 @@ RSpec.describe API::Wikis do ...@@ -216,7 +48,7 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -226,7 +58,7 @@ RSpec.describe API::Wikis do ...@@ -226,7 +58,7 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
end end
...@@ -238,7 +70,7 @@ RSpec.describe API::Wikis do ...@@ -238,7 +70,7 @@ RSpec.describe API::Wikis do
get api(url) get api(url)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -246,7 +78,7 @@ RSpec.describe API::Wikis do ...@@ -246,7 +78,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'returns list of wiki pages' include_examples 'wikis API returns list of wiki pages'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -254,7 +86,7 @@ RSpec.describe API::Wikis do ...@@ -254,7 +86,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'returns list of wiki pages' include_examples 'wikis API returns list of wiki pages'
end end
end end
...@@ -266,7 +98,7 @@ RSpec.describe API::Wikis do ...@@ -266,7 +98,7 @@ RSpec.describe API::Wikis do
get api(url) get api(url)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -274,7 +106,7 @@ RSpec.describe API::Wikis do ...@@ -274,7 +106,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'returns list of wiki pages' include_examples 'wikis API returns list of wiki pages'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -282,7 +114,7 @@ RSpec.describe API::Wikis do ...@@ -282,7 +114,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'returns list of wiki pages' include_examples 'wikis API returns list of wiki pages'
end end
end end
end end
...@@ -299,7 +131,7 @@ RSpec.describe API::Wikis do ...@@ -299,7 +131,7 @@ RSpec.describe API::Wikis do
get api(url) get api(url)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -309,7 +141,7 @@ RSpec.describe API::Wikis do ...@@ -309,7 +141,7 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -319,7 +151,7 @@ RSpec.describe API::Wikis do ...@@ -319,7 +151,7 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
end end
...@@ -331,7 +163,7 @@ RSpec.describe API::Wikis do ...@@ -331,7 +163,7 @@ RSpec.describe API::Wikis do
get api(url) get api(url)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -340,12 +172,12 @@ RSpec.describe API::Wikis do ...@@ -340,12 +172,12 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples 'returns wiki page' include_examples 'wikis API returns wiki page'
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" }
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -356,12 +188,12 @@ RSpec.describe API::Wikis do ...@@ -356,12 +188,12 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples 'returns wiki page' include_examples 'wikis API returns wiki page'
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" }
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
end end
...@@ -374,7 +206,7 @@ RSpec.describe API::Wikis do ...@@ -374,7 +206,7 @@ RSpec.describe API::Wikis do
get api(url) get api(url)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -384,12 +216,12 @@ RSpec.describe API::Wikis do ...@@ -384,12 +216,12 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples 'returns wiki page' include_examples 'wikis API returns wiki page'
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" }
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -400,12 +232,12 @@ RSpec.describe API::Wikis do ...@@ -400,12 +232,12 @@ RSpec.describe API::Wikis do
get api(url, user) get api(url, user)
end end
include_examples 'returns wiki page' include_examples 'wikis API returns wiki page'
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" }
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
end end
...@@ -423,7 +255,7 @@ RSpec.describe API::Wikis do ...@@ -423,7 +255,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload) post(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -432,7 +264,7 @@ RSpec.describe API::Wikis do ...@@ -432,7 +264,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload) post(api(url, user), params: payload)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -441,7 +273,7 @@ RSpec.describe API::Wikis do ...@@ -441,7 +273,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload) post(api(url, user), params: payload)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
end end
...@@ -453,7 +285,7 @@ RSpec.describe API::Wikis do ...@@ -453,7 +285,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload) post(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -461,7 +293,7 @@ RSpec.describe API::Wikis do ...@@ -461,7 +293,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'creates wiki page' include_examples 'wikis API creates wiki page'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -469,7 +301,7 @@ RSpec.describe API::Wikis do ...@@ -469,7 +301,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'creates wiki page' include_examples 'wikis API creates wiki page'
end end
end end
...@@ -481,7 +313,7 @@ RSpec.describe API::Wikis do ...@@ -481,7 +313,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload) post(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -489,7 +321,7 @@ RSpec.describe API::Wikis do ...@@ -489,7 +321,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'creates wiki page' include_examples 'wikis API creates wiki page'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -497,7 +329,7 @@ RSpec.describe API::Wikis do ...@@ -497,7 +329,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'creates wiki page' include_examples 'wikis API creates wiki page'
end end
end end
end end
...@@ -515,7 +347,7 @@ RSpec.describe API::Wikis do ...@@ -515,7 +347,7 @@ RSpec.describe API::Wikis do
put(api(url), params: payload) put(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -525,7 +357,7 @@ RSpec.describe API::Wikis do ...@@ -525,7 +357,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload) put(api(url, user), params: payload)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -535,7 +367,7 @@ RSpec.describe API::Wikis do ...@@ -535,7 +367,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload) put(api(url, user), params: payload)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
end end
...@@ -547,7 +379,7 @@ RSpec.describe API::Wikis do ...@@ -547,7 +379,7 @@ RSpec.describe API::Wikis do
put(api(url), params: payload) put(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -555,7 +387,7 @@ RSpec.describe API::Wikis do ...@@ -555,7 +387,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'updates wiki page' include_examples 'wikis API updates wiki page'
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" }
...@@ -564,7 +396,7 @@ RSpec.describe API::Wikis do ...@@ -564,7 +396,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload) put(api(url, user), params: payload)
end end
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -573,7 +405,7 @@ RSpec.describe API::Wikis do ...@@ -573,7 +405,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'updates wiki page' include_examples 'wikis API updates wiki page'
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" }
...@@ -582,7 +414,7 @@ RSpec.describe API::Wikis do ...@@ -582,7 +414,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload) put(api(url, user), params: payload)
end end
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
end end
...@@ -595,7 +427,7 @@ RSpec.describe API::Wikis do ...@@ -595,7 +427,7 @@ RSpec.describe API::Wikis do
put(api(url), params: payload) put(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -603,7 +435,7 @@ RSpec.describe API::Wikis do ...@@ -603,7 +435,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'updates wiki page' include_examples 'wikis API updates wiki page'
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" }
...@@ -612,7 +444,7 @@ RSpec.describe API::Wikis do ...@@ -612,7 +444,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload) put(api(url, user), params: payload)
end end
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
...@@ -621,7 +453,7 @@ RSpec.describe API::Wikis do ...@@ -621,7 +453,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'updates wiki page' include_examples 'wikis API updates wiki page'
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" }
...@@ -630,7 +462,7 @@ RSpec.describe API::Wikis do ...@@ -630,7 +462,7 @@ RSpec.describe API::Wikis do
put(api(url, user), params: payload) put(api(url, user), params: payload)
end end
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
end end
...@@ -638,7 +470,7 @@ RSpec.describe API::Wikis do ...@@ -638,7 +470,7 @@ RSpec.describe API::Wikis do
context 'when wiki belongs to a group project' do context 'when wiki belongs to a group project' do
let(:project) { create(:project, :wiki_repo, namespace: group) } let(:project) { create(:project, :wiki_repo, namespace: group) }
include_examples 'updates wiki page' include_examples 'wikis API updates wiki page'
end end
end end
...@@ -654,7 +486,7 @@ RSpec.describe API::Wikis do ...@@ -654,7 +486,7 @@ RSpec.describe API::Wikis do
delete(api(url)) delete(api(url))
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -664,7 +496,7 @@ RSpec.describe API::Wikis do ...@@ -664,7 +496,7 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -674,7 +506,7 @@ RSpec.describe API::Wikis do ...@@ -674,7 +506,7 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
end end
...@@ -686,7 +518,7 @@ RSpec.describe API::Wikis do ...@@ -686,7 +518,7 @@ RSpec.describe API::Wikis do
delete(api(url)) delete(api(url))
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -696,7 +528,7 @@ RSpec.describe API::Wikis do ...@@ -696,7 +528,7 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -706,7 +538,7 @@ RSpec.describe API::Wikis do ...@@ -706,7 +538,7 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '204 No Content' include_examples 'wiki API 204 No Content'
end end
end end
...@@ -718,7 +550,7 @@ RSpec.describe API::Wikis do ...@@ -718,7 +550,7 @@ RSpec.describe API::Wikis do
delete(api(url)) delete(api(url))
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -728,7 +560,7 @@ RSpec.describe API::Wikis do ...@@ -728,7 +560,7 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -738,12 +570,12 @@ RSpec.describe API::Wikis do ...@@ -738,12 +570,12 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '204 No Content' include_examples 'wiki API 204 No Content'
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" }
include_examples '404 Wiki Page Not Found' include_examples 'wiki API 404 Wiki Page Not Found'
end end
end end
end end
...@@ -755,7 +587,7 @@ RSpec.describe API::Wikis do ...@@ -755,7 +587,7 @@ RSpec.describe API::Wikis do
delete(api(url, user)) delete(api(url, user))
end end
include_examples '204 No Content' include_examples 'wiki API 204 No Content'
end end
end end
...@@ -783,7 +615,7 @@ RSpec.describe API::Wikis do ...@@ -783,7 +615,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload) post(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -792,7 +624,7 @@ RSpec.describe API::Wikis do ...@@ -792,7 +624,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload) post(api(url, user), params: payload)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -801,7 +633,7 @@ RSpec.describe API::Wikis do ...@@ -801,7 +633,7 @@ RSpec.describe API::Wikis do
post(api(url, user), params: payload) post(api(url, user), params: payload)
end end
include_examples '403 Forbidden' include_examples 'wiki API 403 Forbidden'
end end
end end
...@@ -813,7 +645,7 @@ RSpec.describe API::Wikis do ...@@ -813,7 +645,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload) post(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -821,7 +653,7 @@ RSpec.describe API::Wikis do ...@@ -821,7 +653,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'uploads wiki attachment' include_examples 'wiki API uploads wiki attachment'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -829,7 +661,7 @@ RSpec.describe API::Wikis do ...@@ -829,7 +661,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'uploads wiki attachment' include_examples 'wiki API uploads wiki attachment'
end end
end end
...@@ -841,7 +673,7 @@ RSpec.describe API::Wikis do ...@@ -841,7 +673,7 @@ RSpec.describe API::Wikis do
post(api(url), params: payload) post(api(url), params: payload)
end end
include_examples '404 Project Not Found' include_examples 'wiki API 404 Project Not Found'
end end
context 'when user is developer' do context 'when user is developer' do
...@@ -849,7 +681,7 @@ RSpec.describe API::Wikis do ...@@ -849,7 +681,7 @@ RSpec.describe API::Wikis do
project.add_developer(user) project.add_developer(user)
end end
include_examples 'uploads wiki attachment' include_examples 'wiki API uploads wiki attachment'
end end
context 'when user is maintainer' do context 'when user is maintainer' do
...@@ -857,7 +689,7 @@ RSpec.describe API::Wikis do ...@@ -857,7 +689,7 @@ RSpec.describe API::Wikis do
project.add_maintainer(user) project.add_maintainer(user)
end end
include_examples 'uploads wiki attachment' include_examples 'wiki API uploads wiki attachment'
end end
end end
end end
......
# frozen_string_literal: true
RSpec.shared_examples_for 'wikis API returns list of wiki pages' do
context 'when wiki has pages' do
let!(:pages) do
[create(:wiki_page, wiki: wiki, title: 'page1', content: 'content of page1'),
create(:wiki_page, wiki: wiki, title: 'page2.with.dot', content: 'content of page2')]
end
it 'returns the list of wiki pages without content' do
get api(url, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
json_response.each_with_index do |page, index|
expect(page.keys).to match_array(expected_keys_without_content)
expect(page['slug']).to eq(pages[index].slug)
expect(page['title']).to eq(pages[index].title)
end
end
it 'returns the list of wiki pages with content' do
get api(url, user), params: { with_content: 1 }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
json_response.each_with_index do |page, index|
expect(page.keys).to match_array(expected_keys_with_content)
expect(page['content']).to eq(pages[index].content)
expect(page['slug']).to eq(pages[index].slug)
expect(page['title']).to eq(pages[index].title)
end
end
end
it 'return the empty list of wiki pages' do
get api(url, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(0)
end
end
RSpec.shared_examples_for 'wikis API returns wiki page' do
it 'returns the wiki page' do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(page.content)
expect(json_response['slug']).to eq(page.slug)
expect(json_response['title']).to eq(page.title)
end
end
RSpec.shared_examples_for 'wikis API creates wiki page' do
it 'creates the wiki page' do
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
expect(json_response['title']).to eq(payload[:title])
expect(json_response['rdoc']).to eq(payload[:rdoc])
end
[:title, :content].each do |part|
it "responds with validation error on empty #{part}" do
payload.delete(part)
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq("#{part} is missing")
end
end
end
RSpec.shared_examples_for 'wikis API updates wiki page' do
it 'updates the wiki page' do
put(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
expect(json_response['title']).to eq(payload[:title])
end
[:title, :content, :format].each do |part|
it "updates with wiki with missing #{part}" do
payload.delete(part)
put(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
RSpec.shared_examples_for 'wiki API 403 Forbidden' do
it 'returns 403 Forbidden' do
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('403 Forbidden')
end
end
RSpec.shared_examples_for 'wiki API 404 Wiki Page Not Found' do
it 'returns 404 Wiki Page Not Found' do
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('404 Wiki Page Not Found')
end
end
RSpec.shared_examples_for 'wiki API 404 Not Found' do |what|
it "returns 404 #{what} Not Found" do
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq("404 #{what} Not Found")
end
end
RSpec.shared_examples_for 'wiki API 204 No Content' do
it 'returns 204 No Content' do
expect(response).to have_gitlab_http_status(:no_content)
end
end
RSpec.shared_examples_for 'wiki API uploads wiki attachment' do
it 'pushes attachment to the wiki repository' do
allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
workhorse_post_with_file(api(url, user), file_key: :file, params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to eq result_hash.deep_stringify_keys
end
it 'responds with validation error on empty file' do
payload.delete(:file)
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq('file is missing')
end
it 'responds with validation error on invalid temp file' do
payload[:file] = { tempfile: '/etc/hosts' }
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq('file is invalid')
end
it 'is backward compatible with regular multipart uploads' do
allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to eq result_hash.deep_stringify_keys
end
end
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