From 1be5c192977fb0e90ce19f239d1710e4d76bdbdd Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Sat, 26 May 2018 19:06:26 +0200 Subject: [PATCH 01/37] - add some missing "dependent: :destroy" in Organization model: fixes #359, removes all organization memberships and activity when destroying an org instance - introduce OrganizationPolicy to properly define an access control strategy for Organizations --- app/controllers/organizations_controller.rb | 15 ++++++++------- app/models/organization.rb | 8 ++++---- app/models/transfer.rb | 2 +- app/policies/organization_policy.rb | 19 +++++++++++++++++++ app/views/organizations/index.html.erb | 10 +++------- app/views/organizations/show.html.erb | 9 --------- config/routes.rb | 2 +- .../organizations_controller_spec.rb | 3 +++ 8 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 app/policies/organization_policy.rb diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 0a394f172..22bc18d7f 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -1,12 +1,14 @@ class OrganizationsController < ApplicationController - before_filter :load_resource, only: [:show, :edit, :update, :destroy] + before_filter :load_resource, only: [:show, :edit, :update] def new @organization = Organization.new + + authorize @organization end def index - @organizations = Organization.all + @organizations = Organization.all.page(params[:page]).per(25) end def show @@ -21,6 +23,8 @@ def show def create @organization = Organization.new(organization_params) + authorize @organization + if @organization.save redirect_to @organization, status: :created else @@ -36,11 +40,6 @@ def update end end - def destroy - @organization.destroy - redirect_to organizations_path, notice: "deleted" - end - def set_current if current_user session[:current_organization_id] = @organization.id @@ -52,6 +51,8 @@ def set_current def load_resource @organization = Organization.find(params[:id]) + + authorize @organization end def organization_params diff --git a/app/models/organization.rb b/app/models/organization.rb index 9f664d9b6..4040d35a2 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,15 +1,15 @@ class Organization < ActiveRecord::Base has_many :members, dependent: :destroy has_many :users, -> { order "members.created_at DESC" }, through: :members - has_many :all_accounts, class_name: "Account", inverse_of: :organization + has_many :all_accounts, class_name: "Account", inverse_of: :organization, dependent: :destroy has_many :all_movements, class_name: "Movement", through: :all_accounts, source: :movements has_many :all_transfers, class_name: "Transfer", through: :all_movements, source: :transfer - has_one :account, as: :accountable + has_one :account, as: :accountable, dependent: :destroy has_many :member_accounts, through: :members, source: :account - has_many :posts + has_many :posts, dependent: :destroy has_many :offers has_many :inquiries - has_many :documents, as: :documentable + has_many :documents, as: :documentable, dependent: :destroy validates :name, presence: true, uniqueness: true diff --git a/app/models/transfer.rb b/app/models/transfer.rb index a5b28e657..824de8cea 100644 --- a/app/models/transfer.rb +++ b/app/models/transfer.rb @@ -15,7 +15,7 @@ class Transfer < ActiveRecord::Base belongs_to :post belongs_to :operator, class_name: "User" - has_many :movements + has_many :movements, dependent: :destroy validate :different_source_and_destination diff --git a/app/policies/organization_policy.rb b/app/policies/organization_policy.rb new file mode 100644 index 000000000..8ee0af773 --- /dev/null +++ b/app/policies/organization_policy.rb @@ -0,0 +1,19 @@ +class OrganizationPolicy < ApplicationPolicy + alias_method :organization, :record + + def index? + true + end + + def show? + user&.active?(organization) + end + + def create? + user&.superadmin? + end + + def update? + user&.admins?(organization) + end +end diff --git a/app/views/organizations/index.html.erb b/app/views/organizations/index.html.erb index 11c0c2fc6..6847e1905 100644 --- a/app/views/organizations/index.html.erb +++ b/app/views/organizations/index.html.erb @@ -27,20 +27,16 @@ <%= link_to org.name, org %> <%= org.users.count %> - <% if current_user.admins?(org) %> + <% if current_user&.admins?(org) %> <%= link_to edit_organization_path(org), class: 'action' do %> <%= glyph :pencil %> <%= t 'global.edit' %> <% end %> - <%= link_to organization_path(org), - data: { method: :delete }, - class: 'action' do %> - <%= glyph :trash %> - <%= t 'global.borrar' %> - <% end %> <% end %> <% end %> + +<%= paginate @organizations %> diff --git a/app/views/organizations/show.html.erb b/app/views/organizations/show.html.erb index 3793022cf..020f012d7 100644 --- a/app/views/organizations/show.html.erb +++ b/app/views/organizations/show.html.erb @@ -100,15 +100,6 @@ <% end %> <% end %> - <% if superadmin? %> -
  • - <%= link_to organization_path(@organization), - data: { method: :delete, confirm: t("are_you_sure") } do %> - <%= glyph :trash %> - <%= t "global.delete" %> - <% end %> -
  • - <% end %>
  • <%= link_to new_transfer_path(id: @organization, destination_account_id: @organization.account.id) do %> <%= glyph :time %> diff --git a/config/routes.rb b/config/routes.rb index 79c776c14..6ab4661ad 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -33,7 +33,7 @@ get :give_time, on: :member end - resources :organizations, concerns: :accountable do + resources :organizations, concerns: :accountable, except: :destroy do member do post :set_current end diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index f56b7950a..7f8b23b9c 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -3,8 +3,11 @@ describe OrganizationsController do describe '#show' do let(:organization) { Fabricate(:organization) } + let(:member) { Fabricate(:member, organization: organization) } it 'links to new_transfer_path' do + login(member.user) + get 'show', id: organization.id expect(response.body).to include( "" From 6c89900e29295ad859953c99dcf127eb6c592809 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Sat, 26 May 2018 19:10:10 +0200 Subject: [PATCH 02/37] gems: update Pundit to latest release (1.1.0) --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 3a36ae4cb..846237cca 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'rails-i18n' gem "rdiscount" gem 'activeadmin', '~> 1.2.1' gem 'has_scope' -gem 'pundit' +gem 'pundit', '~> 1.1.0' gem 'pg', '0.17.1' gem 'hstore_translate' gem 'dalli' diff --git a/Gemfile.lock b/Gemfile.lock index 77f77a7bd..c8fb71b8e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -239,7 +239,7 @@ GEM prawn-table (0.2.2) prawn (>= 1.3.0, < 3.0.0) public_suffix (2.0.5) - pundit (0.3.0) + pundit (1.1.0) activesupport (>= 3.0.0) rack (1.6.9) rack-protection (2.0.1) @@ -429,7 +429,7 @@ DEPENDENCIES pg (= 0.17.1) prawn (~> 2.2.0) prawn-table (~> 0.2.2) - pundit + pundit (~> 1.1.0) rails (~> 4.2) rails-i18n rails_12factor (= 0.0.3) From d34e0835608376cf37d5d803dd5397d83b886c5d Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Sat, 26 May 2018 19:55:09 +0200 Subject: [PATCH 03/37] add more OrganizationsController specs --- app/policies/organization_policy.rb | 4 +- .../organizations_controller_spec.rb | 60 ++++++++++++++++--- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/app/policies/organization_policy.rb b/app/policies/organization_policy.rb index 8ee0af773..907c85dbc 100644 --- a/app/policies/organization_policy.rb +++ b/app/policies/organization_policy.rb @@ -6,7 +6,7 @@ def index? end def show? - user&.active?(organization) + user&.superadmin? || user&.active?(organization) end def create? @@ -14,6 +14,6 @@ def create? end def update? - user&.admins?(organization) + user&.superadmin? || user&.admins?(organization) end end diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index 7f8b23b9c..455c7f5b2 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -1,17 +1,61 @@ require 'spec_helper' describe OrganizationsController do - describe '#show' do - let(:organization) { Fabricate(:organization) } - let(:member) { Fabricate(:member, organization: organization) } + let!(:organization) { Fabricate(:organization) } + let(:member) { Fabricate(:member, organization: organization) } - it 'links to new_transfer_path' do + describe 'GET #show' do + context 'with a logged user (organization member)' do + it 'links to new_transfer_path' do + login(member.user) + + get 'show', id: organization.id + expect(response.body).to include( + "" + ) + end + end + end + + describe 'GET #index' do + it 'populates and array of organizations' do + get :index + + expect(assigns(:organizations)).to eq([organization]) + end + end + + describe 'POST #create' do + it 'only superdamins are authorized create to new organizations' do login(member.user) - get 'show', id: organization.id - expect(response.body).to include( - "" - ) + expect { + post :create, organization: { name: 'New cool organization' } + }.not_to change { Organization.count } + end + end + + describe 'POST #update' do + context 'with a logged user (admins organization)' do + let(:member) { Fabricate(:member, organization: organization, manager: true) } + + it 'allows to update organization' do + login(member.user) + + post :update, id: organization.id, organization: { name: 'New org name' } + + organization.reload + expect(organization.name).to eq('New org name') + end + end + + context 'without a logged user' do + it 'does not allow to update organization' do + post :update, id: organization.id, organization: { name: 'New org name' } + + expect(response).to redirect_to(root_path) + expect(flash[:error]).to eq('You are not authorized to perform this action.') + end end end end From 26d77a4915adb9f3446906141d93a270cfaf17d2 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Mon, 28 May 2018 21:28:21 +0200 Subject: [PATCH 04/37] UserPolicy minor DRY refactor: This policy inherits from the ApplicationPolicy class this behaviour: def new? create? end --- app/policies/user_policy.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index a0b6b3739..bcce8ae72 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -1,8 +1,4 @@ class UserPolicy < ApplicationPolicy - def new? - user.admins?(organization) - end - def create? user.admins?(organization) end From 035117bfb308b0bb9520477b72b57f927fa8e84c Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Mon, 28 May 2018 23:09:22 +0200 Subject: [PATCH 05/37] add some organizations#show view specs --- .../organizations_controller_spec.rb | 16 +++-- .../views/organizations/show.html.erb_spec.rb | 60 +++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 spec/views/organizations/show.html.erb_spec.rb diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index 455c7f5b2..fa8c5368a 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -6,13 +6,21 @@ describe 'GET #show' do context 'with a logged user (organization member)' do - it 'links to new_transfer_path' do + it 'displays the organization page' do login(member.user) get 'show', id: organization.id - expect(response.body).to include( - "" - ) + + expect(response.body).to include(organization.name) + end + end + + context 'without a logged user' do + it 'redirects to the root path' do + get 'show', id: organization.id + + expect(response).to redirect_to(root_path) + expect(flash[:error]).to eq('You are not authorized to perform this action.') end end end diff --git a/spec/views/organizations/show.html.erb_spec.rb b/spec/views/organizations/show.html.erb_spec.rb new file mode 100644 index 000000000..8837fa1d2 --- /dev/null +++ b/spec/views/organizations/show.html.erb_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +RSpec.describe 'organizations/show' do + let(:organization) { Fabricate(:organization) } + + before do + allow(view).to receive(:admin?).and_return(false) + allow(view).to receive(:superadmin?).and_return(false) + + assign :organization, organization + end + + context 'without a logged user' do + before do + allow(view).to receive(:current_user).and_return(nil) + + assign :movements, [] + render template: 'organizations/show' + end + + it 'links to new_transfer_path' do + expect(rendered).to have_link( + t('global.give_time'), + href: new_transfer_path( + id: organization, + destination_account_id: organization.account.id + ) + ) + end + + it 'does not diplay the movements section' do + expect(rendered).not_to match t('organizations.movements') + end + end + + context 'with a logged user' do + let(:user) { Fabricate(:user) } + + before do + allow(view).to receive(:current_user).and_return(user) + + assign :movements, Movement.page + render template: 'organizations/show' + end + + it 'links to new_transfer_path' do + expect(rendered).to have_link( + t('global.give_time'), + href: new_transfer_path( + id: organization, + destination_account_id: organization.account.id + ) + ) + end + + it 'diplays the movements' do + expect(rendered).to match t('shared.movements.movements') + end + end +end From 4bfc63626f63a8fce8d9f5154719335a442194fe Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Tue, 29 May 2018 21:14:49 +0200 Subject: [PATCH 06/37] OrganizatioPolicy: make show action a public page --- app/policies/organization_policy.rb | 4 ---- app/views/organizations/show.html.erb | 14 +++++++------ .../organizations_controller_spec.rb | 21 +++++-------------- .../views/organizations/show.html.erb_spec.rb | 13 ++++++------ 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/app/policies/organization_policy.rb b/app/policies/organization_policy.rb index 907c85dbc..28ab2ca46 100644 --- a/app/policies/organization_policy.rb +++ b/app/policies/organization_policy.rb @@ -5,10 +5,6 @@ def index? true end - def show? - user&.superadmin? || user&.active?(organization) - end - def create? user&.superadmin? end diff --git a/app/views/organizations/show.html.erb b/app/views/organizations/show.html.erb index 020f012d7..1bec6927a 100644 --- a/app/views/organizations/show.html.erb +++ b/app/views/organizations/show.html.erb @@ -100,12 +100,14 @@ <% end %>
  • <% end %> -
  • - <%= link_to new_transfer_path(id: @organization, destination_account_id: @organization.account.id) do %> - <%= glyph :time %> - <%= t "global.give_time" %> - <% end %> -
  • + <% if current_user&.active?(@organization) %> +
  • + <%= link_to new_transfer_path(id: @organization, destination_account_id: @organization.account.id) do %> + <%= glyph :time %> + <%= t "global.give_time" %> + <% end %> +
  • + <% end %> diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index fa8c5368a..4037ac346 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -5,23 +5,12 @@ let(:member) { Fabricate(:member, organization: organization) } describe 'GET #show' do - context 'with a logged user (organization member)' do - it 'displays the organization page' do - login(member.user) - - get 'show', id: organization.id - - expect(response.body).to include(organization.name) - end - end + it 'displays the organization page' do + get 'show', id: organization.id - context 'without a logged user' do - it 'redirects to the root path' do - get 'show', id: organization.id - - expect(response).to redirect_to(root_path) - expect(flash[:error]).to eq('You are not authorized to perform this action.') - end + expect(assigns(:organization)).to eq(organization) + expect(response.status).to eq(200) + expect(response.body).to include(organization.name) end end diff --git a/spec/views/organizations/show.html.erb_spec.rb b/spec/views/organizations/show.html.erb_spec.rb index 8837fa1d2..785cb9ca2 100644 --- a/spec/views/organizations/show.html.erb_spec.rb +++ b/spec/views/organizations/show.html.erb_spec.rb @@ -18,8 +18,8 @@ render template: 'organizations/show' end - it 'links to new_transfer_path' do - expect(rendered).to have_link( + it 'does not display link to new_transfer_path' do + expect(rendered).not_to have_link( t('global.give_time'), href: new_transfer_path( id: organization, @@ -28,13 +28,14 @@ ) end - it 'does not diplay the movements section' do + it 'does not display the movements section' do expect(rendered).not_to match t('organizations.movements') end end - context 'with a logged user' do - let(:user) { Fabricate(:user) } + context 'with a logged user (organization member)' do + let(:member) { Fabricate(:member, organization: organization) } + let(:user) { member.user } before do allow(view).to receive(:current_user).and_return(user) @@ -53,7 +54,7 @@ ) end - it 'diplays the movements' do + it 'diplays the movements section' do expect(rendered).to match t('shared.movements.movements') end end From 9418484f23eacef4b0b388aa8346106c3c1eba24 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Thu, 7 Jun 2018 22:51:29 +0200 Subject: [PATCH 07/37] delete events when deleting target object --- app/models/member.rb | 1 + app/models/post.rb | 1 + app/models/transfer.rb | 1 + 3 files changed, 3 insertions(+) diff --git a/app/models/member.rb b/app/models/member.rb index 6c0b9aeca..bf1692ff3 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -3,6 +3,7 @@ class Member < ActiveRecord::Base belongs_to :organization has_one :account, as: :accountable has_many :movements, through: :account + has_many :events, dependent: :destroy delegate :balance, to: :account, prefix: true, allow_nil: true delegate :gender, :date_of_birth, to: :user, prefix: true, allow_nil: true diff --git a/app/models/post.rb b/app/models/post.rb index 89b91ff25..31f129661 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -46,6 +46,7 @@ def self.inherited(child) has_many :user_members, class_name: "Member", through: :user, source: :members has_many :transfers has_many :movements, through: :transfers + has_many :events, dependent: :destroy delegate :name, to: :category, prefix: true, allow_nil: true diff --git a/app/models/transfer.rb b/app/models/transfer.rb index 824de8cea..1ae17890f 100644 --- a/app/models/transfer.rb +++ b/app/models/transfer.rb @@ -16,6 +16,7 @@ class Transfer < ActiveRecord::Base belongs_to :post belongs_to :operator, class_name: "User" has_many :movements, dependent: :destroy + has_many :events, dependent: :destroy validate :different_source_and_destination From 7f6a0877268a9a23d37264c1cdfe6b51f30c2697 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Sun, 10 Jun 2018 20:31:12 +0200 Subject: [PATCH 08/37] - let's remove PushNotification when we delete an Event - added some missing Relations specs - remove a couple of unused Relations --- app/controllers/organizations_controller.rb | 2 +- app/models/event.rb | 1 + app/models/post.rb | 2 -- app/models/transfer.rb | 1 - spec/models/event_spec.rb | 1 + spec/models/member_spec.rb | 1 + spec/models/post_spec.rb | 12 ++++++++++++ spec/models/transfer_spec.rb | 9 +++++++++ 8 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 spec/models/post_spec.rb create mode 100644 spec/models/transfer_spec.rb diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 22bc18d7f..db2c1b417 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -26,7 +26,7 @@ def create authorize @organization if @organization.save - redirect_to @organization, status: :created + redirect_to @organization else render action: :new, status: :unprocessable_entity end diff --git a/app/models/event.rb b/app/models/event.rb index 2058045b7..df6275dd7 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -4,6 +4,7 @@ class Event < ActiveRecord::Base belongs_to :post belongs_to :member belongs_to :transfer + has_many :push_notifications, dependent: :destroy validates :action, presence: true validate :resource_presence diff --git a/app/models/post.rb b/app/models/post.rb index 31f129661..767551389 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -39,11 +39,9 @@ def self.inherited(child) attr_reader :member_id belongs_to :category - belongs_to :user belongs_to :organization belongs_to :publisher, class_name: "User", foreign_key: "publisher_id" - has_many :user_members, class_name: "Member", through: :user, source: :members has_many :transfers has_many :movements, through: :transfers has_many :events, dependent: :destroy diff --git a/app/models/transfer.rb b/app/models/transfer.rb index 1ae17890f..b841cce45 100644 --- a/app/models/transfer.rb +++ b/app/models/transfer.rb @@ -14,7 +14,6 @@ class Transfer < ActiveRecord::Base attr_accessor :source, :destination, :amount, :hours, :minutes belongs_to :post - belongs_to :operator, class_name: "User" has_many :movements, dependent: :destroy has_many :events, dependent: :destroy diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 2961fc2ee..e463defc5 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -35,6 +35,7 @@ it { is_expected.to belong_to(:post) } it { is_expected.to belong_to(:member) } it { is_expected.to belong_to(:transfer) } + it { is_expected.to have_many(:push_notifications) } it { is_expected.to have_db_column(:post_id) } it { is_expected.to have_db_column(:member_id) } diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 531379fbc..059cdaad0 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -6,6 +6,7 @@ it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:organization) } it { is_expected.to have_one(:account) } + it { is_expected.to have_many(:events) } it { is_expected.to delegate_method(:balance).to(:account).with_prefix } it { is_expected.to delegate_method(:gender).to(:user).with_prefix } it { is_expected.to delegate_method(:date_of_birth).to(:user).with_prefix } diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb new file mode 100644 index 000000000..3dee6f67b --- /dev/null +++ b/spec/models/post_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +RSpec.describe Post do + describe 'Relations' do + it { is_expected.to belong_to(:category) } + it { is_expected.to belong_to(:user) } + it { is_expected.to belong_to(:publisher) } + it { is_expected.to have_many(:transfers) } + it { is_expected.to have_many(:movements) } + it { is_expected.to have_many(:events) } + end +end diff --git a/spec/models/transfer_spec.rb b/spec/models/transfer_spec.rb new file mode 100644 index 000000000..b041ac033 --- /dev/null +++ b/spec/models/transfer_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +RSpec.describe Transfer do + describe 'Relations' do + it { is_expected.to belong_to(:post) } + it { is_expected.to have_many(:movements) } + it { is_expected.to have_many(:events) } + end +end From 2231b637dae76d25445e8ba92c6d849ce905eeb0 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Wed, 8 Aug 2018 19:48:51 +0200 Subject: [PATCH 09/37] gems: Pundit 2 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 846237cca..eae1a46b8 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'rails-i18n' gem "rdiscount" gem 'activeadmin', '~> 1.2.1' gem 'has_scope' -gem 'pundit', '~> 1.1.0' +gem 'pundit', '~> 2.0.0' gem 'pg', '0.17.1' gem 'hstore_translate' gem 'dalli' diff --git a/Gemfile.lock b/Gemfile.lock index a037c6346..c8b8b0355 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -239,7 +239,7 @@ GEM prawn-table (0.2.2) prawn (>= 1.3.0, < 3.0.0) public_suffix (2.0.5) - pundit (1.1.0) + pundit (2.0.0) activesupport (>= 3.0.0) rack (1.6.10) rack-protection (2.0.1) @@ -430,7 +430,7 @@ DEPENDENCIES pg (= 0.17.1) prawn (~> 2.2.0) prawn-table (~> 0.2.2) - pundit (~> 1.1.0) + pundit (~> 2.0.0) rails (~> 4.2) rails-i18n rails_12factor (= 0.0.3) From 43b3738c272b92c86ac5cb434e29398235436251 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Wed, 15 Aug 2018 15:44:47 +0200 Subject: [PATCH 10/37] policies: :scissors: Scopes as we are not really using it (policy_scope method in controllers/views are never called) --- app/policies/application_policy.rb | 21 +-------------------- app/policies/user_policy.rb | 15 --------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 795d32efc..8866e93a2 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -13,7 +13,7 @@ def index? end def show? - scope.where(id: record.id).exists? + record.class.where(id: record.id).exists? end def create? @@ -35,23 +35,4 @@ def edit? def destroy? false end - - def scope - Pundit.policy_scope!(member, record.class) - end - - class Scope - attr_reader :member, :user, :organization, :scope - - def initialize(member, scope) - @member = member - @user = member.user if member - @organization = member.organization if member - @scope = scope - end - - def resolve - scope - end - end end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index bcce8ae72..43682895f 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -10,19 +10,4 @@ def update? user.admins?(organization) ) end - - class Scope < ApplicationPolicy::Scope - attr_reader :member, :user, :organization, :scope - - def initialize(user, scope) - @member = member - @user = member.user if member - @organization = member.organization if member - @scope = scope - end - - def resolve - scope - end - end end From ea3858121df1dcdc97e76f536a2723a48ef1a01b Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 16:54:05 +0200 Subject: [PATCH 11/37] Add PushNotification#to --- app/models/push_notification.rb | 4 ++++ spec/models/push_notification_spec.rb | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/app/models/push_notification.rb b/app/models/push_notification.rb index 5aff8621a..6971489ec 100644 --- a/app/models/push_notification.rb +++ b/app/models/push_notification.rb @@ -3,4 +3,8 @@ class PushNotification < ActiveRecord::Base belongs_to :device_token, foreign_key: 'device_token_id' validates :event, :device_token, presence: true + + def to + device_token.token + end end diff --git a/spec/models/push_notification_spec.rb b/spec/models/push_notification_spec.rb index f17261023..1bf7f8006 100644 --- a/spec/models/push_notification_spec.rb +++ b/spec/models/push_notification_spec.rb @@ -13,4 +13,13 @@ it { is_expected.to have_db_column(:event_id) } it { is_expected.to have_db_column(:device_token_id) } end + + describe "#to" do + let(:device_token) { Fabricate.build(:device_token, token: 'token') } + let(:push_notification) { described_class.new(device_token: device_token) } + + it 'returns the associated DeviceToken\'s token' do + expect(push_notification.to).to eq('token') + end + end end From 8069d5173007b39cc6bf37aa02b64f47846f291e Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 17:17:37 +0200 Subject: [PATCH 12/37] Add title to PushNotification --- app/models/push_notification.rb | 2 +- .../20180604145622_add_title_to_push_notification.rb | 10 ++++++++++ db/schema.rb | 3 ++- spec/models/push_notification_spec.rb | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20180604145622_add_title_to_push_notification.rb diff --git a/app/models/push_notification.rb b/app/models/push_notification.rb index 6971489ec..24ac3e3c8 100644 --- a/app/models/push_notification.rb +++ b/app/models/push_notification.rb @@ -2,7 +2,7 @@ class PushNotification < ActiveRecord::Base belongs_to :event, foreign_key: 'event_id' belongs_to :device_token, foreign_key: 'device_token_id' - validates :event, :device_token, presence: true + validates :event, :device_token, :title, presence: true def to device_token.token diff --git a/db/migrate/20180604145622_add_title_to_push_notification.rb b/db/migrate/20180604145622_add_title_to_push_notification.rb new file mode 100644 index 000000000..634012c81 --- /dev/null +++ b/db/migrate/20180604145622_add_title_to_push_notification.rb @@ -0,0 +1,10 @@ +class AddTitleToPushNotification < ActiveRecord::Migration + def up + add_column :push_notifications, :title, :string, null: false, default: 'Title for existing records' + change_column_default(:push_notifications, :title, nil) + end + + def down + remove_column :push_notifications, :title + end +end diff --git a/db/schema.rb b/db/schema.rb index 341743d47..7d3b07b2d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180530180546) do +ActiveRecord::Schema.define(version: 20180604145622) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -164,6 +164,7 @@ t.datetime "processed_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "title", null: false end create_table "transfers", force: :cascade do |t| diff --git a/spec/models/push_notification_spec.rb b/spec/models/push_notification_spec.rb index 1bf7f8006..974a51778 100644 --- a/spec/models/push_notification_spec.rb +++ b/spec/models/push_notification_spec.rb @@ -4,6 +4,7 @@ describe 'Validations' do it { is_expected.to validate_presence_of(:event) } it { is_expected.to validate_presence_of(:device_token) } + it { is_expected.to validate_presence_of(:title) } end describe 'Associations' do From 2e8b31da4cd933a0823e7977a30b84c2cc79cc8c Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 17:19:09 +0200 Subject: [PATCH 13/37] Add PushNotification fabricator --- spec/fabricators/push_notification_fabricator.rb | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 spec/fabricators/push_notification_fabricator.rb diff --git a/spec/fabricators/push_notification_fabricator.rb b/spec/fabricators/push_notification_fabricator.rb new file mode 100644 index 000000000..539639867 --- /dev/null +++ b/spec/fabricators/push_notification_fabricator.rb @@ -0,0 +1,2 @@ +Fabricator(:push_notification) do +end From ae9ef903983bf187f14939a432686ad76d1578ed Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 17:19:38 +0200 Subject: [PATCH 14/37] Add token to DeviceToken fabricator --- spec/fabricators/device_token_fabricator.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/fabricators/device_token_fabricator.rb b/spec/fabricators/device_token_fabricator.rb index 64f2a980f..ad354d147 100644 --- a/spec/fabricators/device_token_fabricator.rb +++ b/spec/fabricators/device_token_fabricator.rb @@ -1,2 +1,3 @@ Fabricator(:device_token) do + token 'token' end From cb16c0323775a2cb3038a551fdbbc0f0b55883c1 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 17:20:47 +0200 Subject: [PATCH 15/37] Create new PushNotifications with title --- app/services/push_notifications/creator.rb | 12 +++++++++++- spec/services/push_notifications/creator_spec.rb | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/services/push_notifications/creator.rb b/app/services/push_notifications/creator.rb index 9096cbdd8..e1a81189d 100644 --- a/app/services/push_notifications/creator.rb +++ b/app/services/push_notifications/creator.rb @@ -11,12 +11,22 @@ def initialize(event:) def create! event_notifier = EventNotifierFactory.new(event: event).build event_notifier.device_tokens.each do |device_token| - PushNotification.create!(event: event, device_token: device_token) + PushNotification.create!( + event: event, + device_token: device_token, + title: title + ) end end private attr_accessor :event + + # TODO: For now we only create push notifications for Post + # + def title + 'A new post has been created.' + end end end diff --git a/spec/services/push_notifications/creator_spec.rb b/spec/services/push_notifications/creator_spec.rb index 4b8df3f17..6cff7c525 100644 --- a/spec/services/push_notifications/creator_spec.rb +++ b/spec/services/push_notifications/creator_spec.rb @@ -16,7 +16,8 @@ it 'creates as many PushNotification resources as needed' do expect(PushNotification).to receive(:create!).with( event: event, - device_token: device_token + device_token: device_token, + title: 'A new post has been created.' ).once creator.create! From 2352b79739cc6d1cfc91a7f70c5e64758773bccf Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 17:23:07 +0200 Subject: [PATCH 16/37] Remove unused services --- .../push_notifications/expo_sender_service.rb | 30 ------------------- .../post_broadcaster_service.rb | 19 ------------ 2 files changed, 49 deletions(-) delete mode 100644 app/services/push_notifications/expo_sender_service.rb delete mode 100644 app/services/push_notifications/post_broadcaster_service.rb diff --git a/app/services/push_notifications/expo_sender_service.rb b/app/services/push_notifications/expo_sender_service.rb deleted file mode 100644 index 61a8e528c..000000000 --- a/app/services/push_notifications/expo_sender_service.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'net/http' - -module PushNotifications - class ExpoAdaptorService - def initialize(notification, user) - @notification = notification - @user = user - end - - def run - user.device_tokens.each do |device_token| - # https://docs.expo.io/versions/latest/guides/push-notifications.html - uri = URI('https://exp.host/--/api/v2/push/send') - Net::HTTP.post_form(uri, post_data(device_token.token)) - end - end - - private - - attr_reader :notification, :user - - def post_data(token) - { - "to" => token, - "title" => notification.title, - "body" => notification.body - } - end - end -end diff --git a/app/services/push_notifications/post_broadcaster_service.rb b/app/services/push_notifications/post_broadcaster_service.rb deleted file mode 100644 index 76addb143..000000000 --- a/app/services/push_notifications/post_broadcaster_service.rb +++ /dev/null @@ -1,19 +0,0 @@ -module PushNotifications - class UsersBroadcasterService - def initialize(users) - @users = users - end - - def broadcast - notification = PostNotification.new - - users.each do |user| - ExpoSenderService.new(notification, user).run - end - end - - private - - attr_reader :users - end -end From 67c4fe87dad2728dbbe3d8ce4ee0cda0979f73c2 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 17:51:43 +0200 Subject: [PATCH 17/37] Add scheduled job to send push notifications --- Gemfile | 1 + Gemfile.lock | 7 +++ app/jobs/send_push_notifications_job.rb | 9 ++++ app/services/push_notifications/broadcast.rb | 28 ++++++++++++ config/schedule.yml | 4 ++ spec/jobs/send_push_notifications_job_spec.rb | 43 +++++++++++++++++++ .../push_notifications/broadcast_spec.rb | 32 ++++++++++++++ 7 files changed, 124 insertions(+) create mode 100644 app/jobs/send_push_notifications_job.rb create mode 100644 app/services/push_notifications/broadcast.rb create mode 100644 config/schedule.yml create mode 100644 spec/jobs/send_push_notifications_job_spec.rb create mode 100644 spec/services/push_notifications/broadcast_spec.rb diff --git a/Gemfile b/Gemfile index e386d1131..a6a949176 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,7 @@ gem 'sidekiq-cron', '0.6.3' # TODO: remove this once the following issue has been addressed # https://github.com/ondrejbartas/sidekiq-cron/issues/199 gem 'rufus-scheduler', '~> 3.4.2' +gem 'exponent-server-sdk', '0.0.5' # Assets gem 'jquery-rails', '>= 4.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index e2e1f9011..50e955468 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -146,7 +146,11 @@ GEM erubis (2.7.0) et-orbi (1.1.2) tzinfo + ethon (0.11.0) + ffi (>= 1.3.0) execjs (2.6.0) + exponent-server-sdk (0.0.5) + typhoeus fabrication (2.11.3) faker (1.4.3) i18n (~> 0.5) @@ -367,6 +371,8 @@ GEM thread_safe (0.3.6) tilt (2.0.8) ttfunk (1.5.1) + typhoeus (1.3.0) + ethon (>= 0.9.0) tzinfo (1.2.5) thread_safe (~> 0.1) uglifier (2.7.2) @@ -415,6 +421,7 @@ DEPENDENCIES dotenv-rails (= 1.0.2) elasticsearch-model elasticsearch-rails + exponent-server-sdk (= 0.0.5) fabrication faker has_scope diff --git a/app/jobs/send_push_notifications_job.rb b/app/jobs/send_push_notifications_job.rb new file mode 100644 index 000000000..f8199f8d8 --- /dev/null +++ b/app/jobs/send_push_notifications_job.rb @@ -0,0 +1,9 @@ +class SendPushNotificationsJob < ActiveJob::Base + queue_as :cron + + def perform + push_notifications = PushNotification.where(processed_at: nil) + + ::PushNotifications::Broadcast.new(push_notifications: push_notifications).send + end +end diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb new file mode 100644 index 000000000..b34e83f3b --- /dev/null +++ b/app/services/push_notifications/broadcast.rb @@ -0,0 +1,28 @@ +module PushNotifications + class Broadcast + def initialize(push_notifications:) + @push_notifications = push_notifications + end + + def send + return unless push_notifications.any? + + client = Exponent::Push::Client.new + + client.publish(notifications) + end + + private + + attr_reader :push_notifications + + def notifications + push_notifications.map do |push_notification| + { + to: push_notification.to, + title: push_notification.title + } + end + end + end +end diff --git a/config/schedule.yml b/config/schedule.yml new file mode 100644 index 000000000..56487c3a6 --- /dev/null +++ b/config/schedule.yml @@ -0,0 +1,4 @@ +send_push_notifications_job: + cron: '*/5 * * * *' + class: 'SendPushNotificationsJob' + queue: cron diff --git a/spec/jobs/send_push_notifications_job_spec.rb b/spec/jobs/send_push_notifications_job_spec.rb new file mode 100644 index 000000000..db9fecb9a --- /dev/null +++ b/spec/jobs/send_push_notifications_job_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +RSpec.describe SendPushNotificationsJob, type: :job do + describe '#perform' do + let(:user) { Fabricate(:user) } + let(:device_token) { Fabricate(:device_token, user: user) } + let(:post) { Fabricate(:post) } + let(:event_created) { Fabricate(:event, post: post, action: :created) } + let(:event_updated) { Fabricate(:event, post: post, action: :updated) } + let(:push_notification) do + Fabricate( + :push_notification, + event: event_created, + device_token: device_token, + title: 'A new Post hase been created.' + ) + end + let(:processed_push_notification) do + Fabricate( + :push_notification, + event: event_updated, + device_token: device_token, + title: 'A new Post hase been created.', + processed_at: Time.zone.now + ) + end + + before do + push_notification + processed_push_notification + end + + it 'calls Broadcast to send the notifications' do + broadcast = instance_double(::PushNotifications::Broadcast) + expect(::PushNotifications::Broadcast).to receive(:new) + .with(push_notifications: [push_notification]) + .and_return(broadcast) + expect(broadcast).to receive(:send) + + described_class.new.perform + end + end +end diff --git a/spec/services/push_notifications/broadcast_spec.rb b/spec/services/push_notifications/broadcast_spec.rb new file mode 100644 index 000000000..0e6513f92 --- /dev/null +++ b/spec/services/push_notifications/broadcast_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +RSpec.describe PushNotifications::Broadcast do + describe '#send' do + let(:user) { Fabricate(:user) } + let(:device_token) { Fabricate(:device_token, user: user) } + let(:post) { Fabricate(:post) } + let(:event_created) { Fabricate(:event, post: post, action: :created) } + let(:push_notification) do + Fabricate( + :push_notification, + event: event_created, + device_token: device_token, + title: 'Hola' + ) + end + let(:client) { instance_double(Exponent::Push::Client) } + let(:notification) do + { + to: push_notification.to, + title: push_notification.title + } + end + + it 'calls Expo HTTP client to send notifications' do + expect(Exponent::Push::Client).to receive(:new).and_return(client) + expect(client).to receive(:publish).with([notification]) + + described_class.new(push_notifications: [push_notification]).send + end + end +end From 13ff3d1b5712fa6d2d8e74fcc47534c29c183930 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Mon, 4 Jun 2018 18:18:08 +0200 Subject: [PATCH 18/37] Upgrade elasticsearch gems --- Gemfile.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 50e955468..c471b1139 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -129,17 +129,17 @@ GEM dotenv (1.0.2) dotenv-rails (1.0.2) dotenv (= 1.0.2) - elasticsearch (1.0.8) - elasticsearch-api (= 1.0.7) - elasticsearch-transport (= 1.0.7) - elasticsearch-api (1.0.7) + elasticsearch (5.0.5) + elasticsearch-api (= 5.0.5) + elasticsearch-transport (= 5.0.5) + elasticsearch-api (5.0.5) multi_json - elasticsearch-model (0.1.7) + elasticsearch-model (5.0.2) activesupport (> 3) - elasticsearch (> 0.4) + elasticsearch (~> 5) hashie - elasticsearch-rails (0.1.7) - elasticsearch-transport (1.0.7) + elasticsearch-rails (5.0.2) + elasticsearch-transport (5.0.5) faraday multi_json erubi (1.7.1) @@ -154,7 +154,7 @@ GEM fabrication (2.11.3) faker (1.4.3) i18n (~> 0.5) - faraday (0.9.1) + faraday (0.15.2) multipart-post (>= 1.2, < 3) ffi (1.9.23) formtastic (3.1.5) @@ -166,7 +166,7 @@ GEM has_scope (0.6.0) actionpack (>= 3.2, < 5) activesupport (>= 3.2, < 5) - hashie (3.4.1) + hashie (3.5.7) hstore_translate (1.0.0) activerecord (>= 3.1.0) http-cookie (1.0.3) @@ -218,7 +218,7 @@ GEM mini_mime (1.0.0) mini_portile2 (2.3.0) minitest (5.11.3) - multi_json (1.11.2) + multi_json (1.13.1) multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) From 5c114f4cb435e1f05df2dcf198c546d0e8382653 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Tue, 19 Jun 2018 12:31:37 +0200 Subject: [PATCH 19/37] Flag push_notifications as processed --- app/services/push_notifications/broadcast.rb | 1 + spec/services/push_notifications/broadcast_spec.rb | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index b34e83f3b..3a32ed701 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -9,6 +9,7 @@ def send client = Exponent::Push::Client.new + push_notifications.update_all(processed_at: Time.now.utc) client.publish(notifications) end diff --git a/spec/services/push_notifications/broadcast_spec.rb b/spec/services/push_notifications/broadcast_spec.rb index 0e6513f92..8b7ff6b5d 100644 --- a/spec/services/push_notifications/broadcast_spec.rb +++ b/spec/services/push_notifications/broadcast_spec.rb @@ -14,6 +14,7 @@ title: 'Hola' ) end + let(:push_notifications) { PushNotification.all } let(:client) { instance_double(Exponent::Push::Client) } let(:notification) do { @@ -26,7 +27,16 @@ expect(Exponent::Push::Client).to receive(:new).and_return(client) expect(client).to receive(:publish).with([notification]) - described_class.new(push_notifications: [push_notification]).send + described_class.new(push_notifications: push_notifications).send + end + + it 'flags the push_notification as processed' do + allow(Exponent::Push::Client).to receive(:new).and_return(client) + allow(client).to receive(:publish).with([notification]) + + described_class.new(push_notifications: push_notifications).send + + expect(push_notification.reload.processed_at).to_not be_nil end end end From 931347487025d832b785e9e9b84f1e18f384d822 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Tue, 21 Aug 2018 22:06:56 +0200 Subject: [PATCH 20/37] Set notifications as processed after publish --- app/services/push_notifications/broadcast.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index 3a32ed701..d42b5f49d 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -9,8 +9,8 @@ def send client = Exponent::Push::Client.new - push_notifications.update_all(processed_at: Time.now.utc) client.publish(notifications) + push_notifications.update_all(processed_at: Time.now.utc) end private From 005e68371a5ca9b284a26392b69b371d71e4e2aa Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 23 Aug 2018 10:03:02 +0200 Subject: [PATCH 21/37] Revert "Upgrade elasticsearch gems" This reverts commit 13ff3d1b5712fa6d2d8e74fcc47534c29c183930. --- Gemfile.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c471b1139..50e955468 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -129,17 +129,17 @@ GEM dotenv (1.0.2) dotenv-rails (1.0.2) dotenv (= 1.0.2) - elasticsearch (5.0.5) - elasticsearch-api (= 5.0.5) - elasticsearch-transport (= 5.0.5) - elasticsearch-api (5.0.5) + elasticsearch (1.0.8) + elasticsearch-api (= 1.0.7) + elasticsearch-transport (= 1.0.7) + elasticsearch-api (1.0.7) multi_json - elasticsearch-model (5.0.2) + elasticsearch-model (0.1.7) activesupport (> 3) - elasticsearch (~> 5) + elasticsearch (> 0.4) hashie - elasticsearch-rails (5.0.2) - elasticsearch-transport (5.0.5) + elasticsearch-rails (0.1.7) + elasticsearch-transport (1.0.7) faraday multi_json erubi (1.7.1) @@ -154,7 +154,7 @@ GEM fabrication (2.11.3) faker (1.4.3) i18n (~> 0.5) - faraday (0.15.2) + faraday (0.9.1) multipart-post (>= 1.2, < 3) ffi (1.9.23) formtastic (3.1.5) @@ -166,7 +166,7 @@ GEM has_scope (0.6.0) actionpack (>= 3.2, < 5) activesupport (>= 3.2, < 5) - hashie (3.5.7) + hashie (3.4.1) hstore_translate (1.0.0) activerecord (>= 3.1.0) http-cookie (1.0.3) @@ -218,7 +218,7 @@ GEM mini_mime (1.0.0) mini_portile2 (2.3.0) minitest (5.11.3) - multi_json (1.13.1) + multi_json (1.11.2) multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) From 20eb8cb4482570c823c362e295f4679c906b5870 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 23 Aug 2018 10:04:31 +0200 Subject: [PATCH 22/37] Remove Expo client gem --- Gemfile | 1 - Gemfile.lock | 7 ------- 2 files changed, 8 deletions(-) diff --git a/Gemfile b/Gemfile index a6a949176..e386d1131 100644 --- a/Gemfile +++ b/Gemfile @@ -28,7 +28,6 @@ gem 'sidekiq-cron', '0.6.3' # TODO: remove this once the following issue has been addressed # https://github.com/ondrejbartas/sidekiq-cron/issues/199 gem 'rufus-scheduler', '~> 3.4.2' -gem 'exponent-server-sdk', '0.0.5' # Assets gem 'jquery-rails', '>= 4.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 50e955468..e2e1f9011 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -146,11 +146,7 @@ GEM erubis (2.7.0) et-orbi (1.1.2) tzinfo - ethon (0.11.0) - ffi (>= 1.3.0) execjs (2.6.0) - exponent-server-sdk (0.0.5) - typhoeus fabrication (2.11.3) faker (1.4.3) i18n (~> 0.5) @@ -371,8 +367,6 @@ GEM thread_safe (0.3.6) tilt (2.0.8) ttfunk (1.5.1) - typhoeus (1.3.0) - ethon (>= 0.9.0) tzinfo (1.2.5) thread_safe (~> 0.1) uglifier (2.7.2) @@ -421,7 +415,6 @@ DEPENDENCIES dotenv-rails (= 1.0.2) elasticsearch-model elasticsearch-rails - exponent-server-sdk (= 0.0.5) fabrication faker has_scope From 775176649d26bbc7b4f6b5a105e2bf0616e899ca Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 23 Aug 2018 10:22:41 +0200 Subject: [PATCH 23/37] Use standard ruby net http instead of Expo client --- app/services/push_notifications/broadcast.rb | 10 +++++++--- spec/services/push_notifications/broadcast_spec.rb | 11 +++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index d42b5f49d..30dbeae45 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -1,15 +1,18 @@ +require 'net/http' + module PushNotifications class Broadcast def initialize(push_notifications:) @push_notifications = push_notifications end + # https://docs.expo.io/versions/latest/guides/push-notifications.html def send return unless push_notifications.any? - client = Exponent::Push::Client.new + uri = URI('https://exp.host/--/api/v2/push/send') + Net::HTTP.post_form(uri, notifications) - client.publish(notifications) push_notifications.update_all(processed_at: Time.now.utc) end @@ -21,7 +24,8 @@ def notifications push_notifications.map do |push_notification| { to: push_notification.to, - title: push_notification.title + title: push_notification.title, + body: 'WAT!?' } end end diff --git a/spec/services/push_notifications/broadcast_spec.rb b/spec/services/push_notifications/broadcast_spec.rb index 8b7ff6b5d..84d5ce1db 100644 --- a/spec/services/push_notifications/broadcast_spec.rb +++ b/spec/services/push_notifications/broadcast_spec.rb @@ -15,24 +15,23 @@ ) end let(:push_notifications) { PushNotification.all } - let(:client) { instance_double(Exponent::Push::Client) } let(:notification) do { to: push_notification.to, - title: push_notification.title + title: push_notification.title, + body: 'WAT!?' } end + let(:uri) { URI('https://exp.host/--/api/v2/push/send') } it 'calls Expo HTTP client to send notifications' do - expect(Exponent::Push::Client).to receive(:new).and_return(client) - expect(client).to receive(:publish).with([notification]) + expect(Net::HTTP).to receive(:post_form).with(uri, [notification]) described_class.new(push_notifications: push_notifications).send end it 'flags the push_notification as processed' do - allow(Exponent::Push::Client).to receive(:new).and_return(client) - allow(client).to receive(:publish).with([notification]) + allow(Net::HTTP).to receive(:post_form).with(uri, [notification]) described_class.new(push_notifications: push_notifications).send From e2471106caa4736e40eb655527d1623142b97e8d Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 23 Aug 2018 14:46:17 +0200 Subject: [PATCH 24/37] #send is a word reserved to Ruby... :boom --- app/jobs/send_push_notifications_job.rb | 4 +++- app/services/push_notifications/broadcast.rb | 2 +- spec/jobs/send_push_notifications_job_spec.rb | 2 +- spec/services/push_notifications/broadcast_spec.rb | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/jobs/send_push_notifications_job.rb b/app/jobs/send_push_notifications_job.rb index f8199f8d8..41835d74c 100644 --- a/app/jobs/send_push_notifications_job.rb +++ b/app/jobs/send_push_notifications_job.rb @@ -4,6 +4,8 @@ class SendPushNotificationsJob < ActiveJob::Base def perform push_notifications = PushNotification.where(processed_at: nil) - ::PushNotifications::Broadcast.new(push_notifications: push_notifications).send + ::PushNotifications::Broadcast.new( + push_notifications: push_notifications + ).send_notifications end end diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index 30dbeae45..630d1662f 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -7,7 +7,7 @@ def initialize(push_notifications:) end # https://docs.expo.io/versions/latest/guides/push-notifications.html - def send + def send_notifications return unless push_notifications.any? uri = URI('https://exp.host/--/api/v2/push/send') diff --git a/spec/jobs/send_push_notifications_job_spec.rb b/spec/jobs/send_push_notifications_job_spec.rb index db9fecb9a..07c0fe73a 100644 --- a/spec/jobs/send_push_notifications_job_spec.rb +++ b/spec/jobs/send_push_notifications_job_spec.rb @@ -35,7 +35,7 @@ expect(::PushNotifications::Broadcast).to receive(:new) .with(push_notifications: [push_notification]) .and_return(broadcast) - expect(broadcast).to receive(:send) + expect(broadcast).to receive(:send_notifications) described_class.new.perform end diff --git a/spec/services/push_notifications/broadcast_spec.rb b/spec/services/push_notifications/broadcast_spec.rb index 84d5ce1db..fc11d0df5 100644 --- a/spec/services/push_notifications/broadcast_spec.rb +++ b/spec/services/push_notifications/broadcast_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' RSpec.describe PushNotifications::Broadcast do - describe '#send' do + describe '#send_notifications' do let(:user) { Fabricate(:user) } let(:device_token) { Fabricate(:device_token, user: user) } let(:post) { Fabricate(:post) } From 269874727d44467a76fded150e57bb241ce84774 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 23 Aug 2018 14:46:55 +0200 Subject: [PATCH 25/37] Fix notifications broadcast --- app/services/push_notifications/broadcast.rb | 31 +++++++-- .../push_notifications/broadcast_spec.rb | 65 ++++++++++++++----- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index 630d1662f..a33d41224 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -1,7 +1,7 @@ -require 'net/http' - module PushNotifications class Broadcast + class PostError < ::StandardError; end + def initialize(push_notifications:) @push_notifications = push_notifications end @@ -10,8 +10,15 @@ def initialize(push_notifications:) def send_notifications return unless push_notifications.any? - uri = URI('https://exp.host/--/api/v2/push/send') - Net::HTTP.post_form(uri, notifications) + response = client.post( + uri.request_uri, + notifications.to_json, + headers + ) + + unless response.is_a? Net::HTTPOK + raise PostError, "HTTP response: #{response.code}, #{response.body}" + end push_notifications.update_all(processed_at: Time.now.utc) end @@ -29,5 +36,21 @@ def notifications } end end + + def client + https = Net::HTTP.new(uri.host, uri.port) + https.use_ssl = true + https + end + + def uri + URI('https://exp.host/--/api/v2/push/send') + end + + def headers + { + "Content-Type" => "application/json" + } + end end end diff --git a/spec/services/push_notifications/broadcast_spec.rb b/spec/services/push_notifications/broadcast_spec.rb index fc11d0df5..3188baefd 100644 --- a/spec/services/push_notifications/broadcast_spec.rb +++ b/spec/services/push_notifications/broadcast_spec.rb @@ -6,14 +6,6 @@ let(:device_token) { Fabricate(:device_token, user: user) } let(:post) { Fabricate(:post) } let(:event_created) { Fabricate(:event, post: post, action: :created) } - let(:push_notification) do - Fabricate( - :push_notification, - event: event_created, - device_token: device_token, - title: 'Hola' - ) - end let(:push_notifications) { PushNotification.all } let(:notification) do { @@ -23,19 +15,60 @@ } end let(:uri) { URI('https://exp.host/--/api/v2/push/send') } + let(:client) { Net::HTTP.new(uri.host, uri.port) } + let(:headers) { { "Content-Type" => "application/json" } } - it 'calls Expo HTTP client to send notifications' do - expect(Net::HTTP).to receive(:post_form).with(uri, [notification]) + context 'when there are push notifications to send' do + let(:push_notification) do + Fabricate( + :push_notification, + event: event_created, + device_token: device_token, + title: 'Hola' + ) + end - described_class.new(push_notifications: push_notifications).send - end + context 'when the HTTP response is OK' do + let(:http_response) { Net::HTTPOK.new(1.0, 200, "OK") } + + it 'calls Expo API to send notifications' do + allow(Net::HTTP).to receive(:new).with(uri.host, uri.port).and_return(client) + expect(client).to receive(:post).with(uri.request_uri, [notification].to_json, headers).and_return(http_response) + + described_class.new(push_notifications: push_notifications).send_notifications + end + + it 'flags the push_notification as processed' do + allow(Net::HTTP).to receive(:new).with(uri.host, uri.port).and_return(client) + allow(client).to receive(:post).with(uri.request_uri, [notification].to_json, headers).and_return(http_response) - it 'flags the push_notification as processed' do - allow(Net::HTTP).to receive(:post_form).with(uri, [notification]) + described_class.new(push_notifications: push_notifications).send_notifications + + expect(push_notification.reload.processed_at).to_not be_nil + end + + context 'when the HTTP response is not OK' do + let(:http_response) { Net::HTTPNotFound.new(1.0, 400, "Not Found") } + + it 'raises an error' do + allow(Net::HTTP).to receive(:new).with(uri.host, uri.port).and_return(client) + allow(client).to receive(:post).with(uri.request_uri, [notification].to_json, headers).and_return(http_response) + allow(http_response).to receive(:body).and_return("Everything is broken!") + + expect { + described_class.new(push_notifications: push_notifications).send_notifications + }.to raise_error(::PushNotifications::Broadcast::PostError) + end + end + end + end - described_class.new(push_notifications: push_notifications).send + context 'when there are no push notifications to send' do + it 'calls Expo API to send notifications' do + expect(Net::HTTP).to_not receive(:new).with(uri.host, uri.port) - expect(push_notification.reload.processed_at).to_not be_nil + described_class.new(push_notifications: push_notifications).send_notifications + end end end end From d94684e6c00cb74c35e4fb07f49c2816cfd519d3 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 23 Aug 2018 15:21:57 +0200 Subject: [PATCH 26/37] Use Post title as notification title --- app/services/push_notifications/creator.rb | 2 +- spec/services/push_notifications/creator_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/push_notifications/creator.rb b/app/services/push_notifications/creator.rb index e1a81189d..076f20acf 100644 --- a/app/services/push_notifications/creator.rb +++ b/app/services/push_notifications/creator.rb @@ -26,7 +26,7 @@ def create! # TODO: For now we only create push notifications for Post # def title - 'A new post has been created.' + event.post.title end end end diff --git a/spec/services/push_notifications/creator_spec.rb b/spec/services/push_notifications/creator_spec.rb index 6cff7c525..3a38552ec 100644 --- a/spec/services/push_notifications/creator_spec.rb +++ b/spec/services/push_notifications/creator_spec.rb @@ -17,7 +17,7 @@ expect(PushNotification).to receive(:create!).with( event: event, device_token: device_token, - title: 'A new post has been created.' + title: event.post.title ).once creator.create! From 1e816a37fe40400b57f246debde87812b33ecdb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 31 Aug 2018 18:43:49 +0000 Subject: [PATCH 27/37] [Security] Bump rubyzip from 1.2.1 to 1.2.2 Bumps [rubyzip](https://github.com/rubyzip/rubyzip) from 1.2.1 to 1.2.2. **This update includes security fixes.** - [Release notes](https://github.com/rubyzip/rubyzip/releases) - [Changelog](https://github.com/rubyzip/rubyzip/blob/master/Changelog.md) - [Commits](https://github.com/rubyzip/rubyzip/compare/v1.2.1...v1.2.2) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ffea63e66..094767664 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -321,7 +321,7 @@ GEM ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-progressbar (1.9.0) - rubyzip (1.2.1) + rubyzip (1.2.2) rufus-scheduler (3.4.2) et-orbi (~> 1.0) sass (3.4.21) From 285617fbe82c868c7c3017e54c941fc1e3bce6d3 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Fri, 31 Aug 2018 22:14:04 +0200 Subject: [PATCH 28/37] `.env.example` cleanup (remove unused vars) and dotenv-rails upgrade --- .env.example | 4 ++-- Gemfile | 2 +- Gemfile.lock | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index 3f56d772c..a5a5f830b 100644 --- a/.env.example +++ b/.env.example @@ -10,12 +10,12 @@ # database setup: -DATABASE_ADAPTER=postgres DATABASE_USER=postgres -DATABASE_HOST=localhost +DATABASE_NAME=timeoverflow_development # host part of the url for mail links: MAIL_LINK_HOST=localhost:3000 +MAIL_LINK_PROTO=http # a list of emails for superadmin users ADMINS="admin@timeoverflow.org" diff --git a/Gemfile b/Gemfile index e386d1131..128fb1344 100644 --- a/Gemfile +++ b/Gemfile @@ -48,7 +48,7 @@ group :development do gem 'airbrussh', require: false gem 'localeapp', '2.1.1', require: false gem 'letter_opener', '1.4.1' - gem 'dotenv-rails', '1.0.2' + gem 'dotenv-rails', '2.5.0' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index ffea63e66..17f53c522 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -126,9 +126,10 @@ GEM diff-lcs (1.3) domain_name (0.5.20170223) unf (>= 0.0.5, < 1.0.0) - dotenv (1.0.2) - dotenv-rails (1.0.2) - dotenv (= 1.0.2) + dotenv (2.5.0) + dotenv-rails (2.5.0) + dotenv (= 2.5.0) + railties (>= 3.2, < 6.0) elasticsearch (1.0.8) elasticsearch-api (= 1.0.7) elasticsearch-transport (= 1.0.7) @@ -412,7 +413,7 @@ DEPENDENCIES dalli database_cleaner (= 1.6.2) devise (~> 4.4.1) - dotenv-rails (= 1.0.2) + dotenv-rails (= 2.5.0) elasticsearch-model elasticsearch-rails fabrication From 94acd09ae0d9d439af42d74157be805f85783fbf Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Wed, 15 Aug 2018 19:04:40 +0200 Subject: [PATCH 29/37] :scissors: config/newrelic.yml, we are using Skylight now --- config/newrelic.yml | 255 -------------------------------------------- 1 file changed, 255 deletions(-) delete mode 100644 config/newrelic.yml diff --git a/config/newrelic.yml b/config/newrelic.yml deleted file mode 100644 index 6f86fde59..000000000 --- a/config/newrelic.yml +++ /dev/null @@ -1,255 +0,0 @@ -# Here are the settings that are common to all environments -common: &default_settings - # ============================== LICENSE KEY =============================== - - # You must specify the license key associated with your New Relic - # account. This key binds your Agent's data to your account in the - # New Relic service. - license_key: '<%= ENV["NEW_RELIC_LICENSE_KEY"] %>' - - # Agent Enabled (Rails Only) - # Use this setting to force the agent to run or not run. - # Default is 'auto' which means the agent will install and run only - # if a valid dispatcher such as Mongrel is running. This prevents - # it from running with Rake or the console. Set to false to - # completely turn the agent off regardless of the other settings. - # Valid values are true, false and auto. - # - # agent_enabled: auto - - # Application Name Set this to be the name of your application as - # you'd like it show up in New Relic. The service will then auto-map - # instances of your application into an "application" on your - # dashboard page. If you want to map this instance into multiple - # apps, like "AJAX Requests" and "All UI" then specify a semicolon - # separated list of up to three distinct names, or a yaml list. - # Defaults to the capitalized RAILS_ENV or RACK_ENV (i.e., - # Production, Staging, etc) - # - # Example: - # - # app_name: - # - Ajax Service - # - All Services - # - app_name: <%= ENV["NEW_RELIC_APP_NAME"] %> - - # When "true", the agent collects performance data about your - # application and reports this data to the New Relic service at - # newrelic.com. This global switch is normally overridden for each - # environment below. (formerly called 'enabled') - monitor_mode: true - - # Developer mode should be off in every environment but - # development as it has very high overhead in memory. - developer_mode: false - - # The newrelic agent generates its own log file to keep its logging - # information separate from that of your application. Specify its - # log level here. - log_level: info - - # Optionally set the path to the log file This is expanded from the - # root directory (may be relative or absolute, e.g. 'log/' or - # '/var/log/') The agent will attempt to create this directory if it - # does not exist. - # log_file_path: 'log' - - # Optionally set the name of the log file, defaults to 'newrelic_agent.log' - # log_file_name: 'newrelic_agent.log' - - # The newrelic agent communicates with the service via http by - # default. If you want to communicate via https to increase - # security, then turn on SSL by setting this value to true. Note, - # this will result in increased CPU overhead to perform the - # encryption involved in SSL communication, but this work is done - # asynchronously to the threads that process your application code, - # so it should not impact response times. - ssl: false - - # EXPERIMENTAL: enable verification of the SSL certificate sent by - # the server. This setting has no effect unless SSL is enabled - # above. This may block your application. Only enable it if the data - # you send us needs end-to-end verified certificates. - # - # This means we cannot cache the DNS lookup, so each request to the - # service will perform a lookup. It also means that we cannot - # use a non-blocking lookup, so in a worst case, if you have DNS - # problems, your app may block indefinitely. - # verify_certificate: true - - # Set your application's Apdex threshold value with the 'apdex_t' - # setting, in seconds. The apdex_t value determines the buckets used - # to compute your overall Apdex score. - # Requests that take less than apdex_t seconds to process will be - # classified as Satisfying transactions; more than apdex_t seconds - # as Tolerating transactions; and more than four times the apdex_t - # value as Frustrating transactions. - # For more about the Apdex standard, see - # http://newrelic.com/docs/general/apdex - - apdex_t: 0.5 - - #============================== Browser Monitoring =============================== - # New Relic Real User Monitoring gives you insight into the performance real users are - # experiencing with your website. This is accomplished by measuring the time it takes for - # your users' browsers to download and render your web pages by injecting a small amount - # of JavaScript code into the header and footer of each page. - browser_monitoring: - # By default the agent automatically injects the monitoring JavaScript - # into web pages. Set this attribute to false to turn off this behavior. - auto_instrument: true - - # Proxy settings for connecting to the service. - # - # If a proxy is used, the host setting is required. Other settings - # are optional. Default port is 8080. - # - # proxy_host: hostname - # proxy_port: 8080 - # proxy_user: - # proxy_pass: - - - # Tells transaction tracer and error collector (when enabled) - # whether or not to capture HTTP params. When true, frameworks can - # exclude HTTP parameters from being captured. - # Rails: the RoR filter_parameter_logging excludes parameters - # Java: create a config setting called "ignored_params" and set it to - # a comma separated list of HTTP parameter names. - # ex: ignored_params: credit_card, ssn, password - capture_params: false - - - # Transaction tracer captures deep information about slow - # transactions and sends this to the service once a - # minute. Included in the transaction is the exact call sequence of - # the transactions including any SQL statements issued. - transaction_tracer: - - # Transaction tracer is enabled by default. Set this to false to - # turn it off. This feature is only available at the Professional - # and above product levels. - enabled: true - - # Threshold in seconds for when to collect a transaction - # trace. When the response time of a controller action exceeds - # this threshold, a transaction trace will be recorded and sent to - # the service. Valid values are any float value, or (default) - # "apdex_f", which will use the threshold for an dissatisfying - # Apdex controller action - four times the Apdex T value. - transaction_threshold: apdex_f - - # When transaction tracer is on, SQL statements can optionally be - # recorded. The recorder has three modes, "off" which sends no - # SQL, "raw" which sends the SQL statement in its original form, - # and "obfuscated", which strips out numeric and string literals - record_sql: obfuscated - - # Threshold in seconds for when to collect stack trace for a SQL - # call. In other words, when SQL statements exceed this threshold, - # then capture and send the current stack trace. This is - # helpful for pinpointing where long SQL calls originate from - stack_trace_threshold: 0.500 - - # Determines whether the agent will capture query plans for slow - # SQL queries. Only supported in mysql and postgres. Should be - # set to false when using other adapters. - # explain_enabled: true - - # Threshold for query execution time below which query plans will not - # not be captured. Relevant only when `explain_enabled` is true. - # explain_threshold: 0.5 - - # Error collector captures information about uncaught exceptions and - # sends them to the service for viewing - error_collector: - - # Error collector is enabled by default. Set this to false to turn - # it off. This feature is only available at the Professional and above - # product levels - enabled: true - - # Rails Only - tells error collector whether or not to capture a - # source snippet around the place of the error when errors are View - # related. - capture_source: true - - # To stop specific errors from reporting to New Relic, set this property - # to comma separated values. Default is to ignore routing errors - # which are how 404's get triggered. - # - ignore_errors: ActionController::RoutingError - - # (Advanced) Uncomment this to ensure the cpu and memory samplers - # won't run. Useful when you are using the agent to monitor an - # external resource - # disable_samplers: true - - # If you aren't interested in visibility in these areas, you can - # disable the instrumentation to reduce overhead. - # - # disable_view_instrumentation: true - # disable_activerecord_instrumentation: true - # disable_memcache_instrumentation: true - # disable_dj: true - - # If you're interested in capturing memcache keys as though they - # were SQL uncomment this flag. Note that this does increase - # overhead slightly on every memcached call, and can have security - # implications if your memcached keys are sensitive - # capture_memcache_keys: true - - # Certain types of instrumentation such as GC stats will not work if - # you are running multi-threaded. Please let us know. - # multi_threaded = false - -# Application Environments -# ------------------------------------------ -# Environment specific settings are in this section. -# For Rails applications, RAILS_ENV is used to determine the environment -# For Java applications, pass -Dnewrelic.environment to set -# the environment - -# NOTE if your application has other named environments, you should -# provide newrelic configuration settings for these environments here. - -development: - <<: *default_settings - # Turn off communication to New Relic service in development mode (also - # 'enabled'). - # NOTE: for initial evaluation purposes, you may want to temporarily - # turn the agent on in development mode. - monitor_mode: false - - # Rails Only - when running in Developer Mode, the New Relic Agent will - # present performance information on the last 100 transactions you have - # executed since starting the mongrel. - # NOTE: There is substantial overhead when running in developer mode. - # Do not use for production or load testing. - developer_mode: true - - # Enable textmate links - # textmate: true - -test: - <<: *default_settings - # It almost never makes sense to turn on the agent when running - # unit, functional or integration tests or the like. - monitor_mode: false - -# Turn on the agent in production for 24x7 monitoring. NewRelic -# testing shows an average performance impact of < 5 ms per -# transaction, you you can leave this on all the time without -# incurring any user-visible performance degradation. -production: - <<: *default_settings - monitor_mode: true - -# Many applications have a staging environment which behaves -# identically to production. Support for that environment is provided -# here. By default, the staging environment has the agent turned on. -staging: - <<: *default_settings - monitor_mode: true - app_name: <%= ENV["NEW_RELIC_APP_NAME"] %> (Staging) From d2eae501d22d668fcac014a452e8a56851acb312 Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Fri, 31 Aug 2018 22:38:38 +0200 Subject: [PATCH 30/37] :scissors: unused app/inputs/* (old simple_form overrides) --- app/inputs/collection_select2_input.rb | 5 ----- app/inputs/datepicker_input.rb | 6 ------ 2 files changed, 11 deletions(-) delete mode 100644 app/inputs/collection_select2_input.rb delete mode 100644 app/inputs/datepicker_input.rb diff --git a/app/inputs/collection_select2_input.rb b/app/inputs/collection_select2_input.rb deleted file mode 100644 index 2bcea6f65..000000000 --- a/app/inputs/collection_select2_input.rb +++ /dev/null @@ -1,5 +0,0 @@ -class CollectionSelect2Input < SimpleForm::Inputs::CollectionSelectInput - def input_html_classes - super.push("select2") - end -end diff --git a/app/inputs/datepicker_input.rb b/app/inputs/datepicker_input.rb deleted file mode 100644 index a1a1d31cd..000000000 --- a/app/inputs/datepicker_input.rb +++ /dev/null @@ -1,6 +0,0 @@ -class DatepickerInput < SimpleForm::Inputs::Base - def input - @builder.text_field(attribute_name, input_html_options) + \ - @builder.hidden_field(attribute_name, class: attribute_name.to_s + "-alt") - end -end From 452e5c4514cebc81735846ba4f445fa4159af825 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Sat, 1 Sep 2018 04:14:54 +0000 Subject: [PATCH 31/37] [Security] Bump ffi from 1.9.23 to 1.9.25 Bumps [ffi](https://github.com/ffi/ffi) from 1.9.23 to 1.9.25. **This update includes security fixes.** - [Release notes](https://github.com/ffi/ffi/releases) - [Changelog](https://github.com/ffi/ffi/blob/master/CHANGELOG.md) - [Commits](https://github.com/ffi/ffi/compare/1.9.23...1.9.25) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ffea63e66..d45812de0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -152,7 +152,7 @@ GEM i18n (~> 0.5) faraday (0.9.1) multipart-post (>= 1.2, < 3) - ffi (1.9.23) + ffi (1.9.25) formtastic (3.1.5) actionpack (>= 3.2.13) formtastic_i18n (0.6.0) From fee1aac95567b5cd34ec12696481fc75c18cd1dc Mon Sep 17 00:00:00 2001 From: Maxim Colls Date: Mon, 3 Sep 2018 20:43:33 +0100 Subject: [PATCH 32/37] Fixed migrations with defaults --- ...0180604145622_add_title_to_push_notification.rb | 3 +-- ...20180828160700_add_body_to_push_notification.rb | 9 +++++++++ ...20180831161349_add_data_to_push_notification.rb | 9 +++++++++ db/schema.rb | 14 ++++++++------ 4 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 db/migrate/20180828160700_add_body_to_push_notification.rb create mode 100644 db/migrate/20180831161349_add_data_to_push_notification.rb diff --git a/db/migrate/20180604145622_add_title_to_push_notification.rb b/db/migrate/20180604145622_add_title_to_push_notification.rb index 634012c81..9b4a91ed2 100644 --- a/db/migrate/20180604145622_add_title_to_push_notification.rb +++ b/db/migrate/20180604145622_add_title_to_push_notification.rb @@ -1,7 +1,6 @@ class AddTitleToPushNotification < ActiveRecord::Migration def up - add_column :push_notifications, :title, :string, null: false, default: 'Title for existing records' - change_column_default(:push_notifications, :title, nil) + add_column :push_notifications, :title, :string, null: false, default: '' end def down diff --git a/db/migrate/20180828160700_add_body_to_push_notification.rb b/db/migrate/20180828160700_add_body_to_push_notification.rb new file mode 100644 index 000000000..52e697ca0 --- /dev/null +++ b/db/migrate/20180828160700_add_body_to_push_notification.rb @@ -0,0 +1,9 @@ +class AddBodyToPushNotification < ActiveRecord::Migration + def up + add_column :push_notifications, :body, :string, null: false, default: '' + end + + def down + remove_column :push_notifications, :body + end +end diff --git a/db/migrate/20180831161349_add_data_to_push_notification.rb b/db/migrate/20180831161349_add_data_to_push_notification.rb new file mode 100644 index 000000000..410349f2f --- /dev/null +++ b/db/migrate/20180831161349_add_data_to_push_notification.rb @@ -0,0 +1,9 @@ +class AddDataToPushNotification < ActiveRecord::Migration + def up + add_column :push_notifications, :data, :json, null: false, default: '{}' + end + + def down + remove_column :push_notifications, :data + end +end diff --git a/db/schema.rb b/db/schema.rb index 7d3b07b2d..fb61c5627 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180604145622) do +ActiveRecord::Schema.define(version: 20180831161349) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -159,12 +159,14 @@ add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree create_table "push_notifications", force: :cascade do |t| - t.integer "event_id", null: false - t.integer "device_token_id", null: false + t.integer "event_id", null: false + t.integer "device_token_id", null: false t.datetime "processed_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "title", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "title", default: "", null: false + t.string "body", default: "", null: false + t.json "data", default: {}, null: false end create_table "transfers", force: :cascade do |t| From bcb86848eea95cb7c9833f28db89cb3035be2cbb Mon Sep 17 00:00:00 2001 From: Maxim Colls Date: Mon, 3 Sep 2018 20:44:33 +0100 Subject: [PATCH 33/37] Refactor PushNotificatiosn::Creator with a Base class --- app/jobs/create_push_notifications_job.rb | 6 ++- app/jobs/send_push_notifications_job.rb | 2 +- app/models/push_notification.rb | 4 +- app/services/push_notifications/broadcast.rb | 8 ++-- app/services/push_notifications/creator.rb | 32 -------------- .../push_notifications/creator/base.rb | 42 +++++++++++++++++++ .../push_notifications/creator/post.rb | 25 +++++++++++ .../create_push_notifications_job_spec.rb | 4 +- spec/models/push_notification_spec.rb | 4 +- .../push_notifications/broadcast_spec.rb | 9 ++-- .../{creator_spec.rb => post_spec.rb} | 12 ++---- 11 files changed, 93 insertions(+), 55 deletions(-) delete mode 100644 app/services/push_notifications/creator.rb create mode 100644 app/services/push_notifications/creator/base.rb create mode 100644 app/services/push_notifications/creator/post.rb rename spec/services/push_notifications/{creator_spec.rb => post_spec.rb} (70%) diff --git a/app/jobs/create_push_notifications_job.rb b/app/jobs/create_push_notifications_job.rb index 3e7ccff3b..64a7ab5a6 100644 --- a/app/jobs/create_push_notifications_job.rb +++ b/app/jobs/create_push_notifications_job.rb @@ -6,6 +6,10 @@ def perform(event_id:) raise 'A valid Event must be provided' unless event - ::PushNotifications::Creator.new(event: event).create! + if event.post_id + ::PushNotifications::Creator::Post.new(event: event).create! + else + raise "You need to define a PushNotifications::Creator class for this event type ##{event.id}" + end end end diff --git a/app/jobs/send_push_notifications_job.rb b/app/jobs/send_push_notifications_job.rb index 41835d74c..5bf79b546 100644 --- a/app/jobs/send_push_notifications_job.rb +++ b/app/jobs/send_push_notifications_job.rb @@ -2,7 +2,7 @@ class SendPushNotificationsJob < ActiveJob::Base queue_as :cron def perform - push_notifications = PushNotification.where(processed_at: nil) + push_notifications = PushNotification.where(processed_at: nil).limit(100) ::PushNotifications::Broadcast.new( push_notifications: push_notifications diff --git a/app/models/push_notification.rb b/app/models/push_notification.rb index 24ac3e3c8..3a61d845c 100644 --- a/app/models/push_notification.rb +++ b/app/models/push_notification.rb @@ -4,7 +4,5 @@ class PushNotification < ActiveRecord::Base validates :event, :device_token, :title, presence: true - def to - device_token.token - end + delegate :token, to: :device_token end diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index a33d41224..9681ea9d2 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -20,7 +20,8 @@ def send_notifications raise PostError, "HTTP response: #{response.code}, #{response.body}" end - push_notifications.update_all(processed_at: Time.now.utc) + now = Time.now.utc + push_notifications.update_all(processed_at: now, updated_at: now) end private @@ -30,9 +31,10 @@ def send_notifications def notifications push_notifications.map do |push_notification| { - to: push_notification.to, + to: push_notification.token, title: push_notification.title, - body: 'WAT!?' + body: push_notification.body, + data: push_notification.data } end end diff --git a/app/services/push_notifications/creator.rb b/app/services/push_notifications/creator.rb deleted file mode 100644 index 076f20acf..000000000 --- a/app/services/push_notifications/creator.rb +++ /dev/null @@ -1,32 +0,0 @@ -module PushNotifications - class Creator - # Given an Event it will create as many PushNotification resources - # necessary as the resource associated to the Event will require. - # - # @param [Hash] event: - def initialize(event:) - @event = event - end - - def create! - event_notifier = EventNotifierFactory.new(event: event).build - event_notifier.device_tokens.each do |device_token| - PushNotification.create!( - event: event, - device_token: device_token, - title: title - ) - end - end - - private - - attr_accessor :event - - # TODO: For now we only create push notifications for Post - # - def title - event.post.title - end - end -end diff --git a/app/services/push_notifications/creator/base.rb b/app/services/push_notifications/creator/base.rb new file mode 100644 index 000000000..b7fdec805 --- /dev/null +++ b/app/services/push_notifications/creator/base.rb @@ -0,0 +1,42 @@ +module PushNotifications + module Creator + class Base + # Given an Event it will create as many PushNotification resources + # necessary as the resource associated to the Event will require. + # + # @param [Hash] event: + def initialize(event:) + @event = event + end + + def create! + event_notifier = EventNotifierFactory.new(event: event).build + event_notifier.device_tokens.each do |device_token| + PushNotification.create!( + event: event, + device_token: device_token, + title: title, + body: body, + data: data + ) + end + end + + private + + attr_accessor :event + + def title + raise 'implement the private method `title`' + end + + def body + raise 'implement the private method `body`' + end + + def data + raise 'implement the private method `data`' + end + end + end +end diff --git a/app/services/push_notifications/creator/post.rb b/app/services/push_notifications/creator/post.rb new file mode 100644 index 000000000..4579aa961 --- /dev/null +++ b/app/services/push_notifications/creator/post.rb @@ -0,0 +1,25 @@ +module PushNotifications + module Creator + class Post < Base + private + + def title + event.post.title + end + + def body + event.post.description&.truncate(20) || 'No description' + end + + def data + if event.post.class.to_s == 'Offer' + { url: Rails.application.routes.url_helpers.offer_path(event.post) } + elsif event.post.class.to_s == 'Inquiry' + { url: Rails.application.routes.url_helpers.inquiry_path(event.post) } + else + {} + end + end + end + end +end diff --git a/spec/jobs/create_push_notifications_job_spec.rb b/spec/jobs/create_push_notifications_job_spec.rb index 34bcc0414..0ff5a54c9 100644 --- a/spec/jobs/create_push_notifications_job_spec.rb +++ b/spec/jobs/create_push_notifications_job_spec.rb @@ -18,8 +18,8 @@ let(:event_id) { event.id } it 'calls the PushNotification creator' do - creator = instance_double(::PushNotifications::Creator) - expect(::PushNotifications::Creator).to receive(:new) + creator = instance_double(::PushNotifications::Creator::Post) + expect(::PushNotifications::Creator::Post).to receive(:new) .with(event: event) .and_return(creator) expect(creator).to receive(:create!) diff --git a/spec/models/push_notification_spec.rb b/spec/models/push_notification_spec.rb index 974a51778..7258af63b 100644 --- a/spec/models/push_notification_spec.rb +++ b/spec/models/push_notification_spec.rb @@ -15,12 +15,12 @@ it { is_expected.to have_db_column(:device_token_id) } end - describe "#to" do + describe "#token" do let(:device_token) { Fabricate.build(:device_token, token: 'token') } let(:push_notification) { described_class.new(device_token: device_token) } it 'returns the associated DeviceToken\'s token' do - expect(push_notification.to).to eq('token') + expect(push_notification.token).to eq('token') end end end diff --git a/spec/services/push_notifications/broadcast_spec.rb b/spec/services/push_notifications/broadcast_spec.rb index 3188baefd..cd16618de 100644 --- a/spec/services/push_notifications/broadcast_spec.rb +++ b/spec/services/push_notifications/broadcast_spec.rb @@ -9,9 +9,10 @@ let(:push_notifications) { PushNotification.all } let(:notification) do { - to: push_notification.to, + to: push_notification.token, title: push_notification.title, - body: 'WAT!?' + body: push_notification.body, + data: push_notification.data } end let(:uri) { URI('https://exp.host/--/api/v2/push/send') } @@ -24,7 +25,9 @@ :push_notification, event: event_created, device_token: device_token, - title: 'Hola' + title: 'Hola', + body: 'Caracola', + data: {} ) end diff --git a/spec/services/push_notifications/creator_spec.rb b/spec/services/push_notifications/post_spec.rb similarity index 70% rename from spec/services/push_notifications/creator_spec.rb rename to spec/services/push_notifications/post_spec.rb index 3a38552ec..43d2b6165 100644 --- a/spec/services/push_notifications/creator_spec.rb +++ b/spec/services/push_notifications/post_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -RSpec.describe PushNotifications::Creator do +RSpec.describe PushNotifications::Creator::Post do let(:user) { Fabricate(:user) } let!(:device_token) { Fabricate(:device_token, user: user, token: 'aloha') } let(:organization) { Fabricate(:organization) } @@ -14,13 +14,9 @@ describe '#create!' do it 'creates as many PushNotification resources as needed' do - expect(PushNotification).to receive(:create!).with( - event: event, - device_token: device_token, - title: event.post.title - ).once - - creator.create! + expect { + creator.create! + }.to change{PushNotification.count}.by(1) end end end From 49606643b3bd977bd4ed033e26791c40277b4742 Mon Sep 17 00:00:00 2001 From: sseerrggii Date: Tue, 18 Sep 2018 14:59:09 +0200 Subject: [PATCH 34/37] en.yml --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index c69407497..8c5b4361b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -403,7 +403,7 @@ en: title: The software designed by and for title2: Time Banks app-mobile: Mobile App - app-mobile-text: The mobile app TimeOverflow for Android and iOS is available for download.
    This app has been possible thanks to the collaboration of the municipality of Barcelona, program %{impulsem_link} (Barcelona Activa) 2017-2018 + app-mobile-text: The mobile app TimeOverflow is available.
    This app has been possible thanks to the collaboration of the municipality of Barcelona, program %{impulsem_link} (Barcelona Activa) 2017-2018 impulsem-link: "Impulsem el que fas" posts: show: From c6e9934b9e646c3c0e4e66e59a3521a7e422ac2b Mon Sep 17 00:00:00 2001 From: sseerrggii Date: Tue, 18 Sep 2018 15:01:46 +0200 Subject: [PATCH 35/37] ca es eu pt-BR --- config/locales/ca.yml | 8 ++++---- config/locales/es.yml | 8 ++++---- config/locales/eu.yml | 6 +++--- config/locales/pt-BR.yml | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 38250ae2f..a25bfbf59 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -374,14 +374,13 @@ ca: pages: about: app-mobile: Aplicació Mòbil - app-mobile-text: L'aplicació mòbil de TimeOverflow està disponible per Android i IOS
    Aquesta app ha estat possible gràcies a la col·laboració de l'Ajuntament de Barcelona, a través del programa %{impulsem_link} (Barcelona Activa) 2017-2018 + app-mobile-text: L'aplicació mòbil de TimeOverflow està disponible
    Aquesta app ha estat possible gràcies a la col·laboració de l'Ajuntament de Barcelona, a través del programa %{impulsem_link} (Barcelona Activa) 2017-2018 banner-button: Sol·licita accés banner-subtitle: Us ajudarem a posar-lo en marxa o fer-vos una demostració banner-title: Ets un Banc de Temps? donate-link: Dona 1€ al mes donate-text: Amb la finalitat de donar suport a moltes comunitats la associació ADBdT ofereix la plataforma TimeOverflow a tots los Bancs de Temps. Considera %{donate_link} per contribuir a les despeses de manteniment i innovació. donate-title: Participa amb una donació - donate_link: donar 1€ al mes empower-adbdt: ADBdT empower-adbdt-title: Associació pel Desenvolupament dels Bancs de Temps empower-coopdevs: CoopDevs @@ -499,9 +498,7 @@ ca: edit: edit_user: Canviar usuari form: - admin_warning: Atenció!!! Estàs atorgant poders a aquest usuari!! notifications: Notificacions - superadmin_warning: Atenció!!! Estàs atorgant PODERS DIVINS a aquest usuari!! give_time: give_time: Donar Temps a index: @@ -515,6 +512,9 @@ ca: manage_warning_angular: Vas a canviar els permisos de l'usuari {{username}} members: Membres user_created: Usuari %{uid} %{name} guardat + member_card: + active_ago: + no_activity: new: cancel: Cancel·lar create_more_users_button: Crear i introduir un nou usuari diff --git a/config/locales/es.yml b/config/locales/es.yml index b257d99ba..ec0f68f76 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -374,14 +374,13 @@ es: pages: about: app-mobile: App Móvil - app-mobile-text: La app móvil de TimeOverflow está disponible para Android y IOS
    Esta app ha sido posible gracias a la colaboración del Ayuntamiento de Barcelona, a través del programa %{impulsem_link} (Barcelona Activa) 2017-2018 + app-mobile-text: La app móvil de TimeOverflow está disponible
    Esta app ha sido posible gracias a la colaboración del Ayuntamiento de Barcelona, a través del programa %{impulsem_link} (Barcelona Activa) 2017-2018 banner-button: Solicita acceso banner-subtitle: Os ayudaremos a ponerlo en marcha o a haceros una demostración banner-title: "¿Eres un Banco de Tiempo?" donate-link: Donar 1€ al mes donate-text: Con el fin de apoyar a muchas comunidades la asociación ADBdT ofrece la plataforma TimeOverflow a todos los Bancos de Tiempo. Considera %{donate_link} para contribuir a los gastos de mantenimiento e innovación. donate-title: Participa con una donación - donate_link: donar 1€ al mes empower-adbdt: ADBdT empower-adbdt-title: Asociación para el Desarrollo de los Bancos de Tiempo empower-coopdevs: CoopDevs @@ -499,9 +498,7 @@ es: edit: edit_user: Cambiar usuario form: - admin_warning: Atención!!! Estás dando poderes a este usuario!! notifications: Notificaciones - superadmin_warning: Atención!!! Estás dando PODERES DIVINOS a este usuario!! give_time: give_time: Dar Tiempo a index: @@ -515,6 +512,9 @@ es: manage_warning_angular: Va a cambiar los privilegios del usuario {{username}} members: Miembros user_created: Usuario %{uid} %{name} guardado + member_card: + active_ago: + no_activity: new: cancel: Cancelar create_more_users_button: Crear e introducir otro usuario diff --git a/config/locales/eu.yml b/config/locales/eu.yml index cdb099c0d..ee6060db4 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -387,7 +387,6 @@ eu: donate-link: donate-text: komunitate askori babesteko asmotan ADBdt elkarteak , TimeOverflow plataforma eskaintzen die Denbora Banku guztiei. Hausnar ezazu %{donate_link} mantenu eta berritze lanetan laguntzeko. donate-title: Laguntzan parte hartu - donate_link: Hilean €1 ematea empower-adbdt: ADBdt empower-adbdt-title: Denbora Bankuen garapenerako elkartea empower-coopdevs: CoopDevs @@ -505,9 +504,7 @@ eu: edit: edit_user: Erabiltzailea aldatu form: - admin_warning: Kontuz!!! Erabiltzaile honi boterea ematen ari zara. notifications: Jakinarazpen - superadmin_warning: Kontuz!!! Erabiltzaile honi izugarrizko boterea ematen ari zara. give_time: give_time: honi denbora eman index: @@ -521,6 +518,9 @@ eu: manage_warning_angular: " {{username}} erabiltzailearen onurak, aldatuko diztuzu" members: user_created: "%{uid} %{name} erabiltzailea gorde da" + member_card: + active_ago: + no_activity: new: cancel: Deuseztatu create_more_users_button: Beste erabiltzaile bat sortu eta sartu diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index fba1b09f6..a1b31f8c6 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -381,7 +381,6 @@ pt-BR: donate-link: donate-text: donate-title: - donate_link: empower-adbdt: ADBdt empower-adbdt-title: Associação para o Desenvolvimento dos Bancos de Tempo empower-coopdevs: CoopDevs @@ -499,9 +498,7 @@ pt-BR: edit: edit_user: Trocar usuário form: - admin_warning: Atenção!!! Você está dando poderes a este usuário!! notifications: Notificações - superadmin_warning: Atenção!!! Você está dando PODERES DIVINOS a este usuário!! give_time: give_time: Dar Tempo a index: @@ -515,6 +512,9 @@ pt-BR: manage_warning_angular: Mudará os privilégios do usuário {{username}} members: user_created: Usuário %{uid} %{name} guardado + member_card: + active_ago: + no_activity: new: cancel: Cancelar create_more_users_button: Criar e introduzir outro usuário From 14fe6bc75bc42bfb8ebf7e038b8c8aa70859d06a Mon Sep 17 00:00:00 2001 From: Marc Anguera Insa Date: Wed, 19 Sep 2018 21:42:31 +0200 Subject: [PATCH 36/37] Admin section: Logout user if deleted organization is current_organization --- app/admin/organization.rb | 13 +++++++++++++ spec/admin/organizations_controller_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 spec/admin/organizations_controller_spec.rb diff --git a/app/admin/organization.rb b/app/admin/organization.rb index 8d7f4a94e..873ec46fc 100644 --- a/app/admin/organization.rb +++ b/app/admin/organization.rb @@ -27,6 +27,19 @@ f.actions end + controller do + def destroy + resource.destroy + + if resource == current_organization + sign_out(current_user) + redirect_to root_path + else + redirect_to admin_organizations_path + end + end + end + filter :name filter :city, as: :select, collection: -> { Organization.pluck(:city).uniq } filter :neighborhood diff --git a/spec/admin/organizations_controller_spec.rb b/spec/admin/organizations_controller_spec.rb new file mode 100644 index 000000000..743051c07 --- /dev/null +++ b/spec/admin/organizations_controller_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +RSpec.describe Admin::OrganizationsController, type: :controller do + let(:organization) { Fabricate(:organization) } + let(:member) { Fabricate(:member, organization: organization) } + let(:user) { member.user } + + before do + login(user) + allow(controller).to receive(:authenticate_superuser!).and_return(true) + end + + describe "DELETE #destroy" do + it "sign out if current user is logged to organization deleted" do + expect { + delete :destroy, id: organization.id + }.to change { controller.current_user }.to nil + end + end +end \ No newline at end of file From cbe7e14e0a5affc0e3677e60f21d01b74f2c18f6 Mon Sep 17 00:00:00 2001 From: sseerrggii Date: Thu, 20 Sep 2018 13:04:44 +0200 Subject: [PATCH 37/37] fix cancel_membership wrong key name --- app/views/users/_cancel_membership_link.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/users/_cancel_membership_link.html.erb b/app/views/users/_cancel_membership_link.html.erb index 393bfb567..884e27bec 100644 --- a/app/views/users/_cancel_membership_link.html.erb +++ b/app/views/users/_cancel_membership_link.html.erb @@ -3,5 +3,5 @@ method: :delete, data: { confirm: t('users.user_rows.cancel_warning', user: member.username) } do %> <%= glyph :ban_circle %> - <%= t('global.cancel_member') %> + <%= t('global.cancel_membership') %> <% end %> \ No newline at end of file