continue to backport old code

This commit is contained in:
2021-04-24 00:24:05 +02:00
parent 5d7217f355
commit 04434760c5
72 changed files with 795 additions and 78 deletions

View File

@@ -32,7 +32,7 @@ gem 'mobility', '~> 1.1.1'
# Omniauth Strategy for Battle.net OAuth Login. For more info visit https://dev.battle.net
gem 'omniauth-bnet', '~> 2.0.0'
# This gem provides a mitigation against CVE-2015-9284
# gem 'omniauth-rails_csrf_protection', '~> 0.1.2'
gem 'omniauth-rails_csrf_protection', '~> 0.1.2'
# A Ruby wrapper around Blizzard's Game Data and Profile APIs
gem 'rbattlenet', '~> 2.2.4', git: 'https://github.com/Dainii/rbattlenet'
# A gem that provides Rails integration for the Sentry error logger

View File

@@ -179,6 +179,9 @@ GEM
omniauth-oauth2 (1.7.1)
oauth2 (~> 1.4)
omniauth (>= 1.9, < 3)
omniauth-rails_csrf_protection (0.1.2)
actionpack (>= 4.2)
omniauth (>= 1.3.1)
orm_adapter (0.5.0)
parallel (1.20.1)
parser (3.0.1.0)
@@ -390,6 +393,7 @@ DEPENDENCIES
lograge (~> 0.11.2)
mobility (~> 1.1.1)
omniauth-bnet (~> 2.0.0)
omniauth-rails_csrf_protection (~> 0.1.2)
pg (~> 1.1)
pry-rails (~> 0.3.9)
puma (~> 5.0)

View File

@@ -0,0 +1,3 @@
// Place all the styles related to the wow_mounts controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/

View File

@@ -0,0 +1,3 @@
// Place all the styles related to the wow_pets controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/

View File

@@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base
around_action :switch_locale
def switch_locale(&action)
locale = I18n.default_locale
locale = I18n.locale_available?(request.headers['Locale']) ? request.headers['Locale'] : I18n.default_locale
I18n.with_locale(locale, &action)
end

View File

@@ -11,6 +11,9 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
WowCharactersWorker.perform_async(@user.id)
WowMountsCollectionWorker.perform_async(@user.id)
WowPetsCollectionWorker.perform_async(@user.id)
set_flash_message(:notice, :success, kind: 'Bnet') if is_navigational_format?
else
session['devise.bnet_data'] = request.env['omniauth.auth'].except(:extra)

View File

@@ -1,5 +1,9 @@
class WowCharactersController < ProtectedController
def index
@characters = current_user.wow_characters.all
@wow_characters = current_user.wow_characters.all
end
def show
@wow_character = current_user.wow_characters.find(params[:id])
end
end

View File

@@ -0,0 +1,9 @@
class WowMountsController < ProtectedController
def index
@wow_mounts = WowMount.all
end
def show
@wow_mount = WowMount.find(params[:id])
end
end

View File

@@ -0,0 +1,9 @@
class WowPetsController < ProtectedController
def index
@wow_pets = WowPet.all
end
def show
@wow_pet = WowPet.find(params[:id])
end
end

View File

@@ -0,0 +1,2 @@
module WowMountsHelper
end

View File

@@ -0,0 +1,2 @@
module WowPetsHelper
end

View File

@@ -0,0 +1,4 @@
class LearnedWowPetAbility < ApplicationRecord
belongs_to :wow_pet
belongs_to :wow_pet_ability
end

View File

@@ -8,6 +8,10 @@ class User < ApplicationRecord
devise :rememberable, :omniauthable, omniauth_providers: [:bnet]
has_many :wow_characters, dependent: :destroy
has_many :user_obtain_wow_mounts, dependent: :destroy
has_many :wow_mounts, through: :user_obtain_wow_mounts
has_many :user_obtain_wow_pets, dependent: :destroy
has_many :wow_pets, through: :user_obtain_wow_pets
validates :battletag, presence: true, uniqueness: true
@@ -28,8 +32,8 @@ class User < ApplicationRecord
def self.new_with_session(params, session)
super.tap do |user|
if (data = session['devise.bnet_data']) && session['devise.bnet_data']['extra']['raw_info']
user.email = data['email'] if user.email.blank?
if (data = session['devise.bnet_data']) && session['devise.bnet_data']['extra']['raw_info'] && user.email.blank?
user.email = data['email']
end
end
end

View File

@@ -0,0 +1,4 @@
class UserObtainWowMount < ApplicationRecord
belongs_to :user
belongs_to :wow_mount
end

View File

@@ -0,0 +1,4 @@
class UserObtainWowPet < ApplicationRecord
belongs_to :user
belongs_to :wow_pet
end

View File

@@ -11,4 +11,35 @@ class WowCharacter < ApplicationRecord
validates :name, presence: true
validates :character_id, presence: true, uniqueness: true
def gender_class_name
case gender
when 'FEMALE'
wow_class.female_name
when 'MALE'
wow_class.male_name
end
end
def gender_race_name
case gender
when 'FEMALE'
wow_race.female_name
when 'MALE'
wow_race.male_name
end
end
def title_name
if wow_character_title
case gender
when 'FEMALE'
wow_character_title.female_name.gsub('{name}', name)
when 'MALE'
wow_character_title.male_name.gsub('{name}', name)
end
else
name
end
end
end

10
app/models/wow_mount.rb Normal file
View File

@@ -0,0 +1,10 @@
class WowMount < ApplicationRecord
extend Mobility
translates :name, :description, :translated_faction, :translated_source
has_many :user_obtain_mounts, dependent: :destroy
has_many :users, through: :user_obtain_mounts
validates :name, presence: true
validates :mount_id, presence: true, uniqueness: true
end

10
app/models/wow_pet.rb Normal file
View File

@@ -0,0 +1,10 @@
class WowPet < ApplicationRecord
extend Mobility
translates :name, :translated_battle_pet_type, :description, :translated_source_type
has_many :learned_wow_pet_abilities, dependent: :destroy
has_many :wow_pet_abilities, through: :learned_wow_pet_abilities
validates :name, presence: true
validates :pet_id, presence: true, uniqueness: true
end

View File

@@ -0,0 +1,10 @@
class WowPetAbility < ApplicationRecord
extend Mobility
translates :name, :translated_battle_pet_type
has_many :learned_pet_abilities, dependent: :destroy
has_many :wow_pets, through: :learned_pet_abilities
validates :name, presence: true
validates :ability_id, presence: true, uniqueness: true
end

View File

@@ -1,2 +1,5 @@
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<% if user_signed_in? %>
<h1>Welcome <%= current_user.battletag %></h1>
<% else %>
<h1>Welcome guest</h1>
<% end %>

View File

@@ -1,24 +1,33 @@
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-dark">
<nav class="navbar navbar-dark navbar-expand-lg bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Northwhale 2</a>
<a class="navbar-brand" href="<%= root_path %>">Northwhale 2</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="nav navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item">
<% if user_signed_in? %>
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="<%= wow_characters_path %>">Characters</a>
</li>
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="<%= wow_mounts_path %>">Mounts</a>
</li>
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="<%= wow_pets_path %>">Pets</a>
</li>
</ul>
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Menu
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li>Bnet: <%= current_user.battletag %></li>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li class="dropdown-item disabled" >Bnet:<%= current_user.battletag %></li>
<li><hr class="dropdown-divider"></li>
<li><%= link_to '<i class="fas fa-sign-out-alt"></i>'.html_safe, destroy_user_session_path, method: :delete %></li>
<li><%= link_to '<i class="fas fa-sign-out-alt"></i>'.html_safe, destroy_user_session_path, method: :delete, class: "dropdown-item" %></li>
</ul>
</li>
<% else %>
<%= link_to 'Sign in with <i class="fab fa-battle-net"></i>'.html_safe, user_bnet_omniauth_authorize_path, method: :post, class: "btn btn-primary" %>
<%= link_to 'Sign in with <i class="fab fa-battle-net"></i>'.html_safe, user_bnet_omniauth_authorize_path, method: :post, class: "btn btn-primary nav-item" %>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -15,6 +15,8 @@
<%= render 'layouts/navbar' %>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<div class="container-fluid">
<%= yield %>
</div>
</body>
</html>

