Skip to content

Commit 016303c

Browse files
committed
Start on modeling
1 parent 7647b40 commit 016303c

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

app/models/stream_resource.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class StreamResource < ApplicationRecord
2+
BUFFER_SECONDS = 10
3+
4+
enum :status, %w[started created processing complete error retrying cancelled invalid].to_enum_h, prefix: true
5+
6+
belongs_to :stream_recording, -> { with_deleted }, touch: true, optional: true
7+
has_one :podcast, through: :stream_recording
8+
has_one :task, -> { order(id: :desc) }, as: :owner
9+
has_many :tasks, as: :owner
10+
11+
validates :start_at, presence: true
12+
validates :end_at, presence: true, comparison: {greater_than: :start_at}
13+
validates :actual_start_at, presence: true
14+
validates :actual_end_at, presence: true, comparison: {greater_than: :actual_start_at}
15+
validates :original_url, presence: true
16+
17+
after_initialize :set_defaults
18+
before_validation :set_defaults
19+
20+
acts_as_paranoid
21+
22+
# NOTE: called twice, because podcast won't be there on initialize
23+
def set_defaults
24+
set_default(:status, "created")
25+
set_default(:guid, SecureRandom.uuid)
26+
set_default(:url, published_url)
27+
end
28+
29+
def file_name
30+
File.basename(URI.parse(original_url).path) if original_url.present?
31+
end
32+
33+
def published_path
34+
"#{podcast.path}/#{stream_resource_path}" if podcast
35+
end
36+
37+
def published_url
38+
"#{podcast.base_published_url}/#{stream_resource_path}" if podcast
39+
end
40+
41+
private
42+
43+
def stream_resource_path
44+
"streams/#{guid}/#{file_name}"
45+
end
46+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FactoryBot.define do
2+
factory :stream_resource do
3+
start_at { "2025-12-18T13:00:00Z" }
4+
end_at { "2025-12-18T14:00:00Z" }
5+
actual_start_at { "2025-12-18T12:59:50Z" }
6+
actual_end_at { "2025-12-18T14:00:10Z" }
7+
8+
original_url { "s3://prx-testing/test/audio.mp3" }
9+
10+
status { "complete" }
11+
mime_type { "audio/mpeg" }
12+
file_size { 774059 }
13+
bit_rate { 128 }
14+
sample_rate { 44100 }
15+
channels { 2 }
16+
duration { 3620.0 }
17+
end
18+
end
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
require "test_helper"
2+
3+
describe StreamResource do
4+
let(:podcast) { build_stubbed(:podcast) }
5+
let(:resource) { build_stubbed(:stream_resource, podcast: podcast) }
6+
7+
describe "#set_defaults" do
8+
it "sets unchanged defaults" do
9+
res = StreamResource.new(podcast: podcast)
10+
assert_equal "created", res.status
11+
assert res.guid.present?
12+
assert res.url.present?
13+
refute res.changed?
14+
end
15+
end
16+
17+
describe "#file_name" do
18+
it "parses the original url" do
19+
assert_equal "audio.mp3", resource.file_name
20+
21+
resource.original_url = "http://some.where/the/file.name.here#and?other&stuff=1"
22+
assert_equal "file.name.here", resource.file_name
23+
24+
resource.original_url = ""
25+
assert_nil resource.file_name
26+
end
27+
end
28+
29+
describe "#published_path" do
30+
it "includes the podcast prefix" do
31+
assert_equal "#{podcast.id}/streams/#{resource.guid}/audio.mp3", resource.published_path
32+
end
33+
end
34+
35+
describe "#published_url" do
36+
it "includes the podcast http url" do
37+
assert_equal "https://f.prxu.org/#{resource.published_path}", resource.published_url
38+
end
39+
40+
it "sets the url field" do
41+
# NOTE: podcast is nil after_initialize
42+
assert_nil resource.url
43+
44+
# but will be there before validation
45+
assert resource.valid?
46+
refute_nil resource.url
47+
assert_equal resource.published_url, resource.url
48+
49+
resource.guid = "some-other-guid"
50+
resource.original_url = "http://some/other.filename"
51+
assert resource.valid?
52+
refute_equal resource.published_url, resource.url
53+
end
54+
end
55+
end

0 commit comments

Comments
 (0)