osm 0.5.0 → 0.6.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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## Version 0.6.0
2
+
3
+ * Badge::Data
4
+ * completed attribute is now a Fixnum not Boolean (fixes staged badges)
5
+ * Add awarded attribute (the last level awarded)
6
+ * Add due? method to tell if the badge is due
7
+ * Add started? method to tell if the badge has been started
8
+ * Add started method to tell which stage has been started
9
+ * Add first\_name and last\_name attributes
10
+ * Add mark\_awarded method
11
+ * Add mark\_due method
12
+ * Badge
13
+ * Make get\_badge\_data\_for\_section an instance not class method (called get\_data\_for\_section)
14
+ * Add get\_summary\_for\_section(api, section, term=nil, options={}) method
15
+ * Add optional section\_type parameter to get\_badges\_for\_section method
16
+
1
17
  ## Version 0.5.0
2
18
 
3
19
  * Code breaking changes to DueBadges:
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  ##Build State
6
6
  This project uses continuous integration to help ensure that a quality product is delivered.
7
7
  Travis CI monitors two branches (versions) of the code - Master (which is what gets released)
8
- and Staging (which is what is currently being debugged ready for moving to master).
8
+ and Staging (which is what is currently being developed ready for moving to master).
9
9
 
10
10
  Master [![Build Status](https://secure.travis-ci.org/robertgauld/osm.png?branch=master)](http://travis-ci.org/robertgauld/osm)
11
11
 
@@ -32,7 +32,7 @@ Use the [Online Scout Manager](https://www.onlinescoutmanager.co.uk) API.
32
32
  Add to your Gemfile and run the `bundle` command to install it.
33
33
 
34
34
  ```ruby
35
- gem 'osm', '~> 0.5.0'
35
+ gem 'osm', '~> 0.6.0'
36
36
  ```
37
37
 
38
38
  Configure the gem during the initalization of the app (e.g. if using rails then config/initializers/osm.rb would look like):
data/lib/osm/badge.rb CHANGED
@@ -7,7 +7,7 @@ module Osm
7
7
  # @return [String] the name of the badge
8
8
  # @!attribute [rw] requirement_notes
9
9
  # @return [String] a description of the badge
10
- # @!attribute [rw] key
10
+ # @!attribute [rw] osm_key
11
11
  # @return [String] the key for the badge in OSM
12
12
  # @!attribute [rw] sections_needed
13
13
  # @return [Fixnum]
@@ -45,13 +45,15 @@ module Osm
45
45
  # Get badges
46
46
  # @param [Osm::Api] api The api to use to make the request
47
47
  # @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the due badges for
48
+ # @param [Symbol] section_type The type of section to get badges for (if nil uses the type of the section param)
48
49
  # @!macro options_get
49
50
  # @return [Array<Osm::Badge>]
50
- def self.get_badges_for_section(api, section, options={})
51
- raise Error, 'This method must be called on one of the subclasses (CoreBadge, ChallengeBadge, StagedBadge or ActivityBadge)' if badge_type.nil?
51
+ def self.get_badges_for_section(api, section, section_type=nil, options={})
52
+ raise Error, 'This method must be called on one of the subclasses (CoreBadge, ChallengeBadge, StagedBadge or ActivityBadge)' if type.nil?
52
53
  require_ability_to(api, :read, :badge, section, options)
53
54
  section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
54
- cache_key = ['badges', section.type, badge_type]
55
+ section_type ||= section.type
56
+ cache_key = ['badges', section_type, type]
55
57
 
56
58
  if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
57
59
  return cache_read(api, cache_key)
@@ -60,7 +62,7 @@ module Osm
60
62
  term_id = Osm::Term.get_current_term_for_section(api, section, options).to_i
61
63
  badges = []
62
64
 
63
- data = api.perform_query("challenges.php?action=getInitialBadges&type=#{badge_type}&sectionid=#{section.id}&section=#{section.type}&termid=#{term_id}")
65
+ data = api.perform_query("challenges.php?action=getInitialBadges&type=#{type}&sectionid=#{section.id}&section=#{section_type}&termid=#{term_id}")
64
66
  badge_order = data["badgeOrder"].to_s.split(',')
65
67
  structures = data["structure"] || {}
66
68
  details = data["details"] || {}
@@ -97,34 +99,70 @@ module Osm
97
99
  return badges
98
100
  end
99
101
 
102
+ # Get a summary of badges earnt by members
103
+ # @param [Osm::Api] api The api to use to make the request
104
+ # @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the due badges for
105
+ # @param [Osm::Term, Fixnum, #to_i, nil] term The term (or its ID) to get the due badges for, passing nil causes the current term to be used
106
+ # @!macro options_get
107
+ # @return [Array<Hash>]
108
+ def self.get_summary_for_section(api, section, term=nil, options={})
109
+ raise Error, 'This method must be called on one of the subclasses (CoreBadge, ChallengeBadge, StagedBadge or ActivityBadge)' if type.nil?
110
+ require_ability_to(api, :read, :badge, section, options)
111
+ section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
112
+ term_id = (term.nil? ? Osm::Term.get_current_term_for_section(api, section, options) : term).to_i
113
+ cache_key = ['badge-summary', section.id, term_id, type]
114
+
115
+ if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
116
+ return cache_read(api, cache_key)
117
+ end
118
+
119
+ summary = []
120
+ data = api.perform_query("challenges.php?action=summary&section=#{section.type}&sectionid=#{section.id}&termid=#{term_id}&type=#{type}")
121
+ data['items'].each do |item|
122
+ new_item = {
123
+ :first_name => item['firstname'],
124
+ :last_name => item['lastname'],
125
+ }
126
+ (item.keys - ['firstname', 'lastname']).each do |key|
127
+ new_item[key] = item[key]
128
+ end
129
+ summary.push new_item
130
+ end
131
+
132
+ cache_write(api, cache_key, summary)
133
+ return summary
134
+ end
135
+
100
136
  # Get a list of badge requirements met by members
101
137
  # @param [Osm::Api] api The api to use to make the request
102
138
  # @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the due badges for
103
- # @param [Osm::Badge] badge The badge to get data for
104
139
  # @param [Osm::Term, Fixnum, #to_i, nil] term The term (or its ID) to get the due badges for, passing nil causes the current term to be used
105
140
  # @!macro options_get
106
141
  # @return [Array<Osm::Badge::Data>]
107
- def self.get_badge_data_for_section(api, section, badge, term=nil, options={})
108
- raise Error, 'This method must be called on one of the subclasses (CoreBadge, ChallengeBadge, StagedBadge or ActivityBadge)' if badge_type.nil?
142
+ def get_data_for_section(api, section, term=nil, options={})
143
+ raise Error, 'This method must be called on one of the subclasses (CoreBadge, ChallengeBadge, StagedBadge or ActivityBadge)' if type.nil?
109
144
  Osm::Model.require_ability_to(api, :read, :badge, section, options)
110
145
  section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
111
146
  term_id = (term.nil? ? Osm::Term.get_current_term_for_section(api, section, options) : term).to_i
112
- cache_key = ['badge_data', section.id, term_id, badge.osm_key]
147
+ cache_key = ['badge_data', section.id, term_id, osm_key]
113
148
 
114
149
  if !options[:no_cache] && cache_exist?(api, cache_key)
115
150
  return cache_read(api, cache_key)
116
151
  end
117
152
 
118
153
  datas = []
119
- data = api.perform_query("challenges.php?termid=#{term_id}&type=#{badge_type}&section=#{section.type}&c=#{badge.osm_key}&sectionid=#{section.id}")
154
+ data = api.perform_query("challenges.php?termid=#{term_id}&type=#{type}&section=#{section.type}&c=#{osm_key}&sectionid=#{section.id}")
120
155
  data['items'].each do |d|
121
156
  datas.push Osm::Badge::Data.new(
122
157
  :member_id => d['scoutid'],
123
- :completed => d['completed'].eql?('1'),
158
+ :first_name => d['firstname'],
159
+ :last_name => d['lastname'],
160
+ :completed => d['completed'].to_i,
161
+ :awarded => d['awarded'].to_i,
124
162
  :awarded_date => Osm.parse_date(d['awardeddate']),
125
163
  :requirements => d.select{ |k,v| k.include?('_') },
126
164
  :section_id => section.id,
127
- :badge => badge,
165
+ :badge => self,
128
166
  )
129
167
  end
130
168
 
@@ -140,13 +178,20 @@ module Osm
140
178
  end
141
179
 
142
180
 
143
- private
144
- def self.badge_type
181
+ def self.type
145
182
  nil
146
183
  end
184
+ def type
185
+ self.class.type
186
+ end
187
+
188
+ private
147
189
  def self.subscription_required
148
190
  :bronze
149
191
  end
192
+ def subscription_required
193
+ self.class.subscription_required
194
+ end
150
195
 
151
196
 
152
197
  class Requirement
@@ -196,14 +241,17 @@ module Osm
196
241
  end # Class Requirement
197
242
 
198
243
 
199
- class Data
200
- include ::ActiveAttr::MassAssignmentSecurity
201
- include ::ActiveAttr::Model
202
-
244
+ class Data < Osm::Model
203
245
  # @!attribute [rw] member_id
204
246
  # @return [Fixnum] ID of the member this data relates to
247
+ # @!attribute [rw] first_name
248
+ # @return [Fixnum] the member's first name
249
+ # @!attribute [rw] last_name
250
+ # @return [Fixnum] Ithe member's last name
205
251
  # @!attribute [rw] completed
206
- # @return [Boolean] whether this badge has been completed (i.e. it is due?)
252
+ # @return [Fixnum] whether this badge has been completed (i.e. it is due?), number indicates stage if appropriate
253
+ # @!attribute [rw] awarded
254
+ # @return [Date] the last stage awarded
207
255
  # @!attribute [rw] awarded_date
208
256
  # @return [Date] when the badge was awarded
209
257
  # @!attribute [rw] requirements
@@ -214,16 +262,22 @@ module Osm
214
262
  # @return [Osm::Badge] the badge that the data belongs to
215
263
 
216
264
  attribute :member_id, :type => Integer
217
- attribute :completed, :type => Boolean
218
- attribute :awarded_date, :type => Date
265
+ attribute :first_name, :type => String
266
+ attribute :last_name, :type => String
267
+ attribute :completed, :type => Integer, :default => 0
268
+ attribute :awarded, :type => Integer, :default => 0
269
+ attribute :awarded_date, :type => Date, :default => nil
219
270
  attribute :requirements, :type => Object, :default => DirtyHashy.new
220
271
  attribute :section_id, :type => Integer
221
272
  attribute :badge, :type => Object
222
273
 
223
- attr_accessible :member_id, :completed, :awarded_date, :requirements, :section_id, :badge
274
+ attr_accessible :member_id, :first_name, :last_name, :completed, :awarded, :awarded_date, :requirements, :section_id, :badge
224
275
 
225
276
  validates_presence_of :badge
226
- validates_inclusion_of :completed, :in => [true, false]
277
+ validates_presence_of :first_name
278
+ validates_presence_of :last_name
279
+ validates_numericality_of :completed, :only_integer=>true, :greater_than_or_equal_to=>0
280
+ validates_numericality_of :awarded, :only_integer=>true, :greater_than_or_equal_to=>0
227
281
  validates_numericality_of :member_id, :only_integer=>true, :greater_than=>0
228
282
  validates_numericality_of :section_id, :only_integer=>true, :greater_than=>0
229
283
  validates :requirements, :hash => {:key_type => String, :value_type => String}
@@ -246,7 +300,7 @@ module Osm
246
300
  def total_gained
247
301
  count = 0
248
302
  requirements.each do |field, data|
249
- next if data.blank? || data.downcase[0].eql?('x')
303
+ next if data.blank? || data[0].downcase.eql?('x')
250
304
  count += 1
251
305
  end
252
306
  return count
@@ -273,12 +327,110 @@ module Osm
273
327
  requirements.each do |field, data|
274
328
  field = field.split('_')[0]
275
329
  count[field] ||= 0
276
- next if data.blank? || data.downcase[0].eql?('x')
330
+ next if data.blank? || data[0].downcase.eql?('x')
277
331
  count[field] += 1
278
332
  end
279
333
  return count
280
334
  end
281
335
 
336
+ # Check if this badge is due
337
+ # @return [Boolean] whether the badge is due to the member
338
+ def due?
339
+ completed > awarded
340
+ end
341
+
342
+ # Check if this badge has been started
343
+ # @return [Boolean] whether the badge has been started by the member (always false if the badge has been completed)
344
+ def started?
345
+ unless badge.type == :staged
346
+ return false if completed?
347
+ requirements.each do |key, value|
348
+ return true unless value.blank? || value[0].downcase.eql?('x')
349
+ end
350
+ else
351
+ # Staged badge
352
+ return (started > completed)
353
+ end
354
+ return false
355
+ end
356
+
357
+ # Get which stage has been started
358
+ # @return [Fixnum] which stage of the badge has been started by the member (lowest)
359
+ def started
360
+ unless badge.type == :staged
361
+ return started? ? 1 : 0
362
+ else
363
+ # Staged badge
364
+ if ['nightsaway', 'hikes'].include?(badge.osm_key) # Special staged badges
365
+ stages = [1, 5, 10, 20, 35, 50, 75, 100, 125, 150, 175, 200] if badge.osm_key.eql?('nightsaway')
366
+ stages = [1, 5, 10, 20, 35, 50] if badge.osm_key.eql?('hikes')
367
+ done = requirements['y_01'].to_i
368
+ return 0 if done < stages[0] # Not started the first stage
369
+ return 0 if done >= stages[stages.size - 1] # No more stages can be started
370
+ (1..stages.size-1).reverse_each do |index|
371
+ if (done < stages[index]) && (done > stages[index-1])
372
+ return stages[index]
373
+ end
374
+ end
375
+ else
376
+ start_group = 'abcde'[completed] # Requirements use the group letter to denote stage
377
+ started = 'z'
378
+ requirements.each do |key, value|
379
+ next if key[0] < start_group # This stage is marked as completed
380
+ next if key[0] > started # This stage is after the stage currently started
381
+ started = key[0] unless value.blank? || value[0].downcase.eql?('x')
382
+ end
383
+ return started.eql?('z') ? 0 : 'abcde'.index(started)+1
384
+ end
385
+ return 0
386
+ end
387
+ end
388
+
389
+ # Mark the badge as awarded in OSM
390
+ # @param [Osm::Api] api The api to use to make the request
391
+ # @param [Date] date The date to mark the badge as awarded
392
+ # @param [Fixnum] level The level of the badge to award (1 for non-staged badges)
393
+ # @param [Symbol] mark_as :awarded or :due
394
+ # @return [Boolean] whether the data was updated in OSM
395
+ def mark_awarded(api, date=Date.today, level=completed, mark_as=:awarded)
396
+ raise ArgumentError, 'date is not a Date' unless date.is_a?(Date)
397
+ raise ArgumentError, 'mark_as is not an allowed value, use :awarded or :du' unless [:awarded, :due].include?(mark_as)
398
+ raise ArgumentError, 'level can not be negative' if level < 0
399
+ section = Osm::Section.get(api, section_id)
400
+ require_ability_to(api, :write, :badge, section)
401
+
402
+ date_formatted = date.strftime(Osm::OSM_DATE_FORMAT)
403
+
404
+ result = api.perform_query("challenges.php?action=award", {
405
+ 'dateAwarded' => date_formatted,
406
+ 'sectionid' => section_id,
407
+ 'section' => section.type,
408
+ 'chal' => badge.osm_key,
409
+ 'type' => badge.type,
410
+ 'stagedLevel' => level,
411
+ 'due' => mark_as,
412
+ })
413
+ updated = result.is_a?(Array) &&
414
+ result[0].is_a?(Hash) &&
415
+ (result[0]['sid'].to_i == member_id) &&
416
+ (result[0]['awarded'].to_i == level) &&
417
+ (result[0]['awardeddate'] == date_formatted)
418
+
419
+ if updated
420
+ awarded = level
421
+ awarded_date = date
422
+ end
423
+ return updated
424
+ end
425
+
426
+ # Mark the badge as due in OSM
427
+ # @param [Osm::Api] api The api to use to make the request
428
+ # @param [Fixnum] level The level of the badge to mark as due (1 for non-staged badges)
429
+ # @return [Boolean] whether the data was updated in OSM
430
+ def mark_due(api, level)
431
+ mark_awarded(api, Date.today, level, :due)
432
+ end
433
+
282
434
  # Update data in OSM
283
435
  # @param [Osm::Api] api The api to use to make the request
284
436
  # @return [Boolean] whether the data was updated in OSM
@@ -286,13 +438,13 @@ module Osm
286
438
  def update(api)
287
439
  raise Osm::ObjectIsInvalid, 'data is invalid' unless valid?
288
440
  section = Osm::Section.get(api, section_id)
289
- Osm::Model.require_ability_to(api, :write, :badge, section)
441
+ require_ability_to(api, :write, :badge, section)
290
442
 
291
443
  updated = true
292
444
  editable_fields = badge.requirements.select{ |r| r.editable }.map{ |r| r.field}
293
445
  requirements.changes.each do |field, (was,now)|
294
446
  if editable_fields.include?(field)
295
- result = api.perform_query("challenges.php?type=#{badge.class.badge_type}&section=#{section.type}", {
447
+ result = api.perform_query("challenges.php?type=#{badge.class.type}&section=#{section.type}", {
296
448
  'action' => 'updatesingle',
297
449
  'id' => member_id,
298
450
  'col' => field,
@@ -306,11 +458,18 @@ module Osm
306
458
  end
307
459
  end
308
460
 
309
-
310
461
  if updated
311
462
  requirements.clean_up!
312
463
  end
313
464
 
465
+ if changed_attributes.include?('awarded') || changed_attributes.include?('awarded_date')
466
+ if mark_awarded(api, awarded_date, awarded)
467
+ reset_changed_attributes
468
+ else
469
+ updated = false
470
+ end
471
+ end
472
+
314
473
  return updated
315
474
  end
316
475
 
@@ -333,28 +492,28 @@ module Osm
333
492
 
334
493
  class CoreBadge < Osm::Badge
335
494
  private
336
- def self.badge_type
495
+ def self.type
337
496
  :core
338
497
  end
339
498
  end # Class CoreBadge
340
499
 
341
500
  class ChallengeBadge < Osm::Badge
342
501
  private
343
- def self.badge_type
502
+ def self.type
344
503
  :challenge
345
504
  end
346
505
  end # Class ChallengeBadge
347
506
 
348
507
  class StagedBadge < Osm::Badge
349
508
  private
350
- def self.badge_type
509
+ def self.type
351
510
  :staged
352
511
  end
353
512
  end # Class StagedBadge
354
513
 
355
514
  class ActivityBadge < Osm::Badge
356
515
  private
357
- def self.badge_type
516
+ def self.type
358
517
  :activity
359
518
  end
360
519
  def self.subscription_required
data/lib/osm/register.rb CHANGED
@@ -56,7 +56,9 @@ module Osm
56
56
  end
57
57
 
58
58
  data = api.perform_query("users.php?action=register&sectionid=#{section_id}&termid=#{term_id}")
59
- dates = get_structure(api, section, term, options).map{ |f| f.id }.select{ |f| f.match(Osm::OSM_DATE_REGEX) }
59
+ dates_s = get_structure(api, section, term, options)
60
+ dates_s = dates_s.map{ |f| f.id }.select{ |f| f.match(Osm::OSM_DATE_REGEX) }
61
+ dates_d = dates_s.map{ |d| Osm::parse_date(d) }
60
62
 
61
63
  to_return = []
62
64
  if data.is_a?(Hash) && data['items'].is_a?(Array)
@@ -65,9 +67,8 @@ module Osm
65
67
  if item.is_a?(Hash)
66
68
  unless item['scoutid'].to_i < 0 # It's a total row
67
69
  attendance = {}
68
- dates.each do |date|
69
- item_attendance = item[date]
70
- date = Date.strptime(date, Osm::OSM_DATE_FORMAT)
70
+ dates_d.each_with_index do |date, index|
71
+ item_attendance = item[dates_s[index]]
71
72
  attendance[date] = :unadvised_absent
72
73
  attendance[date] = :yes if item_attendance.eql?('Yes')
73
74
  attendance[date] = :advised_absent if item_attendance.eql?('No')
@@ -44,7 +44,10 @@ describe "Badge" do
44
44
  it "Create Data" do
45
45
  data = Osm::Badge::Data.new(
46
46
  :member_id => 1,
47
- :completed => true,
47
+ :first_name => 'First',
48
+ :last_name => 'Last',
49
+ :completed => 4,
50
+ :awarded => 3,
48
51
  :awarded_date => Date.new(2000, 1, 2),
49
52
  :requirements => {},
50
53
  :section_id => 2,
@@ -52,7 +55,10 @@ describe "Badge" do
52
55
  )
53
56
 
54
57
  data.member_id.should == 1
55
- data.completed.should == true
58
+ data.first_name.should == 'First'
59
+ data.last_name.should == 'Last'
60
+ data.completed.should == 4
61
+ data.awarded.should == 3
56
62
  data.awarded_date.should == Date.new(2000, 1, 2)
57
63
  data.requirements.should == {}
58
64
  data.section_id.should == 2
@@ -128,6 +134,64 @@ describe "Badge" do
128
134
  data.sections_gained.should == 1
129
135
  end
130
136
 
137
+ it "Works out if the badge is due" do
138
+ Osm::Badge::Data.new(:completed => 0, :awarded => 0).due?.should be_false
139
+ Osm::Badge::Data.new(:completed => 1, :awarded => 0).due?.should be_true
140
+ Osm::Badge::Data.new(:completed => 2, :awarded => 2).due?.should be_false
141
+ Osm::Badge::Data.new(:completed => 2, :awarded => 1).due?.should be_true
142
+ end
143
+
144
+ it "Works out if the badge has been started" do
145
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => 'Yes', 'a_02' => ''}).started?.should be_true
146
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => 'Yes', 'a_02' => ''}, :completed => 1).started?.should be_false
147
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => 'xNo', 'a_02' => ''}).started?.should be_false
148
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => '', 'a_02' => ''}).started?.should be_false
149
+ # Staged Badge
150
+ Osm::Badge::Data.new(
151
+ :badge => Osm::StagedBadge.new,
152
+ :requirements => {'a_01' => 'Yes', 'b_01' => 'Yes', 'b_02' => ''},
153
+ :completed => 1,
154
+ ).started?.should be_true
155
+ Osm::Badge::Data.new(
156
+ :badge => Osm::StagedBadge.new(:osm_key => 'nightsaway'),
157
+ :requirements => {'a_01' => 5, 'y_01' => '5', 'custom_26695' => ''},
158
+ :completed => 5,
159
+ ).started?.should be_false
160
+ Osm::Badge::Data.new(
161
+ :badge => Osm::StagedBadge.new(:osm_key => 'hikes'),
162
+ :requirements => {'a_01' => 2, 'y_01' => '2', 'custom_26695' => ''},
163
+ :completed => 1,
164
+ ).started?.should be_true
165
+ end
166
+
167
+ it "Works out what stage of the badge has been started" do
168
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => 'Yes', 'a_02' => ''}).started.should == 1
169
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => 'Yes', 'a_02' => ''}, :completed => 1).started.should == 0
170
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => 'xNo', 'a_02' => ''}).started.should == 0
171
+ Osm::Badge::Data.new(:badge => Osm::CoreBadge.new, :requirements => {'a_01' => '', 'a_02' => ''}).started.should == 0
172
+
173
+ # Staged Badge
174
+ Osm::Badge::Data.new(
175
+ :badge => Osm::StagedBadge.new(:osm_key => 'test'),
176
+ :requirements => {'a_01' => 'Yes', 'b_01' => 'Yes', 'b_02' => ''},
177
+ :completed => 1,
178
+ ).started.should == 2
179
+ Osm::Badge::Data.new(
180
+ :badge => Osm::StagedBadge.new(:osm_key => 'test'),
181
+ :requirements => {'a_01' => 'Yes', 'b_01' => 'Yes', 'b_02' => '', 'c_01' => 'Yes', 'c_02' => ''},
182
+ :completed => 1,
183
+ ).started.should == 2
184
+ Osm::Badge::Data.new(
185
+ :badge => Osm::StagedBadge.new(:osm_key => 'nightsaway'),
186
+ :requirements => {'a_01' => 7, 'y_01' => '7', 'custom_26695' => ''},
187
+ :completed => 5,
188
+ ).started.should == 10
189
+ Osm::Badge::Data.new(
190
+ :badge => Osm::StagedBadge.new(:osm_key => 'hikes'),
191
+ :requirements => {'a_01' => 2, 'y_01' => '2', 'custom_26695' => ''},
192
+ :completed => 1,
193
+ ).started.should == 5
194
+ end
131
195
 
