popolo 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +65 -7
  3. data/app/assets/javascripts/popolo.js +1 -0
  4. data/app/assets/stylesheets/popolo/bootstrap.min.scss +7 -0
  5. data/app/assets/stylesheets/popolo/main.css.scss +14 -0
  6. data/app/assets/stylesheets/popolo.css +3 -0
  7. data/app/controllers/popolo/memberships_controller.rb +7 -0
  8. data/app/controllers/popolo/organizations_controller.rb +0 -39
  9. data/app/controllers/popolo/people_controller.rb +1 -6
  10. data/app/controllers/popolo/posts_controller.rb +1 -1
  11. data/app/helpers/popolo_helper.rb +0 -8
  12. data/app/models/popolo/area.rb +20 -12
  13. data/app/models/popolo/contact_detail.rb +22 -0
  14. data/app/models/popolo/count.rb +24 -0
  15. data/app/models/popolo/date_string.rb +23 -0
  16. data/app/models/popolo/group_result.rb +15 -0
  17. data/app/models/popolo/identifier.rb +1 -1
  18. data/app/models/popolo/link.rb +7 -3
  19. data/app/models/popolo/membership.rb +34 -9
  20. data/app/models/popolo/motion.rb +37 -0
  21. data/app/models/popolo/organization.rb +37 -16
  22. data/app/models/popolo/other_name.rb +5 -5
  23. data/app/models/popolo/person.rb +57 -27
  24. data/app/models/popolo/post.rb +27 -13
  25. data/app/models/popolo/vote.rb +28 -0
  26. data/app/models/popolo/vote_event.rb +35 -0
  27. data/app/views/popolo/contact_details/_contact_detail.html.erb +17 -0
  28. data/app/views/popolo/identifiers/_identifier.html.erb +2 -0
  29. data/app/views/popolo/links/_link.html.erb +1 -0
  30. data/app/views/popolo/memberships/show.html.erb +81 -0
  31. data/app/views/popolo/organizations/index.html.erb +16 -1
  32. data/app/views/popolo/organizations/show.html.erb +146 -1
  33. data/app/views/popolo/other_names/other_name.html.erb +9 -0
  34. data/app/views/popolo/people/show.html.erb +120 -0
  35. data/app/views/popolo/posts/show.html.erb +90 -0
  36. data/config/routes.rb +4 -12
  37. data/lib/generators/popolo_generator.rb +4 -0
  38. data/lib/popolo/initializers/pupa_compat.rb +11 -0
  39. data/lib/popolo/version.rb +1 -1
  40. data/lib/popolo.rb +17 -5
  41. data/spec/controllers/popolo/memberships_controller_spec.rb +16 -0
  42. data/spec/controllers/popolo/organizations_controller_spec.rb +1 -47
  43. data/spec/controllers/popolo/people_controller_spec.rb +0 -14
  44. data/spec/controllers/popolo/posts_controller_spec.rb +0 -8
  45. data/spec/dummy/app/assets/stylesheets/application.css +1 -0
  46. data/spec/dummy/app/models/cat.rb +0 -3
  47. data/spec/dummy/app/models/dog.rb +0 -7
  48. data/spec/dummy/app/views/layouts/application.html.erb +2 -0
  49. data/spec/dummy/config/locales/en.yml +30 -0
  50. data/spec/dummy/config/routes.rb +1 -1
  51. data/spec/dummy/log/test.log +8670 -48801
  52. data/spec/factories.rb +3 -8
  53. data/spec/models/popolo/{source_spec.rb → contact_detail_spec.rb} +2 -2
  54. data/spec/models/popolo/count_spec.rb +7 -0
  55. data/spec/models/popolo/date_string_spec.rb +121 -0
  56. data/spec/models/popolo/group_result_spec.rb +7 -0
  57. data/spec/models/popolo/membership_spec.rb +1 -17
  58. data/spec/models/popolo/motion_spec.rb +5 -0
  59. data/spec/models/popolo/organization_spec.rb +1 -19
  60. data/spec/models/popolo/other_name_spec.rb +1 -17
  61. data/spec/models/popolo/person_spec.rb +23 -19
  62. data/spec/models/popolo/post_spec.rb +1 -3
  63. data/spec/models/popolo/vote_event_spec.rb +4 -0
  64. data/spec/models/popolo/vote_spec.rb +4 -0
  65. data/spec/popolo_spec.rb +65 -0
  66. data/spec/routing/popolo/memberships_routing_spec.rb +11 -0
  67. data/spec/routing/popolo/organizations_routing_spec.rb +1 -19
  68. data/spec/routing/popolo/people_routing_spec.rb +1 -11
  69. data/spec/routing/popolo/posts_routing_spec.rb +1 -7
  70. data/spec/spec_helper.rb +6 -1
  71. data/spec/support/shared_examples.rb +19 -0
  72. metadata +99 -109
  73. data/app/assets/javascripts/popolo/application.js +0 -13
  74. data/app/assets/stylesheets/popolo/application.css +0 -13
  75. data/app/controllers/popolo/areas_controller.rb +0 -43
  76. data/app/models/popolo/address.rb +0 -27
  77. data/app/models/popolo/event.rb +0 -46
  78. data/app/models/popolo/source.rb +0 -29
  79. data/app/views/popolo/addresses/_address.html.erb +0 -16
  80. data/app/views/popolo/areas/index.html.erb +0 -1
  81. data/app/views/popolo/areas/show.html.erb +0 -1
  82. data/app/views/popolo/areas_or_organizations/_breadcrumb.html.erb +0 -13
  83. data/app/views/popolo/areas_or_organizations/_index.html.erb +0 -31
  84. data/app/views/popolo/areas_or_organizations/_show.html.erb +0 -18
  85. data/app/views/popolo/organizations/post.html.erb +0 -27
  86. data/app/views/popolo/organizations/posts.html.erb +0 -23
  87. data/app/views/popolo/people/index.html.erb +0 -0
  88. data/app/views/popolo/posts/index.html.erb +0 -0
  89. data/lib/popolo/mixins/eventable.rb +0 -15
  90. data/lib/popolo/mixins/sluggable.rb +0 -66
  91. data/spec/controllers/popolo/areas_controller_spec.rb +0 -53
  92. data/spec/dummy/log/development.log +0 -6
  93. data/spec/models/popolo/address_spec.rb +0 -4
  94. data/spec/models/popolo/event_spec.rb +0 -7
  95. data/spec/popolo/mixins/sluggable_spec.rb +0 -153
  96. data/spec/routing/popolo/areas_routing_spec.rb +0 -25
