2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
20 from datetime
import datetime
, timedelta
22 from django
.test
import TestCase
24 from mygpo
.podcasts
.models
import Podcast
, Episode
27 def create_podcast(**kwargs
):
28 return Podcast
.objects
.create(id=uuid
.uuid1(), **kwargs
)
31 class PodcastTests(unittest
.TestCase
):
32 """ Test podcasts and their properties """
34 def test_next_update(self
):
35 """ Test calculation of Podcast.next_update """
36 last_update
= datetime(2014, 3, 31, 11, 00)
37 update_interval
= 123 # hours
39 # create an "old" podcast with update-information
40 create_podcast(last_update
=last_update
, update_interval
=update_interval
)
42 # the podcast should be the next to be updated
43 p
= Podcast
.objects
.all().order_by_next_update().first()
45 # assert that the next_update property is calculated correctly
46 self
.assertEqual(p
.next_update
,
47 last_update
+ timedelta(hours
=update_interval
))
50 def test_get_or_create_for_url(self
):
51 """ Test that get_or_create_for_url returns existing Podcast """
52 URL
= 'http://example.com/get_or_create.rss'
53 p1
= Podcast
.objects
.get_or_create_for_url(URL
)
54 p2
= Podcast
.objects
.get_or_create_for_url(URL
)
55 self
.assertEqual(p1
.pk
, p2
.pk
)
57 def test_episode_count(self
):
58 """ Test if Podcast.episode_count is updated correctly """
59 PODCAST_URL
= 'http://example.com/podcast.rss'
60 EPISODE_URL
= 'http://example.com/episode%d.mp3'
63 p
= Podcast
.objects
.get_or_create_for_url(PODCAST_URL
)
64 for n
in range(NUM_EPISODES
):
65 Episode
.objects
.get_or_create_for_url(p
, EPISODE_URL
% (n
, ))
67 p
= Podcast
.objects
.get(pk
=p
.pk
)
68 self
.assertEqual(p
.episode_count
, NUM_EPISODES
)
70 # the episodes already exist this time -- no episode is created
71 for n
in range(NUM_EPISODES
):
72 Episode
.objects
.get_or_create_for_url(p
, EPISODE_URL
% (n
, ))
74 p
= Podcast
.objects
.get(pk
=p
.pk
)
75 self
.assertEqual(p
.episode_count
, NUM_EPISODES
)
77 real_count
= Episode
.objects
.filter(podcast
=p
).count()
78 self
.assertEqual(real_count
, NUM_EPISODES
)
81 class PodcastGroupTests(unittest
.TestCase
):
82 """ Test grouping of podcasts """
85 self
.podcast1
= create_podcast()
86 self
.podcast2
= create_podcast()
88 group
= self
.podcast1
.group_with(self
.podcast2
, 'My Group', 'p1', 'p2')
90 self
.assertIn(self
.podcast1
, group
.podcast_set
.all())
91 self
.assertIn(self
.podcast2
, group
.podcast_set
.all())
92 self
.assertEqual(len(group
.podcast_set
.all()), 2)
93 self
.assertEqual(group
.title
, 'My Group')
94 self
.assertEqual(self
.podcast1
.group_member_name
, 'p1')
95 self
.assertEqual(self
.podcast2
.group_member_name
, 'p2')
98 self
.podcast3
= create_podcast()
100 group
= self
.podcast1
.group_with(self
.podcast3
, 'My Group', 'p1', 'p3')
102 self
.assertIn(self
.podcast3
, group
.podcast_set
.all())
103 self
.assertEqual(self
.podcast3
.group_member_name
, 'p3')
105 # add group to podcast
106 self
.podcast4
= create_podcast()
108 group
= self
.podcast4
.group_with(self
.podcast1
, 'My Group', 'p4', 'p1')
110 self
.assertIn(self
.podcast4
, group
.podcast_set
.all())
111 self
.assertEqual(self
.podcast4
.group_member_name
, 'p4')
114 class SlugTests(TestCase
):
115 """ Test various slug functionality """
117 def test_update_slugs(self
):
119 # this is the current number of queries when writing the test; this has
120 # not been optimized in any particular way, it should just be used to
121 # alert when something changes
122 podcast
= create_podcast()
124 with self
.assertNumQueries(8):
125 # set the canonical slug
126 podcast
.set_slug('podcast-1')
127 self
.assertEqual(podcast
.slug
, 'podcast-1')
129 with self
.assertNumQueries(9):
130 # set a new list of slugs
131 podcast
.set_slugs(['podcast-2', 'podcast-1'])
132 self
.assertEqual(podcast
.slug
, 'podcast-2')
134 with self
.assertNumQueries(2):
135 # remove the canonical slug
136 podcast
.remove_slug('podcast-2')
137 self
.assertEqual(podcast
.slug
, 'podcast-1')
139 with self
.assertNumQueries(3):
140 # add a non-canonical slug
141 podcast
.add_slug('podcast-3')
142 self
.assertEqual(podcast
.slug
, 'podcast-1')
145 def load_tests(loader
, tests
, ignore
):
146 tests
.addTest(unittest
.TestLoader().loadTestsFromTestCase(PodcastTests
))
147 tests
.addTest(unittest
.TestLoader().loadTestsFromTestCase(PodcastGroupTests
))
148 tests
.addTest(unittest
.TestLoader().loadTestsFromTestCase(SlugTests
))