132
196
  describe "Using the OSM API" do
133
197
 
@@ -261,6 +325,14 @@ describe "Badge" do
261
325
  requirement.badge.osm_key.should == 'badge'
262
326
  end
263
327
 
328
+ it "For a different section type" do
329
+ FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=getInitialBadges&type=activity&sectionid=1&section=cubs&termid=2", :body => @data)
330
+ Osm::Term.stub(:get_current_term_for_section){ Osm::Term.new(:id => 2) }
331
+
332
+ badges = Osm::ActivityBadge.get_badges_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), :cubs)
333
+ badges.size.should == 1
334
+ end
335
+
264
336
  end
265
337
 
266
338
 
@@ -274,8 +346,8 @@ describe "Badge" do
274
346
  'firstname' => 'fn',
275
347
  'lastname' => 'ln',
276
348
  'sid' => '',
277
- 'completed' => '1',
278
- 'awarded' => '',
349
+ 'completed' => '2',
350
+ 'awarded' => '1',
279
351
  'awardeddate' => '2000-01-02',
280
352
  'patrolid' => 4,
281
353
  'a_1' => 'd',
@@ -286,11 +358,14 @@ describe "Badge" do
286
358
 
287
359
  it "Core badge" do
288
360
  FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?termid=2&type=core&section=beavers&c=badge&sectionid=1", :body => @data)
