]> nos-oignons.net Git - gestion-adh.git/commitdiff
Add join date, fix renewal logic and add ability to specify path to wiki-ca
authorLunar <lunar@anargeek.net>
Sun, 2 Jun 2013 11:49:49 +0000 (13:49 +0200)
committerLunar <lunar@anargeek.net>
Sun, 2 Jun 2013 11:50:34 +0000 (13:50 +0200)
12 files changed:
Gemfile.lock
README
features/list-emails.feature
features/pre-commit-hook.feature
features/pre-receive-hook.feature
features/step_definitions/commands.rb
features/step_definitions/members.rb
features/support/env.rb
features/support/fixtures.rb
lib/nos_oignons.rb
lib/nos_oignons/member.rb
nos_oignons.gemspec

index b8a6262db02768187ba67ade912e7182c8e88b25..f41add5c30570e782985355bee1d59280d8dc0e6 100644 (file)
@@ -28,6 +28,7 @@ GEM
     rspec-expectations (2.13.0)
       diff-lcs (>= 1.1.3, < 2.0)
     safe_yaml (0.9.2)
+    timecop (0.6.1)
 
 PLATFORMS
   ruby
@@ -37,3 +38,4 @@ DEPENDENCIES
   cucumber
   json (~> 1.7.7)
   nos_oignons!
+  timecop
diff --git a/README b/README
index c31001e4340bd62e1bec02e010a9fb49c473325c..573ec803058fbe0d834cd30719604e82c2806564 100644 (file)
--- a/README
+++ b/README
@@ -31,6 +31,7 @@ Chaque page doit ressembler à :
       42 rue du Fleuve
       12042 Essaiville
     email: violette@example.org
+    joined_on: 2013-05-25
     membership_fee_paid_on: 2013-05-25
     ---
 
@@ -47,6 +48,8 @@ suivantes :
 =`email`=
     L'adresse email du membre. C'est à cette adresse que seront envoyés les
     messages de l'assemblée générale et les rappels de cotisation.
+=`joined_on`=
+    Date d'adhésion à l'association.
 =`membership_fee_paid_on`=
     Date du paiement de la dernière cotisation.
 
@@ -61,6 +64,12 @@ Voici le détail des scripts utilisés. On peut se faire une idée de leurs
 fonctionalités respectives en lisant les cas d'utilisation dans les fichiers
 `features/*.feature`.
 
+Le chemin vers la racine du clone du wiki du conseil d'amnisitration est
+spécifié par la variable d'environnement `NOS_OIGNONS_BOARD_WIKI_PATH`. Si
+cette dernière n'est pas spécifié, les scripts cherchent un répertoire
+`Membres` à la racine du Git courant, et si ce n'est pas le cas, dans
+le répertoire `wiki-ca` du répertoire parent du Git courant.
+
 `list-email`
 ------------
 
