adhocracy 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Mzc4MGI0NWEzMTM5YTA5Mzg4NDcyNjlkMTRhODdlN2E3OGVlMDFjOA==
4
+ MGIyMWQyYTE2OGZmM2MzMDRhNmJkYzYyZDcwMGM3ZWQzMDBkZDNjMw==
5
5
  data.tar.gz: !binary |-
6
- MWU2NTA1NTkyYTBiNGFjMDI3OTllN2U2ZTM4MjJmMjI4Yjc2MjJkMQ==
6
+ YjdhYWMwMTNlYmE2YzYzNDYyNGQ3MTE3ZWRhY2RkMmYyYjczNzNlNA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Y2U1ZDBiYjQ0NzZjNGNkMmFmOTFlOTYwMjVmN2U3NDEzNTI1MDA0ODU2ZDhl
10
- YzFkZmJmM2JhNGJhODZiODQ2YzRkMzBlYzY3MTMxNDRmMmY4MTNkOWNjOTU1
11
- YzQ2NWQxYTA1YjUyYWJiMjExMzg1NWE5NWMxYjU4MmVlNjg2ZGQ=
9
+ MmYwZjA2ZDYxNzcwOTFmZDE3NDQzYWM2MWNkMjM2MTg1ODUxYjhkMGQyOTBm
10
+ OWUwODM3ZmE0MzNjNzllZjE5ZDQ3MWFkYTA1MmM2NzgwMTAzY2ExYzc5YmZi
11
+ ZTEzOGE0YmQ4YzU2ZDIyYWM4ZWYwMDQ5MjgyZWJmZTNhM2Q2NGU=
12
12
  data.tar.gz: !binary |-