289
- datas = Osm::CoreBadge.get_badge_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), Osm::Badge.new(:osm_key => 'badge'), 2)
361
+ datas = Osm::CoreBadge.new(:osm_key => 'badge').get_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
290
362
  datas.size.should == 1
291
363
  data = datas[0]
292
364
  data.member_id.should == 3
293
- data.completed.should == true
365
+ data.first_name.should == 'fn'
366
+ data.last_name.should == 'ln'
367
+ data.completed.should == 2
368
+ data.awarded.should == 1
294
369
  data.awarded_date.should == Date.new(2000, 1, 2)
295
370
  data.requirements.should == {'a_1' => 'd'}
296
371
  data.section_id.should == 1
@@ -299,11 +374,14 @@ describe "Badge" do
299
374
 
300
375
  it "Challenge badge" do
301
376
  FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?termid=2&type=challenge&section=beavers&c=badge&sectionid=1", :body => @data)
302
- datas = Osm::ChallengeBadge.get_badge_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), Osm::Badge.new(:osm_key => 'badge'), 2)
377
+ datas = Osm::ChallengeBadge.new(:osm_key => 'badge').get_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
303
378
  datas.size.should == 1
304
379
  data = datas[0]
305
380
  data.member_id.should == 3
306
- data.completed.should == true
381
+ data.first_name.should == 'fn'
382
+ data.last_name.should == 'ln'
383
+ data.completed.should == 2
384
+ data.awarded.should == 1
307
385
  data.awarded_date.should == Date.new(2000, 1, 2)
308
386
  data.requirements.should == {'a_1' => 'd'}
309
387
  data.section_id.should == 1
@@ -312,11 +390,14 @@ describe "Badge" do
312
390
 
313
391
  it "Staged badge" do
314
392
  FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?termid=2&type=staged&section=beavers&c=badge&sectionid=1", :body => @data)
315
- datas = Osm::StagedBadge.get_badge_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), Osm::Badge.new(:osm_key => 'badge'), 2)
393
+ datas = Osm::StagedBadge.new(:osm_key => 'badge').get_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
316
394
  datas.size.should == 1
317
395
  data = datas[0]
318
396
  data.member_id.should == 3
319
- data.completed.should == true
397
+ data.first_name.should == 'fn'
398
+ data.last_name.should == 'ln'
399
+ data.completed.should == 2
400
+ data.awarded.should == 1
320
401
  data.awarded_date.should == Date.new(2000, 1, 2)
321
402
  data.requirements.should == {'a_1' => 'd'}
322
403
  data.section_id.should == 1
@@ -325,11 +406,14 @@ describe "Badge" do
325
406
 
326
407
  it "Activity badge" do
327
408
  FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?termid=2&type=activity&section=beavers&c=badge&sectionid=1", :body => @data)
328
- datas = Osm::ActivityBadge.get_badge_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), Osm::Badge.new(:osm_key => 'badge'), 2)
409
+ datas = Osm::ActivityBadge.new(:osm_key => 'badge').get_data_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
329
410
  datas.size.should == 1
