Skip to content

Instantly share code, notes, and snippets.

@lsfernandes92
Created February 19, 2022 20:18
Show Gist options
  • Save lsfernandes92/f5fdfa671d92798636d73873919d671f to your computer and use it in GitHub Desktop.
Save lsfernandes92/f5fdfa671d92798636d73873919d671f to your computer and use it in GitHub Desktop.
Mental step by step code challenge FullStackLabs

Antes de começar:

  • Rodar um
    • sudo chown -R $USER:$USER .
    • sudo chown -R $USER:$USER .

Lembrar de:

  • Trabalhar com branches
  • Rodar rubocop?
  • Ir explicando o que estou fazendo em voz alta e clara

No inicio do vídeo começar falando o que fiz antes

  • Explicar que agora o projeto roda no Docker.
    • Arquivos modificados:
      1. .dockerignore
      2. Dockerfile
      3. Gemfile
      4. Gemfile.lock
      5. config/database.yml
      6. docker-compose.yml
      7. entrypoint.sh
  • Explicar que mudei o jeito que estou pegando o ruby version
  • Falar tb que atualizei o README.md
  • Falar tb que coloquei uma options a mais no .rspec: o --format documentation e o --order random
  • Falar tb que reorganizei uma pequena quantidade do código para que o container reconhecesse o chrome driverr
    • Arquivos modificados:
      1. spec/rails_helper.rb
      2. spec/system/short_urls_spec.rb
      3. docker-compose.yml (parte do webdriver_chrome e environment do web)

Dizer sobre os principais aliases do docker que irei usar for the sake of the time limited video durante meu work flow to facilitate

  • Mostrar aliases docker dotfiles
    1. dcu
    2. dcd
    3. dsa
    4. dcr
    5. dcb
    6. gco
    7. gcb

Criar uma nova branch e chamar de algo como "polish-index-page" e começar fazendo o seeds

# frozen_string_literal: true
puts '=== Creating some awesome Urls...'
11.times do |_i|
  Url.create!(
    short_url: Faker::Lorem.characters(number: 5, min_alpha: 5).upcase,
    original_url: Faker::Internet.url,
    clicks_count: rand(10)
  )
end
puts '=== Urls successfully created!'

puts '=== Creating some awesome Clicks...'
10.times do |_i|
  Click.create!(
    browser: %i[IE Firefox Chrome Safari].sample,
    platform: %i[Windows macOS Ubuntu Other].sample,
    url: Url.all.sample
  )
end
puts '=== Clicks successfully created!'
# A Scope & Engine based, clean, powerful, customizable and sophisticated paginator for Ruby webapps
gem 'kaminari'
1. dcr bundle
2. sudo docker-compose build
3. e colocar max_paginates_per 10  no model Url
4. Colocar o seguinte no url_controller:
page_number = params[:page].try(:[], :number)
per_page = params[:page].try(:[], :size)

@urls = Url.all.page(page_number).per(per_page)
  • Mudar o conteudo do index.html
        <td><%= link_to url.friendly_url, urls_path %></td>
        <td><%= link_to url.original_url, urls_path %></td>
        <td><%= url.created_at.strftime("%b %d, %Y") %></td> (http://strftime.net/)
        <td><%= url.clicks.count %></td>
  • Adicionar no url model
  def friendly_url
    "#{default_url}/#{short_url}"
  end
  • Adionar no environment.rb
Rails.application.routes.default_url_options = {
  schema: 'http',
  host: '127.0.0.1'
}
  • Adicionar default url helper
# frozen_string_literal: true

module DefaultUrlHelper
  def default_host
    Rails.application.routes.default_url_options[:host]
  end

  def default_port
    Rails.application.routes.default_url_options[:port]
  end

  def default_schema
    Rails.application.routes.default_url_options[:schema]
  end

  def default_url
    "#{default_schema}://#{default_host}:#{default_port}"
  end
end
  • Adicionar associação de Click com Url

Criar uma nova branch e chamar de algo como "add-url-validations"

  • gcb add-url-validations
  • Começar com os testes positivos
  subject { build(:url) }

  context 'when is being creating' do
    it 'succeds with valid attributes' do
      expect(subject).to be_valid
      expect{ subject.save }.to change { Url.count }.by(1)
    end
  end
  • ADicionar configuraçao do factory bot no rails_helper.rb
config.include FactoryBot::Syntax::Methods
  • Adicionar factory do click
# frozen_string_literal: true

FactoryBot.define do
  factory :click do
    browser { %i[IE Firefox Chrome Safari].sample }
    platform { %i[Windows macOS Ubuntu Other].sample }
    association :url, factory: :url
  end
end
  • Adicionar Url with clicks factory
    transient do
       clicks_quantity { 2 }
     end

     trait :with_clicks do
       after(:create) do |url, evaluator|
         create_list(
           :click,
           evaluator.clicks_quantity,
           url: url
         )
       end
     end

     factory :url_with_clicks, traits: [:with_clicks]
  • Add before save method Url model
  before_save :generate_friendly_url

  private

  def generate_friendly_url
    self.short_url = Faker::Lorem.characters(number: 5, min_alpha: 5).upcase
  end
  • Adionar primeiro test de validacao
    it 'validades short_url presence' do
      subject.save
      expect(subject.short_url).to be_present
    end
  • Adicionar validao presence shor url
    it 'validates short_url length of 5 characters' do
      subject.save
      expect(subject.short_url.length).to eq 5
    end
  • Add vlaidao upcase letter
    it 'validates short_url generates only upper case letters' do
      subject.save
      only_uppercase_letters = subject.short_url.match?(/^[A-Z]+$/)
      expect(only_uppercase_letters).to eq true
    end
  • Add validacao short url be unique
    let(:first_url) { Url.first }
    let(:short_url_already_took) { build(:url, short_url: first_url.short_url) }
...
... 
...
it 'validates short_url to be unique' do
      subject.save
      expect(short_url_already_took).not_to be_valid
      expect(short_url_already_took.errors.full_messages).to match_array(
        ["Short url has already been taken"]
      )
    end
  • Add validao model
validates :short_url, uniqueness: { case_sensitive: true }
  • ADd test presenc original
    it 'validates original_url presence' do
      subject.original_url = ''
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ["Original url can't be blank", "Original url is not a valid HTTP URL"]
      )
    end
  • Add presence url model
  validates :original_url,
          presence: true,
  • Add test original url to be unique
