osm 1.2.7 → 1.2.8

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.
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --format documentation
@@ -1,3 +1,8 @@
1
+ ## Version 1.2.8
2
+
3
+ * api.get\_user\_permissions now includes the quartermaster permission
4
+ * Fix administer permission level excluded from ApiAccess
5
+
1
6
  ## Version 1.2.7
2
7
 
3
8
  * Fix can't compare exception when a FlexiRecord has a nil name.
data/README.md CHANGED
@@ -7,7 +7,7 @@ Master branch:
7
7
  [![Code Climate](https://codeclimate.com/github/robertgauld/osm.png?branch=master)](https://codeclimate.com/github/robertgauld/osm)
8
8
 
9
9
  Staging branch:
10
- [![Build Status](https://secure.travis-ci.org/robertgauld/osm.png?branch=staging)](http://travis-ci.org/robertgauld/o
10
+ [![Build Status](https://secure.travis-ci.org/robertgauld/osm.png?branch=staging)](http://travis-ci.org/robertgauld/osm)
11
11
  [![Coveralls Status](https://coveralls.io/repos/robertgauld/osm/badge.png?branch=master)](https://coveralls.io/r/robertgauld/osm)
12
12
  [![Code Climate](https://codeclimate.com/github/robertgauld/osm.png?branch=staging)](https://codeclimate.com/github/robertgauld/osm)
13
13
 
@@ -6,10 +6,8 @@ gem 'activesupport', '~> 3.2'
6
6
  gem 'dirty_hashy', '~> 0.2.1'
7
7
  gem 'httparty', '~> 0.9'
8
8
  gem 'rake', '~> 10.1'
9
- gem 'rspec', '~> 2.0', '< 2.14'
9
+ gem 'rspec', '~> 2.0', '>= 2.14.1'
10
10
  gem 'fakeweb', '~> 1.3.0'
11
11
  gem 'osm', :path=>'../'
12
12
  gem 'coveralls', '~> 0.7'
13
13
  gem 'simplecov', '~> 0.7'
14
-
15
- #gemspec :path=>"../"
@@ -6,8 +6,12 @@ class ArrayOfValidator < ActiveModel::EachValidator
6
6
  record.errors.add(attribute, "items in the Array must be a #{options[:item_type].name}")
7
7
  else
8
8
  # We don't want to check the item is valid if it's the wrong type
9
- if !options[:item_valid].nil? && (value_item.valid? != options[:item_valid])
10
- record.errors.add(attribute, 'contains an invalid item')
9
+ unless options[:item_valid].nil?
10
+ # Check validity of item matches item_valid option
11
+ unless value_item.valid?.eql?(options[:item_valid])
12
+ message = "contains #{value_item.valid? ? 'a valid' : 'an invalid'} item"
13
+ record.errors.add(attribute, message)
14
+ end
11
15
  end
12
16
  end
13
17
  end
data/lib/osm.rb CHANGED
@@ -150,7 +150,7 @@ module Osm
150
150
  }
151
151
 
152
152
  return permissions.inject({}) do |new_hash, (key, value)|
153
- if ["badge", "member", "user", "register", "contact", "programme","events", "flexi", "finance"].include?(key)
153
+ if ["badge", "member", "user", "register", "contact", "programme","events", "flexi", "finance", "quartermaster"].include?(key)
154
154
  # This is a permission we care about
155
155
  new_hash[key.to_sym] = permissions_map[value.to_i]
156
156
  end
@@ -42,6 +42,7 @@ module Osm
42
42
  permissions_map = {
43
43
  10 => [:read],
44
44
  20 => [:read, :write],
45
+ 100 => [:read, :write, :administer]
45
46
  }
46
47
  result = Array.new
47
48
  ids = Array.new
@@ -269,7 +269,7 @@ module Osm
269
269
  end
270
270
  badges = nil
271
271
 
272
- if user_has_permission?(api, :write, :badge, section_id, options)
272
+ if has_permission?(api, :write, :badge, section_id, options)
273
273
  # We can shortcut and do it in one query
274
274
  badges = api.perform_query("users.php?action=getActivityRequirements&date=#{date.strftime(Osm::OSM_DATE_FORMAT)}&sectionid=#{section.id}&section=#{section.type}")
275
275
 
@@ -112,13 +112,22 @@ module Osm
112
112
  end
113
113
 
114
114
 
115
+ # Check if the user has access to a section
116
+ # @param [Osm::Api] api The api to use to make the request
117
+ # @param [Osm::Section, Fixnum, #to_i] section The Section (or its ID) the $
118
+ # @!macro options_get
119
+ # @return [Boolean] If the Api user has access the section
120
+ def self.has_access_to_section?(api, section, options={})
121
+ api.get_user_permissions(options).keys.include?(section.to_i)
122
+ end
123
+
115
124
  # Raise an exception if the user does not have access to a section
116
125
  # @param [Osm::Api] api The api to use to make the request
117
126
  # @param [Osm::Section, Fixnum, #to_i] section The Section (or its ID) the permission is required on
118
127
  # @!macro options_get
119
128
  # @raise [Osm::Forbidden] If the Api user can not access the section
120
129
  def self.require_access_to_section(api, section, options={})
121
- unless api.get_user_permissions(options).keys.include?(section.to_i)
130
+ unless has_access_to_section?(api, section, options)
122
131
  raise Osm::Forbidden, "You do not have access to that section"
123
132
  end
124
133
  end
@@ -138,7 +147,7 @@ module Osm
138
147
  # @param [Osm::Section, Fixnum, #to_i] section The Section (or its ID) the permission is required on
139
148
  # @!macro options_get
140
149
  def self.has_permission?(api, to, on, section, options={})
141
- user_has_permission(api, to, on, section, options) && api_has_permission(api, to, on, section, options)
150
+ user_has_permission?(api, to, on, section, options) && api_has_permission?(api, to, on, section, options)
142
151
  end
143
152
 
144
153
  # Check if the user has the relevant permission within OSM
@@ -165,13 +174,9 @@ module Osm
165
174
  # @param [Osm::Section, Fixnum, #to_i] section The Section (or its ID) the permission is required on
166
175
  # @!macro options_get
167
176
  def self.api_has_permission?(api, to, on, section, options={})
168
- section_id = section.to_i
169
- permissions = Osm::ApiAccess.get_ours(api, section_id, options).permissions
170
- permissions = permissions[on] || []
171
- unless permissions.include?(to)
172
- return false
173
- end
174
- return true
177
+ access = Osm::ApiAccess.get_ours(api, section, options)
178
+ return false if access.nil?
179
+ (access.permissions[on] || []).include?(to)
175
180
  end
176
181
 
177
182
  # Raise an exception if the user does not have the relevant permission
@@ -182,22 +187,24 @@ module Osm
182
187
  # @!macro options_get
183
188
  # @raise [Osm::Forbidden] If the Api user does not have the required permission
184
189
  def self.require_permission(api, to, on, section, options={})
190
+ section = Osm::Section.get(api, section.to_i, options) unless section.is_a?(Osm::Section)
191
+ section_name = section.try(:name)
185
192
  unless user_has_permission?(api, to, on, section, options)
186
- raise Osm::Forbidden, "Your OSM user does not have permission to #{to} on #{on} for #{Osm::Section.get(api, section.to_i, options).try(:name)}"
193
+ raise Osm::Forbidden, "Your OSM user does not have permission to #{to} on #{on} for #{section_name}."
187
194
  end
188
195
  unless api_has_permission?(api, to, on, section, options)
189
- raise Osm::Forbidden, "You have not granted the #{to} permissions on #{on} to the #{api.api_name} API for #{Osm::Section.get(api, section.to_i, options).try(:name)}"
196
+ raise Osm::Forbidden, "You have not granted the #{to} permissions on #{on} to the #{api.api_name} API for #{section_name}."
190
197
  end
191
198
  end
192
199
 
193
200
  # Raise an exception if the user does not have the relevant permission
194
201
  # @param [Osm::Api] api The api to use to make the request
195
- # @param [Symbol] level The OSM subscription level required (:bronze, :silver, :gold, :gold_plus)
202
+ # @param [Symbol, Fixnum] level The OSM subscription level required (:bronze, :silver, :gold, :gold_plus)
196
203
  # @param [Osm::Section, Fixnum, #to_i] section The Section (or its ID) the subscription is required on
197
204
  # @!macro options_get
198
205
  # @raise [Osm::Forbidden] If the Section does not have the required OSM Subscription (or higher)
199
206
  def self.require_subscription(api, level, section, options={})
200
- section = Osm::Section.get(api, section, options) if section.is_a?(Fixnum)
207
+ section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
201
208
  if level.is_a?(Symbol) # Convert to Fixnum
202
209
  case level
203
210
  when :bronze
@@ -214,7 +221,7 @@ module Osm
214
221
  end
215
222
  if section.nil? || section.subscription_level < level
216
223
  level_name = Osm::SUBSCRIPTION_LEVEL_NAMES[level] || level
217
- raise Osm::Forbidden, "Insufficent OSM subscription level (#{level_name} required for #{section.name})"
224
+ raise Osm::Forbidden, "Insufficent OSM subscription level (#{level_name} required for #{section.name})."
218
225
  end
219
226
  end
220
227
 
@@ -225,7 +232,7 @@ module Osm
225
232
  # @param [Osm::Section, Fixnum, #to_i] section The Section (or its ID) the permission is required on
226
233
  # @!macro options_get
227
234
  def self.require_ability_to(api, to, on, section, options={})
228
- section = Osm::Section.get(api, section, options) if section.is_a?(Fixnum)
235
+ section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
229
236
  require_permission(api, to, on, section, options)
230
237
  if section.youth_section? && [:register, :contact, :events, :flexi].include?(on)
231
238
  require_subscription(api, :silver, section, options)
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+
5
+ class FixnumTestModel < Osm::Model
6
+ attribute :array
7
+ validates :array, :array_of => {:item_type => Fixnum}
8
+ end
9
+
10
+ class TestItem
11
+ def initialize(attrs)
12
+ @valid = !!attrs[:valid]
13
+ end
14
+ def valid?
15
+ @valid
16
+ end
17
+ end
18
+
19
+ class ValidTestModel < Osm::Model
20
+ attribute :array
21
+ validates :array, :array_of => {:item_type => TestItem, :item_valid=>true}
22
+ end
23
+
24
+ class InvalidTestModel < Osm::Model
25
+ attribute :array
26
+ validates :array, :array_of => {:item_type => TestItem, :item_valid=>false}
27
+ end
28
+
29
+ class NovalidTestModel < Osm::Model
30
+ attribute :array
31
+ validates :array, :array_of => {:item_type => TestItem}
32
+ end
33
+
34
+
35
+ describe "array_of validator" do
36
+
37
+ it "Allows an empty array" do
38
+ i = FixnumTestModel.new(array: [])
39
+ i.valid?.should == true
40
+ i.errors.count.should == 0
41
+ end
42
+
43
+ describe ":item_type option" do
44
+
45
+ it "Allows arrays of the right type" do
46
+ i = FixnumTestModel.new(array: [1, 2, 3])
47
+ i.valid?.should == true
48
+ i.errors.count.should == 0
49
+ end
50
+
51
+ it "Forbids arrays containing >= 1 incorrect type" do
52
+ i = FixnumTestModel.new(array: [1, '2', 3])
53
+ i.valid?.should == false
54
+ i.errors.count.should == 1
55
+ i.errors.messages.should == {:array=>["items in the Array must be a Fixnum"]}
56
+ end
57
+
58
+ end
59
+
60
+ describe ":valid option" do
61
+
62
+ it "Allows (in)valid items unless valid option is passed" do
63
+ i = NovalidTestModel.new(array: [TestItem.new(valid: false), TestItem.new(valid: true)])
64
+ i.valid?.should == true
65
+ i.errors.count.should == 0
66
+ end
67
+
68
+ describe "Valid option is false" do
69
+
70
+ it "Contains all invalid items" do
71
+ i = InvalidTestModel.new(array: [TestItem.new(valid: false)])
72
+ i.valid?.should == true
73
+ i.errors.count.should == 0
74
+ end
75
+
76
+ it "Contains a valid item" do
77
+ i = InvalidTestModel.new(array: [TestItem.new(valid: true)])
78
+ i.valid?.should == false
79
+ i.errors.count.should == 1
80
+ i.errors.messages.should == {:array => ['contains a valid item']}
81
+ end
82
+
83
+ end
84
+
85
+ describe "Valid option is true" do
86
+
87
+ it "Contains all valid items" do
88
+ i = ValidTestModel.new(array: [TestItem.new(valid: true)])
89
+ i.valid?.should == true
90
+ i.errors.count.should == 0
91
+ end
92
+
93
+ it "Contains an invalid item" do
94
+ i = ValidTestModel.new(array: [TestItem.new(valid: false)])
95
+ i.valid?.should == false
96
+ i.errors.count.should == 1
97
+ i.errors.messages.should == {:array => ['contains an invalid item']} end
98
+ end
99
+
100
+ end
101
+
102
+ end
@@ -119,8 +119,8 @@ describe "Activity" do
119
119
  activity.location.should == :indoors
120
120
  activity.shared.should == 0
121
121
  activity.rating.should == 4
122
- activity.editable.should == true
123
- activity.deletable.should == false
122
+ activity.editable.should be_true
123
+ activity.deletable.should be_false
124
124
  activity.used.should == 3
125
125
  activity.versions[0].version.should == 0
126
126
  activity.versions[0].created_by.should == 1
@@ -35,7 +35,7 @@ describe "API Access" do
35
35
  {
36
36
  'apiid' => '1',
37
37
  'name' => 'API Name',
38
- 'permissions' => { 'read' => '10', 'readwrite' => '20' }
38
+ 'permissions' => { 'read' => '10', 'readwrite' => '20', 'administer' => '100' }
39
39
  }, {
40
40
  'apiid' => '2',
41
41
  'name' => 'API 2 Name',
@@ -54,7 +54,7 @@ describe "API Access" do
54
54
  api_access = api_accesses[0]
55
55
  api_access.id.should == 1
56
56
  api_access.name.should == 'API Name'
57
- api_access.permissions.should == {:read => [:read], :readwrite => [:read, :write]}
57
+ api_access.permissions.should == {:read => [:read], :readwrite => [:read, :write], :administer => [:read, :write, :administer]}
58
58
  end
59
59
 
60
60
  it "From cache" do
@@ -36,7 +36,7 @@ describe "Badge" do
36
36
  requirement.name.should == 'name'
37
37
  requirement.description.should == 'description'
38
38
  requirement.field.should == 'field'
39
- requirement.editable.should == true
39
+ requirement.editable.should be_true
40
40
  requirement.badge.osm_key.should == 'key'
41
41
  requirement.valid?.should be_true
42
42
  end
@@ -423,7 +423,7 @@ describe "Badge" do
423
423
  requirement.name.should == 'r_name'
424
424
  requirement.description.should == 'r_description'
425
425
  requirement.field.should == 'r_field'
426
- requirement.editable.should == true
426
+ requirement.editable.should be_true
427
427
  requirement.badge.osm_key.should == 'badge'
428
428
  end
429
429
 
@@ -445,7 +445,7 @@ describe "Badge" do
445
445
  requirement.name.should == 'r_name'
446
446
  requirement.description.should == 'r_description'
447
447
  requirement.field.should == 'r_field'
448
- requirement.editable.should == true
448
+ requirement.editable.should be_true
449
449
  requirement.badge.osm_key.should == 'badge'
450
450
  end
451
451
 
@@ -467,7 +467,7 @@ describe "Badge" do
467
467
  requirement.name.should == 'r_name'
468
468
  requirement.description.should == 'r_description'
469
469
  requirement.field.should == 'r_field'
470
- requirement.editable.should == true
470
+ requirement.editable.should be_true
471
471
  requirement.badge.osm_key.should == 'badge'
472
472
  end
473
473
 
@@ -489,7 +489,7 @@ describe "Badge" do
489
489
  requirement.name.should == 'r_name'
490
490
  requirement.description.should == 'r_description'
491
491
  requirement.field.should == 'r_field'
492
- requirement.editable.should == true
492
+ requirement.editable.should be_true
493
493
  requirement.badge.osm_key.should == 'badge'
494
494
  end
495
495
 
@@ -51,7 +51,7 @@ describe "Badges" do
51
51
  FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=outstandingBadges&section=cubs&sectionid=1&termid=2", :body => data.to_json, :content_type => 'application/json')
52
52
 
53
53
  db = Osm::Badges.get_due_badges(@api, Osm::Section.new(:id => 1, :type => :cubs), 2)
54
- db.empty?.should == false
54
+ db.empty?.should be_false
55
55
  db.badge_names.should == {'badge_name_1'=>'Badge Name', 'staged_staged_participation_2'=>'Participation (Level 2)'}
56
56
  db.by_member.should == {1=>['badge_name_1', 'staged_staged_participation_2'], 2=>['staged_staged_participation_2']}
57
57
  db.member_names.should == {1 => 'John Doe', 2 => 'Jane Doe'}
@@ -62,7 +62,7 @@ describe "Badges" do
62
62
  it "handles an empty array representing no due badges" do
63
63
  FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=outstandingBadges&section=cubs&sectionid=1&termid=2", :body => '[]', :content_type => 'application/json')
64
64
  db = Osm::Badges.get_due_badges(@api, Osm::Section.new(:id => 1, :type => :cubs), 2)
65
- db.should_not == nil
65
+ db.should_not be_nil
66
66
  end
67
67
 
68
68
 
@@ -32,7 +32,7 @@ describe "Event" do
32
32
  event.section_id.should == 2
33
33
  event.name.should == 'Event name'
34
34
  event.start.should == DateTime.new(2001, 1, 2, 12, 0, 0)
35
- event.finish.should == nil
35
+ event.finish.should be_nil
36
36
  event.cost.should == '1.23'
37
37
  event.location.should == 'Somewhere'
38
38
  event.notes.should == 'None'
@@ -41,10 +41,10 @@ describe "Event" do
41
41
  event.notepad.should == 'notepad'
42
42
  event.public_notepad.should == 'public notepad'
43
43
  event.confirm_by_date.should == Date.new(2002, 1, 2)
44
- event.allow_changes.should == true
45
- event.reminders.should == false
44
+ event.allow_changes.should be_true
45
+ event.reminders.should be_false
46
46
  event.attendance_limit.should == 3
47
- event.attendance_limit_includes_leaders.should == true
47
+ event.attendance_limit_includes_leaders.should be_true
48
48
  event.attendance_reminder.should == 14
49
49
  event.allow_booking.should be_false
50
50
  event.valid?.should be_true
@@ -196,16 +196,16 @@ describe "Event" do
196
196
  event.notepad.should == 'notepad'
197
197
  event.public_notepad.should == 'public notepad'
198
198
  event.confirm_by_date.should == Date.new(2002, 1, 2)
199
- event.allow_changes.should == true
200
- event.reminders.should == false
199
+ event.allow_changes.should be_true
200
+ event.reminders.should be_false
201
201
  event.attendance_limit.should == 3
202
- event.attendance_limit_includes_leaders.should == true
202
+ event.attendance_limit_includes_leaders.should be_true
203
203
  event.attendance_reminder.should == 7
204
- event.allow_booking.should == true
204
+ event.allow_booking.should be_true
205
205
  event.columns[0].id.should == 'f_1'
206
206
  event.columns[0].name.should == 'Name'
207
207
  event.columns[0].label.should == 'Label'
208
- event.columns[0].parent_required.should == true
208
+ event.columns[0].parent_required.should be_true
209
209
  event.valid?.should be_true
210
210
  end
211
211
 
@@ -282,7 +282,7 @@ describe "Event" do
282
282
  it "No limit" do
283
283
  event = Osm::Event.new(:attendance_limit => 0, :id => 1, :section_id => 2)
284
284
  event.spaces?(@api).should be_true
285
- event.spaces(@api).should == nil
285
+ event.spaces(@api).should be_nil
286
286
  end
287
287
 
288
288
  it "Under limit" do
@@ -975,4 +975,4 @@ describe "Event" do
975
975
 
976
976
  end
977
977
 
978
- end
978
+ end
@@ -103,6 +103,18 @@ describe "Flexi Record" do
103
103
  records.sort.should == [fr1, fr2, fr3]
104
104
  end
105
105
 
106
+ it "Compare handles a nil name" do
107
+ fr1 = Osm::FlexiRecord.new(section_id: 1, name: nil)
108
+ fr2 = Osm::FlexiRecord.new(section_id: 1, name: 'Something')
109
+ (fr1 <=> fr2).should == -1
110
+ end
111
+
112
+ it "Compare handles a nil section_id" do
113
+ fr1 = Osm::FlexiRecord.new(section_id: nil, name: 'a')
114
+ fr2 = Osm::FlexiRecord.new(section_id: 1, name: 'a')
115
+ (fr1 <=> fr2).should == -1
116
+ end
117
+
106
118
 
107
119
  describe "Using the API" do
108
120
 
@@ -29,7 +29,7 @@ describe "Grouping" do
29
29
  patrol.id.should == 1
30
30
  patrol.section_id.should == 2
31
31
  patrol.name.should == 'Patrol Name'
32
- patrol.active.should == true
32
+ patrol.active.should be_true
33
33
  patrol.points.should == 3
34
34
  patrol.valid?.should be_true
35
35
  end
@@ -101,4 +101,4 @@ describe "Grouping" do
101
101
 
102
102
  end
103
103
 
104
- end
104
+ end
@@ -20,8 +20,8 @@ describe "Invoice" do
20
20
  i.name.should == 'Name'
21
21
  i.extra_details.should == 'Extra Details'
22
22
  i.date.should == Date.new(2001, 2, 3)
23
- i.archived.should == true
24
- i.finalised.should == true
23
+ i.archived.should be_true
24
+ i.finalised.should be_true
25
25
  i.valid?.should be_true
26
26
  end
27
27
 
@@ -168,8 +168,8 @@ describe "Invoice" do
168
168
  invoice.name.should == 'Invoice 1'
169
169
  invoice.extra_details.should == 'Some more details'
170
170
  invoice.date.should == Date.new(2010, 1, 1)
171
- invoice.archived.should == false
172
- invoice.finalised.should == false
171
+ invoice.archived.should be_false
172
+ invoice.finalised.should be_false
173
173
  invoice.valid?.should be_true
174
174
  end
175
175
 
@@ -157,6 +157,7 @@ describe "Meeting" do
157
157
  end
158
158
 
159
159
  it "Fetch badge requirements for a meeting (from API)" do
160
+ Osm::Model.stub('has_permission?').and_return(true)
160
161
  badges_body = [{'a'=>'a'},{'a'=>'A'}]
161
162
  FakeWeb.register_uri(:post, 'https://www.onlinescoutmanager.co.uk/users.php?action=getActivityRequirements&date=2000-01-02&sectionid=3&section=cubs', :body => badges_body.to_json, :content_type => 'application/json')
162
163
  roles_body = [
@@ -169,6 +170,7 @@ describe "Meeting" do
169
170
  end
170
171
 
171
172
  it "Fetch badge requirements for a meeting (iterating through activities)" do
173
+ Osm::Model.stub('has_permission?').with(@api, :write, :badge, 3, {}).and_return(false)
172
174
  roles_body = [
173
175
  {"sectionConfig"=>"{\"subscription_level\":1,\"subscription_expires\":\"2013-01-05\",\"sectionType\":\"cubs\",\"columnNames\":{\"column_names\":\"names\"},\"numscouts\":10,\"hasUsedBadgeRecords\":true,\"hasProgramme\":true,\"extraRecords\":[],\"wizard\":\"false\",\"fields\":{\"fields\":true},\"intouch\":{\"intouch_fields\":true},\"mobFields\":{\"mobile_fields\":true}}", "groupname"=>"3rd Somewhere", "groupid"=>"3", "groupNormalised"=>"1", "sectionid"=>"3", "sectionname"=>"Section 1", "section"=>"beavers", "isDefault"=>"1", "permissions"=>{"badge"=>10, "member"=>20, "user"=>100, "register"=>100, "contact"=>100, "programme"=>10, "originator"=>1, "events"=>100, "finance"=>100, "flexi"=>100}},
174
176
  ]
@@ -253,7 +255,7 @@ describe "Meeting" do
253
255
  :start_time => '11:11',
254
256
  :finish_time => '22:22',
255
257
  :title => 'Title',
256
- }).should be_true
258
+ }).is_a?(Osm::Meeting).should be_true
257
259
  end
258
260
 
259
261
  it "Create a meeting (failed)" do
@@ -265,7 +267,7 @@ describe "Meeting" do
265
267
  :start_time => '11:11',
266
268
  :finish_time => '22:22',
267
269
  :title => 'Title',
268
- }).should be_false
270
+ }).should be_nil
269
271
  end
270
272
 
271
273
 
@@ -179,4 +179,232 @@ describe "Model" do
179
179
 
180
180
  end
181
181
 
182
+ describe "Access control" do
183
+
184
+ describe "user_has_permission?" do
185
+
186
+ before :each do
187
+ @api.stub(:get_user_permissions).and_return( { 1 => {foo: [:bar]} } )
188
+ end
189
+
190
+ it "Has permission" do
191
+ Osm::Model.user_has_permission?(@api, :bar, :foo, 1).should be_true
192
+ end
193
+
194
+ it "Doesn't have the level of permission" do
195
+ Osm::Model.user_has_permission?(@api, :barbar, :foo, 1).should be_false
196
+ end
197
+
198
+ it "Doesn't have access to section" do
199
+ Osm::Model.user_has_permission?(@api, :bar, :foo, 2).should be_false
200
+ end
201
+
202
+ end
203
+
204
+ describe "api_has_permission?" do
205
+
206
+ before :each do
207
+ Osm::ApiAccess.stub(:get_ours).and_return(Osm::ApiAccess.new(
208
+ id: @api.api_id,
209
+ name: @api.api_name,
210
+ permissions: {foo: [:bar]}
211
+ ))
212
+ end
213
+
214
+ it "Has permission" do
215
+ Osm::Model.api_has_permission?(@api, :bar, :foo, 1).should be_true
216
+ end
217
+
218
+ it "Doesn't have the level of permission" do
219
+ Osm::Model.api_has_permission?(@api, :barbar, :foo, 1).should be_false
220
+ end
221
+
222
+ it "Doesn't have access to the section" do
223
+ Osm::ApiAccess.stub(:get_ours).and_return(nil)
224
+ Osm::Model.api_has_permission?(@api, :bar, :foo, 2).should be_false
225
+ end
226
+
227
+ end
228
+
229
+ describe "has_permission?" do
230
+
231
+ it "Only returns true if the user can and they have granted the api permission" do
232
+ section = Osm::Section.new
233
+ options = {:foo => :bar}
234
+ expect(Osm::Model).to receive('user_has_permission?').with(@api, :can_do, :can_to, section, options).and_return(true)
235
+ expect(Osm::Model).to receive('api_has_permission?').with(@api, :can_do, :can_to, section, options).and_return(true)
236
+ Osm::Model.has_permission?(@api, :can_do, :can_to, section, options).should be_true
237
+ end
238
+
239
+ describe "Otherwise returns false" do
240
+ [ [true,false], [false, true], [false, false] ].each do |user, api|
241
+ it "User #{user ? 'can' : "can't"} and #{api ? 'has' : "hasn't"} given access" do
242
+ Osm::Model.stub('user_has_permission?').and_return(user)
243
+ Osm::Model.stub('api_has_permission?').and_return(api)
244
+ Osm::Model.has_permission?(@api, :can_do, :can_to, Osm::Section.new).should be_false
245
+ end
246
+ end
247
+ end
248
+
249
+ end
250
+
251
+ describe "has_access_to_section?" do
252
+
253
+ before :each do
254
+ @api.stub(:get_user_permissions).and_return( {1=>{}} )
255
+ end
256
+
257
+ it "Has access" do
258
+ Osm::Model.has_access_to_section?(@api, 1).should be_true
259
+ end
260
+
261
+ it "Doesn't have access" do
262
+ Osm::Model.has_access_to_section?(@api, 2).should be_false
263
+ end
264
+
265
+ end
266
+
267
+ describe "require_access_to_section" do
268
+
269
+ before :each do
270
+ Osm::Model.unstub(:require_access_to_section)
271
+ end
272
+
273
+ it "Does nothing when access is allowed" do
274
+ Osm::Model.stub('has_access_to_section?') { true }
275
+ expect{ Osm::Model.require_access_to_section(@api, 1) }.not_to raise_error
276
+ end
277
+
278
+ it "Raises exception when access is not allowed" do
279
+ Osm::Model.stub('has_access_to_section?') { false }
280
+ expect{ Osm::Model.require_access_to_section(@api, 1) }.to raise_error(Osm::Forbidden, "You do not have access to that section")
281
+ end
282
+
283
+ end
284
+
285
+ describe "require_permission" do
286
+
287
+ it "Does nothing when access is allowed" do
288
+ Osm::Model.stub('user_has_permission?').and_return(true)
289
+ Osm::Model.stub('api_has_permission?').and_return(true)
290
+ section = Osm::Section.new(name: 'A SECTION')
291
+ expect{ Osm::Model.require_permission(@api, :to, :on, section) }.not_to raise_error
292
+ end
293
+
294
+ it "Raises exception when user doesn't have access" do
295
+ Osm::Model.stub('user_has_permission?').and_return(false)
296
+ Osm::Model.stub('api_has_permission?').and_return(true)
297
+ section = Osm::Section.new(name: 'A SECTION')
298
+ expect{ Osm::Model.require_permission(@api, :can_do, :can_on, section) }.to raise_error(Osm::Forbidden, "Your OSM user does not have permission to can_do on can_on for A SECTION.")
299
+ end
300
+
301
+ it "Raises exception when api doesn't have access" do
302
+ Osm::Model.stub('user_has_permission?').and_return(true)
303
+ Osm::Model.stub('api_has_permission?').and_return(false)
304
+ section = Osm::Section.new(name: 'A SECTION')
305
+ expect{ Osm::Model.require_permission(@api, :can_to, :can_on, section) }.to raise_error(Osm::Forbidden, "You have not granted the can_to permissions on can_on to the API NAME API for A SECTION.")
306
+ end
307
+
308
+ end
309
+
310
+ describe "require_subscription" do
311
+
312
+ it "Checks against a number" do
313
+ section1 = Osm::Section.new(subscription_level: 1, name: 'NAME') # Bronze
314
+ section2 = Osm::Section.new(subscription_level: 2, name: 'NAME') # Silver
315
+ section3 = Osm::Section.new(subscription_level: 3, name: 'NAME') # Gold
316
+ section4 = Osm::Section.new(subscription_level: 4, name: 'NAME') # Gold+
317
+
318
+ expect{ Osm::Model.require_subscription(@api, 1, section1) }.not_to raise_error
319
+ expect{ Osm::Model.require_subscription(@api, 2, section1) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Silver required for NAME).")
320
+ expect{ Osm::Model.require_subscription(@api, 3, section1) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold required for NAME).")
321
+ expect{ Osm::Model.require_subscription(@api, 4, section1) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold+ required for NAME).")
322
+
323
+ expect{ Osm::Model.require_subscription(@api, 1, section2) }.not_to raise_error
324
+ expect{ Osm::Model.require_subscription(@api, 2, section2) }.not_to raise_error
325
+ expect{ Osm::Model.require_subscription(@api, 3, section2) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold required for NAME).")
326
+ expect{ Osm::Model.require_subscription(@api, 4, section2) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold+ required for NAME).")
327
+
328
+ expect{ Osm::Model.require_subscription(@api, 1, section3) }.not_to raise_error
329
+ expect{ Osm::Model.require_subscription(@api, 2, section3) }.not_to raise_error
330
+ expect{ Osm::Model.require_subscription(@api, 3, section3) }.not_to raise_error
331
+ expect{ Osm::Model.require_subscription(@api, 4, section3) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold+ required for NAME).")
332
+
333
+ expect{ Osm::Model.require_subscription(@api, 1, section4) }.not_to raise_error
334
+ expect{ Osm::Model.require_subscription(@api, 2, section4) }.not_to raise_error
335
+ expect{ Osm::Model.require_subscription(@api, 3, section4) }.not_to raise_error
336
+ expect{ Osm::Model.require_subscription(@api, 4, section4) }.not_to raise_error
337
+ end
338
+
339
+ it "Checks against a symbol" do
340
+ section1 = Osm::Section.new(subscription_level: 1, name: 'NAME') # Bronze
341
+ section2 = Osm::Section.new(subscription_level: 2, name: 'NAME') # Silver
342
+ section3 = Osm::Section.new(subscription_level: 3, name: 'NAME') # Gold
343
+ section4 = Osm::Section.new(subscription_level: 4, name: 'NAME') # Gold+
344
+
345
+ expect{ Osm::Model.require_subscription(@api, :bronze, section1) }.not_to raise_error
346
+ expect{ Osm::Model.require_subscription(@api, :silver, section1) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Silver required for NAME).")
347
+ expect{ Osm::Model.require_subscription(@api, :gold, section1) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold required for NAME).")
348
+ expect{ Osm::Model.require_subscription(@api, :gold_plus, section1) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold+ required for NAME).")
349
+
350
+ expect{ Osm::Model.require_subscription(@api, :bronze, section2) }.not_to raise_error
351
+ expect{ Osm::Model.require_subscription(@api, :silver, section2) }.not_to raise_error
352
+ expect{ Osm::Model.require_subscription(@api, :gold, section2) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold required for NAME).")
353
+ expect{ Osm::Model.require_subscription(@api, :gold_plus, section2) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold+ required for NAME).")
354
+
355
+ expect{ Osm::Model.require_subscription(@api, :bronze, section3) }.not_to raise_error
356
+ expect{ Osm::Model.require_subscription(@api, :silver, section3) }.not_to raise_error
357
+ expect{ Osm::Model.require_subscription(@api, :gold, section3) }.not_to raise_error
358
+ expect{ Osm::Model.require_subscription(@api, :gold_plus, section3) }.to raise_error(Osm::Forbidden, "Insufficent OSM subscription level (Gold+ required for NAME).")
359
+
360
+ expect{ Osm::Model.require_subscription(@api, :bronze, section4) }.not_to raise_error
361
+ expect{ Osm::Model.require_subscription(@api, :silver, section4) }.not_to raise_error
362
+ expect{ Osm::Model.require_subscription(@api, :gold, section4) }.not_to raise_error
363
+ expect{ Osm::Model.require_subscription(@api, :gold_plus, section4) }.not_to raise_error
364
+ end
365
+
366
+ end
367
+
368
+ describe "Require_abillity_to" do
369
+
370
+ before :each do
371
+ Osm::Model.unstub(:require_ability_to)
372
+ end
373
+
374
+ it "Requires permission" do
375
+ section = Osm::Section.new(type: :waiting)
376
+ options = {foo: 'bar'}
377
+ expect(Osm::Model).to receive(:require_permission).with(@api, :can_do, :can_on, section, options).and_return(true)
378
+ expect(Osm::Model).not_to receive(:require_subscription)
379
+ expect{ Osm::Model.require_ability_to(@api, :can_do, :can_on, section, options) }.not_to raise_error
380
+ end
381
+
382
+ describe "Requires the right subscription level for" do
383
+
384
+ before :each do
385
+ @section = Osm::Section.new(type: :beavers)
386
+ @options = {bar: 'foo'}
387
+ Osm::Model.stub(:require_permission).and_return(nil)
388
+ end
389
+
390
+ [:register, :contact, :events, :flexi].each do |can_on|
391
+ it ":#{can_on.to_s} (Silver)" do
392
+ expect(Osm::Model).to receive(:require_subscription).with(@api, :silver, @section, @options).and_return(true)
393
+ expect{ Osm::Model.require_ability_to(@api, :read, can_on, @section, @options) }.to_not raise_error
394
+ end
395
+ end
396
+
397
+ [:finance].each do |can_on|
398
+ it ":#{can_on.to_s} (Gold)" do
399
+ expect(Osm::Model).to receive(:require_subscription).with(@api, :gold, @section, @options).and_return(true)
400
+ expect{ Osm::Model.require_ability_to(@api, :read, can_on, @section, @options) }.to_not raise_error
401
+ end
402
+ end
403
+
404
+ end
405
+
406
+ end
407
+
408
+ end
409
+
182
410
  end
@@ -22,19 +22,19 @@ describe "Online Scout Manager" do
22
22
  end
23
23
 
24
24
  it "is given neither" do
25
- Osm::make_datetime('', '').should == nil
25
+ Osm::make_datetime('', '').should be_nil
26
26
  end
27
27
 
28
28
  it "is given an invalid date" do
29
- Osm::make_datetime('No date here1', '04:05:06').should == nil
29
+ Osm::make_datetime('No date here1', '04:05:06').should be_nil
30
30
  end
31
31
 
32
32
  it "is given an invalid time" do
33
- Osm::make_datetime('2001-02-03', 'No time here!').should == nil
33
+ Osm::make_datetime('2001-02-03', 'No time here!').should be_nil
34
34
  end
35
35
 
36
36
  it "is given just an invalid date" do
37
- Osm::make_datetime('No date here1', nil).should == nil
37
+ Osm::make_datetime('No date here1', nil).should be_nil
38
38
  end
39
39
  end
40
40
 
@@ -64,29 +64,29 @@ describe "Section" do
64
64
  section.group_id.should == 3
65
65
  section.group_name.should == '3rd Somewhere'
66
66
  section.flexi_records.should == []
67
- section.gocardless.should == true
67
+ section.gocardless.should be_true
68
68
  section.myscout_events_expires.should == Date.today + 61
69
69
  section.myscout_badges_expires.should == Date.today + 62
70
70
  section.myscout_programme_expires.should == Date.today + 63
71
71
  section.myscout_details_expires.should == Date.today + 64
72
- section.myscout_events.should == true
73
- section.myscout_badges.should == true
74
- section.myscout_programme.should == true
75
- section.myscout_payments.should == true
72
+ section.myscout_events.should be_true
73
+ section.myscout_badges.should be_true
74
+ section.myscout_programme.should be_true
75
+ section.myscout_payments.should be_true
76
76
  section.myscout_emails.should == {:email1 => true, :email2 => false}
77
77
  section.myscout_email_address_from.should == 'send_from@example.com'
78
78
  section.myscout_email_address_copy.should == ''
79
- section.myscout_badges_partial.should == true
80
- section.myscout_programme_summary.should == true
81
- section.myscout_programme_times.should == true
79
+ section.myscout_badges_partial.should be_true
80
+ section.myscout_programme_summary.should be_true
81
+ section.myscout_programme_times.should be_true
82
82
  section.myscout_programme_show.should == 20
83
83
  section.myscout_event_reminder_count.should == 4
84
84
  section.myscout_event_reminder_frequency.should == 5
85
85
  section.myscout_payment_reminder_count.should == 6
86
86
  section.myscout_payment_reminder_frequency.should == 7
87
- section.myscout_details.should == true
87
+ section.myscout_details.should be_true
88
88
  section.myscout_details_email_changes_to.should == 'notify-changes-to@example.com'
89
- section.sms_sent_test.should == true
89
+ section.sms_sent_test.should be_true
90
90
  section.sms_messages_sent.should == 8
91
91
  section.sms_messages_remaining.should == 9
92
92
  section.valid?.should be_true
@@ -97,7 +97,7 @@ describe "Section" do
97
97
  section = Osm::Section.new
98
98
 
99
99
  section.subscription_level.should == 1
100
- section.subscription_expires.should == nil
100
+ section.subscription_expires.should be_nil
101
101
  section.type.should == :unknown
102
102
  section.column_names.should == {}
103
103
  section.fields.should == {}
@@ -108,7 +108,7 @@ describe "Section" do
108
108
  section.myscout_email_address_copy.should == ''
109
109
  section.myscout_details_email_changes_to.should == ''
110
110
  section.myscout_programme_show.should == 0
111
- section.sms_sent_test.should == false
111
+ section.sms_sent_test.should be_false
112
112
  section.sms_messages_sent.should == 0
113
113
  section.sms_messages_remaining.should == 0
114
114
  end
@@ -144,29 +144,29 @@ describe "Section" do
144
144
  section.flexi_records.size.should == 1
145
145
  section.flexi_records[0].id.should == 111
146
146
  section.flexi_records[0].name.should == 'Flexi Record 1'
147
- section.gocardless.should == true
147
+ section.gocardless.should be_true
148
148
  section.myscout_events_expires.should == Date.new(2013, 1, 6)
149
149
  section.myscout_badges_expires.should == Date.new(2013, 1, 7)
150
150
  section.myscout_programme_expires.should == Date.new(2013, 1, 8)
151
151
  section.myscout_programme_show.should == 10
152
152
  section.myscout_details_expires.should == Date.new(2013, 1, 9)
153
- section.myscout_events.should == true
154
- section.myscout_badges.should == true
155
- section.myscout_programme.should == true
156
- section.myscout_payments.should == true
153
+ section.myscout_events.should be_true
154
+ section.myscout_badges.should be_true
155
+ section.myscout_programme.should be_true
156
+ section.myscout_payments.should be_true
157
157
  section.myscout_emails.should == {:email1 => true, :email2 => false}
158
158
  section.myscout_email_address_from.should == 'send_from@example.com'
159
159
  section.myscout_email_address_copy.should == ''
160
- section.myscout_badges_partial.should == true
161
- section.myscout_programme_summary.should == true
162
- section.myscout_programme_times.should == true
160
+ section.myscout_badges_partial.should be_true
161
+ section.myscout_programme_summary.should be_true
162
+ section.myscout_programme_times.should be_true
163
163
  section.myscout_event_reminder_count.should == 4
164
164
  section.myscout_event_reminder_frequency.should == 5
165
165
  section.myscout_payment_reminder_count.should == 6
166
166
  section.myscout_payment_reminder_frequency.should == 7
167
- section.myscout_details.should == true
167
+ section.myscout_details.should be_true
168
168
  section.myscout_details_email_changes_to.should == 'notify-changes-to@example.com'
169
- section.sms_sent_test.should == true
169
+ section.sms_sent_test.should be_true
170
170
  section.sms_messages_remaining.should == 8
171
171
  section.sms_messages_sent.should == 9
172
172
  section.valid?.should be_true
@@ -53,9 +53,9 @@ describe "Term" do
53
53
  term2 = Osm::Term.new(@attributes.merge(:start => (Date.today - 0), :finish => (Date.today + 0)))
54
54
  term3 = Osm::Term.new(@attributes.merge(:start => (Date.today + 1), :finish => (Date.today + 60)))
55
55
 
56
- term1.before?(Date.today).should == true
57
- term2.before?(Date.today).should == false
58
- term3.before?(Date.today).should == false
56
+ term1.before?(Date.today).should be_true
57
+ term2.before?(Date.today).should be_false
58
+ term3.before?(Date.today).should be_false
59
59
  end
60
60
 
61
61
  it "Works out if it is completly after a date" do
@@ -63,9 +63,9 @@ describe "Term" do
63
63
  term2 = Osm::Term.new(@attributes.merge(:start => (Date.today - 0), :finish => (Date.today + 0)))
64
64
  term3 = Osm::Term.new(@attributes.merge(:start => (Date.today + 1), :finish => (Date.today + 60)))
65
65
 
66
- term1.after?(Date.today).should == false
67
- term2.after?(Date.today).should == false
68
- term3.after?(Date.today).should == true
66
+ term1.after?(Date.today).should be_false
67
+ term2.after?(Date.today).should be_false
68
+ term3.after?(Date.today).should be_true
69
69
  end
70
70
 
71
71
  it "Works out if it has passed" do
@@ -73,9 +73,9 @@ describe "Term" do
73
73
  term2 = Osm::Term.new(@attributes.merge(:start => (Date.today - 0), :finish => (Date.today + 0)))
74
74
  term3 = Osm::Term.new(@attributes.merge(:start => (Date.today + 1), :finish => (Date.today + 60)))
75
75
 
76
- term1.past?().should == true
77
- term2.past?().should == false
78
- term3.past?().should == false
76
+ term1.past?().should be_true
77
+ term2.past?().should be_false
78
+ term3.past?().should be_false
79
79
  end
80
80
 
81
81
  it "Works out if it is in the future" do
@@ -83,9 +83,9 @@ describe "Term" do
83
83
  term2 = Osm::Term.new(@attributes.merge(:start => (Date.today - 0), :finish => (Date.today + 0)))
84
84
  term3 = Osm::Term.new(@attributes.merge(:start => (Date.today + 1), :finish => (Date.today + 60)))
85
85
 
86
- term1.future?().should == false
87
- term2.future?().should == false
88
- term3.future?().should == true
86
+ term1.future?().should be_false
87
+ term2.future?().should be_false
88
+ term3.future?().should be_true
89
89
  end
90
90
 
91
91
  it "Works out if it is the current term" do
@@ -93,9 +93,9 @@ describe "Term" do
93
93
  term2 = Osm::Term.new(@attributes.merge(:start=> (Date.today - 0), :finish => (Date.today + 0)))
94
94
  term3 = Osm::Term.new(@attributes.merge(:start => (Date.today + 1), :finish => (Date.today + 60)))
95
95
 
96
- term1.current?().should == false
97
- term2.current?().should == true
98
- term3.current?().should == false
96
+ term1.current?().should be_false
97
+ term2.current?().should be_true
98
+ term3.current?().should be_false
99
99
  end
100
100
 
101
101
  it "Works out if it contains a date" do
@@ -103,9 +103,9 @@ describe "Term" do
103
103
  term2 = Osm::Term.new(@attributes.merge(:start => (Date.today - 0), :finish => (Date.today + 0)))
104
104
  term3 = Osm::Term.new(@attributes.merge(:start => (Date.today + 1), :finish => (Date.today + 60)))
105
105
 
106
- term1.contains_date?(Date.today).should == false
107
- term2.contains_date?(Date.today).should == true
108
- term3.contains_date?(Date.today).should == false
106
+ term1.contains_date?(Date.today).should be_false
107
+ term2.contains_date?(Date.today).should be_true
108
+ term3.contains_date?(Date.today).should be_false
109
109
  end
110
110
 
111
111
  it "Date helpers return false for nil dates" do
@@ -20,6 +20,7 @@ FakeWeb.allow_net_connect = %r[^https://coveralls.io] # Allow coveralls to repor
20
20
 
21
21
 
22
22
  RSpec.configure do |config|
23
+
23
24
  # == Mock Framework
24
25
  #
25
26
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
@@ -27,7 +28,17 @@ RSpec.configure do |config|
27
28
  # config.mock_with :mocha
28
29
  # config.mock_with :flexmock
29
30
  # config.mock_with :rr
30
- config.mock_with :rspec
31
+ config.mock_with :rspec do |configuration|
32
+ # Using the expect syntax is preferable to the should syntax in some cases.
33
+ # The problem here is that the :should syntax that RSpec uses can fail in
34
+ # the case of proxy objects, and objects that include the delegate module.
35
+ # Essentially it requires that we define methods on every object in the
36
+ # system. Not owning every object means that we cannot ensure this works in
37
+ # a consistent manner. The expect syntax gets around this problem by not
38
+ # relying on RSpec specific methods being defined on every object in the
39
+ # system.
40
+ configuration.syntax = [:expect, :should]
41
+ end
31
42
 
32
43
  config.before(:each) do
33
44
  FakeWeb.clean_registry
@@ -54,8 +65,8 @@ RSpec.configure do |config|
54
65
  Osm::configure(@CONFIGURATION)
55
66
 
56
67
  @api = Osm::Api.new('user_id', 'secret')
57
- Osm::Model.stub(:require_ability_to) {}
58
- Osm::Model.stub(:require_access_to_section) {}
68
+ Osm::Model.stub(:require_ability_to).and_return(nil)
69
+ Osm::Model.stub(:require_access_to_section).and_return(nil)
59
70
  end
60
71
  end
61
72
 
data/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Osm
2
- VERSION = "1.2.7"
2
+ VERSION = "1.2.8"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: osm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.7
4
+ version: 1.2.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-15 00:00:00.000000000 Z
12
+ date: 2014-03-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -267,6 +267,7 @@ files:
267
267
  - lib/osm/sms.rb
268
268
  - lib/osm/term.rb
269
269
  - osm.gemspec
270
+ - spec/array_of_validator_spec.rb
270
271
  - spec/osm/activity_spec.rb
271
272
  - spec/osm/api_access_spec.rb
272
273
  - spec/osm/api_spec.rb