Commit 2f2ad9ea authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'master' into feature/improve-mrwbs-and-todos-for-pipelines

* master:
  Update health_check gem to `~> 2.2.0`
  API: Version information
  Revert "Merge branch 'tests-use-tmpfs' into 'master'"
  Added documentation chapter for Git attributes
  Use activerecord_sane_schema_dumper
  Add a separate stage for bundle check
  Add a bundle check step to ensure dependencies are correct
  Create a new /templates API namespace
  Add disabled delete button to protected branches
  Make spec deterministic
  refactors tests because of gitlab-test repository changes
  Addresses Robert's feedback
  Speed up specs for GET /projects/:id/events
  API: New /users/:id/events endpoint
  writes tests to verify the issue is solved and fixes breaking issues.
  removes inconsistency regarding tagging immediately as merged once you create a branch using new branch button and adds changelog entry
parents 2e3bc854 58e2b44a
...@@ -19,8 +19,6 @@ variables: ...@@ -19,8 +19,6 @@ variables:
before_script: before_script:
- source ./scripts/prepare_build.sh - source ./scripts/prepare_build.sh
- cp config/gitlab.yml.example config/gitlab.yml - cp config/gitlab.yml.example config/gitlab.yml
- mkdir -p tmp/tests
- mount -t tmpfs tmpfs tmp/tests || echo "tmpfs mount failed, falling back to disc"
- bundle --version - bundle --version
- '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"' - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"'
- retry gem install knapsack - retry gem install knapsack
...@@ -257,6 +255,12 @@ lint-doc: ...@@ -257,6 +255,12 @@ lint-doc:
script: script:
- scripts/lint-doc.sh - scripts/lint-doc.sh
bundler:check:
stage: test
<<: *ruby-static-analysis
script:
- bundle check
bundler:audit: bundler:audit:
stage: test stage: test
<<: *ruby-static-analysis <<: *ruby-static-analysis
......
...@@ -15,10 +15,12 @@ v 8.13.0 (unreleased) ...@@ -15,10 +15,12 @@ v 8.13.0 (unreleased)
- Clarify documentation for Runners API (Gennady Trafimenkov) - Clarify documentation for Runners API (Gennady Trafimenkov)
- Change user & group landing page routing from /u/:username to /:username - Change user & group landing page routing from /u/:username to /:username
- Prevent running GfmAutocomplete setup for each diff note !6569 - Prevent running GfmAutocomplete setup for each diff note !6569
- Added documentation for .gitattributes files
- AbstractReferenceFilter caches project_refs on RequestStore when active - AbstractReferenceFilter caches project_refs on RequestStore when active
- Replaced the check sign to arrow in the show build view. !6501 - 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) - 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 - 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 - Speed-up group milestones show page
- Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps) - Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps)
- Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs) - Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs)
...@@ -31,6 +33,7 @@ v 8.13.0 (unreleased) ...@@ -31,6 +33,7 @@ v 8.13.0 (unreleased)
- Cache rendered markdown in the database, rather than Redis - Cache rendered markdown in the database, rather than Redis
- Avoid database queries on Banzai::ReferenceParser::BaseParser for nodes without references - Avoid database queries on Banzai::ReferenceParser::BaseParser for nodes without references
- Simplify Mentionable concern instance methods - Simplify Mentionable concern instance methods
- API: Ability to retrieve version information (Robert Schilling)
- Fix permission for setting an issue's due date - Fix permission for setting an issue's due date
- API: Multi-file commit !6096 (mahcsig) - API: Multi-file commit !6096 (mahcsig)
- Revert "Label list shows all issues (opened or closed) with that label" - Revert "Label list shows all issues (opened or closed) with that label"
...@@ -71,8 +74,10 @@ v 8.13.0 (unreleased) ...@@ -71,8 +74,10 @@ v 8.13.0 (unreleased)
- Fix Long commit messages overflow viewport in file tree - Fix Long commit messages overflow viewport in file tree
- Revert avoid touching file system on Build#artifacts? - Revert avoid touching file system on Build#artifacts?
- Stop using a Redis lease when updating the project activity timestamp whenever a new event is created - Stop using a Redis lease when updating the project activity timestamp whenever a new event is created
- Add disabled delete button to protected branches (ClemMakesApps)
- Add broadcast messages and alerts below sub-nav - Add broadcast messages and alerts below sub-nav
- Better empty state for Groups view - Better empty state for Groups view
- API: New /users/:id/events endpoint
- Update ruby-prof to 0.16.2. !6026 (Elan Ruusamäe) - Update ruby-prof to 0.16.2. !6026 (Elan Ruusamäe)
- Replace bootstrap caret with fontawesome caret (ClemMakesApps) - Replace bootstrap caret with fontawesome caret (ClemMakesApps)
- Fix unnecessary escaping of reserved HTML characters in milestone title. !6533 - Fix unnecessary escaping of reserved HTML characters in milestone title. !6533
...@@ -151,6 +156,7 @@ v 8.12.1 ...@@ -151,6 +156,7 @@ v 8.12.1
- Fix issue with search filter labels not displaying - Fix issue with search filter labels not displaying
v 8.12.0 v 8.12.0
- Removes inconsistency regarding tagging immediatelly as merged once you create a new branch. !6408
- Update the rouge gem to 2.0.6, which adds highlighting support for JSX, Prometheus, and others. !6251 - Update the rouge gem to 2.0.6, which adds highlighting support for JSX, Prometheus, and others. !6251
- Only check :can_resolve permission if the note is resolvable - Only check :can_resolve permission if the note is resolvable
- Bump fog-aws to v0.11.0 to support ap-south-1 region - Bump fog-aws to v0.11.0 to support ap-south-1 region
......
...@@ -262,6 +262,8 @@ group :development do ...@@ -262,6 +262,8 @@ group :development do
# thin instead webrick # thin instead webrick
gem 'thin', '~> 1.7.0' gem 'thin', '~> 1.7.0'
gem 'activerecord_sane_schema_dumper', '0.2'
end end
group :development, :test do group :development, :test do
...@@ -341,7 +343,7 @@ gem 'oauth2', '~> 1.2.0' ...@@ -341,7 +343,7 @@ gem 'oauth2', '~> 1.2.0'
gem 'paranoia', '~> 2.0' gem 'paranoia', '~> 2.0'
# Health check # Health check
gem 'health_check', '~> 2.1.0' gem 'health_check', '~> 2.2.0'
# System information # System information
gem 'vmstat', '~> 2.2' gem 'vmstat', '~> 2.2'
......
...@@ -38,6 +38,8 @@ GEM ...@@ -38,6 +38,8 @@ GEM
multi_json (~> 1.11, >= 1.11.2) multi_json (~> 1.11, >= 1.11.2)
rack (>= 1.5.2, < 3) rack (>= 1.5.2, < 3)
railties (>= 4.0, < 5.1) railties (>= 4.0, < 5.1)
activerecord_sane_schema_dumper (0.2)
rails (>= 4, < 5)
activesupport (4.2.7.1) activesupport (4.2.7.1)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
...@@ -334,7 +336,7 @@ GEM ...@@ -334,7 +336,7 @@ GEM
thor thor
tilt tilt
hashie (3.4.4) hashie (3.4.4)
health_check (2.1.0) health_check (2.2.1)
rails (>= 4.0) rails (>= 4.0)
hipchat (1.5.2) hipchat (1.5.2)
httparty httparty
...@@ -805,6 +807,7 @@ DEPENDENCIES ...@@ -805,6 +807,7 @@ DEPENDENCIES
RedCloth (~> 4.3.2) RedCloth (~> 4.3.2)
ace-rails-ap (~> 4.1.0) ace-rails-ap (~> 4.1.0)
activerecord-session_store (~> 1.0.0) activerecord-session_store (~> 1.0.0)
activerecord_sane_schema_dumper (= 0.2)
acts-as-taggable-on (~> 4.0) acts-as-taggable-on (~> 4.0)
addressable (~> 2.3.8) addressable (~> 2.3.8)
after_commit_queue (~> 1.3.0) after_commit_queue (~> 1.3.0)
...@@ -872,7 +875,7 @@ DEPENDENCIES ...@@ -872,7 +875,7 @@ DEPENDENCIES
grape-entity (~> 0.4.2) grape-entity (~> 0.4.2)
haml_lint (~> 0.18.2) haml_lint (~> 0.18.2)
hamlit (~> 2.6.1) hamlit (~> 2.6.1)
health_check (~> 2.1.0) health_check (~> 2.2.0)
hipchat (~> 1.5.0) hipchat (~> 1.5.0)
html-pipeline (~> 1.11.0) html-pipeline (~> 1.11.0)
httparty (~> 0.13.3) httparty (~> 0.13.3)
......
...@@ -6,11 +6,10 @@ ...@@ -6,11 +6,10 @@
groupProjectsPath: "/api/:version/groups/:id/projects.json", groupProjectsPath: "/api/:version/groups/:id/projects.json",
projectsPath: "/api/:version/projects.json?simple=true", projectsPath: "/api/:version/projects.json?simple=true",
labelsPath: "/:namespace_path/:project_path/labels", labelsPath: "/:namespace_path/:project_path/labels",
licensePath: "/api/:version/licenses/:key", licensePath: "/api/:version/templates/licenses/:key",
gitignorePath: "/api/:version/gitignores/:key", gitignorePath: "/api/:version/templates/gitignores/:key",
gitlabCiYmlPath: "/api/:version/gitlab_ci_ymls/:key", gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key",
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key", issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key",
group: function(group_id, callback) { group: function(group_id, callback) {
var url = Api.buildUrl(Api.groupPath) var url = Api.buildUrl(Api.groupPath)
.replace(':id', group_id); .replace(':id', group_id);
......
...@@ -1016,7 +1016,8 @@ class Repository ...@@ -1016,7 +1016,8 @@ class Repository
root_ref_commit = commit(root_ref) root_ref_commit = commit(root_ref)
if branch_commit if branch_commit
is_ancestor?(branch_commit.id, root_ref_commit.id) same_head = branch_commit.id == root_ref_commit.id
!same_head && is_ancestor?(branch_commit.id, root_ref_commit.id)
else else
nil nil
end end
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
= render 'projects/buttons/download', project: @project, ref: branch.name = render 'projects/buttons/download', project: @project, ref: branch.name
- if can_remove_branch?(@project, branch.name) - if can?(current_user, :push_code, @project)
= link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: 'btn btn-remove remove-row has-tooltip', title: "Delete branch", method: :delete, data: { confirm: "Deleting the '#{branch.name}' branch cannot be undone. Are you sure?", container: 'body' }, remote: true do = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: "btn btn-remove remove-row has-tooltip #{can_remove_branch?(@project, branch.name) ? '' : 'disabled'}", title: "Delete branch", method: :delete, data: { confirm: "Deleting the '#{branch.name}' branch cannot be undone. Are you sure?", container: 'body' }, remote: true do
= icon("trash-o") = icon("trash-o")
- if branch.name != @repository.root_ref - if branch.name != @repository.root_ref
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
- [Webhooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. - [Webhooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project.
- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. - [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN.
- [University](university/README.md) Learn Git and GitLab through videos and courses. - [University](university/README.md) Learn Git and GitLab through videos and courses.
- [Git Attributes](user/project/git_attributes.md) Managing Git attributes using a `.gitattributes` file.
## Administrator documentation ## Administrator documentation
......
...@@ -17,6 +17,8 @@ following locations: ...@@ -17,6 +17,8 @@ following locations:
- [Commits](commits.md) - [Commits](commits.md)
- [Deployments](deployments.md) - [Deployments](deployments.md)
- [Deploy Keys](deploy_keys.md) - [Deploy Keys](deploy_keys.md)
- [Gitignores templates](templates/gitignores.md)
- [GitLab CI Config templates](templates/gitlab_ci_ymls.md)
- [Groups](groups.md) - [Groups](groups.md)
- [Group Access Requests](access_requests.md) - [Group Access Requests](access_requests.md)
- [Group Members](members.md) - [Group Members](members.md)
...@@ -25,7 +27,7 @@ following locations: ...@@ -25,7 +27,7 @@ following locations:
- [Labels](labels.md) - [Labels](labels.md)
- [Merge Requests](merge_requests.md) - [Merge Requests](merge_requests.md)
- [Milestones](milestones.md) - [Milestones](milestones.md)
- [Open source license templates](licenses.md) - [Open source license templates](templates/licenses.md)
- [Namespaces](namespaces.md) - [Namespaces](namespaces.md)
- [Notes](notes.md) (comments) - [Notes](notes.md) (comments)
- [Notification settings](notification_settings.md) - [Notification settings](notification_settings.md)
...@@ -46,6 +48,7 @@ following locations: ...@@ -46,6 +48,7 @@ following locations:
- [Todos](todos.md) - [Todos](todos.md)
- [Users](users.md) - [Users](users.md)
- [Validate CI configuration](ci/lint.md) - [Validate CI configuration](ci/lint.md)
- [Version](version.md)
### Internal CI API ### Internal CI API
......
...@@ -436,7 +436,7 @@ Parameters: ...@@ -436,7 +436,7 @@ Parameters:
### Get project events ### Get project events
Get the events for the specified project. Get the events for the specified project.
Sorted from newest to latest Sorted from newest to oldest
``` ```
GET /projects/:id/events GET /projects/:id/events
......
# 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 @@ ...@@ -5,7 +5,7 @@
Get all license templates. Get all license templates.
``` ```
GET /licenses GET /templates/licenses
``` ```
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
...@@ -13,7 +13,7 @@ GET /licenses ...@@ -13,7 +13,7 @@ GET /licenses
| `popular` | boolean | no | If passed, returns only popular licenses | | `popular` | boolean | no | If passed, returns only popular licenses |
```bash ```bash
curl https://gitlab.example.com/api/v3/licenses?popular=1 curl https://gitlab.example.com/api/v3/templates/licenses?popular=1
``` ```
Example response: Example response:
...@@ -102,7 +102,7 @@ Get a single license template. You can pass parameters to replace the license ...@@ -102,7 +102,7 @@ Get a single license template. You can pass parameters to replace the license
placeholder. placeholder.
``` ```
GET /licenses/:key GET /templates/licenses/:key
``` ```
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
...@@ -116,7 +116,7 @@ If you omit the `fullname` parameter but authenticate your request, the name of ...@@ -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. the authenticated user will be used to replace the copyright holder placeholder.
```bash ```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: Example response:
......
...@@ -627,3 +627,149 @@ Parameters: ...@@ -627,3 +627,149 @@ Parameters:
Will return `200 OK` on success, `404 User Not Found` is user cannot be found or Will return `200 OK` on success, `404 User Not Found` is user cannot be found or
`403 Forbidden` when trying to unblock a user blocked by LDAP synchronization. `403 Forbidden` when trying to unblock a user blocked by LDAP synchronization.
### Get user contribution events
Get the contribution events for the specified user, sorted from newest to oldest.
```
GET /users/:id/events
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the user |
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/user/:id/events
```
Example response:
```json
[
{
"title": null,
"project_id": 15,
"action_name": "closed",
"target_id": 830,
"target_type": "Issue",
"author_id": 1,
"data": null,
"target_title": "Public project search field",
"author": {
"name": "Dmitriy Zaporozhets",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
"web_url": "http://localhost:3000/u/root"
},
"author_username": "root"
},
{
"title": null,
"project_id": 15,
"action_name": "opened",
"target_id": null,
"target_type": null,
"author_id": 1,
"author": {
"name": "Dmitriy Zaporozhets",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
"web_url": "http://localhost:3000/u/root"
},
"author_username": "john",
"data": {
"before": "50d4420237a9de7be1304607147aec22e4a14af7",
"after": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
"ref": "refs/heads/master",
"user_id": 1,
"user_name": "Dmitriy Zaporozhets",
"repository": {
"name": "gitlabhq",
"url": "git@dev.gitlab.org:gitlab/gitlabhq.git",
"description": "GitLab: self hosted Git management software. \r\nDistributed under the MIT License.",
"homepage": "https://dev.gitlab.org/gitlab/gitlabhq"
},
"commits": [
{
"id": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
"message": "Add simple search to projects in public area",
"timestamp": "2013-05-13T18:18:08+00:00",
"url": "https://dev.gitlab.org/gitlab/gitlabhq/commit/c5feabde2d8cd023215af4d2ceeb7a64839fc428",
"author": {
"name": "Dmitriy Zaporozhets",
"email": "dmitriy.zaporozhets@gmail.com"
}
}
],
"total_commits_count": 1
},
"target_title": null
},
{
"title": null,
"project_id": 15,
"action_name": "closed",
"target_id": 840,
"target_type": "Issue",
"author_id": 1,
"data": null,
"target_title": "Finish & merge Code search PR",
"author": {
"name": "Dmitriy Zaporozhets",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
"web_url": "http://localhost:3000/u/root"
},
"author_username": "root"
},
{
"title": null,
"project_id": 15,
"action_name": "commented on",
"target_id": 1312,
"target_type": "Note",
"author_id": 1,
"data": null,
"target_title": null,
"created_at": "2015-12-04T10:33:58.089Z",
"note": {
"id": 1312,
"body": "What an awesome day!",
"attachment": null,
"author": {
"name": "Dmitriy Zaporozhets",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
"web_url": "http://localhost:3000/u/root"
},
"created_at": "2015-12-04T10:33:56.698Z",
"system": false,
"upvote": false,
"downvote": false,
"noteable_id": 377,
"noteable_type": "Issue"
},
"author": {
"name": "Dmitriy Zaporozhets",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
"web_url": "http://localhost:3000/u/root"
},
"author_username": "root"
}
]
```
# Version API
>**Note:** This feature was introduced in GitLab 8.13
Retrieve version information for this GitLab instance. Responds `200 OK` for
authenticated users.
```
GET /version
```
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/version
```
Example response:
```json
{
"version": "8.13.0-pre",
"revision": "4e963fe"
}
```
# Git Attributes
GitLab supports defining custom [Git attributes][gitattributes] such as what
files to treat as binary, and what language to use for syntax highlighting
diffs.
To define these attributes, create a file called `.gitattributes` in the root
directory of your repository and push it to the default branch of your project.
## Encoding Requirements
The `.gitattributes` file _must_ be encoded in UTF-8 and _must not_ contain a
Byte Order Mark. If a different encoding is used, the file's contents will be
ignored.
## Syntax Highlighting
The `.gitattributes` file can be used to define which language to use when
syntax highlighting files and diffs. See ["Syntax
Highlighting"](highlighting.md) for more information.
[gitattributes]: https://git-scm.com/docs/gitattributes
...@@ -46,7 +46,6 @@ module API ...@@ -46,7 +46,6 @@ module API
mount ::API::Boards mount ::API::Boards
mount ::API::Keys mount ::API::Keys
mount ::API::Labels mount ::API::Labels
mount ::API::LicenseTemplates
mount ::API::Lint mount ::API::Lint
mount ::API::Members mount ::API::Members
mount ::API::MergeRequests mount ::API::MergeRequests
...@@ -73,6 +72,7 @@ module API ...@@ -73,6 +72,7 @@ module API
mount ::API::Triggers mount ::API::Triggers
mount ::API::Users mount ::API::Users
mount ::API::Variables mount ::API::Variables
mount ::API::Version
route :any, '*path' do route :any, '*path' do
error!('404 Not Found', 404) error!('404 Not Found', 404)
......
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 module API
class Templates < Grape::API class Templates < Grape::API
GLOBAL_TEMPLATE_TYPES = { GLOBAL_TEMPLATE_TYPES = {
gitignores: Gitlab::Template::GitignoreTemplate, gitignores: {
gitlab_ci_ymls: Gitlab::Template::GitlabCiYmlTemplate klass: Gitlab::Template::GitignoreTemplate,
gitlab_version: 8.8
},
gitlab_ci_ymls: {
klass: Gitlab::Template::GitlabCiYmlTemplate,
gitlab_version: 8.9
}
}.freeze }.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 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) def render_response(template_type, template)
not_found!(template_type.to_s.singularize) unless template not_found!(template_type.to_s.singularize) unless template
present template, with: Entities::Template present template, with: Entities::Template
end end
end end
GLOBAL_TEMPLATE_TYPES.each do |template_type, klass| { "licenses" => :deprecated, "templates/licenses" => :ok }.each do |route, status|
# Get the list of the available template desc 'Get the list of the available license template' do
# detailed_desc = 'This feature was introduced in GitLab 8.7.'
# Example Request: detailed_desc << DEPRECATION_MESSAGE unless status == :ok
# GET /gitignores detail detailed_desc
# GET /gitlab_ci_ymls success Entities::RepoLicense
get template_type.to_s do 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 present klass.all, with: Entities::TemplatesList
end 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) render_response(template_type, new_template)
end end
end end
end end
end
end end
...@@ -321,6 +321,26 @@ module API ...@@ -321,6 +321,26 @@ module API
user.activate user.activate
end end
end end
desc 'Get contribution events of a specified user' do
detail 'This feature was introduced in GitLab 8.13.'
success Entities::Event
end
params do
requires :id, type: String, desc: 'The user ID'
end
get ':id/events' do
user = User.find_by(id: declared(params).id)
not_found!('User') unless user
events = user.recent_events.
merge(ProjectsFinder.new.execute(current_user)).
references(:project).
with_associations.
page(params[:page])
present paginate(events), with: Entities::Event
end
end end
resource :user do resource :user do
......
module API
class Version < Grape::API
before { authenticate! }
desc 'Get the version information of the GitLab instance.' do
detail 'This feature was introduced in GitLab 8.13.'
end
get '/version' do
{ version: Gitlab::VERSION, revision: Gitlab::REVISION }
end
end
end
...@@ -102,15 +102,16 @@ describe Projects::CommitController do ...@@ -102,15 +102,16 @@ describe Projects::CommitController do
describe "as patch" do describe "as patch" do
include_examples "export as", :patch include_examples "export as", :patch
let(:format) { :patch } let(:format) { :patch }
let(:commit2) { project.commit('498214de67004b1da3d820901307bed2a68a8ef6') }
it "is a git email patch" do it "is a git email patch" do
go(id: commit.id, format: format) go(id: commit2.id, format: format)
expect(response.body).to start_with("From #{commit.id}") expect(response.body).to start_with("From #{commit2.id}")
end end
it "contains a git diff" do it "contains a git diff" do
go(id: commit.id, format: format) go(id: commit2.id, format: format)
expect(response.body).to match(/^diff --git/) expect(response.body).to match(/^diff --git/)
end end
...@@ -135,6 +136,8 @@ describe Projects::CommitController do ...@@ -135,6 +136,8 @@ describe Projects::CommitController do
describe "GET branches" do describe "GET branches" do
it "contains branch and tags information" do it "contains branch and tags information" do
commit = project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
get(:branches, get(:branches,
namespace_id: project.namespace.to_param, namespace_id: project.namespace.to_param,
project_id: project.to_param, project_id: project.to_param,
...@@ -254,16 +257,17 @@ describe Projects::CommitController do ...@@ -254,16 +257,17 @@ describe Projects::CommitController do
end end
let(:existing_path) { '.gitmodules' } let(:existing_path) { '.gitmodules' }
let(:commit2) { project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e') }
context 'when the commit exists' do context 'when the commit exists' do
context 'when the user has access to the project' do context 'when the user has access to the project' do
context 'when the path exists in the diff' do context 'when the path exists in the diff' do
it 'enables diff notes' do it 'enables diff notes' do
diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path) diff_for_path(id: commit2.id, old_path: existing_path, new_path: existing_path)
expect(assigns(:diff_notes_disabled)).to be_falsey expect(assigns(:diff_notes_disabled)).to be_falsey
expect(assigns(:comments_target)).to eq(noteable_type: 'Commit', expect(assigns(:comments_target)).to eq(noteable_type: 'Commit',
commit_id: commit.id) commit_id: commit2.id)
end end
it 'only renders the diffs for the path given' do it 'only renders the diffs for the path given' do
...@@ -272,7 +276,7 @@ describe Projects::CommitController do ...@@ -272,7 +276,7 @@ describe Projects::CommitController do
meth.call(diffs) meth.call(diffs)
end end
diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path) diff_for_path(id: commit2.id, old_path: existing_path, new_path: existing_path)
end end
end end
......
...@@ -19,7 +19,7 @@ describe SearchHelper do ...@@ -19,7 +19,7 @@ describe SearchHelper do
expect(subject.filename).to eq('CHANGELOG') expect(subject.filename).to eq('CHANGELOG')
expect(subject.basename).to eq('CHANGELOG') expect(subject.basename).to eq('CHANGELOG')
expect(subject.ref).to eq('master') expect(subject.ref).to eq('master')
expect(subject.startline).to eq(186) expect(subject.startline).to eq(188)
expect(subject.data.lines[2]).to eq(" - Feature: Replace teams with group membership\n") expect(subject.data.lines[2]).to eq(" - Feature: Replace teams with group membership\n")
end end
......
...@@ -8,13 +8,13 @@ describe Gitlab::DataBuilder::Push, lib: true do ...@@ -8,13 +8,13 @@ describe Gitlab::DataBuilder::Push, lib: true do
let(:data) { described_class.build_sample(project, user) } let(:data) { described_class.build_sample(project, user) }
it { expect(data).to be_a(Hash) } it { expect(data).to be_a(Hash) }
it { expect(data[:before]).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } it { expect(data[:before]).to eq('1b12f15a11fc6e62177bef08f47bc7b5ce50b141') }
it { expect(data[:after]).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') } it { expect(data[:after]).to eq('b83d6e391c22777fca1ed3012fce84f633d7fed0') }
it { expect(data[:ref]).to eq('refs/heads/master') } it { expect(data[:ref]).to eq('refs/heads/master') }
it { expect(data[:commits].size).to eq(3) } it { expect(data[:commits].size).to eq(3) }
it { expect(data[:total_commits_count]).to eq(3) } it { expect(data[:total_commits_count]).to eq(3) }
it { expect(data[:commits].first[:added]).to eq(['gitlab-grack']) } it { expect(data[:commits].first[:added]).to eq(['bar/branch-test.txt']) }
it { expect(data[:commits].first[:modified]).to eq(['.gitmodules']) } it { expect(data[:commits].first[:modified]).to eq([]) }
it { expect(data[:commits].first[:removed]).to eq([]) } it { expect(data[:commits].first[:removed]).to eq([]) }
include_examples 'project hook data with deprecateds' include_examples 'project hook data with deprecateds'
......
...@@ -628,7 +628,7 @@ describe Notify do ...@@ -628,7 +628,7 @@ describe Notify do
it_behaves_like 'a user cannot unsubscribe through footer link' it_behaves_like 'a user cannot unsubscribe through footer link'
it 'has the correct subject' do it 'has the correct subject' do
is_expected.to have_subject /#{commit.title} \(#{commit.short_id}\)/ is_expected.to have_subject /Re: #{project.name} | #{commit.title} \(#{commit.short_id}\)/
end end
it 'contains a link to the commit' do it 'contains a link to the commit' do
......
...@@ -164,10 +164,10 @@ eos ...@@ -164,10 +164,10 @@ eos
let(:data) { commit.hook_attrs(with_changed_files: true) } let(:data) { commit.hook_attrs(with_changed_files: true) }
it { expect(data).to be_a(Hash) } it { expect(data).to be_a(Hash) }
it { expect(data[:message]).to include('Add submodule from gitlab.com') } it { expect(data[:message]).to include('adds bar folder and branch-test text file to check Repository merged_to_root_ref method') }
it { expect(data[:timestamp]).to eq('2014-02-27T11:01:38+02:00') } it { expect(data[:timestamp]).to eq('2016-09-27T14:37:46+00:00') }
it { expect(data[:added]).to eq(["gitlab-grack"]) } it { expect(data[:added]).to eq(["bar/branch-test.txt"]) }
it { expect(data[:modified]).to eq([".gitmodules"]) } it { expect(data[:modified]).to eq([]) }
it { expect(data[:removed]).to eq([]) } it { expect(data[:removed]).to eq([]) }
end end
......
...@@ -6,9 +6,9 @@ describe MergeRequestDiff, models: true do ...@@ -6,9 +6,9 @@ describe MergeRequestDiff, models: true do
it { expect(subject).to be_valid } it { expect(subject).to be_valid }
it { expect(subject).to be_persisted } it { expect(subject).to be_persisted }
it { expect(subject.commits.count).to eq(5) } it { expect(subject.commits.count).to eq(29) }
it { expect(subject.diffs.count).to eq(8) } it { expect(subject.diffs.count).to eq(20) }
it { expect(subject.head_commit_sha).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') } it { expect(subject.head_commit_sha).to eq('b83d6e391c22777fca1ed3012fce84f633d7fed0') }
it { expect(subject.base_commit_sha).to eq('ae73cb07c9eeaf35924a10f713b364d32b2dd34f') } it { expect(subject.base_commit_sha).to eq('ae73cb07c9eeaf35924a10f713b364d32b2dd34f') }
it { expect(subject.start_commit_sha).to eq('0b4bc9a49b562e85de7cc9e834518ea6828729b9') } it { expect(subject.start_commit_sha).to eq('0b4bc9a49b562e85de7cc9e834518ea6828729b9') }
end end
......
...@@ -489,7 +489,7 @@ describe MergeRequest, models: true do ...@@ -489,7 +489,7 @@ describe MergeRequest, models: true do
subject(:merge_request_with_divergence) { create(:merge_request, :diverged, source_project: project, target_project: project) } subject(:merge_request_with_divergence) { create(:merge_request, :diverged, source_project: project, target_project: project) }
it 'counts commits that are on target branch but not on source branch' do it 'counts commits that are on target branch but not on source branch' do
expect(subject.diverged_commits_count).to eq(5) expect(subject.diverged_commits_count).to eq(29)
end end
end end
...@@ -497,7 +497,7 @@ describe MergeRequest, models: true do ...@@ -497,7 +497,7 @@ describe MergeRequest, models: true do
subject(:merge_request_fork_with_divergence) { create(:merge_request, :diverged, source_project: fork_project, target_project: project) } subject(:merge_request_fork_with_divergence) { create(:merge_request, :diverged, source_project: fork_project, target_project: project) }
it 'counts commits that are on target branch but not on source branch' do it 'counts commits that are on target branch but not on source branch' do
expect(subject.diverged_commits_count).to eq(5) expect(subject.diverged_commits_count).to eq(29)
end end
end end
......
...@@ -122,11 +122,30 @@ describe Repository, models: true do ...@@ -122,11 +122,30 @@ describe Repository, models: true do
end end
describe '#merged_to_root_ref?' do describe '#merged_to_root_ref?' do
context 'merged branch' do context 'merged branch without ff' do
subject { repository.merged_to_root_ref?('branch-merged') }
it { is_expected.to be_truthy }
end
# If the HEAD was ff then it will be false
context 'merged with ff' do
subject { repository.merged_to_root_ref?('improve/awesome') } subject { repository.merged_to_root_ref?('improve/awesome') }
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
context 'not merged branch' do
subject { repository.merged_to_root_ref?('not-merged-branch') }
it { is_expected.to be_falsey }
end
context 'default branch' do
subject { repository.merged_to_root_ref?('master') }
it { is_expected.to be_falsey }
end
end end
describe '#can_be_merged?' do describe '#can_be_merged?' do
...@@ -324,7 +343,7 @@ describe Repository, models: true do ...@@ -324,7 +343,7 @@ describe Repository, models: true do
subject { results.first } subject { results.first }
it { is_expected.to be_an String } it { is_expected.to be_an String }
it { expect(subject.lines[2]).to eq("master:CHANGELOG:188: - Feature: Replace teams with group membership\n") } it { expect(subject.lines[2]).to eq("master:CHANGELOG:190: - Feature: Replace teams with group membership\n") }
end end
end end
...@@ -968,10 +987,10 @@ describe Repository, models: true do ...@@ -968,10 +987,10 @@ describe Repository, models: true do
context 'cherry-picking a merge commit' do context 'cherry-picking a merge commit' do
it 'cherry-picks the changes' do it 'cherry-picks the changes' do
expect(repository.blob_at_branch('master', 'foo/bar/.gitkeep')).to be_nil expect(repository.blob_at_branch('improve/awesome', 'foo/bar/.gitkeep')).to be_nil
repository.cherry_pick(user, pickable_merge, 'master') repository.cherry_pick(user, pickable_merge, 'improve/awesome')
expect(repository.blob_at_branch('master', 'foo/bar/.gitkeep')).not_to be_nil expect(repository.blob_at_branch('improve/awesome', 'foo/bar/.gitkeep')).not_to be_nil
end end
end end
end end
......
...@@ -53,7 +53,12 @@ describe API::API, api: true do ...@@ -53,7 +53,12 @@ describe API::API, api: true do
get api("/projects/#{project.id}/repository/commits?until=#{before.utc.iso8601}", user) get api("/projects/#{project.id}/repository/commits?until=#{before.utc.iso8601}", user)
if commits.size >= 20
expect(json_response.size).to eq(20)
else
expect(json_response.size).to eq(commits.size - 1) expect(json_response.size).to eq(commits.size - 1)
end
expect(json_response.first["id"]).to eq(commits.second.id) expect(json_response.first["id"]).to eq(commits.second.id)
expect(json_response.second["id"]).to eq(commits.third.id) expect(json_response.second["id"]).to eq(commits.third.id)
end end
...@@ -447,11 +452,12 @@ describe API::API, api: true do ...@@ -447,11 +452,12 @@ describe API::API, api: true do
end end
it 'returns the inline comment' do it 'returns the inline comment' do
post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 7, line_type: 'new' post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new'
expect(response).to have_http_status(201) expect(response).to have_http_status(201)
expect(json_response['note']).to eq('My comment') expect(json_response['note']).to eq('My comment')
expect(json_response['path']).to eq(project.repository.commit.raw_diffs.first.new_path) expect(json_response['path']).to eq(project.repository.commit.raw_diffs.first.new_path)
expect(json_response['line']).to eq(7) expect(json_response['line']).to eq(1)
expect(json_response['line_type']).to eq('new') expect(json_response['line_type']).to eq('new')
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
...@@ -588,37 +588,39 @@ describe API::API, api: true do ...@@ -588,37 +588,39 @@ describe API::API, api: true do
before do before do
note = create(:note_on_issue, note: 'What an awesome day!', project: project) note = create(:note_on_issue, note: 'What an awesome day!', project: project)
EventCreateService.new.leave_note(note, note.author) EventCreateService.new.leave_note(note, note.author)
get api("/projects/#{project.id}/events", user)
end end
it { expect(response).to have_http_status(200) } it 'returns all events' do
get api("/projects/#{project.id}/events", user)
context 'joined event' do expect(response).to have_http_status(200)
let(:json_event) { json_response[1] }
it { expect(json_event['action_name']).to eq('joined') } first_event = json_response.first
it { expect(json_event['project_id'].to_i).to eq(project.id) }
it { expect(json_event['author_username']).to eq(user3.username) }
it { expect(json_event['author']['name']).to eq(user3.name) }
end
context 'comment event' do expect(first_event['action_name']).to eq('commented on')
let(:json_event) { json_response.first } expect(first_event['note']['body']).to eq('What an awesome day!')
it { expect(json_event['action_name']).to eq('commented on') } last_event = json_response.last
it { expect(json_event['note']['body']).to eq('What an awesome day!') }
expect(last_event['action_name']).to eq('joined')
expect(last_event['project_id'].to_i).to eq(project.id)
expect(last_event['author_username']).to eq(user3.username)
expect(last_event['author']['name']).to eq(user3.name)
end end
end end
it 'returns a 404 error if not found' do it 'returns a 404 error if not found' do
get api('/projects/42/events', user) get api('/projects/42/events', user)
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found') expect(json_response['message']).to eq('404 Project Not Found')
end end
it 'returns a 404 error if user is not a member' do it 'returns a 404 error if user is not a member' do
other_user = create(:user) other_user = create(:user)
get api("/projects/#{project.id}/events", other_user) get api("/projects/#{project.id}/events", other_user)
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
end end
......
...@@ -21,7 +21,7 @@ describe API::API, api: true do ...@@ -21,7 +21,7 @@ describe API::API, api: true do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.first['name']).to eq('encoding') expect(json_response.first['name']).to eq('bar')
expect(json_response.first['type']).to eq('tree') expect(json_response.first['type']).to eq('tree')
expect(json_response.first['mode']).to eq('040000') expect(json_response.first['mode']).to eq('040000')
end end
...@@ -166,9 +166,9 @@ describe API::API, api: true do ...@@ -166,9 +166,9 @@ describe API::API, api: true do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response).to be_an Array expect(json_response).to be_an Array
contributor = json_response.first contributor = json_response.first
expect(contributor['email']).to eq('dmitriy.zaporozhets@gmail.com') expect(contributor['email']).to eq('tiagonbotelho@hotmail.com')
expect(contributor['name']).to eq('Dmitriy Zaporozhets') expect(contributor['name']).to eq('tiagonbotelho')
expect(contributor['commits']).to eq(13) expect(contributor['commits']).to eq(1)
expect(contributor['additions']).to eq(0) expect(contributor['additions']).to eq(0)
expect(contributor['deletions']).to eq(0) expect(contributor['deletions']).to eq(0)
end end
......
...@@ -3,53 +3,201 @@ require 'spec_helper' ...@@ -3,53 +3,201 @@ require 'spec_helper'
describe API::Templates, api: true do describe API::Templates, api: true do
include ApiHelpers include ApiHelpers
context 'global templates' do shared_examples_for 'the Template Entity' do |path|
describe 'the Template Entity' do before { get api(path) }
before { get api('/gitignores/Ruby') }
it { expect(json_response['name']).to eq('Ruby') } it { expect(json_response['name']).to eq('Ruby') }
it { expect(json_response['content']).to include('*.gem') } it { expect(json_response['content']).to include('*.gem') }
end end
describe 'the TemplateList Entity' do shared_examples_for 'the TemplateList Entity' do |path|
before { get api('/gitignores') } before { get api(path) }
it { expect(json_response.first['name']).not_to be_nil } it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil } it { expect(json_response.first['content']).to be_nil }
end end
context 'requesting gitignores' do shared_examples_for 'requesting gitignores' do |path|
describe 'GET /gitignores' do
it 'returns a list of available gitignore templates' do 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).to be_an Array
expect(json_response.size).to be > 15 expect(json_response.size).to be > 15
end end
end end
end
context 'requesting gitlab-ci-ymls' do shared_examples_for 'requesting gitlab-ci-ymls' do |path|
describe 'GET /gitlab_ci_ymls' do
it 'returns a list of available gitlab_ci_ymls' do 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).to be_an Array
expect(json_response.first['name']).not_to be_nil expect(json_response.first['name']).not_to be_nil
end end
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 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(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,") expect(json_response['content']).to start_with("# This file is a template,")
end end
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
end end
...@@ -913,4 +913,58 @@ describe API::API, api: true do ...@@ -913,4 +913,58 @@ describe API::API, api: true do
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
end end
describe 'GET /user/:id/events' do
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:note) { create(:note_on_issue, note: 'What an awesome day!', project: project) }
before do
project.add_user(user, :developer)
EventCreateService.new.leave_note(note, user)
end
context "as a user than cannot see the event's project" do
it 'returns no events' do
other_user = create(:user)
get api("/users/#{user.id}/events", other_user)
expect(response).to have_http_status(200)
expect(json_response).to be_empty
end
end
context "as a user than can see the event's project" do
it_behaves_like 'a paginated resources' do
let(:request) { get api("/users/#{user.id}/events", user) }
end
context 'joined event' do
it 'returns the "joined" event' do
get api("/users/#{user.id}/events", user)
comment_event = json_response.find { |e| e['action_name'] == 'commented on' }
expect(comment_event['project_id'].to_i).to eq(project.id)
expect(comment_event['author_username']).to eq(user.username)
expect(comment_event['note']['id']).to eq(note.id)
expect(comment_event['note']['body']).to eq('What an awesome day!')
joined_event = json_response.find { |e| e['action_name'] == 'joined' }
expect(joined_event['project_id'].to_i).to eq(project.id)
expect(joined_event['author_username']).to eq(user.username)
expect(joined_event['author']['name']).to eq(user.name)
end
end
end
it 'returns a 404 error if not found' do
get api('/users/42/events', user)
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
end
end end
require 'spec_helper'
describe API::API, api: true do
include ApiHelpers
describe 'GET /version' do
context 'when unauthenticated' do
it 'returns authentication error' do
get api('/version')
expect(response).to have_http_status(401)
end
end
context 'when authenticated' do
let(:user) { create(:user) }
it 'returns the version information' do
get api('/version', user)
expect(response).to have_http_status(200)
expect(json_response['version']).to eq(Gitlab::VERSION)
expect(json_response['revision']).to eq(Gitlab::REVISION)
end
end
end
end
...@@ -439,8 +439,8 @@ describe 'Git HTTP requests', lib: true do ...@@ -439,8 +439,8 @@ describe 'Git HTTP requests', lib: true do
before do before do
# Provide a dummy file in its place # Provide a dummy file in its place
allow_any_instance_of(Repository).to receive(:blob_at).and_call_original allow_any_instance_of(Repository).to receive(:blob_at).and_call_original
allow_any_instance_of(Repository).to receive(:blob_at).with('5937ac0a7beb003549fc5fd26fc247adbce4a52e', 'info/refs') do allow_any_instance_of(Repository).to receive(:blob_at).with('b83d6e391c22777fca1ed3012fce84f633d7fed0', 'info/refs') do
Gitlab::Git::Blob.find(project.repository, 'master', '.gitignore') Gitlab::Git::Blob.find(project.repository, 'master', 'bar/branch-test.txt')
end end
get "/#{project.path_with_namespace}/blob/master/info/refs" get "/#{project.path_with_namespace}/blob/master/info/refs"
......
...@@ -118,7 +118,7 @@ describe MergeRequests::RefreshService, services: true do ...@@ -118,7 +118,7 @@ describe MergeRequests::RefreshService, services: true do
it { expect(@merge_request.notes).to be_empty } it { expect(@merge_request.notes).to be_empty }
it { expect(@merge_request).to be_open } it { expect(@merge_request).to be_open }
it { expect(@fork_merge_request.notes.last.note).to include('Added 4 commits') } it { expect(@fork_merge_request.notes.last.note).to include('Added 28 commits') }
it { expect(@fork_merge_request).to be_open } it { expect(@fork_merge_request).to be_open }
it { expect(@build_failed_todo).to be_pending } it { expect(@build_failed_todo).to be_pending }
it { expect(@fork_build_failed_todo).to be_pending } it { expect(@fork_build_failed_todo).to be_pending }
...@@ -169,7 +169,7 @@ describe MergeRequests::RefreshService, services: true do ...@@ -169,7 +169,7 @@ describe MergeRequests::RefreshService, services: true do
notes = @fork_merge_request.notes.reorder(:created_at).map(&:note) notes = @fork_merge_request.notes.reorder(:created_at).map(&:note)
expect(notes[0]).to include('Restored source branch `master`') expect(notes[0]).to include('Restored source branch `master`')
expect(notes[1]).to include('Added 4 commits') expect(notes[1]).to include('Added 28 commits')
expect(@fork_merge_request).to be_open expect(@fork_merge_request).to be_open
end end
end end
......
...@@ -54,7 +54,7 @@ describe SystemNoteService, services: true do ...@@ -54,7 +54,7 @@ describe SystemNoteService, services: true do
it 'adds a message line for each commit' do it 'adds a message line for each commit' do
new_commits.each_with_index do |commit, i| new_commits.each_with_index do |commit, i|
# Skip the header # Skip the header
expect(note_lines[i + 1]).to eq "* #{commit.short_id} - #{commit.title}" expect(HTMLEntities.new.decode(note_lines[i + 1])).to eq "* #{commit.short_id} - #{commit.title}"
end end
end end
end end
...@@ -81,7 +81,7 @@ describe SystemNoteService, services: true do ...@@ -81,7 +81,7 @@ describe SystemNoteService, services: true do
end end
it 'includes a commit count' do it 'includes a commit count' do
expect(summary_line).to end_with " - 2 commits from branch `feature`" expect(summary_line).to end_with " - 26 commits from branch `feature`"
end end
end end
...@@ -91,7 +91,7 @@ describe SystemNoteService, services: true do ...@@ -91,7 +91,7 @@ describe SystemNoteService, services: true do
end end
it 'includes a commit count' do it 'includes a commit count' do
expect(summary_line).to end_with " - 2 commits from branch `feature`" expect(summary_line).to end_with " - 26 commits from branch `feature`"
end end
end end
...@@ -537,7 +537,7 @@ describe SystemNoteService, services: true do ...@@ -537,7 +537,7 @@ describe SystemNoteService, services: true do
let(:mergereq) { create(:merge_request, :simple, target_project: project, source_project: project) } let(:mergereq) { create(:merge_request, :simple, target_project: project, source_project: project) }
let(:jira_issue) { ExternalIssue.new("JIRA-1", project)} let(:jira_issue) { ExternalIssue.new("JIRA-1", project)}
let(:jira_tracker) { project.jira_service } let(:jira_tracker) { project.jira_service }
let(:commit) { project.commit } let(:commit) { project.repository.commits('master').find { |commit| commit.id == '5937ac0a7beb003549fc5fd26fc247adbce4a52e' } }
context 'in JIRA issue tracker' do context 'in JIRA issue tracker' do
before do before do
......
...@@ -50,11 +50,6 @@ RSpec.configure do |config| ...@@ -50,11 +50,6 @@ RSpec.configure do |config|
example.run example.run
Rails.cache = caching_store Rails.cache = caching_store
end end
config.after(:each) do
FileUtils.rm_rf("tmp/tests/repositories")
FileUtils.mkdir_p("tmp/tests/repositories")
end
end end
FactoryGirl::SyntaxRunner.class_eval do FactoryGirl::SyntaxRunner.class_eval do
......
...@@ -5,6 +5,8 @@ module TestEnv ...@@ -5,6 +5,8 @@ module TestEnv
# When developing the seed repository, comment out the branch you will modify. # When developing the seed repository, comment out the branch you will modify.
BRANCH_SHA = { BRANCH_SHA = {
'not-merged-branch' => 'b83d6e3',
'branch-merged' => '498214d',
'empty-branch' => '7efb185', 'empty-branch' => '7efb185',
'ends-with.json' => '98b0d8b', 'ends-with.json' => '98b0d8b',
'flatten-dir' => 'e56497b', 'flatten-dir' => 'e56497b',
...@@ -14,7 +16,7 @@ module TestEnv ...@@ -14,7 +16,7 @@ module TestEnv
'improve/awesome' => '5937ac0', 'improve/awesome' => '5937ac0',
'markdown' => '0ed8c6c', 'markdown' => '0ed8c6c',
'lfs' => 'be93687', 'lfs' => 'be93687',
'master' => '5937ac0', 'master' => 'b83d6e3',
"'test'" => 'e56497b', "'test'" => 'e56497b',
'orphaned-branch' => '45127a9', 'orphaned-branch' => '45127a9',
'binary-encoding' => '7b1cf43', 'binary-encoding' => '7b1cf43',
......
...@@ -57,7 +57,7 @@ describe EmailsOnPushWorker do ...@@ -57,7 +57,7 @@ describe EmailsOnPushWorker do
end end
it "sends a mail with the correct subject" do it "sends a mail with the correct subject" do
expect(email.subject).to include('Change some files') expect(email.subject).to include('adds bar folder and branch-test text file')
end end
it "mentions force pushing in the body" do it "mentions force pushing in the body" do
...@@ -73,7 +73,7 @@ describe EmailsOnPushWorker do ...@@ -73,7 +73,7 @@ describe EmailsOnPushWorker do
before { perform } before { perform }
it "sends a mail with the correct subject" do it "sends a mail with the correct subject" do
expect(email.subject).to include('Change some files') expect(email.subject).to include('adds bar folder and branch-test text file')
end end
it "does not mention force pushing in the body" do it "does not mention force pushing in the body" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment