dune-admin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +18 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +14 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +74 -0
  10. data/Rakefile +14 -0
  11. data/app/assets/images/dune/admin/.gitkip +0 -0
  12. data/app/assets/javascripts/dune-admin.js +2 -0
  13. data/app/assets/javascripts/dune/admin/admin.js.coffee +11 -0
  14. data/app/assets/javascripts/dune/admin/channels/new.js.coffee +14 -0
  15. data/app/assets/javascripts/dune/admin/modules/sort.js.coffee +44 -0
  16. data/app/assets/stylesheets/dune/admin/.gitkip +0 -0
  17. data/app/assets/stylesheets/dune/admin/admin.sass +37 -0
  18. data/app/assets/stylesheets/neighborly-admin.sass +1 -0
  19. data/app/controllers/dune/admin/base_controller.rb +25 -0
  20. data/app/controllers/dune/admin/channels/members_controller.rb +46 -0
  21. data/app/controllers/dune/admin/channels_controller.rb +49 -0
  22. data/app/controllers/dune/admin/contacts_controller.rb +9 -0
  23. data/app/controllers/dune/admin/contributions_controller.rb +33 -0
  24. data/app/controllers/dune/admin/dashboard_controller.rb +8 -0
  25. data/app/controllers/dune/admin/financials_controller.rb +33 -0
  26. data/app/controllers/dune/admin/press_assets_controller.rb +26 -0
  27. data/app/controllers/dune/admin/projects_controller.rb +80 -0
  28. data/app/controllers/dune/admin/reports/base_controller.rb +8 -0
  29. data/app/controllers/dune/admin/reports/contribution_reports_controller.rb +8 -0
  30. data/app/controllers/dune/admin/reports/funding_raised_per_project_reports_controller.rb +4 -0
  31. data/app/controllers/dune/admin/reports/statistics_controller.rb +5 -0
  32. data/app/controllers/dune/admin/tags_controller.rb +35 -0
  33. data/app/controllers/dune/admin/users_controller.rb +27 -0
  34. data/app/models/dune/admin/.gitkip +0 -0
  35. data/app/models/dune/admin/contribution_concern.rb +23 -0
  36. data/app/models/dune/admin/funding_raised_per_project_report.rb +5 -0
  37. data/app/models/dune/admin/project_concern.rb +41 -0
  38. data/app/models/dune/admin/statistics.rb +5 -0
  39. data/app/models/dune/admin/user_concern.rb +13 -0
  40. data/app/policies/dune/admin/admin_policy.rb +7 -0
  41. data/app/views/dune/admin/.gitkip +0 -0
  42. data/app/views/dune/admin/channels/_form.html.slim +98 -0
  43. data/app/views/dune/admin/channels/edit.html.slim +7 -0
  44. data/app/views/dune/admin/channels/index.html.slim +58 -0
  45. data/app/views/dune/admin/channels/members/index.html.slim +38 -0
  46. data/app/views/dune/admin/channels/members/new.html.slim +11 -0
  47. data/app/views/dune/admin/channels/new.html.slim +7 -0
  48. data/app/views/dune/admin/contacts/index.html.slim +32 -0
  49. data/app/views/dune/admin/contacts/show.html.slim +34 -0
  50. data/app/views/dune/admin/contributions/index.html.slim +138 -0
  51. data/app/views/dune/admin/dashboard/index.html.slim +65 -0
  52. data/app/views/dune/admin/financials/index.html.slim +88 -0
  53. data/app/views/dune/admin/layouts/_menu.html.slim +11 -0
  54. data/app/views/dune/admin/press_assets/_form.html.slim +11 -0
  55. data/app/views/dune/admin/press_assets/edit.html.slim +9 -0
  56. data/app/views/dune/admin/press_assets/index.html.slim +32 -0
  57. data/app/views/dune/admin/press_assets/new.html.slim +9 -0
  58. data/app/views/dune/admin/projects/index.html.slim +151 -0
  59. data/app/views/dune/admin/projects/populate_contribution.html.slim +48 -0
  60. data/app/views/dune/admin/tags/_form.html.slim +4 -0
  61. data/app/views/dune/admin/tags/edit.html.slim +7 -0
  62. data/app/views/dune/admin/tags/index.html.slim +44 -0
  63. data/app/views/dune/admin/tags/new.html.slim +7 -0
  64. data/app/views/dune/admin/users/index.html.slim +68 -0
  65. data/bin/rails +8 -0
  66. data/config/locales/en.yml +274 -0
  67. data/config/routes.rb +47 -0
  68. data/db/migrate/20141005184741_create_dune_admin_funding_raised_per_project_reports.rb +21 -0
  69. data/db/migrate/20141005191509_create_dune_admin_statistics.rb +55 -0
  70. data/dune-admin.gemspec +27 -0
  71. data/lib/dune/admin.rb +10 -0
  72. data/lib/dune/admin/engine.rb +13 -0
  73. data/lib/dune/admin/version.rb +5 -0
  74. data/spec/controllers/dune/admin/channels/members_controller_spec.rb +119 -0
  75. data/spec/controllers/dune/admin/channels_controller_spec.rb +161 -0
  76. data/spec/controllers/dune/admin/contacts_controller_spec.rb +23 -0
  77. data/spec/controllers/dune/admin/cotributions_controller_spec.rb +130 -0
  78. data/spec/controllers/dune/admin/dasboard_controller_spec.rb +18 -0
  79. data/spec/controllers/dune/admin/financials_controller_spec.rb +45 -0
  80. data/spec/controllers/dune/admin/press_assets_controller_spec.rb +138 -0
  81. data/spec/controllers/dune/admin/projects_controller_spec.rb +201 -0
  82. data/spec/controllers/dune/admin/tags_controller_spec.rb +137 -0
  83. data/spec/controllers/dune/admin/users_controller_spec.rb +30 -0
  84. data/spec/models/dune/admin/contribution_concern_spec.rb +19 -0
  85. data/spec/models/dune/admin/project_concern_spec.rb +56 -0
  86. data/spec/models/dune/admin/user_concern_spec.rb +65 -0
  87. data/spec/policies/dune/admin/admin_policy_spec.rb +22 -0
  88. data/spec/spec_helper.rb +40 -0
  89. metadata +237 -0
