Skip to content

Commit b4c493d

Browse files
committed
Add tests for SoundcloudCommentsExtractor to handle null next_href and empty comments
1 parent 81da2b2 commit b4c493d

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package org.schabi.newpipe.extractor.services.soundcloud;
2+
3+
import static org.junit.jupiter.api.Assertions.assertFalse;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
6+
7+
import org.junit.jupiter.api.Nested;
8+
import org.junit.jupiter.api.Test;
9+
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
10+
import org.schabi.newpipe.extractor.Page;
11+
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
12+
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
13+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
14+
import org.schabi.newpipe.extractor.services.DefaultSimpleExtractorTest;
15+
16+
import java.io.IOException;
17+
18+
public class SoundcloudCommentsExtractorTest {
19+
20+
/**
21+
* Regression test for <a href="https://github.com/TeamNewPipe/NewPipeExtractor/issues/1243">
22+
* issue #1243</a>: when the SoundCloud API returns {@code "next_href": null} (no more pages),
23+
* a subsequent call to {@link CommentsExtractor#getPage(Page)} with a null URL must not throw
24+
* {@link IllegalArgumentException} ("Page doesn't contain an URL"). Instead the extractor
25+
* must return {@link InfoItemsPage#emptyPage()}.
26+
*
27+
* <p>The crash manifests during pagination: the last page of comments stores
28+
* {@code new Page(null)} as the next page, and when Paging 3 tries to fetch it the
29+
* exception propagates and kills the app.</p>
30+
*/
31+
@Nested
32+
class TrackWithComments extends DefaultSimpleExtractorTest<CommentsExtractor> {
33+
// This track is known to reproduce issue #1243: it has comments, but when pagination
34+
// exhausts the pages the API returns next_href=null, which previously caused a crash.
35+
private static final String URL = "https://soundcloud.com/user-722618400/a-real-playa";
36+
37+
@Override
38+
protected CommentsExtractor createExtractor() throws Exception {
39+
return SoundCloud.getCommentsExtractor(URL);
40+
}
41+
42+
/**
43+
* The initial page must load successfully without throwing any exception.
44+
*/
45+
@Test
46+
void testGetInitialPageSucceeds() throws IOException, ExtractionException {
47+
final InfoItemsPage<CommentsInfoItem> page = extractor().getInitialPage();
48+
// The track has comments; we only assert the call itself does not throw
49+
// and that the result is a valid (non-null) page.
50+
assertTrue(page.getErrors().isEmpty(),
51+
"Expected no extractor errors on initial page");
52+
}
53+
54+
/**
55+
* Regression test for issue #1243: calling {@link CommentsExtractor#getPage(Page)} with a
56+
* {@link Page} whose URL is null (which is what gets stored when {@code next_href} is
57+
* absent in the API response) must return {@link InfoItemsPage#emptyPage()} rather than
58+
* throw {@link IllegalArgumentException}.
59+
*/
60+
@Test
61+
void testGetPageWithNullUrlReturnsEmptyPage() throws IOException, ExtractionException {
62+
final InfoItemsPage<CommentsInfoItem> page = extractor().getPage(new Page((String) null));
63+
assertTrue(page.getItems().isEmpty(),
64+
"Expected empty items when page URL is null");
65+
assertFalse(page.hasNextPage(),
66+
"Expected no next page when page URL is null");
67+
}
68+
}
69+
70+
/**
71+
* Tests a SoundCloud track that has no comments.
72+
*
73+
* <p>Verifies that the extractor handles an empty collection gracefully:
74+
* the initial page must load without error, return no items, and have no next page.</p>
75+
*/
76+
@Nested
77+
class TrackWithNoComments extends DefaultSimpleExtractorTest<CommentsExtractor> {
78+
private static final String URL = "https://soundcloud.com/user285130010/jdkskls";
79+
80+
@Override
81+
protected CommentsExtractor createExtractor() throws Exception {
82+
return SoundCloud.getCommentsExtractor(URL);
83+
}
84+
85+
/**
86+
* The initial page must load successfully, return an empty items list,
87+
* and report no next page.
88+
*/
89+
@Test
90+
void testGetInitialPageIsEmpty() throws IOException, ExtractionException {
91+
final InfoItemsPage<CommentsInfoItem> page = extractor().getInitialPage();
92+
assertTrue(page.getErrors().isEmpty(),
93+
"Expected no extractor errors on initial page");
94+
assertTrue(page.getItems().isEmpty(),
95+
"Expected no comments for a track with no comments");
96+
assertFalse(page.hasNextPage(),
97+
"Expected no next page for a track with no comments");
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)