bnet_scraper 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +51 -31
- data/bnet_scraper.gemspec +3 -1
- data/fixtures/vcr_cassettes/demon_achievements.yml +246 -0
- data/fixtures/vcr_cassettes/demon_leagues.yml +359 -0
- data/fixtures/vcr_cassettes/demon_match_history.yml +241 -0
- data/fixtures/vcr_cassettes/demon_matches.yml +240 -0
- data/fixtures/vcr_cassettes/demon_profile.yml +1428 -0
- data/fixtures/vcr_cassettes/demon_profile_leagues.yml +1291 -0
- data/fixtures/vcr_cassettes/full_demon_scrape.yml +5449 -0
- data/fixtures/vcr_cassettes/invalid_achievement.yml +199 -0
- data/fixtures/vcr_cassettes/invalid_leagues.yml +199 -0
- data/fixtures/vcr_cassettes/invalid_matches.yml +199 -0
- data/fixtures/vcr_cassettes/invalid_profile.yml +199 -0
- data/fixtures/vcr_cassettes/new_league.yml +595 -0
- data/fixtures/vcr_cassettes/profile_invalid.yml +199 -0
- data/fixtures/vcr_cassettes/profile_not_laddered.yml +443 -0
- data/fixtures/vcr_cassettes/realm_status.yml +578 -0
- data/lib/bnet_scraper/starcraft2.rb +7 -8
- data/lib/bnet_scraper/starcraft2/achievement_scraper.rb +5 -5
- data/lib/bnet_scraper/starcraft2/league.rb +54 -0
- data/lib/bnet_scraper/starcraft2/league_scraper.rb +3 -1
- data/lib/bnet_scraper/starcraft2/match.rb +15 -0
- data/lib/bnet_scraper/starcraft2/match_history_scraper.rb +9 -18
- data/lib/bnet_scraper/starcraft2/profile.rb +45 -0
- data/lib/bnet_scraper/starcraft2/profile_scraper.rb +68 -44
- data/spec/spec_helper.rb +14 -0
- data/spec/starcraft2/achievement_scraper_spec.rb +67 -83
- data/spec/starcraft2/league_scraper_spec.rb +25 -59
- data/spec/starcraft2/league_spec.rb +43 -0
- data/spec/starcraft2/match_history_scraper_spec.rb +19 -39
- data/spec/starcraft2/profile_scraper_spec.rb +36 -141
- data/spec/starcraft2/profile_spec.rb +46 -0
- data/spec/starcraft2/status_scraper_spec.rb +12 -5
- data/spec/starcraft2_spec.rb +19 -36
- data/spec/support/shared/sc2_scraper.rb +28 -13
- metadata +57 -42
- data/spec/support/achievements.html +0 -1156
- data/spec/support/failure.html +0 -565
- data/spec/support/initial_league.html +0 -1082
- data/spec/support/initial_leagues.html +0 -3598
- data/spec/support/league.html +0 -8310
- data/spec/support/leagues.html +0 -3810
- data/spec/support/load_fakeweb.rb +0 -42
- data/spec/support/matches.html +0 -1228
- data/spec/support/no_ladder.html +0 -967
- data/spec/support/no_ladder_leagues.html +0 -664
- data/spec/support/profile.html +0 -1074
- data/spec/support/status.html +0 -1
@@ -94,15 +94,14 @@ module BnetScraper
|
|
94
94
|
# scraped from the website
|
95
95
|
def self.full_profile_scrape bnet_id, account, region = 'na'
|
96
96
|
profile_scraper = ProfileScraper.new bnet_id: bnet_id, account: account, region: region
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
profile_output[:leagues].each do |league|
|
101
|
-
league_scraper = LeagueScraper.new url: league[:href]
|
102
|
-
parsed_leagues << league_scraper.scrape
|
97
|
+
profile = profile_scraper.scrape
|
98
|
+
profile.leagues.each do |league|
|
99
|
+
league.scrape_league
|
103
100
|
end
|
104
|
-
|
105
|
-
|
101
|
+
profile.achievements
|
102
|
+
profile.match_history
|
103
|
+
|
104
|
+
return profile
|
106
105
|
end
|
107
106
|
|
108
107
|
# Determine if Supplied profile is valid. Useful for validating now before an
|
@@ -72,11 +72,11 @@ module BnetScraper
|
|
72
72
|
def scrape_progress
|
73
73
|
progress_ach = response.css("#progress-module .achievements-progress:nth(2) span")
|
74
74
|
@progress = {
|
75
|
-
liberty_campaign:
|
76
|
-
exploration:
|
77
|
-
custom_game:
|
78
|
-
cooperative:
|
79
|
-
quick_match:
|
75
|
+
liberty_campaign: response.css(".progress-tile:nth-child(1) .profile-progress span").inner_text,
|
76
|
+
exploration: response.css(".progress-tile:nth-child(2) .profile-progress span").inner_text,
|
77
|
+
custom_game: response.css(".progress-tile:nth-child(3) .profile-progress span").inner_text,
|
78
|
+
cooperative: response.css(".progress-tile:nth-child(4) .profile-progress span").inner_text,
|
79
|
+
quick_match: response.css(".progress-tile:nth-child(5) .profile-progress span").inner_text,
|
80
80
|
}
|
81
81
|
end
|
82
82
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module BnetScraper
|
2
|
+
module Starcraft2
|
3
|
+
class League
|
4
|
+
attr_accessor :id, :name, :href, :season, :name, :division, :size, :random, :bnet_id,
|
5
|
+
:account
|
6
|
+
|
7
|
+
def initialize options = {}
|
8
|
+
options.each_key do |key|
|
9
|
+
self.send "#{key}=", options[key]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
scrape_or_return :@name
|
15
|
+
end
|
16
|
+
|
17
|
+
def season
|
18
|
+
scrape_or_return :@season
|
19
|
+
end
|
20
|
+
|
21
|
+
def division
|
22
|
+
scrape_or_return :@division
|
23
|
+
end
|
24
|
+
|
25
|
+
def size
|
26
|
+
scrape_or_return :@size
|
27
|
+
end
|
28
|
+
|
29
|
+
def bnet_id
|
30
|
+
scrape_or_return :@bnet_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def account
|
34
|
+
scrape_or_return :@account
|
35
|
+
end
|
36
|
+
|
37
|
+
def scrape_or_return attribute
|
38
|
+
if self.instance_variable_get(attribute)
|
39
|
+
return self.instance_variable_get(attribute)
|
40
|
+
else
|
41
|
+
scrape_league
|
42
|
+
self.instance_variable_get(attribute)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def scrape_league
|
47
|
+
scraped_data = LeagueScraper.new(url: href).scrape
|
48
|
+
scraped_data.each_key do |key|
|
49
|
+
self.send "#{key}=", scraped_data[key]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bnet_scraper/starcraft2/league'
|
2
|
+
|
1
3
|
module BnetScraper
|
2
4
|
module Starcraft2
|
3
5
|
# This pulls information on a specific league for a specific account. It is best used either in conjunction with a
|
@@ -34,7 +36,7 @@ module BnetScraper
|
|
34
36
|
if @response.success?
|
35
37
|
@response = Nokogiri::HTML(@response.body)
|
36
38
|
value = @response.css(".data-title .data-label h3").inner_text().strip
|
37
|
-
header_regex = /
|
39
|
+
header_regex = /(.+) -\s+(\dv\d)( Random)? (\w+)\s+Division (.+)/
|
38
40
|
header_values = value.match(header_regex).to_a
|
39
41
|
header_values.shift()
|
40
42
|
@season, @size, @random, @division, @name = header_values
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bnet_scraper/starcraft2/match'
|
2
|
+
|
1
3
|
module BnetScraper
|
2
4
|
module Starcraft2
|
3
5
|
# This pulls the 25 most recent matches played for an account. Note that this is only as up-to-date as battle.net is, and
|
@@ -42,29 +44,18 @@ module BnetScraper
|
|
42
44
|
|
43
45
|
response.css('.match-row').each do |m|
|
44
46
|
match = {}
|
47
|
+
match = Match.new
|
45
48
|
|
46
49
|
cells = m.css('td')
|
47
|
-
match
|
48
|
-
match
|
49
|
-
match
|
50
|
-
match
|
50
|
+
match.map_name = cells[1].inner_text
|
51
|
+
match.type = cells[2].inner_text
|
52
|
+
match.outcome = (cells.css('.match-loss') ? :win : :loss)
|
53
|
+
match.date = cells[4].inner_text.strip
|
54
|
+
|
51
55
|
@matches << match
|
52
|
-
if match[:outcome] == :win
|
53
|
-
@wins += 1
|
54
|
-
else
|
55
|
-
@losses += 1
|
56
|
-
end
|
57
|
-
output
|
58
56
|
end
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
def output
|
63
|
-
{
|
64
|
-
matches: @matches,
|
65
|
-
wins: @wins,
|
66
|
-
losses: @losses
|
67
|
-
}
|
58
|
+
@matches
|
68
59
|
end
|
69
60
|
end
|
70
61
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
module BnetScraper
|
3
|
+
module Starcraft2
|
4
|
+
class Profile
|
5
|
+
attr_accessor :portrait, :url, :achievement_points, :current_solo_league,
|
6
|
+
:highest_solo_league, :current_team_league, :highest_team_league,
|
7
|
+
:career_games, :games_this_season, :terran_swarm_level, :protoss_swarm_level,
|
8
|
+
:zerg_swarm_level, :leagues, :swarm_levels
|
9
|
+
|
10
|
+
def initialize options = {}
|
11
|
+
options.each_key do |key|
|
12
|
+
self.send "#{key}=", options[key]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def achievements
|
17
|
+
@achievements ||= AchievementScraper.new(url: url).scrape
|
18
|
+
end
|
19
|
+
|
20
|
+
def recent_achievements
|
21
|
+
achievements[:recent]
|
22
|
+
end
|
23
|
+
|
24
|
+
def progress_achievements
|
25
|
+
achievements[:progress]
|
26
|
+
end
|
27
|
+
|
28
|
+
def showcase_achievements
|
29
|
+
achievements[:showcase]
|
30
|
+
end
|
31
|
+
|
32
|
+
def match_history
|
33
|
+
@match_history ||= MatchHistoryScraper.new(url: url).scrape
|
34
|
+
end
|
35
|
+
|
36
|
+
def swarm_levels
|
37
|
+
{
|
38
|
+
zerg: @zerg_swarm_level,
|
39
|
+
protoss: @protoss_swarm_level,
|
40
|
+
terran: @terran_swarm_level
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bnet_scraper/starcraft2/profile'
|
2
|
+
|
1
3
|
module BnetScraper
|
2
4
|
module Starcraft2
|
3
5
|
# This pulls basic profile information for an account, as well as an array of league URLs. This is a good starting
|
@@ -28,19 +30,22 @@ module BnetScraper
|
|
28
30
|
# ]
|
29
31
|
# }
|
30
32
|
class ProfileScraper < BaseScraper
|
31
|
-
attr_reader :achievement_points, :career_games, :
|
32
|
-
:
|
33
|
-
:current_team_league, :portrait
|
33
|
+
attr_reader :achievement_points, :career_games, :leagues, :games_this_season,
|
34
|
+
:highest_solo_league, :current_solo_league, :highest_team_league,
|
35
|
+
:current_team_league, :portrait, :terran_swarm_level, :protoss_swarm_level,
|
36
|
+
:zerg_swarm_level, :profile
|
34
37
|
|
35
38
|
def initialize options = {}
|
36
39
|
super
|
37
40
|
@leagues = []
|
41
|
+
@profile ||= Profile.new url: profile_url
|
38
42
|
end
|
39
43
|
|
40
44
|
def scrape
|
41
45
|
get_profile_data
|
42
46
|
get_league_list
|
43
|
-
|
47
|
+
|
48
|
+
@profile
|
44
49
|
end
|
45
50
|
|
46
51
|
# scrapes the profile page for basic account information
|
@@ -50,64 +55,83 @@ module BnetScraper
|
|
50
55
|
if response.success?
|
51
56
|
html = Nokogiri::HTML(response.body)
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
@
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
@profile.achievement_points = html.css("#profile-header h3").inner_html()
|
59
|
+
@profile.career_games = html.css(".career-stat-block:nth-child(4) .stat-value").inner_html()
|
60
|
+
@profile.games_this_season = html.css(".career-stat-block:nth-child(5) .stat-value").inner_html()
|
61
|
+
|
62
|
+
get_portrait html
|
63
|
+
get_solo_league_info html
|
64
|
+
get_team_league_info html
|
65
|
+
get_swarm_levels html
|
66
|
+
else
|
67
|
+
raise BnetScraper::InvalidProfileError
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_portrait html
|
72
|
+
# Portraits use spritemaps, so we extract positions and map to
|
73
|
+
# PORTRAITS.
|
74
|
+
@profile.portrait = begin
|
75
|
+
portrait = html.css("#profile-header #portrait span").attr('style').to_s.scan(/url\('(.*?)'\) ([\-\d]+)px ([\-\d]+)px/).flatten
|
76
|
+
portrait_map, portrait_size = portrait[0].scan(/(\d)\-(\d+)\.jpg/)[0]
|
77
|
+
portrait_position = (((0-portrait[2].to_i) / portrait_size.to_i) * 6) + ((0-portrait[1].to_i) / portrait_size.to_i + 1)
|
78
|
+
PORTRAITS[portrait_map.to_i][portrait_position-1]
|
79
|
+
rescue
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
63
83
|
|
64
|
-
|
65
|
-
|
66
|
-
@
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
if html.css("#best-finish-SOLO div")[0]
|
71
|
-
@highest_solo_league = html.css("#best-finish-SOLO div")[0].children[2].inner_text.strip
|
72
|
-
if html.css("#best-finish-SOLO div")[0].children[8]
|
73
|
-
@current_solo_league = html.css("#best-finish-SOLO div")[0].children[8].inner_text.strip
|
74
|
-
else
|
75
|
-
@current_solo_league = html.css("#best-finish-SOLO div")[0].children[5].inner_text.strip
|
76
|
-
end
|
84
|
+
def get_solo_league_info html
|
85
|
+
if html.css("#best-finish-SOLO div")[0]
|
86
|
+
@profile.highest_solo_league = html.css("#best-finish-SOLO div")[0].children[2].inner_text.strip
|
87
|
+
if html.css("#best-finish-SOLO div")[0].children[8]
|
88
|
+
@profile.current_solo_league = html.css("#best-finish-SOLO div")[0].children[8].inner_text.strip
|
77
89
|
else
|
78
|
-
@
|
79
|
-
@current_solo_league = "Not Yet Ranked"
|
90
|
+
@profile.current_solo_league = "Not Yet Ranked"
|
80
91
|
end
|
92
|
+
else
|
93
|
+
@profile.highest_solo_league = "Not Yet Ranked"
|
94
|
+
@profile.current_solo_league = "Not Yet Ranked"
|
95
|
+
end
|
96
|
+
end
|
81
97
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
@current_team_league = html.css("#best-finish-TEAM div")[0].children[5].inner_text.strip
|
88
|
-
end
|
98
|
+
def get_team_league_info html
|
99
|
+
if html.css("#best-finish-TEAM div")[0]
|
100
|
+
@profile.highest_team_league = html.css("#best-finish-TEAM div")[0].children[2].inner_text.strip
|
101
|
+
if html.css("#best-finish-TEAM div")[0].children[8]
|
102
|
+
@profile.current_team_league = html.css("#best-finish-TEAM div")[0].children[8].inner_text.strip
|
89
103
|
else
|
90
|
-
@
|
91
|
-
@current_team_league = "Not Yet Ranked"
|
104
|
+
@profile.current_team_league = "Not Yet Ranked"
|
92
105
|
end
|
93
|
-
|
94
106
|
else
|
95
|
-
|
107
|
+
@profile.highest_team_league = "Not Yet Ranked"
|
108
|
+
@profile.current_team_league = "Not Yet Ranked"
|
96
109
|
end
|
97
110
|
end
|
98
111
|
|
112
|
+
def get_swarm_levels html
|
113
|
+
@profile.protoss_swarm_level = get_swarm_level :protoss, html
|
114
|
+
@profile.terran_swarm_level = get_swarm_level :terran, html
|
115
|
+
@profile.zerg_swarm_level = get_swarm_level :zerg, html
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_swarm_level race, html
|
119
|
+
level = html.css(".race-level-block.#{race} .level-value").inner_html
|
120
|
+
level.match(/Level (\d+)/)[1].to_i
|
121
|
+
end
|
122
|
+
|
99
123
|
# scrapes the league list from account's league page and sets an array of URLs
|
100
124
|
def get_league_list
|
101
125
|
response = Faraday.get profile_url + "ladder/leagues"
|
102
126
|
if response.success?
|
103
127
|
html = Nokogiri::HTML(response.body)
|
104
128
|
|
105
|
-
@leagues = html.css("a[href*='#current-rank']").map do |league|
|
106
|
-
{
|
107
|
-
name: league.
|
129
|
+
@profile.leagues = html.css("a[href*='#current-rank']").map do |league|
|
130
|
+
League.new({
|
131
|
+
name: league.inner_text().strip,
|
108
132
|
id: league.attr('href').sub('#current-rank',''),
|
109
133
|
href: "#{profile_url}ladder/#{league.attr('href')}"
|
110
|
-
}
|
134
|
+
})
|
111
135
|
end
|
112
136
|
else
|
113
137
|
raise BnetScraper::InvalidProfileError
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
2
2
|
|
3
3
|
require 'bnet_scraper'
|
4
|
+
require 'pry'
|
5
|
+
require 'vcr'
|
4
6
|
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f }
|
5
7
|
|
8
|
+
VCR.configure do |config|
|
9
|
+
config.cassette_library_dir = 'fixtures/vcr_cassettes'
|
10
|
+
config.hook_into :fakeweb
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.around(:each, :vcr) do |example|
|
16
|
+
name = example.metadata[:full_description].split(/\s+/, 2).join("/").underscore.gsub(/[^\w\/]+/, "_")
|
17
|
+
VCR.use_cassette(name) { example.call }
|
18
|
+
end
|
19
|
+
end
|
@@ -9,97 +9,81 @@ describe BnetScraper::Starcraft2::AchievementScraper do
|
|
9
9
|
let(:subject) { scraper_class.new(url: url) }
|
10
10
|
end
|
11
11
|
|
12
|
-
describe '
|
13
|
-
it 'should get the HTML response to be scraped' do
|
14
|
-
subject.response.should be_nil
|
15
|
-
subject.get_response
|
16
|
-
subject.response.should_not be_nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#scrape' do
|
21
|
-
it 'should call get_response and trigger scraper methods' do
|
22
|
-
subject.should_receive(:get_response)
|
23
|
-
subject.should_receive(:scrape_progress)
|
24
|
-
subject.should_receive(:scrape_recent)
|
25
|
-
subject.should_receive(:scrape_showcase)
|
26
|
-
subject.scrape
|
27
|
-
end
|
28
|
-
|
12
|
+
describe 'scrape' do
|
29
13
|
it 'should return InvalidProfileError if response is 404' do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
describe '#scrape_showcase' do
|
37
|
-
before :each do
|
38
|
-
subject.get_response
|
39
|
-
subject.scrape_showcase
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should set the showcase' do
|
43
|
-
subject.showcase.should have(5).achievements
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe '#scrape_recent' do
|
48
|
-
before :each do
|
49
|
-
subject.get_response
|
50
|
-
subject.scrape_recent
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should have the title of the achievement' do
|
54
|
-
subject.recent[0][:title].should == 'Blink of an Eye'
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'should have the description of the achievement' do
|
58
|
-
# this is a cop-out because the string contains UTF-8. Please fix this. - Cad
|
59
|
-
subject.recent[0][:description].should be_a String
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'should have the date the achievement was earned' do
|
63
|
-
subject.recent[0][:earned].should == '3/5/2012'
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
describe '#scrape_progress' do
|
68
|
-
before :each do
|
69
|
-
subject.get_response
|
70
|
-
subject.scrape_progress
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should set the liberty campaign progress' do
|
74
|
-
subject.progress[:liberty_campaign].should == '1580'
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should set the exploration progress' do
|
78
|
-
subject.progress[:exploration].should == '480'
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should set the custom game progress' do
|
82
|
-
subject.progress[:custom_game].should == '330'
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should set the cooperative progress' do
|
86
|
-
subject.progress[:cooperative].should == '660'
|
14
|
+
VCR.use_cassette('invalid_achievement') do
|
15
|
+
url = 'http://us.battle.net/sc2/en/profile/2377239/1/SomeDude/achievements/'
|
16
|
+
scraper = BnetScraper::Starcraft2::AchievementScraper.new(url: url)
|
17
|
+
expect { scraper.scrape }.to raise_error(BnetScraper::InvalidProfileError)
|
18
|
+
end
|
87
19
|
end
|
88
20
|
|
89
|
-
|
90
|
-
|
21
|
+
context 'valid' do
|
22
|
+
before do
|
23
|
+
VCR.use_cassette('demon_achievements') do
|
24
|
+
subject.get_response
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'showcase' do
|
29
|
+
before { subject.scrape_showcase }
|
30
|
+
its(:showcase) { should have(5).achievements }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'recent' do
|
34
|
+
before { subject.scrape_recent }
|
35
|
+
|
36
|
+
it 'should have the title of the achievement' do
|
37
|
+
subject.recent[0][:title].should == 'Three-way Dominant'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should have the description of the achievement' do
|
41
|
+
# this is a cop-out because the string contains UTF-8. Please fix this. - Cad
|
42
|
+
subject.recent[0][:description].should be_a String
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should have the date the achievement was earned' do
|
46
|
+
subject.recent[0][:earned].should == '2/7/2013'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'progress' do
|
51
|
+
before { subject.scrape_progress }
|
52
|
+
|
53
|
+
it 'should set the liberty campaign progress' do
|
54
|
+
subject.progress[:liberty_campaign].should == '1580'
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should set the exploration progress' do
|
58
|
+
subject.progress[:exploration].should == '0'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should set the custom game progress' do
|
62
|
+
subject.progress[:custom_game].should == '1280'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should set the cooperative progress' do
|
66
|
+
subject.progress[:cooperative].should == '120'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should set the quick match progress' do
|
70
|
+
subject.progress[:quick_match].should == '220'
|
71
|
+
end
|
72
|
+
end
|
91
73
|
end
|
92
74
|
end
|
93
75
|
|
94
76
|
describe '#output' do
|
95
77
|
it 'should return the scraped data when scrape has been called' do
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
78
|
+
VCR.use_cassette('demon_achievements') do
|
79
|
+
subject.scrape
|
80
|
+
expected = {
|
81
|
+
recent: subject.recent,
|
82
|
+
showcase: subject.showcase,
|
83
|
+
progress: subject.progress
|
84
|
+
}
|
85
|
+
subject.output.should == expected
|
86
|
+
end
|
103
87
|
end
|
104
88
|
end
|
105
89
|
end
|