330
411
  data = datas[0]
331
412
  data.member_id.should == 3
332
- data.completed.should == true
413
+ data.first_name.should == 'fn'
414
+ data.last_name.should == 'ln'
415
+ data.completed.should == 2
416
+ data.awarded.should == 1
333
417
  data.awarded_date.should == Date.new(2000, 1, 2)
334
418
  data.requirements.should == {'a_1' => 'd'}
335
419
  data.section_id.should == 1
@@ -341,7 +425,7 @@ describe "Badge" do
341
425
  describe "Update badge data for a section/member" do
342
426
 
343
427
  before :each do
344
- @post_data = {
428
+ @update_post_data = {
345
429
  'apiid' => @CONFIGURATION[:api][:osm][:id],
346
430
  'token' => @CONFIGURATION[:api][:osm][:token],
347
431
  'userid' => 'user_id',
@@ -353,13 +437,29 @@ describe "Badge" do
353
437
  'chal' => 'badge',
354
438
  'sectionid' => 2,
355
439
  }
440
+ @update_body_data = {'sid' => '1', 'a' => '2', 'b' => '2'}
356
441
 
357
- @body_data = {'sid' => '1', 'a' => '2', 'b' => '2'}
442
+ @awarded_post_data = {
443
+ 'apiid' => @CONFIGURATION[:api][:osm][:id],
444
+ 'token' => @CONFIGURATION[:api][:osm][:token],
445
+ 'userid' => 'user_id',
446
+ 'secret' => 'secret',
447
+ 'dateAwarded' => '2000-01-02',
448
+ 'sectionid' => 2,
449
+ 'section' => :beavers,
450
+ 'chal' => 'badge',
451
+ 'stagedLevel' => 1,
452
+ 'due' => :awarded,
453
+ }
454
+ @awarded_body_data = [{'sid'=>'1', 'awarded'=>'1', 'awardeddate'=>'2000-01-02'}]
455
+ @awarded_url = "https://www.onlinescoutmanager.co.uk/challenges.php?action=award"
358
456
  end
359
457
 
360
458
  it "Core badge" do
361
459
  data = Osm::Badge::Data.new(
362
460
  :member_id => 1,
461
+ :first_name => 'fn',
462
+ :last_name => 'ln',
363
463
  :section_id => 2,
364
464
  :requirements => {'a' => '1', 'b' => '2'},
365
465
  :badge => Osm::CoreBadge.new(
@@ -368,20 +468,25 @@ describe "Badge" do
368
468
  Osm::Badge::Requirement.new(:field => 'a', :editable => true),
369
469
  Osm::Badge::Requirement.new(:field => 'b', :editable => true),
370
470
  ]),
371
- :completed => false,
471
+ :completed => 0,
372
472
  )
