Commit 7a274122 authored by Francis's avatar Francis
Browse files

Updated WoW profile endpoints and automated tests

parent 421c9985
inherit_from: .rubocop_todo.yml
Metrics/LineLength:
Max: 120
Max: 140
Metrics/ModuleLength:
Exclude:
......
Please view this file on the master branch, otherwise it may be outdated
**Version 0.2.5**
* Added two unreleased endpoints for character profile(`raid_progression` and `collections`).
* Added new WoW profile endpoints
* Added missing profile automated tests
**Version 0.2.4**
* Added new WoW profile endpoints: #2 https://us.battle.net/forums/en/bnet/topic/20772457051
* Added support for HearthStone: !1 (Thanks Bradyn Glines for implementing this)
......
PATH
remote: .
specs:
blizzard_api (0.2.3)
blizzard_api (0.2.5)
redis (~> 4.1, >= 4.1.0)
GEM
......
......@@ -88,8 +88,6 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
- index
- categories
- category :id
- character_achievement_index
- guild_achievement_index
- media :id
* Blizzard::Wow::ConnectedRealm
- index
......@@ -168,6 +166,7 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
- index
- get :id
- complete
- status :realms
* Blizzard::Wow::Region
- index
- get :id
......@@ -187,9 +186,11 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
- classes
- class :id
- subclass :class_id, :subclass_id
- media :id
* Blizzard::Wow::AzeriteEssence
- index
- get :id
- media :id
* Blizzard::Wow::Auction
- get :realm
......@@ -199,10 +200,6 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
* Blizzard::Wow::Challenge
- realm_index
- region_index
* Blizzard::Wow::Character
- get :realm, :character, :fields
- get_keystone_profile :realm, :character, :user_token, :season
- get_user_characters :user_token
* Blizzard::Wow::Guild
- get :relam, :name, :fields
- rewards
......@@ -219,11 +216,24 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
- index
- get :id
* BlizzardApi::Wow::CharacterProfile
- get_keystone_profile :realm, :character, :user_token, :season
- get_user_characters :user_token
- get :realm, :character, :fields
- pvp_summmary :realm, :character, :user_token
- pvp_bracket :realm, :character, :bracket, :user_token
- achievements :realm, :character
- appearance :realm, :character
- equipment :realm, :character
- media :realm, :character
- pvp_bracket :realm, :character, :bracket
- pvp_summary :realm, :character
- specializations :realm, :character
- statistics :realm, :character
- titles :realm, :character
- mythic_keystone_profile :realm, :character
- mythic_keystone_seasons :realm, :character
- collections :realm, :character (Not active yet on Blizzard servers)
- raid_progression :realm, :character (Not active yet on Blizzard servers)
### 4.2. Diablo III endpoints
......
......@@ -2,5 +2,5 @@
module BlizzardApi
# Gem version
VERSION = '0.2.4'
VERSION = '0.2.5'
end
......@@ -173,7 +173,6 @@ module BlizzardApi
require_relative 'wow/community/auction'
require_relative 'wow/community/boss'
require_relative 'wow/community/challenge'
require_relative 'wow/community/character'
require_relative 'wow/community/pvp'
require_relative 'wow/community/quest'
require_relative 'wow/community/recipe'
......
# frozen_string_literal: true
module BlizzardApi
module Wow
##
# This class allows access to World of Warcraft character data
#
# @see https://develop.battle.net/documentation/api-reference/world-of-warcraft-community-api
#
# You can get an instance of this class using the default region as follows:
# api_instance = BlizzardApi::Wow.character
class Character < Wow::Request
# Valid fields for character profile requests
VALID_FIELDS = %w[
achievements
appearance
feed
guild
hunterPets
items
mounts
pets
petSlots
professions
progression
pvp
quests
reputation
statistics
stats
talents
titles
audit
].freeze
##
# Helper method for checking valid fields. Use this to validate an array of fields if you are not sure about their
# names.
#
# @param fields [Array<String>] Array containing desired fields to include
#
# @raise ArgumentError
def validate_fields(fields)
fields.each do |field|
raise ArgumentError, "Unrecognized field #{field}" unless VALID_FIELDS.include? field
end
end
##
# Return data about the specified char
#
# @param realm [String] The character realm's slug
# @param character [String] The character name
# @param fields [Array<String>] An array containing all the fields you want to be included in the response.
# @!macro request_options
#
# @!macro response
def get(realm, character, fields = [], options = {})
validate_fields fields if options.include? :validate_fields
opts = { ttl: CACHE_DAY, fields: fields.join(',') }.merge(options)
api_request "#{base_url(:community)}/character/#{CGI.escape(realm)}/#{CGI.escape(character)}", opts
end
##
# Return a list containing all WoW characters of a BNet account
#
# @note This endpoint requires a user token obtained through the user authorization flow
# @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
#
# @param user_token [String] A token obtained by the authorization flow. See link below.
# @!macro request_options
#
# @!macro response
def get_user_characters(user_token, options = {})
opts = { ttl: CACHE_HOUR, access_token: user_token }.merge(options)
api_request "#{base_url(:community)}/user/characters", opts
end
end
end
end
......@@ -54,30 +54,6 @@ module BlizzardApi
api_request "#{endpoint_uri('category')}/#{id}", default_options.merge(options)
end
##
# Return a list of possible character achievements.
# This endpoint uses a community endpoint. It is recommended to use the new data endpoint using {#index}.
# @see https://us.battle.net/forums/en/bnet/topic/20771546990
#
# @!macro request_options
#
# @!macro response
def character_achievement_index(options = {})
api_request "#{base_url(:community)}/data/character/achievements", { ttl: CACHE_TRIMESTER }.merge(options)
end
##
# Return a list of possible guild achievements
# This endpoint uses a community endpoint. It is recommended to use the new data endpoint using {#index}.
# @see https://us.battle.net/forums/en/bnet/topic/20771546990
#
# @!macro request_options
#
# @!macro response
def guild_achievement_index(options = {})
api_request "#{base_url(:community)}/data/guild/achievements", { ttl: CACHE_TRIMESTER }.merge(options)
end
##
# Fetch media assets for the specified achievement
#
......
......@@ -10,6 +10,18 @@ module BlizzardApi
# You can get an instance of this class using the default region as follows:
# api_instance = BlizzardApi::Wow.azerite_essence
class AzeriteEssence < Wow::GenericDataEndpoint
##
# Fetch media for one of the azerite essences listed by the {#index} using its *id*
#
# @param id [Integer] Azerite essence id
#
# @!macro request_options
#
# @!macro response
def media(id, options = {})
api_request "#{base_url(:media)}/azerite-essence/#{id}", default_options.merge(options)
end
protected
def endpoint_setup
......
......@@ -12,7 +12,8 @@ module BlizzardApi
# api_instance = BlizzardApi::Wow.guild
class Guild < Wow::Request
# Valid fields for guild profile request
VALID_FIELDS = %w[achievements challenge members news].freeze
VALID_FIELDS = %w[achievements achievementsCompleted achievementsCompletedTimestamp criteria criteriaCreated
criteriaQuantity criteriaTimestamp challenge members news].freeze
##
# Helper method for checking valid fields. Use this to validate an array of fields if you are not sure about their
......@@ -84,11 +85,16 @@ module BlizzardApi
#
# @param realm [String] The guild realm's slug
# @param guild [String] The guild's name
#
# @!macro request_options
# @option options [Boolean] :use_community_endpoint If set to true, this method will call the community endpoint
# instead of the data endpoint https://develop.battle.net/documentation/api-reference/world-of-warcraft-community-api
#
# @!macro response
def achievements(realm, guild, options = {})
if options.include? :use_community_endpoint
return api_request "#{base_url(:community)}/data/guild/achievements", { ttl: CACHE_TRIMESTER }.merge(options)
end
guild_request realm, guild, options, 'achievements'
end
......
......@@ -91,6 +91,18 @@ module BlizzardApi
api_request "#{endpoint_uri('class')}/#{id}/item-subclass/#{subclass_id}", default_options.merge(options)
end
##
# Fetch media for an item using its *id*
#
# @param id [Integer] Item id
#
# @!macro request_options
#
# @!macro response
def media(id, options = {})
api_request "#{base_url(:media)}/item/#{id}", default_options.merge(options)
end
protected
def endpoint_setup
......
......@@ -25,7 +25,7 @@ module BlizzardApi
#
# @!macro response
def dungeons(options = {})
api_request "#{endpoint_uri}/period/index", default_options.merge(options)
api_request "#{endpoint_uri}/dungeon/index", default_options.merge(options)
end
##
......
......@@ -14,10 +14,12 @@ module BlizzardApi
# This method is actually located at the community scope, but included here because of its relevance
# @see https://develop.battle.net/documentation/api-reference/world-of-warcraft-community-api
#
# @param realms [Array<String>] An optional list of realm-slugs to filter results
# @!macro request_options
#
# @!macro response
def status(options = {})
def status(realms = [], options = {})
options[:realms] = realms.map(&:string_to_slug).join(',') if realms.count.positive?
api_request "#{base_url(:community)}/realm/status", { ttl: CACHE_MINUTE }.merge(options)
end
......
......@@ -10,6 +10,79 @@ module BlizzardApi
# You can get an instance of this class using the default region as follows:
# api_instance = BlizzardApi::Wow.achievement
class CharacterProfile < Wow::Request
# Valid fields for character profile requests
VALID_FIELDS = %w[
achievements
appearance
feed
guild
hunterPets
items
mounts
pets
petSlots
professions
progression
pvp
quests
reputation
statistics
stats
talents
titles
audit
].freeze
##
# Helper method for checking valid fields. Use this to validate an array of fields if you are not sure about their
# names.
#
# @param fields [Array<String>] Array containing desired fields to include
#
# @raise ArgumentError
def validate_fields(fields)
fields.each do |field|
raise ArgumentError, "Unrecognized field #{field}" unless VALID_FIELDS.include? field
end
end
##
# Return a list containing all WoW characters of a BNet account
#
# @note This endpoint requires a user token obtained through the user authorization flow
# @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
#
# @param user_token [String] A token obtained by the authorization flow. See link below.
# @!macro request_options
#
# @!macro response
def get_user_characters(user_token, options = {})
opts = { ttl: CACHE_HOUR, access_token: user_token }.merge(options)
api_request "#{base_url(:community)}/user/characters", opts
end
##
# Return character achievements
#
# @see https://develop.battle.net/documentation/api-reference/world-of-warcraft-profile-api
#
# @param realm [String] The character realm's slug
# @param character [String] The character name
# @param fields [Array<String>] An array containing all the fields you want to be included in the response. Only
# used for community endpoint.
# @!macro request_options
# @option options [Boolean] :use_community_endpoint If set to true, this method will call the community endpoint
# instead of the data endpoint https://develop.battle.net/documentation/api-reference/world-of-warcraft-community-api
#
# @!macro response
def get(realm, character, fields = [], options = {})
return character_request realm, character, options unless options.include? :use_community_endpoint
validate_fields fields if options.include? :validate_fields
opts = { ttl: CACHE_DAY, fields: fields.join(',') }.merge(options)
api_request "#{base_url(:community)}/character/#{CGI.escape(realm)}/#{CGI.escape(character)}", opts
end
##
# Return character achievements
#
......@@ -18,10 +91,14 @@ module BlizzardApi
# @param realm [String] The character realm's slug
# @param character [String] The character name
# @!macro request_options
# @option options [Boolean] :use_community_endpoint If set to true, this method will call the community endpoint
# instead of the data endpoint https://develop.battle.net/documentation/api-reference/world-of-warcraft-community-api
#
# @!macro response
def achievements(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/achievements", default_options.merge(options)
return character_request realm, character, options, 'achievements' unless options.include? :use_community_endpoint
api_request "#{base_url(:community)}/data/guild/achievements", { ttl: CACHE_TRIMESTER }.merge(options)
end
##
......@@ -35,7 +112,7 @@ module BlizzardApi
#
# @!macro response
def appearance(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/appearance", default_options.merge(options)
character_request realm, character, options, 'appearance'
end
##
......@@ -49,7 +126,7 @@ module BlizzardApi
#
# @!macro response
def equipment(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/equipment", default_options.merge(options)
character_request realm, character, options, 'equipment'
end
##
......@@ -63,7 +140,7 @@ module BlizzardApi
#
# @!macro response
def media(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/character-media", default_options.merge(options)
character_request realm, character, options, 'character-media'
end
##
......@@ -78,7 +155,7 @@ module BlizzardApi
#
# @!macro response
def pvp_bracket(realm, character, bracket, options = {})
api_request "#{endpoint_uri(realm, character)}/pvp-bracket/#{bracket}", default_options.merge(options)
character_request realm, character, options, "pvp-bracket/#{bracket}"
end
##
......@@ -92,7 +169,7 @@ module BlizzardApi
#
# @!macro response
def pvp_summary(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/pvp-summary", default_options.merge(options)
character_request realm, character, options, 'pvp-summary'
end
##
......@@ -106,7 +183,7 @@ module BlizzardApi
#
# @!macro response
def specializations(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/specializations", default_options.merge(options)
character_request realm, character, options, 'specializations'
end
##
......@@ -120,7 +197,7 @@ module BlizzardApi
#
# @!macro response
def statistics(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/statistics", default_options.merge(options)
character_request realm, character, options, 'statistics'
end
##
......@@ -134,7 +211,7 @@ module BlizzardApi
#
# @!macro response
def titles(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/titles", default_options.merge(options)
character_request realm, character, options, 'titles'
end
##
......@@ -147,8 +224,8 @@ module BlizzardApi
# @!macro request_options
#
# @!macro response
def keystone_profile(realm, character, options = {})
api_request "#{endpoint_uri(realm, character)}/mythic-keystone-profile", default_options.merge(options)
def mythic_keystone_profile(realm, character, options = {})
character_request realm, character, options, 'mythic-keystone-profile'
end
##
......@@ -162,9 +239,36 @@ module BlizzardApi
# @!macro request_options
#
# @!macro response
def keystone_season_details(realm, character, season = nil, options = {})
api_request api_request "#{endpoint_uri(realm, character)}/mythic-keystone-profile/season/#{season}",
default_options.merge(options)
def mythic_keystone_seasons(realm, character, season = nil, options = {})
character_request realm, character, options, "mythic-keystone-profile/season/#{season}"
end
##
# Return a character's collections
#
# @see https://develop.battle.net/documentation/api-reference/world-of-warcraft-profile-api
#
# @param realm [String] The character realm's slug
# @param character [String] The character name
# @!macro request_options
#
# @!macro response
def collections(realm, character, options = {})
character_request realm, character, options, 'collections'
end
##
# Return a character's raid progression
#
# @see https://develop.battle.net/documentation/api-reference/world-of-warcraft-profile-api
#
# @param realm [String] The character realm's slug
# @param character [String] The character name
# @!macro request_options
#
# @!macro response
def raid_progression(realm, character, options = {})
character_request realm, character, options, 'raid-progression'
end
private
......@@ -175,8 +279,10 @@ module BlizzardApi
opts
end
def endpoint_uri(realm, character)
"#{base_url(:profile)}/character/#{CGI.escape(realm)}/#{CGI.escape(character)}"
def character_request(realm, character, options = {}, variant = nil)
uri = "#{base_url(:profile)}/character/#{CGI.escape(realm.downcase)}/#{CGI.escape(character.downcase)}"
uri += "/#{variant}" if variant
api_request uri, default_options.merge(options)
end
end
end
......
# frozen_string_literal: true
require 'test_helper'
module BlizzardApi
module Wow
class CharacterTest < Minitest::Test
def test_character_get
character = BlizzardApi::Wow::Character.new
character_data = character.get 'azralon', 'Schiller', ['titles']
assert_equal 11, character_data[:class]
end
end
end
end
......@@ -8,7 +8,7 @@ module BlizzardApi
def test_achievement_index
achievement = BlizzardApi::Wow::Achievement.new
achievement_data = achievement.index
assert_equal 5028, achievement_data[:achievements].count
assert_equal 5029, achievement_data[:achievements].count
end
def test_achievement_get
......@@ -20,18 +20,6 @@ module BlizzardApi
assert_equal 50, achievement_data[:points]
end
def test_character_achievement_index
achievement = BlizzardApi::Wow::Achievement.new
achievement_data = achievement.character_achievement_index
assert_equal 92, achievement_data[:achievements][0][:id]
end
def test_guild_achievement_index
achievement = BlizzardApi::Wow::Achievement.new
achievement_data = achievement.guild_achievement_index
assert_equal 15_088, achievement_data[:achievements][0][:id]
end
def test_achievement_complete
assert_raises BlizzardApi::ApiException do
achievement = BlizzardApi::Wow::Achievement.new
......
......@@ -18,6 +18,11 @@ module BlizzardApi
title_data = @azerite_essence.get 2