index 161600f8b49fb2f6ab92353ef6fe9c07bf502e83..ebcf76f514dc4c72f87f1d5eb29a0d205c1291e5 100644 (file)
@@ -45,3 +45,34 @@ Fonctionnalité: obtenir les emails des membres à jour de cotisations
       jane@example.org
       fatima@example.org
       """
+
+  Plan du scénario: Renouvellement de la cotisation
+    Soit une base avec Pierre qui a adhéré le <adhésion> et payé sa dernière cotisation le <cotisation>
+    Lorsque j'exécute list-emails le <maintenant>
+    Alors la sortie doit être "<sortie>"
+
+    Exemples:
+      | adhésion   | cotisation | maintenant | sortie             |
+      | 2012-01-01 | 2012-01-01 | 2012-01-01 | pierre@example.org |
+      | 2012-01-01 | 2012-01-01 | 2012-12-31 | pierre@example.org |
+      | 2012-01-01 | 2012-01-01 | 2013-01-01 | pierre@example.org |
+      | 2012-01-01 | 2012-01-01 | 2013-01-02 |                    |
+      | 2012-01-01 | 2012-01-01 | 2013-02-01 |                    |
+      | 2012-06-01 | 2012-06-01 | 2013-01-01 | pierre@example.org |
+      | 2012-06-01 | 2012-06-01 | 2013-06-01 | pierre@example.org |
+      | 2012-06-01 | 2012-06-01 | 2013-06-02 |                    |
+      | 2012-06-01 | 2012-06-01 | 2014-01-01 |                    |
+      | 2012-02-29 | 2012-02-29 | 2013-02-01 | pierre@example.org |
+      | 2012-02-29 | 2012-02-29 | 2013-03-01 | pierre@example.org |
+      | 2012-02-29 | 2012-02-29 | 2013-03-02 |                    |
+      | 2012-02-29 | 2012-02-29 | 2013-12-31 |                    |
+      | 2012-12-15 | 2012-12-15 | 2013-01-01 | pierre@example.org |
+      | 2012-12-15 | 2012-12-15 | 2012-06-01 | pierre@example.org |
+      | 2012-12-15 | 2012-12-15 | 2013-12-15 | pierre@example.org |
+      | 2012-12-15 | 2012-12-15 | 2013-12-16 |                    |
+      | 2012-12-15 | 2012-12-15 | 2013-12-31 |                    |
+      | 2012-12-15 | 2013-12-01 | 2013-12-01 | pierre@example.org |
+      | 2012-12-15 | 2013-12-01 | 2013-12-15 | pierre@example.org |
+      | 2012-12-15 | 2013-12-01 | 2014-01-01 | pierre@example.org |
+      | 2012-12-15 | 2013-12-01 | 2014-12-16 |                    |
+      | 2012-12-15 | 2013-12-01 | 2014-12-31 |                    |
index 8f59ee37464ea918b2b91f06d1c843a90336a870..ba479313983443099526df7b0eb7c948661efef8 100644 (file)
@@ -45,6 +45,16 @@ Fonctionnalité: pre-commit hook Git
     Et que je fais un `commit` du nouveau fichier
     Alors je dois voir comme erreur "pas le bon format"
 
+  Scénario: Commit d'une fiche avec une date d'adhésion incensée
+    Lorsque j'ajoute une fiche avec comme date d'adhésion "2011-99-01"
+    Et que je fais un `commit` du nouveau fichier
+    Alors je dois voir comme erreur "pas le bon format"
+
+  Scénario: Commit d'une fiche avec une mauvaise date d'adhésion
+    Lorsque j'ajoute une fiche avec comme date d'adhésion "janvier 2013"
+    Et que je fais un `commit` du nouveau fichier
+    Alors je dois voir comme erreur "pas le bon format"
+
   Scénario: Commit d'une fiche avec une date de cotisation incensée
     Lorsque j'ajoute une fiche avec comme date de cotisation "2011-99-01"
     Et que je fais un `commit` du nouveau fichier
index aa7f405bb31b556b288abd58ec5ba753d1b5d9bb..d4d3a4053961653794b2864970aab97846b8f8c7 100644 (file)
@@ -45,6 +45,16 @@ Fonctionnalité: pre-receive hook Git
     Et que je pousse la modification
     Alors je dois voir comme erreur "pas le bon format"
 
+  Scénario: Commit d'une fiche avec une date d'adhésion incensée
+    Lorsque j'ajoute une fiche avec comme date d'adhésion "2011-99-01"
+    Et que je pousse la modification
+    Alors je dois voir comme erreur "pas le bon format"
+
+  Scénario: Commit d'une fiche avec une mauvaise date d'adhésion
+    Lorsque j'ajoute une fiche avec comme date d'adhésion "janvier 2013"
+    Et que je pousse la modification
+    Alors je dois voir comme erreur "pas le bon format"
+
   Scénario: Commit d'une fiche avec une date de cotisation incensée
     Lorsque j'ajoute une fiche avec comme date de cotisation "2011-99-01"
     Et que je pousse la modification
index 685aa158906edabe144cb84c55a3295c9a8a78c1..26886e6e2662b6f3c5e5ed5afdab968c0e128682 100644 (file)
@@ -4,6 +4,19 @@ When /^j'exécute list\-emails$/ do
   run_simple 'list-emails'
 end
 
+When /^j'exécute list-emails le (\d+)\-(\d+)\-(\d+)$/ do |year, month, day|$/
+  Timecop.travel(Time.new(year, month, day)) do
+    stdout_io = StringIO.new
+    begin
+      $stdout = stdout_io
+      NosOignons.list_emails!
+      @stdout = stdout_io.string
+    ensure
+      $stdout = STDOUT
+    end
+  end
+end
+
 When /^j'exécute update-ag-subscribers$/ do
   run_simple 'update-ag-subscribers'
 end
@@ -17,10 +30,14 @@ Then /^je dois voir comme erreur "(.*?)"$/ do |expected|
 end
 
 Then /^la sortie doit être vide$/ do
-  assert_exact_output('', all_stdout)
+  assert_exact_output('', @stdout || all_stdout)
 end
 
 Then /^la sortie doit être:$/ do |expected|
   # add an extra line feed for nice scenario
-  assert_exact_output(expected + "\n", all_stdout)
+  assert_exact_output(expected + "\n", @stdout || all_stdout)
+end
+
+Then /^la sortie doit être "([^"]*)"$/ do |expected|
+  assert_exact_output(expected, (@stdout || all_stdout).rstrip)
 end
index 8bb03306dec73ecd86dcc82b313655331dd643e7..5bcc39c1bde36dc0c965cee9f8801df6a8eabb04 100644 (file)
@@ -1,37 +1,47 @@
 #-*- coding: utf-8 -*-
 
-Given /une base de membres vide$/ do
-  create_dir 'Membres'
+def init_db
+  @member_db_path = File.join(current_dir, NosOignons::MEMBERS_DB_DIR)
+  ENV['NOS_OIGNONS_BOARD_WIKI_PATH'] = current_dir
+  create_dir @member_db_path
 end
 
-Given /^(?:une base )?avec (\w+)(, à jour de cotisation| qui n'a pas payé sa cotisation cette année)$/ do |name, uptodate|
-  case uptodate
-  when ', à jour de cotisation'
-    # ± 1 month ago
-    paid_on = (Time.now - 3600*24*30).strftime('%Y-%m-%d')
-  else
-    # ± 15 months ago
-    paid_on = (Time.now - 3600*24*30*15).strftime('%Y-%m-%d')
-  end
+def create_new_member(name, joined_on, paid_on)
   data = { 'name' => name,
            'address' => "At #{name}",
            'email' => "#{name.downcase}@example.org",
+           'joined_on' => joined_on,
            'membership_fee_paid_on' => paid_on
          }
-  create_dir 'Membres'
+  init_db unless @member_db_path
   file = member_filename_for_id(new_id)
   write_file file, render_member_file(data)
 end
 
+Given /une base de membres vide$/ do
+  init_db
+end
+
+Given /^(?:une base )?avec (\w+)(, à jour de cotisation| qui n'a pas payé sa cotisation cette année)$/ do |name, uptodate|
+  # ± 15 months ago
+  joined_on = (Time.now - 3600*24*30*15).strftime('%Y-%m-%d')
+  case uptodate
+  when ', à jour de cotisation'
+    # 30 days ago
+    paid_on = (Time.now - 3600*24*30).strftime('%Y-%m-%d')
+  else
+    paid_on = joined_on
+  end
+  create_new_member(name, joined_on, paid_on)
+end
+
+Given /^une base avec (\w+) qui a adhéré le ([0-9-]+) et payé sa dernière cotisation le ([0-9-]+)$/ do |name, joined_on, paid_on|
+  create_new_member(name, joined_on, paid_on)
+end
+
 Given /^une nouvelle adhésion de (\w+)$/ do |name|
-  data = { 'name' => name,
-           'address' => "At #{name}",
-           'email' => "#{name.downcase}@example.org",
-           'membership_fee_paid_on' => Time.now.strftime('%Y-%m-%d')
-         }
-  create_dir 'Membres'
-  file = member_filename_for_id(new_id)
-  write_file file, render_member_file(data)
+  joined_on = Time.now.strftime('%Y-%m-%d')
+  create_new_member(name, joined_on, joined_on)
 end
 
 When /^j'ajoute une fiche correcte pour une nouvelle adhésion$/ do
@@ -68,6 +78,7 @@ When /^j'ajoute une fiche sans email$/ do
     address: |
       21 Jump Street
       42000 Synthé
+    joined_on: 2013-02-20
     membership_fee_paid_on: 2013-02-20
     ---
   EOF
@@ -81,11 +92,27 @@ When /^j'ajoute une fiche sans nom$/ do
     address: |
       21 Jump Street
       42000 Synthé
+    joined_on: 2013-02-20
     membership_fee_paid_on: 2013-02-20
     ---
   EOF
 end
 
+When /^j'ajoute une fiche avec comme date d'adhésion "([^"]*)"$/ do |date|
+  @file = member_filename_for_id(new_id)
+  write_file @file, <<-EOF.gsub(/^    /, '')
+    ---
+    name: J. Example
+    email: joe@example.org
+    address: |
+      21 Jump Street
+      42000 Synthé
+    joined_on: #{date}
+    membership_fee_paid_on: 2013-04-04
+    ---
+  EOF
+end
+
 When /^j'ajoute une fiche avec comme date de cotisation "([^"]*)"$/ do |date|
   @file = member_filename_for_id(new_id)
   write_file @file, <<-EOF.gsub(/^    /, '')
@@ -95,6 +122,7 @@ When /^j'ajoute une fiche avec comme date de cotisation "([^"]*)"$/ do |date|
     address: |
       21 Jump Street
       42000 Synthé
+    joined_on: 2013-04-04
     membership_fee_paid_on: #{date}
     ---
   EOF
index afaec3321dc3504272dd6f073350a21790616e4d..154fc30bd3892b7c7c65cc9b7185eb6259bdc515 100644 (file)
@@ -2,20 +2,25 @@ require 'rubygems'
 require 'bundler'
 Bundler.setup
 
+require 'timecop'
 require 'tmpdir'
 require 'aruba/cucumber'
 require 'safe_yaml'
 
 SafeYAML::OPTIONS[:default_mode] = :safe
 
+require 'nos_oignons'
+
 Before do
   ENV['GIT_COMMITTER_NAME'] = ENV['GIT_AUTHOR_NAME'] = 'J. Test'
   ENV['GIT_COMMITTER_EMAIL'] = ENV['GIT_AUTHOR_EMAIL'] = 'test@example.org'
   @tmpdir = Dir.mktmpdir('gestion-adh')
   @dirs = [@tmpdir]
-  @aruba_io_wait_seconds = 0.5
+  @aruba_io_wait_seconds = 1
+  @orig_wiki_path = ENV['NOS_OIGNONS_BOARD_WIKI_PATH']
 end
 
 After do
+  ENV['NOS_OIGNONS_BOARD_WIKI_PATH'] = @orig_wiki_path
   FileUtils.remove_entry_secure @tmpdir
 end
index d9d91deae40d0775c5ab74406b2782c17ac990c7..fb06a0c0f27da5597c4fb384ce83e7788912ffa8 100644 (file)
@@ -13,6 +13,7 @@ BASE_MEMBERS = YAML.load(<<END_OF_YAML)
     75009 Paris
     FR
   email: registry@domainnetwork.fr
+  joined_on: 2013-02-21
   membership_fee_paid_on: 2013-02-21
   notes:
     Il vient de `whois cogent.fr`.
@@ -23,6 +24,7 @@ BASE_MEMBERS = YAML.load(<<END_OF_YAML)
     13, rue de Javel
     75015 Paris
   email: sylvain.dufier@orange-ftgroup.com
+  joined_on: 2013-05-20
   membership_fee_paid_on: 2013-05-29
     Il vient de `whois orange.fr`.
 000003:
@@ -32,7 +34,8 @@ BASE_MEMBERS = YAML.load(<<END_OF_YAML)
     15, rue de la Nuee Bleue
     67000 Strasbourg
   email: domaines@sdv.fr
-  membership_fee_paid_on: 2010-01-21
+  joined_on: 2010-01-21
+  membership_fee_paid_on: 2011-01-11
     Il vient de `whois numericable.fr`.
     Et il n'est pas à jour de cotisation.
 END_OF_YAML
@@ -44,6 +47,7 @@ address: |
   42, avenue de Friedland
   75008 Paris
 email: domains@sfr.com
+joined_on: 2013-04-04
 membership_fee_paid_on: 2013-04-04
 notes:
   Il vient de `whois sfr.fr`.
@@ -55,6 +59,7 @@ name: <%= name %>
 address: |
 <%= address.gsub(/^/, '  ').rstrip %>
 email: <%= email %>
+joined_on: <%= joined_on %>
 membership_fee_paid_on: <%= membership_fee_paid_on %>
 ---
 
index 694a87b9649af1b1153d5b700be9618043832e2c..028cac97375f77f8d0227dcdef5ea8c3a5fbc941 100644 (file)
@@ -34,7 +34,7 @@ module NosOignons
 
       IO.popen(['git', 'diff-index', '--cached', '--name-status', against]) do |io|
         NosOignons::Git.handle_modified_files(io) do |file|
-          next unless file.start_with?("#{NosOignons::MEMBERS_ROOT}/")
+          next unless file.start_with?("#{NosOignons::MEMBERS_DB_DIR}/")
           begin
             # Use empty ref to get the index
             NosOignons::Member.read_from_git('', file)
@@ -51,7 +51,7 @@ module NosOignons
         old_value, new_value, ref_name = ref_line.rstrip.split(' ', 3)
         IO.popen(['git', 'diff', '--name-status', "#{old_value}..#{new_value}"]) do |io|
           NosOignons::Git.handle_modified_files(io) do |file|
-            next unless file.start_with?("#{NosOignons::MEMBERS_ROOT}/")
+            next unless file.start_with?("#{NosOignons::MEMBERS_DB_DIR}/")
             begin
               NosOignons::Member.read_from_git(new_value, file)
             rescue ArgumentError
index 9787a63c4e597c20402c906ce4070d81b4b734d6..7e6254e81eeb8a6d4a82cee0dcd3c44ffc570e7a 100644 (file)
@@ -2,21 +2,38 @@ require 'safe_yaml'
 SafeYAML::OPTIONS[:default_mode] = :safe
 
 module NosOignons
-  MEMBERS_ROOT = 'Membres'
-  MEMBER_FIELDS = [:name, :address, :email, :membership_fee_paid_on]
+  MEMBER_FIELDS = [:name, :address, :email, :joined_on, :membership_fee_paid_on]
   MEMBER_MANDATORY_FIELDS = [:name, :email]
+  # Directory in the board wiki which holds the member pages
+  MEMBERS_DB_DIR = 'Membres'
 
   class Member < Struct.new(*MEMBER_FIELDS)
     class << self
+      def db_path
+        if ENV['NOS_OIGNONS_BOARD_WIKI_PATH']
+          @db_path = File.join(ENV['NOS_OIGNONS_BOARD_WIKI_PATH'], MEMBERS_DB_DIR)
+        else
+          return @db_path if @db_path
+
+          git_path = `git rev-parse --show-toplevel`.strip
+          if File.exists?(File.join(git_path, MEMBERS_DB_DIR))
+            @db_path = File.join(git_path, MEMBERS_DB_DIR)
+          else
+            @db_path = File.join(File.expand_path('../wiki-ca', path), MEMBERS_DB_DIR)
+          end
+        end
+        @db_path
+      end
+
       def all
-        Dir.glob("#{MEMBERS_ROOT}/*.mdwn").sort.collect do |file|
+        Dir.glob("#{db_path}/*.mdwn").sort.collect do |file|
           member_id = File.basename(file).gsub(/\.mdwn$/, '')
           Member.new(member_id)
         end
       end
 
       def filename_for_id(member_id)
-        "Membres/%06d.mdwn" % member_id
+        "#{NosOignons::Member.db_path}/%06d.mdwn" % member_id
       end
 
       def read_from_git(ref, file)
@@ -51,15 +68,19 @@ module NosOignons
       MEMBER_MANDATORY_FIELDS.each do |sym|
         raise ArgumentError.new('missing mandatory fields') unless self[sym]
       end
-      if membership_fee_paid_on && !membership_fee_paid_on.is_a?(Date)
-        raise ArgumentError.new('membership_fee_paid_on is not a date')
+      [:joined_on, :membership_fee_paid_on].each do |sym|
+        if self[sym] && !self[sym].is_a?(Date)
+          raise ArgumentError.new("#{sym.to_s} is not a date")
+        end
       end
     end
 
     def up_to_date?
-      now = Time.now
-      last_year = Time.new(now.year - 1, now.month, now.day).to_date
-      membership_fee_paid_on && last_year < membership_fee_paid_on
+      return false if !joined_on || !membership_fee_paid_on
+
+      now = Time.now.to_date
+      expire_on = Time.new(membership_fee_paid_on.year + 1, joined_on.month, joined_on.day).to_date
+      now <= expire_on
     end
   end
 end
index e32ccd1fddf9d623cb043892e67b57dc37574c85..a8584229fa0680a28679642bcc1378f6a45de5fb 100644 (file)
@@ -6,5 +6,6 @@ Gem::Specification.new do |s|
   s.add_development_dependency 'cucumber'
   s.add_development_dependency 'aruba'
   s.add_development_dependency 'json', '~> 1.7.7'
+  s.add_development_dependency 'timecop'
   s.add_runtime_dependency 'safe_yaml'
 end