Updated French translation
[profile/ivi/rygel.git] / tests / rygel-http-byte-seek-test.vala
1 /*
2  * Copyright (C) 2010 Nokia Corporation.
3  *
4  * Author: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
5  *                               <zeeshanak@gnome.org>
6  *
7  * This file is part of Rygel.
8  *
9  * Rygel is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Rygel is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24 private errordomain Rygel.TestError {
25     SKIP
26 }
27
28 private class Rygel.HTTPIdentityHandler : GLib.Object {}
29
30 public class Rygel.MediaObject : GLib.Object {
31     public int64 size = 2048;
32 }
33
34 private class Rygel.MediaItem : MediaObject {
35 }
36
37 private class Rygel.Thumbnail : GLib.Object {
38     public int64 size = 1024;
39 }
40
41 private class Rygel.Subtitle : GLib.Object {
42     public int64 size = 512;
43 }
44
45 public class Rygel.MediaContainer : MediaObject {
46 }
47
48 public class Rygel.ClientHacks : GLib.Object {
49     public static ClientHacks create (Soup.Message msg) throws Error {
50         return new ClientHacks ();
51     }
52
53     public bool force_seek () {
54         return false;
55     }
56 }
57
58 private class Rygel.HTTPGet : GLib.Object {
59     public const string ITEM_URI = "http://DoesntMatterWhatThisIs";
60
61     public Soup.Message msg;
62     public MediaObject object;
63     public Thumbnail thumbnail;
64     public Subtitle subtitle;
65
66     public HTTPIdentityHandler handler;
67
68     public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) {
69         this.msg = new Soup.Message ("HTTP", ITEM_URI);
70         this.object = new MediaItem ();
71         this.handler = new HTTPIdentityHandler ();
72         this.thumbnail = thumbnail;
73         this.subtitle = subtitle;
74     }
75
76     public HTTPGet.seek_start (int64      start,
77                                Thumbnail? thumbnail,
78                                Subtitle?  subtitle) {
79         this (thumbnail, subtitle);
80
81         this.add_headers (start, -1);
82     }
83
84     public HTTPGet.seek_stop (int64      stop,
85                               Thumbnail? thumbnail,
86                               Subtitle?  subtitle) {
87         this (thumbnail, subtitle);
88
89         this.add_headers (0, stop);
90     }
91
92     public HTTPGet.seek_start_stop (int64      start,
93                                     int64      stop,
94                                     Thumbnail? thumbnail,
95                                     Subtitle?  subtitle) {
96         this (thumbnail, subtitle);
97
98         this.add_headers (start, stop);
99     }
100
101     public HTTPGet.inverted_range () {
102         this (null, null);
103         this.msg.request_headers.append ("Range", "bytes=34-0");
104     }
105
106     public HTTPGet.invalid_range () {
107         this (null, null);
108         this.msg.request_headers.append ("Range", "bytes=a-b");
109     }
110
111     private void add_headers (int64 start, int64 stop) {
112         this.msg.request_headers.set_range (start, stop);
113     }
114 }
115
116 private class Rygel.HTTPByteSeekTest : GLib.Object {
117     private Regex range_regex;
118
119     public static int main (string[] args) {
120         try {
121             var test = new HTTPByteSeekTest ();
122
123             test.run ();
124         /* TODO: Nothing throws this exception. Should it?
125         } catch (TestError.SKIP error) {
126             return 77;
127         */
128         } catch (Error error) {
129             critical ("%s", error.message);
130
131             return -1;
132         }
133
134         return 0;
135     }
136
137     public void run () throws HTTPSeekError {
138         var thumbnails = new Thumbnail[] { null, new Thumbnail () };
139         var subtitles = new Subtitle[] { null, new Subtitle () };
140
141         foreach (var thumbnail in thumbnails) {
142             foreach (var subtitle in subtitles) {
143                 this.test_no_seek (thumbnail, subtitle);
144                 this.test_start_only_seek (thumbnail, subtitle);
145                 this.test_stop_only_seek (thumbnail, subtitle);
146                 this.test_start_stop_seek (thumbnail, subtitle);
147             }
148         }
149
150         try {
151             new HTTPByteSeek (new HTTPGet.inverted_range ());
152             assert_not_reached ();
153         } catch (HTTPSeekError error) {}
154
155         try {
156             new HTTPByteSeek (new HTTPGet.invalid_range ());
157             assert_not_reached ();
158         } catch (HTTPSeekError error) {}
159     }
160
161     private HTTPByteSeekTest () {
162         try {
163             this.range_regex = new Regex ("bytes +[0-9]+-[0-9]+/[0-9]+",
164                                           RegexCompileFlags.CASELESS);
165         } catch (RegexError error) {
166             // This means that it is not a regular expression
167             assert_not_reached ();
168         }
169     }
170
171     private void test_no_seek (Thumbnail? thumbnail,
172                                Subtitle?  subtitle) throws HTTPSeekError {
173         var request = new HTTPGet (thumbnail, subtitle);
174
175         int64 size;
176         if (request.thumbnail != null) {
177             size = request.thumbnail.size;
178         } else if (request.subtitle != null) {
179             size = request.subtitle.size;
180         } else {
181             size = request.object.size;
182         }
183
184         this.test_seek (request, 0, size - 1);
185     }
186
187     private void test_start_only_seek (Thumbnail? thumbnail,
188                                        Subtitle?  subtitle)
189                                        throws HTTPSeekError {
190         var request = new HTTPGet.seek_start (128, thumbnail, subtitle);
191
192         int64 size;
193         if (request.thumbnail != null) {
194             size = request.thumbnail.size;
195         } else if (request.subtitle != null) {
196             size = request.subtitle.size;
197         } else {
198             size = request.object.size;
199         }
200
201         this.test_seek (request, 128, size - 1);
202     }
203
204     private void test_stop_only_seek (Thumbnail? thumbnail,
205                                       Subtitle?  subtitle)
206                                       throws HTTPSeekError {
207         var request = new HTTPGet.seek_stop (128, thumbnail, subtitle);
208
209         this.test_seek (request, 0, 128);
210     }
211
212     private void test_start_stop_seek (Thumbnail? thumbnail,
213                                        Subtitle?  subtitle)
214                                        throws HTTPSeekError {
215         var request = new HTTPGet.seek_start_stop (128,
216                                                    256,
217                                                    thumbnail,
218                                                    subtitle);
219
220         this.test_seek (request, 128, 256);
221     }
222
223     private void test_seek (HTTPGet request,
224                             int64   start,
225                             int64   stop) throws HTTPSeekError {
226         assert (HTTPByteSeek.needed (request));
227
228         var seek = new HTTPByteSeek (request);
229         seek.add_response_headers ();
230
231         assert (seek != null);
232         assert (seek.start == start);
233         assert (seek.stop == stop);
234
235         if (request.thumbnail != null) {
236             assert (seek.total_length == request.thumbnail.size);
237         } else if (request.subtitle != null) {
238             assert (seek.total_length == request.subtitle.size);
239         } else {
240             assert (seek.total_length == request.object.size);
241         }
242
243         if (request.msg.request_headers.get_one ("Range") != null) {
244             var header = request.msg.response_headers.get_one ("Accept-Ranges");
245             assert (header == "bytes");
246             header = request.msg.response_headers.get_one ("Content-Range");
247             assert (header != null);
248             assert (this.range_regex.match (header));
249         }
250
251         assert (request.msg.response_headers.get_content_length () ==
252                 seek.length);
253
254         /* TODO: This is just here to avoid a warning about
255          * requested() not being used.
256          * How should this really be tested?
257          * Sometimes the result here is true, and sometimes it is false.
258          */
259         /* bool result = */ HTTPByteSeek.requested(request);
260     }
261 }