mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-20 14:11:11 +00:00
Add API support for wiki pages
This commit is contained in:
5
changelogs/unreleased/wiki_api.yml
Normal file
5
changelogs/unreleased/wiki_api.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Add API support for wiki pages
|
||||||
|
merge_request: 13372
|
||||||
|
author: Vitaliy @blackst0ne Klachkov
|
||||||
|
type: added
|
@ -58,6 +58,7 @@ following locations:
|
|||||||
- [Validate CI configuration](lint.md)
|
- [Validate CI configuration](lint.md)
|
||||||
- [V3 to V4](v3_to_v4.md)
|
- [V3 to V4](v3_to_v4.md)
|
||||||
- [Version](version.md)
|
- [Version](version.md)
|
||||||
|
- [Wikis](wikis.md)
|
||||||
|
|
||||||
## Road to GraphQL
|
## Road to GraphQL
|
||||||
|
|
||||||
|
157
doc/api/wikis.md
Normal file
157
doc/api/wikis.md
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
# Wikis API
|
||||||
|
|
||||||
|
> [Introduced][ce-13372] in GitLab 10.0.
|
||||||
|
|
||||||
|
Available only in APIv4.
|
||||||
|
|
||||||
|
## List wiki pages
|
||||||
|
|
||||||
|
Get all wiki pages for a given project.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /projects/:id/wikis
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | ------- | -------- | --------------------- |
|
||||||
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
|
||||||
|
| `with_content` | boolean | no | Include pages' content |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/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 project.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /projects/:id/wikis/:slug
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | ------- | -------- | --------------------- |
|
||||||
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
|
||||||
|
| `slug` | string | yes | The slug (a unique string) of the wiki page |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/wikis/home
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"content" : "home page",
|
||||||
|
"format" : "markdown",
|
||||||
|
"slug" : "home",
|
||||||
|
"title" : "home"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a new wiki page
|
||||||
|
|
||||||
|
Creates a new wiki page for the given repository with the given title, slug, and content.
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /projects/:id/wikis
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| ------------- | ------- | -------- | ---------------------------- |
|
||||||
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](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`, and `asciidoc` |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --data "format=rdoc&title=Hello&content=Hello world" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/wikis"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content" : "Hello world",
|
||||||
|
"format" : "markdown",
|
||||||
|
"slug" : "Hello",
|
||||||
|
"title" : "Hello"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Edit an existing wiki page
|
||||||
|
|
||||||
|
Updates an existing wiki page. At least one parameter is required to update the wiki page.
|
||||||
|
|
||||||
|
```
|
||||||
|
PUT /projects/:id/wikis/:slug
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------------- | ------- | --------------------------------- | ------------------------------- |
|
||||||
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](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`, and `asciidoc` |
|
||||||
|
| `slug` | string | yes | The slug (a unique string) of the wiki page |
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --request PUT --data "format=rdoc&content=documentation&title=Docs" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/wikis/foo"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content" : "documentation",
|
||||||
|
"format" : "markdown",
|
||||||
|
"slug" : "Docs",
|
||||||
|
"title" : "Docs"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Delete a wiki page
|
||||||
|
|
||||||
|
Deletes a wiki page with a given slug.
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /projects/:id/wikis/:slug
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | ------- | -------- | --------------------- |
|
||||||
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
|
||||||
|
| `slug` | string | yes | The slug (a unique string) of the wiki page |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/wikis/foo"
|
||||||
|
```
|
||||||
|
|
||||||
|
On success the HTTP status code is `204` and no JSON response is expected.
|
@ -143,6 +143,7 @@ module API
|
|||||||
mount ::API::Variables
|
mount ::API::Variables
|
||||||
mount ::API::GroupVariables
|
mount ::API::GroupVariables
|
||||||
mount ::API::Version
|
mount ::API::Version
|
||||||
|
mount ::API::Wikis
|
||||||
|
|
||||||
route :any, '*path' do
|
route :any, '*path' do
|
||||||
error!('404 Not Found', 404)
|
error!('404 Not Found', 404)
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
module API
|
module API
|
||||||
module Entities
|
module Entities
|
||||||
|
class WikiPageBasic < Grape::Entity
|
||||||
|
expose :format
|
||||||
|
expose :slug
|
||||||
|
expose :title
|
||||||
|
end
|
||||||
|
|
||||||
|
class WikiPage < WikiPageBasic
|
||||||
|
expose :content
|
||||||
|
end
|
||||||
|
|
||||||
class UserSafe < Grape::Entity
|
class UserSafe < Grape::Entity
|
||||||
expose :name, :username
|
expose :name, :username
|
||||||
end
|
end
|
||||||
|
@ -35,6 +35,12 @@ module API
|
|||||||
@project ||= find_project!(params[:id])
|
@project ||= find_project!(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wiki_page
|
||||||
|
page = user_project.wiki.find_page(params[:slug])
|
||||||
|
|
||||||
|
page || not_found!('Wiki Page')
|
||||||
|
end
|
||||||
|
|
||||||
def available_labels
|
def available_labels
|
||||||
@available_labels ||= LabelsFinder.new(current_user, project_id: user_project.id).execute
|
@available_labels ||= LabelsFinder.new(current_user, project_id: user_project.id).execute
|
||||||
end
|
end
|
||||||
|
89
lib/api/wikis.rb
Normal file
89
lib/api/wikis.rb
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
module API
|
||||||
|
class Wikis < Grape::API
|
||||||
|
helpers do
|
||||||
|
params :wiki_page_params do
|
||||||
|
requires :content, type: String, desc: 'Content of a wiki page'
|
||||||
|
requires :title, type: String, desc: 'Title of a wiki page'
|
||||||
|
optional :format,
|
||||||
|
type: String,
|
||||||
|
values: ProjectWiki::MARKUPS.values.map(&:to_s),
|
||||||
|
default: 'markdown',
|
||||||
|
desc: 'Format of a wiki page. Available formats are markdown, rdoc, and asciidoc'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
|
||||||
|
desc 'Get a list of wiki pages' do
|
||||||
|
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, user_project
|
||||||
|
|
||||||
|
entity = params[:with_content] ? Entities::WikiPage : Entities::WikiPageBasic
|
||||||
|
present user_project.wiki.pages, with: entity
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Get a wiki page' do
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Create a wiki page' do
|
||||||
|
success Entities::WikiPage
|
||||||
|
end
|
||||||
|
params do
|
||||||
|
use :wiki_page_params
|
||||||
|
end
|
||||||
|
post ':id/wikis' do
|
||||||
|
authorize! :create_wiki, user_project
|
||||||
|
|
||||||
|
page = WikiPages::CreateService.new(user_project, current_user, params).execute
|
||||||
|
|
||||||
|
if page.valid?
|
||||||
|
present page, with: Entities::WikiPage
|
||||||
|
else
|
||||||
|
render_validation_error!(page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Update a wiki page' do
|
||||||
|
success Entities::WikiPage
|
||||||
|
end
|
||||||
|
params do
|
||||||
|
use :wiki_page_params
|
||||||
|
end
|
||||||
|
put ':id/wikis/:slug' do
|
||||||
|
authorize! :create_wiki, user_project
|
||||||
|
|
||||||
|
page = WikiPages::UpdateService.new(user_project, current_user, params).execute(wiki_page)
|
||||||
|
|
||||||
|
if page.valid?
|
||||||
|
present page, with: Entities::WikiPage
|
||||||
|
else
|
||||||
|
render_validation_error!(page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Delete a wiki page'
|
||||||
|
params do
|
||||||
|
requires :slug, type: String, desc: 'The slug of a wiki page'
|
||||||
|
end
|
||||||
|
delete ':id/wikis/:slug' do
|
||||||
|
authorize! :admin_wiki, user_project
|
||||||
|
|
||||||
|
status 204
|
||||||
|
WikiPages::DestroyService.new(user_project, current_user).execute(wiki_page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
679
spec/requests/api/wikis_spec.rb
Normal file
679
spec/requests/api/wikis_spec.rb
Normal file
@ -0,0 +1,679 @@
|
|||||||
|
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
|
||||||
|
# - master
|
||||||
|
# because they are 3 edge cases of using wiki pages.
|
||||||
|
|
||||||
|
describe API::Wikis do
|
||||||
|
let(:user) { create(: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 'returns list of wiki pages' do
|
||||||
|
context 'when wiki has pages' do
|
||||||
|
let!(:pages) do
|
||||||
|
[create(:wiki_page, wiki: project.wiki, attrs: { title: 'page1', content: 'content of page1' }),
|
||||||
|
create(:wiki_page, wiki: project.wiki, attrs: { title: 'page2', content: 'content of page2' })]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the list of wiki pages without content' do
|
||||||
|
get api(url, user)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
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), with_content: 1
|
||||||
|
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
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_http_status(200)
|
||||||
|
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_http_status(200)
|
||||||
|
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), payload)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(201)
|
||||||
|
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), payload)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(400)
|
||||||
|
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
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples_for '403 Forbidden' do
|
||||||
|
it 'returns 403 Forbidden' do
|
||||||
|
expect(response).to have_http_status(403)
|
||||||
|
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_http_status(404)
|
||||||
|
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_http_status(404)
|
||||||
|
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_http_status(204)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /projects/:id/wikis' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis" }
|
||||||
|
|
||||||
|
context 'when wiki is disabled' do
|
||||||
|
let(:project) { create(:project, :wiki_disabled) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
get api(url)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available only for team members' do
|
||||||
|
let(:project) { create(:project, :wiki_private) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
get api(url)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns list of wiki pages'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns list of wiki pages'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available for everyone with access' do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
get api(url)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns list of wiki pages'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns list of wiki pages'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /projects/:id/wikis/:slug' do
|
||||||
|
let(:page) { create(:wiki_page, wiki: project.wiki) }
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/#{page.slug}" }
|
||||||
|
|
||||||
|
context 'when wiki is disabled' do
|
||||||
|
let(:project) { create(:project, :wiki_disabled) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
get api(url)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available only for team members' do
|
||||||
|
let(:project) { create(:project, :wiki_private) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
get api(url)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available for everyone with access' do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
get api(url)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
get api(url, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'returns wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST /projects/:id/wikis' do
|
||||||
|
let(:payload) { { title: 'title', content: 'content' } }
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis" }
|
||||||
|
|
||||||
|
context 'when wiki is disabled' do
|
||||||
|
let(:project) { create(:project, :wiki_disabled) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
post(api(url), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
post(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
post(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available only for team members' do
|
||||||
|
let(:project) { create(:project, :wiki_private) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
post(api(url), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'creates wiki page'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'creates wiki page'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available for everyone with access' do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
post(api(url), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'creates wiki page'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'creates wiki page'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PUT /projects/:id/wikis/:slug' do
|
||||||
|
let(:page) { create(:wiki_page, wiki: project.wiki) }
|
||||||
|
let(:payload) { { title: 'new title', content: 'new content' } }
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/#{page.slug}" }
|
||||||
|
|
||||||
|
context 'when wiki is disabled' do
|
||||||
|
let(:project) { create(:project, :wiki_disabled) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
put(api(url), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
put(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
put(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available only for team members' do
|
||||||
|
let(:project) { create(:project, :wiki_private) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
put(api(url), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
put(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'updates wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
put(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'updates wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available for everyone with access' do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
put(api(url), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
put(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'updates wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
put(api(url, user), payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples 'updates wiki page'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE /projects/:id/wikis/:slug' do
|
||||||
|
let(:page) { create(:wiki_page, wiki: project.wiki) }
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/#{page.slug}" }
|
||||||
|
|
||||||
|
context 'when wiki is disabled' do
|
||||||
|
let(:project) { create(:project, :wiki_disabled) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
delete(api(url))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
delete(api(url, user))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
delete(api(url, user))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available only for team members' do
|
||||||
|
let(:project) { create(:project, :wiki_private) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
delete(api(url))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
delete(api(url, user))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
delete(api(url, user))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '204 No Content'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wiki is available for everyone with access' do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
context 'when user is guest' do
|
||||||
|
before do
|
||||||
|
delete(api(url))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '404 Project Not Found'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is developer' do
|
||||||
|
before do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
delete(api(url, user))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '403 Forbidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is master' do
|
||||||
|
before do
|
||||||
|
project.add_master(user)
|
||||||
|
|
||||||
|
delete(api(url, user))
|
||||||
|
end
|
||||||
|
|
||||||
|
include_examples '204 No Content'
|
||||||
|
|
||||||
|
context 'when page is not existing' do
|
||||||
|
let(:url) { "/projects/#{project.id}/wikis/unknown" }
|
||||||
|
|
||||||
|
include_examples '404 Wiki Page Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue
Block a user