fix: parsed_url + stripped_url

- store and redirect urls without protocol
- update README
- increment counter with SQL COALESCE
- add linksHelper
- update tests
This commit is contained in:
Juan Rodriguez
2023-03-27 06:58:48 +02:00
parent af9c7b0024
commit cebdfb35d7
9 changed files with 52 additions and 55 deletions
+2 -36
View File
@@ -40,44 +40,10 @@ docker-compose run --rm app bundle exec rails test
docker-compose run --rm app bundle exec rubocop
```
# Results
## Testing
## Dokku deployment
```bash
Finished in 2.211344s, 9.9487 runs/s, 10.4009 assertions/s.
22 runs, 23 assertions, 0 failures, 0 errors, 0 skips
Coverage report generated for Minitest to /usr/src/app/coverage. 81 / 81 LOC (100.0%) covered.
COVERAGE: 100.00% -- 81/81 lines in 8 files
BRANCH COVERAGE: 100.00% -- 20/20 branches in 8 branches
+----------+-------------------------------------------+-------+--------+---------+-----------------+----------+-----------------+------------------+
| coverage | file | lines | missed | missing | branch coverage | branches | branches missed | branches missing |
+----------+-------------------------------------------+-------+--------+---------+-----------------+----------+-----------------+------------------+
| 100.00% | app/controllers/application_controller.rb | 3 | 0 | | 100.00% | 0 | 0 | |
| 100.00% | app/controllers/links_controller.rb | 23 | 0 | | 100.00% | 8 | 0 | |
| 100.00% | app/controllers/sessions_controller.rb | 17 | 0 | | 100.00% | 4 | 0 | |
| 100.00% | app/controllers/users_controller.rb | 16 | 0 | | 100.00% | 4 | 0 | |
| 100.00% | app/helpers/sessions_helper.rb | 3 | 0 | | 100.00% | 0 | 0 | |
| 100.00% | app/models/application_record.rb | 2 | 0 | | 100.00% | 0 | 0 | |
| 100.00% | app/models/link.rb | 13 | 0 | | 100.00% | 4 | 0 | |
| 100.00% | app/models/user.rb | 4 | 0 | | 100.00% | 0 | 0 | |
+----------+-------------------------------------------+-------+--------+---------+-----------------+----------+-----------------+------------------+
```
## Rubocop
```bash
Inspecting 43 files
...........................................
43 files inspected, no offenses detected
```
- Dokku deployment
```bash
bundle exec rails assets:precompile
bundle exec rails db:migrate
```
- Production link
## Production link
https://url-shortener.sjdonado.de
+7 -3
View File
@@ -1,13 +1,15 @@
# frozen_string_literal: true
class LinksController < ApplicationController
include LinksHelper
before_action :authenticate, only: %i[create]
before_action :set_link, only: %i[redirect counter]
def redirect
if @link
@link.update(click_counter: @link.click_counter + 1)
redirect_to @link.url
@link.increment!(:click_counter) # rubocop:disable Rails/SkipsModelValidations
redirect_to @link.parsed_url
else
render file: Rails.root.join('/public/404'), status: :not_found
end
@@ -22,7 +24,9 @@ class LinksController < ApplicationController
end
def create
@link = Link.find_or_create_by(url: link_params[:url]) do |link|
url = stripped_url(link_params[:url])
@link = Link.find_or_create_by(url: url) do |link|
link.user = @current_user if @current_user
end
+7
View File
@@ -0,0 +1,7 @@
# frozen_string_literal: true
module LinksHelper
def stripped_url(url)
url.sub(%r{^.*://(www\.)?}, '').sub(/^www\./, '')
end
end
+9 -5
View File
@@ -1,18 +1,22 @@
# frozen_string_literal: true
VALID_URL_REGEX = /\A(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)? \
([a-zA-Z0-9-]+\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,})?) \
(?:\/[^\s]*)?\z/
class Link < ApplicationRecord
validates :url, presence: true
validates :slug, uniqueness: true
validates :url, format: { with: VALID_URL_REGEX, message: 'invalid format' }
validates :url,
format: {
with: %r{\A(https?://)?(www\.)?([a-zA-Z0-9_-]+\.)+[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?([/?#][^\s]*)?\z}i,
message: 'must be a valid URL'
}
validates :url, length: { within: 3..30_000, on: :create, message: 'max length is 30000' }
before_validation :generate_slug
def parsed_url
"https://#{url}"
end
def generate_slug(attempts = 0)
return if slug.present? || attempts == 3
+1 -1
View File
@@ -4,7 +4,7 @@
URL Shortener
</label>
<div class="mt-4 flex rounded-md shadow-sm">
<%= f.text_field :url, pattern: '(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([a-zA-Z0-9-]+\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,})?)(?:\/[^\s]*)?', data: { target: "links.url" }, placeholder: "https://google.com", class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
<%= f.text_field :url, pattern: '(https?:\/\/)?(www\.)?([a-zA-Z0-9_-]+\.)+[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?([\/?#][^\s]*)?', data: { target: "links.url" }, placeholder: "https://google.com", class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
</div>
+1 -1
View File
@@ -6,7 +6,7 @@
Website
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<a href="<%= link.url %>" class="mt-1 text-sm text-gray-600 underline" target="_blank" rel="noreferrer"><%= link.url %></a>
<a href="<%= link.parsed_url %>" class="mt-1 text-sm text-gray-600 underline" target="_blank" rel="noreferrer"><%= link.url %></a>
</dd>
</div>
<div class="bg-white px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
+2 -1
View File
@@ -42,9 +42,10 @@ class LinksControllerTest < ActionDispatch::IntegrationTest
test 'Should redirect from slug to url' do
link = links(:one)
slug = link.slug
get short_url(slug: slug)
assert_redirected_to link.url
assert_redirected_to link.parsed_url
end
test 'Should get link counter' do
+6 -1
View File
@@ -7,5 +7,10 @@ one:
two:
slug: qwu62l
url: 'https://gapfish.com'
url: 'https://www.google.com'
click_counter: 1
three:
slug: rwi43l
url: 'google.com'
click_counter: 1
+17 -7
View File
@@ -9,21 +9,31 @@ class LinkTest < ActiveSupport::TestCase
assert_not link.save, 'Saved the link without a url'
end
test 'Should not save a link with a invalid url' do
test 'Should not save a link with a invalid url - number' do
link = Link.new
link.url = 'test.com'
link.url = 0
assert_not link.save, 'Saved the link with invalid url format'
end
test 'Should create a link with a valid url' do
test 'Should not save a link with a invalid url - string' do
link = Link.new
link.url = 'https://test.com'
assert link.save, 'Link with valid url not saved'
link.url = 'test'
assert_not link.save, 'Saved the link with invalid url format'
end
test 'Should generate a slug on save a new link' do
test 'Should generate a slug on save a new link - format https://google.com' do
link = links(:one)
assert link.slug, 'Slug not generated on save a new link'
assert link.save, 'Slug generated on save a new link'
end
test 'Should generate a slug on save a new link - format http://www.google.com' do
link = links(:two)
assert link.save, 'Slug generated on save a new link'
end
test 'Should generate a slug on save a new link - format google.com' do
link = links(:three)
assert link.save, 'Slug generated on save a new link'
end
test 'Should generate an unique slug' do