meetupinator 0.4 → 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97c297cc039e044757e3c64e2d597a3486d52f1b
4
- data.tar.gz: 80f4aa6922def7ce3b8e4d9ac2cc241ccecebcdd
3
+ metadata.gz: 807cb86ec05130fef1235a08122c6a80f7475699
4
+ data.tar.gz: 532b7089fc9b8c295dbb33ef5390a8cdcdc0ca49
5
5
  SHA512:
6
- metadata.gz: d1e4d402408dda78c42b21be201eafb248c30ab423ffa906e7dc79aad44d35293cf44724df8af1f15c568a0775cd9761529548c554755299461661c0e3c1b862
7
- data.tar.gz: 52d17bf67b89553cc5ff3d5f556bf4fecab9988ddca2a968b123eb5e27b6982d5ba59bff71699098a783e20bff07e18ea3e95cda2bd9e7b9731f94a60028ac76
6
+ metadata.gz: 6ef813072e22cd0c8f9818730a6b6e7e8d186a638d1b369498d79de625104aa1094377dca543ca874537a1ebab1a896a24925977c4e034d2faa55f5b80db3bef
7
+ data.tar.gz: f311fc3c830f103787d7c72bde26a2681787bd524838621a6172a5af2a1a3baa31260d7e489e85bd01c4013faa7151bb348e13ceaa8e90c460c86c4aa394097f
data/README.md CHANGED
@@ -22,7 +22,7 @@ This will write a otuput.csv to the current directory.
22
22
  ## During development
23
23
 
24
24
  ```
25
- $ ruby -Ilib ./bin/meetupinator ...
25
+ $ bundle exec ./bin/meetupinator ...
26
26
  ```
27
27
 
28
28
  # todo
@@ -30,11 +30,5 @@ $ ruby -Ilib ./bin/meetupinator ...
30
30
  - [ ] - provide options for date range
31
31
  - [x] - Gem this
32
32
 
33
- ##Spec Notes
34
- - Using VCR gem, will call API when tests are run first time.
35
- - Export MEETUP_API_KEY into your environment
36
- - Times from the api are milliseconds since epoch
37
-
38
-
39
33
  # Licence