View File

@@ -4,26 +4,26 @@
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Name</th>
<th scope="col">Gender</th>
<th scope="col">Realm</th>
<th scope="col">Race</th>
<th scope="col">Class</th>
<th scope="col">Faction</th>
<th scope="col">Level</th>
<th scope="col"><%= t('character_list.name') %></th>
<th scope="col"><%= t('character_list.gender') %></th>
<th scope="col"><%= t('character_list.realm') %></th>
<th scope="col"><%= t('character_list.race') %></th>
<th scope="col"><%= t('character_list.class') %></th>
<th scope="col"><%= t('character_list.faction') %></th>
<th scope="col"><%= t('character_list.level') %></th>
</tr>
</thead>
<tbody>
<% @characters.each do |character| %>
<% @wow_characters.each do |character| %>
<tr>
<td><% if character.wow_character_medium %>
<img class="rounded-circle border border-white" src=<%= character.wow_character_medium.avatar %> alt="avatar">
<% end %></td>
<td><%= character.name %></td>
<td><%= link_to character.name, character %></td>
<td><%= character.translated_gender %></td>
<td><%= character.wow_realm.name %></td>
<td><%= %></td>
<td><%= %></td>
<td><%= character.gender_race_name %></td>
<td><%= character.gender_class_name %></td>
<td><%= character.translated_faction %></td>
<td><%= character.level %></td>
</tr>

View File

@@ -0,0 +1,19 @@
<div class="row">
<div class="col-5">
<% if @wow_character.wow_character_medium %>
<img src=<%= @wow_character.wow_character_medium.main_raw %> class="card-img-top" alt="character-main-image">
<% end %>
<div class="card">
<div class="card-body">
<h5 class="card-title"><%= @wow_character.title_name %></h5>
<p class="card-text"><%= @wow_character.gender_race_name %></p>
<p class="card-text"><%= @wow_character.gender_class_name %></p>
<p class="card-text"><%= @wow_character.last_login_timestamp %></p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
<div class="col-7">
Post du perso
</div>
</div>

View File

@@ -0,0 +1,20 @@
<h2>Mount list</h2>
<table class="table table-hover table-dark table-image">
<thead>
<tr>
<th scope="col"><%= t('mount_list.name') %></th>
<th scope="col"><%= t('mount_list.description') %></th>
<th scope="col"><%= t('mount_list.owned') %></th>
</tr>
</thead>
<tbody>
<% @wow_mounts.each do |mount| %>
<tr>
<td><%= link_to mount.name, mount %></td>
<td><%= mount.description %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -0,0 +1,17 @@
<div class="row">
<div class="col-5">
<div class="card">
<% if @wow_mount.asset_zoom %>
<img src=<%= @wow_mount.asset_zoom %> class="card-img-top" alt="mount-zoom-image">
<% end %>
<div class="card-body">
<h5 class="card-title"><%= @wow_mount.name %></h5>
<p class="card-text">Description: <%= @wow_mount.description %></p>
<p class="card-text">Owned: </p>
</div>
</div>
</div>
<div class="col-7">
<h1>Suite de la page de la monture</h1>
</div>
</div>

View File

@@ -0,0 +1,20 @@
<h2>Pet list</h2>
<table class="table table-hover table-dark table-image">
<thead>
<tr>
<th scope="col"><%= t('pet_list.name') %></th>
<th scope="col"><%= t('pet_list.description') %></th>
<th scope="col"><%= t('pet_list.owned') %></th>
</tr>
</thead>
<tbody>
<% @wow_pets.each do |pet| %>
<tr>
<td><%= link_to pet.name, pet %></td>
<td><%= pet.description %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -0,0 +1,19 @@
<div class="row">
<div class="col-5">
<div class="card">
<% if @wow_pet.icon %>
<img src=<%= @wow_pet.icon %> class="card-img-top" alt="pet-icon-image">
<% end %>
<div class="card-body">
<h5 class="card-title"><%= @wow_pet.name %></h5>
<p class="card-text">Description: <%= @wow_pet.description %></p>
<% @wow_pet.wow_pet_abilities.each do |ability| %>
<p>Ability: <%= ability.name %></p>
<% end %>
</div>
</div>
</div>
<div class="col-7">
<h1>Suite de la page du pet</h1>
</div>
</div>