@@ -1,16 +0,0 @@
1
- <section>
2
- <% if address.type? %>
3
- <header>
4
- <%=t address.type, default: address.type %>
5
- </header>
6
- <% end %>
7
- <% if address.voice? %>
8
- <p>Phone: <%= address.voice %></p>
9
- <% end %>
10
- <% if address.fax? %>
11
- <p>Fax: <%= address.fax %></p>
12
- <% end %>
13
- <% if address.address? %>
14
- <%= simple_format address.address %>
15
- <% end %>
16
- </section>
@@ -1 +0,0 @@
1
- <%= render partial: 'popolo/areas_or_organizations/index', locals: {collection: @areas, object: @area} %>
@@ -1 +0,0 @@
1
- <%= render partial: 'popolo/areas_or_organizations/show', locals: {object: @area} %>
@@ -1,13 +0,0 @@
1
- <nav>
2
- <ul class="breadcrumb">
3
- <li><%= link_to resource_collection_name.capitalize, collection_path %> <span class="divider">/</span></li>
4
- <% ancestors = object.ancestors %>
5
- <% ancestors.each_with_index do |ancestor,index| %>
6
- <li>
7
- <%= link_to ancestor.name, nested_resource_path(ancestors[0..index]) %>
8
- <span class="divider">/</span>
9
- </li>
10
- <% end %>
11
- <li class="active"><%= object.name %></li>
12
- </ul>
13
- </nav>
@@ -1,31 +0,0 @@
1
- <% if object %>
2
- <nav>
3
- <ul class="breadcrumb">
4
- <li><%= link_to resource_collection_name.capitalize, collection_path %> <span class="divider">/</span></li>
5
- <% ancestors = object.ancestors %>
6
- <% ancestors.each_with_index do |ancestor,index| %>
7
- <li>
8
- <%= link_to ancestor.name, nested_resources_path(ancestors[0..index]) %>
9
- <span class="divider">/</span>
10
- </li>
11
- <% end %>
12
- <li class="active"><%= object.name %></li>
13
- </ul>
14
- </nav>
15
- <% end %>
16
-
17
- <% unless collection.empty? %>
18
- <% groups = collection.asc(:sort_name).group_by(&:classification) %>
19
- <% groups.each do |classification,documents| %>
20
- <section>
21
- <header>
22
- <h1><%= t(classification, scope: [:popolo, resource_collection_name, :classifications]) %></h1>
23
- </header>
24
- <ol>
25
- <% documents.each do |document| %>
26
- <li><%= link_to document.name, nested_resources_path([object, document].compact) %></li>
27
- <% end %>
28
- </ol>
29
- </section>
30
- <% end %>
31
- <% end %>
@@ -1,18 +0,0 @@
1
- <%= render partial: 'popolo/areas_or_organizations/breadcrumb', locals: {object: object} %>
2
-
3
- <% collection = object.children %>
4
- <% unless collection.empty? %>
5
- <% groups = collection.asc(:sort_name).group_by(&:classification) %>
6
- <% groups.each do |classification,documents| %>
7
- <section>
8
- <header>
9
- <h1><%= t(classification, scope: [:popolo, resource_collection_name, :classifications]) %></h1>
10
- </header>
11
- <ol>
12
- <% documents.each do |document| %>
13
- <li><%= link_to document.name, nested_resource_path([object, document]) %></li>
14
- <% end %>
15
- </ol>
16
- </section>
17
- <% end %>
18
- <% end %>
@@ -1,27 +0,0 @@
1
- <%= render partial: 'popolo/areas_or_organizations/breadcrumb', locals: {object: @organization} %>
2
-
3
- <section>
4
- <div class="media">
5
- <% if @post.person && @post.person.image? %>
6
- <span class="pull-left">
7
- <%= image_tag(@post.person.image, class: 'media-object') %>
8
- </span>
9
- <% end %>
10
- <div class="media-body">
11
- <h4 class="media-heading"><%= @post.name %></h4>
12
- <% if @post.person %>
13
- <%= @post.person.name %>
14
- <% end %>
15
- </div>
16
- </div>
17
- <% if @post.person && @post.person.summary? %>
18
- <p><%= @post.person.summary %></p>
19
- <% end %>
20
-
21
- <aside>
22
- <% if @post.person && @post.person.email? %>
23
- <p>Email: <%= mail_to @post.person.email %></p>
24
- <% end %>
25
- <%= render @post.addresses %>
26
- </aside>
27
- </section>
@@ -1,23 +0,0 @@
1
- <%= render partial: 'popolo/areas_or_organizations/breadcrumb', locals: {object: @organization} %>
2
-
3
- <section>
4
- <h1><%= @organization.name %></h1>
5
-
6
- <ol class="media-list">
7
- <% @posts.asc(:sort_name).each do |post| %>
8
- <li class="media">
9
- <% if post.person && post.person.image? %>
10
- <span class="pull-left">
11
- <%= image_tag(post.person.image, class: 'image-object') %>
12
- </span>
13
- <% end %>
14
- <div class="media-body">
15
- <h4 class="media-heading"><%= link_to post.name, nested_organization_post_path(@organization.ancestors_and_self, post) %></h4>
16
- <% if post.person %>
17
- <%= post.person.name %>
18
- <% end %>
19
- </div>
20
- </li>
21
- <% end %>
22
- </ol>
23
- </section>
File without changes
File without changes
@@ -1,15 +0,0 @@
1
- module Popolo
2
- module Eventable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- embeds_many :sources, as: :sourceable, class_name: 'Popolo::Source'
7
- end
8
-
9
- # @note It's not possible to do a many-to-many polymorphic relation, so
10
- # we must create the relation manually.
11
- def events
12
- Event.where("related.#{self.class.name.demodulize.underscore}" => id)
13
- end
14
- end
15
- end
@@ -1,66 +0,0 @@
1
- module Popolo
2
- module Sluggable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- # The field used as the basis of the slug, usually the resource's name.
7
- field slug_source, type: String
8
- # A lowercase identifier composed of letters, numbers and dashes.
9
- field :slug, type: String
10
- # The field used to sort the document.
11
- field :sort_name, type: String
12
-
13
- index sort_name: 1
14
-
15
- validates_presence_of slug_source, :slug, :sort_name
16
-
17
- before_validation :set_slug_and_sort_name
18
- end
19
-
20
- module ClassMethods
21
- # Finds a resource by its slug or ID.
22
- #
23
- # @param [String] slug a slug or ID
24
- # @return a matching resource
25
- def find_by_slug_or_id(slug)
26
- where(slug: slug.to_s.parameterize).first || find(slug)
27
- end
28
-
29
- # Finds a resource by its slug or raises an error.
30
- #
31
- # @param [String] slug a slug
32
- # @param [Hash] opts conditions
33
- # @return a matching resource
34
- # @raises [Mongoid::Errors::DocumentNotFound] if not found
35
- def find_by_slug(slug, opts = {})
36
- find_by(opts.merge(slug: slug.parameterize))
37
- end
38
-
39
- # @private
40
- def slug_source
41
- if defined?(super)
42
- super
43
- else
44
- :name
45
- end
46
- end
47
- end
48
-
49
- def to_param
50
- slug
51
- end
52
-
53
- private
54
-
55
- # @return [String] the value of the field used as the basis of the slug
56
- def slug_source
57
- send(self.class.slug_source)
58
- end
59
-
60
- # @note Leave it to the content manager to choose a slug in case of conflicts.
61
- def set_slug_and_sort_name
62
- self.slug ||= slug_source.parameterize if slug_source
63
- self.sort_name ||= slug_source
64
- end
65
- end
66
- end
@@ -1,53 +0,0 @@
1
- # coding: utf-8
2
- require 'spec_helper'
3
-
4
- describe Popolo::AreasController do
5
- before :each do
6
- @routes = Popolo::Engine.routes
7
- @area = FactoryGirl.create :area, name: 'Canada'
8
- @ontario = @area.children.create name: 'Ontario'
9
- @quebec = @area.children.create name: 'Québec'
10
- @montreal = @quebec.children.create name: 'Montréal'
11
- @villemarie = @montreal.children.create name: 'Ville-Marie'
12
- end
13
-
14
- describe 'GET index' do
15
- it 'assigns all areas as @areas' do
16
- get :index
17
- assigns(:areas).to_a.should == [@area]
18
- response.should be_success
19
- end
20
- end
21
-
22
- describe 'GET show' do
23
- it 'assigns the requested area as @area' do
24
- get :show, id: @area.id.to_s
25
- assigns(:area).should == @area
26
- response.should be_success
27
- end
28
- end
29
-
30
- describe 'GET nested_index' do
31
- it 'succeeds if properly nested' do
32
- get :nested_index, path: 'canada/quebec/montreal'
33
- assigns(:areas).to_a.should == [@villemarie]
34
- response.should be_success
35
- end
36
-
37
- it 'fails if improperly nested' do
38
- expect {get :nested_index, path: 'canada/ontario/montreal'}.to raise_error(Mongoid::Errors::DocumentNotFound)
39
- end
40
- end
41
-
42
- describe 'GET nested_show' do
43
- it 'succeeds if properly nested' do
44
- get :nested_show, path: 'canada/quebec/montreal'
45
- assigns(:area).should == @montreal
46
- response.should be_success
47
- end
48
-
49
- it 'fails if improperly nested' do
50
- expect {get :nested_show, path: 'canada/ontario/montreal'}.to raise_error(Mongoid::Errors::DocumentNotFound)
51
- end
52
- end
53
- end
@@ -1,6 +0,0 @@
1
- MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} (1.4269ms)
2
- MOPED: 127.0.0.1:27017 INSERT database=popolo_development collection=popolo_people documents=[{"_id"=>"50f305f223e2f6045a000001", "name"=>{"en"=>"John Doe"}, "slug"=>"john-doe", "updated_at"=>2013-01-13 19:07:30 UTC, "created_at"=>2013-01-13 19:07:30 UTC}] flags=[] (0.2322ms)
3
- MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} (1.0641ms)
4
- MOPED: 127.0.0.1:27017 QUERY database=popolo_development collection=popolo_people selector={"$query"=>{"deleted_at"=>nil}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 fields=nil (0.7071ms)
5
- MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} (0.6180ms)
6
- MOPED: 127.0.0.1:27017 QUERY database=popolo_development collection=popolo_people selector={"$query"=>{"deleted_at"=>nil}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 fields=nil (0.7722ms)
@@ -1,4 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Popolo::Address do
4
- end
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Popolo::Event do
4
- [:source, :url, :body, :issued_at].each do |attribute|
5
- it {should validate_presence_of attribute}
6
- end
7
- end
@@ -1,153 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Popolo::Sluggable do
4
- describe '.included' do
5
- describe '#new' do
6
- subject {Cat.new}
7
-
8
- [:name, :slug, :sort_name].each do |attribute|
9
- it {should validate_presence_of attribute}
10
- end
11
-
12
- context 'with a custom slug source' do
13
- subject {Dog.new}
14
-
15
- [:moniker, :slug, :sort_name].each do |attribute|
16
- it {should validate_presence_of attribute}
17
- end
18
-
19
- it {should_not validate_presence_of :name}
20
- end
21
- end
22
-
23
- describe '#slug_source' do
24
- it 'should default to :name' do
25
- Cat.slug_source.should == :name
26
- end
27
-
28
- context 'with a custom slug source' do
29
- it 'should use the custom slug source' do
30
- Dog.slug_source.should == :moniker
31
- end
32
- end
33
- end
34
-
35
- describe '#create' do
36
- it 'should set the slug' do
37
- Cat.create(name: 'Foo').slug.should == 'foo'
38
- end
39
-
40
- it 'should not set the slug if it is already set' do
41
- Cat.create(name: 'Foo', slug: 'bar').slug.should == 'bar'
42
- end
43
-
44
- it 'should not attempt to set the slug if the slug source is empty' do
45
- expect {Cat.create!}.to raise_error(Mongoid::Errors::Validations)
46
- end
47
-
48
- it 'should prevent duplicate slugs' do
49
- Cat.create name: 'Foo', slug: 'foo'
50
- expect {Cat.with(safe: true).create(name: 'Bar', slug: 'foo')}.to raise_error(Moped::Errors::OperationFailure)
51
- end
52
-
53
- it 'should set the sort name' do
54
- Cat.create(name: 'Foo').sort_name.should == 'Foo'
55
- end
56
-
57
- it 'should not set the sort name if it is already set' do
58
- Cat.create(name: 'Foo', sort_name: 'Bar').sort_name.should == 'Bar'
59
- end
60
-
61
- context 'with a custom slug source' do
62
- it 'should set the slug' do
63
- Dog.create(moniker: 'Foo').slug.should == 'foo'
64
- end
65
-
66
- it 'should not set the slug if it is already set' do
67
- Dog.create(moniker: 'Foo', slug: 'bar').slug.should == 'bar'
68
- end
69
-
70
- it 'should not attempt to set the slug if the slug source is empty' do
71
- expect {Dog.create!}.to raise_error(Mongoid::Errors::Validations)
72
- end
73
-
74
- it 'should prevent duplicate slugs' do
75
- Dog.create moniker: 'Foo', slug: 'foo'
76
- expect {Dog.with(safe: true).create(moniker: 'Bar', slug: 'foo')}.to raise_error(Moped::Errors::OperationFailure)
77
- end
78
-
79
- it 'should set the sort name' do
80
- Dog.create(moniker: 'Foo').sort_name.should == 'Foo'
81
- end
82
-
83
- it 'should not set the sort name if it is already set' do
84
- Dog.create(moniker: 'Foo', sort_name: 'Bar').sort_name.should == 'Bar'
85
- end
86
- end
87
- end
88
-
89
- describe '#find_by_slug' do
90
- let :resource do
91
- Cat.create(name: 'Foo')
92
- end
93
-
94
- it 'should find a resource by its slug' do
95
- Cat.find_by_slug(resource.slug).should == resource
96
- end
97
-
98
- it 'should find a resource by its slug source' do
99
- Cat.find_by_slug(resource.name).should == resource
100
- end
101
-
102
- context 'with a custom slug source' do
103
- let :resource do
104
- Dog.create(moniker: 'Foo')
105
- end
106
-
107
- it 'should find a resource by its slug' do
108
- Dog.find_by_slug(resource.slug).should == resource
109
- end
110
-
111
- it 'should find a resource by its slug source' do
112
- Dog.find_by_slug(resource.moniker).should == resource
113
- end
114
- end
115
- end
116
-
117
- describe '#find_by_slug_or_id' do
118
- let :resource do
119
- Cat.create(name: 'Foo')
120
- end
121
-
122
- it 'should find a resource by its slug' do
123
- Cat.find_by_slug_or_id(resource.slug).should == resource
124
- end
125
-
126
- it 'should find a resource by its slug source' do
127
- Cat.find_by_slug(resource.name).should == resource
128
- end
129
-
130
- it 'should find a resource by its ID' do
131
- Cat.find_by_slug_or_id(resource.id).should == resource
132
- end
133
-
134
- context 'with a custom slug source' do
135
- let :resource do
136
- Dog.create(moniker: 'Foo')
137
- end
138
-
139
- it 'should find a resource by its slug' do
140
- Dog.find_by_slug_or_id(resource.slug).should == resource
141
- end
142
-
143
- it 'should find a resource by its slug' do
144
- Dog.find_by_slug_or_id(resource.moniker).should == resource
145
- end
146
-
147
- it 'should find a resource by its ID' do
148
- Dog.find_by_slug_or_id(resource.id).should == resource
149
- end
150
- end
151
- end
152
- end
153
- end
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Popolo::AreasController do
4
- describe 'routing' do
5
- before :each do
6
- @routes = Popolo::Engine.routes
7
- end
8
-
9
- it 'routes to #index' do
10
- get('/areas').should route_to('popolo/areas#index')
11
- end
12
-
13
- it 'routes to #show' do
14
- get('/areas/1').should route_to('popolo/areas#show', id: '1')
15
- end
16
-
17
- it 'routes to #nested_index' do
18
- get('/areas/foo/areas').should route_to('popolo/areas#nested_index', path: 'foo')
19
- end
20
-
21
- it 'routes to #nested_show' do
22
- get('/areas/foo/bar').should route_to('popolo/areas#nested_show', path: 'foo/bar')
23
- end
24
- end
25
- end