40
- some open source one. not sure yet.
34
+ [MIT](https://github.com/joesustaric/meetupinator/blob/master/LICENSE.md)
@@ -0,0 +1,25 @@
1
+ module Meetupinator
2
+ # doco
3
+ class App
4
+ def self.version
5
+ 'meetupinator v' + Meetupinator::VERSION
6
+ end
7
+
8
+ def self.run(args = {})
9
+ new.run(args)
10
+ end
11
+
12
+ def run(args)
13
+ init(args)
14
+ events = @event_finder.extract_events(@group_names, @api, args[:week])
15
+ @event_list_file_writer.write events, args[:output]
16
+ end
17
+
18
+ def init(args)
19
+ @api = Meetupinator::MeetupAPI.new(args[:meetup_api_key])
20
+ @group_names = Meetupinator::InputFileReader.group_names args[:input]
21
+ @event_finder = Meetupinator::EventFinder.new
22
+ @event_list_file_writer = Meetupinator::EventListFileWriter.new
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ require 'thor'
2
+ require 'meetupinator'
3
+
4
+ module Meetupinator
5
+ # class doco
6
+ # rubocop:disable Metrics/LineLength
7
+ class CLI < Thor
8
+ attr_accessor :event_finder
9
+ attr_accessor :event_list_file_writer
10
+ attr_accessor :api
11
+
12
+ class_option :meetup_api_key,
13
+ type: :string, aliases: '-k',
14
+ desc: 'API key for the meetup.com API,
15
+ defaults to MEETUP_API_KEY environment
16
+ variable if not set'
17
+
18
+ desc 'getevents', 'Write all upcoming events for the given meetup
19
+ groups specified in INPUT to OUTPUT'
20
+ map 'getevents' => 'run_app'
21
+ method_option :input, aliases: '-i', required: true, type: :string,
22
+ desc: 'The location of the input file'
23
+ method_option :output,
24
+ aliases: '-o', required: false, type: :string,
25
+ default: 'output.csv',
26
+ desc: 'The name of the file you want to output. (default is ./output.csv)'
27
+
28
+ method_option :week, aliases: '-w', required: false, type: :boolean
29
+
30
+ def run_app
31
+ Meetupinator::App.run(options)
32
+ puts "Output written to #{options[:output]}"
33
+ end
34
+
35
+ desc '--version', 'Print version'
36
+ map '--version' => 'version'
37
+ map '-v' => 'version'
38
+ def version
39
+ puts Meetupinator::App.version
40
+ end
41
+
42
+ default_task :run_app
43
+ end
44
+ end
45
+ # rubocop:enable Metrics/LineLength
@@ -0,0 +1,10 @@
1
+ module Meetupinator
2
+ # class def
3
+ class EventFinder
4
+ def extract_events(group_url_names, api, week)
5
+ ids = group_url_names.map { |name| api.get_meetup_id name }
6
+
7
+ api.get_upcoming_events(ids, week)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,50 @@
1
+ require 'csv'
2
+
3
+ module Meetupinator
4
+ # class def
5
+ class EventListFileWriter
6
+ def write(events, file_name)
7
+ CSV.open(file_name, 'wb') do |csv|
8
+ csv << ['Group name', 'Event name', 'Day of week', 'Date',
9
+ 'Start time', 'End time', 'Event URL']
10
+ events.each do |event|
11
+ csv << extract_row(event)
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def extract_row(event)
19
+ start_time, end_time = extract_times event
20
+ [
21
+ event['group']['name'], event['name'], start_time.strftime('%A'),
22
+ start_time.strftime('%-e/%m/%Y'), start_time.strftime('%-l:%M %p'),
23
+ end_time.strftime('%-l:%M %p'), event['event_url']
24
+ ]
25
+ end
26
+
27
+ def extract_times(event)
28
+ start_time = time_with_offset(event['time'], event['utc_offset'])
29
+ # According to http://www.meetup.com/meetup_api/docs/2/events/,
30
+ # if no duration is specified, we can assume 3 hours.
31
+ # TODO: We should probably display a warning when this happens.
32
+ duration = event['duration'] || three_hours
33
+ end_time = start_time + ms_to_seconds(duration)
34
+
35
+ [start_time, end_time]
36
+ end
37
+
38
+ def time_with_offset(time, offset)
39
+ Time.at(ms_to_seconds(time)).getlocal(ms_to_seconds(offset))
40
+ end
41
+
42
+ def ms_to_seconds(ms)
43
+ ms / 1000
44
+ end
45
+
46
+ def three_hours
47
+ 3 * 60 * 60 * 1000
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ module Meetupinator
2
+ # class doco
3
+ class InputFileReader
4
+ def self.group_names(file_name)
5
+ group_names = []
6
+ File.open(file_name, 'rb') do |file|
7
+ file.each_line { |line| group_names << line.strip }
8
+ end
9
+ group_names
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,73 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ module Meetupinator
5
+ # This class is responsible for communicating with the meetup.com API
6
+ # and returning the json responses only.
7
+ class MeetupAPI
8
+ attr_reader :api_key
9
+
10
+ def initialize(api_key = nil)
11
+ @base_uri = 'api.meetup.com'
12
+ @groups_endpoint = '/2/groups'
13
+ @events_endpoint = '/2/events'
14
+ if key_valid?(api_key) || key_found_in_env?
15
+ @api_key = retreive_key api_key
16
+ else
17
+ fail('no MEETUP_API_KEY provided')
18
+ end
19
+ end
20
+
21
+ def get_meetup_id(group_url_name)
22
+ query_string = 'key=' + @api_key + '&group_urlname=' + group_url_name
23
+ uri = URI::HTTP.build(host: @base_uri, path: @groups_endpoint,
24
+ query: query_string)
25
+ extract_meetup_id get_meetup_response(uri)
26
+ end
27
+
28
+ def get_upcoming_events(group_ids, week)
29
+ query_string = 'sign=true&photo-host=public&status=upcoming&key=' +
30
+ @api_key + '&group_id=' + group_ids.join(',')
31
+
32
+ query_string << '&time=,1w' if week
33
+
34
+ uri = URI::HTTP.build(host: @base_uri, path: @events_endpoint,
35
+ query: query_string)
36
+ response = get_meetup_response uri
37
+ get_results response
38
+ end
39
+
40
+ private
41
+
42
+ def get_meetup_response(uri)
43
+ response = Net::HTTP.get_response uri
44
+ if response.code != '200'
45
+ msg = "Call to #{uri} failed: #{response.code} - #{response.message}"
46
+ msg << '. ' + response.body if response.class.body_permitted?
47
+ fail(msg)
48
+ end
49
+ JSON.parse response.body
50
+ end
51
+
52
+ def extract_meetup_id(response)
53
+ get_results(response)[0]['id']
54
+ end
55
+
56
+ def get_results(response)
57
+ response['results']
58
+ end
59
+
60
+ def retreive_key(api_key)
61
+ return api_key if key_valid? api_key
62
+ return ENV['MEETUP_API_KEY'] if key_found_in_env?
63
+ end
64
+
65
+ def key_valid?(api_key)
66
+ !(api_key.nil? || api_key.empty?)
67
+ end
68
+
69
+ def key_found_in_env?
70
+ !(ENV['MEETUP_API_KEY'].nil? || ENV['MEETUP_API_KEY'].empty?)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,4 @@
1
+ # Module Comment
2
+ module Meetupinator
3
+ VERSION = '0.5'
4
+ end
@@ -0,0 +1,7 @@
1
+ require 'meetupinator/app'
2
+ require 'meetupinator/cli'
3
+ require 'meetupinator/event_finder'
4
+ require 'meetupinator/event_list_file_writer'
5
+ require 'meetupinator/meetup_api'
6
+ require 'meetupinator/version'
7
+ require 'meetupinator/input_file_reader'
@@ -0,0 +1,22 @@
1
+ Group name,Event name,Day of week,Date,Start time,End time,Event URL
2
+ Ruby and Rails Melbourne,Ruby on Rails InstallFest,Thursday,19/02/2015,6:30 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219051382/
3
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,25/02/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219387830/
4
+ Ruby and Rails Melbourne,Hack Night,Tuesday,10/03/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219525271/
5
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,25/03/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219525272/
6
+ Ruby and Rails Melbourne,Hack Night,Tuesday,14/04/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytgbsb/
7
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,29/04/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytgbmc/
8
+ Ruby and Rails Melbourne,Hack Night,Tuesday,12/05/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlythbqb/
9
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,27/05/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlythbkc/
10
+ Ruby and Rails Melbourne,Hack Night,Tuesday,9/06/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/220405387/
11
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,24/06/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytjbgc/
12
+ Ruby and Rails Melbourne,Hack Night,Tuesday,14/07/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytkbsb/
13
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,29/07/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytkbmc/
14
+ Ruby and Rails Melbourne,Hack Night,Tuesday,11/08/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytlbpb/
15
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,26/08/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytlbjc/
16
+ Ruby and Rails Melbourne,Hack Night,Tuesday,8/09/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytmblb/
17
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,30/09/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytmbnc/
18
+ Ruby and Rails Melbourne,Hack Night,Tuesday,13/10/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytnbrb/
19
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,28/10/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytnblc/
20
+ Ruby and Rails Melbourne,Hack Night,Tuesday,10/11/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytpbnb/
21
+ Ruby and Rails Melbourne,Melbourne Ruby,Wednesday,25/11/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/fdxfdlytpbhc/
22
+ Ruby and Rails Melbourne,Hack Night,Tuesday,8/12/2015,6:00 PM,9:00 PM,http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/tdxfdlytqblb/
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'vcr_setup'
3
+ require 'meetupinator/cli'
4
+
5
+ # I wanted to execute these tests by running the exe file
6
+ # but it won't engage the vcr gem because I think it might
7
+ # spawn a new process? (I think)
8
+ describe 'The meetupinator command line interface' do
9
+ let(:meetups) { ['MelbNodeJS', 'Ruby-On-Rails-Oceania-Melbourne'] }
10
+
11
+ before do
12
+ FileUtils.mkdir_p('test')
13
+ Dir.chdir('test')
14
+ File.open('input.txt', 'wb') do |file|
15
+ meetups.each { |m| file << m + "\n" }
16
+ end
17
+ end
18
+
19
+ after do
20
+ Dir.chdir('..')
21
+ FileUtils.rm_rf('test')
22
+ end
23
+
24
+ context 'no arguments' do
25
+ end
26
+
27
+ context 'meetup api and input file specified' do
28
+ it 'generates the correct output.csv in the working dir' do
29
+ VCR.use_cassette('functional') do
30
+ Meetupinator::CLI.start(['-i', 'input.txt', '-k', '1234'])
31
+ end
32
+ expect(CSV.read('output.csv')).to eq(CSV.read('../spec/fixtures/functional.csv'))
33
+ end
34
+ end
35
+
36
+ context 'meetup api and input file and output file specified' do
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ require 'fakefs/spec_helpers'
2
+ require 'spec_helper'
3
+ require 'meetupinator/app'
4
+
5
+ describe Meetupinator::App do
6
+ describe '#run' do
7
+ let(:input_file) { 'input.txt' }
8
+ let(:output_file) { 'output.csv' }
9
+ let(:event_finder) { double('event finder') }
10
+ let(:file_writer) { double('file writer') }
11
+ let(:meetup_api) { double('meetup api') }
12
+ let(:group_names) { ['First meetup group', 'Second meetup group'] }
13
+ let(:events) { double('events') }
14
+ let(:args) do
15
+ {
16
+ meetup_api_key: 1234,
17
+ input: input_file,
18
+ output: output_file,
19
+ week: false
20
+ }
21
+ end
22
+
23
+ context 'when input file / output file / api key / is specified' do
24
+ it 'executes the program' do
25
+ expect(Meetupinator::MeetupAPI).to receive(:new).and_return(meetup_api)
26
+ expect(Meetupinator::InputFileReader).to receive(:group_names).with(input_file).and_return(group_names)
27
+ expect(Meetupinator::EventFinder).to receive(:new).and_return(event_finder)
28
+ expect(Meetupinator::EventListFileWriter).to receive(:new).and_return(file_writer)
29
+ expect(event_finder).to receive(:extract_events).with(group_names, meetup_api, false).and_return(events)
30
+ expect(file_writer).to receive(:write).with(events, output_file)
31
+ Meetupinator::App.run(args)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'meetupinator/event_finder'
3
+ require 'meetupinator/meetup_api'
4
+
5
+ describe Meetupinator::EventFinder do
6
+ describe '#extract_events' do
7
+ let(:meetups) do
8
+ {
9
+ 'first' => 101,
10
+ 'second' => 201,
11
+ 'third' => 301
12
+ }
13
+ end
14
+
15
+ let(:events) { [:first_event, :another_event, :more_events, :final_event] }
16
+ let(:events_in_week) { [:event_in_week] }
17
+
18
+ let(:api) { instance_double(Meetupinator::MeetupAPI) }
19
+
20
+ before do
21
+ allow(api).to receive(:get_meetup_id) { |name| meetups[name] }
22
+ allow(api).to receive(:get_upcoming_events).with(meetups.values, nil) { events }
23
+ allow(api).to receive(:get_upcoming_events).with(meetups.values, true) { events_in_week }
24
+ end
25
+
26
+ it { expect(subject.extract_events(meetups.keys, api, nil)).to eq(events) }
27
+ it { expect(subject.extract_events(meetups.keys, api, true)).to eq(events_in_week) }
28
+ end
29
+ end
@@ -0,0 +1,77 @@
1
+ require 'fakefs/spec_helpers'
2
+ require 'spec_helper'
3
+ require 'meetupinator/event_list_file_writer'
4
+
5
+ describe Meetupinator::EventListFileWriter do
6
+ include FakeFS::SpecHelpers::All
7
+
8
+ let(:file_name) { 'output.csv' }
9
+ let(:events) do
10
+ [
11
+ {
12
+ 'group' => { 'name' => 'The Society of Chocolate Eaters' },
13
+ 'name' => 'The Time When We Eat Chocolate',
14
+ 'time' => 142_355_160_000_0,
15
+ 'utc_offset' => 396_000_00,
16
+ 'duration' => 720_000_0,
17
+ 'event_url' => 'http://www.awesomemeetup.com/'
18
+ }
19
+ ]
20
+ end
21
+
22
+ let(:expected_csv_output) do
23
+ [
24
+ {
25
+ group_name: 'The Society of Chocolate Eaters',
26
+ event_name: 'The Time When We Eat Chocolate',
27
+ day_of_week: 'Tuesday',
28
+ date: '10/02/2015',
29
+ start_time: '6:00 PM',
30
+ end_time: '8:00 PM',
31
+ event_url: 'http://www.awesomemeetup.com/'
32
+ }
33
+ ]
34
+ end
35
+
36
+ def clean_up
37
+ File.delete(file_name) if File.exist?(file_name)
38
+ end
39
+
40
+ before { clean_up }
41
+
42
+ after { clean_up }
43
+
44
+ describe '#write' do
45
+ it 'writes the events to file' do
46
+ subject.write events, file_name
47
+
48
+ File.open file_name do |body|
49
+ csv = CSV.new(body, headers: true, header_converters: :symbol,
50
+ converters: :all)
51
+ actual_csv_output = csv.to_a.map(&:to_hash)
52
+ expect(actual_csv_output).to eq(expected_csv_output)
53
+ end
54
+ end
55
+
56
+ context 'when the event does not have a duration' do
57
+ before do
58
+ events[0].delete('duration')
59
+ expected_csv_output[0][:end_time] = '9:00 PM'
60
+ end
61
+
62
+ # According to http://www.meetup.com/meetup_api/docs/2/events/,
63
+ # if no duration is specified,
64
+ # we can assume 3 hours.
65
+ it 'writes the event to file assuming the duration is 3 hours' do
66
+ subject.write events, file_name
67
+
68
+ File.open file_name do |body|
69
+ csv = CSV.new(body, headers: true, header_converters: :symbol,
70
+ converters: :all)
71
+ actual_csv_output = csv.to_a.map(&:to_hash)
72
+ expect(actual_csv_output).to eq(expected_csv_output)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,116 @@
1
+ require 'vcr_setup'
2
+ require 'spec_helper'
3
+ require 'meetupinator/cli'
4
+
5
+ # Joe: I know I've written another functional test as well but,
6
+ # i'll leave this one in here too.
7
+ # Sometime it helps to write the output to disk especially for debugging.
8
+
9
+ describe 'meetupinator' do
10
+ # In an ideal world, we'd use FakeFS here.
11
+ # Unfortunately, FakeFS and VCR don't coexist very well.
12
+ # Something like the solution proposed in https://github.com/vcr/vcr/issues/234 could work,
13
+ # but for the time being we can just use temp files instead.
14
+ let(:input_file) { Dir::Tmpname.make_tmpname(['input', '.txt'], nil) }
15
+ let(:output_file) { Dir::Tmpname.make_tmpname(['output', '.csv'], nil) }
16
+
17
+ let(:expected_csv_output) do
18
+ [
19
+ {
20
+ group_name: 'The Melbourne Node.JS Meetup Group',
21
+ event_name: 'Feb meetup: io.js & ES6 & more',
22
+ day_of_week: 'Wednesday',
23
+ date: '4/02/2015',
24
+ start_time: '6:30 PM',
25
+ end_time: '9:30 PM',
26
+ event_url: 'http://www.meetup.com/MelbNodeJS/events/219976432/'
27
+ },
28
+ {
29
+ group_name: 'Ruby and Rails Melbourne',
30
+ event_name: 'Hack Night',
31
+ day_of_week: 'Tuesday',
32
+ date: '10/02/2015',
33
+ start_time: '6:00 PM',
34
+ end_time: '9:00 PM',
35
+ event_url: 'http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219387827/'
36
+ },
37
+ {
38
+ group_name: 'Ruby and Rails Melbourne',
39
+ event_name: 'Ruby on Rails InstallFest',
40
+ day_of_week: 'Thursday',
41
+ date: '19/02/2015',
42
+ start_time: '6:30 PM',
43
+ end_time: '9:00 PM',
44
+ event_url: 'http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219051382/'
45
+ },
46
+ {
47
+ group_name: 'Ruby and Rails Melbourne',
48
+ event_name: 'Melbourne Ruby',
49
+ day_of_week: 'Wednesday',
50
+ date: '25/02/2015',
51
+ start_time: '6:00 PM',
52
+ end_time: '9:00 PM',
53
+ event_url: 'http://www.meetup.com/Ruby-On-Rails-Oceania-Melbourne/events/219387830/'
54
+ }
55
+ ]
56
+ end
57
+
58
+ def clean_up(file)
59
+ File.delete(file) if File.exist?(file)
60
+ end
61
+
62
+ before do
63
+ clean_up input_file
64
+ clean_up output_file
65
+ create_input_file
66
+ end
67
+
68
+ after do
69
+ clean_up input_file
70
+ clean_up output_file
71
+ end
72
+
73
+ context 'when given minimal correct arguments' do
74
+ it 'will fetch and save events for all meetups' do
75
+ VCR.use_cassette('getevents_functional_test') do
76
+ args = ['getevents', '-i', input_file, '-o', output_file, '-k', '1234']
77
+ expect { Meetupinator::CLI.start(args) }.to match_stdout("Output written to #{output_file}")
78
+ expect(read_output_file).to eq(expected_csv_output)
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'when given the --version argument' do
84
+ before { stub_const('Meetupinator::VERSION', '9.23') }
85
+
86
+ it 'returns the version' do
87
+ args = ['--version']
88
+ expect { Meetupinator::CLI.start(args) }.to match_stdout('meetupinator v9.23')
89
+ end
90
+ end
91
+
92
+ context 'when given the -v argument' do
93
+ before { stub_const('Meetupinator::VERSION', '9.23') }
94
+
95
+ it 'returns the version' do
96
+ args = ['-v']
97
+ expect { Meetupinator::CLI.start(args) }.to match_stdout('meetupinator v9.23')
98
+ end
99
+ end
100
+
101
+ def create_input_file
102
+ group_names = ['MelbNodeJS', 'Ruby-On-Rails-Oceania-Melbourne']
103
+ File.open(input_file, 'wb') do |file|
104
+ group_names.each { |name| file << name + "\n" }
105
+ end
106
+ end
107
+
108
+ def read_output_file
109
+ actual_csv_output = nil
110
+ File.open output_file do |body|
111
+ csv = CSV.new(body, headers: true, header_converters: :symbol, converters: :all)
112
+ actual_csv_output = csv.to_a.map(&:to_hash)
113
+ end
114
+ actual_csv_output
115
+ end
116
+ end
@@ -0,0 +1,23 @@
1
+ require 'fakefs/spec_helpers'
2
+ require 'spec_helper'
3
+ require 'meetupinator/input_file_reader'
4
+
5
+ describe Meetupinator::InputFileReader do
6
+ include FakeFS::SpecHelpers::All
7
+
8
+ let(:input_file_dir) { '/tmp/input/file/location' }
9
+ let(:file_name) { input_file_dir + '/input_file.txt' }
10
+ let(:group_names) { %w(some_group another_group more_groups) }
11
+
12
+ before do
13
+ # need to make dir for fakefs
14
+ FileUtils.mkdir_p(input_file_dir)
15
+ File.open(file_name, 'wb') do |file|
16
+ group_names.each { |items| file << items + "\n" }
17
+ end
18
+ end
19
+
20
+ describe '#group_names' do
21
+ it { expect(Meetupinator::InputFileReader.group_names(file_name)).to eq(group_names) }
22
+ end
23
+ end