View File

@@ -0,0 +1,33 @@
class WowMountDetailWorker < WowSidekiqWorker
def locales
super
end
def perform(mount_id)
return unless (mount = WowMount.where(mount_id: mount_id).first)
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Mount.find(mount_id)
return unless result.status_code == 200
mount.faction = result.faction.type if result.faction
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) do
mount.translated_faction = result.faction.name[locale[1]] if result.faction
mount.description = result.description[locale[1]]
end
end
if result.creature_displays.first
mount.creature_display_id = result.creature_displays.first.id
media = RBattlenet::Wow::CreatureMedia.find(result.creature_displays.first.id)
mount.asset_zoom = media.assets.find { |asset| asset['key'] == 'zoom' }.value || nil
end
mount.save
end
end

View File

@@ -0,0 +1,19 @@
class WowMountsCollectionWorker
include Sidekiq::Worker
def perform(user_id)
# Update the WoW character list
return unless (user = User.find(user_id))
RBattlenet.set_options(locale: 'en_US')
result = RBattlenet::Wow::Profile::MountsCollection.find(user.token)
return unless result.status_code == 200
result.mounts.each do |mount|
next unless (local_mount = WowMount.where(mount_id: mount.mount.id).first)
UserObtainWowMount.where(user: user.id, wow_mount: local_mount.id).first_or_create
end
end
end

View File

@@ -0,0 +1,30 @@
class WowMountsWorker < WowSidekiqWorker
def locales
super
end
def perform
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Mount.all
return unless result.status_code == 200
result.mounts.each do |mount|
wow_mount = WowMount.where(mount_id: mount.id).first_or_initialize
# Global data
wow_mount.mount_id = mount.id
wow_mount.href = mount.key.href
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_mount.name = mount.name[locale[1]] }
end
wow_mount.save
WowMountDetailWorker.perform_async(wow_mount.mount_id) if wow_mount.persisted?
end
end
end

View File

@@ -0,0 +1,30 @@
class WowPetAbilitiesWorker < WowSidekiqWorker
def locales
super
end
def perform
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::PetAbility.all
return unless result.status_code == 200
result.abilities.each do |ability|
wow_pet_ability = WowPetAbility.where(ability_id: ability.id).first_or_initialize
# Global data
wow_pet_ability.ability_id = ability.id
wow_pet_ability.href = ability.key.href
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_pet_ability.name = ability.name[locale[1]] }
end
wow_pet_ability.save
WowPetAbilityDetailWorker.perform_async(wow_pet_ability.ability_id) if wow_pet_ability.persisted?
end
end
end

View File

@@ -0,0 +1,33 @@
class WowPetAbilityDetailWorker < WowSidekiqWorker
def locales
super
end
def perform(ability_id)
return unless (ability = WowPetAbility.where(ability_id: ability_id).first)
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::PetAbility.find(ability_id)
return unless result.status_code == 200
ability.battle_pet_type = result.battle_pet_type.type
ability.battle_pet_type_id = result.battle_pet_type.id
ability.rounds = result.rounds if result.rounds
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) do
ability.translated_battle_pet_type = result.battle_pet_type.name[locale[1]]
end
end
if result.media
media = RBattlenet::Wow::PetAbilityMedia.find(result.media.id)
ability.media = media.assets.find { |asset| asset['key'] == 'icon' }.value || nil
end
ability.save
end
end

View File

@@ -0,0 +1,44 @@
class WowPetDetailWorker < WowSidekiqWorker
def locales
super
end
def perform(pet_id)
return unless (pet = WowPet.where(pet_id: pet_id).first)
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Pet.find(pet_id)
return unless result.status_code == 200
pet.is_capturable = result.is_capturable
pet.is_battlepet = result.is_battlepet
pet.is_alliance_only = result.is_alliance_only
pet.is_horde_only = result.is_horde_only
pet.is_capturable = result.is_capturable
pet.is_random_creature_display = result.is_random_creature_display
pet.icon = result.icon
pet.creature_id = result.creature.id
pet.battle_pet_type = result.battle_pet_type.type
pet.battle_pet_type_id = result.battle_pet_type.id
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) do
pet.translated_battle_pet_type = result.battle_pet_type.name[locale[1]]
pet.description = result.description[locale[1]]
end
end
if result.abilities
result.abilities.each do |ability|
next unless (local_ability = WowPetAbility.where(ability_id: ability.ability.id).first)
LearnedWowPetAbility.where(wow_pet: pet.id, wow_pet_ability: local_ability.id).first_or_create
end
end
pet.save
end
end