373
473
 
374
- url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=core&section=beavers"
375
- HTTParty.should_receive(:post).with(url, {:body => @post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@body_data.to_json}) }
474
+ update_url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=core&section=beavers"
475
+ HTTParty.should_receive(:post).with(update_url, {:body => @update_post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@update_body_data.to_json}) }
476
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :core})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
376
477
  Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
377
478
 
378
479
  data.requirements['a'] = '2'
480
+ data.awarded = 1
481
+ data.awarded_date = Date.new(2000, 1, 2)
379
482
  data.update(@api).should be_true
380
483
  end
381
484
 
382
485
  it "Challenge badge" do
383
486
  data = Osm::Badge::Data.new(
384
487
  :member_id => 1,
488
+ :first_name => 'fn',
489
+ :last_name => 'ln',
385
490
  :section_id => 2,
386
491
  :requirements => {'a' => '1', 'b' => '2'},
387
492
  :badge => Osm::ChallengeBadge.new(
@@ -390,20 +495,25 @@ describe "Badge" do
390
495
  Osm::Badge::Requirement.new(:field => 'a', :editable => true),
391
496
  Osm::Badge::Requirement.new(:field => 'b', :editable => true),
392
497
  ]),
393
- :completed => false,
498
+ :completed => 0,
394
499
  )
