shortener 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfe3cdfcd8f92d17f455e75a416661205335d32f
4
- data.tar.gz: c1e126da86b1030d2c992bd31b9268e385cfaa4b
3
+ metadata.gz: c6357583710204365555ba59c8343c84a8dd17dc
4
+ data.tar.gz: ac7a8274dbee24478663ead28beef369895e1645
5
5
  SHA512:
6
- metadata.gz: f7fe49c5b8d563a8c394cad809b40cb99b9f1ddc625d4313fc1bef2dae1c284dcbf389b00ec17ad605edaa124cefcb6d8d17d4c41d0aa15993c7948d8b343ed0
7
- data.tar.gz: b53a02226b84fb67a3ccaa01565acc600f507ebebf8f3d3ef6c310c8f2194fa0cd2243fc62dab4c2eafe726038fd4f9d5563a7f2b7916a28478d02b833d16ecb
6
+ metadata.gz: 9e3bcddeb02d11a0a49adc7484c7a62b09e2458aac54290e80aa9aa774ac78b82b28c034dd50dba673d5777c86dedc029b0a06de7e9490ca5cb695a2985f2d53
7
+ data.tar.gz: ee61134fedd6f2ddb85bff8e9f9e6ace9aaabdd3a430e60b14a3d8d36c747c91345310029e8823dd6d342742ddf316530c529216b45fffb5197bd18a78f81797
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.0.0
5
4
  - 2.1.0
6
5
  - 2.2.3
@@ -14,6 +14,22 @@ The majority of the Shortener consists of three parts:
14
14
  * a controller to accept incoming requests and redirecting them to the target URL;
15
15
  * a helper for generating shortened URLs from controllers and views.
16
16
 
17
+ === Dependencies
18
+
19
+ Shortener is designed to work from within a Rails 3 and Rails 4 applications. It has dependancies Rails core components like ActiveRecord, ActionController, the rails routing engine and more.
20
+
21
+ === Ruby Version Support
22
+
23
+ As Ruby 1.9.3 entered end of maintainance in early 2015, the last version of the Shortener gem
24
+ to support Ruby 1.9.3 is 0.4.x. Shortener v0.5 onwards will require Ruby 2+.
25
+
26
+ === Upgrading
27
+
28
+ ==== v0.4.0 to v0.5.0
29
+ There have been some breaking changes:
30
+ 1. The owner argument is passed into the generator and helper methods as a named parameter.
31
+ 2. Original URLs arguments without a hypertext protocol (http|https) will be assumed to be relative paths.
32
+
17
33
  === Some niceities of Shortener:
18
34
 
19
35
  * The controller does a 301 redirect, which is the recommended type of redirect for maintaining maximum google juice to the original URL;
@@ -30,10 +46,9 @@ The majority of the Shortener consists of three parts:
30
46
  * The system could store the shortened URL if the url is to be continually rendered;
31
47
  * Some implementations might want duplicate links to be generated each time a user request a shortened link.
32
48
 
33
-
34
49
  == Installation
35
50
 
36
- You can use the latest Rails 3 gem with the latest Shortener gem. In your Gemfile:
51
+ Shortener is compatible with Rails v3 and v4. To install, add to your Gemfile:
37
52
 
38
53
  gem 'shortener'
39
54
 
