yourub 2.0.2 → 3.0.0
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +0 -4
- data/Gemfile +3 -3
- data/README.md +59 -53
- data/config/yourub.yml +0 -2
- data/lib/yourub/client.rb +92 -16
- data/lib/yourub/config.rb +16 -10
- data/lib/yourub/country_codes.rb +28 -0
- data/lib/yourub/meta_search.rb +116 -43
- data/lib/yourub/rest/categories.rb +6 -5
- data/lib/yourub/rest/request.rb +13 -13
- data/lib/yourub/rest/videos.rb +1 -3
- data/lib/yourub/result.rb +1 -0
- data/lib/yourub/validator.rb +21 -28
- data/lib/yourub/version.rb +2 -2
- data/lib/yourub.rb +1 -0
- data/spec/fixtures/categories_list.json +316 -1
- data/spec/fixtures/search_list.json +182 -1
- data/spec/fixtures/video_with_200_views.json +63 -1
- data/spec/fixtures/videos_list.json +62 -1
- data/spec/support/shared_context_result_load_fixture.rb +12 -1
- data/spec/support/shared_context_result_search_list.rb +18 -4
- data/spec/support/shared_context_result_search_list_with_single_videos.rb +30 -8
- data/spec/support/shared_context_stub_client_connection.rb +0 -8
- data/spec/yourub/client_spec.rb +62 -1
- data/spec/yourub/count_spec.rb +7 -7
- data/spec/yourub/integration.rb +3 -7
- data/spec/yourub/meta_search_spec.rb +93 -56
- data/spec/yourub/rest/categories_spec.rb +30 -6
- data/spec/yourub/rest/request_spec.rb +3 -3
- data/spec/yourub/validator_spec.rb +36 -16
- data/yourub.gemspec +3 -3
- metadata +23 -22
- data/spec/fixtures/categories_list_formatted.json +0 -1
- data/spec/fixtures/single_video.json +0 -1
|
@@ -1 +1,182 @@
|
|
|
1
|
-
|
|
1
|
+
{
|
|
2
|
+
"kind": "youtube#searchListResponse",
|
|
3
|
+
"etag": "1Hj13BmpcyyXVaPnfQJ4LMaJw8s",
|
|
4
|
+
"nextPageToken": "CAUQAA",
|
|
5
|
+
"regionCode": "DE",
|
|
6
|
+
"pageInfo": {
|
|
7
|
+
"totalResults": 1000000,
|
|
8
|
+
"resultsPerPage": 5
|
|
9
|
+
},
|
|
10
|
+
"items": [
|
|
11
|
+
{
|
|
12
|
+
"kind": "youtube#searchResult",
|
|
13
|
+
"etag": "dm1jPHgd2f_mTEEL7X9dx_cbZ5w",
|
|
14
|
+
"id": {
|
|
15
|
+
"kind": "youtube#video",
|
|
16
|
+
"videoId": "yIlTwwJv1Ac"
|
|
17
|
+
},
|
|
18
|
+
"snippet": {
|
|
19
|
+
"publishedAt": "2026-03-24T15:10:42Z",
|
|
20
|
+
"channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
|
|
21
|
+
"title": "Ignition: NASA's Plan for The Moon",
|
|
22
|
+
"description": "Join us as we provide an update on the implementation of the National Space Policy and how we're accelerating preparations for ...",
|
|
23
|
+
"thumbnails": {
|
|
24
|
+
"default": {
|
|
25
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/default.jpg",
|
|
26
|
+
"width": 120,
|
|
27
|
+
"height": 90
|
|
28
|
+
},
|
|
29
|
+
"medium": {
|
|
30
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/mqdefault.jpg",
|
|
31
|
+
"width": 320,
|
|
32
|
+
"height": 180
|
|
33
|
+
},
|
|
34
|
+
"high": {
|
|
35
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/hqdefault.jpg",
|
|
36
|
+
"width": 480,
|
|
37
|
+
"height": 360
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"channelTitle": "NASA",
|
|
41
|
+
"liveBroadcastContent": "none",
|
|
42
|
+
"publishTime": "2026-03-24T15:10:42Z"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"kind": "youtube#searchResult",
|
|
47
|
+
"etag": "r6BRaBZ00wUP7Ro3W-nheq2kY7Q",
|
|
48
|
+
"id": {
|
|
49
|
+
"kind": "youtube#video",
|
|
50
|
+
"videoId": "LZea4h8zxLY"
|
|
51
|
+
},
|
|
52
|
+
"snippet": {
|
|
53
|
+
"publishedAt": "2026-03-24T21:49:56Z",
|
|
54
|
+
"channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
|
|
55
|
+
"title": "Ignition: NASA News Conference (March 24, 2026)",
|
|
56
|
+
"description": "We're holding a live news conference to provide an update on the agency's progress toward implementing the National Space ...",
|
|
57
|
+
"thumbnails": {
|
|
58
|
+
"default": {
|
|
59
|
+
"url": "https://i.ytimg.com/vi/LZea4h8zxLY/default.jpg",
|
|
60
|
+
"width": 120,
|
|
61
|
+
"height": 90
|
|
62
|
+
},
|
|
63
|
+
"medium": {
|
|
64
|
+
"url": "https://i.ytimg.com/vi/LZea4h8zxLY/mqdefault.jpg",
|
|
65
|
+
"width": 320,
|
|
66
|
+
"height": 180
|
|
67
|
+
},
|
|
68
|
+
"high": {
|
|
69
|
+
"url": "https://i.ytimg.com/vi/LZea4h8zxLY/hqdefault.jpg",
|
|
70
|
+
"width": 480,
|
|
71
|
+
"height": 360
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"channelTitle": "NASA",
|
|
75
|
+
"liveBroadcastContent": "none",
|
|
76
|
+
"publishTime": "2026-03-24T21:49:56Z"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"kind": "youtube#searchResult",
|
|
81
|
+
"etag": "1ogiEy3B16P0k44pGzNidi8-_9s",
|
|
82
|
+
"id": {
|
|
83
|
+
"kind": "youtube#video",
|
|
84
|
+
"videoId": "RVxHWX688jM"
|
|
85
|
+
},
|
|
86
|
+
"snippet": {
|
|
87
|
+
"publishedAt": "2024-08-04T14:11:48Z",
|
|
88
|
+
"channelId": "UC415bOPUcGSamy543abLmRA",
|
|
89
|
+
"title": "NASA’s Next-Generation Space Suits",
|
|
90
|
+
"description": "Did you know NASA hasn't updated their space suit design in over 30 YEARS? It's becoming a major problem, especially since ...",
|
|
91
|
+
"thumbnails": {
|
|
92
|
+
"default": {
|
|
93
|
+
"url": "https://i.ytimg.com/vi/RVxHWX688jM/default.jpg",
|
|
94
|
+
"width": 120,
|
|
95
|
+
"height": 90
|
|
96
|
+
},
|
|
97
|
+
"medium": {
|
|
98
|
+
"url": "https://i.ytimg.com/vi/RVxHWX688jM/mqdefault.jpg",
|
|
99
|
+
"width": 320,
|
|
100
|
+
"height": 180
|
|
101
|
+
},
|
|
102
|
+
"high": {
|
|
103
|
+
"url": "https://i.ytimg.com/vi/RVxHWX688jM/hqdefault.jpg",
|
|
104
|
+
"width": 480,
|
|
105
|
+
"height": 360
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"channelTitle": "Cleo Abram",
|
|
109
|
+
"liveBroadcastContent": "none",
|
|
110
|
+
"publishTime": "2024-08-04T14:11:48Z"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"kind": "youtube#searchResult",
|
|
115
|
+
"etag": "hT5fYJRh6f23JPqZXcN1V-hRPBs",
|
|
116
|
+
"id": {
|
|
117
|
+
"kind": "youtube#video",
|
|
118
|
+
"videoId": "BYH6W9iCs2E"
|
|
119
|
+
},
|
|
120
|
+
"snippet": {
|
|
121
|
+
"publishedAt": "2026-03-24T20:05:32Z",
|
|
122
|
+
"channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
|
|
123
|
+
"title": "Ignition: NASA's Plan for Science and Discovery",
|
|
124
|
+
"description": "Join us for continuing coverage as our leaders discuss the agency's implementation of the National Space Policy and our plans to ...",
|
|
125
|
+
"thumbnails": {
|
|
126
|
+
"default": {
|
|
127
|
+
"url": "https://i.ytimg.com/vi/BYH6W9iCs2E/default.jpg",
|
|
128
|
+
"width": 120,
|
|
129
|
+
"height": 90
|
|
130
|
+
},
|
|
131
|
+
"medium": {
|
|
132
|
+
"url": "https://i.ytimg.com/vi/BYH6W9iCs2E/mqdefault.jpg",
|
|
133
|
+
"width": 320,
|
|
134
|
+
"height": 180
|
|
135
|
+
},
|
|
136
|
+
"high": {
|
|
137
|
+
"url": "https://i.ytimg.com/vi/BYH6W9iCs2E/hqdefault.jpg",
|
|
138
|
+
"width": 480,
|
|
139
|
+
"height": 360
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"channelTitle": "NASA",
|
|
143
|
+
"liveBroadcastContent": "none",
|
|
144
|
+
"publishTime": "2026-03-24T20:05:32Z"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"kind": "youtube#searchResult",
|
|
149
|
+
"etag": "AJIQJ7djmIIesED6iLnz9ae68Qg",
|
|
150
|
+
"id": {
|
|
151
|
+
"kind": "youtube#video",
|
|
152
|
+
"videoId": "J34PtfFShoU"
|
|
153
|
+
},
|
|
154
|
+
"snippet": {
|
|
155
|
+
"publishedAt": "2024-12-08T15:00:18Z",
|
|
156
|
+
"channelId": "UCUeZBocfxALSUdOgNJB5ySA",
|
|
157
|
+
"title": "NASA Spot Wreckage on Mars",
|
|
158
|
+
"description": "These incredibly eerie images were taken on another planet. What caused the wreckage and where did the images come from?",
|
|
159
|
+
"thumbnails": {
|
|
160
|
+
"default": {
|
|
161
|
+
"url": "https://i.ytimg.com/vi/J34PtfFShoU/default.jpg",
|
|
162
|
+
"width": 120,
|
|
163
|
+
"height": 90
|
|
164
|
+
},
|
|
165
|
+
"medium": {
|
|
166
|
+
"url": "https://i.ytimg.com/vi/J34PtfFShoU/mqdefault.jpg",
|
|
167
|
+
"width": 320,
|
|
168
|
+
"height": 180
|
|
169
|
+
},
|
|
170
|
+
"high": {
|
|
171
|
+
"url": "https://i.ytimg.com/vi/J34PtfFShoU/hqdefault.jpg",
|
|
172
|
+
"width": 480,
|
|
173
|
+
"height": 360
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"channelTitle": "Dr Ben Miles",
|
|
177
|
+
"liveBroadcastContent": "none",
|
|
178
|
+
"publishTime": "2024-12-08T15:00:18Z"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
@@ -1 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
{
|
|
2
|
+
"kind": "youtube#videoListResponse",
|
|
3
|
+
"etag": "di3iIBxYxR9Zt-miPNNxHlqDlpM",
|
|
4
|
+
"items": [
|
|
5
|
+
{
|
|
6
|
+
"kind": "youtube#video",
|
|
7
|
+
"etag": "ULUqewP9_v1dnnvIkm_ge8ZZF68",
|
|
8
|
+
"id": "yIlTwwJv1Ac",
|
|
9
|
+
"snippet": {
|
|
10
|
+
"publishedAt": "2026-03-24T15:10:42Z",
|
|
11
|
+
"channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
|
|
12
|
+
"title": "Ignition: NASA's Plan for The Moon",
|
|
13
|
+
"description": "Join us as we provide an update on the implementation of the National Space Policy and how we're accelerating preparations for America’s return to the surface of the Moon by 2028.\n\nThe program will open with remarks from NASA Administrator Jared Isaacman, followed by a series of high-level panels. Participants include:\n\n- Administrator Jared Isaacman\n- Associate Administrator Amit Kshatriya\n- Dana Weigel, program manager, International Space Station Program\n- Carlos Garcia-Galan, program executive, Moon Base \n- Steve Sinacore, program executive, Fission Surface Power \n- Dr. Nicola Fox, associate administrator, Science Mission Directorate \n- Dr. Lori Glaze, acting associate administrator, Exploration Systems Development Mission Directorate\n\nMore info: https://go.nasa.gov/40QGOtA\n\nCredit: NASA",
|
|
14
|
+
"thumbnails": {
|
|
15
|
+
"default": {
|
|
16
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/default.jpg",
|
|
17
|
+
"width": 120,
|
|
18
|
+
"height": 90
|
|
19
|
+
},
|
|
20
|
+
"medium": {
|
|
21
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/mqdefault.jpg",
|
|
22
|
+
"width": 320,
|
|
23
|
+
"height": 180
|
|
24
|
+
},
|
|
25
|
+
"high": {
|
|
26
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/hqdefault.jpg",
|
|
27
|
+
"width": 480,
|
|
28
|
+
"height": 360
|
|
29
|
+
},
|
|
30
|
+
"standard": {
|
|
31
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/sddefault.jpg",
|
|
32
|
+
"width": 640,
|
|
33
|
+
"height": 480
|
|
34
|
+
},
|
|
35
|
+
"maxres": {
|
|
36
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/maxresdefault.jpg",
|
|
37
|
+
"width": 1280,
|
|
38
|
+
"height": 720
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"channelTitle": "NASA",
|
|
42
|
+
"categoryId": "28",
|
|
43
|
+
"liveBroadcastContent": "none",
|
|
44
|
+
"defaultLanguage": "en",
|
|
45
|
+
"localized": {
|
|
46
|
+
"title": "Ignition: NASA's Plan for The Moon",
|
|
47
|
+
"description": "Join us as we provide an update on the implementation of the National Space Policy and how we're accelerating preparations for America’s return to the surface of the Moon by 2028.\n\nThe program will open with remarks from NASA Administrator Jared Isaacman, followed by a series of high-level panels. Participants include:\n\n- Administrator Jared Isaacman\n- Associate Administrator Amit Kshatriya\n- Dana Weigel, program manager, International Space Station Program\n- Carlos Garcia-Galan, program executive, Moon Base \n- Steve Sinacore, program executive, Fission Surface Power \n- Dr. Nicola Fox, associate administrator, Science Mission Directorate \n- Dr. Lori Glaze, acting associate administrator, Exploration Systems Development Mission Directorate\n\nMore info: https://go.nasa.gov/40QGOtA\n\nCredit: NASA"
|
|
48
|
+
},
|
|
49
|
+
"defaultAudioLanguage": "en"
|
|
50
|
+
},
|
|
51
|
+
"statistics": {
|
|
52
|
+
"viewCount": "200",
|
|
53
|
+
"likeCount": "3218",
|
|
54
|
+
"favoriteCount": "0"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"pageInfo": {
|
|
59
|
+
"totalResults": 1,
|
|
60
|
+
"resultsPerPage": 1
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
@@ -1 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
{
|
|
2
|
+
"kind": "youtube#videoListResponse",
|
|
3
|
+
"etag": "di3iIBxYxR9Zt-miPNNxHlqDlpM",
|
|
4
|
+
"items": [
|
|
5
|
+
{
|
|
6
|
+
"kind": "youtube#video",
|
|
7
|
+
"etag": "ULUqewP9_v1dnnvIkm_ge8ZZF68",
|
|
8
|
+
"id": "yIlTwwJv1Ac",
|
|
9
|
+
"snippet": {
|
|
10
|
+
"publishedAt": "2026-03-24T15:10:42Z",
|
|
11
|
+
"channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
|
|
12
|
+
"title": "Ignition: NASA's Plan for The Moon",
|
|
13
|
+
"description": "Join us as we provide an update on the implementation of the National Space Policy and how we're accelerating preparations for America’s return to the surface of the Moon by 2028.\n\nThe program will open with remarks from NASA Administrator Jared Isaacman, followed by a series of high-level panels. Participants include:\n\n- Administrator Jared Isaacman\n- Associate Administrator Amit Kshatriya\n- Dana Weigel, program manager, International Space Station Program\n- Carlos Garcia-Galan, program executive, Moon Base \n- Steve Sinacore, program executive, Fission Surface Power \n- Dr. Nicola Fox, associate administrator, Science Mission Directorate \n- Dr. Lori Glaze, acting associate administrator, Exploration Systems Development Mission Directorate\n\nMore info: https://go.nasa.gov/40QGOtA\n\nCredit: NASA",
|
|
14
|
+
"thumbnails": {
|
|
15
|
+
"default": {
|
|
16
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/default.jpg",
|
|
17
|
+
"width": 120,
|
|
18
|
+
"height": 90
|
|
19
|
+
},
|
|
20
|
+
"medium": {
|
|
21
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/mqdefault.jpg",
|
|
22
|
+
"width": 320,
|
|
23
|
+
"height": 180
|
|
24
|
+
},
|
|
25
|
+
"high": {
|
|
26
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/hqdefault.jpg",
|
|
27
|
+
"width": 480,
|
|
28
|
+
"height": 360
|
|
29
|
+
},
|
|
30
|
+
"standard": {
|
|
31
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/sddefault.jpg",
|
|
32
|
+
"width": 640,
|
|
33
|
+
"height": 480
|
|
34
|
+
},
|
|
35
|
+
"maxres": {
|
|
36
|
+
"url": "https://i.ytimg.com/vi/yIlTwwJv1Ac/maxresdefault.jpg",
|
|
37
|
+
"width": 1280,
|
|
38
|
+
"height": 720
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"channelTitle": "NASA",
|
|
42
|
+
"categoryId": "28",
|
|
43
|
+
"liveBroadcastContent": "none",
|
|
44
|
+
"defaultLanguage": "en",
|
|
45
|
+
"localized": {
|
|
46
|
+
"title": "Ignition: NASA's Plan for The Moon",
|
|
47
|
+
"description": "Join us as we provide an update on the implementation of the National Space Policy and how we're accelerating preparations for America’s return to the surface of the Moon by 2028.\n\nThe program will open with remarks from NASA Administrator Jared Isaacman, followed by a series of high-level panels. Participants include:\n\n- Administrator Jared Isaacman\n- Associate Administrator Amit Kshatriya\n- Dana Weigel, program manager, International Space Station Program\n- Carlos Garcia-Galan, program executive, Moon Base \n- Steve Sinacore, program executive, Fission Surface Power \n- Dr. Nicola Fox, associate administrator, Science Mission Directorate \n- Dr. Lori Glaze, acting associate administrator, Exploration Systems Development Mission Directorate\n\nMore info: https://go.nasa.gov/40QGOtA\n\nCredit: NASA"
|
|
48
|
+
},
|
|
49
|
+
"defaultAudioLanguage": "en"
|
|
50
|
+
},
|
|
51
|
+
"statistics": {
|
|
52
|
+
"viewCount": "91568",
|
|
53
|
+
"likeCount": "3218",
|
|
54
|
+
"favoriteCount": "0"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"pageInfo": {
|
|
59
|
+
"totalResults": 1,
|
|
60
|
+
"resultsPerPage": 1
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
shared_context "result load fixture" do |fixture_file|
|
|
2
2
|
let(:result){ double }
|
|
3
3
|
let(:loaded_fixture) { fixture(fixture_file) }
|
|
4
|
+
let(:loaded_items) do
|
|
5
|
+
data = loaded_fixture
|
|
6
|
+
if data.is_a?(Hash) && data.key?("items")
|
|
7
|
+
data["items"]
|
|
8
|
+
elsif data.is_a?(Array)
|
|
9
|
+
data
|
|
10
|
+
else
|
|
11
|
+
raise ArgumentError,
|
|
12
|
+
"#{fixture_file} must be a YouTube list response with an items array or a bare items array"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
4
15
|
|
|
5
16
|
before do
|
|
6
17
|
allow(result).to receive(:status).and_return(200)
|
|
7
18
|
allow(result).to receive_message_chain(
|
|
8
|
-
:data, :items).and_return(
|
|
19
|
+
:data, :items).and_return(loaded_items)
|
|
9
20
|
allow(Yourub::REST::Request).to receive(:new).and_return(result)
|
|
10
21
|
end
|
|
11
22
|
end
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
shared_context "search list result load fixture" do |fixture_file|
|
|
2
2
|
let(:search_list_result){ double }
|
|
3
3
|
let(:loaded_fixture) { fixture(fixture_file) }
|
|
4
|
+
let(:search_list_items) do
|
|
5
|
+
data = loaded_fixture
|
|
6
|
+
if data.is_a?(Hash) && data.key?("items")
|
|
7
|
+
data["items"]
|
|
8
|
+
elsif data.is_a?(Array)
|
|
9
|
+
data
|
|
10
|
+
else
|
|
11
|
+
raise ArgumentError, "search list fixture must be a searchListResponse or an items array"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
4
14
|
|
|
5
15
|
before do
|
|
6
|
-
# search list req
|
|
7
16
|
allow(search_list_result).to receive_message_chain(
|
|
8
|
-
:data, :items).and_return(
|
|
9
|
-
|
|
17
|
+
:data, :items).and_return(search_list_items)
|
|
18
|
+
search_list_items.each do |single_video|
|
|
19
|
+
video_id = if single_video.is_a?(Hash) && single_video["id"].is_a?(Hash)
|
|
20
|
+
single_video["id"]["videoId"]
|
|
21
|
+
else
|
|
22
|
+
"video_id_stub"
|
|
23
|
+
end
|
|
10
24
|
allow(single_video).to receive_message_chain(
|
|
11
|
-
|
|
25
|
+
:id, :video_id).and_return(video_id)
|
|
12
26
|
end
|
|
13
27
|
|
|
14
28
|
allow(Yourub::REST::Search).to receive(:list).and_return(search_list_result)
|
|
@@ -2,21 +2,43 @@ shared_context "search list result load fixture with single video" do |fixture_f
|
|
|
2
2
|
let(:search_list_result) { double }
|
|
3
3
|
let(:video_result) { double }
|
|
4
4
|
let(:loaded_fixture) { fixture(fixture_file) }
|
|
5
|
-
let(:
|
|
5
|
+
let(:search_list_items) do
|
|
6
|
+
data = loaded_fixture
|
|
7
|
+
if data.is_a?(Hash) && data.key?("items")
|
|
8
|
+
data["items"]
|
|
9
|
+
elsif data.is_a?(Array)
|
|
10
|
+
data
|
|
11
|
+
else
|
|
12
|
+
raise ArgumentError, "search list fixture must be a searchListResponse or an items array"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
let(:videos_list_items_for_detail) do
|
|
16
|
+
raw = fixture("videos_list.json")
|
|
17
|
+
if raw.is_a?(Hash) && raw.key?("items")
|
|
18
|
+
raw["items"]
|
|
19
|
+
elsif raw.is_a?(Array)
|
|
20
|
+
raw
|
|
21
|
+
else
|
|
22
|
+
raise ArgumentError, "videos_list.json must be a video list response or items array"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
6
25
|
|
|
7
26
|
before do
|
|
8
|
-
# stub search list req
|
|
9
27
|
allow(search_list_result).to receive_message_chain(
|
|
10
|
-
:data, :items).and_return(
|
|
11
|
-
|
|
28
|
+
:data, :items).and_return(search_list_items)
|
|
29
|
+
search_list_items.each do |single_video|
|
|
30
|
+
video_id = if single_video.is_a?(Hash) && single_video["id"].is_a?(Hash)
|
|
31
|
+
single_video["id"]["videoId"]
|
|
32
|
+
else
|
|
33
|
+
"video_id_stub"
|
|
34
|
+
end
|
|
12
35
|
allow(single_video).to receive_message_chain(
|
|
13
|
-
|
|
36
|
+
:id, :video_id).and_return(video_id)
|
|
37
|
+
end
|
|
14
38
|
|
|
15
|
-
# stub single video request
|
|
16
39
|
allow(video_result).to receive(:status).and_return(200)
|
|
17
40
|
allow(video_result).to receive_message_chain(
|
|
18
|
-
:data, :items).and_return(
|
|
19
|
-
end
|
|
41
|
+
:data, :items).and_return(videos_list_items_for_detail)
|
|
20
42
|
|
|
21
43
|
allow(Yourub::REST::Search).to receive(:list).and_return(search_list_result)
|
|
22
44
|
allow(Yourub::REST::Videos).to receive(:single_video).and_return(video_result)
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
shared_context "stub client connection" do
|
|
2
2
|
let(:client) { Yourub::Client.new }
|
|
3
|
-
let(:discovered_api) { double('youtube_api') }
|
|
4
3
|
let(:stubbed_response) { OpenStruct.new(data: 'bla', status: 200) }
|
|
5
4
|
|
|
6
5
|
before do
|
|
7
|
-
allow(discovered_api).to receive_message_chain(
|
|
8
|
-
:videos, :list).and_return('videos.list')
|
|
9
|
-
allow(discovered_api).to receive_message_chain(
|
|
10
|
-
:search, :list).and_return('search.list')
|
|
11
|
-
allow(discovered_api).to receive_message_chain(
|
|
12
|
-
:video_categories, :list).and_return('video_categories.list')
|
|
13
|
-
allow(client).to receive(:youtube_api).and_return(discovered_api)
|
|
14
6
|
allow(client).to receive(:execute!).and_return(stubbed_response)
|
|
15
7
|
end
|
|
16
8
|
end
|
data/spec/yourub/client_spec.rb
CHANGED
|
@@ -33,6 +33,67 @@ describe Yourub::Client do
|
|
|
33
33
|
|
|
34
34
|
it 'raise an argument error if there is no a developer_key in the option' do
|
|
35
35
|
options = { application_name: 'my app' }
|
|
36
|
-
expect
|
|
36
|
+
expect { Yourub::Client.new(options) }.to raise_error(ArgumentError)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe '#list_video_categories' do
|
|
40
|
+
let(:options) do
|
|
41
|
+
{ developer_key: 'Super',
|
|
42
|
+
application_name: 'yourub',
|
|
43
|
+
application_version: 2.0,
|
|
44
|
+
log_level: 3 }
|
|
45
|
+
end
|
|
46
|
+
let(:client) { Yourub::Client.new(options) }
|
|
47
|
+
let(:service) { client.instance_variable_get(:@service) }
|
|
48
|
+
let(:api_response) { Object.new }
|
|
49
|
+
|
|
50
|
+
it 'delegates to YouTubeService with region_code' do
|
|
51
|
+
expect(service).to receive(:list_video_categories).with(
|
|
52
|
+
'snippet',
|
|
53
|
+
region_code: 'DE'
|
|
54
|
+
).and_return(api_response)
|
|
55
|
+
expect(client.list_video_categories(region_code: 'de')).to be(api_response)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'omits region_code when nil (YouTube default catalog, e.g. US)' do
|
|
59
|
+
expect(service).to receive(:list_video_categories).with(
|
|
60
|
+
'snippet'
|
|
61
|
+
).and_return(api_response)
|
|
62
|
+
expect(client.list_video_categories).to be(api_response)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'omits region_code when blank' do
|
|
66
|
+
expect(service).to receive(:list_video_categories).with(
|
|
67
|
+
'snippet'
|
|
68
|
+
).and_return(api_response)
|
|
69
|
+
expect(client.list_video_categories(region_code: ' ')).to be(api_response)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'passes hl when given' do
|
|
73
|
+
expect(service).to receive(:list_video_categories).with(
|
|
74
|
+
'snippet',
|
|
75
|
+
region_code: 'US',
|
|
76
|
+
hl: 'en_GB'
|
|
77
|
+
).and_return(api_response)
|
|
78
|
+
expect(client.list_video_categories(region_code: 'US', hl: 'en_GB')).to be(api_response)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'caches per region_code and hl' do
|
|
82
|
+
expect(service).to receive(:list_video_categories).once.with(
|
|
83
|
+
'snippet',
|
|
84
|
+
region_code: 'DE'
|
|
85
|
+
).and_return(api_response)
|
|
86
|
+
2.times { expect(client.list_video_categories(region_code: 'DE')).to be(api_response) }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'flush_video_categories_cache! forces a new API call' do
|
|
90
|
+
expect(service).to receive(:list_video_categories).twice.with(
|
|
91
|
+
'snippet',
|
|
92
|
+
region_code: 'FR'
|
|
93
|
+
).and_return(api_response)
|
|
94
|
+
client.list_video_categories(region_code: 'FR')
|
|
95
|
+
client.flush_video_categories_cache!
|
|
96
|
+
client.list_video_categories(region_code: 'FR')
|
|
97
|
+
end
|
|
37
98
|
end
|
|
38
99
|
end
|
data/spec/yourub/count_spec.rb
CHANGED
|
@@ -8,23 +8,23 @@ describe Yourub::MetaSearch do
|
|
|
8
8
|
let(:result){ double }
|
|
9
9
|
|
|
10
10
|
context 'integrates a view count filter' do
|
|
11
|
-
context 'having a search result with
|
|
11
|
+
context 'having a search result with 5 videos (details from videos_list.json)' do
|
|
12
12
|
include_context "stub client connection"
|
|
13
13
|
include_context "search list result load fixture with single video", "search_list.json"
|
|
14
|
-
context "searching videos with
|
|
15
|
-
it '
|
|
14
|
+
context "searching videos with at least 200 views" do
|
|
15
|
+
it 'finds one yielded video per search result item' do
|
|
16
16
|
filter = { views: '>= 200' }
|
|
17
17
|
videos = []
|
|
18
18
|
client.search(query: "nasa", count_filter: filter, max_results: 2) do |v|
|
|
19
19
|
videos.push(v)
|
|
20
20
|
end
|
|
21
|
-
expect(videos.count).to eq(
|
|
21
|
+
expect(videos.count).to eq(5)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
context "searching videos with more than
|
|
26
|
-
it '
|
|
27
|
-
filter = { views: '>
|
|
25
|
+
context "searching videos with more views than the fixture has" do
|
|
26
|
+
it 'finds no videos' do
|
|
27
|
+
filter = { views: '> 91568' }
|
|
28
28
|
videos = []
|
|
29
29
|
client.search(query: "nasa", count_filter: filter, max_results: 2) do |v|
|
|
30
30
|
videos.push(v)
|
data/spec/yourub/integration.rb
CHANGED
|
@@ -30,9 +30,9 @@ describe Yourub::Client do
|
|
|
30
30
|
expect(videos).to_not be_empty
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
it "
|
|
33
|
+
it "searches without a category filter when :category is omitted" do
|
|
34
34
|
videos = []
|
|
35
|
-
subject.search(
|
|
35
|
+
subject.search(query: "nasa", country: "US") do |v|
|
|
36
36
|
videos.push(v)
|
|
37
37
|
end
|
|
38
38
|
expect(videos).to_not be_empty
|
|
@@ -64,7 +64,7 @@ describe Yourub::Client do
|
|
|
64
64
|
|
|
65
65
|
it "retrieves the given number of video for the given category" do
|
|
66
66
|
videos = []
|
|
67
|
-
subject.search(category: "Sports", max_results: 2) do |v|
|
|
67
|
+
subject.search(country: "US", category: "Sports", max_results: 2) do |v|
|
|
68
68
|
videos.push(v)
|
|
69
69
|
end
|
|
70
70
|
expect(videos.count).to eq(2)
|
|
@@ -91,10 +91,6 @@ describe Yourub::Client do
|
|
|
91
91
|
# expect(videos.first["id"]).to eql("mN0Dbj-xHY0")
|
|
92
92
|
# end
|
|
93
93
|
|
|
94
|
-
# it "retrieves the view count for given id" do
|
|
95
|
-
# expect(subject.get_views("mN0Dbj-xHY0")).to be_a_kind_of(Integer)
|
|
96
|
-
# end
|
|
97
|
-
|
|
98
94
|
# it "return nil for a not existing video" do
|
|
99
95
|
# subject.search(id: "fffffffffffffffffffff")
|
|
100
96
|
# expect(subject.videos).to be_empty
|