395
500
 
396
- url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=challenge&section=beavers"
397
- HTTParty.should_receive(:post).with(url, {:body => @post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@body_data.to_json}) }
501
+ update_url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=challenge&section=beavers"
502
+ HTTParty.should_receive(:post).with(update_url, {:body => @update_post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@update_body_data.to_json}) }
503
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :challenge})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
398
504
  Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
399
505
 
400
506
  data.requirements['a'] = '2'
507
+ data.awarded = 1
508
+ data.awarded_date = Date.new(2000, 1, 2)
401
509
  data.update(@api).should be_true
402
510
  end
403
511
 
404
512
  it "Staged badge" do
405
513
  data = Osm::Badge::Data.new(
406
514
  :member_id => 1,
515
+ :first_name => 'fn',
516
+ :last_name => 'ln',
407
517
  :section_id => 2,
408
518
  :requirements => {'a' => '1', 'b' => '2'},
409
519
  :badge => Osm::StagedBadge.new(
@@ -412,20 +522,25 @@ describe "Badge" do
412
522
  Osm::Badge::Requirement.new(:field => 'a', :editable => true),
413
523
  Osm::Badge::Requirement.new(:field => 'b', :editable => true),
414
524
  ]),
415
- :completed => false,
525
+ :completed => 0,
416
526
  )
417
527
 
418
- url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=staged&section=beavers"
419
- HTTParty.should_receive(:post).with(url, {:body => @post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@body_data.to_json}) }
528
+ update_url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=staged&section=beavers"
529
+ HTTParty.should_receive(:post).with(update_url, {:body => @update_post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@update_body_data.to_json}) }
530
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :staged})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
420
531
  Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
421
532
 
422
533
  data.requirements['a'] = '2'
534
+ data.awarded = 1
535
+ data.awarded_date = Date.new(2000, 1, 2)
423
536
  data.update(@api).should be_true
424
537
  end
425
538
 
426
539
  it "Activity badge" do
427
540
  data = Osm::Badge::Data.new(
428
541
  :member_id => 1,
542
+ :first_name => 'fn',
543
+ :last_name => 'ln',
429
544
  :section_id => 2,
430
545
  :requirements => {'a' => '1', 'b' => '2'},
431
546
  :badge => Osm::ActivityBadge.new(
@@ -434,19 +549,171 @@ describe "Badge" do
434
549
  Osm::Badge::Requirement.new(:field => 'a', :editable => true),
435
550
  Osm::Badge::Requirement.new(:field => 'b', :editable => true),
436
551
  ]),
437
- :completed => false,
552
+ :completed => 0,
438
553
  )
439
554
 
440
- url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=activity&section=beavers"
441
- HTTParty.should_receive(:post).with(url, {:body => @post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@body_data.to_json}) }
555
+ update_url = "https://www.onlinescoutmanager.co.uk/challenges.php?type=activity&section=beavers"
556
+ HTTParty.should_receive(:post).with(update_url, {:body => @update_post_data}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@update_body_data.to_json}) }
557
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :activity})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
442
558
  Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
443
559
 
444
560
  data.requirements['a'] = '2'
561
+ data.awarded = 1
562
+ data.awarded_date = Date.new(2000, 1, 2)
445
563
  data.update(@api).should be_true
446
564
  end
447
565
 
448
566
  end
449
567
 
