Merge branch 'release/5.0' into dev

pull/4355/head
Oliver Günther 9 years ago
commit 3848c8aef0
  1. 3
      .rubocop.yml
  2. 2
      Gemfile
  3. 6
      Gemfile.lock
  4. 2
      app/assets/javascripts/tab_handling.js
  5. 2
      app/assets/stylesheets/content/_accounts_mobile.sass
  6. 2
      app/assets/stylesheets/content/_forms_mobile.sass
  7. 2
      app/assets/stylesheets/content/_notifications_mobile.sass
  8. 2
      app/assets/stylesheets/content/_widget_box.sass
  9. 2
      app/assets/stylesheets/content/_wiki.sass
  10. 2
      app/assets/stylesheets/layout/_base_mobile.sass
  11. 2
      app/assets/stylesheets/layout/_drop_down_mobile.sass
  12. 2
      app/assets/stylesheets/layout/_toolbar.sass
  13. 2
      app/assets/stylesheets/layout/_top_menu_mobile.sass
  14. 102
      app/assets/stylesheets/layout/_work_package_mobile.sass
  15. 2
      app/assets/stylesheets/specific/homescreen.sass
  16. 8
      app/controllers/concerns/omniauth_login.rb
  17. 2
      app/controllers/repositories_controller.rb
  18. 2
      app/helpers/application_helper.rb
  19. 2
      app/seeders/composite_seeder.rb
  20. 4
      app/views/homescreen/blocks/_community.html.erb
  21. 4
      app/views/members/index.html.erb
  22. 2
      app/views/repositories/settings/_repository_committers_link.html.erb
  23. 3
      app/views/repositories/settings/_vendor_attribute_groups.html.erb
  24. 34
      doc/operation_guides/docker/installation-guide.md
  25. 47
      spec/controllers/repositories_controller_spec.rb
  26. BIN
      spec/fixtures/repositories/subversion_repository.dump.gz
  27. BIN
      spec/fixtures/repositories/subversion_repository.tar.gz
  28. 24
      spec/lib/open_project/scm/adapters/subversion_adapter_spec.rb
  29. 8
      spec/models/repository/subversion_spec.rb
  30. 8
      spec/routing/repositories_routing_spec.rb
  31. 8
      spec_legacy/unit/repository_subversion_spec.rb

@ -207,9 +207,6 @@ StringLiterals:
VariableInterpolation:
Enabled: false
TrailingComma:
Enabled: false
TrivialAccessors:
Enabled: false

@ -182,7 +182,7 @@ group :ldap do
end
group :development do
gem 'letter_opener', '~> 1.3.0'
gem 'letter_opener'
gem 'thin'
gem 'faker'
gem 'quiet_assets'

@ -181,7 +181,7 @@ GEM
cliver (0.3.2)
cocaine (0.5.7)
climate_control (>= 0.0.3, < 1.0)
codecov (0.0.8)
codecov (0.1.4)
json
simplecov
url
@ -318,7 +318,7 @@ GEM
mini_portile2 (2.0.0)
minitest (5.8.0)
mixlib-shellout (2.1.0)
multi_json (1.11.2)
multi_json (1.11.3)
multi_test (0.1.2)
multi_xml (0.5.5)
mysql2 (0.3.20)
@ -601,7 +601,7 @@ DEPENDENCIES
jruby-openssl
json_spec
launchy (~> 2.3.0)
letter_opener (~> 1.3.0)
letter_opener
multi_json (~> 1.11.0)
mysql2 (~> 0.3.20)
net-ldap (~> 0.8.0)