13
- YTMyZTIwZjM2MjA5OWQxNzgyYWZlNTI1M2UzNmVkOTk1ZGMyZGM2ZTU3YzJm
14
- ZDE4NWIyYmMzMWYwYjAyMDFmMGM0NGEyNDg5YmI3ZDQ3OGY2ZDMxM2E5YWE5
15
- MjVmZDUxOTIzZWZhZmU2MWRmNGRlYzRjM2U0MTI4NmIxYmY2YWU=
13
+ NTdkYjk0MGJmNzRiN2VjNmI1ZGUyMGI1NTVkZTE2NzE2OTliNDBjZTNiOWY4
14
+ NmNmNGE4ZDFmOTQ2MzFiNGNhMzQzZjRiODk4NzFhZmJkZjEwOTdmNjA1NDg3
15
+ NTU4YTg3MDZhYjUzODU2OTg1MTY5ZDAwOWMzOGUxNmI4OGUyZTg=
data/README.rdoc CHANGED
@@ -1,3 +1,184 @@
1
- = Adhocracy {<img src="https://badge.fury.io/rb/adhocracy.png" alt="Gem Version" />}[http://badge.fury.io/rb/adhocracy] {<img src="https://travis-ci.org/timothycommoner/adhocracy.png?branch=master" alt="Build Status" />}[https://travis-ci.org/timothycommoner/adhocracy] {<img src="https://codeclimate.com/github/timothycommoner/adhocracy.png" />}[https://codeclimate.com/github/timothycommoner/adhocracy]
1
+ = Adhocracy {<img src="https://badge.fury.io/rb/adhocracy.png" alt="Gem Version" />}[http://badge.fury.io/rb/adhocracy] {<img src="https://travis-ci.org/timothycommoner/adhocracy.png?branch=master" alt="Build Status" />}[https://travis-ci.org/timothycommoner/adhocracy] {<img src="https://coveralls.io/repos/timothycommoner/adhocracy/badge.png" alt="Coverage Status" />}[https://coveralls.io/r/timothycommoner/adhocracy] {<img src="https://codeclimate.com/github/timothycommoner/adhocracy.png" />}[https://codeclimate.com/github/timothycommoner/adhocracy]
2
2
 
3
- A group management engine for Rails.
3
+ A group management engine for Rails.
4
+
5
+ == Compatibility
6
+
7
+ Adhocracy is a Rails Engine, which means it plays best with Rails applications. So far, it's only been tested with Rails 4.
8
+
9
+ == Usage
10
+
11
+ === Installation
12
+
13
+ 1. Add Adhocracy to your gemfile: `gem 'adhocracy'`
14
+ 2. Run bundler: `bundle install`
15
+ 3. Run this in your app folder: `rake adhocracy:install:migrations`
16
+ 4. Run your migrations: `rake db:migrate`
17
+ 5. Add `acts_as_group` to the models you want to have group functionality
18
+ 6. Add `acts_as_member` to the models you want to have member functionality
19
+
20
+ === Creating Groups and Members
21
+
22
+ Scenario: You want your Club model to have group functionality. Ideally, it'll accept members from both the Student and Teacher model.
23
+
24
+ First, add `acts_as_group` to your Club model:
25
+
26
+ class Club < ActiveRecord::Base
27
+ acts_as_group
28
+ end
29
+
30
+ Then, add 'acts_as_member' to your Student and Teacher models:
31
+
32
+ class Student < ActiveRecord::Base
33
+ acts_as_member
34
+ end
35
+
36
+ class Teacher < ActiveRecord::Base
37
+ acts_as_member
38
+ end
39
+
40
+ After that, you can add members to your Club by:
41
+
42
+ @club.add_member(@student)
43
+ @student.join_group(@club)
44
+ @teacher.join_group(@club)
45
+
46
+ List the current members:
47
+
48
+ @club.members # => returns an array with @student and @teacher in it
49
+
50
+ Or list the groups a member is a part of:
51
+
52
+ @student.groups # => returns an array with only @club
53
+
54
+ Check for membership:
55
+
56
+ @student.member_of?(@club) # => true
57
+ @club.has_member?(@teacher) # => true
58
+
59
+ And destroy memberships
60
+
61
+ @student.leave_group(@club)
62
+ @group.remove_member(@teacher)
63
+
64
+ === Officers
65
+
66
+ Scenario: You want a special class of membership that has the privilege to edit the group and accept/invite new members.
67
+
68
+ Adhocracy allows for administrative members called officers. You can create a new officer with:
69
+
70
+ @club.add_officer(@student)
71
+
72
+ Alternatively, if `@student` is already a member, you can promote her with:
73
+
74
+ @club.promote_to_officer(@student)
75
+
76
+ Later, you can strip an officer of her title with:
77
+
78
+ @club.demote_officer(@student)
79
+
80
+ === Inviting Members
81
+
82
+ Scenario: You want your users to have control over which groups they join.
83
+
84
+ Groups can send invitations to users:
85
+
86
+ @club.invite_member(@student)
87
+ @student.groups # => does not yet include @club
88
+ @student.group_invitations # => array including @club
89
+
90
+ The user can either accept or decline:
91
+
92
+ @invitation = @student.membership_invitations.first
93
+ @invitation.accept
94
+ - or -
95
+ @invitation.decline
96
+
97
+ If they accept, then they become a member of the group.
98
+
99
+ Invitations can be queried for their state of acceptance:
100
+
101
+ @invitation.pending?
102
+ @invitation.accepted?
103
+ @invitation.declined?
104
+
105
+ You can also check to see if an invitation is already sent:
106
+
107
+ @student.invited_to?(@club)
108
+ @club.invited?(@student)
109
+
110
+ These checks can include the state of the invitation:
111
+
112
+ @student.invited_to?(@club, { pending: true })
113
+ @student.invited_to?(@club, { accepted: false })
114
+ @student.invited_to?(@club, { declined: false })
115
+
116
+ === Requesting Membership
117
+
118
+ Scenario: You want your groups to have control over which users join them.
119
+
120
+ Interested users can send membership requests to groups:
121
+
122
+ @student.request_membership_in(@club)
123
+ @club.members # => does not yet include @student
124
+ @club.membership_requests # => array including @student
125
+
126
+ The group can either accept or decline:
127
+
128
+ @request = @club.membership_requests.first
129
+ @request.accept
130
+ - or -
131
+ @request.decline
132
+
133
+ Requests can be queried for their state of acceptance:
134
+
135
+ @request.pending?
136
+ @request.accepted?
137
+ @request.declined?
138
+
139
+ You can also check to see if a request is already sent:
140
+
141
+ @student.requested_membership_in?(@club)
142
+ @club.recieved_request_from?(@student)
143
+
144
+ These checks can include the state of the request:
145
+
146
+ @student.requested_membership_in?(@club, { pending: true })
147
+ @student.requested_membership_in?(@club, { accepted: false })
148
+ @student.requested_membership_in?(@club, { declined: false })
149
+
150
+ === Nesting Groups
151
+
152
+ Scenario: You want your Company model to have many subsidiary companies.
153
+
154
+ Create a model that both `acts_as_group` and `acts_as_member`:
155
+
156
+ class Company < ActiveRecord::Base
157
+ acts_as_group
158
+ acts_as_member
159
+ end
160
+
161
+ You can then nest companies like you would any other member:
162
+
163
+ @company.add_member(@child_company)
164
+ @child_company.add_member(@grand_child_company)
165
+
166
+ == Limitations
167
+
168
+ Unfortunately, Rails does not support `has_many through` relationships that pass through a polymorphic join table, which we do in Adhocracy. In order to work around this limitation, we've created pseudo-associations, such as `@club.members` and `@user.groups`. These pseudo-associations return a simple array, rather than the feature-packed associations Rails typically uses. This means you can't chain in scopes or use commands like `@user.groups.create`. If you know of a way we can reincorporate Rails associations without losing our ability to join groups and members polymorphically, please share your thoughts!
169
+
170
+ == Issues
171
+
172
+ Adhocracy is still very young, and both its functionality and its documentation are bound to be lacking. If you're having trouble with something, feel free to open an issue.
173
+
174
+ == Contributing
175
+
176
+ Feel free to send us a pull request. Public methods, callbacks, and validations should have Rspec tests to back them up.
177
+
178
+ === Contributors
179
+
180
+ Timothy Baron
181
+
182
+ == License
183
+
184
+ Released under the MIT license.
@@ -12,4 +12,4 @@ module Adhocracy
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -1,31 +1,9 @@
1
1
  module Adhocracy
2
2
  class MembershipInvitation < ActiveRecord::Base
3
3
  include Acceptable
4
+ include Joinable
4
5
 
5
6
  belongs_to :member, polymorphic: true
6
7
  belongs_to :group, polymorphic: true
7
-
8
- validate :no_pending_invitations, on: :create
9
- validate :no_declined_invitations, on: :create
10
- validate :not_currently_a_member, on: :create
11
-
12
- private
13
- def no_pending_invitations
14
- if self.member.invited_to?(self.group, { pending: true })
15
- errors[:base] << I18n.t("activerecord.errors.models.membership_invitation.still_pending")
16
- end
17
- end
18
-
19
- def no_declined_invitations
20
- if self.member.invited_to?(self.group, { declined: true })
21
- errors[:base] << I18n.t("activerecord.errors.models.membership_invitation.already_declined")
22
- end
23
- end
24
-
25
- def not_currently_a_member
26
- if self.member.member_of?(self.group)
27
- errors[:base] << I18n.t("activerecord.errors.models.membership_invitation.already_a_member")
28
- end
29
- end
30
8
  end
31
9
  end
@@ -1,31 +1,9 @@
1
1
  module Adhocracy
2
2
  class MembershipRequest < ActiveRecord::Base
3
3
  include Acceptable
4
+ include Joinable
4
5
 
5
6
  belongs_to :member, polymorphic: true
6
7
  belongs_to :group, polymorphic: true
7
-
8
- validate :no_pending_requests, on: :create
9
- validate :no_declined_requests, on: :create
10
- validate :not_currently_a_member, on: :create
11
-
12
- private
13
- def no_pending_requests
14
- if self.member.requested_membership_in?(self.group, { pending: true })
15
- errors[:base] << I18n.t("activerecord.errors.models.membership_request.still_pending")
16
- end
17
- end
18
-
19
- def no_declined_requests
20
- if self.member.requested_membership_in?(self.group, { declined: true })
21
- errors[:base] << I18n.t("activerecord.errors.models.membership_request.already_declined")
22
- end
23
- end
24
-
25
- def not_currently_a_member
26
- if self.member.member_of?(self.group)
27
- errors[:base] << I18n.t("activerecord.errors.models.membership_request.already_a_member")
28
- end
29
- end
30
8
  end
31
9
  end
@@ -8,7 +8,9 @@ en:
8
8
  still_pending: "Invitation still pending."
9
9
  already_declined: "Cannot invite member again."
10
10
  already_a_member: "Already a member."
11
+ other_party_had_pending_request: "The member already sent a request. Membership automatically accepted."
11
12
  membership_request:
12
13
  still_pending: "Request still pending."
13
14
  already_declined: "Cannot request membership again."
14
- already_a_member: "Already a member."
15
+ already_a_member: "Already a member."
16
+ other_party_had_pending_request: "The group already sent an invitation. Membership automatically accepted."
@@ -5,10 +5,12 @@ class CreateAdhocracyMemberships < ActiveRecord::Migration
5
5
  t.integer :member_id
6
6
  t.string :group_type
7
7
  t.integer :group_id
8
+ t.boolean :officer, null: false, default: false
8
9
 
9
10
  t.timestamps
10
11
  end
11
12
 
13
+ add_index :adhocracy_memberships, :officer
12
14
  add_index :adhocracy_memberships,
13
15
  [:member_id, :member_type],
14
16
  name: "adhocracy_memberships_on_member"
@@ -10,6 +10,8 @@ module Adhocracy
10
10
  class_name: "Adhocracy::MembershipInvitation"
11
11
  has_many :membership_requests, as: :group,
12
12
  class_name: "Adhocracy::MembershipRequest"
13
+ has_many :officer_memberships, -> { where officer: true }, as: :group,
14
+ class_name: "Adhocracy::Membership"
13
15
 
14
16
  send :include, InstanceMethods
15
17
  end
@@ -20,6 +22,11 @@ module Adhocracy
20
22
  MembershipAssociation.new(group: self).list_members_for_membership
21
23
  end
22
24
 
25
+ def officers
26
+ Adhocracy::Membership.where(group: self, officer: true).
27
+ includes(:member).collect { |membership| membership.member }
28
+ end
29
+
23
30
  def invited_members
24
31
  MembershipAssociation.new(group: self).
25
32
  list_members_for_membership_invitation
@@ -35,6 +42,25 @@ module Adhocracy
35
42
  create_membership
36
43
  end
37
44
 
45
+ def add_officer(member)
46
+ membership = Adhocracy::Membership.where(member: member, group: self).
47
+ first_or_create(officer: true)
48
+ promote_to_officer(member, membership) unless membership.officer?
49
+ membership
50
+ end
51
+
52
+ def promote_to_officer(member, membership = nil)
53
+ membership ||= Adhocracy::Membership.find_by(member: member, group: self)
54
+ return false if !membership.present? || membership.officer?
55
+ return membership.update_column(:officer, true)
56
+ end
57
+
58
+ def demote_officer(member)
59
+ membership = Adhocracy::Membership.find_by(member: member, group: self)
60
+ return false if !membership.present? || !membership.officer?
61
+ return membership.update_column(:officer, false)
62
+ end
63
+
38
64
  def invite_member(member)
39
65
  MembershipAssociation.new(member: member, group: self).
40
66
  create_membership_invitation
@@ -0,0 +1,71 @@
1
+ module Adhocracy
2
+ module Joinable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validate :no_pending_joins, on: :create
7
+ validate :no_declined_joins, on: :create
8
+ validate :not_currently_a_member, on: :create
9
+ validate :other_party_has_pending_request, on: :create
10
+ end
11
+
12
+ private
13
+ def detect_preexisting_join(state, inverted = false)
14
+ self.member.send(query_symbol(inverted), self.group, { state => true })
15
+ end
16
+
17
+ def no_pending_joins
18
+ if detect_preexisting_join(:pending)
19
+ errors[:base] << I18n.t("activerecord.errors.models.membership_#{i18n_string}.still_pending")
20
+ end
21
+ end
22
+
23
+ def no_declined_joins
24
+ if detect_preexisting_join(:declined)
25
+ errors[:base] << I18n.t("activerecord.errors.models.membership_#{i18n_string}.already_declined")
26
+ end
27
+ end
28
+
29
+ def not_currently_a_member
30
+ if self.member.member_of?(self.group)
31
+ errors[:base] << I18n.t("activerecord.errors.models.membership_#{i18n_string}.already_a_member")
32
+ end
33
+ end
34
+
35
+ def other_party_has_pending_request
36
+ if detect_preexisting_join(:pending, true)
37
+ accept_preexisting_join
38
+ errors[:base] << I18n.t("activerecord.errors.models.membership_#{i18n_string}.other_party_had_pending_request")
39
+ end
40
+ end
41
+
42
+ def i18n_string
43
+ return case self.class.name
44
+ when "Adhocracy::MembershipInvitation" then "invitation"
45
+ when "Adhocracy::MembershipRequest" then "request"
46
+ end
47
+ end
48
+
49
+ def query_symbol(inverted)
50
+ test_class = inverted == false ? self.class.name : inverted_class
51
+ return case test_class
52
+ when "Adhocracy::MembershipInvitation" then :invited_to?
53
+ when "Adhocracy::MembershipRequest" then :requested_membership_in?
54
+ end
55
+ end
56
+
57
+ def inverted_class
58
+ return case self.class.name
59
+ when "Adhocracy::MembershipInvitation"
60
+ "Adhocracy::MembershipRequest"
61
+ when "Adhocracy::MembershipRequest"
62
+ "Adhocracy::MembershipInvitation"
63
+ end
64
+ end
65
+
66
+ def accept_preexisting_join
67
+ inverted_class.constantize.where(member: self.member, group: self.group).
68
+ first.accept
69
+ end
70
+ end
71
+ end
@@ -1,3 +1,3 @@
1
1
  module Adhocracy
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/adhocracy.rb CHANGED
@@ -2,6 +2,7 @@ require "adhocracy/engine"
2
2
  require "adhocracy/acts_as_member"
3
3
  require "adhocracy/acts_as_group"
4
4
  require "adhocracy/acceptable"
5
+ require "adhocracy/joinable"
5
6
  require "adhocracy/membership_association"
6
7
 
7
8
  module Adhocracy
@@ -49,6 +49,7 @@ ActiveRecord::Schema.define(version: 20140306214620) do
49
49
  t.integer "member_id"
50
50
  t.string "group_type"
51
51
  t.integer "group_id"
52
+ t.boolean "officer", default: false, null: false
52
53
  t.datetime "created_at"
53
54
  t.datetime "updated_at"
54
55
  end
@@ -57,6 +58,7 @@ ActiveRecord::Schema.define(version: 20140306214620) do
57
58
  add_index "adhocracy_memberships", ["group_id", "group_type"], name: "adhocracy_membership_requests_on_group", using: :btree
58
59
  add_index "adhocracy_memberships", ["group_id", "group_type"], name: "adhocracy_memberships_on_group", using: :btree
59
60
  add_index "adhocracy_memberships", ["member_id", "member_type"], name: "adhocracy_memberships_on_member", using: :btree
61
+ add_index "adhocracy_memberships", ["officer"], name: "index_adhocracy_memberships_on_officer", using: :btree
60
62
 
61
63
  create_table "adhocs", force: true do |t|
62
64
  end
@@ -19,6 +19,10 @@ module Adhocracy
19
19
  it "membership invitations" do
20
20
  expect(@adhoc).to have_many(:membership_invitations)
21
21
  end
22
+
23
+ it "officer memberships" do
24
+ expect(@adhoc).to have_many(:officer_memberships)
25
+ end
22
26
  end
23
27
 
24
28
  context "produces a list" do
@@ -30,7 +34,7 @@ module Adhocracy
30
34
  @user4 = FactoryGirl.create(:user)
31
35
  @user5 = FactoryGirl.create(:user)
32
36
  @adhoc.add_member(@user1)
33
- @adhoc.add_member(@user3)
37
+ @adhoc.add_officer(@user3)
34
38
  @adhoc.invite_member(@user4)
35
39
  @user5.request_membership_in(@adhoc)
36
40
  end
@@ -43,6 +47,14 @@ module Adhocracy
43
47
  expect(@adhoc.members).to_not include @user2, @user4, @user5
44
48
  end
45
49
 
50
+ it "including all officers" do
51
+ expect(@adhoc.officers).to include @user3
52
+ end
53
+
54
+ it "excluding non-officers" do
55
+ expect(@adhoc.officers).to_not include @user1, @user2, @user4, @user5
56
+ end
57
+
46
58
  it "including all invited members" do
47
59
  expect(@adhoc.invited_members).to include @user4
48
60
  end
@@ -136,6 +148,16 @@ module Adhocracy
136
148
  expect(@adhoc.add_member(@user).valid?).to be false
137
149
  end
138
150
 
151
+ it "creating officers" do
152
+ @adhoc.add_officer(@user)
153
+ expect(@adhoc.officers).to include @user
154
+ end
155
+
156
+ it "not creating duplicate officers" do
157
+ @adhoc.add_officer(@user)
158
+ expect(@adhoc.add_officer(@user).valid?).to be false
159
+ end
160
+
139
161
  it "inviting members" do
140
162
  @adhoc.invite_member(@user)
141
163
  expect(@adhoc.invited_members).to include @user
@@ -156,6 +178,12 @@ module Adhocracy
156
178
  @adhoc.add_member(@user)
157
179
  expect(@adhoc.invite_member(@user).valid?).to be false
158
180
  end
181
+
182
+ it "accepting invited members if they've requested membership" do
183
+ @user.request_membership_in(@adhoc)
184
+ expect(@adhoc.invite_member(@user).valid?).to be false
185
+ expect(@adhoc.members).to include @user
186
+ end
159
187
  end
160
188
 
161
189
  context "destroys memberships" do
@@ -175,5 +203,51 @@ module Adhocracy
175
203
  end
176
204
  end
177
205
 
206
+ context "promotes members to officers" do
207
+ before :each do
208
+ @adhoc = FactoryGirl.create(:adhoc)
209
+ @user = FactoryGirl.create(:user)
210
+ end
211
+
212
+ it "if the member is a non-officer" do
213
+ @adhoc.add_member(@user)
214
+ @adhoc.promote_to_officer(@user)
215
+ expect(@adhoc.officers).to include @user
216
+ end
217
+
218
+ it "if the member is a non-officer member (and add_officer is used)" do
219
+ @adhoc.add_member(@user)
220
+ @adhoc.add_officer(@user)
221
+ expect(@adhoc.officers).to include @user
222
+ end
223
+
224
+ it "but returns false if the user is not a member" do
225
+ expect(@adhoc.promote_to_officer(@user)).to be false
226
+ end
227
+
228
+ it "but returns false if the member is already an officer" do
229
+ @adhoc.add_officer(@user)
230
+ expect(@adhoc.promote_to_officer(@user)).to be false
231
+ end
232
+ end
233
+
234
+ context "demotes officers" do
235
+ before :each do
236
+ @adhoc = FactoryGirl.create(:adhoc)
237
+ @user = FactoryGirl.create(:user)
238
+ end
239
+
240
+ it "if the member is an officer" do
241
+ @adhoc.add_officer(@user)
242
+ @adhoc.demote_officer(@user)
243
+ expect(@adhoc.officers).to_not include @user
244
+ end
245
+
246
+ it "but returns false if the member is not an officer" do
247
+ @adhoc.add_member(@user)
248
+ expect(@adhoc.demote_officer(@user)).to be false
249
+ end
250
+ end
251
+
178
252
  end
179
253
  end
@@ -118,6 +118,12 @@ module Adhocracy
118
118
  expect(@user.requested_membership_in?(@adhoc, { pending: true })).
119
119
  to be false
120
120
  end
121
+
122
+ it "accepting requested groups if they've already invited membership" do
123
+ @adhoc.invite_member(@user)
124
+ expect(@user.request_membership_in(@adhoc).valid?).to be false
125
+ expect(@user.groups).to include @adhoc
126
+ end
121
127
  end
122
128
 
123
129
  context "handles prospective groups by" do
data/spec/spec_helper.rb CHANGED
@@ -10,6 +10,9 @@ Spork.prefork do
10
10
  require 'database_cleaner'
11
11
  require 'shoulda'
12
12
  require 'debugger'
13
+ require 'coveralls'
14
+
15
+ Coveralls.wear!('rails')
13
16
 
14
17
  # Requires supporting ruby files with custom matchers and macros, etc,
15
18
  # in spec/support/ and its subdirectories.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adhocracy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - timothycommoner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-07 00:00:00.000000000 Z
11
+ date: 2014-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ! '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: coveralls
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description: Adhocracy is group management engine for Rails.
140
154
  email:
141
155
  - timothythehuman@gmail.com
@@ -164,6 +178,7 @@ files:
164
178
  - lib/adhocracy/acts_as_group.rb
165
179
  - lib/adhocracy/acts_as_member.rb
166
180
  - lib/adhocracy/engine.rb
181
+ - lib/adhocracy/joinable.rb
167
182
  - lib/adhocracy/membership_association.rb
168
183
  - lib/adhocracy/version.rb
169
184
  - lib/tasks/adhocracy_tasks.rake
@@ -240,48 +255,48 @@ summary: Adhocracy is group management engine for Rails.
240
255
  test_files:
241
256
  - spec/lib/adhocracy/acts_as_group_spec.rb
242
257
  - spec/lib/adhocracy/acts_as_member_spec.rb
243
- - spec/factories/adhocracy_memberships.rb
244
- - spec/factories/adhoc.rb
245
- - spec/factories/adhocracy_membership_invitations.rb
246
- - spec/factories/users.rb
247
- - spec/factories/adhocracy_membership_requests.rb
248
- - spec/spec_helper.rb
249
- - spec/dummy/Rakefile
250
- - spec/dummy/config/application.rb
251
- - spec/dummy/config/boot.rb
252
- - spec/dummy/config/initializers/backtrace_silencers.rb
253
- - spec/dummy/config/initializers/inflections.rb
254
- - spec/dummy/config/initializers/session_store.rb
255
- - spec/dummy/config/initializers/mime_types.rb
256
- - spec/dummy/config/initializers/secret_token.rb
257
- - spec/dummy/config/initializers/filter_parameter_logging.rb
258
- - spec/dummy/config/initializers/wrap_parameters.rb
259
- - spec/dummy/config/routes.rb
260
- - spec/dummy/config/environment.rb
261
- - spec/dummy/config/locales/en.yml
262
- - spec/dummy/config/database.yml
263
- - spec/dummy/config/environments/development.rb
264
- - spec/dummy/config/environments/production.rb
265
- - spec/dummy/config/environments/test.rb
266
- - spec/dummy/config.ru
258
+ - spec/dummy/README.rdoc
267
259
  - spec/dummy/app/helpers/application_helper.rb
268
260
  - spec/dummy/app/views/layouts/application.html.erb
269
- - spec/dummy/app/controllers/application_controller.rb
270
261
  - spec/dummy/app/assets/stylesheets/application.css
271
262
  - spec/dummy/app/assets/javascripts/application.js
272
263
  - spec/dummy/app/models/adhoc.rb
273
264
  - spec/dummy/app/models/user.rb
274
- - spec/dummy/bin/bundle
275
- - spec/dummy/bin/rails
276
- - spec/dummy/bin/rake
265
+ - spec/dummy/app/controllers/application_controller.rb
266
+ - spec/dummy/db/migrate/20140306214611_create_users.rb
267
+ - spec/dummy/db/migrate/20140306214620_create_adhocs.rb
268
+ - spec/dummy/db/schema.rb
277
269
  - spec/dummy/public/422.html
278
270
  - spec/dummy/public/404.html
279
271
  - spec/dummy/public/favicon.ico
280
272
  - spec/dummy/public/500.html
281
- - spec/dummy/README.rdoc
282
- - spec/dummy/db/migrate/20140306214611_create_users.rb
283
- - spec/dummy/db/migrate/20140306214620_create_adhocs.rb
284
- - spec/dummy/db/schema.rb
273
+ - spec/dummy/Rakefile
274
+ - spec/dummy/bin/rails
275
+ - spec/dummy/bin/bundle
276
+ - spec/dummy/bin/rake
277
+ - spec/dummy/config/initializers/mime_types.rb
278
+ - spec/dummy/config/initializers/inflections.rb
279
+ - spec/dummy/config/initializers/backtrace_silencers.rb
280
+ - spec/dummy/config/initializers/wrap_parameters.rb
281
+ - spec/dummy/config/initializers/session_store.rb
282
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
283
+ - spec/dummy/config/initializers/secret_token.rb
284
+ - spec/dummy/config/application.rb
285
+ - spec/dummy/config/environments/test.rb
286
+ - spec/dummy/config/environments/development.rb
287
+ - spec/dummy/config/environments/production.rb
288
+ - spec/dummy/config/boot.rb
289
+ - spec/dummy/config/routes.rb
290
+ - spec/dummy/config/locales/en.yml
291
+ - spec/dummy/config/environment.rb
292
+ - spec/dummy/config/database.yml
293
+ - spec/dummy/config.ru
294
+ - spec/spec_helper.rb
295
+ - spec/factories/adhocracy_membership_requests.rb
296
+ - spec/factories/users.rb
297
+ - spec/factories/adhocracy_membership_invitations.rb
298
+ - spec/factories/adhocracy_memberships.rb
299
+ - spec/factories/adhoc.rb
285
300
  - spec/models/adhocracy/membership_spec.rb
286
301
  - spec/models/adhocracy/membership_request_spec.rb
287
302
  - spec/models/adhocracy/membership_invitation_spec.rb