View File

@@ -0,0 +1,18 @@
class WowPetsCollectionWorker
include Sidekiq::Worker
def perform(user_id)
return unless (user = User.find(user_id))
RBattlenet.set_options(locale: 'en_US')
result = RBattlenet::Wow::Profile::PetsCollection.find(user.token)
return unless result.status_code == 200
result.pets.each do |pet|
next unless (local_pet = WowPet.where(pet_id: pet.species.id).first)
UserObtainWowPet.where(user: user.id, wow_pet: local_pet.id).first_or_create
end
end
end

View File

@@ -0,0 +1,30 @@
class WowPetsWorker < WowSidekiqWorker
def locales
super
end
def perform
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Pet.all
return unless result.status_code == 200
result.pets.each do |pet|
wow_pet = WowPet.where(pet_id: pet.id).first_or_initialize
# Global data
wow_pet.pet_id = pet.id
wow_pet.href = pet.key.href
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_pet.name = pet.name[locale[1]] }
end
wow_pet.save
WowPetDetailWorker.perform_async(wow_pet.pet_id) if wow_pet.persisted?
end
end
end

View File

@@ -0,0 +1,20 @@
class WowSidekiqWorker
include Sidekiq::Worker
def locales
[
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
end
end

View File

@@ -1,6 +1,6 @@
# This file is used by Rack-based servers to start the application.
require_relative "config/environment"
require_relative 'config/environment'
run Rails.application
Rails.application.load_server

View File

@@ -23,5 +23,6 @@ module Northwhale2
config.autoload_paths << "#{Rails.root}/app/workers"
config.i18n.default_locale = 'en-gb'
config.i18n.available_locales = ['de-de', 'en-gb', 'en-us', 'es-mx', 'pt-br', 'es-es', 'fr-fr', 'it', 'ru-ru', 'ko', 'zh-tw', 'zh-cn']
config.i18n.fallbacks.map = { 'fr-fr': :'fr-ch' }
end
end

View File

@@ -1,6 +1,6 @@
# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
en:
en-gb:
devise:
confirmations:
confirmed: "Your email address has been successfully confirmed."

View File

@@ -29,5 +29,20 @@
# To learn more, please read the Rails Internationalization guide
# available at https://guides.rubyonrails.org/i18n.html.
en:
hello: "Hello world"
en-gb:
character_list:
name: "Name"
gender: "Gender"
realm: "Realm"
race: "Race"
class: "Class"
faction: "Faction"
level: "Level"
mount_list:
name: "Name"
description: "Description"
owned: "Owned"
pet_list:
name: "Name"
description: "Description"
owned: "Owned"

View File

@@ -4,10 +4,12 @@ Rails.application.routes.draw do
get 'home/index'
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
devise_scope :user do
get 'sign_in', :to => 'devise/sessions#new', :as => :new_user_session
get 'sign_in', :to => 'home#index', :as => :new_user_session
delete 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
end
root to: "home#index"
mount Sidekiq::Web => '/sidekiq'
resources :wow_characters, path: '/wow-characters', only: [:index, :show]
resources :wow_characters, only: [:index, :show]
resources :wow_mounts, only: [:index, :show]
resources :wow_pets, only: [:index, :show]
end

View File

@@ -0,0 +1,20 @@
class CreateWowMounts < ActiveRecord::Migration[6.1]
def change
create_table :wow_mounts do |t|
t.jsonb :name
t.string :source_type
t.jsonb :translated_source
t.string :faction
t.jsonb :translated_faction
t.jsonb :description
t.integer :mount_id, null: false
t.integer :creature_display_id
t.string :href
t.string :asset_zoom
t.timestamps
end
add_index :wow_mounts, :mount_id, unique: true
end
end

View File

@@ -0,0 +1,9 @@
class CreateUserObtainWowMounts < ActiveRecord::Migration[6.1]
def change
create_table :user_obtain_wow_mounts do |t|
t.belongs_to :user
t.belongs_to :wow_mount
t.timestamps
end
end
end

View File

@@ -0,0 +1,18 @@
class CreateWowPetAbilities < ActiveRecord::Migration[6.1]
def change
create_table :wow_pet_abilities do |t|
t.integer :ability_id
t.jsonb :name
t.string :battle_pet_type
t.jsonb :translated_battle_pet_type
t.integer :battle_pet_type_id
t.integer :rounds
t.string :media
t.string :href
t.timestamps
end
add_index :wow_pet_abilities, :ability_id, unique: true
end
end

View File

@@ -0,0 +1,27 @@
class CreateWowPets < ActiveRecord::Migration[6.1]
def change
create_table :wow_pets do |t|
t.jsonb :name
t.integer :pet_id
t.string :href
t.string :battle_pet_type
t.jsonb :translated_battle_pet_type
t.integer :battle_pet_type_id
t.jsonb :description
t.boolean :is_capturable
t.boolean :is_tradable
t.boolean :is_battlepet
t.boolean :is_alliance_only
t.boolean :is_horde_only
t.string :icon
t.boolean :is_random_creature_display
t.string :source_type
t.jsonb :translated_source_type
t.integer :creature_id
t.timestamps
end
add_index :wow_pets, :pet_id, unique: true
end
end

View File

@@ -0,0 +1,9 @@
class CreateLearnedWowPetAbilities < ActiveRecord::Migration[6.1]
def change
create_table :learned_wow_pet_abilities do |t|
t.belongs_to :wow_pet
t.belongs_to :wow_pet_ability
t.timestamps
end
end
end

View File

@@ -0,0 +1,9 @@
class CreateUserObtainWowPets < ActiveRecord::Migration[6.1]
def change
create_table :user_obtain_wow_pets do |t|
t.belongs_to :user
t.belongs_to :wow_pet
t.timestamps
end
end
end

82
db/schema.rb generated
View File

@@ -10,11 +10,20 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_04_22_193459) do
ActiveRecord::Schema.define(version: 2021_04_23_153941) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "learned_wow_pet_abilities", force: :cascade do |t|
t.bigint "wow_pet_id"
t.bigint "wow_pet_ability_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["wow_pet_ability_id"], name: "index_learned_wow_pet_abilities_on_wow_pet_ability_id"
t.index ["wow_pet_id"], name: "index_learned_wow_pet_abilities_on_wow_pet_id"
end
create_table "mobility_string_translations", force: :cascade do |t|
t.string "locale", null: false
t.string "key", null: false
@@ -40,6 +49,24 @@ ActiveRecord::Schema.define(version: 2021_04_22_193459) do
t.index ["translatable_id", "translatable_type", "locale", "key"], name: "index_mobility_text_translations_on_keys", unique: true
end
create_table "user_obtain_wow_mounts", force: :cascade do |t|
t.bigint "user_id"
t.bigint "wow_mount_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["user_id"], name: "index_user_obtain_wow_mounts_on_user_id"
t.index ["wow_mount_id"], name: "index_user_obtain_wow_mounts_on_wow_mount_id"
end
create_table "user_obtain_wow_pets", force: :cascade do |t|
t.bigint "user_id"
t.bigint "wow_pet_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["user_id"], name: "index_user_obtain_wow_pets_on_user_id"
t.index ["wow_pet_id"], name: "index_user_obtain_wow_pets_on_wow_pet_id"
end
create_table "users", force: :cascade do |t|
t.string "email"
t.string "encrypted_password"
@@ -119,6 +146,59 @@ ActiveRecord::Schema.define(version: 2021_04_22_193459) do
t.index ["class_id"], name: "index_wow_classes_on_class_id", unique: true
end
create_table "wow_mounts", force: :cascade do |t|
t.jsonb "name"
t.string "source_type"
t.jsonb "translated_source"
t.string "faction"
t.jsonb "translated_faction"
t.jsonb "description"
t.integer "mount_id", null: false
t.integer "creature_display_id"
t.string "href"
t.string "asset_zoom"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["mount_id"], name: "index_wow_mounts_on_mount_id", unique: true
end
create_table "wow_pet_abilities", force: :cascade do |t|
t.integer "ability_id"
t.jsonb "name"
t.string "battle_pet_type"
t.jsonb "translated_battle_pet_type"
t.integer "battle_pet_type_id"
t.integer "rounds"
t.string "media"
t.string "href"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["ability_id"], name: "index_wow_pet_abilities_on_ability_id", unique: true
end
create_table "wow_pets", force: :cascade do |t|
t.jsonb "name"
t.integer "pet_id"
t.string "href"
t.string "battle_pet_type"
t.jsonb "translated_battle_pet_type"
t.integer "battle_pet_type_id"
t.jsonb "description"
t.boolean "is_capturable"
t.boolean "is_tradable"
t.boolean "is_battlepet"
t.boolean "is_alliance_only"
t.boolean "is_horde_only"
t.string "icon"
t.boolean "is_random_creature_display"
t.string "source_type"
t.jsonb "translated_source_type"
t.integer "creature_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["pet_id"], name: "index_wow_pets_on_pet_id", unique: true
end
create_table "wow_races", force: :cascade do |t|
t.jsonb "name"
t.string "href"