@ -36,7 +36,7 @@
// Responsible to hide the old selected tab and show the content
// of the currently selected tab.
function showTab(name, url) {
jQuery('div#content .tabs .a .position-label').hide();
jQuery('div#content .tabs .position-label').hide();
jQuery('div#content .tabs #tab-' + name + ' .position-label').show();
jQuery('div#content .tab-content').hide();
jQuery('div.tabs a').removeClass('selected');

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(960px down)
@include breakpoint(680px down)
body.controller-account
#login-form,
#content .login-auth-providers,

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(960px down)
@include breakpoint(680px down)
form
.grid-block
display: block

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(960px down)
@include breakpoint(680px down)
.notification-box--wrapper,
.flash,
#errorExplanation

@ -124,7 +124,7 @@ $widget-box--enumeration-width: 20px
//necessary for correct alignment even with long texts
width: calc(100% - #{$widget-box--enumeration-width})
@include breakpoint(960px down)
@include breakpoint(680px down)
.widget-boxes
&.-flex
.widget-box

@ -196,7 +196,7 @@ blockquote
.toolbar-container ~ .wiki-content
margin-top: -64px
@include breakpoint(960px down)
@include breakpoint(680px down)
.toolbar-container ~ .wiki-content
margin-top: 0

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(960px down)
@include breakpoint(680px down)
html
min-width: 0 !important

@ -30,7 +30,7 @@
// https://github.com/plapier/jquery-dropdown
// (dual MIT/GPL-Licensed)
@include breakpoint(960px down)
@include breakpoint(680px down)
.dropdown .dropdown-menu,
.toolbar .legacy-actions-more
LI > A,

@ -272,7 +272,7 @@
*
outline: none
@include breakpoint(960px down)
@include breakpoint(680px down)
.toolbar-container .toolbar-items
background: #fff
display: flex

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(960px down)
@include breakpoint(680px down)
#logo
background-color: transparent

@ -26,41 +26,45 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(960px down)
@include breakpoint(1248px down)
body.controller-work_packages
&.action-show #content
overflow: visible
&.action-show
overflow: auto !important
overflow-y: scroll !important
.toolbar-container
margin-bottom: 4px
min-height: 0
#main,
#content
position: relative !important
.work-packages--show-view
padding: 0
#main
padding-bottom: 0
#toolbar-items
background: #fff
display: flex
margin-bottom: 20px
width: calc(100% + 5px)
#content
height: 100% !important
overflow: visible
> li
-webkit-flex: 1 0 0
flex: 1 0 0
.work-packages--list-table-area
position: relative
&:first-child
-webkit-flex: 3 0 0
flex: 3 0 0
.work-packages--list
padding-bottom: 55px
button
width: 100%
.work-packages--page-container
.toolbar > .work-packages--split-view
display: block
.wp-create-button .dropdown
left: 0 !important
#content
overflow: visible
.toolbar-container
margin-bottom: 4px
min-height: 0
.work-packages--show-view
padding: 0
padding-right: 20px
.action_menu_main .dropdown
left: auto !important
.work-packages--split-view
display: block
@ -171,10 +175,10 @@
.work-packages--page-container
.toolbar
padding: 0
padding-right: 20px
.title-container
max-width: 40%
max-width: 90%
overflow: hidden
span
@ -185,11 +189,43 @@
text-overflow: ellipsis
white-space: nowrap
> .work-packages--split-view
display: block
.work-packages--list-table-area
position: relative
.work-packages--list
padding-bottom: 55px
@include breakpoint (680px down)
body.controller-work_packages
.work-packages--page-container
.toolbar
padding-right: 0
&.action-show #content
.work-packages--show-view
padding-right: 0
.toolbar-items
background: #fff
display: flex
margin-bottom: 20px
width: calc(100% + 5px)
> li
-webkit-flex: 1 0 0
flex: 1 0 0
&:first-child
-webkit-flex: 3 0 0
flex: 3 0 0
button
width: 100%
.wp-create-button .dropdown
left: 0 !important
.action_menu_main .dropdown
left: auto !important
.work-packages--list-table-area
position: relative
.work-packages--list
padding-bottom: 55px

@ -62,7 +62,7 @@
font-size: 3rem
color: $homescreen-footer-icon-color
@include breakpoint(960px down)
@include breakpoint(680px down)
.homescreen--links
padding: 20px
flex-wrap: wrap

@ -35,7 +35,13 @@ module Concerns::OmniauthLogin
included do
# disable CSRF protection since that should be covered by the omniauth strategy
skip_before_filter :verify_authenticity_token, only: [:omniauth_login]
# the other filters are not applicable either since OmniAuth is doing authentication
# itself
[
:verify_authenticity_token, :user_setup,
:check_if_login_required, :check_session_lifetime
]
.each { |key| skip_before_filter key, only: [:omniauth_login] }
helper :omniauth
end

@ -349,7 +349,7 @@ class RepositoriesController < ApplicationController
# Prepare checkout instructions
# available on all pages (even empty!)
@path = CGI.unescape(params[:path] || '')
@path = params[:path] || ''
@instructions = ::Scm::CheckoutInstructionsService.new(@repository, path: @path)
# Asserts repository availability, or renders an appropriate error

@ -366,7 +366,7 @@ module ApplicationHelper
end
def to_path_param(path)
CGI.escape(path.to_s)
path.to_s
end
def reorder_links(name, url, options = {})

@ -62,7 +62,7 @@ class CompositeSeeder < Seeder
def discovered_seeder_classes
Seeder
.subclasses
.reject { |cl| cl.namespace_name == namespace }
.reject { |cl| cl.to_s.deconstantize == namespace }
.select { |cl| include_discovered_class? cl }
end

@ -26,7 +26,7 @@
</a>
</li>
<li>
<a href="https://www.openproject.com/enterprise-services/"
<a href="https://www.openproject.org/professional-services/"
target="_blank"
title="<%= l(:label_professional_support) %>">
<%= l(:label_professional_support) %>
@ -40,7 +40,7 @@
</a>
</li>
<li>
<a href="https://www.openproject.org/open-source/openproject-plugins/"
<a href="https://www.openproject.org/open-source/plugins/"
target="_blank"
title="<%= l(:label_plugins) %>">
<%= l(:label_plugins) %>

@ -27,8 +27,8 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<% html_title 'Members' %>
<%= toolbar title: 'Members' do %>
<% html_title t(:label_member_plural) %>
<%= toolbar title: t(:label_member_plural) do %>
<% if authorize_for(:members, :new) %>
<a href="<%= new_project_member_path %>" id="add-member-button" title="Add Member" class="button -alt-highlight">
<i class="button--icon icon-add"></i>

@ -0,0 +1,2 @@
<%= link_to l(:label_user_plural), committers_project_repository_path(repository.project),
class: 'icon icon-user' %>

@ -12,8 +12,7 @@
</div>
<% unless repository.new_record? %>
<div class="attributes-group--header-control">
<%= link_to l(:label_user_plural), committers_project_repository_path(repository.project),
class: 'icon icon-user' %>
<%= render partial: '/repositories/settings/repository_committers_link', locals: { repository: repository } %>
<% if type === 'managed' %>
<%= link_to l(:button_delete), destroy_info_project_repository_path(repository.project),
method: :get,

@ -88,6 +88,40 @@ Docker Engine, or via an environment file:
[configuration-doc]: https://github.com/opf/openproject/blob/dev/doc/CONFIGURATION.md
### SMTP configuration
By default, the docker container will try to send emails via the local
`postfix` daemon. However emails sent this way are more than likely to fail or
end up in the spam inbox of your users. We recommend using an external SMTP
server to send your emails.
A good choice is [SendGrid](https://sendgrid.net), which offers a free plan
with up to 12000 emails per month. Just sign up on the website, and once your
account is provisioned, generate a new API key and copy it somewhere (it looks
like `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`).
You can also just use your SendGrid username and password, but this is less
secure.
You can then configure OpenProject with the following additonal environment
variables (with SendGrid, the `SMTP_USER_NAME` is always `apikey`. Just replace
`SMTP_PASSWORD` with the API key you've generated and you should be good to
go):
docker run -d \
-e EMAIL_DELIVERY_METHOD=smtp \
-e SMTP_ADDRESS=smtp.sendgrid.net \
-e SMTP_PORT=587 \
-e SMTP_DOMAIN=my.domain.com \
-e SMTP_AUTHENTICATION=login \
-e SMTP_ENABLE_STARTTLS_AUTO=true \
-e SMTP_USER_NAME="apikey" \
-e SMTP_PASSWORD="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" \
...
You can adjust those settings for other SMTP providers, such as GMail,
Mandrill, etc. Please refer to the documentation of the corresponding provider
to see what values should be used.
## FAQ
* Can I use SSL?

@ -1,3 +1,4 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
@ -252,6 +253,52 @@ describe RepositoriesController, type: :controller do
end
end
shared_examples 'renders the repository title' do |active_breadcrumb|
it do
expect(response).to be_success
expect(response.body).to have_selector('.repository-breadcrumbs', text: active_breadcrumb)
end
end
describe 'show' do
render_views
let(:role) { FactoryGirl.create(:role, permissions: [:browse_repository]) }
before do
get :show, project_id: project.identifier, path: path
end
context 'with brackets' do
let(:path) { 'subversion_test/[folder_with_brackets]' }
it_behaves_like 'renders the repository title', '[folder_with_brackets]'
end
context 'with unicode' do
let(:path) { 'Föbar/äm/Sägepütz!%5D§' }
it_behaves_like 'renders the repository title', 'Sägepütz!%5D§'
end
end
describe 'changes' do
render_views
let(:role) { FactoryGirl.create(:role, permissions: [:browse_repository]) }
before do
get :changes, project_id: project.identifier, path: path
expect(response).to be_success
end
context 'with brackets' do
let(:path) { 'subversion_test/[folder_with_brackets]' }
it_behaves_like 'renders the repository title', '[folder_with_brackets]'
end
context 'with unicode' do
let(:path) { 'Föbar/äm' }
it_behaves_like 'renders the repository title', 'äm'
end
end
describe 'checkout path' do
render_views

@ -187,30 +187,32 @@ describe OpenProject::Scm::Adapters::Subversion do
it 'builds the info object' do
info = adapter.info
expect(info.root_url).to eq(url)
expect(info.lastrev.identifier).to eq('12')
expect(info.lastrev.identifier).to eq('13')
expect(info.lastrev.author).to eq('oliver')
expect(info.lastrev.time).to eq('2015-07-08T13:32:29.228572Z')
expect(info.lastrev.time).to eq('2016-04-14T19:23:01.74469Z')
end
end
describe '.entries' do
it 'reads all entries from the current revision' do
entries = adapter.entries
expect(entries.length).to eq(1)
expect(entries.length).to eq(2)
expect(entries[0].name).to eq('subversion_test')
expect(entries[0].path).to eq('subversion_test')
expect(entries[0].name).to eq('Föbar')
expect(entries[0].path).to eq('Föbar')
expect(entries[1].name).to eq('subversion_test')
expect(entries[1].path).to eq('subversion_test')
end
it 'contains a reference to the last revision' do
entries = adapter.entries
expect(entries.length).to eq(1)
expect(entries.length).to eq(2)
lastrev = entries[0].lastrev
expect(lastrev.identifier).to eq('12')
expect(lastrev.identifier).to eq('13')
expect(lastrev.author).to eq('oliver')
expect(lastrev.message).to eq('')
expect(lastrev.time).to eq('2015-07-08T13:32:29.228572Z')
expect(lastrev.time).to eq('2016-04-14T19:23:01.74469Z')
end
it 'reads all entries from the given revision' do
@ -282,13 +284,13 @@ describe OpenProject::Scm::Adapters::Subversion do
describe '.revisions' do
it 'returns all revisions by default' do
revisions = adapter.revisions
expect(revisions.length).to eq(12)
expect(revisions.length).to eq(13)
expect(revisions[0].author).to eq('oliver')
expect(revisions[0].message).to eq("Propedit\n")
expect(revisions[0].message).to eq("UTF-8 Test")
revisions.each_with_index do |rev, i|
expect(rev.identifier).to eq((12 - i).to_s)
expect(rev.identifier).to eq((13 - i).to_s)
end
end

@ -167,8 +167,8 @@ describe Repository::Subversion, type: :model do
instance.fetch_changesets
instance.reload
expect(instance.changesets.count).to eq(12)
expect(instance.file_changes.count).to eq(21)
expect(instance.changesets.count).to eq(13)
expect(instance.file_changes.count).to eq(25)
expect(instance.changesets.find_by(revision: '1').comments).to eq('Initial import.')
end
@ -181,7 +181,7 @@ describe Repository::Subversion, type: :model do
expect(instance.changesets.count).to eq(5)
instance.fetch_changesets
expect(instance.changesets.count).to eq(12)
expect(instance.changesets.count).to eq(13)
end
it 'should latest changesets' do
@ -296,7 +296,7 @@ describe Repository::Subversion, type: :model do
changeset = instance.find_changeset_by_name('1')
expect(changeset.previous).to be_nil
changeset = instance.find_changeset_by_name('12')
changeset = instance.find_changeset_by_name('13')
expect(changeset.next).to be_nil
end

@ -45,6 +45,14 @@ describe RepositoriesController, type: :routing do
path: 'path/to/file.c')
}
it {
expect(get('/projects/testproject/repository/folder%20with%20spaces'))
.to route_to(controller: 'repositories',
action: 'show',
project_id: 'testproject',
path: 'folder with spaces')
}
it {
expect(get('/projects/testproject/repository/revisions/5'))
.to route_to(controller: 'repositories',

@ -45,8 +45,8 @@ describe Repository::Subversion, type: :model do
@repository.fetch_changesets
@repository.reload
assert_equal 12, @repository.changesets.count
assert_equal 21, @repository.file_changes.count
assert_equal 13, @repository.changesets.count
assert_equal 25, @repository.file_changes.count
assert_equal 'Initial import.', @repository.changesets.find_by(revision: '1').comments
end
@ -58,7 +58,7 @@ describe Repository::Subversion, type: :model do
assert_equal 5, @repository.changesets.count
@repository.fetch_changesets
assert_equal 12, @repository.changesets.count
assert_equal 13, @repository.changesets.count
end
it 'should latest changesets' do
@ -199,7 +199,7 @@ describe Repository::Subversion, type: :model do
it 'should next nil' do
@repository.fetch_changesets
@repository.reload
changeset = @repository.find_changeset_by_name('12')
changeset = @repository.find_changeset_by_name('13')
assert_nil changeset.next
end

Loading…
Cancel
Save