data/config/routes.rb ADDED
@@ -0,0 +1,47 @@
1
+ Dune::Admin::Engine.routes.draw do
2
+ root to: 'dashboard#index'
3
+ resources :tags, except: [:show]
4
+ resources :press_assets, except: [:show]
5
+ resources :financials, only: [ :index ]
6
+ resources :users, only: [ :index ]
7
+
8
+ resources :channels, except: [:show] do
9
+ member do
10
+ put 'push_to_draft'
11
+ put 'push_to_online'
12
+ end
13
+
14
+ resources :members, only: [:index, :new, :create, :destroy], controller: 'channels/members'
15
+ end
16
+
17
+ resources :projects, only: [ :index, :update, :destroy ] do
18
+ member do
19
+ put 'launch'
20
+ put 'reject'
21
+ put 'push_to_draft'
22
+ put 'approve'
23
+ get 'populate_contribution'
24
+ post 'populate'
25
+ end
26
+ end
27
+
28
+ resources :contributions, only: [ :index, :update ] do
29
+ member do
30
+ put 'confirm'
31
+ put 'pendent'
32
+ put 'change_reward'
33
+ put 'refund'
34
+ put 'hide'
35
+ put 'cancel'
36
+ put 'push_to_trash'
37
+ end
38
+ end
39
+
40
+ namespace :reports do
41
+ resources :contribution_reports, only: [ :index ]
42
+ resources :funding_raised_per_project_reports, only: [ :index ]
43
+ resources :statistics, only: [ :index ]
44
+ end
45
+
46
+ resources :contacts, only: [:index, :show]
47
+ end
@@ -0,0 +1,21 @@
1
+ class CreateDuneAdminFundingRaisedPerProjectReports < ActiveRecord::Migration
2
+ def up
3
+ execute <<-SQL
4
+ CREATE OR REPLACE VIEW dune_admin_funding_raised_per_project_reports AS
5
+ SELECT
6
+ project.id AS project_id,
7
+ project.name AS project_name,
8
+ sum(contributions.value) AS total_raised,
9
+ count(*) AS total_backs,
10
+ count(DISTINCT contributions.user_id) AS total_backers
11
+ FROM contributions
12
+ JOIN projects AS project ON project.id = contributions.project_id
13
+ WHERE contributions.state::text <> ALL (ARRAY['waiting_confirmation'::character varying::text, 'pending'::character varying::text, 'canceled'::character varying::text, 'deleted'])
14
+ GROUP BY project.id;
15
+ SQL
16
+ end
17
+
18
+ def down
19
+ drop_view :dune_admin_funding_raised_per_project_reports
20
+ end
21
+ end
@@ -0,0 +1,55 @@
1
+ class CreateDuneAdminStatistics < ActiveRecord::Migration
2
+ def up
3
+ execute <<-SQL
4
+ CREATE OR REPLACE VIEW dune_admin_statistics AS
5
+ SELECT
6
+ ( SELECT count(*) AS count FROM users) AS total_users,
7
+ ( SELECT count(*) AS count FROM users WHERE profile_type::text = 'organization'::text ) AS total_organization_users,
8
+ ( SELECT count(*) AS count FROM users WHERE profile_type::text = 'personal'::text ) AS total_personal_users,
9
+ ( SELECT count(*) AS count FROM users WHERE profile_type::text = 'channel'::text ) AS total_channel_users,
10
+ ( SELECT COUNT(*) FROM ( SELECT DISTINCT address_city, address_state FROM projects ) AS count ) AS total_communities,
11
+ contributions_totals.total_contributions,
12
+ contributions_totals.total_contributors,
13
+ contributions_totals.total_contributed,
14
+ projects_totals.total_projects,
15
+ projects_totals.total_projects_success,
16
+ projects_totals.total_projects_online,
17
+ projects_totals.total_projects_draft,
18
+ projects_totals.total_projects_soon
19
+ FROM ( SELECT count(*) AS total_contributions,
20
+ count(DISTINCT contributions.user_id) AS total_contributors,
21
+ sum(contributions.value) AS total_contributed
22
+ FROM contributions
23
+ WHERE contributions.state::text <> ALL (ARRAY['waiting_confirmation'::character varying::text, 'pending'::character varying::text, 'canceled'::character varying::text, 'deleted'])) contributions_totals,
24
+ ( SELECT count(*) AS total_projects,
25
+ count(
26
+ CASE
27
+ WHEN projects.state::text = 'draft'::text THEN 1
28
+ ELSE NULL::integer
29
+ END) AS total_projects_draft,
30
+ count(
31
+ CASE
32
+ WHEN projects.state::text = 'soon'::text THEN 1
33
+ ELSE NULL::integer
34
+ END) AS total_projects_soon,
35
+ count(
36
+ CASE
37
+ WHEN projects.state::text = 'successful'::text THEN 1
38
+ ELSE NULL::integer
39
+ END) AS total_projects_success,
40
+ count(
41
+ CASE
42
+ WHEN projects.state::text = 'online'::text THEN 1
43
+ ELSE NULL::integer
44
+ END) AS total_projects_online
45
+ FROM projects
46
+ WHERE projects.state::text <> ALL (ARRAY['deleted'::character varying::text, 'rejected'::character varying::text])) projects_totals;
47
+ SQL
48
+ end
49
+
50
+ def down
51
+ execute <<-SQL
52
+ DROP VIEW dune_admin_statistics;
53
+ SQL
54
+ end
55
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dune/admin/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'dune-admin'
8
+ spec.version = Dune::Admin::VERSION
9
+ spec.authors = ['Pierre Legrand']
10
+ spec.email = %w(legrand.work@gmail.com)
11
+ spec.summary = 'Dune Admin.'
12
+ spec.description = 'This is the admin of dune-investissement'
13
+ spec.homepage = 'https://github.com/FromUte/dune-admin'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'rails', '~> 4.0'
22
+ spec.add_dependency 'best_in_place', '~> 3.0.0.rc1'
23
+ spec.add_dependency 'postgres-copy', '~> 0.8.0', '>= 0.8.0'
24
+ spec.add_development_dependency 'rake', '~> 10.2'
25
+ spec.add_development_dependency 'rspec-rails', '~> 2.14'
26
+ spec.add_development_dependency 'factory_girl_rails', '~> 4.3'
27
+ end
data/lib/dune/admin.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'dune/admin/engine'
2
+ require 'dune/admin/version'
3
+ require 'best_in_place'
4
+ require 'postgres-copy'
5
+
6
+ module Dune
7
+ module Admin
8
+ # Your code goes here...
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ module Dune
2
+ module Admin
3
+ class Engine < ::Rails::Engine
4
+ isolate_namespace Dune::Admin
5
+
6
+ config.to_prepare do
7
+ ::Project.send(:include, Dune::Admin::ProjectConcern)
8
+ ::User.send(:include, Dune::Admin::UserConcern)
9
+ ::Contribution.send(:include, Dune::Admin::ContributionConcern)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Dune
2
+ module Admin
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Admin::Channels::MembersController do
4
+ routes { Dune::Admin::Engine.routes }
5
+
6
+ subject{ response }
7
+ let(:admin) { create(:user, admin: true) }
8
+ let(:channel) { create(:channel) }
9
+ let(:current_user){ admin }
10
+
11
+ before do
12
+ controller.stub(:current_user).and_return(current_user)
13
+ end
14
+
15
+ describe "GET index" do
16
+ context "when I'm not logged in" do
17
+ let(:current_user){ nil }
18
+ before do
19
+ get :index, channel_id: channel
20
+ end
21
+ it{ should redirect_to '/login' }
22
+ end
23
+
24
+ context "when I'm logged as admin" do
25
+ before do
26
+ get :index, channel_id: channel
27
+ end
28
+ its(:status){ should == 200 }
29
+ end
30
+ end
31
+
32
+ describe "GET new" do
33
+ context "when I'm not logged in" do
34
+ let(:current_user){ nil }
35
+ before do
36
+ get :new, channel_id: channel
37
+ end
38
+ it{ should redirect_to '/login' }
39
+ end
40
+
41
+ context "when I'm logged as admin" do
42
+ before do
43
+ get :new, channel_id: channel
44
+ end
45
+ its(:status){ should == 200 }
46
+ end
47
+ end
48
+
49
+ describe "POST create" do
50
+ context "when I'm not logged in" do
51
+ let(:current_user){ nil }
52
+ before do
53
+ post :create, channel_id: channel
54
+ end
55
+ it{ should redirect_to '/login' }
56
+ end
57
+
58
+ context "when I'm logged as admin" do
59
+ let(:user) { create(:user) }
60
+
61
+ context 'when the user does not exists' do
62
+ before do
63
+ post :create, channel_id: channel, user_id: 'not_exist'
64
+ end
65
+
66
+ it { expect(flash.alert).to eq(I18n.t('dune.admin.channels.members.messages.user_not_found')) }
67
+ it { should redirect_to channel_members_path(channel) }
68
+ end
69
+
70
+ context 'when the user has not channel' do
71
+ before do
72
+ post :create, channel_id: channel, user_id: user.id
73
+ end
74
+
75
+ it 'should assign the user to the channel' do
76
+ expect(channel.members).to eq [user]
77
+ end
78
+
79
+ it { expect(flash.notice).to eq(I18n.t('dune.admin.channels.members.messages.success')) }
80
+ it { should redirect_to channel_members_path(channel) }
81
+ end
82
+
83
+ context 'when the user has a channel' do
84
+ before do
85
+ channel.members << user
86
+ channel.save
87
+ post :create, channel_id: channel, user_id: user.id
88
+ end
89
+
90
+ it { expect(flash.alert).to eq(I18n.t('dune.admin.channels.members.messages.already_a_member')) }
91
+ it { should redirect_to channel_members_path(channel) }
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "DELETE destroy" do
97
+ let(:user) { create(:user) }
98
+ before { channel.members << user; channel.save }
99
+
100
+ context "when I'm not logged in" do
101
+ let(:current_user){ nil }
102
+ before do
103
+ delete :destroy, id: user, channel_id: channel
104
+ end
105
+ it{ should redirect_to '/login' }
106
+ end
107
+
108
+ context "when I'm logged as admin" do
109
+ before { delete :destroy, id: user, channel_id: channel }
110
+
111
+ it{ should redirect_to channel_members_path(channel) }
112
+
113
+ it 'should remove the user from channel members' do
114
+ expect(channel.reload.members).to eq []
115
+ end
116
+ end
117
+ end
118
+
119
+ end
@@ -0,0 +1,161 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dune::Admin::ChannelsController do
4
+ routes { Dune::Admin::Engine.routes }
5
+ subject{ response }
6
+ let(:admin) { create(:user, admin: true) }
7
+ let(:current_user){ admin }
8
+
9
+ before do
10
+ controller.stub(:current_user).and_return(current_user)
11
+ end
12
+
13
+ describe 'PUT push_to_draft' do
14
+ let(:channel) { create(:channel, state: 'online') }
15
+ subject { channel.draft? }
16
+
17
+ before do
18
+ put :push_to_draft, id: channel
19
+ channel.reload
20
+ end
21
+
22
+ it { should be_true }
23
+ end
24
+
25
+ describe 'PUT push_to_online' do
26
+ let(:channel) { create(:channel, state: 'draft') }
27
+ subject { channel.online? }
28
+
29
+ before do
30
+ put :push_to_online, id: channel
31
+ channel.reload
32
+ end
33
+
34
+ it { should be_true }
35
+ end
36
+
37
+ describe "GET index" do
38
+ context "when I'm not logged in" do
39
+ let(:current_user){ nil }
40
+ before do
41
+ get :index
42
+ end
43
+ it{ should redirect_to '/login' }
44
+ end
45
+
46
+ context "when I'm logged as admin" do
47
+ before do
48
+ get :index
49
+ end
50
+ its(:status){ should == 200 }
51
+ end
52
+ end
53
+
54
+ describe "GET edit" do
55
+ let(:channel) { create(:channel) }
56
+ context "when I'm not logged in" do
57
+ let(:current_user){ nil }
58
+ before do
59
+ get :edit, id: channel
60
+ end
61
+ it{ should redirect_to '/login' }
62
+ end
63
+
64
+ context "when I'm logged as admin" do
65
+ before do
66
+ get :edit, id: channel
67
+ end
68
+ its(:status){ should == 200 }
69
+
70
+ it 'should assigns the correct resource' do
71
+ expect(assigns(:channel)).to eq channel
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "PUT update" do
77
+ let(:channel) { create(:channel) }
78
+
79
+ context "when I'm not logged in" do
80
+ let(:current_user){ nil }
81
+ before do
82
+ put :update, id: channel
83
+ end
84
+ it{ should redirect_to '/login' }
85
+ end
86
+
87
+ context "when I'm logged as admin" do
88
+ before do
89
+ put :update, id: channel, channel: { name: 'Updated name!' }
90
+ end
91
+
92
+ it{ should redirect_to channels_path }
93
+
94
+ it 'should create a new channel' do
95
+ expect(channel.reload.name).to eq 'Updated name!'
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "GET new" do
101
+ context "when I'm not logged in" do
102
+ let(:current_user){ nil }
103
+ before do
104
+ get :new
105
+ end
106
+ it{ should redirect_to '/login' }
107
+ end
108
+
109
+ context "when I'm logged as admin" do
110
+ before do
111
+ get :new
112
+ end
113
+ its(:status){ should == 200 }
114
+ end
115
+ end
116
+
117
+ describe "POST create" do
118
+ context "when I'm not logged in" do
119
+ let(:current_user){ nil }
120
+ before do
121
+ post :create
122
+ end
123
+ it{ should redirect_to '/login' }
124
+ end
125
+
126
+ context "when I'm logged as admin" do
127
+ before do
128
+ post :create, channel: build(:channel).attributes
129
+ end
130
+
131
+ it{ should redirect_to channels_path }
132
+
133
+ it 'should create a new channel' do
134
+ expect(Channel.all).to have(1).channel
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "DELETE destroy" do
140
+ let(:channel) { create(:channel, state: 'online') }
141
+
142
+ context "when I'm not logged in" do
143
+ let(:current_user){ nil }
144
+ before do
145
+ delete :destroy, id: channel
146
+ end
147
+ it{ should redirect_to '/login' }
148
+ end
149
+
150
+ context "when I'm logged as admin" do
151
+ before { delete :destroy, id: channel }
152
+
153
+ it{ should redirect_to channels_path }
154
+
155
+ it 'should destroy the channel' do
156
+ expect{ channel.reload }.to raise_error(ActiveRecord::RecordNotFound)
157
+ end
158
+ end
159
+ end
160
+ end
161
+