View File

@@ -3,13 +3,13 @@
"private": true,
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.3",
"@popperjs/core": "^2.9.2",
"@rails/actioncable": "^6.0.0",
"@rails/activestorage": "^6.0.0",
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "5.2.1",
"bootstrap": "^4.6.0",
"bootstrap": "^5.0.0-beta3",
"jquery": "^3.6.0",
"popper.js": "^1.16.1",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",

View File

@@ -0,0 +1,15 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the WowMountsHelper. For example:
#
# describe WowMountsHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe WowMountsHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,15 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the WowPetsHelper. For example:
#
# describe WowPetsHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe WowPetsHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe LearnedWowPetAbility, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe UserObtainWowMount, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe UserObtainWowPet, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe WowMount, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe WowPetAbility, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe WowPet, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,7 @@
require 'rails_helper'
RSpec.describe "WowMounts", type: :request do
describe "GET /index" do
pending "add some examples (or delete) #{__FILE__}"
end
end

View File

@@ -0,0 +1,7 @@
require 'rails_helper'
RSpec.describe "WowPets", type: :request do
describe "GET /index" do
pending "add some examples (or delete) #{__FILE__}"
end
end

View File

@@ -1,5 +0,0 @@
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
end

View File

@@ -1,11 +0,0 @@
require "test_helper"
class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
# test "connects with cookies" do
# cookies.signed[:user_id] = 42
#
# connect
#
# assert_equal connection.user_id, "42"
# end
end

