bnet_scraper 0.3.1 → 0.4.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 +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
|