568
+
569
+ describe "Mark badge awarded" do
570
+
571
+ before :each do
572
+ @awarded_post_data = {
573
+ 'apiid' => @CONFIGURATION[:api][:osm][:id],
574
+ 'token' => @CONFIGURATION[:api][:osm][:token],
575
+ 'userid' => 'user_id',
576
+ 'secret' => 'secret',
577
+ 'dateAwarded' => '2000-01-02',
578
+ 'sectionid' => 2,
579
+ 'section' => :beavers,
580
+ 'chal' => 'badge',
581
+ 'stagedLevel' => 1,
582
+ 'due' => :awarded,
583
+ }
584
+ @awarded_body_data = [{'sid'=>'1', 'awarded'=>'1', 'awardeddate'=>'2000-01-02'}]
585
+ @awarded_url = "https://www.onlinescoutmanager.co.uk/challenges.php?action=award"
586
+ end
587
+
588
+ it "Core badge" do
589
+ data = Osm::Badge::Data.new(
590
+ :member_id => 1,
591
+ :section_id => 2,
592
+ :badge => Osm::CoreBadge.new(
593
+ :osm_key => 'badge',
594
+ )
595
+ )
596
+
597
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :core})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
598
+ Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
599
+
600
+ data.mark_awarded(@api, Date.new(2000, 1, 2), 1).should be_true
601
+ end
602
+
603
+ it "Challenge badge" do
604
+ data = Osm::Badge::Data.new(
605
+ :member_id => 1,
606
+ :section_id => 2,
607
+ :badge => Osm::ChallengeBadge.new(
608
+ :osm_key => 'badge',
609
+ )
610
+ )
611
+
612
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :challenge})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
613
+ Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
614
+
615
+ data.mark_awarded(@api, Date.new(2000, 1, 2), 1).should be_true
616
+ end
617
+
618
+ it "Staged badge" do
619
+ data = Osm::Badge::Data.new(
620
+ :member_id => 1,
621
+ :section_id => 2,
622
+ :badge => Osm::StagedBadge.new(
623
+ :osm_key => 'badge',
624
+ )
625
+ )
626
+
627
+ @awarded_body_data[0].merge!({'awarded' => '4'})
628
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :staged, 'stagedLevel' => 4})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
629
+ Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
630
+
631
+ data.mark_awarded(@api, Date.new(2000, 1, 2), 4).should be_true
632
+ end
633
+
634
+ it "Activity badge" do
635
+ data = Osm::Badge::Data.new(
636
+ :member_id => 1,
637
+ :section_id => 2,
638
+ :badge => Osm::ActivityBadge.new(
639
+ :osm_key => 'badge',
640
+ )
641
+ )
642
+
643
+ HTTParty.should_receive(:post).with(@awarded_url, {:body => @awarded_post_data.merge({'type' => :activity})}) { OsmTest::DummyHttpResult.new(:response=>{:code=>'200', :body=>@awarded_body_data.to_json}) }
644
+ Osm::Section.stub(:get) { Osm::Section.new(:id => 2, :type => :beavers) }
645
+
646
+ data.mark_awarded(@api, Date.new(2000, 1, 2), 1).should be_true
647
+ end
648
+
649
+ end
650
+
651
+
652
+ describe "Get summary data for a section" do
653
+
654
+ before :each do
655
+ @data = {
656
+ 'items' => [
657
+ {
658
+ 'firstname' => 'First',
659
+ 'lastname' => 'Last',
660
+ 'badge_none' => '',
661
+ 'badge_earnt' => '2000-01-02',
662
+ }
663
+ ]
664
+ }
665
+ @data = @data.to_json
666
+ end
667
+
668
+ it "Core badge" do
669
+ FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=summary&section=beavers&sectionid=1&termid=2&type=core", :body => @data)
670
+ summary = Osm::CoreBadge.get_summary_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
671
+ summary.size.should == 1
672
+ summary[0].should == {
673
+ :first_name => 'First',
674
+ :last_name => 'Last',
675
+ 'badge_none' => '',
676
+ 'badge_earnt' => '2000-01-02',
677
+ }
678
+ end
679
+
680
+ it "Challenge badge" do
681
+ FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=summary&section=beavers&sectionid=1&termid=2&type=challenge", :body => @data)
682
+ summary = Osm::ChallengeBadge.get_summary_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
683
+ summary.size.should == 1
684
+ summary[0].should == {
685
+ :first_name => 'First',
686
+ :last_name => 'Last',
687
+ 'badge_none' => '',
688
+ 'badge_earnt' => '2000-01-02',
689
+ }
690
+ end
691
+
692
+ it "Staged badge" do
693
+ FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=summary&section=beavers&sectionid=1&termid=2&type=staged", :body => @data)
694
+ summary = Osm::StagedBadge.get_summary_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
695
+ summary.size.should == 1
696
+ summary[0].should == {
697
+ :first_name => 'First',
698
+ :last_name => 'Last',
699
+ 'badge_none' => '',
700
+ 'badge_earnt' => '2000-01-02',
701
+ }
702
+ end
703
+
704
+ it "Activity badge" do
705
+ FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/challenges.php?action=summary&section=beavers&sectionid=1&termid=2&type=activity", :body => @data)
706
+ summary = Osm::ActivityBadge.get_summary_for_section(@api, Osm::Section.new(:id => 1, :type => :beavers), 2)
707
+ summary.size.should == 1
708
+ summary[0].should == {
709
+ :first_name => 'First',
710
+ :last_name => 'Last',
711
+ 'badge_none' => '',
712
+ 'badge_earnt' => '2000-01-02',
713
+ }
714
+ end
715
+ end
716
+
450
717
  end
451
718
 
452
719
  end
data/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Osm
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
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: 0.5.0
4
+ version: 0.6.0
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: 2013-03-29 00:00:00.000000000 Z
12
+ date: 2013-04-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport