audio-feed-manager 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +17 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +86 -0
  8. data/Rakefile +2 -0
  9. data/audio-feed-manager.gemspec +32 -0
  10. data/bin/afm +5 -0
  11. data/lib/audio-feed-manager.rb +1 -0
  12. data/lib/audio_feed_manager/application.rb +39 -0
  13. data/lib/audio_feed_manager/audio_file.rb +9 -0
  14. data/lib/audio_feed_manager/audio_file_adder.rb +14 -0
  15. data/lib/audio_feed_manager/audio_file_repository.rb +42 -0
  16. data/lib/audio_feed_manager/cli/add_audio_file.rb +39 -0
  17. data/lib/audio_feed_manager/cli/add_feed.rb +20 -0
  18. data/lib/audio_feed_manager/cli/arguments.rb +27 -0
  19. data/lib/audio_feed_manager/cli/arguments_parser.rb +67 -0
  20. data/lib/audio_feed_manager/cli/arguments_specification.rb +103 -0
  21. data/lib/audio_feed_manager/cli/command.rb +23 -0
  22. data/lib/audio_feed_manager/cli/commands_list.rb +120 -0
  23. data/lib/audio_feed_manager/cli/get_feed_url.rb +20 -0
  24. data/lib/audio_feed_manager/cli/initialize_project.rb +44 -0
  25. data/lib/audio_feed_manager/cli/list_feeds.rb +38 -0
  26. data/lib/audio_feed_manager/cli/publish.rb +21 -0
  27. data/lib/audio_feed_manager/cli/show_feed.rb +44 -0
  28. data/lib/audio_feed_manager/cli/update_feed_rss.rb +19 -0
  29. data/lib/audio_feed_manager/cli.rb +19 -0
  30. data/lib/audio_feed_manager/config.rb +5 -0
  31. data/lib/audio_feed_manager/config_repository.rb +14 -0
  32. data/lib/audio_feed_manager/console.rb +28 -0
  33. data/lib/audio_feed_manager/directory_lister.rb +9 -0
  34. data/lib/audio_feed_manager/error.rb +4 -0
  35. data/lib/audio_feed_manager/feed.rb +9 -0
  36. data/lib/audio_feed_manager/feed_items_repository.rb +30 -0
  37. data/lib/audio_feed_manager/feed_repository.rb +32 -0
  38. data/lib/audio_feed_manager/feed_syncer.rb +20 -0
  39. data/lib/audio_feed_manager/file_storage.rb +20 -0
  40. data/lib/audio_feed_manager/id3_tags.rb +14 -0
  41. data/lib/audio_feed_manager/new_model_creator.rb +15 -0
  42. data/lib/audio_feed_manager/rss_generator.rb +10 -0
  43. data/lib/audio_feed_manager/rss_repository.rb +36 -0
  44. data/lib/audio_feed_manager/s3_gateway.rb +39 -0
  45. data/lib/audio_feed_manager/secret_token_generator.rb +9 -0
  46. data/lib/audio_feed_manager/stop_application.rb +4 -0
  47. data/lib/audio_feed_manager/support/getter_setter_method.rb +18 -0
  48. data/lib/audio_feed_manager/support/hash_constructor.rb +9 -0
  49. data/lib/audio_feed_manager/tags.rb +9 -0
  50. data/lib/audio_feed_manager/unique_id_generator.rb +19 -0
  51. data/lib/audio_feed_manager/url_maker.rb +13 -0
  52. data/lib/audio_feed_manager/version.rb +3 -0
  53. data/lib/audio_feed_manager.rb +57 -0
  54. data/spec/audio_feed_manager/audio_file_adder_spec.rb +49 -0
  55. data/spec/audio_feed_manager/audio_file_repository_spec.rb +58 -0
  56. data/spec/audio_feed_manager/cli/add_audio_file_spec.rb +44 -0
  57. data/spec/audio_feed_manager/cli/add_feed_spec.rb +27 -0
  58. data/spec/audio_feed_manager/cli/arguments_parser_spec.rb +85 -0
  59. data/spec/audio_feed_manager/cli/arguments_specification_spec.rb +51 -0
  60. data/spec/audio_feed_manager/cli/commands_list_spec.rb +91 -0
  61. data/spec/audio_feed_manager/cli/get_feed_url_spec.rb +26 -0
  62. data/spec/audio_feed_manager/cli/initialize_project_spec.rb +47 -0
  63. data/spec/audio_feed_manager/cli/list_feeds_spec.rb +27 -0
  64. data/spec/audio_feed_manager/cli/show_feed_spec.rb +41 -0
  65. data/spec/audio_feed_manager/cli/update_feed_rss_spec.rb +26 -0
  66. data/spec/audio_feed_manager/cli_spec.rb +42 -0
  67. data/spec/audio_feed_manager/directory_lister_spec.rb +23 -0
  68. data/spec/audio_feed_manager/feed_items_repository_spec.rb +34 -0
  69. data/spec/audio_feed_manager/feeds_repository_spec.rb +40 -0
  70. data/spec/audio_feed_manager/file_storage_spec.rb +22 -0
  71. data/spec/audio_feed_manager/id3_tags_spec.rb +26 -0
  72. data/spec/audio_feed_manager/new_model_creator_spec.rb +44 -0
  73. data/spec/audio_feed_manager/rss_repository_spec.rb +34 -0
  74. data/spec/audio_feed_manager/s3_gateway_spec.rb +51 -0
  75. data/spec/audio_feed_manager/secret_token_generator_spec.rb +13 -0
  76. data/spec/audio_feed_manager/support/getter_setter_method_spec.rb +77 -0
  77. data/spec/audio_feed_manager/unique_id_generator_spec.rb +23 -0
  78. data/spec/fixtures/test.mp3 +0 -0
  79. data/spec/fixtures/test.txt +1 -0
  80. data/spec/help_spec.rb +64 -0
  81. data/spec/initializing_spec.rb +12 -0
  82. data/spec/managing_audio_files_spec.rb +21 -0
  83. data/spec/managing_feeds_spec.rb +51 -0
  84. data/spec/publishing_spec.rb +24 -0
  85. data/spec/s3_credentials.yml.sample +5 -0
  86. data/spec/spec_helper.rb +17 -0
  87. data/spec/support/builders.rb +26 -0
  88. data/spec/support/fake_console.rb +13 -0
  89. data/spec/support/fakes.rb +5 -0
  90. data/spec/support/integration_helpers.rb +38 -0
  91. metadata +297 -0