let(:original_url_already_took) { build(:url, original_url: first_url.original_url) }
...
...
...
it 'validates original_url to be unique' do
      subject.save
      expect(original_url_already_took).not_to be_valid
      expect(original_url_already_took.errors.full_messages).to match_array(
        ["Original url has already been taken"]
      )
    end
  • Add validaos model url
        uniqueness: { case_sensitive: true },
  • Add test origin url to be valid URL
    it 'validates original_url is a valid URL' do
      subject.original_url = 'something://thatis.notan.url'
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ["Original url is not a valid HTTP URL"]
      )
    end
  • Addd validacao model url
http_url: true
  • Validating an URL is a tricky job. It's also a very broad request.
  • If you want to validate the format of an URI/URL, then you might want to use regular expressions. Instead of searching for one, use the built-in Ruby URI.parse method.
class HttpUrlValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value.present? && compliant?(value)
      record.errors.add(attribute, "is not a valid HTTP URL")
    end
  end

  private

  def compliant?(value)
    uri = URI.parse(value)
    uri.kind_of?(URI::HTTP) && !uri.host.nil?
  rescue URI::InvalidURIError
    false
  end
end
  • rodar os tests
  • gco main
  • git merge add-url-validations
  1. Criar uma nova branch e chamar de algo como "add-click-validations"
  • gcb add-click-validations
  • COmeçar com so testes de caminho feliz
  subject { build(:click) }

  before { subject.url = create(:url) }

  context 'when is being creating' do
    it 'succeds with valid attributes' do
      expect(subject).to be_valid
      expect{ subject.save }.to change { Click.count }.by(1)
    end
  end
  • Add teste url presence
  context 'with validations' do
    it 'validates url presence' do
      subject.url_id = ''
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ['Url must exist']
      )
    end
  • Add teste browser presence
    it 'validates browser presence' do
      subject.browser = ''
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ["Browser can't be blank"]
      )
    end
  • Add validatinoon click model
validates browser, presence: true
  • ADd testes browser lenght
    it 'validates browser length' do
      subject.browser = 'a' * 21
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ['Browser is too long (maximum is 20 characters)']
      )
    end
  • Add valivadation click model
validates :browser, presence: true, length: { maximum: 20 }
  • Add teste platform presence
    it 'validates platform presence' do
      subject.platform = ''
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ["Platform can't be blank"]
      )
    end
  • Add validation click model
validates browser, presence: true
  • Add tests platform lenght
    it 'validates platform length' do
      subject.platform = 'a' * 21
      expect(subject).not_to be_valid
      expect(subject.errors.full_messages).to match_array(
        ['Platform is too long (maximum is 20 characters)']
      )
    end
  • Add vlaidation click model
validates :platform, presence: true, length: { maximum: 20 }

Criar uma nova branch e chamar de algo como "add-click-validations"

perguntar: para o validacao da URL quais tipos de URL serão aceitas? htttp? ftp? utp?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment