Commit 3c31f185 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch '17541-move-licenses-api-endpoint-to-templates-licenses' into 'master'

Resolve "Move `/licenses` api endpoint to `/templates/licenses`"

## What does this MR do?

It moves the `/licenses`, `/gitignores` and `/gitlab_ci_ymls` API endpoints under the `/templates` namespace

## Why was this MR needed?

In EE we now have somewhat ambiguous API endpoints. `/license` refers to the EE license while `/licenses` (plural) refers to license templates. @DouweM mentioned that we're adding .gitignore templates in #14106 so it may make sense to add a /templates namespace. Then, move the /license templates endpoint to be underneath, along with .gitignore endpoints. 

Closes #17541

See merge request !5717
parents 8aa381c9 b9b13ea8
......@@ -19,6 +19,7 @@ v 8.13.0 (unreleased)
- Replaced the check sign to arrow in the show build view. !6501
- Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar)
- Fix Error 500 when viewing old merge requests with bad diff data
- Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar)
- Speed-up group milestones show page
- Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps)
- Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs)
......
......@@ -6,11 +6,10 @@
groupProjectsPath: "/api/:version/groups/:id/projects.json",
projectsPath: "/api/:version/projects.json?simple=true",
labelsPath: "/:namespace_path/:project_path/labels",
licensePath: "/api/:version/licenses/:key",
gitignorePath: "/api/:version/gitignores/:key",
gitlabCiYmlPath: "/api/:version/gitlab_ci_ymls/:key",
licensePath: "/api/:version/templates/licenses/:key",
gitignorePath: "/api/:version/templates/gitignores/:key",
gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key",
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key",
group: function(group_id, callback) {
var url = Api.buildUrl(Api.groupPath)
.replace(':id', group_id);
......
......@@ -17,6 +17,8 @@ following locations:
- [Commits](commits.md)
- [Deployments](deployments.md)
- [Deploy Keys](deploy_keys.md)
- [Gitignores templates](templates/gitignores.md)
- [GitLab CI Config templates](templates/gitlab_ci_ymls.md)
- [Groups](groups.md)
- [Group Access Requests](access_requests.md)
- [Group Members](members.md)
......@@ -25,7 +27,7 @@ following locations:
- [Labels](labels.md)
- [Merge Requests](merge_requests.md)
- [Milestones](milestones.md)
- [Open source license templates](licenses.md)
- [Open source license templates](templates/licenses.md)
- [Namespaces](namespaces.md)
- [Notes](notes.md) (comments)
- [Notification settings](notification_settings.md)
......
# Gitignores
## List gitignore templates
Get all gitignore templates.
```
GET /templates/gitignores
```
```bash
curl https://gitlab.example.com/api/v3/templates/gitignores
```
Example response:
```json
[
{
"name": "AppEngine"
},
{
"name": "Laravel"
},
{
"name": "Elisp"
},
{
"name": "SketchUp"
},
{
"name": "Ada"
},
{
"name": "Ruby"
},
{
"name": "Kohana"
},
{
"name": "Nanoc"
},
{
"name": "Erlang"
},
{
"name": "OCaml"
},
{
"name": "Lithium"
},
{
"name": "Fortran"
},
{
"name": "Scala"
},
{
"name": "Node"
},
{
"name": "Fancy"
},
{
"name": "Perl"
},
{
"name": "Zephir"
},
{
"name": "WordPress"
},
{
"name": "Symfony"
},
{
"name": "FuelPHP"
},
{
"name": "DM"
},
{
"name": "Sdcc"
},
{
"name": "Rust"
},
{
"name": "C"
},
{
"name": "Umbraco"
},
{
"name": "Actionscript"
},
{
"name": "Android"
},
{
"name": "Grails"
},
{
"name": "Composer"
},
{
"name": "ExpressionEngine"
},
{
"name": "Gcov"
},
{
"name": "Qt"
},
{
"name": "Phalcon"
},
{
"name": "ArchLinuxPackages"
},
{
"name": "TeX"
},
{
"name": "SCons"
},
{
"name": "Lilypond"
},
{
"name": "CommonLisp"
},
{
"name": "Rails"
},
{
"name": "Mercury"
},
{
"name": "Magento"
},
{
"name": "ChefCookbook"
},
{
"name": "GitBook"
},
{
"name": "C++"
},
{
"name": "Eagle"
},
{
"name": "Go"
},
{
"name": "OpenCart"
},
{
"name": "Scheme"
},
{
"name": "Typo3"
},
{
"name": "SeamGen"
},
{
"name": "Swift"
},
{
"name": "Elm"
},
{
"name": "Unity"
},
{
"name": "Agda"
},
{
"name": "CUDA"
},
{
"name": "VVVV"
},
{
"name": "Finale"
},
{
"name": "LemonStand"
},
{
"name": "Textpattern"
},
{
"name": "Julia"
},
{
"name": "Packer"
},
{
"name": "Scrivener"
},
{
"name": "Dart"
},
{
"name": "Plone"
},
{
"name": "Jekyll"
},
{
"name": "Xojo"
},
{
"name": "LabVIEW"
},
{
"name": "Autotools"
},
{
"name": "KiCad"
},
{
"name": "Prestashop"
},
{
"name": "ROS"
},
{
"name": "Smalltalk"
},
{
"name": "GWT"
},
{
"name": "OracleForms"
},
{
"name": "SugarCRM"
},
{
"name": "Nim"
},
{
"name": "SymphonyCMS"
},
{
"name": "Maven"
},
{
"name": "CFWheels"
},
{
"name": "Python"
},
{
"name": "ZendFramework"
},
{
"name": "CakePHP"
},
{
"name": "Concrete5"
},
{
"name": "PlayFramework"
},
{
"name": "Terraform"
},
{
"name": "Elixir"
},
{
"name": "CMake"
},
{
"name": "Joomla"
},
{
"name": "Coq"
},
{
"name": "Delphi"
},
{
"name": "Haskell"
},
{
"name": "Yii"
},
{
"name": "Java"
},
{
"name": "UnrealEngine"
},
{
"name": "AppceleratorTitanium"
},
{
"name": "CraftCMS"
},
{
"name": "ForceDotCom"
},
{
"name": "ExtJs"
},
{
"name": "MetaProgrammingSystem"
},
{
"name": "D"
},
{
"name": "Objective-C"
},
{
"name": "RhodesRhomobile"
},
{
"name": "R"
},
{
"name": "EPiServer"
},
{
"name": "Yeoman"
},
{
"name": "VisualStudio"
},
{
"name": "Processing"
},
{
"name": "Leiningen"
},
{
"name": "Stella"
},
{
"name": "Opa"
},
{
"name": "Drupal"
},
{
"name": "TurboGears2"
},
{
"name": "Idris"
},
{
"name": "Jboss"
},
{
"name": "CodeIgniter"
},
{
"name": "Qooxdoo"
},
{
"name": "Waf"
},
{
"name": "Sass"
},
{
"name": "Lua"
},
{
"name": "Clojure"
},
{
"name": "IGORPro"
},
{
"name": "Gradle"
},
{
"name": "Archives"
},
{
"name": "SynopsysVCS"
},
{
"name": "Ninja"
},
{
"name": "Tags"
},
{
"name": "OSX"
},
{
"name": "Dreamweaver"
},
{
"name": "CodeKit"
},
{
"name": "NotepadPP"
},
{
"name": "VisualStudioCode"
},
{
"name": "Mercurial"
},
{
"name": "BricxCC"
},
{
"name": "DartEditor"
},
{
"name": "Eclipse"
},
{
"name": "Cloud9"
},
{
"name": "TortoiseGit"
},
{
"name": "NetBeans"
},
{
"name": "GPG"
},
{
"name": "Espresso"
},
{
"name": "Redcar"
},
{
"name": "Xcode"
},
{
"name": "Matlab"
},
{
"name": "LyX"
},
{
"name": "SlickEdit"
},
{
"name": "Dropbox"
},
{
"name": "CVS"
},
{
"name": "Calabash"
},
{
"name": "JDeveloper"
},
{
"name": "Vagrant"
},
{
"name": "IPythonNotebook"
},
{
"name": "TextMate"
},
{
"name": "Ensime"
},
{
"name": "WebMethods"
},
{
"name": "VirtualEnv"
},
{
"name": "Emacs"
},
{
"name": "Momentics"
},
{
"name": "JetBrains"
},
{
"name": "SublimeText"
},
{
"name": "Kate"
},
{
"name": "ModelSim"
},
{
"name": "Redis"
},
{
"name": "KDevelop4"
},
{
"name": "Bazaar"
},
{
"name": "Linux"
},
{
"name": "Windows"
},
{
"name": "XilinxISE"
},
{
"name": "Lazarus"
},
{
"name": "EiffelStudio"
},
{
"name": "Anjuta"
},
{
"name": "Vim"
},
{
"name": "Otto"
},
{
"name": "MicrosoftOffice"
},
{
"name": "LibreOffice"
},
{
"name": "SBT"
},
{
"name": "MonoDevelop"
},
{
"name": "SVN"
},
{
"name": "FlexBuilder"
}
]
```
## Single gitignore template
Get a single gitignore template.
```
GET /templates/gitignores/:key
```
| Attribute | Type | Required | Description |
| ---------- | ------ | -------- | ----------- |
| `key` | string | yes | The key of the gitignore template |
```bash
curl https://gitlab.example.com/api/v3/templates/gitignores/Ruby
```
Example response:
```json
{
"name": "Ruby",
"content": "*.gem\n*.rbc\n/.config\n/coverage/\n/InstalledFiles\n/pkg/\n/spec/reports/\n/spec/examples.txt\n/test/tmp/\n/test/version_tmp/\n/tmp/\n\n# Used by dotenv library to load environment variables.\n# .env\n\n## Specific to RubyMotion:\n.dat*\n.repl_history\nbuild/\n*.bridgesupport\nbuild-iPhoneOS/\nbuild-iPhoneSimulator/\n\n## Specific to RubyMotion (use of CocoaPods):\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# vendor/Pods/\n\n## Documentation cache and generated files:\n/.yardoc/\n/_yardoc/\n/doc/\n/rdoc/\n\n## Environment normalization:\n/.bundle/\n/vendor/bundle\n/lib/bundler/man/\n\n# for a library or gem, you might want to ignore these files since the code is\n# intended to run in multiple environments; otherwise, check them in:\n# Gemfile.lock\n# .ruby-version\n# .ruby-gemset\n\n# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:\n.rvmrc\n"
}
```
# GitLab CI YMLs
## List GitLab CI YML templates
Get all GitLab CI YML templates.
```
GET /templates/gitlab_ci_ymls
```
```bash
curl https://gitlab.example.com/api/v3/templates/gitlab_ci_ymls
```
Example response:
```json
[
{
"name": "C++"
},
{
"name": "Docker"
},
{
"name": "Elixir"
},
{
"name": "LaTeX"
},
{
"name": "Grails"
},
{
"name": "Rust"
},
{
"name": "Nodejs"
},
{
"name": "Ruby"
},
{
"name": "Scala"
},
{
"name": "Maven"
},
{
"name": "Harp"
},
{
"name": "Pelican"
},
{
"name": "Hyde"
},
{
"name": "Nanoc"
},
{
"name": "Octopress"
},
{
"name": "JBake"
},
{
"name": "HTML"
},
{
"name": "Hugo"
},
{
"name": "Metalsmith"
},
{
"name": "Hexo"
},
{
"name": "Lektor"
},
{
"name": "Doxygen"
},
{
"name": "Brunch"
},
{
"name": "Jekyll"
},
{
"name": "Middleman"
}
]
```
## Single GitLab CI YML template
Get a single GitLab CI YML template.
```
GET /templates/gitlab_ci_ymls/:key
```
| Attribute | Type | Required | Description |
| ---------- | ------ | -------- | ----------- |
| `key` | string | yes | The key of the GitLab CI YML template |
```bash
curl https://gitlab.example.com/api/v3/templates/gitlab_ci_ymls/Ruby
```
Example response:
```json
{
"name": "Ruby",
"content": "# This file is a template, and might need editing before it works on your project.\n# Official language image. Look for the different tagged releases at:\n# https://hub.docker.com/r/library/ruby/tags/\nimage: \"ruby:2.3\"\n\n# Pick zero or more services to be used on all builds.\n# Only needed when using a docker container to run your tests in.\n# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service\nservices:\n - mysql:latest\n - redis:latest\n - postgres:latest\n\nvariables:\n POSTGRES_DB: database_name\n\n# Cache gems in between builds\ncache:\n paths:\n - vendor/ruby\n\n# This is a basic example for a gem or script which doesn't use\n# services such as redis or postgres\nbefore_script:\n - ruby -v # Print out ruby version for debugging\n # Uncomment next line if your rails app needs a JS runtime:\n # - apt-get update -q && apt-get install nodejs -yqq\n - gem install bundler --no-ri --no-rdoc # Bundler is not installed with the image\n - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby\n\n# Optional - Delete if not using `rubocop`\nrubocop:\n script:\n - rubocop\n\nrspec:\n script:\n - rspec spec\n\nrails:\n variables:\n DATABASE_URL: \"postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB\"\n script:\n - bundle exec rake db:migrate\n - bundle exec rake db:seed\n - bundle exec rake test\n"
}
```
......@@ -5,7 +5,7 @@
Get all license templates.
```
GET /licenses
GET /templates/licenses
```
| Attribute | Type | Required | Description |
......@@ -13,7 +13,7 @@ GET /licenses
| `popular` | boolean | no | If passed, returns only popular licenses |
```bash
curl https://gitlab.example.com/api/v3/licenses?popular=1
curl https://gitlab.example.com/api/v3/templates/licenses?popular=1
```
Example response:
......@@ -102,7 +102,7 @@ Get a single license template. You can pass parameters to replace the license
placeholder.
```
GET /licenses/:key
GET /templates/licenses/:key
```
| Attribute | Type | Required | Description |
......@@ -116,7 +116,7 @@ If you omit the `fullname` parameter but authenticate your request, the name of
the authenticated user will be used to replace the copyright holder placeholder.
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/licenses/mit?project=My+Cool+Project
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/templates/licenses/mit?project=My+Cool+Project
```
Example response:
......
......@@ -46,7 +46,6 @@ module API
mount ::API::Boards
mount ::API::Keys
mount ::API::Labels
mount ::API::LicenseTemplates
mount ::API::Lint
mount ::API::Members
mount ::API::MergeRequests
......
module API
# License Templates API
class LicenseTemplates < Grape::API
PROJECT_TEMPLATE_REGEX =
/[\<\{\[]
(project|description|
one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
[\>\}\]]/xi.freeze
YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze
FULLNAME_TEMPLATE_REGEX =
/[\<\{\[]
(fullname|name\sof\s(author|copyright\sowner))
[\>\}\]]/xi.freeze
# Get the list of the available license templates
#
# Parameters:
# popular - Filter licenses to only the popular ones
#
# Example Request:
# GET /licenses
# GET /licenses?popular=1
get 'licenses' do
options = {
featured: params[:popular].present? ? true : nil
}
present Licensee::License.all(options), with: Entities::RepoLicense
end
# Get text for specific license
#
# Parameters:
# key (required) - The key of a license
# project - Copyrighted project name
# fullname - Full name of copyright holder
#
# Example Request:
# GET /licenses/mit
#
get 'licenses/:key', requirements: { key: /[\w\.-]+/ } do
required_attributes! [:key]
not_found!('License') unless Licensee::License.find(params[:key])
# We create a fresh Licensee::License object since we'll modify its
# content in place below.
license = Licensee::License.new(params[:key])
license.content.gsub!(YEAR_TEMPLATE_REGEX, Time.now.year.to_s)
license.content.gsub!(PROJECT_TEMPLATE_REGEX, params[:project]) if params[:project].present?
fullname = params[:fullname].presence || current_user.try(:name)
license.content.gsub!(FULLNAME_TEMPLATE_REGEX, fullname) if fullname
present license, with: Entities::RepoLicense
end
end
end
module API
class Templates < Grape::API
GLOBAL_TEMPLATE_TYPES = {
gitignores: Gitlab::Template::GitignoreTemplate,
gitlab_ci_ymls: Gitlab::Template::GitlabCiYmlTemplate
gitignores: {
klass: Gitlab::Template::GitignoreTemplate,
gitlab_version: 8.8
},
gitlab_ci_ymls: {
klass: Gitlab::Template::GitlabCiYmlTemplate,
gitlab_version: 8.9
}
}.freeze
PROJECT_TEMPLATE_REGEX =
/[\<\{\[]
(project|description|
one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here
[\>\}\]]/xi.freeze
YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze
FULLNAME_TEMPLATE_REGEX =
/[\<\{\[]
(fullname|name\sof\s(author|copyright\sowner))
[\>\}\]]/xi.freeze
DEPRECATION_MESSAGE = ' This endpoint is deprecated and will be removed in GitLab 9.0.'.freeze
helpers do
def parsed_license_template
# We create a fresh Licensee::License object since we'll modify its
# content in place below.
template = Licensee::License.new(params[:name])
template.content.gsub!(YEAR_TEMPLATE_REGEX, Time.now.year.to_s)
template.content.gsub!(PROJECT_TEMPLATE_REGEX, params[:project]) if params[:project].present?
fullname = params[:fullname].presence || current_user.try(:name)
template.content.gsub!(FULLNAME_TEMPLATE_REGEX, fullname) if fullname
template
end
def render_response(template_type, template)
not_found!(template_type.to_s.singularize) unless template
present template, with: Entities::Template
end
end
GLOBAL_TEMPLATE_TYPES.each do |template_type, klass|
# Get the list of the available template
#
# Example Request:
# GET /gitignores
# GET /gitlab_ci_ymls
get template_type.to_s do
{ "licenses" => :deprecated, "templates/licenses" => :ok }.each do |route, status|
desc 'Get the list of the available license template' do
detailed_desc = 'This feature was introduced in GitLab 8.7.'
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::RepoLicense
end
params do
optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses'
end
get route do
options = {
featured: declared(params).popular.present? ? true : nil
}
present Licensee::License.all(options), with: Entities::RepoLicense
end
end
{ "licenses/:name" => :deprecated, "templates/licenses/:name" => :ok }.each do |route, status|
desc 'Get the text for a specific license' do
detailed_desc = 'This feature was introduced in GitLab 8.7.'
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::RepoLicense
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get route, requirements: { name: /[\w\.-]+/ } do
not_found!('License') unless Licensee::License.find(declared(params).name)
template = parsed_license_template
present template, with: Entities::RepoLicense
end
end
GLOBAL_TEMPLATE_TYPES.each do |template_type, properties|
klass = properties[:klass]
gitlab_version = properties[:gitlab_version]
{ template_type => :deprecated, "templates/#{template_type}" => :ok }.each do |route, status|
desc 'Get the list of the available template' do
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::TemplatesList
end
get route do
present klass.all, with: Entities::TemplatesList
end
end
{ "#{template_type}/:name" => :deprecated, "templates/#{template_type}/:name" => :ok }.each do |route, status|
desc 'Get the text for a specific template present in local filesystem' do
detailed_desc = "This feature was introduced in GitLab #{gitlab_version}."
detailed_desc << DEPRECATION_MESSAGE unless status == :ok
detail detailed_desc
success Entities::Template
end
params do
requires :name, type: String, desc: 'The name of the template'
end
get route do
new_template = klass.find(declared(params).name)
# Get the text for a specific template present in local filesystem
#
# Parameters:
# name (required) - The name of a template
#
# Example Request:
# GET /gitignores/Elixir
# GET /gitlab_ci_ymls/Ruby
get "#{template_type}/:name" do
required_attributes! [:name]
new_template = klass.find(params[:name])
render_response(template_type, new_template)
end
end
end
end
end
require 'spec_helper'
describe API::API, api: true do
include ApiHelpers
describe 'Entity' do
before { get api('/licenses/mit') }
it { expect(json_response['key']).to eq('mit') }
it { expect(json_response['name']).to eq('MIT License') }
it { expect(json_response['nickname']).to be_nil }
it { expect(json_response['popular']).to be true }
it { expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/') }
it { expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT') }
it { expect(json_response['description']).to include('A permissive license that is short and to the point.') }
it { expect(json_response['conditions']).to eq(%w[include-copyright]) }
it { expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use]) }
it { expect(json_response['limitations']).to eq(%w[no-liability]) }
it { expect(json_response['content']).to include('The MIT License (MIT)') }
end
describe 'GET /licenses' do
it 'returns a list of available license templates' do
get api('/licenses')
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(15)
expect(json_response.map { |l| l['key'] }).to include('agpl-3.0')
end
describe 'the popular parameter' do
context 'with popular=1' do
it 'returns a list of available popular license templates' do
get api('/licenses?popular=1')
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
expect(json_response.map { |l| l['key'] }).to include('apache-2.0')
end
end
end
end
describe 'GET /licenses/:key' do
context 'with :project and :fullname given' do
before do
get api("/licenses/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
end
context 'for the mit license' do
let(:license_type) { 'mit' }
it 'returns the license text' do
expect(json_response['content']).to include('The MIT License (MIT)')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} Anton")
end
end
context 'for the agpl-3.0 license' do
let(:license_type) { 'agpl-3.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU AFFERO GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the gpl-3.0 license' do
let(:license_type) { 'gpl-3.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the gpl-2.0 license' do
let(:license_type) { 'gpl-2.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the apache-2.0 license' do
let(:license_type) { 'apache-2.0' }
it 'returns the license text' do
expect(json_response['content']).to include('Apache License')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include("Copyright #{Time.now.year} Anton")
end
end
context 'for an uknown license' do
let(:license_type) { 'muth-over9000' }
it 'returns a 404' do
expect(response).to have_http_status(404)
end
end
end
context 'with no :fullname given' do
context 'with an authenticated user' do
let(:user) { create(:user) }
it 'replaces the copyright owner placeholder with the name of the current user' do
get api('/licenses/mit', user)
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} #{user.name}")
end
end
end
end
end
......@@ -3,53 +3,201 @@ require 'spec_helper'
describe API::Templates, api: true do
include ApiHelpers
context 'global templates' do
describe 'the Template Entity' do
before { get api('/gitignores/Ruby') }
shared_examples_for 'the Template Entity' do |path|
before { get api(path) }
it { expect(json_response['name']).to eq('Ruby') }
it { expect(json_response['content']).to include('*.gem') }
end
describe 'the TemplateList Entity' do
before { get api('/gitignores') }
shared_examples_for 'the TemplateList Entity' do |path|
before { get api(path) }
it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil }
end
context 'requesting gitignores' do
describe 'GET /gitignores' do
shared_examples_for 'requesting gitignores' do |path|
it 'returns a list of available gitignore templates' do
get api('/gitignores')
get api(path)
expect(response.status).to eq(200)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to be > 15
end
end
end
context 'requesting gitlab-ci-ymls' do
describe 'GET /gitlab_ci_ymls' do
shared_examples_for 'requesting gitlab-ci-ymls' do |path|
it 'returns a list of available gitlab_ci_ymls' do
get api('/gitlab_ci_ymls')
get api(path)
expect(response.status).to eq(200)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).not_to be_nil
end
end
end
describe 'GET /gitlab_ci_ymls/Ruby' do
shared_examples_for 'requesting gitlab-ci-yml for Ruby' do |path|
it 'adds a disclaimer on the top' do
get api('/gitlab_ci_ymls/Ruby')
get api(path)
expect(response).to have_http_status(200)
expect(json_response['name']).not_to be_nil
expect(json_response['content']).to start_with("# This file is a template,")
end
end
shared_examples_for 'the License Template Entity' do |path|
before { get api(path) }
it 'returns a license template' do
expect(json_response['key']).to eq('mit')
expect(json_response['name']).to eq('MIT License')
expect(json_response['nickname']).to be_nil
expect(json_response['popular']).to be true
expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/')
expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT')
expect(json_response['description']).to include('A permissive license that is short and to the point.')
expect(json_response['conditions']).to eq(%w[include-copyright])
expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use])
expect(json_response['limitations']).to eq(%w[no-liability])
expect(json_response['content']).to include('The MIT License (MIT)')
end
end
shared_examples_for 'GET licenses' do |path|
it 'returns a list of available license templates' do
get api(path)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(15)
expect(json_response.map { |l| l['key'] }).to include('agpl-3.0')
end
describe 'the popular parameter' do
context 'with popular=1' do
it 'returns a list of available popular license templates' do
get api("#{path}?popular=1")
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
expect(json_response.map { |l| l['key'] }).to include('apache-2.0')
end
end
end
end
shared_examples_for 'GET licenses/:name' do |path|
context 'with :project and :fullname given' do
before do
get api("#{path}/#{license_type}?project=My+Awesome+Project&fullname=Anton+#{license_type.upcase}")
end
context 'for the mit license' do
let(:license_type) { 'mit' }
it 'returns the license text' do
expect(json_response['content']).to include('The MIT License (MIT)')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} Anton")
end
end
context 'for the agpl-3.0 license' do
let(:license_type) { 'agpl-3.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU AFFERO GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the gpl-3.0 license' do
let(:license_type) { 'gpl-3.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the gpl-2.0 license' do
let(:license_type) { 'gpl-2.0' }
it 'returns the license text' do
expect(json_response['content']).to include('GNU GENERAL PUBLIC LICENSE')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include('My Awesome Project')
expect(json_response['content']).to include("Copyright (C) #{Time.now.year} Anton")
end
end
context 'for the apache-2.0 license' do
let(:license_type) { 'apache-2.0' }
it 'returns the license text' do
expect(json_response['content']).to include('Apache License')
end
it 'replaces placeholder values' do
expect(json_response['content']).to include("Copyright #{Time.now.year} Anton")
end
end
context 'for an uknown license' do
let(:license_type) { 'muth-over9000' }
it 'returns a 404' do
expect(response).to have_http_status(404)
end
end
end
context 'with no :fullname given' do
context 'with an authenticated user' do
let(:user) { create(:user) }
it 'replaces the copyright owner placeholder with the name of the current user' do
get api('/templates/licenses/mit', user)
expect(json_response['content']).to include("Copyright (c) #{Time.now.year} #{user.name}")
end
end
end
end
describe 'with /templates namespace' do
it_behaves_like 'the Template Entity', '/templates/gitignores/Ruby'
it_behaves_like 'the TemplateList Entity', '/templates/gitignores'
it_behaves_like 'requesting gitignores', '/templates/gitignores'
it_behaves_like 'requesting gitlab-ci-ymls', '/templates/gitlab_ci_ymls'
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/templates/gitlab_ci_ymls/Ruby'
it_behaves_like 'the License Template Entity', '/templates/licenses/mit'
it_behaves_like 'GET licenses', '/templates/licenses'
it_behaves_like 'GET licenses/:name', '/templates/licenses'
end
describe 'without /templates namespace' do
it_behaves_like 'the Template Entity', '/gitignores/Ruby'
it_behaves_like 'the TemplateList Entity', '/gitignores'
it_behaves_like 'requesting gitignores', '/gitignores'
it_behaves_like 'requesting gitlab-ci-ymls', '/gitlab_ci_ymls'
it_behaves_like 'requesting gitlab-ci-yml for Ruby', '/gitlab_ci_ymls/Ruby'
it_behaves_like 'the License Template Entity', '/licenses/mit'
it_behaves_like 'GET licenses', '/licenses'
it_behaves_like 'GET licenses/:name', '/licenses'
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