mr_video 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -49,6 +49,7 @@ Mount it in your `config/routes.rb`.
49
49
  MyApp::Application.routes.draw do
50
50
 
51
51
  if Rails.env.development?
52
+ require 'mr_video'
52
53
  mount MrVideo::Engine => '/mr_video'
53
54
  end
54
55
 
@@ -3,19 +3,10 @@ module MrVideo
3
3
  class EpisodesController < MrVideoController
4
4
 
5
5
  def show
6
- cassette = Cassette.find(params[:cassette_id])
7
- episode = cassette.find_episode_by_id(params[:id])
8
- episode_content = episode.content
9
-
10
- unless params[:fix_relative_links] == 'false'
11
- episode_content.gsub!(/href="\//, "href=\"#{episode.website_url}/")
12
- episode_content.gsub!(/href="(?<foo>[a-zA-z0-9_])/, 'href="' + episode.website_url + '/\k<foo>')
13
- episode_content.gsub!(/src="\//, "src=\"#{episode.website_url}/")
14
- episode_content.gsub!(/@import url\("/, "@import url(\"#{episode.website_url}/")
15
- end
6
+ show_presenter = Episodes::ShowPresenter.new(self)
16
7
 
17
8
  # TODO: Add method for sending decompressed content
18
- send_data episode_content, type: episode.content_type, disposition: 'inline'
9
+ send_data show_presenter.content, type: show_presenter.content_type, disposition: 'inline'
19
10
  end
20
11
 
21
12
  def destroy
@@ -23,7 +23,7 @@ module MrVideo
23
23
  end
24
24
 
25
25
  def updated_at
26
- Time.zone.parse(File.mtime(cassette_path).to_s).to_datetime
26
+ @updated_at ||= episodes.map(&:recorded_at).max
27
27
  end
28
28
 
29
29
 
@@ -0,0 +1,80 @@
1
+ module MrVideo
2
+
3
+ module Episodes
4
+
5
+ class ShowPresenter
6
+
7
+ def initialize(context)
8
+ @context = context
9
+ end
10
+
11
+ def content
12
+ if fix_relative_links?
13
+ content_with_relative_links_fixed
14
+ else
15
+ raw_content
16
+ end
17
+ end
18
+
19
+ def content_type
20
+ episode.content_type
21
+ end
22
+
23
+ private
24
+
25
+ def content_with_relative_links_fixed
26
+ content = raw_content
27
+ [
28
+ /href=["']([^'" >]+)["']/,
29
+ /src=["']([^'" >]+)["']/,
30
+ /@import url\(([^'" >]+)\)/
31
+ ].each do |pattern|
32
+ content.gsub!(pattern) do |match|
33
+ url = $1
34
+ match.gsub(url, URI.join(base_url, url).to_s)
35
+ end
36
+ end
37
+ content
38
+ end
39
+
40
+ def base_url
41
+ episode.website_url
42
+ end
43
+
44
+ def raw_content
45
+ episode.content
46
+ end
47
+
48
+ def fix_relative_links?
49
+ params[:fix_relative_links] != 'false'
50
+ end
51
+
52
+ def episode
53
+ @episode ||= cassette.find_episode_by_id(id)
54
+ end
55
+
56
+ def cassette
57
+ @cassette ||= Cassette.find(cassette_id)
58
+ end
59
+
60
+ def cassette_id
61
+ params[:cassette_id]
62
+ end
63
+
64
+ def id
65
+ params[:id]
66
+ end
67
+
68
+ def params
69
+ context.params
70
+ end
71
+
72
+ def context
73
+ @context
74
+ end
75
+
76
+ end # ShowPresenter class
77
+
78
+ end # Episodes module
79
+
80
+ end # MrVideo module
@@ -9,7 +9,7 @@
9
9
  <%= stylesheet_link_tag 'mr_video/application', media: 'all' %>
10
10
  </head>
11
11
  <body>
12
- <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
12
+ <nav class="navbar navbar-default navbar-fixed-top navbar-inverse" role="navigation">
13
13
  <div class="container">
14
14
  <!-- Brand and toggle get grouped for better mobile display -->
15
15
  <div class="navbar-header">
@@ -19,7 +19,7 @@
19
19
  <span class="icon-bar"></span>
20
20
  <span class="icon-bar"></span>
21
21
  </button>
22
- <a class="navbar-brand" href="<%= root_path %>">Mr. Video</a>
22
+ <a class="navbar-brand" style="color: white;" href="<%= root_path %>">Mr. Video</a>
23
23
  </div><!-- /.navbar-header -->
24
24
  <div class="navbar-collapse collapse" id="navbar-main">
25
25
  <ul class="nav navbar-nav">
@@ -33,7 +33,7 @@
33
33
  <div class="container">
34
34
  <%= yield %>
35
35
  </div>
36
- <div class="navbar navbar-fixed-bottom navbar-inverse">
36
+ <!--div class="navbar navbar-fixed-bottom navbar-inverse">
37
37
  <div class="navbar-inner">
38
38
  <div class="container">
39
39
  <ul class="nav navbar-nav">
@@ -49,7 +49,7 @@
49
49
  </ul>
50
50
  </div>
51
51
  </div>
52
- </div>
52
+ </div-->
53
53
  <%= javascript_include_tag 'mr_video/application' %>
54
54
  </body>
55
55
  </html>
@@ -10,7 +10,7 @@
10
10
  <th>Url</th>
11
11
  <th>Method</th>
12
12
  <th>Content Type</th>
13
- <th>Last Recorded</th>
13
+ <th>Recorded</th>
14
14
  <th>Action</th>
15
15
  </tr>
16
16
  </thead>
@@ -18,7 +18,7 @@
18
18
  <% @cassette.episodes.each_with_index do |episode, index| %>
19
19
  <tr id="episode_<%= episode.id %>_row">
20
20
  <td><%= index + 1 %></td>
21
- <td><%= link_to(episode.url, cassette_episode_path(@cassette, episode), html_options = { target: '_blank' }) %></td>
21
+ <td><%= link_to(episode.url, cassette_episode_path(@cassette, episode, fix_relative_links: true), html_options = { target: '_blank' }) %></td>
22
22
  <td><%= episode.request_method.upcase %></td>
23
23
  <td><%= episode.content_type %></td>
24
24
  <td title="<%= episode.recorded_at %>"><%= time_ago_in_words(episode.recorded_at) %> ago</td>
@@ -1,5 +1,5 @@
1
1
  module MrVideo
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.2'
3
3
  URL = 'https://github.com/quidproquo/mr_video'
4
4
  NAME = 'Mr. Video'
5
5
  end
@@ -0,0 +1,96 @@
1
+ require 'rails_helper'
2
+
3
+ describe MrVideo::EpisodesController do
4
+ routes { MrVideo::Engine.routes }
5
+
6
+ render_views
7
+
8
+ describe '#show' do
9
+ let(:cassette_id) { 'bell_house' }
10
+ let(:id) { 1234 }
11
+ let(:fix_relative_links) { 'false' }
12
+ let(:cassette) { double(:cassette, id: cassette_id) }
13
+ let(:episode) { double(:episode, id: id) }
14
+ let(:content) { '<html><body></body></html>' }
15
+ let(:website_url) { 'http://www.mrvideo.com' }
16
+ let(:content_type) { 'text/html' }
17
+ let(:params) { {
18
+ cassette_id: cassette_id,
19
+ id: id,
20
+ fix_relative_links: fix_relative_links
21
+ } }
22
+ let(:show) { get(:show, params) }
23
+
24
+ subject { show }
25
+
26
+ before do
27
+ expect(MrVideo::Cassette).to receive(:find).with(cassette_id) { cassette }
28
+ expect(cassette).to receive(:find_episode_by_id).with(id.to_s) { episode }
29
+ expect(episode).to receive(:content) { content }
30
+ allow(episode).to receive(:website_url) { website_url }
31
+ expect(episode).to receive(:content_type) { 'text/html' }
32
+ show
33
+ end
34
+
35
+ it { should be_success }
36
+
37
+ context 'fix relative links is true' do
38
+ let(:fix_relative_links) { 'true' }
39
+ let(:content) { raise NotImplementedError }
40
+ let(:body) { show.body }
41
+
42
+ subject { body }
43
+
44
+ context 'when href contains href="/' do
45
+ let(:content) { '<a href="/videos/video_1234" class="interesting">click here</a>' }
46
+ it 'should have correctly replaced the href' do
47
+ expect(body).to match(/href="http:\/\/www\.mrvideo\.com\/videos\/video_1234"/)
48
+ end
49
+ end
50
+
51
+ context 'when img contains src="/' do
52
+ let(:content) { '<img src="/videos/video_1234.png" />' }
53
+ it 'should have correctly replaced the src' do
54
+ expect(body).to match(/src="http:\/\/www\.mrvideo\.com\/videos\/video_1234.png"/)
55
+ end
56
+ end
57
+
58
+ context 'when @import is relative' do
59
+ let(:content) { '<style>@import url(fun.css);<style/>' }
60
+ it 'should have correctly replaced the url' do
61
+ expect(body).to match(/@import url\(http:\/\/www\.mrvideo\.com\/fun\.css\)/)
62
+ end
63
+ end
64
+
65
+ end # fix relative links
66
+
67
+ end # show
68
+
69
+ describe '#destroy' do
70
+ let(:cassette_id) { 'bell_house' }
71
+ let(:id) { 0 }
72
+ let(:params) { {
73
+ cassette_id: cassette_id,
74
+ id: id
75
+ } }
76
+ let(:cassette) { double(:cassette) }
77
+ let(:episode) { double(:episode, id: id) }
78
+ let(:destroy) { xhr(:post, :destroy, params) }
79
+
80
+ subject { destroy }
81
+
82
+ before do
83
+ expect(MrVideo::Cassette).to receive(:find).with(cassette_id) { cassette }
84
+ expect(cassette).to receive(:find_episode_by_id).with(id.to_s) { episode }
85
+ allow(episode).to receive(:destroy)
86
+ destroy
87
+ end
88
+
89
+ it { should be_success }
90
+
91
+ it 'should destroy the episode' do
92
+ expect(episode).to have_received(:destroy)
93
+ end
94
+ end # #destroy
95
+
96
+ end # MrVideo::EpisodesController