@@ -0,0 +1,26 @@
1
+ module AudioFeedManager
2
+ describe UpdateFeedRss do
3
+ fake(:feed_repository)
4
+ fake(:rss_generator)
5
+ let(:console) { FakeConsole.new }
6
+
7
+ let(:update_feed_rss) { isolate(UpdateFeedRss) }
8
+
9
+ it "generates the feed RSS" do
10
+ feed = build_feed
11
+ stub(feed_repository).fetch("feeds/foo") { feed }
12
+
13
+ update_feed_rss.run(feed: "feeds/foo")
14
+
15
+ expect(rss_generator).to have_received.generate(feed)
16
+ end
17
+
18
+ it "prints an error message when feed not found" do
19
+ stub(feed_repository).fetch("feeds/foo") { raise FeedNotFound.for_id("feeds/foo") }
20
+
21
+ update_feed_rss.run(feed: "feeds/foo")
22
+
23
+ expect(console.out).to include("not found")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ module AudioFeedManager
2
+ describe CLI do
3
+ fake(:command, arguments: ArgumentsSpecification.new, name: "init") { InitializeProject }
4
+ fake(:commands_list)
5
+ fake(:arguments_parser)
6
+ fake(:help)
7
+ fake(:console)
8
+ let(:arguments) { Arguments.from_hash(project_dir: "my-project-name") }
9
+
10
+ let(:cli) { isolate(CLI) }
11
+
12
+ it "runs the specified command" do
13
+ stub(commands_list).get(["init", "my-project-name"]) { [command, ["my-project-name"]]}
14
+ stub(arguments_parser).parse(command.arguments, ["my-project-name"]) { arguments }
15
+
16
+ cli.run(["init", "my-project-name"])
17
+
18
+ expect(command).to have_received.run(project_dir: "my-project-name")
19
+ end
20
+
21
+ it "prints command usage if command arguments are invalid and stops the application" do
22
+ stub(commands_list).get(["init"]) { [command, []]}
23
+ stub(arguments_parser).parse(command.arguments, []) { raise InvalidArguments }
24
+
25
+ expect {
26
+ cli.run(["init"])
27
+ }.to raise_error(StopApplication)
28
+
29
+ expect(help).to have_received.print_command_usage("init")
30
+ end
31
+
32
+ it "prints usage if command is invalid and stops the application" do
33
+ stub(commands_list).get(["foo"]) { raise UnknownCommand }
34
+
35
+ expect {
36
+ cli.run(["foo"])
37
+ }.to raise_error(StopApplication)
38
+
39
+ expect(help).to have_received.print_usage
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,23 @@
1
+ module AudioFeedManager
2
+ describe DirectoryLister do
3
+ let(:directory_lister) { isolate(DirectoryLister) }
4
+
5
+ it "returns an empty array for non-existent directories" do
6
+ files = directory_lister.list("/tmp/asdfasdfasdfasdfasdfasdf")
7
+
8
+ expect(files).to eq([])
9
+ end
10
+
11
+ it "returns a list of all the files in a given directory, sorted by name" do
12
+ FileUtils.rm_rf("/tmp/foobar")
13
+ FileUtils.mkdir_p("/tmp/foobar")
14
+ FileUtils.touch("/tmp/foobar/foo.txt")
15
+ FileUtils.touch("/tmp/foobar/bar.txt")
16
+ FileUtils.touch("/tmp/foobar/baz.txt")
17
+
18
+ files = directory_lister.list("/tmp/foobar")
19
+
20
+ expect(files).to eq(["bar.txt", "baz.txt", "foo.txt"])
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ module AudioFeedManager
2
+ describe FeedItemsRepository do
3
+ let(:items_directory) { Pathname.new("/tmp/foo") }
4
+ let(:feed_items_repository) { isolate(FeedItemsRepository) }
5
+ fake(:audio_file_repository)
6
+
7
+ before do
8
+ FileUtils.rm_rf(items_directory)
9
+ FileUtils.mkdir_p(items_directory)
10
+ end
11
+
12
+ it "returns an empty array for a feed with no items" do
13
+ feed = build_feed
14
+
15
+ expect(feed_items_repository.list(feed)).to eq([])
16
+ end
17
+
18
+ it "returns a list of audio files added for a feed, latest first" do
19
+ feed = build_feed(id: "feeds/abc")
20
+ other_feed = build_feed(id: "feeds/def")
21
+ foo = AudioFile.new(id: "audio_files/foo")
22
+ bar = AudioFile.new(id: "audio_files/bar")
23
+ baz = AudioFile.new(id: "audio_files/baz")
24
+ stub(audio_file_repository).fetch("audio_files/foo") { foo }
25
+ stub(audio_file_repository).fetch("audio_files/bar") { bar }
26
+ stub(audio_file_repository).fetch("audio_files/baz") { baz }
27
+ feed_items_repository.add(feed, foo)
28
+ feed_items_repository.add(feed, bar)
29
+ feed_items_repository.add(other_feed, baz)
30
+
31
+ expect(feed_items_repository.list(feed)).to eq([bar, foo])
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ module AudioFeedManager
4
+ describe FeedRepository do
5
+ let(:feed_repository) { isolate(FeedRepository) }
6
+ let(:feeds_directory) { Pathname.new("/tmp/foo/feeds") }
7
+ let(:feeds_prefix) { "feeds" }
8
+ fake(:new_model_creator)
9
+ fake(:storage)
10
+ fake(:directory_lister)
11
+
12
+ it "stores new feeds" do
13
+ saved_feed = Feed.new(id: "feeds/foo")
14
+ feed = Feed.new(title: "Hello World!")
15
+ mock(new_model_creator).create(feed, directory: feeds_directory,
16
+ prefix: feeds_prefix) { saved_feed }
17
+
18
+ feed = feed_repository.add(feed)
19
+ end
20
+
21
+ it "fetches the stored feeds" do
22
+ stub(storage).read("feeds/hello-world") { {id: "feeds/hello-world", title: "Hello World"} }
23
+
24
+ expect(feed_repository.fetch("feeds/hello-world")).to eq(Feed.new(id: "feeds/hello-world", title: "Hello World"))
25
+ end
26
+
27
+ it "raises FeedNotFound when a feed by given id does not exist" do
28
+ stub(storage).read("feeds/hello-world") { raise FileNotFound }
29
+
30
+ expect{feed_repository.fetch("feeds/hello-world")}.to raise_error(FeedNotFound)
31
+ end
32
+
33
+ it "lists the feeds" do
34
+ stub(directory_lister).list(feeds_directory) { ["hello-world"] }
35
+ stub(storage).read("feeds/hello-world") { {id: "feeds/hello-world", title: "Hello World"} }
36
+
37
+ expect(feed_repository.list).to include(Feed.new(id: "feeds/hello-world", title: "Hello World"))
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,22 @@
1
+ module AudioFeedManager
2
+ describe FileStorage do
3
+ let(:directory) { Pathname.new("/tmp/foo") }
4
+
5
+ let(:storage) { isolate(FileStorage) }
6
+
7
+ before do
8
+ FileUtils.rm_rf(directory)
9
+ FileUtils.mkdir_p(directory.join("feeds"))
10
+ end
11
+
12
+ it "stores the contents in a specified file" do
13
+ storage.store("feeds/hello", {id: 1, title: "hello!"})
14
+
15
+ expect(storage.read("feeds/hello")).to eq(id: 1, title: "hello!")
16
+ end
17
+
18
+ it "raises an error, when the given file does not exist" do
19
+ expect{ storage.read("feeds/hello") }.to raise_error(FileNotFound)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ module AudioFeedManager
2
+ describe Id3Tags do
3
+ let(:id3tags) { isolate(Id3Tags) }
4
+
5
+ it "reads ID3 tags from an mp3 file" do
6
+ tags = id3tags.read(fixture_file("test.mp3"))
7
+
8
+ expect(tags.title).to eq("My first audio file")
9
+ expect(tags.artist).to eq("Adam Pohorecki")
10
+ end
11
+
12
+ it "returns empty tags for a file that does not exist" do
13
+ tags = id3tags.read(Pathname.new("/tmp/file-which-does-not-exist"))
14
+
15
+ expect(tags.title).to eq(nil)
16
+ expect(tags.artist).to eq(nil)
17
+ end
18
+
19
+ it "returns empty tags for a file that is not an mp3 file" do
20
+ tags = id3tags.read(fixture_file("test.txt"))
21
+
22
+ expect(tags.title).to eq(nil)
23
+ expect(tags.artist).to eq(nil)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ module AudioFeedManager
2
+ describe NewModelCreator do
3
+ class SampleModel < Struct.new(:id, :title, :secret_token, :foo)
4
+ include HashConstructor
5
+ end
6
+
7
+ let(:new_model_creator) { isolate(NewModelCreator) }
8
+ let(:directory) { Pathname.new("/tmp/foo/feeds") }
9
+ let(:prefix) { "feeds" }
10
+ fake(:unique_id_generator, generate: "hello-world")
11
+ fake(:secret_token_generator, generate: "secret-token")
12
+ fake(:storage)
13
+
14
+ it "sets the id for the added model" do
15
+ stub(unique_id_generator).generate("Hello World!", directory) { "hello-world" }
16
+ model = SampleModel.new(title: "Hello World!")
17
+
18
+ new_model_creator.create(model, prefix: prefix, directory: directory)
19
+
20
+ expect(model.id).to eq("feeds/hello-world")
21
+ end
22
+
23
+ it "stores the added model" do
24
+ model = SampleModel.new(title: "Hello World!", foo: "hello there")
25
+
26
+ new_model_creator.create(model, prefix: prefix, directory: directory)
27
+
28
+ expect(storage).to have_received.store(
29
+ "feeds/hello-world",
30
+ id: "feeds/hello-world",
31
+ title: "Hello World!",
32
+ secret_token: "secret-token",
33
+ foo: "hello there",
34
+ )
35
+ end
36
+
37
+ it "assigns a secret token to the created model" do
38
+ model = new_model_creator.create(SampleModel.new(title: "Hello World!"), prefix: prefix, directory: directory)
39
+
40
+ expect(model.secret_token).to eq("secret-token")
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module AudioFeedManager
2
+ describe RSSRepository do
3
+ fake(:url_maker, feed_url: "http://example.com/feed.xml", audio_file_url: "http://example.com/audio/foo.mp3")
4
+ let(:rss_files_directory) { Pathname.new("/tmp/my-project/rss") }
5
+
6
+ before do
7
+ FileUtils.rm_rf(rss_files_directory)
8
+ FileUtils.mkdir_p(rss_files_directory)
9
+ end
10
+
11
+ it "stores an RSS feed under rss/:secret_token.xml" do
12
+ feed = build_feed(id: "feeds/hello",
13
+ title: "My First Feed",
14
+ description: "some description",
15
+ secret_token: "abcdefgh")
16
+ audio_file = build_audio_file(secret_token: "foobar",
17
+ extension: ".mp3",
18
+ title: "Some audio file",
19
+ author: "Audio file author")
20
+ rss_repository = isolate(RSSRepository)
21
+
22
+ rss_repository.store(feed, [audio_file])
23
+
24
+ feed_content = File.read("/tmp/my-project/rss/abcdefgh.xml")
25
+ expect(feed_content).to include("<?xml")
26
+ expect(feed_content).to include("My First Feed")
27
+ expect(feed_content).to include("some description")
28
+ expect(feed_content).not_to include("feeds/hello")
29
+ expect(feed_content).to include("Some audio file")
30
+ expect(feed_content).to include("Audio file author")
31
+ expect(feed_content).to include("http://example.com/audio/foo.mp3")
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,51 @@
1
+ require 'net/http'
2
+
3
+ module AudioFeedManager
4
+ describe S3Gateway, :slow do
5
+ let(:config) { Config.new(s3_bucket: s3_config["bucket"],
6
+ s3_access_key: s3_config["access_key"],
7
+ s3_secret: s3_config["secret_key"],
8
+ s3_region: s3_config["region"]) }
9
+
10
+ let(:s3_gateway) { isolate(S3Gateway) }
11
+
12
+ it "syncs files to S3" do
13
+ unique_key = "test/#{SecureRandom.hex}"
14
+ file_name = :not_called
15
+
16
+ s3_gateway.sync(unique_key, fixture_file("test.mp3")) { |f| file_name = f }
17
+
18
+ expect(file_name).to eq(unique_key)
19
+ end
20
+
21
+ it "does not sync the same file twice" do
22
+ unique_key = "test/#{SecureRandom.hex}"
23
+ file_name = :not_called
24
+
25
+ s3_gateway.sync(unique_key, fixture_file("test.mp3"))
26
+ s3_gateway.sync(unique_key, fixture_file("test.mp3")) { |f| file_name = f }
27
+
28
+ expect(file_name).to eq(:not_called)
29
+ end
30
+
31
+ it "syncs the same file twice if the contents change" do
32
+ unique_key = "test/#{SecureRandom.hex}"
33
+ file_name = :not_called
34
+
35
+ s3_gateway.sync(unique_key, fixture_file("test.mp3"))
36
+ s3_gateway.sync(unique_key, fixture_file("test.txt")) { |f| file_name = f }
37
+
38
+ expect(file_name).to eq(unique_key)
39
+ end
40
+
41
+ it "makes the file publicly accessible" do
42
+ unique_key = "test/#{SecureRandom.hex}"
43
+
44
+ s3_gateway.sync(unique_key, fixture_file("test.txt"))
45
+
46
+ url = URI.parse(s3_gateway.url(unique_key))
47
+ content = File.read(fixture_file("test.txt"))
48
+ expect(Net::HTTP.get(url)).to eq(content)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,13 @@
1
+ module AudioFeedManager
2
+ describe SecretTokenGenerator do
3
+ let(:generator) { isolate(SecretTokenGenerator) }
4
+
5
+ it "generates 16-character strings" do
6
+ expect(generator.generate.size).to eq(16)
7
+ end
8
+
9
+ it "generates unique strings" do
10
+ expect(generator.generate).not_to eq(generator.generate)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,77 @@
1
+ module AudioFeedManager
2
+ describe GetterSetterMethod do
3
+ context "without a default value" do
4
+ klass = Class.new do
5
+ extend GetterSetterMethod
6
+
7
+ get_set :foo
8
+ get_set :bar
9
+ end
10
+
11
+ it "returns nil by default" do
12
+ instance = klass.new
13
+
14
+ expect(instance.foo).to be_nil
15
+ expect(instance.bar).to be_nil
16
+ end
17
+
18
+ it "sets the value when value given" do
19
+ instance = klass.new
20
+
21
+ instance.foo "bar"
22
+
23
+ expect(instance.foo).to eq("bar")
24
+ end
25
+
26
+ it "does not overwrite other values when setting one property" do
27
+ instance = klass.new
28
+
29
+ instance.foo "bar"
30
+
31
+ expect(instance.bar).to be_nil
32
+ end
33
+ end
34
+
35
+ context "with a default value" do
36
+ klass = Class.new do
37
+ extend GetterSetterMethod
38
+
39
+ get_set(:foo) { bar }
40
+ get_set :bar
41
+ get_set(:baz) { "hello" }
42
+ end
43
+
44
+ it "returns the default value" do
45
+ instance = klass.new
46
+
47
+ expect(instance.baz).to eq("hello")
48
+ end
49
+
50
+ it "overwrites the value when value given" do
51
+ instance = klass.new
52
+
53
+ instance.baz "aaa"
54
+
55
+ expect(instance.baz).to eq("aaa")
56
+ end
57
+
58
+ it "evaluates the default block lazily" do
59
+ instance = klass.new
60
+
61
+ instance.bar "aaa"
62
+
63
+ expect(instance.foo).to eq("aaa")
64
+ end
65
+
66
+ it "caches the value once set" do
67
+ instance = klass.new
68
+
69
+ instance.bar "aaa"
70
+ instance.foo
71
+ instance.bar "bbb"
72
+
73
+ expect(instance.foo).to eq("aaa")
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,23 @@
1
+ module AudioFeedManager
2
+ describe UniqueIdGenerator do
3
+ fake(:directory_lister)
4
+
5
+ let(:generator) { isolate(UniqueIdGenerator) }
6
+
7
+ it "generates ids based on the given name" do
8
+ stub(directory_lister).list("/foo") { [] }
9
+
10
+ id = generator.generate("Hello World!", "/foo")
11
+
12
+ expect(id).to eq("hello-world")
13
+ end
14
+
15
+ it "suffixes the id with a number if the name is not unique" do
16
+ stub(directory_lister).list("/foo") { ["hello-world", "foo-bar"] }
17
+
18
+ id = generator.generate("Hello World!", "/foo")
19
+
20
+ expect(id).to eq("hello-world-1")
21
+ end
22
+ end
23
+ end
Binary file
@@ -0,0 +1 @@
1
+ Hello!
data/spec/help_spec.rb ADDED
@@ -0,0 +1,64 @@
1
+ require 'stringio'
2
+
3
+ describe "help commands" do
4
+ let(:stdin) { StringIO.new }
5
+ let(:stderr) { StringIO.new }
6
+
7
+ it "prints help when no arguments given" do
8
+ AudioFeedManager.run(
9
+ argv: [],
10
+ stdin: stdin,
11
+ stderr: stderr,
12
+ )
13
+
14
+ expect(stderr.string).to include("Usage:")
15
+ expect(stderr.string).to include("init")
16
+ end
17
+
18
+ it "prints help with the help command" do
19
+ AudioFeedManager.run(
20
+ argv: ["help"],
21
+ stdin: stdin,
22
+ stderr: stderr,
23
+ )
24
+
25
+ expect(stderr.string).to include("Usage:")
26
+ expect(stderr.string).to include("init")
27
+ end
28
+
29
+ it "prints help with an unknown command" do
30
+ AudioFeedManager.run(
31
+ argv: ["asdfasdfa"],
32
+ stdin: stdin,
33
+ stderr: stderr,
34
+ exit: ->(out) {}
35
+ )
36
+
37
+ expect(stderr.string).to include("Usage:")
38
+ expect(stderr.string).to include("init")
39
+ end
40
+
41
+ it "prints help for specific commands" do
42
+ AudioFeedManager.run(
43
+ argv: ["help", "init"],
44
+ stdin: stdin,
45
+ stderr: stderr,
46
+ )
47
+
48
+ expect(stderr.string).to include("Usage:")
49
+ expect(stderr.string).to include("init")
50
+ expect(stderr.string).to include("<PROJECT_DIR>")
51
+ end
52
+
53
+ it "prints help for multi-word commands" do
54
+ AudioFeedManager.run(
55
+ argv: ["help", "feeds", "add"],
56
+ stdin: stdin,
57
+ stderr: stderr,
58
+ )
59
+
60
+ expect(stderr.string).to include("Usage:")
61
+ expect(stderr.string).to include("feeds add")
62
+ expect(stderr.string).to include("<TITLE>")
63
+ end
64
+ end
@@ -0,0 +1,12 @@
1
+ describe "Initializing project" do
2
+ it "creates the project directory and some support files/directories" do
3
+ FileUtils.rm_rf("/tmp/my-test-project")
4
+
5
+ init_project("/tmp/my-test-project")
6
+
7
+ expect(File.exists?("/tmp/my-test-project")).to be(true)
8
+ expect(File.exists?("/tmp/my-test-project/feeds")).to be(true)
9
+ expect(File.exists?("/tmp/my-test-project/audio_files")).to be(true)
10
+ expect(File.exists?("/tmp/my-test-project/config.yml")).to be(true)
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ describe "Managing audio files" do
2
+ it "adds audio files to feeds" do
3
+ dir = init_project
4
+ feed = add_feed(dir)
5
+
6
+ AudioFeedManager.run(
7
+ pwd: dir,
8
+ stdout: StringIO.new,
9
+ argv: ["audio", "add", feed.id, fixture_file("test.mp3")]
10
+ )
11
+
12
+ out = StringIO.new
13
+ AudioFeedManager.run(
14
+ pwd: dir,
15
+ stdout: out,
16
+ argv: ["feeds", "show", feed.id]
17
+ )
18
+
19
+ expect(out.string).to include("My first audio file")
20
+ end
21
+ end
@@ -0,0 +1,51 @@
1
+ describe "Managing Feeds" do
2
+ it "adds feeds using afm feeds add" do
3
+ dir = init_project
4
+
5
+ AudioFeedManager.run(
6
+ pwd: dir,
7
+ stdin: StringIO.new("some description"),
8
+ stdout: StringIO.new,
9
+ argv: ["feeds", "add", "Hello World!"]
10
+ )
11
+
12
+ stdout = StringIO.new
13
+ AudioFeedManager.run(
14
+ pwd: dir,
15
+ argv: ["feeds", "list"],
16
+ stdout: stdout,
17
+ )
18
+
19
+ expect(stdout.string).to include("Hello World!")
20
+ end
21
+
22
+ it "allows getting the feed url" do
23
+ dir = init_project
24
+ feed = add_feed(dir)
25
+
26
+ out = StringIO.new
27
+ AudioFeedManager.run(
28
+ pwd: dir,
29
+ stdout: out,
30
+ argv: ["feeds", "get-url", feed.id]
31
+ )
32
+
33
+ expect(out.string).to include("http")
34
+ end
35
+
36
+ it "allows regenerating feed rss" do
37
+ dir = init_project
38
+ feed = add_feed(dir)
39
+
40
+ rss_files = File.join(dir, "rss/*.xml")
41
+ Dir[rss_files].each{|f| FileUtils.rm_rf(f)}
42
+
43
+ AudioFeedManager.run(
44
+ pwd: dir,
45
+ stdout: StringIO.new,
46
+ argv: ["feeds", "update-rss", feed.id]
47
+ )
48
+
49
+ expect(Dir[rss_files]).not_to eq([])
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require 'net/http'
2
+
3
+ describe "Publishing content to S3", :slow do
4
+ it "publishes the RSS and data files" do
5
+ dir = init_project
6
+ feed = add_feed(dir)
7
+ add_audio_file(dir, feed)
8
+
9
+ AudioFeedManager.run(
10
+ pwd: dir,
11
+ stdout: StringIO.new,
12
+ argv: ["publish"]
13
+ )
14
+
15
+ AudioFeedManager.run(
16
+ pwd: dir,
17
+ stdout: out = StringIO.new,
18
+ argv: ["feeds", "get-url", feed.id]
19
+ )
20
+ feed_url = out.string.chomp
21
+
22
+ expect(Net::HTTP.get(URI.parse(feed_url))).to include("Hello World!")
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ secret_key: "SECRET"
3
+ access_key: "ACCESS"
4
+ bucket: "BUCKET"
5
+ region: "us-west-2"
@@ -0,0 +1,17 @@
1
+ require 'audio-feed-manager'
2
+ require 'bogus/rspec'
3
+ require 'dependor/rspec'
4
+ require "fileutils"
5
+
6
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each do |file|
7
+ require file
8
+ end
9
+
10
+ Bogus.configure do |config|
11
+ config.search_modules = [AudioFeedManager]
12
+ end
13
+
14
+ RSpec.configure do |config|
15
+ config.include IntegrationHelpers
16
+ config.include Builders
17
+ end