@@ -60,17 +75,17 @@ By default, when a unique key isn't matched the site is redirected to "/". You c
60
75
  ```
61
76
  == Usage
62
77
 
63
- To generate a Shortened URL object for the URL "http://dealush.com" within your controller / models do the following:
78
+ To generate a Shortened URL object for the URL "http://example.com" within your controller / models do the following:
64
79
 
65
- Shortener::ShortenedUrl.generate("http://dealush.com")
80
+ Shortener::ShortenedUrl.generate("http://example.com")
66
81
 
67
- or
82
+ Alternatively, you can create a shortened url to a relative path within your application:
68
83
 
69
- Shortener::ShortenedUrl.generate("dealush.com")
84
+ Shortener::ShortenedUrl.generate("/relative-path?param=whatever")
70
85
 
71
86
  To generate and display a shortened URL in your application use the helper method:
72
87
 
73
- short_url("dealush.com")
88
+ short_url("http://example.com")
74
89
 
75
90
  This will generate a shortened URL. store it to the db and return a string representing the shortened URL.
76
91
 
@@ -84,12 +99,22 @@ You can link shortened URLs to an owner, to scope them. To do so, add the follow
84
99
 
85
100
  This will allow you to pass the owner when generating URLs:
86
101
 
87
- Shortener::ShortenedUrl.generate("example.com", user)
102
+ Shortener::ShortenedUrl.generate("example.com", owner: user)
103
+
104
+ short_url("http://example.com", owner: user)
88
105
 
89
106
  And to access those URLs:
90
107
 
91
108
  user.shortened_urls
92
109
 
110
+ === Shortened URLs with custom unqiue key
111
+
112
+ You can pass in your own key when generating a shortened URL. This should be unique.
113
+
114
+ Shortener::ShortenedUrl.instance("example.com", owner: user, custom_key: "my-key")
115
+
116
+ short_url("http://example.com", custom_key: 'yourkey')
117
+
93
118
  === Shorten URLs in generated emails
94
119
 
95
120
  You can register the included mail interceptor to shorten all links in the emails generated by your Rails app. For example, add to your mailer:
@@ -108,7 +133,7 @@ The interceptor supports a few more arguments, see the implementation for detail
108
133
 
109
134
  == Origins
110
135
 
111
- Shortener is based on code from Dealush[http://example.com], for a bit of backstory to Shortener see this {blog post}[http://jamespmcgrath.com/a-simple-link-shortener-in-rails/].
136
+ For a bit of backstory to Shortener see this {blog post}[http://jamespmcgrath.com/a-simple-link-shortener-in-rails/].
112
137
 
113
138
  == In The Wild
114
139
 
@@ -1,8 +1,8 @@
1
1
  module Shortener::ShortenerHelper
2
2
 
3
3
  # generate a url from a url string
4
- def short_url(url, owner=nil)
5
- short_url = Shortener::ShortenedUrl.generate(url, owner)
4
+ def short_url(url, owner: nil, custom_key: nil)
5
+ short_url = Shortener::ShortenedUrl.generate(url, owner: owner, custom_key: custom_key)
6
6
  short_url ? url_for(controller: :"shortener/shortened_urls", action: :show, id: short_url.unique_key, only_path: false) : url
7
7
  end
8
8
 
@@ -1,6 +1,5 @@
1
1
  class Shortener::ShortenedUrl < ActiveRecord::Base
2
2
 
3
- URL_PROTOCOL_HTTP = "http://"
4
3
  REGEX_LINK_HAS_PROTOCOL = Regexp.new('\Ahttp:\/\/|\Ahttps:\/\/', Regexp::IGNORECASE)
5
4
 
6
5
  validates :url, presence: true
@@ -10,35 +9,38 @@ class Shortener::ShortenedUrl < ActiveRecord::Base
10
9
 
11
10
  # ensure the url starts with it protocol and is normalized
12
11
  def self.clean_url(url)
13
- return nil if url.blank?
14
- url = URL_PROTOCOL_HTTP + url.strip unless url =~ REGEX_LINK_HAS_PROTOCOL
12
+
13
+ url = url.to_s.strip
14
+ if url !~ REGEX_LINK_HAS_PROTOCOL && url[0] != '/'
15
+ url = "/#{url}"
16
+ end
15
17
  URI.parse(url).normalize.to_s
16
18
  end
17
19
 
18
20
  # generate a shortened link from a url
19
21
  # link to a user if one specified
20
22
  # throw an exception if anything goes wrong
21
- def self.generate!(orig_url, owner=nil)
23
+ def self.generate!(destination_url, owner: nil, custom_key: nil)
22
24
  # if we get a shortened_url object with a different owner, generate
23
25
  # new one for the new owner. Otherwise return same object
24
- if orig_url.is_a? Shortener::ShortenedUrl
25
- if orig_url.owner == owner
26
- result = orig_url
26
+ if destination_url.is_a? Shortener::ShortenedUrl
27
+ if destination_url.owner == owner
28
+ result = destination_url
27
29
  else
28
- result = generate!(orig_url.url, owner)
30
+ result = generate!(destination_url.url, owner: owner, custom_key: custom_key)
29
31
  end
30
32
  else
31
33
  scope = owner ? owner.shortened_urls : self
32
- result = scope.where(url: clean_url(orig_url)).first_or_create
34
+ result = scope.where(url: clean_url(destination_url)).first_or_create
33
35
  end
34
36
 
35
37
  result
36
38
  end
37
39
 
38
40
  # return shortened url on success, nil on failure
39
- def self.generate(orig_url, owner=nil)
41
+ def self.generate(destination_url, owner: nil, custom_key: nil)
40
42
  begin
41
- generate!(orig_url, owner)
43
+ generate!(destination_url, owner: owner, custom_key: custom_key)
42
44
  rescue
43
45
  nil
44
46
  end
@@ -6,7 +6,7 @@ class CreateShortenedUrlsTable < ActiveRecord::Migration
6
6
  t.string :owner_type, limit: 20
7
7
 
8
8
  # the real url that we will redirect to
9
- t.string :url, null: false
9
+ t.text :url, null: false
10
10
 
11
11
  # the unique key
12
12
  t.string :unique_key, limit: 10, null: false
@@ -1,3 +1,3 @@
1
1
  module Shortener
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -12,7 +12,10 @@ describe Shortener::ShortenedUrlsController, type: :controller do
12
12
 
13
13
  context 'valid keys' do
14
14
  context 'real key' do
15
- let(:key) { short_url.unique_key}
15
+ before do
16
+ short_url
17
+ end
18
+ let(:key) { short_url.unique_key }
16
19
 
17
20
  it 'redirects to the destination url' do
18
21
  expect(response).to redirect_to destination
@@ -4,23 +4,41 @@ require 'spec_helper'
4
4
  describe Shortener::ShortenerHelper, type: :helper do
5
5
  describe '#short_url' do
6
6
  let(:destination) { Faker::Internet.url }
7
- before do
8
- expect(Shortener::ShortenedUrl).to receive(:generate).with(destination, nil).and_return(shortened_url)
9
- end
10
7
 
11
- context 'short url was generated' do
12
- let(:shortened_url) { instance_double('ShortenedUrl', unique_key: '12345') }
8
+ context 'without user or custom key' do
9
+ before do
10
+ expect(Shortener::ShortenedUrl).to receive(:generate).with(destination, owner: nil, custom_key: nil).and_return(shortened_url)
11
+ end
12
+
13
+ context 'short url was generated' do
14
+ let(:shortened_url) { instance_double('ShortenedUrl', unique_key: '12345') }
15
+
16
+ it "shortens the url" do
17
+ expect(helper.short_url(destination)).to eq "http://test.host/12345"
18
+ end
19
+ end
20
+
21
+ context 'short url could not be generated' do
22
+ let(:shortened_url) { nil }
13
23
 
14
- it "shortens the url" do
15
- expect(helper.short_url(destination)).to eq "http://test.host/12345"
24
+ it 'returns the original url' do
25
+ expect(helper.short_url(destination)).to eq destination
26
+ end
16
27
  end
17
28
  end
18
29
 
19
- context 'short url could not be generated' do
20
- let(:shortened_url) { nil }
30
+ context 'with owner' do
31
+ let(:owner) { double('User') }
32
+ it 'sends user to generate function' do
33
+ expect(Shortener::ShortenedUrl).to receive(:generate).with(destination, owner: owner, custom_key: nil)
34
+ helper.short_url(destination, owner: owner)
35
+ end
36
+ end
21
37
 
22
- it 'returns the original url' do
23
- expect(helper.short_url(destination)).to eq destination
38
+ context 'with custom_key' do
39
+ it 'sends custom key code to generate function' do
40
+ expect(Shortener::ShortenedUrl).to receive(:generate).with(destination, owner: nil, custom_key: 'custkey')
41
+ helper.short_url(destination, custom_key: 'custkey')
24
42
  end
25
43
  end
26
44
  end
@@ -11,7 +11,7 @@ describe Shortener::ShortenedUrl, type: :model do
11
11
  let(:expected_url) { Faker::Internet.url }
12
12
 
13
13
  shared_examples_for "shortened url" do
14
- let(:short_url) { Shortener::ShortenedUrl.generate!(long_url, owner) }
14
+ let(:short_url) { Shortener::ShortenedUrl.generate!(long_url, owner: owner) }
15
15
  it 'creates a shortened url record for the url' do
16
16
  expect{short_url}.to change{Shortener::ShortenedUrl.count}.by(1)
17
17
  expect(short_url.url).to eq expected_url
@@ -23,15 +23,16 @@ describe Shortener::ShortenedUrl, type: :model do
23
23
  context 'userless url' do
24
24
  let(:owner) { nil }
25
25
 
26
- context 'shortened url ' do
26
+ context 'shortened url' do
27
27
  it_should_behave_like "shortened url" do
28
28
  let(:long_url) { expected_url }
29
29
  end
30
30
  end
31
31
 
32
- context 'shortened url with partial URL' do
32
+ context 'shortened url with relative path' do
33
33
  it_should_behave_like "shortened url" do
34
- let(:long_url) { expected_url.gsub('http://', '') }
34
+ let(:long_url) { Faker::Internet.slug }
35
+ let(:expected_url) { "/#{long_url}" }
35
36
  end
36
37
  end
37
38
 
@@ -55,17 +56,6 @@ describe Shortener::ShortenedUrl, type: :model do
55
56
  let(:url) { Faker::Internet.url }
56
57
  let!(:existing_shortened_url) { Shortener::ShortenedUrl.generate!(url) }
57
58
 
58
- context 'same url as existing' do
59
- let(:protocol_free_url) { url.gsub('http://', '') }
60
-
61
- it 'finds the shortened url from protocol free url' do
62
- expect(Shortener::ShortenedUrl.generate!(protocol_free_url)).to eq existing_shortened_url
63
- end
64
- it "should look up exsiting URL" do
65
- expect(Shortener::ShortenedUrl.generate!(url)).to eq existing_shortened_url
66
- end
67
- end
68
-
69
59
  context 'different url from existing' do
70
60
  it "generates a new shortened url record for a different url" do
71
61
  expect(Shortener::ShortenedUrl.generate!(Faker::Internet.url)).not_to eq existing_shortened_url
@@ -85,6 +75,20 @@ describe Shortener::ShortenedUrl, type: :model do
85
75
  end
86
76
  end
87
77
  end
78
+
79
+ context "existing shortened URL with relative path" do
80
+ let(:path) { Faker::Internet.slug }
81
+ let!(:existing_shortened_url) { Shortener::ShortenedUrl.generate!(path) }
82
+
83
+ context 'same relative path' do
84
+ it 'finds the shortened url from slashless oath' do
85
+ expect(Shortener::ShortenedUrl.generate!(path)).to eq existing_shortened_url
86
+ end
87
+ it "should look up exsiting URL" do
88
+ expect(Shortener::ShortenedUrl.generate!("/#{path}")).to eq existing_shortened_url
89
+ end
90
+ end
91
+ end
88
92
  end
89
93
 
90
94
  describe '#generate' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shortener
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James P. McGrath