View File

View File

View File

View File

View File

View File

View File

View File

@@ -1,13 +0,0 @@
ENV['RAILS_ENV'] ||= 'test'
require_relative "../config/environment"
require "rails/test_help"
class ActiveSupport::TestCase
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors)
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
end

18
yarn.lock generated
View File

@@ -860,6 +860,11 @@
mkdirp "^1.0.4"
rimraf "^3.0.2"
"@popperjs/core@^2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353"
integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==
"@rails/actioncable@^6.0.0":
version "6.1.3"
resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-6.1.3.tgz#c8a67ec4d22ecd6931f7ebd98143fddbc815419a"
@@ -1537,10 +1542,10 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bootstrap@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7"
integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==
bootstrap@^5.0.0-beta3:
version "5.0.0-beta3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.0.0-beta3.tgz#c959f61fbd03667a1b158f763856994859d7a465"
integrity sha512-0urccjfIOzhrb9qJysN8XW/DRw6rg3zH7qLeKIp4Zyl8+Ens4JWB0NC0cB5AhnSFPd2tftRggjwCMxablo6Tpg==
brace-expansion@^1.1.7:
version "1.1.11"
@@ -5208,11 +5213,6 @@ pnp-webpack-plugin@^1.6.4:
dependencies:
ts-pnp "^1.1.6"
popper.js@^1.16.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
portfinder@^1.0.26:
version "1.0.28"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"