directlink 0.0.9.2 → 0.0.11.2

Sign up to get free protection for your applications and to get access to all the features.
data/unit.test.rb ADDED
@@ -0,0 +1,1553 @@
1
+ require "minitest/autorun"
2
+ require "minitest/around/spec"
3
+ require "minitest/mock"
4
+ require "webmock/minitest"
5
+ require_relative "webmock_patch"
6
+ WebMock.enable!
7
+
8
+ require_relative "lib/directlink"
9
+ DirectLink.silent = true # TODO: remove?
10
+ DirectLink.timeout = 30 # TODO: tests about this attribute
11
+
12
+ describe DirectLink do
13
+ around{ |test| Timeout.timeout(4){ test.call } }
14
+ before{ WebMock.reset! }
15
+
16
+ describe "./lib" do
17
+
18
+ describe "google" do
19
+
20
+ # TODO: expand this for every branch in the lib
21
+ %w{
22
+ https_long_blogspot https://1.bp.blogspot.com/-__qsdLxNtcQ/XhaOQle-ECI/AAAAAAAABQ4/S_7SGG_abcDE6XIU2wyPvTj9OyBfr_1sQCLcBGAsYHQ/w1200-h630-p-k-no-nu/iceland_poppies_orange_flowers_field-wallpaper-3840x2160.jpg https://1.bp.blogspot.com/-__qsdLxNtcQ/XhaOQle-ECI/AAAAAAAABQ4/S_7SGG_abcDE6XIU2wyPvTj9OyBfr_1sQCLcBGAsYHQ/s0/
23
+ http_short_blogspot http://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/mabcDE6-v-g/w72-h72-p-k-no-nu/Top-24-Inspired-181.jpg https://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/mabcDE6-v-g/s0/
24
+ just_gplus https://lh3.googleusercontent.com/-NiGph3ObOPg/XE3DgnavXlI/AAAAAAABvgE/pcPPCe88rsU1r941wwP76TVf_abcDE6kwCJoC/w530-h353-n/DSCF0753.JPG https://lh3.googleusercontent.com/-NiGph3ObOPg/XE3DgnavXlI/AAAAAAABvgE/pcPPCe88rsU1r941wwP76TVf_abcDE6kwCJoC/s0/
25
+ google_keep https://lh5.googleusercontent.com/fRmAL_04p7oomNHCiV4tH4-agHSDBtLaWi_Tb6bgE5ZSHVu5OjQF3iRn06nNwP3ywZwdFP92zWM-abcDE6n6m0tDTBARuO6F9e0wYu_1=s685 https://lh5.googleusercontent.com/fRmAL_04p7oomNHCiV4tH4-agHSDBtLaWi_Tb6bgE5ZSHVu5OjQF3iRn06nNwP3ywZwdFP92zWM-abcDE6n6m0tDTBARuO6F9e0wYu_1=s0
26
+ }.each_slice 3 do |name, link, o|
27
+ it "replaces s0 and schema correctly #{name}" do
28
+ assert_equal o, DirectLink.google(link)
29
+ end
30
+ end
31
+
32
+ describe "does not fail" do
33
+ # TODO: also check the #google is being called
34
+
35
+ "
36
+ 1 //1.bp.blogspot.com/-rYk_u-qROQc/WngolJ8M0LI/AAAAAAAAD-w/abcDE6IVzasBPG5C2T1t-VrWKRd_U6lMgCLcBGAs/w530-h278-p/i-469.jpg
37
+ 2 //4.bp.blogspot.com/-1RlHbRShONs/Wngp9WfxbfI/AAAAAAAAD-8/abcDE6SZdvUMz4VjJPBpprLBrJ5QpBaqACLcBGAs/w530-h278-p/i-468.jpg
38
+ 3 //4.bp.blogspot.com/-5kP8ndL0kuM/Wpt82UCqvmI/AAAAAAAAEjI/abcDE60-kgwRXEJ9JEGioR0bm6U8MOkvQCKgBGAs/w530-h278-p/IMG_20171223_093922.jpg
39
+ 4 //4.bp.blogspot.com/-bS1SZxFkvek/Wnjz3D5Il4I/AAAAAAAAD_I/abcDE6GB7r4NGJ0aR1F-ugsbVm4HUjf5ACLcBGAs/w530-h278-p/i-466.jpg
40
+ 5 //lh3.googleusercontent.com/-1CF2jge1MYI/Wmr_kfCQQUI/AAAAAAAClKs/abcDE64v0q0i5N7rgso6G8SrhJNzsHEagCJoC/w530-h352-p/2809525%2B%25D0%2593%25D0%2590%25D0%259B%25D0%259E%2B%25D0%259F%25D0%2590%25D0%25A0%25D0%2593%25D0%2595%25D0%259B%25D0%2598%25D0%2599%2B-%2B%25D0%25A7%25D0%25A3%25D0%259A%25D0%259E%25D0%25A2%25D0%259A%25D0%2590%2B-%2B%25D0%25AE%25D0%25A0%25D0%2598%25D0%2599%2B%25D0%25A5%25D0%2590%25D0%25A0%25D0%25A7%25D0%2595%25D0%259D%25D0%259A%25D0%259E.jpg
41
+ 6 //lh3.googleusercontent.com/-h1siEcRFqJ8/Wiv1iDQhNVI/AAAAAAAAQV4/abcDE6mYkDMLyVTG_1EBCMmj-UhmclXWwCJoC/w530-h353-p/001
42
+ 7 //lh3.googleusercontent.com/-qnZygRb-Tn8/Wlyj4UuKbaI/AAAAAAAATqE/abcDE6-XBZwsh843xJ3cSd0JPt1LedU9gCJoC/w530-h330-p/001
43
+ 8 //lh3.googleusercontent.com/-rXO9PzbjNmk/WlNfjJkJBmI/AAAAAAAATNY/abcDE6tWBzUKWufNXWkK82etw3RKA6jVgCJoC/w530-h361-p/001
44
+
45
+ 13 //lh3.googleusercontent.com/proxy/2fsWfEOeeCMNEP8MGvHiJPkBlg47Ifaf8DwpgDPJSPSYsh9iomTrfOA9OuwB60laZimtNr4-1GKA5J2csuVB6-1DLNO30K-abcDE656ivICWRFAUuOwzizaztBx5gQ=w530-h707-p
46
+ 14 //lh3.googleusercontent.com/proxy/2qy3gOwhBT77Ie_qa9VgGz6kgN14tnOh1AMmV9FB65oiXOSAIll1_qmOZdupL3QCcJQL4701YskEgeDUnxJTnFGq4mFEzNFvjpNC-QMX9Jg7mdar3e89u_siA4AD-j1SJ6mrkl2MwSJSu1s2guYn0NR5ND1985lK34_iGiwzjoGHG2a65IbxKDSEzgSGbPQ_abcDE6BIvfcgvAxtS6E=s530-p
47
+ 28 //lh3.googleusercontent.com/proxy/7N0QCidzIFysO6OhmrG8twRJ74-sboNenI3Nhy3mIWP8C0SSa8J6xFQU3iyBTw4k3QeleiAgXOME3abYutPvBrHGx-0TBUcI-_abcDE69Zaw6PAGdLndkxp5ReRJnsg=w530-h298-p
48
+ 31 //lh3.googleusercontent.com/proxy/7pN3aTE159nEXXQb_KajU1vcnDDzJVpGOv9vlWWPd3CbVuCKu-v4ndr423Mmhx-Zn5vqkVf6-TfZgPA5NyHECsr4w7kaw1jTmQDJbWO-9jU-Cs7ywrzcIRhyYTTZT-abcDE6wI1oEdbooIk=w464-h640-p
49
+ 48 //lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_abcDE6iu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n
50
+ 74 //lh3.googleusercontent.com/proxy/P4FQdTYwWN8cU_PWmFja1cm3oYu57L_flea7LmKvFjx0Ibdxl3glxcp-abcDE6xMFTQ3gQkWsWzlrkyCm9QrSjCUcGIgnbsYBCXewnhEwSn0ZgT4XDg485GdXMoGWpNETrLYa8IGvG20_iw=w504-h597-p
51
+ 137 //lh3.googleusercontent.com/proxy/kX1ABK6_VjHDU12p-zZN6ciTOzqFcXm7IV41uR9F2sveM2t148nmWBEN1clA-VHvowpkd9T4NOPrAfDaip1o-jJBtBnRBElJuCsKo8FviSIkToZWCY9nQFEj06nHkMNuReBtdbVBlIRSodNJM-_cmqiJ-DnmWNe4dk62EF_kGLS28OWmckDLWVG0YFiZ-lVi8JhgR-ZgRmYWTs8bb_u6v6ucgfo8eh7ewchuZAD9_CoxUlQChAqz0QIfuVuKvmcXE06Ylv2H330btswQotjKDf8AXPe6xcyE9X1JXDYQTsPv-7lftLG9WQp1Mlc9Wu1XbHV7f541L-smt--7YpkW6fbDFYk4_87-pIOcg9UqHKB__DWyMCtH3gs8rv6VCmVwL1a-oAeBWSWk0Tc9R6uSuyCjt0nEBGlZY35aW1Pchz0jXr4lq8Il9m-wbRN9E7Kff1JR89YFOrV2N86w_72YTefFerLFfEsgzmhx3WYwok-abcDE6H7MyiHBQt04uRnb58GA4vl5VBQ=w530-h398-p
52
+
53
+ 245 https://lh3.googleusercontent.com/-2JzV0ErXvv8/Wsdr-m5Q_aI/AAAAAAAA_-I/Lw_e6qEMPUck4yW9yWhkC-abcDE6m8c3QCJoC/w530-h795-n/888052_800n.jpg
54
+ 346 https://lh3.googleusercontent.com/-8YmBt-SUaJo/War0Un_7YTI/AAAAAAAB9xs/kgXp9QrHZX8mpDfyLwuS9cabcDE6oH6NgCL0BGAs/w530-d-h443-n/%25D0%259B%25D0%25B5%25D1%2581%2B%25D0%25BD%25D0%25B0%2B%25D0%25B8%25D1%2581%25D1%2585%25D0%25BE%25D0%25B4%25D0%25B5%2B%25D0%25BB%25D0%25B5%25D1%2582%25D0%25B0.JPG
55
+ 1317 https://lh3.googleusercontent.com/-tGAyJv4S6gM/WSLy4A7AFaI/AAAAAAABxk4/eq0Aprp2koM6GEti9xEIn-abcDE6bRRdQCL0B/w530-d-h660-n/%25D0%2592%25D0%25B5%25D1%2581%25D0%25BD%25D1%258B%2B%25D1%2586%25D0%25B2%25D0%25B5%25D1%2582%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5.JPG
56
+
57
+ 178 https://lh3.googleusercontent.com/--Ggbfs9HJZM/Wog1DA2WcFI/AAAAAAAAbdQ/SZKPcnabcDE6Ffl9pddfiLPQnOiJ37muQCJoC/w409-h727-n/11a1c54f37c07d3c04588b40d108b4c2.jpg
58
+ 260 https://lh3.googleusercontent.com/-3Fe6CL9RH4o/WnipWY4889I/AAAAAAAAI4I/CPqdKpabcDE6aBlCqGQ3RdZ9bLJ4nzBwwCJoC/w239-h318-n/gplus1855963830.jpg
59
+ 303 https://lh3.googleusercontent.com/-5vPhLnUILsA/WqFhJhu7VlI/AAAAAAAAAhQ/wWSrC8abcDE6OuzeU3UoXJkNG19tqtAGwCJoC/w265-h353-n/DSC08260.JPG
60
+ 668 https://lh3.googleusercontent.com/-NLW68hNxEzU/WrSNfBxFX2I/AAAAAAAAAT8/7cvRM-abcDE6dlb6CS8pL5-eJ3wbwohlQCJoC/w179-h318-n/23.03.2018%2B-%2B3
61
+ 669 https://lh3.googleusercontent.com/-NVJgqmI_2Is/WqMM2OMYg-I/AAAAAAAALrk/5-p3JLabcDE6o9dOf_p3gpddzqwr3Wp0ACJoC/w424-h318-n/001
62
+ 783 https://lh3.googleusercontent.com/-SqAvt_F__bg/Wq0huHcX2NI/AAAAAAAAVj0/XfnwCUabcDE60Knw8rcXA-bhpKYkI4hdwCJoC/w358-h318-n/IMG_20180317_120218-01-01.jpeg
63
+ 830 https://lh3.googleusercontent.com/-VB3YlLVL_tQ/Wo21yTbKl_I/AAAAAAAAApU/3DURmsabcDE60kif2ZRjhoLG4mTHYf8OwCJoC/w254-h318-n/180218_00001.jpg
64
+ 1002 https://lh3.googleusercontent.com/-d8FkfLWq-_4/WpQXzEfFgBI/AAAAAAAADww/J32xKSabcDE6c3pyrZnNmRec6kjdnJBHgCJoC/w239-h318-n/gplus-485739203.jpg
65
+ ".scan(/(\S+) (\S+)/).each do |i, link| # some pre-May-2018 urls dump from a community
66
+ it "Google Plus community post image ##{i}" do
67
+ assert DirectLink.google link
68
+ end
69
+ end
70
+ %w{
71
+ https://lh3.googleusercontent.com/-abcDE62vWuE/AAAAAAAAAAI/AAAAAAAAAAQ/wVFZagieszU/w530-h176-n/photo.jpg
72
+ //lh3.googleusercontent.com/abcDE6v7EGo0QbuoKxoKZVZO_NcBzufuvPtzirMJfPmAzCzMtnEncfA7zGIDTJfkc1YZFX2MhgKnjA=w530-h398-p
73
+ //lh3.googleusercontent.com/-0Vt5HFpPTVQ/Wnh02Jb4SFI/AAAAAAAAbCU/MtusII6-abcDE6QWofAaWF01IBUVykMyACJoC/w530-h351-p/DSC_3804%2B-%2B%25D0%25BA%25D0%25BE%25D0%25BF%25D0%25B8%25D1%258F.JPG
74
+ https://lh3.googleusercontent.com/-abcDE6-b85c/WvOtHJn-DxI/AAAAAAAAAKg/A_PoO64o0VkX1erPKebiO7Xcs5Iy3idbACJoC/w424-h318-n/IMG_20180510_082023.jpg
75
+ https://lh3.googleusercontent.com/-abcDE6FntJY/Wvl8HLwfF_I/AAAAAAAAA20/mqOtMCFuBkkvtv7jdpVkJv2XSXlOLoXVQCJoC/w212-h318-n/DPP_0006.JPG
76
+ https://lh3.googleusercontent.com/-abcDE64EIiw/WuxqzXHQCHI/AAAAAAAABAI/rA0R2UsbxoswvH6nSePnwa5VHG2f5kNOQCJoC/w398-h318-n/Fox-Desktop-1024x1280.jpg
77
+ https://lh3.googleusercontent.com/-abcDE62-1OA/WvMUBWXI0PI/AAAAAAAAC60/gdtkQz9YI0knYkFB8VjC2CpKOD6-Zs6hQCJoC/w408-h318-n/%25D0%25BF%25D0%25BE%25D1%2581.jpg
78
+ https://lh3.googleusercontent.com/--abcDE6Gk-A/WveQe_YKbAI/AAAAAAAACkQ/eTz2maXvw7A0iKoPjfuwEgfTiZS3a3HSgCJoC/w318-h318-n/gplus1165736192.jpg
79
+ https://lh3.googleusercontent.com/-abcDE6hwMOg/WtOxVJ1DNxI/AAAAAAAAMGs/pJf8awKJcyMFlx2g89p9_QjqlyQDmYMmACJoC/w424-h318-n/DSC03178.JPG
80
+ https://lh3.googleusercontent.com/-abcDE67fY1o/WtaUJCaDGmI/AAAAAAAAmBQ/jZhatiBmHPEiAAABcY2DoJ6KuzVBvqGxQCJoC/w530-h150-n/%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE%25D0%25BA%2B%25D1%258D%25D0%25BA%25D1%2580%25D0%25B0%25D0%25BD%25D0%25B0%2B2018-04-18%2B%25D0%25B2%2B3.32.42.png
81
+ https://lh3.googleusercontent.com/-40QwR_c58sw/WsLyS3a8uhI/AAAAAAAAAas/ojaQoF1-abcDE6S6c5kLs7bOl_TAOU6oACJoC/w424-h318-n/271091.jpg
82
+ https://lh3.googleusercontent.com/-abcDE6yNBjY/WvOtHOyaj_I/AAAAAAAAAKo/gOAn__a75NwYSgaBaEBGeCTAFI9MyjqlwCJoC/w239-h318-n/IMG_20180510_081956.jpg
83
+ https://lh3.googleusercontent.com/-R19p_abcDE6/Wwma1oEvD6I/AAAAAAAAEX8/tQc4JOq58REEWlukw2jDCTUjH3ejGZI8gCJoC/w486-h864-n/gplus1392977354.jpg
84
+ //2.bp.blogspot.com/-mOnRg-mkojA/W22m79XcT_I/AAAAAAAAHDs/C8yQaOA-ZeEAr3WBG--abcDE65nWV0p7QCEwYBhgL/w530-h353-p/_MG_8809-Edit.jpg
85
+ }.each_with_index do |link, i| # March contenstants
86
+ it "another (March) Google Plus community post image ##{i + 1}" do
87
+ assert DirectLink.google link
88
+ end
89
+ end
90
+ %w{
91
+ https://lh3.googleusercontent.com/-abRcDE6_gic/WwUz3_Www7I/AAAAAAAABio/MNYvB57tBvIl6Bxp0GsKHvg0hSyHyVWhwCJoC/w265-h353-n/IMG_20180522_210620_317.jpg
92
+ https://lh3.googleusercontent.com/-abAcDE61QVc/Wu4Khtduz-I/AAAAAAAAA_A/lvpwTuatrtkhL31co1n9xa7kwKEVwc6IwCJoC/w301-h318-n/gplus662578195.jpg
93
+ https://lh3.googleusercontent.com/-abKcDE6NG2Q/Wvt9mUDC1QI/AAAAAAAANEw/2uWvIzQmG-Y3CGHuB8-UU114z4Zr8lkLQCJoC/w530-h175-n/PANO_20180516_025747.jpg
94
+ https://lh3.googleusercontent.com/-abWcDE66_Ew/WwvJcNQ39BI/AAAAAAAABvI/xb1bdwuEZGM2SmbwamwiMmZKFOW44bhPgCJoC/w239-h318-n/DSC03627.JPG
95
+ https://lh3.googleusercontent.com/-abacDE67WWI/Wu4Khq0IkaI/AAAAAAAAA_A/Dxs9JYJ6f6sv_7jNWMdNl3eo2jh9nYqDwCJoC/w296-h318-n/gplus-328480287.jpg
96
+ https://lh3.googleusercontent.com/-ab3cDE6qjyo/Wu4Khr5ZKhI/AAAAAAAAA_A/725HNeKw2hYtuddakPreAkaucQR6HOYGgCJoC/w424-h318-n/20180317_085037.jpg
97
+ https://lh3.googleusercontent.com/-abYcDE6GABY/Wu4Khov2uGI/AAAAAAAAA_A/xFVaLt1emxUtOvys7Mw8QZIF2599lNV6ACJoC/w424-h318-n/20180317_085508.jpg
98
+ https://lh3.googleusercontent.com/-abMcDE6jtXg/Wu4KhkZD9nI/AAAAAAAAA_A/lBHtrho7HBQgkZNztMTdR3o1RSu47OnigCJoC/w239-h318-n/gplus1795981938.jpg
99
+ https://lh3.googleusercontent.com/-ab-cDE6kT88/Wu4Khs76OSI/AAAAAAAAA_A/2rsXBfNM4Isi3YBNWlgLnPgQpVN72dXiQCJoC/w318-h318-n/gplus-379421668.jpg
100
+ }.each_with_index do |link, i| # April contenstants
101
+ it "another (April) Google Plus community post image ##{i + 1}" do
102
+ assert DirectLink.google link
103
+ end
104
+ end
105
+ %w{
106
+ https://lh3.googleusercontent.com/-abcDE6XoL_k/WvMUBQ6TXMI/AAAAAAAAC60/XRgJlEr5hbgKzYzOQkM8b4_fq2Yp5vNbACJoC/w239-h318-n/%25D0%25B7%25D0%25B0%25D1%2581.jpg
107
+ https://lh3.googleusercontent.com/-abcDE6ZYF4Y/Wvl8HH7crSI/AAAAAAAAA20/0vaXtOyqDL0DLx841Gj45ePol01OCOAewCJoC/w212-h318-n/DPP_0007.JPG
108
+ https://lh3.googleusercontent.com/-abcDE6DAoH8/WyCS3fapzjI/AAAAAAAAB5M/hKzS0cR0MEgnM-YJENsL7dX8Tbch5Z04wCJoC/w265-h353-n/DSC03805.JPG
109
+ https://lh3.googleusercontent.com/-abcDE6hweSI/WvMUBS4uAJI/AAAAAAAAC60/tE7aakvztZgTqvRMcrk2FbrauU8LLhGPgCJoC/w239-h318-n/11.jpg
110
+ https://lh3.googleusercontent.com/-abcDE6T_v6g/WyCS3VJ-hVI/AAAAAAAAB5M/qeUFKiNXnwkJ-q2q2VoM2f9ukTqPOGhAACJoC/w265-h353-n/DSC03807.JPG
111
+ //2.bp.blogspot.com/-abcDE6kbjOk/WwlXLbeiF9I/AAAAAAAAKKE/zT7sAlaNYIc7lTxZMY1tyND0u3UH5DuKACLcBGAs/w530-h398-p/EdnjF3yEMM8.jpg
112
+ https://lh3.googleusercontent.com/-1_J-abcDE6E/Wx9lWOEXUjI/AAAAAAAAB34/183rqDWZipkaSWyV6qF_Fm7_XQrtYiwdACJoC/w265-h353-n/DSC03800.JPG
113
+ https://lh3.googleusercontent.com/-I72-abcDE64/Wx9lWLfINqI/AAAAAAAAB34/EIOySV-4ny8xMECMSC4TvHV43qUn0HLLwCJoC/w265-h353-n/DSC03797.JPG
114
+ https://lh3.googleusercontent.com/-L-RnabcDE6I/WxZnv-NRXWI/AAAAAAAARVw/Z3yVnOEDU7kDZ-WbRoLbEh8Tao1_DtQbACJoC/w179-h318-n/20160305_134926.jpg
115
+ //lh3.googleusercontent.com/-abcDE6HFM6E/WtRMPtqimXI/AAAAAAAACIo/txJyaoEvnEQu7r2-35SgwFYCWHGmXDQ3QCJoC/w530-h353-p/IMG_3695.jpg
116
+ }.each_with_index do |link, i| # May contenstants
117
+ it "another (May) Google Plus community post image ##{i + 1}" do
118
+ assert DirectLink.google link
119
+ end
120
+ end
121
+ %w{
122
+ https://lh3.googleusercontent.com/-dWul1-dnMGE/W1npdlvSenI/AAAAAAAAAJI/abcDE65xS98xvFJDNgMgcxrRzPd6gOp9QCJoC/w208-h318-n/alg3_1520-2.jpg
123
+ https://lh3.googleusercontent.com/-t_ab__91ChA/VeLaObkUlgI/AAAAAAAAL4s/abcDE6_lkRw/w530-h351-n/30.08.15%2B-%2B1
124
+ https://lh3.googleusercontent.com/-Ry3uDLjGG0E/W13DzrEntEI/AAAAAAAAAdY/abcDE6-2JPsnuqYq7qtif_eVWhTd0EmnwCJoC/w480-h853-n/gplus-790559743.jpg
125
+ }.each_with_index do |link, i| # June contenstants
126
+ it "another (June) Google Plus community post image ##{i + 1}" do
127
+ assert DirectLink.google link
128
+ end
129
+ end
130
+ %w{
131
+ https://lh3.googleusercontent.com/-s655sojwyvw/VcNB4YMCz-I/AAAAAAAALqo/abcDE6cJJ0g/w530-h398-n/06.08.15%2B-%2B1
132
+ //4.bp.blogspot.com/-TuMlpg-Q1YY/W3PXkW1lkaI/AAAAAAAAHHg/Bh9IsuLV01kbctIu6lcRJHKkY-abcDE6gCLcBGAs/w530-h353-p/_MG_2688-Edit.jpg
133
+ //lh3.googleusercontent.com/proxy/SEfB6tFuim6X0HdZfEBSxrXtumUdf4Q4y05rUW4wc_clWWVrowuWAGZghx71xwPUmf_abcDE6wnRivsM7PfD2gp3kA=w480-h360-n
134
+ https://lh3.googleusercontent.com/-u3FhiUTmLCY/Vk7dMQnxR2I/AAAAAAAAMc0/I76_abcDE6s/w530-h322-n/Harekosh_A%252520Concert_YkRqQg.jpg
135
+ https://lh3.googleusercontent.com/-t_ab__91ChA/VeLaObkUlgI/AAAAAAAAL4s/abcDE6_lkRw/w530-d-h351-n/30.08.15%2B-%2B1
136
+ //lh3.googleusercontent.com/-u2NzdIQfVyQ/Wy83AzoFT8I/AAAAAAAAh6M/fdpxOUkj5mUIfpvYol_abcDE6nF2nDIEACJoC/w530-h298-p/_DSC9134.jpg
137
+ }.each_with_index do |link, i| # July contenstants
138
+ it "another (July) Google Plus community post image ##{i + 1}" do
139
+ assert DirectLink.google link
140
+ end
141
+ end
142
+ %w{
143
+ https://lh3.googleusercontent.com/-f37xWyiyP8U/WvmxOxCd-0I/AAAAAAAACpw/3A2tRj02oY40MzJqZBJyWabcDE6r0lwMgCJoC/s0/140809%2B029.jpg
144
+ https://lh3.googleusercontent.com/-1s_eiQB4x2k/WvXQEx59z2I/AAAAAAAAcI0/DvKYzWw3g6UNelqAQdOwrabcDE6qKgkxwCJoC/s0/001
145
+ https://lh3.googleusercontent.com/-1Rcbffs4iRI/WvaSsRCrxJI/AAAAAAAAcJs/e-N9tmjaTCIxEBE_jXwFjabcDE6Fwh4owCJoC/s0/001
146
+ https://lh3.googleusercontent.com/-VXUjuSl-dZY/WvK340_E9uI/AAAAAAAAVlg/HqKf1LgUcPUJNrLxHebCMabcDE6q36_bQCJoC/s0/gplus248254159.jpg
147
+ https://lh3.googleusercontent.com/-NlZRwcX_Lj8/WvQTijeAfJI/AAAAAAABNyo/jgoDgbZdTvsnLOGmmYlXMabcDE6ieZV4QCJoC/s0/67u8iii.png
148
+ https://lh3.googleusercontent.com/-8baBz80pf8Y/Wu8KG5lyGhI/AAAAAAACSyU/s3hasZzObK0VlntA1EBj-abcDE6gzRnLQCJoC/s0/%25D0%2592%25D0%25B5%25D1%2581%25D0%25B5%25D0%25BD%25D0%25BD%25D0%25B8%25D0%25B5%2B%25D0%25BA%25D1%2580%25D0%25B0%25D1%2581%25D0%25B0%25D0%25B2%25D1%2586%25D1%258B.JPG
149
+ https://lh3.googleusercontent.com/-BBjhu17YIgg/W-gnZNaZeMI/AAAAAAABA-k/UMlSbNuE0DsSEPV8u3yf_abcDE69vFoBgCJoC/s0/gplus320347186.png
150
+ }.each_with_index do |link, i|
151
+ it "already high res image ##{i + 1}" do
152
+ assert DirectLink.google link
153
+ end
154
+ end
155
+ %w{
156
+ https://lh3.googleusercontent.com/-5USmSTZHWWI/WMi3q1GdgiI/AAAAAAAAQIA/lu9FTcUL6xMw4wdoW_I148Vm1abcDE6mwCJoC/w346-h195-n-k-no/Good%2BJob.gif
157
+ https://lh3.googleusercontent.com/-G8eSL3Xx2Kc/WxWt9M6LptI/AAAAAAAAB_c/KNF9RBxjL04Reb3fBtwYLI2AlabcDE67gCJoC/s0/20180602212016_IMG_0244.JPG
158
+ https://lh3.googleusercontent.com/-aUVoiLNsmAg/WzcsUU2xfNI/AAAAAAAAODw/DOBual6E1rkVLHh3SKZSzbpNQabcDE6OQCJoC/w530-h883-n-k-no/gplus-1797734754.mp4
159
+ //lh3.googleusercontent.com/proxy/hOIoIpMEmoVDSP40VRzM92Zw2AeLvEEhxfyKHCOxiNVPyiGvZik5rMvl3jYISLabcDE6mhZuk8pFEYJhX5BU2wy_dw=w530-h822-p
160
+ https://lh3.googleusercontent.com/-GP3BA3zGR5A/W0IwuVXlfmI/AAAAAAADROs/SH8rRlBDYTsHZiHpM45S3zpEiabcDE6PwCJoC/s0/%25D1%2582%25D0%25B0%25D0%25B4%25D0%25B6%25D0%25B8%25D0%25BA%25D1%2581%25D0%25BA%25D0%25BE%25D0%25B5%2B%25D1%2580%25D0%25B0%25D0%25B7%25D0%25BD%25D0%25BE%25D1%2582%25D1%2580%25D0%25B0%25D0%25B2%25D1%258C%25D0%25B5.png
161
+ https://lh3.googleusercontent.com/-DLODAbD9W7E/W27ob5XGCOI/AAAAAAADV8g/J_6RYR6UkKsc2RJOWRx6Q-NBVabcDE6xwCJoC/s0/1236080.jpg
162
+ https://lh3.googleusercontent.com/-cJajRreI87w/W4gW5uF4Q7I/AAAAAAADZKI/mw1YayYE-MY2-1OCCmjvgM3kbabcDE6ggCJoC/s0/2504855.jpg
163
+ https://lh3.googleusercontent.com/-rm-m1meCOMY/W92GhExMG-I/AAAAAAADsTw/bIAm5-1CIOYEpyPJLnxT8VmI_abcDE6dACJoC/s0/2659806_800n.jpg
164
+ https://lh3.googleusercontent.com/-z1nwsq4NOT4/XETT5qhXP-I/AAAAAAAAC0s/03kJ22drB1EdqZ97gUXCPHkLZabcDE6OACJoC/w530-h942-n/gplus1629127930.jpg
165
+ https://lh3.googleusercontent.com/-NiGph3ObOPg/XE3DgnavXlI/AAAAAAABvgE/pcPPCe88rsU1r941wwP76TVf_abcDE6kwCJoC/w530-h353-n/DSCF0753.JPG
166
+ https://lh3.googleusercontent.com/-QfChCi9Lj6A/XEciVlXmDhI/AAAAAAACuZw/iYzoMIxr7SsGzEFbk1LrqIdCdabcDE6HACJoC/w795-h1193-n-rw/z7765765765757575.jpg
167
+ }.each_with_index do |link, i|
168
+ it "gpluscomm_105636351696833883213_86400 ##{i + 1}" do
169
+ assert DirectLink.google link
170
+ end
171
+ end
172
+ %w{
173
+ https://4.bp.blogspot.com/--L451qLtGq8/W2MiFy8SVCI/AAAAAAAARgM/9qr4fr2PiV8IE4dabcDE6dEnlchx1V6vwCLcBGAs/w72-h72-p-k-no-nu/blood_moon_5k.jpg
174
+ https://3.bp.blogspot.com/-aZETNznngSo/W2xbe673_6I/AAAAAAAARhs/hkXvEk85ol4SqVeabcDE6uDGLyT4V45kACLcBGAs/w72-h72-p-k-no-nu/waterfall-1280x800-ireland-4k-19245.jpg
175
+ https://3.bp.blogspot.com/-ZmCuJkPliO8/W3WjIWvdjXI/AAAAAAAARi4/qO9I8kzJvCMRWsgabcDE6cOCQPCyu_xDQCLcBGAs/w72-h72-p-k-no-nu/ford_mustang_neon_lights_5k.jpg
176
+ https://2.bp.blogspot.com/-rb2PXLGZy0s/W2nQe3mXOSI/AAAAAAAARhQ/P8gV-bMtYbY2xxpabcDE6xu3XDTUaugxQCLcBGAs/w72-h72-p-k-no-nu/beach-bora-bora-clouds-753626.jpg
177
+ https://1.bp.blogspot.com/-FGnZn0040os/W3g7wnT2o-I/AAAAAAAARjE/xfgcR4fyvQgBgV5abcDE6YOVK4d4dTouwCLcBGAs/w72-h72-p-k-no-nu/axl_2018_movie_4k_8k-7680x4320.jpg
178
+ https://1.bp.blogspot.com/-h9kL603XSgY/XCe5rYiOczI/AAAAAAAARmY/qz_kMyR1q-scfs-abcDE6of_QocYK7RegCLcBGAs/w72-h72-p-k-no-nu/spider_man_into_the_spider_verse_hd_4k.jpg
179
+ https://2.bp.blogspot.com/-rb2PXLGZy0s/W2nQe3mXOSI/AAAAAAAARhQ/P8gV-bMtYbY2xxpabcDE6xu3XDTUaugxQCLcBGAs/s640/beach-bora-bora-clouds-753626.jpg
180
+ http://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/abcDE6b-v-g/w72-h72-p-k-no-nu/Top-24-Inspired-181.jpg
181
+ http://1.bp.blogspot.com/-iSU4orVuR9Y/VFYrwQZ5qYI/AAAAAAAAMnc/abcDE6aeplw/w72-h72-p-k-no-nu/Wolf%2Bphotography2.jpg
182
+ http://1.bp.blogspot.com/-vPQSh6RKijU/VEi7r3D-jJI/AAAAAAAAL2Q/abcDE6oDp5M/w72-h72-p-k-no-nu/Building%2BIn%2BLondon1-4__880.jpeg
183
+ http://1.bp.blogspot.com/-W4xKJSsVf3M/Uz73jPlctbI/AAAAAAAAGz4/abcDE6ILMeY/w72-h72-p-k-no-nu/Beautiful+Japanese+places4.jpg
184
+ https://1.bp.blogspot.com/-__qsdLxNtcQ/XhaOQle-ECI/AAAAAAAABQ4/S_7SGG_K8eQ7abcDE6yPvTj9OyBfr_1sQCLcBGAsYHQ/w1200-h630-p-k-no-nu/iceland_poppies_orange_flowers_field-wallpaper-3840x2160.jpg
185
+ https://lh3.googleusercontent.com/-tV86KJvppss/XE2Nb2Z2aAI/AAAAAAAAGu4/94E_abcDE6AaJ59n43wmmd9rFa--OUuSQCJoC/w530-h338-n/IMG_6845%252C.png
186
+ https://lh3.googleusercontent.com/-cr-2ZSQGMPg/XFWLfetwr7I/AAAAAAAAQQQ/TbwDabcDE6wb4IDDO0SwfArFSZyDG0i0wCJoC/w530-h360-n/DSC07294.JPG
187
+ https://lh3.googleusercontent.com/-7ey25Wg_cQ4/X-Xy8LJPjMI/AAAAAAAAALE/raXQabcDE6EzEDfAg3TcsOU_xc9z4szcwCLcBGAsYHQ/w1200-h630-p-k-no-nu/1608905381407960-0.png
188
+ https://lh3.googleusercontent.com/C84udoMpvJmi95AqshlF9acaR11TCsUgO9rGB9gG1w5Wp3WpB7U52ntft4jBHAyDg2guo6zqI4KZim-nGx_jf_XGqqiVANe_Jr8u2g=w1400-k
189
+ }.each_with_index do |link, i|
190
+ it "largeimages ##{i + 1}" do
191
+ assert DirectLink.google link
192
+ end
193
+ end
194
+ %w{
195
+ //lh3.googleusercontent.com/proxy/S-Z1P92Dd_u0DjYrz5Tb7j0mbZsGjPVffx9lHPQZCqqCFr6vAigCPOG0fEYKU6d-wIvwYr2WriAfh97KjBr9Bq1RKgyHzHq2fpAotTnJYOLd3x_abcDE6GBVuAewE7qp2QDtCYyomyn3dGjZ6cKUnYIC8w=s110-p-k
196
+ }.each_with_index do |link, i|
197
+ it "posted_website_preview_##{i + 1}" do
198
+ assert DirectLink.google link
199
+ end
200
+ end
201
+ %w{
202
+ 0 https://lh3.googleusercontent.com/-okfIabcDE6g/AAAAAAAAAAI/AAAAAAAAZa0/FEv9H8woCBg/s30-p-rw-no/photo.jpg
203
+ 7 https://lh3.googleusercontent.com/-okfIabcDE6g/AAAAAAAAAAI/AAAAAAAAZa0/FEv9H8woCBg/s75-p-rw-no/photo.jpg
204
+ _ https://lh3.googleusercontent.com/-bhgxabcDE6I/AAAAAAAAAAI/AAAAAAAA4MI/_KuKE-Goa7E/s35-p-k-rw-no/photo.jpg
205
+ - https://lh3.googleusercontent.com/-tl9-abcDE6Y/AAAAAAAAAAI/AAAAAAAA8uY/vVeZX8SbTXI/s35-p-k-rw-no/photo.jpg
206
+ 4 https://lh3.googleusercontent.com/-Rb83abcDE64/AAAAAAAAAAI/AAAAAAAAEJc/DawCLQGnaSA/s45-p-k-rw-no/photo.jpg
207
+ }.each_slice 2 do |i, link|
208
+ it "Google Plus userpic #{i}" do
209
+ assert DirectLink.google link
210
+ end
211
+ end
212
+ %w{
213
+ - https://lh3.googleusercontent.com/-abcDE6oWuoU/AAAAAAAAAAI/AAAAAAAAl90/ed314-fNMGg/s20-c-k-no/photo.jpg
214
+ just https://lh5.googleusercontent.com/-abcDE6YpZzU/AAAAAAAAAAI/AAAAAAAAAO4/WISrqFs1vT8/s46-c-k-no/photo.jpg
215
+ no-no https://lh5.googleusercontent.com/-abcDE6MkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/s64-c-k/photo.jpg
216
+ no-k-no https://lh3.googleusercontent.com/-abcDE66JAgg/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXD1lA9yGoSbsihWmGfnl6Z3Rn43WA/s64-c-mo/photo.jpg
217
+ _ https://lh6.googleusercontent.com/-abcDE6PRFk4/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXDBweE5VzGGy4zMraO_pqiLuFN3yQ/s46-c-k-no-mo/photo.jpg
218
+ }.each_slice 2 do |i, link|
219
+ it "Hangout userpic #{i}" do
220
+ assert DirectLink.google link
221
+ end
222
+ end
223
+ %w{
224
+ https://lh4.googleusercontent.com/abcDE6lyjNKXqSqszuiCgPMi7_oE5fVv1Sw373HXBYlguP8AnIPAqefTS6DbBuurVGYRSxGrtDyKei1hae9Djf6rjiwjJd0aauA5Bg-z=s615
225
+ https://lh5.googleusercontent.com/fRmAL_04p7oomNHCiV4tH4-agHSDBtLaWi_Tb6bgE5ZSHVu5OjQF3iRn06nNwP3ywZwdFP92zWM-abcDE6n6m0tDTBARuO6F9e0wYu_1=s685
226
+ https://lh5.googleusercontent.com/FcYUQBKLXWtFLEvbQduvu7FHUm2f7U_MVdMBVnNbpwfzKHIU-xABkudxw-abcDE60jFYRHedh7Is5Dg6qlgIQF1iSndlWjiKCTTsUo1w=s1080
227
+ https://lh5.googleusercontent.com/gcDb3dxbch9jUKPzKGawJiwtHcNS9wp6o2sc0aJj9wOWQA-u8kXmKIrZ-abcDE6ee6qLaT2p6OK2N7klTJ9CxU66OnpBhYJMg0q9QEdq5Q=s2160
228
+ }.each_with_index do |link, i|
229
+ it "google keep ##{i + 1}" do
230
+ assert DirectLink.google link
231
+ end
232
+ end
233
+
234
+ end
235
+
236
+ end
237
+
238
+ describe "imgur" do
239
+
240
+ %w{
241
+ https://imgur.com/a/badlinkpattern
242
+ http://example.com/
243
+ https://imgur.com/gallery/abcD5.
244
+ }.each_with_index do |url, i|
245
+ it "ErrorBadLink_##{i + 1}" do
246
+ assert_raises DirectLink::ErrorBadLink do
247
+ DirectLink.imgur url
248
+ end
249
+ end
250
+ end
251
+
252
+ it "ErrorNotFound when album is empty" do
253
+ stub_request(:head, "https://api.imgur.com/3/album/abcDEF7/0.json")#.to_return(status: 200, body: "", headers: {})
254
+ stub_request(:get, "https://api.imgur.com/3/album/abcDEF7/0.json").to_return body: {data: {images: {}}}.to_json
255
+ e = assert_raises DirectLink::ErrorNotFound do
256
+ DirectLink.imgur "https://imgur.com/a/abcDEF7"
257
+ end
258
+ assert_nil e.cause if Exception.instance_methods.include? :cause # Ruby 2.1
259
+ end
260
+
261
+ valid_imgur_image_url_direct = "https://i.imgur.com/abcDEF7.jpg"
262
+ valid_imgur_image_url_album = "https://imgur.com/a/abcDEF7"
263
+ [404].each do |error_code|
264
+ it error_code do
265
+ e = assert_raises DirectLink::ErrorNotFound do
266
+ NetHTTPUtils.stub :request_data, ->*{ raise NetHTTPUtils::Error.new "", error_code } do
267
+ DirectLink.imgur valid_imgur_image_url_direct
268
+ end
269
+ end
270
+ assert_equal error_code, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
271
+ end
272
+ end
273
+ [599].each do |error_code|
274
+ it error_code do
275
+ e = assert_raises DirectLink::ErrorAssert do
276
+ NetHTTPUtils.stub :request_data, ->*{ raise NetHTTPUtils::Error.new "", error_code } do
277
+ DirectLink.imgur valid_imgur_image_url_direct
278
+ end
279
+ end
280
+ assert_equal error_code, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
281
+ end
282
+ end
283
+ [400, 500, 502, 503].each do |error_code|
284
+ [
285
+ [valid_imgur_image_url_direct, :direct],
286
+ [valid_imgur_image_url_album, :album],
287
+ ].each do |url, kind|
288
+ it "retries a limited number of times on error #{error_code} (#{kind})" do
289
+ tries = 0
290
+ e = assert_raises DirectLink::ErrorAssert do
291
+ NetHTTPUtils.stub :request_data, ->*{ tries += 1; raise NetHTTPUtils::Error.new "", error_code } do
292
+ DirectLink.imgur url, 1.5
293
+ end
294
+ end
295
+ assert_equal error_code, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
296
+ assert_equal 2, tries
297
+ end
298
+ end
299
+ end
300
+ it "does not throw 400 after a successfull retry" do
301
+ stub_request(:head, "https://api.imgur.com/3/image/abcDEF7/0.json")
302
+ stub_request(:get, "https://api.imgur.com/3/image/abcDEF7/0.json").to_return body: {data: {width: 100, height: 200, type: "image/jpeg", link: "https://i.imgur.com/abcDEF7.jpg"}}.to_json
303
+ f = 0
304
+ m = NetHTTPUtils.method :request_data
305
+ NetHTTPUtils.stub :request_data, lambda{ |*args, **kwargs|
306
+ raise NetHTTPUtils::Error.new "", 400 if 1 == f += 1
307
+ m.call *args, **kwargs
308
+ } do
309
+ assert_equal [[valid_imgur_image_url_direct, 100, 200, "image/jpeg"]],
310
+ DirectLink.imgur(valid_imgur_image_url_direct, 1.5)
311
+ end
312
+ end
313
+
314
+ [
315
+ ["gifv" , "http://i.imgur.com/abcDEF7.gifv", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"http://i.imgur.com/abcDEF7h.gif", "width"=>100, "height"=>200, "type"=>"image/gif"}],
316
+ ["gif" , "https://i.imgur.com/abcD5.mp4", "https://api.imgur.com/3/image/abcD5/0.json", {"link"=>"https://i.imgur.com/abcD5.gif", "width"=>100, "height"=>200, "type"=>"image/gif"}],
317
+ ["mp4" , "https://i.imgur.com/abcDEF7.png", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"}],
318
+ ["fb" , "https://i.imgur.com/abcDEF7.jpg?fb", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
319
+ ["jpEg" , "https://i.imgur.com/abcDEF7.jpeg", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
320
+ [nil , "http://m.imgur.com/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
321
+ [nil , "https://imgur.com/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.mp4", "width"=>100, "height"=>200, "type"=>"video/mp4"}],
322
+ [nil , "http://imgur.com/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
323
+ ["5 char photo" , "https://imgur.com/abcD5", "https://api.imgur.com/3/image/abcD5/0.json", {"link"=>"https://i.imgur.com/abcD5.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
324
+ ["single photo album" , "https://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]}],
325
+ ["5 char https album" , "https://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]*6}, 6],
326
+ ["7 char https album" , "https://imgur.com/a/abcDEF7", "https://api.imgur.com/3/album/abcDEF7/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"]*2}, 2],
327
+ ["album zoomable" , "http://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]*49}, 49],
328
+ ["album not zoomable" , "http://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"]*20}, 20],
329
+ [nil , "http://imgur.com/gallery/abcDEF7/new", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
330
+ [nil , "http://imgur.com/gallery/abcD5", "https://api.imgur.com/3/gallery/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]*7}, 7],
331
+ ["single image gallery?" , "http://imgur.com/gallery/abcDEF7", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"}],
332
+ [nil , "http://imgur.com/gallery/abcD5/new", "https://api.imgur.com/3/gallery/abcD5/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
333
+ ["gallery mp4" , "https://imgur.com/gallery/abcDEF7", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.mp4", "width"=>100, "height"=>200, "type"=>"video/mp4"}],
334
+ ["id belongs to an image", "http://imgur.com/gallery/abcDEF7", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {status: [404, "Not Found"]}, DirectLink::ErrorNotFound],
335
+ ["id belongs to an album", "http://imgur.com/gallery/abcD5", "https://api.imgur.com/3/gallery/abcD5/0.json", {status: [404, "Not Found"]}, DirectLink::ErrorNotFound],
336
+ [nil , "http://imgur.com/r/wallpaper/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg?1", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
337
+ [nil , "https://imgur.com/abcDEF7?third_party=1#_=_", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
338
+ ].each_with_index do |t, i|
339
+ desc, url, stub_head, stub, m = t
340
+ it "kinds of post ##{i + 1}#{" (#{desc})" if desc}" do
341
+ case m
342
+ when Class
343
+ stub_request(:head, stub_head).to_return(stub) if stub_head
344
+ assert_raises m do
345
+ DirectLink.imgur url
346
+ end
347
+ when NilClass
348
+ stub_request(:head, stub_head) if stub_head
349
+ stub_request(:get, stub_head).to_return body: {data: stub}.to_json if stub
350
+ real = DirectLink.imgur url
351
+ assert_equal 1, real.size
352
+ assert_equal((stub["images"] ? stub["images"][0].values : stub.values), real.first)
353
+ when Numeric
354
+ stub_request(:head, stub_head) if stub_head
355
+ stub_request(:get, stub_head).to_return body: {data: stub}.to_json if stub
356
+ real = DirectLink.imgur url
357
+ assert_equal m, real.size
358
+ assert_equal stub["images"][0].values, real.first
359
+ else
360
+ fail "bug in tests"
361
+ end
362
+ end
363
+ end
364
+ end
365
+
366
+ describe "_500px" do
367
+ [
368
+ ["https://500px.com/photo/123456789/morning-by", [1200, 800, "https://drscdn.500px.org/photo/123456789/m%3D900/v2?sig=#{Array.new(64){rand(16).to_s(16)}.join}", "jpeg"]],
369
+ ["https://500px.com/photo/1234567890/-flowers-by/", [1819, 2500, "https://drscdn.500px.org/photo/1234567890/m%3D900/v2?sig=#{Array.new(64){rand(16).to_s(16)}.join}", "jpeg"]],
370
+ ["https://500px.com/photo/1234567890/is%E5-by-%E7ku-/", [2048, 2048, "https://drscdn.500px.org/photo/1234567890/m%3D2048/v2?sig=#{Array.new(64){rand(16).to_s(16)}.join}", "jpeg"]]
371
+ ].each_with_index do |(input, (w, h, u, t)), i|
372
+ it "kinds of links" do
373
+ id = URI(input).path[/\d+/]
374
+ stub_request(:head, "https://api.500px.com/v1/photos?ids=#{id}")
375
+ stub_request(:get, "https://api.500px.com/v1/photos?ids=#{id}").to_return body: {"photos"=>{id=>{"width"=>w,"height"=>h}}}.to_json
376
+ stub_request(:head, "https://api.500px.com/v1/photos?ids=#{id}&image_size%5B%5D=#{w}")
377
+ stub_request(:get, "https://api.500px.com/v1/photos?ids=#{id}&image_size%5B%5D=#{w}").to_return body: {"photos"=>{id=>{"images"=>[{"format"=>t,"url"=>u}]}}}.to_json
378
+ result = DirectLink.method(:_500px).call input
379
+ assert_equal [w, h, u, t], result, "#{input} :: #{result.inspect} != #{[w, h, u, t].inspect}"
380
+ end
381
+ end
382
+ end
383
+
384
+ describe "flickr" do
385
+ [
386
+ ["https://www.flickr.com/photos/tomas-/12345678901/", DirectLink::ErrorNotFound],
387
+ ["https://www.flickr.com/photos/12345678@N07/12345678901", DirectLink::ErrorNotFound],
388
+ ["https://www.flickr.com/photos/12345678@N00/12345678901/", [3000, 2000, "https://live.staticflickr.com/7757/12345678901_ed5178cc6a_o.jpg"]], # trailing slash
389
+ ["https://www.flickr.com/photos/jacob_schmidt/12345678901/in/album-12345678901234567/", DirectLink::ErrorNotFound], # username in-album
390
+ ["https://www.flickr.com/photos/tommygi/1234567890/in/dateposted-public/", [1600, 1062, "https://live.staticflickr.com/5249/1234567890_29fae96e38_h.jpg"]], # username in-public
391
+ ["https://www.flickr.com/photos/123456789@N02/12345678901/in/album-12345678901234567/", DirectLink::ErrorNotFound],
392
+ ["https://www.flickr.com/photos/123456789@N03/12345678901/in/dateposted-public/", [4621, 3081, "https://live.staticflickr.com/3796/12345678901_f751b35aeb_o.jpg"]], # userid in-public
393
+ ["https://www.flickr.com/photos/frank3/1234567890/in/photolist#{"-6KVb92"*50}", [4096, 2723, "https://live.staticflickr.com/2499/1234567890_dfa75a41cc_4k.jpg"]],
394
+ ["https://www.flickr.com/photos/patricksloan/12345678901/sizes/l", [2048, 491, "https://live.staticflickr.com/5572/12345678900_fec4783d79_k.jpg"]],
395
+ ["https://flic.kr/p/abcDEF", [5120, 3413, "https://live.staticflickr.com/507/12345678901_1bd49c5ebd_5k.jpg"]],
396
+ ].each_with_index do |(input, expectation), i|
397
+ it "kinds of links" do
398
+ stub_request(:head, /\Ahttps:\/\/api\.flickr\.com\/services\/rest\/\?api_key=#{ENV["FLICKR_API_KEY"]}&format=json&method=flickr\.photos\.getSizes&nojsoncallback=1&photo_id=[\da-zA-Z]+\z/)
399
+ if expectation.is_a? Class
400
+ stub_request(:get, /\Ahttps:\/\/api\.flickr\.com\/services\/rest\/\?api_key=#{ENV["FLICKR_API_KEY"]}&format=json&method=flickr\.photos\.getSizes&nojsoncallback=1&photo_id=[\da-zA-Z]+\z/).to_return body: {"stat"=>"fail", "code"=>1, "message"=>"Photo not found"}.to_json
401
+ assert_raises expectation, input do
402
+ DirectLink.method(:flickr).call input
403
+ end
404
+ else
405
+ w, h, u = expectation
406
+ stub_request(:get, /\Ahttps:\/\/api\.flickr\.com\/services\/rest\/\?api_key=#{ENV["FLICKR_API_KEY"]}&format=json&method=flickr\.photos\.getSizes&nojsoncallback=1&photo_id=[\da-zA-Z]+\z/).to_return body: {"stat"=>"ok", "sizes"=>{ "size"=>[
407
+ {"width"=>w/2, "height"=>h , "source"=>u*2},
408
+ {"width"=>w , "height"=>h , "source"=>u },
409
+ {"width"=>w , "height"=>h/2, "source"=>u*2},
410
+ ] } }.to_json
411
+ result = DirectLink.method(:flickr).call input
412
+ assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
413
+ end
414
+ end
415
+ end
416
+ end
417
+
418
+ describe "wiki" do
419
+ [
420
+ ["https://en.wikipedia.org/wiki/Prostitution_by_country#/media/File:Prostitution_laws_of_the_world.PNG", "https://upload.wikimedia.org/wikipedia/commons/e/e8/Prostitution_laws_of_the_world.PNG"],
421
+ ["https://en.wikipedia.org/wiki/Third_Party_System#/media/File:United_States_presidential_election_results,_1876-1892.svg", DirectLink::ErrorAssert],
422
+ ["http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg", "https://upload.wikimedia.org/wikipedia/commons/0/0d/Eduard_Bohlen_anagoria.jpg"],
423
+ ["https://en.wikipedia.org/wiki/Spanish_Civil_War#/media/File:Alfonso_XIIIdeEspa%C3%B1a.jpg", "https://upload.wikimedia.org/wikipedia/commons/f/fb/Alfonso_XIIIdeEspa%C3%B1a.jpg"], # escaped input URI
424
+ ["https://en.wikipedia.org/wiki/File:Tyson_Lewis.jpg", "https://upload.wikimedia.org/wikipedia/en/c/cd/Tyson_Lewis.jpg"], # exists only in en.wiki, not in commons
425
+ ].each_with_index do |(input, expectation), i|
426
+ it "kinds of links" do
427
+ url = URI(input).tap{ |_| _.fragment = nil }.to_s
428
+ stub_request(:head, url)
429
+ stub_request(:head, "https://#{URI(input).hostname}/w/api.php?action=query&format=json&iiprop=url&prop=imageinfo&titles=#{input[/(File:.+)/]}")
430
+ if expectation.is_a? Class
431
+ stub_request(:get, "https://en.wikipedia.org/w/api.php?action=query&format=json&iiprop=url&prop=imageinfo&titles=#{input[/(File:.+)/]}").to_return body: {
432
+ "query"=>{"pages"=>{"-1"=>{}}}
433
+ }.to_json
434
+ assert_raises expectation, input do
435
+ DirectLink.wiki input
436
+ end
437
+ else
438
+ stub_request(:get, "https://#{URI(input).hostname}/w/api.php?action=query&format=json&iiprop=url&prop=imageinfo&titles=#{input[/(File:.+)/]}").to_return body: {
439
+ "query"=>{"pages"=>{"-1"=>{"imageinfo"=>[{"url"=>expectation}]}}}
440
+ }.to_json
441
+ result = DirectLink.wiki input
442
+ assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
443
+ end
444
+ end
445
+ end
446
+ end
447
+
448
+ describe "reddit" do
449
+ [
450
+ ["https://i.redd.it/abcde6k7r5xz.jpg", [true, "https://i.redd.it/abcde6k7r5xz.jpg"]],
451
+ ["https://www.reddit.com/r/cacography/comments/abcde6/c/", [true, "http://i.imgur.com/abcde6Z.jpg"], false, "abcde6"],
452
+ ["http://redd.it/abcde6", [true, "http://i.imgur.com/abcde6Z.jpg"], false, "abcde6"], # TODO maybe check that it calls #imgur recursively
453
+ ["http://redd.it/abcde6", [true, "https://i.redd.it/abcde66ehrg11.jpg"], false, "abcde6"],
454
+ ["https://reddit.com/abcde6", [true, "https://i.ytimg.com/vi/abcde6RbIeU/hqdefault.jpg"],
455
+ false, "abcde6",
456
+ {"type"=>"youtube.com","oembed"=>{"thumbnail_url"=>"https://i.ytimg.com/vi/abcde6RbIeU/hqdefault.jpg"}},
457
+ nil,
458
+ "http://www.youtube.com/watch?v=abcde6RbIeU&feature=g-vrec",
459
+ ],
460
+ ["https://www.reddit.com/r/hangers/comments/abcde6/tara_radovic/", [true, "https://i.imgur.com/abcDE6u.jpg"],
461
+ false, "abcde6",
462
+ nil,
463
+ "t3_abcde7",
464
+ ], # "crossport" from Imgur
465
+ ["https://www.reddit.com/gallery/abcde6",
466
+ [true, [
467
+ ["image/jpg", 1440, 1440, "https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b"],
468
+ ["image/jpg", 2441, 2441, "https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a"],
469
+ ] ],
470
+ false, "abcde6",
471
+ nil,
472
+ nil,
473
+ "https://www.reddit.com/gallery/abcde6",
474
+ {
475
+ "x31msdjabcde6"=>{
476
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
477
+ "y"=>1440,
478
+ "x"=>1440,
479
+ "u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b",
480
+ },
481
+ },
482
+ "mwkzq6jabcde6"=>{
483
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
484
+ "y"=>2441,
485
+ "x"=>2441,
486
+ "u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a",
487
+ },
488
+ },
489
+ },
490
+ ],
491
+ ["https://www.reddit.com/abcde6",
492
+ [true, [
493
+ ["image/jpg", 1440, 1440, "https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b"],
494
+ ["image/jpg", 2441, 2441, "https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a"],
495
+ ] ],
496
+ false, "abcde6",
497
+ nil,
498
+ nil,
499
+ "https://www.reddit.com/gallery/abcde6",
500
+ {
501
+ "x31msdjabcde6"=>{
502
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
503
+ "y"=>1440,
504
+ "x"=>1440,
505
+ "u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b",
506
+ },
507
+ },
508
+ "mwkzq6jabcde6"=>{
509
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
510
+ "y"=>2441,
511
+ "x"=>2441,
512
+ "u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a",
513
+ },
514
+ },
515
+ },
516
+ ],
517
+ ["https://www.reddit.com/gallery/abcde6", [true, "https://www.reddit.com/gallery/abcde6"], false, "abcde6"], # deleted gallery
518
+ ["https://www.reddit.com/abcde6", [true, "https://www.reddit.com/r/Firewatch/comments/abcde7/new_wallpaper/"],
519
+ false, "abcde6",
520
+ nil,
521
+ "t3_abcde7",
522
+ "/r/Firewatch/comments/abcde7/new_wallpaper/",
523
+ ], # deleted gallery
524
+ ["https://www.reddit.com/abcde6",
525
+ [true, [
526
+ ["image/jpg", 500, 500, "https://preview.redd.it/abcde6eexo461.jpg?width=500&format=pjpg&auto=webp&s=df211fe0699e3970681ffe493ed1af79725857e8"],
527
+ ["image/jpg", 720, 446, "https://preview.redd.it/abcde6hexo461.jpg?width=720&format=pjpg&auto=webp&s=5e34ab0e6d54c0acfdb47f1daaf283087c5ad6a6"],
528
+ ["image/jpg", 713, 588, "https://preview.redd.it/abcde6lexo461.jpg?width=713&format=pjpg&auto=webp&s=969dfb52bedd6f0055249aa8b7454b23adaa946e"],
529
+ ] ],
530
+ false, "abcde6",
531
+ nil,
532
+ nil,
533
+ "https://www.reddit.com/gallery/abcde6",
534
+ {
535
+ "71t8ljeabcde6"=>{
536
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
537
+ "y"=>500,
538
+ "x"=>500,
539
+ "u"=>"https://preview.redd.it/abcde6eexo461.jpg?width=500&format=pjpg&auto=webp&s=df211fe0699e3970681ffe493ed1af79725857e8",
540
+ },
541
+ },
542
+ "bfmjbtjabcde6"=>{"status"=>"failed"},
543
+ "c11nt7habcde6"=>{
544
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
545
+ "y"=>446,
546
+ "x"=>720,
547
+ "u"=>"https://preview.redd.it/abcde6hexo461.jpg?width=720&format=pjpg&auto=webp&s=5e34ab0e6d54c0acfdb47f1daaf283087c5ad6a6",
548
+ },
549
+ },
550
+ "67mqvllabcde6"=>{
551
+ "status"=>"valid", "m"=>"image/jpg", "s"=>{
552
+ "y"=>588,
553
+ "x"=>713,
554
+ "u"=>"https://preview.redd.it/abcde6lexo461.jpg?width=713&format=pjpg&auto=webp&s=969dfb52bedd6f0055249aa8b7454b23adaa946e"
555
+ },
556
+ },
557
+ },
558
+ ], # failed media
559
+ ["https://www.reddit.com/r/CatsStandingUp/duplicates/abcde6/cat/",
560
+ [true, "https://v.redd.it/abcde6fb6w721/DASH_2_4_M?source=fallback"],
561
+ false, "abcde6",
562
+ {"reddit_video"=>{"fallback_url"=>"https://v.redd.it/abcde6fb6w721/DASH_2_4_M?source=fallback"}},
563
+ nil,
564
+ "https://v.redd.it/abcde6fb6w721",
565
+ ],
566
+ ["https://www.reddit.com/r/MapPorn/comments/abd123/________aaaabdeeeeeefggghhhiilmmnnoorrrssttuvyyz/",
567
+ [true, [
568
+ ["image/gif", 500, 375, "https://i.redd.it/00146fghhjkox.gif"],
569
+ ["image/jpg", 1000, 600, "https://preview.redd.it/1369aacghkswy.jpg?width=1000&format=pjpg&auto=webp&s=0122334444557777778889aaabbbbcdddddeeeef"],
570
+ ]],
571
+ false, "abd123",
572
+ nil,
573
+ nil,
574
+ "https://www.reddit.com/gallery/abd123",
575
+ {
576
+ "00146fghhjkox"=>{
577
+ "status"=>"valid",
578
+ "e"=>"AnimatedImage",
579
+ "m"=>"image/gif",
580
+ "p"=>[],
581
+ "s"=>{
582
+ "y"=>375,
583
+ "gif"=>"https://i.redd.it/00146fghhjkox.gif",
584
+ "mp4"=>"",
585
+ "x"=>500
586
+ },
587
+ "id"=>"00146fghhjkox"
588
+ },
589
+ "1369aacghkswy"=>{
590
+ "status"=>"valid",
591
+ "e"=>"Image",
592
+ "m"=>"image/jpg",
593
+ "p"=>[],
594
+ "s"=>{
595
+ "y"=>600,
596
+ "x"=>1000,
597
+ "u"=>"https://preview.redd.it/1369aacghkswy.jpg?width=1000&format=pjpg&auto=webp&s=0122334444557777778889aaabbbbcdddddeeeef"
598
+ },
599
+ "id"=>"1369aacghkswy"
600
+ }
601
+ },
602
+ ]
603
+ ].each_with_index do |(input, expectation, is_self, id, media, crosspost_parent, url, media_metadata), i|
604
+ it "kinds of links" do
605
+ unless is_self.nil?
606
+ fail "bug in test: no id" unless id
607
+ stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: {"access_token"=>"123456789012-abcDE6CFsglE63e5F1v8ThrVa9HThg"}.to_json
608
+ stub_request(:get, "https://oauth.reddit.com/by_id/t3_#{id}?api_type=json").to_return body: {
609
+ "data"=>{"children"=>[{"data"=>{
610
+ "is_self"=>is_self,
611
+ "media"=>media,
612
+ "crosspost_parent"=>crosspost_parent,
613
+ "url"=>(url||expectation[1]),
614
+ "media_metadata"=>media_metadata,
615
+ # "permalink"=>"/r/cacography/comments/32tq0i/c/",
616
+ # "selftext"=>"",
617
+ }}]}
618
+ }.to_json
619
+ end
620
+ result = DirectLink.reddit input
621
+ assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
622
+ end
623
+ end
624
+ end
625
+
626
+ describe "vk" do
627
+ [
628
+ ["https://vk.com/wall-123456091_7806", [960, 1280, "https://userapi.com/impf/c123456/v123456900/a72f1/7OZ8ux9Wcwo.jpg"], "wall", [
629
+ [97, 130, "https://sun9-3.userapi.com/impf/c123456/v123456900/a72f1/7OZ8ux9Wcwo.jpg?size=98x130&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=ggVFjBTdFDFuIz7Ee5o48mEP3fWLixCvjuPmehhyaTI&type=album"],
630
+ [960, 1280, "https://sun9-3.userapi.com/impf/c123456/v123456900/a72f1/7OZ8ux9Wcwo.jpg?size=960x1280&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=vKCnEFEDol5QYM0qPrYAkbDwzYo6U_jo0SOR8iQO7HA&type=album"],
631
+ ] ],
632
+ ["https://vk.com/wall-123456611_454?z=photo-123456611_457239340%2Fwall-123456611_454", [1280, 960, "https://userapi.com/impf/c123456/v123456578/1a62f6/VB4SdR1O6Tg.jpg"], "photos", [
633
+ [130, 97, "https://sun9-59.userapi.com/impf/c123456/v123456578/1a62f6/VB4SdR1O6Tg.jpg?size=130x98&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=xJlpXkJvi0P9WQhcM5acgLHqSUzXK3FGahuZHHncZQY&type=album"],
634
+ [1280, 960, "https://sun9-59.userapi.com/impf/c123456/v123456578/1a62f6/VB4SdR1O6Tg.jpg?size=1280x960&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=2ulEOYXMOAN-KJm7HPNZYNcScyikyHdIsRmeqM8i16w&type=album"],
635
+ ] ],
636
+ ["https://vk.com/wall-123456091_7946?z=photo-123456091_457243312%2Falbum-123456091_00%2Frev", [1280, 875, "https://userapi.com/impf/c123456/v123456134/1b6b36/0IsDFb-Hda4.jpg"], "photos", [
637
+ [130, 89, "https://sun9-20.userapi.com/impf/c123456/v123456134/1b6b36/0IsDFb-Hda4.jpg?size=130x89&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=PcNYWJFing2At2LiJVOYQOTUd_MbMLxiyPybwnyzaN4&type=album"],
638
+ [1280, 875, "https://sun9-20.userapi.com/impf/c123456/v123456134/1b6b36/0IsDFb-Hda4.jpg?size=1280x875&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=o7eFSi5F74SmkTirdrIS19nh8CEG32Od6yPvX9IPXds&type=album"],
639
+ ] ],
640
+ ["https://vk.com/id12345627?z=photo12345627_456241143%2Falbum12345627_0", [1920, 1440, "https://userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg"], "photos", [
641
+ [130, 97, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=130x98&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=uJX7tU35qumnZFlAUe-EhyVVT1FDBoHmp_8Z-dFAH_I&type=album"],
642
+ [1920, 1440, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=1920x1440&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=06VziJvbo7gkdo5t0AUEQRs6EX8UrmiT2XkfGRmfRz8&type=album"],
643
+ ] ],
644
+ ["https://vk.com/id12345627?z=photo12345627_456241143", [1920, 1440, "https://userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg"], "photos", [
645
+ [130, 97, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=130x98&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=uJX7tU35qumnZFlAUe-EhyVVT1FDBoHmp_8Z-dFAH_I&type=album"],
646
+ [1920, 1440, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=1920x1440&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=06VziJvbo7gkdo5t0AUEQRs6EX8UrmiT2XkfGRmfRz8&type=album"],
647
+ ] ],
648
+ ["https://vk.com/photo1_123187843?all=1", [2560, 1913, "https://userapi.com/impf/c123/v123001/6/53_VwoACy4I.jpg"], "photos", [
649
+ [130, 98, "https://sun1-23.userapi.com/impf/c123/v123001/6/53_VwoACy4I.jpg?size=130x97&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=Hq3mDN7NbJvgRd82cKsQpJ45Tze8deKbUX4FZDwVZGQ&type=album"],
650
+ [2560, 1913, "https://sun1-23.userapi.com/impf/c123/v123001/6/53_VwoACy4I.jpg?size=2560x1913&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=yANq6f3QAVxu7M1xuy6fMu1JgkYOPqB1jBV4bQVjc0Y&type=album"],
651
+ ] ],
652
+ ["https://vk.com/photo123456340_456243948?rev=1", [1583, 1080, "https://userapi.com/impf/c123456/v123456479/321be/9rZaJ2QTdz4.jpg"], "photos", [
653
+ [130, 89, "https://sun9-21.userapi.com/impf/c123456/v123456479/321be/9rZaJ2QTdz4.jpg?size=130x89&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=9comrJGukZcMLlCDrmQMWhFtne217kVaZcafgoQmCVM&type=album"],
654
+ [1583, 1080, "https://sun9-21.userapi.com/impf/c123456/v123456479/321be/9rZaJ2QTdz4.jpg?size=1583x1080&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=iwiLvdT52wwR8avHhjDUwPUozsvMpVyuFHHACavY2zA&type=album"],
655
+ ] ],
656
+ ["https://vk.com/photo-123456973_456242404", [1486, 1000, "https://userapi.com/impf/c123456/v123456877/8578e/m6AJWiskiKE.jpg"], "photos", [
657
+ [130, 87, "https://sun9-51.userapi.com/impf/c123456/v123456877/8578e/m6AJWiskiKE.jpg?size=130x87&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=pSxKInGItqdMMW_83z9SXDzIi74Zl9UJ-P-snVmzHHY&type=album"],
658
+ [1486, 1000, "https://sun9-51.userapi.com/impf/c123456/v123456877/8578e/m6AJWiskiKE.jpg?size=1486x1000&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=2IwG6BAja36QQl3mDsUcWS6PC7ozt6TSExLsfRXRyzA&type=album"],
659
+ ] ],
660
+ ["https://vk.com/feed?section=likes&z=photo-123456754_456261460%2Fliked1234566", [1024, 1335, "https://userapi.com/impf/c123456/v123456353/895b6/izQJresLdf0.jpg"], "photos", [
661
+ [100, 130, "https://sun9-55.userapi.com/impf/c123456/v123456353/895b6/izQJresLdf0.jpg?size=100x130&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=HHJ8PsYFgnwmuq9OfND51luLXJve81QbpWvudWXv5aw&type=album"],
662
+ [1024, 1335, "https://sun9-55.userapi.com/impf/c123456/v123456353/895b6/izQJresLdf0.jpg?size=1024x1335&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=42fraqliOifFUG1CvgahG1lg1txVMF5hbSVlAUkLwf8&type=album"],
663
+ ] ],
664
+ ["https://vk.com/likizimy?z=photo-12345651_456239941%2Fwall-12345651_1908", [1179, 1731, "https://userapi.com/impf/c123456/v123456571/60f7b/ryCPJIMyMkI.jpg"], "photos", [
665
+ [89, 130, "https://sun9-37.userapi.com/impf/c123456/v123456571/60f7b/ryCPJIMyMkI.jpg?size=89x130&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=uaDVTYCfixIN4JKSGzgNSTsjiuOUi0658_CgoIF-mqc&type=album"],
666
+ [1179, 1731, "https://sun9-37.userapi.com/impf/c123456/v123456571/60f7b/ryCPJIMyMkI.jpg?size=1179x1731&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=rTxHctkqrP4SQsbcECYGDCVt03A43cLYRN8eTnOFtD0&type=album"],
667
+ ] ],
668
+ ["https://vk.com/e_rod?z=photo123456340_457247118%2Fphotos123456340", [1728, 2160, "https://userapi.com/impf/c123456/v123456596/c7714/oImGe4o1ZJI.jpg"], "photos", [
669
+ [104, 130, "https://sun9-53.userapi.com/impf/c123456/v123456596/c7714/oImGe4o1ZJI.jpg?size=104x130&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=8KN44nSlDjD-FMDiRhHqk6udwiqZfn5n1qqPNFwu_nI&type=album"],
670
+ [1728, 2160, "https://sun9-53.userapi.com/impf/c123456/v123456596/c7714/oImGe4o1ZJI.jpg?size=1728x2160&quality=96&proxy=1&sign=00011222222224455677888abbbbccee&c_uniq_tag=CA61KgCRsRXbHm4VJEYYskjpjpSiTHI7UPV4FsCPRmI&type=album"],
671
+ ] ],
672
+ ["https://vk.com/wasserman.anatoliy?w=wall-123457771_353", [864, 1080, "https://userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg"], "wall", [
673
+ [104, 130, "https://sun9-38.userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg?size=104x130&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=qX06fI2p7bmyvnta_Pt2omQ-l5RBLcrG1DBsLWx1jJA&type=album"],
674
+ [864, 1080, "https://sun9-38.userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg?size=864x1080&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=6WP6TY0RTDiG_8NK1lkYUOge22jtjkzGLLwc6IDxjjg&type=album"],
675
+ ] ],
676
+ ["https://vk.com/feed?z=photo-88180328_457249666%2Falbum-88180328_00%2Frev", [3, 4, "https://userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg"], "photos", [
677
+ [1, 2, "https://sun9-38.userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg?size=104x130&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=qX06fI2p7bmyvnta_Pt2omQ-l5RBLcrG1DBsLWx1jJA&type=album"],
678
+ [3, 4, "https://sun9-38.userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg?size=864x1080&quality=96&sign=00011222222224455677888abbbbccee&c_uniq_tag=6WP6TY0RTDiG_8NK1lkYUOge22jtjkzGLLwc6IDxjjg&type=album"],
679
+ ] ],
680
+ ].each_with_index do |(input, expectation, mtd, stub), i|
681
+ it "kinds of links" do
682
+ stub = {sizes: stub.map{ |w,h,u| {width: w, height: h, url: u} }}
683
+ stub_request(:post, "https://api.vk.com/method/#{mtd}.getById").to_return body: {response: [
684
+ mtd == "photos" ? stub : {attachments: [{type: :photo, photo: stub}]}
685
+ ] }.to_json
686
+ result = DirectLink.method(:vk).call input
687
+ assert_equal 1, result.size
688
+ result[0][-1].tap do |url|
689
+ url.replace( URI.parse(url).tap do |_|
690
+ _.host = _.host.split(?.).drop(1).join(?.)
691
+ _.query = nil
692
+ end.to_s )
693
+ end
694
+ assert_equal [expectation], result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
695
+ end
696
+ end
697
+ end
698
+
699
+ describe "google" do
700
+ method = :google
701
+ [
702
+ "https://lh3.googleusercontent.com/-NVJgqmI_2Is/WqMM2OMYg-I/AAAAAAAALrk/5-p3JL3iZt0Ho9dOf_abcDE6zqwr3Wp0ACJoC/w424-h318-n/001",
703
+ "//lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_abcDE6iu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n",
704
+ "//1.bp.blogspot.com/-rYk_u-qROQc/WngolJ8M0LI/AAAAAAAAD-w/woivnaIVzasBPG5C2T1t-VrWKRd_abcDE6LcBGAs/w530-h278-p/i-469.jpg",
705
+ "https://2.bp.blogspot.com/-rb2PXLGZy0s/W2nQe3mXOSI/AAAAAAAARhQ/P8gV-abcDE62xxpTJNcYVxu3XDTUaugxQCLcBGAs/s640/beach-bora-bora-clouds-753626.jpg",
706
+ "http://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/mabcDE6-v-g/w72-h72-p-k-no-nu/Top-24-Inspired-181.jpg",
707
+ "https://lh5.googleusercontent.com/FcYUQBKLXWtFLEvbQduvu7FHUm2f7U_MVdMBVnNbpwfzKHIU-xABkudxw-abcDE60jFYRHedh7Is5Dg6qlgIQF1iSndlWjiKCTTsUo1w=s1080",
708
+ ].each do |input|
709
+ it "DirectLink() choses a method '#{method}' according to a domain" do
710
+ DirectLink.stub method, ->(link, timeout = nil){
711
+ assert_equal input, link
712
+ throw :_
713
+ } do
714
+ catch :_ do
715
+ DirectLink input
716
+ fail "DirectLink.#{method} was not called"
717
+ end
718
+ end
719
+ end
720
+ end
721
+ end
722
+
723
+ {
724
+ imgur: [
725
+ [%w{ https://imgur.com/abcD5 https://imgur.com/abcD5 }, [
726
+ %w{ https://imgur.com/abcD5 },
727
+ ] ],
728
+ [%w{ https://i.imgur.com/abcD5 https://imgur.com/abcD5 }, [
729
+ [*%w{ https://i.imgur.com/abcD5 https://imgur.com/abcD5 }, [302, "Moved Temporarily"]],
730
+ %w{ https://imgur.com/abcD5 },
731
+ ] ],
732
+ [%w{ https://m.imgur.com/abcD5 https://imgur.com/abcD5 }, [
733
+ %w{ https://m.imgur.com/abcD5 https://imgur.com/abcD5 },
734
+ %w{ https://imgur.com/abcD5 },
735
+ ] ],
736
+ [%w{ https://www.imgur.com/abcD5 https://imgur.com/abcD5 }, [
737
+ [*%w{ https://www.imgur.com/abcD5 https://imgur.com/abcD5 }, [301, "Moved Permanently"]],
738
+ %w{ https://imgur.com/abcD5 },
739
+ ] ],
740
+ [%w{ https://goo.gl/abcDE6 https://i.imgur.com/abcDEFY.png }, [
741
+ %w{ https://goo.gl/abcDE6 https://i.imgur.com/abcDEFY.png },
742
+ %w{ https://i.imgur.com/abcDEFY.png },
743
+ ] ],
744
+ ],
745
+ _500px: [
746
+ [%w{ https://500px.com/photo/123456789/milky-way https://500px.com/photo/123456789/milky-way }, [
747
+ %w{ https://500px.com/photo/123456789/milky-way },
748
+ ] ],
749
+ ],
750
+ flickr: [
751
+ ["https://www.flickr.com/photos/12345678@N07/12345678901/in/dateposted-public/", [
752
+ ["https://www.flickr.com/photos/12345678@N07/12345678901/in/dateposted-public/"],
753
+ ] ],
754
+ [["https://flic.kr/p/abcDEF", "https://www.flickr.com/photos/lopez/12345678901/"], [
755
+ ["https://flic.kr/p/abcDEF", "https://www.flickr.com/photo.gne?short=abcDEF"],
756
+ ["https://www.flickr.com/photo.gne?short=abcDEF", "/photo.gne?rb=1&short=abcDEF"],
757
+ ["https://www.flickr.com/photo.gne?rb=1&short=abcDEF", "/photos/lopez/12345678901/"],
758
+ ["https://www.flickr.com/photos/lopez/12345678901/"],
759
+ ] ],
760
+ ],
761
+ wiki: [
762
+ ["https://en.wikipedia.org/wiki/Third_Party_System#/media/File:United_States_presidential_election_results,_1876-1892.svg", [
763
+ %w{ https://en.wikipedia.org/wiki/Third_Party_System },
764
+ ] ],
765
+ [%w{ http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg https://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg }, [
766
+ %w{ http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg https://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg },
767
+ %w{ https://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg }
768
+ ] ],
769
+ ],
770
+ reddit: [
771
+ [%w{ https://www.reddit.com/r/abcdef/comments/abcde6/c/ }, [
772
+ %w{ https://www.reddit.com/r/abcdef/comments/abcde6/c/ },
773
+ ] ],
774
+ [%w{ http://redd.it/abcde6 https://www.reddit.com/comments/abcde6 }, [
775
+ [*%w{ http://redd.it/abcde6 https://redd.it/abcde6 }, [301, "Moved Permanently"]],
776
+ [*%w{ https://redd.it/abcde6 https://www.reddit.com/comments/abcde6 }, [302, "Temporarily Moved"]],
777
+ %w{ https://www.reddit.com/comments/abcde6 },
778
+ ] ],
779
+ [%w{ https://reddit.com/123456 https://www.reddit.com/r/funny/comments/123456/im_thinking/ }, [
780
+ [*%w{ https://reddit.com/123456 https://www.reddit.com/123456 }, [301, "Moved Permanently"]],
781
+ [*%w{ https://www.reddit.com/123456 https://www.reddit.com/r/funny/comments/123456/im_thinking/ }, [301, "Moved Permanently"]],
782
+ %w{ https://www.reddit.com/r/funny/comments/123456/im_thinking/ },
783
+ ] ],
784
+ [%w{ https://www.reddit.com/r/abcDEF/comments/abcde6/beard_trimmer/ }, [
785
+ %w{ https://www.reddit.com/r/abcDEF/comments/abcde6/beard_trimmer/ }
786
+ ] ], # NSFW causes redirect to /over_18? if the special cookie not provided # TODO: improve this test
787
+ ],
788
+ vk: [
789
+ ["https://vk.com/id12345678?z=photo12345678_456241143", [
790
+ ["https://vk.com/id12345678?z=photo12345678_456241143", nil, [418, ""]],
791
+ ] ],
792
+ ],
793
+ }.each do |method, tests|
794
+ describe "DirectLink() choses a method '#{method}' according to a domain" do
795
+ tests.each_with_index do |((input, expected), stub), i|
796
+ it "##{i + 1}" do
797
+ DirectLink.stub method, ->(link, timeout = nil, **__){
798
+ assert_equal (expected || input), link
799
+ throw :_
800
+ } do
801
+ (stub || []).each do |u, o, code|
802
+ if o
803
+ stub_request(:head, u).to_return status: (code || [302, "Found"]), headers: {location: o}
804
+ else
805
+ if code
806
+ stub_request(:head, u).to_return status: code
807
+ else
808
+ stub_request(:head, u)
809
+ end
810
+ end
811
+ end
812
+ catch :_ do
813
+ DirectLink input
814
+ fail "DirectLink.#{method} was not called"
815
+ end
816
+ end
817
+ end
818
+ end
819
+ end
820
+ end
821
+
822
+ # TODO: make a Reddit describe
823
+ it "retries limited amount of times on error JSON::ParserError" do
824
+ # TODO: the same but with the error expected to be gone after tries
825
+ stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: '{"access_token": "123456789000-17BDFFGGJJKNPVXZlt-2ACKQZfoswz", "token_type": "bearer", "expires_in": 3600, "scope": "*"}'
826
+ stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde6?api_type=json").to_return body: "invalid JSON"
827
+ tries = 0
828
+ m = JSON.method :load
829
+ e = assert_raises DirectLink::ErrorBadLink do
830
+ JSON.stub :load, ->*_,**__{ tries += 1; m.call *_,**__ } do
831
+ DirectLink.reddit "https://www.reddit.com/r/gifs/comments/abcde6/", 2.5
832
+ end
833
+ end
834
+ assert_instance_of JSON::ParserError, e.cause if Exception.instance_methods.include? :cause # Ruby 2.1
835
+ assert (3 <= tries)
836
+ assert (tries <= 4)
837
+ end
838
+
839
+ it "Reddit correctly parses out id when no token provided" do
840
+ stub_request(:head, "https://www.reddit.com/r/gifs/comments/9ftc8f/")
841
+ m = NetHTTPUtils.method :request_data
842
+ NetHTTPUtils.stub :request_data, lambda{ |u, *args, **kwargs|
843
+ throw :_ if u == "https://www.reddit.com/9ftc8f.json"
844
+ m.call u, *args, **kwargs
845
+ } do
846
+ t = ENV.delete "REDDIT_SECRETS"
847
+ begin
848
+ catch :_ do
849
+ DirectLink "https://www.reddit.com/r/gifs/comments/9ftc8f/"
850
+ fail
851
+ end
852
+ ensure
853
+ ENV["REDDIT_SECRETS"] = t
854
+ end
855
+ end
856
+ end
857
+
858
+ describe "throws ErrorBadLink if method does not match the link" do
859
+ %i{ google imgur flickr _500px wiki reddit vk }.each do |method|
860
+ ["", "test", "http://example.com/"].each_with_index do |url, i|
861
+ it "#{method} ##{i + 1}" do
862
+ assert_raises DirectLink::ErrorBadLink do
863
+ DirectLink.method(method).call url
864
+ end
865
+ end
866
+ end
867
+ end
868
+ end
869
+
870
+ end
871
+
872
+ describe "DirectLink()" do
873
+
874
+ # thanks to gem addressable
875
+ it "does not throw URI::InvalidURIError if there are brackets" do
876
+ stub_request(:head, "https://www.flickr.com/photos/nakilon/12345678900/%2520%5B2048x1152%5D").to_return status: [404, "Not Found"]
877
+ assert_equal 404, (
878
+ assert_raises NetHTTPUtils::Error do
879
+ DirectLink "https://www.flickr.com/photos/nakilon/12345678900/%20[2048x1152]"
880
+ end.code
881
+ )
882
+ end
883
+
884
+ it "throws ErrorNotFound when Reddit gallery is removed" do
885
+ stub_request(:head, "https://www.reddit.com/gallery/abcde6")
886
+ stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: {"access_token"=>"123456789012-abcde6cOO5V20ZD6J8WC6l36gMYRXQ"}.to_json
887
+ stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde6?api_type=json").to_return body: {
888
+ "data"=>{
889
+ "children"=>[{
890
+ "data"=>{
891
+ "selftext"=>"[удалено]",
892
+ "media_metadata"=>nil,
893
+ "is_self"=>false,
894
+ "permalink"=>"/r/woahdude/comments/abcde6/crystal_light/",
895
+ "url"=>"https://www.reddit.com/gallery/abcde6",
896
+ "media"=>nil
897
+ }
898
+ }]
899
+ }
900
+ }.to_json
901
+ assert_raises DirectLink::ErrorNotFound do
902
+ DirectLink "https://www.reddit.com/gallery/abcde6"
903
+ end
904
+ end
905
+
906
+ it "follows Reddit crosspost" do
907
+ stub_request(:head, "https://www.reddit.com/abcde6").to_return status: [301, "Moved Permanently"], headers: {location: "https://www.reddit.com/r/wallpapers/comments/abcde6/new_wallpaper/"}
908
+ stub_request(:head, "https://www.reddit.com/r/wallpapers/comments/abcde6/new_wallpaper/")
909
+ stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: {"access_token"=>"123456789012-abcde6WGKuIupoi5M3NtPVdI7bk1jg"}.to_json
910
+ stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde6?api_type=json").to_return body: {
911
+ "data"=>{
912
+ "children"=>[{
913
+ "data"=>{
914
+ "selftext"=>"",
915
+ "is_self"=>false,
916
+ "crosspost_parent"=>"t3_abcde7",
917
+ "permalink"=>"/r/wallpapers/comments/abcde6/new_wallpaper/",
918
+ "url"=>"/r/Firewatch/comments/abcde7/new_wallpaper/",
919
+ "media"=>nil,
920
+ }
921
+ }]
922
+ }
923
+ }.to_json
924
+ stub_request(:head, "https://www.reddit.com/r/Firewatch/comments/abcde7/new_wallpaper/")
925
+ stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde7?api_type=json").to_return body: {
926
+ "data"=>{
927
+ "children"=>[{
928
+ "data"=>{
929
+ "selftext"=>"I",
930
+ "media_metadata"=>{
931
+ "abcde62zhek51"=>{
932
+ "status"=>"valid",
933
+ "m"=>"image/png",
934
+ "s"=>{"y"=>1920, "x"=>4920, "u"=>"asd"},
935
+ },
936
+ "abcde72zhek51"=>{
937
+ "status"=>"valid",
938
+ "m"=>"image/png",
939
+ "s"=>{"y"=>1920, "x"=>4920, "u"=>"asd"},
940
+ }
941
+ },
942
+ "is_self"=>true,
943
+ "media"=>nil,
944
+ "permalink"=>"/r/Firewatch/comments/abcde7/new_wallpaper/",
945
+ "url"=>"https://www.reddit.com/r/Firewatch/comments/abcde7/new_wallpaper/",
946
+ }
947
+ }],
948
+ }
949
+ }.to_json
950
+ assert_equal %w{ image/png image/png }, DirectLink("https://www.reddit.com/abcde6").map(&:type)
951
+ end
952
+
953
+ it "throws ErrorBadLink if link is invalid" do
954
+ assert_equal "test".inspect, (
955
+ assert_raises DirectLink::ErrorBadLink do
956
+ DirectLink "test"
957
+ end
958
+ ).message
959
+ end
960
+
961
+ describe "does not shadow the internal exception" do
962
+ [
963
+ SocketError,
964
+ Errno::ECONNRESET,
965
+ ].each do |exception|
966
+ it "raises #{exception} from the redirect resolving stage" do
967
+ assert_raises exception do
968
+ NetHTTPUtils.stub :request_data, ->*{ raise exception.new } do
969
+ DirectLink "http://example.com/404"
970
+ end
971
+ end
972
+ end
973
+ end
974
+ it "raises Net::OpenTimeout -- server side issues can happen (not related to User Agent)" do
975
+ assert_raises Net::OpenTimeout do
976
+ NetHTTPUtils.stub :request_data, ->*{ raise Net::OpenTimeout.new } do
977
+ DirectLink "http://example.com/404"
978
+ end
979
+ end
980
+ end
981
+ it "HEAD Errno::ETIMEDOUT and GET FastImage::ImageFetchFailure are handled by DirectLink::NORMAL_EXCEPTIONS" do
982
+ assert_includes DirectLink::NORMAL_EXCEPTIONS, FastImage::ImageFetchFailure
983
+ assert_raises FastImage::ImageFetchFailure do
984
+ NetHTTPUtils.stub :request_data, ->_,mtd,*{ fail unless mtd == :HEAD; raise Errno::ETIMEDOUT } do
985
+ FastImage.stub :new, ->*{ raise FastImage::ImageFetchFailure } do
986
+ DirectLink "http://www.mesacc.edu/~hello12345/hello/images/photos/aerial/a1234.jpg"
987
+ end
988
+ end
989
+ end
990
+ end
991
+ [ # TODO this URLs may be reused from tests that check that this method calls internal method
992
+ [:google, "//lh3.googleusercontent.com/proxy/578BDGJKLLNPTZceiikqtww_Wi2UTaQH0AC_h2kuURiu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n"],
993
+ [:imgur, "http://imgur.com/ABCDEFG"],
994
+ [:flickr, "https://www.flickr.com/photos/12345678@N00/00013355778/"],
995
+ [:_500px, "https://500px.com/photo/123456789/milky-way"],
996
+ [:wiki, "http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg"],
997
+ [:reddit, "https://www.reddit.com/123456"],
998
+ [:vk, "https://vk.com/"],
999
+ ].each do |method, link|
1000
+ it "can otherwise raise DirectLink::ErrorBadLink #{method}" do
1001
+ stub_request(:head, link)
1002
+ e = assert_raises(DirectLink::ErrorBadLink, link) do
1003
+ DirectLink.stub method, ->*{ raise DirectLink::ErrorBadLink.new "test" } do
1004
+ DirectLink link
1005
+ end
1006
+ end
1007
+ assert_equal "\"test\" -- if you think this link is valid, please report the issue", e.message
1008
+ end
1009
+ end
1010
+ end
1011
+
1012
+ describe "other domains tests" do
1013
+ [
1014
+ ["http://www.cute.org/wp-content/uploads/2010/10/Niagara.jpg", SocketError, /nodename nor servname provided, or not known|Name or service not known|getaddrinfo: Name does not resolve/, 0],
1015
+ ].each_with_index do |(input, expectation, message_string_or_regex, max_redirect_resolving_retry_delay), i|
1016
+ it "##{i + 1}" do
1017
+ if expectation.is_a? Class
1018
+ # TODO: move the stub to the array above
1019
+ stub_request(:head, input).to_raise expectation.new("Failed to open TCP connection to www.cute.org:80 (getaddrinfo: nodename nor servname provided, or not known)")
1020
+ e = assert_raises expectation, "for #{input}" do
1021
+ DirectLink input, max_redirect_resolving_retry_delay
1022
+ end
1023
+ if message_string_or_regex.is_a? String
1024
+ assert_equal message_string_or_regex, e.message, "for #{input}"
1025
+ else
1026
+ assert_match message_string_or_regex, e.message, "for #{input}"
1027
+ end
1028
+ else
1029
+ u, w, h, t = expectation
1030
+ result = DirectLink input, max_redirect_resolving_retry_delay
1031
+ assert_equal DirectLink.class_variable_get(:@@directlink).new(u, w, h, t), result, "for #{input}"
1032
+ end
1033
+ end
1034
+ end
1035
+ end
1036
+
1037
+ describe "giving up" do
1038
+ [
1039
+ [
1040
+ ["http://example.com", FastImage::UnknownImageType],
1041
+ [
1042
+ [:get, "http://example.com", {body: "<!doctype html><html><head><title>Example Domain</title><meta charset='utf-8'/></head><body><div><h1>Example Domain</h1><p>Lorem ipsum.</p></div></body></html>"}],
1043
+ ],
1044
+ ],
1045
+ [
1046
+ ["http://imgur.com/QWERTYU", FastImage::UnknownImageType, true],
1047
+ [
1048
+ [:get, "http://imgur.com/QWERTYU", {status: [301, "Moved Permanently"], headers: {location: "https://imgur.com/QWERTYU"}}],
1049
+ [:get, "https://imgur.com/QWERTYU", {body: "<html><body></body></html>"}],
1050
+ ],
1051
+ ],
1052
+ [
1053
+ ["http://imgur.com/QWERTYU", "https://i.imgur.com/QWERTYU.jpeg?fb"], # .at_css("meta[@property='og:image']")
1054
+ [
1055
+ [:head, "http://imgur.com/QWERTYU", {status: [301, "Moved Permanently"], headers: {Location: "https://imgur.com/QWERTYU"}}],
1056
+ [:get, "http://imgur.com/QWERTYU", {status: [301, "Moved Permanently"], headers: {Location: "https://imgur.com/QWERTYU"}}],
1057
+ [:head, "https://imgur.com/QWERTYU", {headers: {"Content-Type"=>"text/html"}}],
1058
+ [:get, "https://imgur.com/QWERTYU", {body: <<~HEREDOC
1059
+ <html>
1060
+ <head>
1061
+ <meta property="og:url" data-react-helmet="true" content="https://imgur.com/QWERTYU">
1062
+ <meta name="twitter:image" data-react-helmet="true" content="https://i.imgur.com/QWERTYUh.jpg">
1063
+ <meta property="og:image:width" data-react-helmet="true" content="1">
1064
+ <meta property="og:image:height" data-react-helmet="true" content="2">
1065
+ <meta property="og:image" data-react-helmet="true" content="https://i.imgur.com/QWERTYU.jpeg?fb">
1066
+ <meta property="og:type" data-react-helmet="true" content="article">
1067
+ </head>
1068
+ <body></body>
1069
+ </html>
1070
+ HEREDOC
1071
+ } ],
1072
+ [:head, "https://i.imgur.com/QWERTYU.jpeg?fb"],
1073
+ [:get, "https://i.imgur.com/QWERTYU.jpeg?fb", {body: "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC9\x00\v\b\x00\x01\x00\x01\x01\x01\x11\x00\xFF\xCC\x00\x06\x00\x10\x10\x05\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xD2\xCF \xFF\xD9"}],
1074
+ ],
1075
+ ],
1076
+ [
1077
+ ["https://www.deviantart.com/nakilon/art/Nakilon-123456789", FastImage::UnknownImageType, true],
1078
+ [
1079
+ [:get, "https://www.deviantart.com/nakilon/art/Nakilon-123456789", {body: <<~HEREDOC
1080
+ <html>
1081
+ <head>
1082
+ <meta data-rh="true" property="og:image" content="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/>
1083
+ </head>
1084
+ <body class="theme-dark">
1085
+ <div id="root">
1086
+ <main role="main" class="_1TdPo">
1087
+ <div class="_3tEjH">
1088
+ <div><img alt="Nakilon" aria-hidden="true" class="_1izoQ" src="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/></div>
1089
+ </div>
1090
+ </main>
1091
+ </div>
1092
+ </body>
1093
+ </html>
1094
+ HEREDOC
1095
+ } ],
1096
+ ],
1097
+ ],
1098
+ [
1099
+ ["https://www.deviantart.com/nakilon/art/Nakilon-123456789", "https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"],
1100
+ [
1101
+ [:head, "https://www.deviantart.com/nakilon/art/Nakilon-123456789", {headers: {"Content-Type"=>"text/html; charset=utf-8"}}],
1102
+ [:get, "https://www.deviantart.com/nakilon/art/Nakilon-123456789", {body: <<~HEREDOC
1103
+ <html>
1104
+ <head>
1105
+ <meta data-rh="true" property="og:image" content="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/>
1106
+ </head>
1107
+ <body class="theme-dark">
1108
+ <div id="root">
1109
+ <main role="main" class="_1TdPo">
1110
+ <div class="_3tEjH">
1111
+ <div><img alt="Nakilon" aria-hidden="true" class="_1izoQ" src="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/></div>
1112
+ </div>
1113
+ </main>
1114
+ </div>
1115
+ </body>
1116
+ </html>
1117
+ HEREDOC
1118
+ } ],
1119
+ [:head, "https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"],
1120
+ [:get, "https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01", {body: "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC9\x00\v\b\x00\x01\x00\x01\x01\x01\x11\x00\xFF\xCC\x00\x06\x00\x10\x10\x05\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xD2\xCF \xFF\xD9"}],
1121
+ ],
1122
+ ],
1123
+ # TODO: og:image without scheme
1124
+ [
1125
+ ["https://www.reddit.com/r/darksouls3/comments/qwe123/hand/", DirectLink::ErrorBadLink, true],
1126
+ [
1127
+ [:head, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {location: "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
1128
+ [:head, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"],
1129
+ [:get, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {"Location"=>"https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
1130
+ [:get, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json", {body: <<~HEREDOC
1131
+ [
1132
+ {
1133
+ "data" : {
1134
+ "before" : null,
1135
+ "children" : [
1136
+ {
1137
+ "data" : {
1138
+ "selftext" : "[A](https://imgur.com/a/abcDEF1). I \\n [Here](https://imgur.com/a/abcDEF2)\\n\\nMobile: https://imgur.com/a/abcDEF3",
1139
+ "id" : "qwe123",
1140
+ "name" : "t3_qwe123",
1141
+ "is_self" : true,
1142
+ "media" : null,
1143
+ "permalink" : "/r/darksouls3/comments/qwe123/hand/",
1144
+ "over_18" : false,
1145
+ "url" : "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/"
1146
+ },
1147
+ "kind" : "t3"
1148
+ }
1149
+ ]
1150
+ }
1151
+ }, {}
1152
+ ]
1153
+ HEREDOC
1154
+ } ],
1155
+ ],
1156
+ ],
1157
+ [
1158
+ ["https://www.reddit.com/r/darksouls3/comments/qwe123/hand/", 6], # TODO: should see the 3rd album too
1159
+ [
1160
+ [:head, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {location: "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
1161
+ [:head, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"],
1162
+ [:get, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {Location: "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
1163
+ [:get, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json", {body: <<~HEREDOC
1164
+ [
1165
+ {
1166
+ "data" : {
1167
+ "before" : null,
1168
+ "children" : [
1169
+ {
1170
+ "data" : {
1171
+ "selftext" : "[A](https://imgur.com/a/abcDEF1). I \\n [Here](https://imgur.com/a/abcDEF2)\\n\\nMobile: https://imgur.com/a/abcDEF3",
1172
+ "id" : "qwe123",
1173
+ "name" : "t3_qwe123",
1174
+ "is_self" : true,
1175
+ "media" : null,
1176
+ "permalink" : "/r/darksouls3/comments/qwe123/hand/",
1177
+ "over_18" : false,
1178
+ "url" : "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/"
1179
+ },
1180
+ "kind" : "t3"
1181
+ }
1182
+ ]
1183
+ }
1184
+ }, {}
1185
+ ]
1186
+ HEREDOC
1187
+ } ],
1188
+ [:head, "https://imgur.com/a/abcDEF1"],
1189
+ [:head, "https://api.imgur.com/3/album/abcDEF1/0.json"],
1190
+ [:get, "https://api.imgur.com/3/album/abcDEF1/0.json", {body: <<~HEREDOC
1191
+ {
1192
+ "status" : 200,
1193
+ "success" : true,
1194
+ "data" : {
1195
+ "id" : "abcDEF1",
1196
+ "link" : "https://imgur.com/a/abcDEF1",
1197
+ "images" : [
1198
+ {
1199
+ "link" : "https://i.imgur.com/abcDEF4.png",
1200
+ "type" : "image/png",
1201
+ "height" : 1080,
1202
+ "width" : 1920
1203
+ },
1204
+ {
1205
+ "link" : "https://i.imgur.com/abcDEF5.png",
1206
+ "type" : "image/png",
1207
+ "height" : 1080,
1208
+ "width" : 1920
1209
+ }
1210
+ ]
1211
+ }
1212
+ }
1213
+ HEREDOC
1214
+ } ],
1215
+ [:head, "https://imgur.com/a/abcDEF2"],
1216
+ [:head, "https://api.imgur.com/3/album/abcDEF2/0.json"],
1217
+ [:get, "https://api.imgur.com/3/album/abcDEF2/0.json", {body: <<~HEREDOC
1218
+ {
1219
+ "status" : 200,
1220
+ "success" : true,
1221
+ "data" : {
1222
+ "id" : "abcDEF2",
1223
+ "link" : "https://imgur.com/a/abcDEF2",
1224
+ "images" : [
1225
+ {
1226
+ "link" : "https://i.imgur.com/abcDEF6.png",
1227
+ "type" : "image/png",
1228
+ "height" : 1080,
1229
+ "width" : 1920
1230
+ },
1231
+ {
1232
+ "link" : "https://i.imgur.com/abcDEF7.jpg",
1233
+ "type" : "image/jpeg",
1234
+ "height" : 1080,
1235
+ "width" : 1920
1236
+ },
1237
+ {
1238
+ "link" : "https://i.imgur.com/abcDEF8.jpg",
1239
+ "type" : "image/jpeg",
1240
+ "height" : 1080,
1241
+ "width" : 1920
1242
+ },
1243
+ {
1244
+ "link" : "https://i.imgur.com/abcDEF9.jpg",
1245
+ "type" : "image/jpeg",
1246
+ "height" : 1080,
1247
+ "width" : 1920
1248
+ }
1249
+ ]
1250
+ }
1251
+ }
1252
+ HEREDOC
1253
+ } ],
1254
+ ],
1255
+ ],
1256
+ ].each do |(input, expectation, giveup), stubs|
1257
+ it "#{URI(input).host} giveup=#{!!giveup}" do
1258
+ stub_request(:head, input)
1259
+ stubs.each do |mtd, link, response|
1260
+ if response
1261
+ stub_request(mtd, link).to_return **response
1262
+ else
1263
+ stub_request(mtd, link)
1264
+ end
1265
+ end
1266
+ ti = ENV.delete "IMGUR_CLIENT_ID" if %w{ imgur com } == URI(input).host.split(?.).last(2)
1267
+ tr = ENV.delete "REDDIT_SECRETS" if %w{ reddit com } == URI(input).host.split(?.).last(2)
1268
+ begin
1269
+ case expectation
1270
+ when Class
1271
+ e = assert_raises expectation, "for #{input} (giveup = #{giveup})" do
1272
+ DirectLink input, 5, giveup: giveup
1273
+ end
1274
+ assert_equal expectation.to_s, e.class.to_s, "for #{input} (giveup = #{giveup})"
1275
+ when String
1276
+ result = DirectLink input, 5, giveup: giveup
1277
+ assert_equal expectation, result.url, "for #{input} (giveup = #{giveup})"
1278
+ else
1279
+ result = DirectLink input, 5, giveup: giveup
1280
+ result = [result] unless result.is_a? Array # we can't do `Array(<Struct>)` because it splats by elements
1281
+ assert_equal expectation, result.size, ->{
1282
+ "for #{input} (giveup = #{giveup}): #{result.map &:url}"
1283
+ }
1284
+ end
1285
+ ensure
1286
+ ENV["IMGUR_CLIENT_ID"] = ti if ti
1287
+ ENV["REDDIT_SECRETS"] = tr if tr
1288
+ end
1289
+ end
1290
+ end
1291
+ end
1292
+
1293
+ end
1294
+
1295
+ describe "./bin" do
1296
+ require "open3"
1297
+
1298
+ describe "shows usage help if misused" do
1299
+ [
1300
+ [/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, nil],
1301
+ [/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "-h"],
1302
+ [/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "--help"],
1303
+ [/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "-v"],
1304
+ [/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "--version"],
1305
+ ["DirectLink::ErrorBadLink: \"--\"\n", "--"],
1306
+ ["DirectLink::ErrorBadLink: \"-\"\n", "-"],
1307
+ ["DirectLink::ErrorBadLink: \"-\"\n", "- -"],
1308
+ ["DirectLink::ErrorBadLink: \"asd\"\n", "asd"],
1309
+ ].each_with_index do |(expectation, param), i|
1310
+ it "##{i + 1}" do
1311
+ string, status = Open3.capture2e "RUBYOPT='-rbundler/setup' ./bin/directlink #{param}"
1312
+ if expectation.is_a? String
1313
+ assert_equal expectation, string
1314
+ else
1315
+ assert_match expectation, string
1316
+ end
1317
+ assert_equal 1, status.exitstatus
1318
+ end
1319
+ end
1320
+ end
1321
+
1322
+ # that hack around `export` is for crossplatform Travis test, since Ubuntu uses `sh` that can't `source`
1323
+ # TODO: but maybe I could make Open3 use the shell I need, since `source` works fine for `.travis.yaml`'s `:script`
1324
+
1325
+ popen = lambda do |input, stubs, export = nil, param = nil|
1326
+ file = Tempfile.new %w{ directlink_webmock .rb }
1327
+ file.write <<~HEREDOC
1328
+ require "webmock"
1329
+ include WebMock::API
1330
+ require "#{__dir__}/webmock_patch"
1331
+ WebMock.enable!
1332
+ #{stubs.inspect}.each do |mtd, input, response|
1333
+ if response
1334
+ stub_request(mtd, input).to_return **response
1335
+ else
1336
+ stub_request(mtd, input)
1337
+ end
1338
+ end
1339
+ HEREDOC
1340
+ file.flush
1341
+ begin
1342
+ Open3.capture2e "#{"export #{File.read("api_tokens.sh").scan(/(?<=^export )\S+=\S+/).join(" ")} && " if export}RUBYOPT='-r bundler/setup #{$-I.map{ |i| "-I #{i}" }.join " "} -r #{file.path}' ./bin/directlink#{" --#{param}" if param} #{input}"
1343
+ ensure
1344
+ file.close
1345
+ file.unlink
1346
+ end
1347
+ end
1348
+
1349
+ [
1350
+ [1, "http://example.com/", /\AFastImage::UnknownImageType\n\z/, [
1351
+ [:head, "http://example.com/"],
1352
+ [:get, "http://example.com/", {body: "<html></html>"}],
1353
+ ] ],
1354
+ [1, "http://example.com/404", /\ANetHTTPUtils::Error: HTTP error #404 \n\z/, [
1355
+ [:head, "http://example.com/404", {status: [404, "Not Found"]}],
1356
+ ] ],
1357
+
1358
+ # TODO: a test when the giveup=false fails and reraises the DirectLink::ErrorMissingEnvVar
1359
+ # maybe put it to ./lib tests
1360
+
1361
+ # by design it should be impossible to write a test for DirectLink::ErrorAssert
1362
+ [1, "https://flic.kr/p/DirectLinkErrorNotFound", /\ANetHTTPUtils::Error: HTTP error #404 \n\z/, [
1363
+ [:head, "https://flic.kr/p/DirectLinkErrorNotFound", {status: [302, "Found"], headers: {"Location"=>"https://www.flickr.com/photo.gne?short=DirectLinkErrorNotFound"}}],
1364
+ [:head, "https://www.flickr.com/photo.gne?short=DirectLinkErrorNotFound", {status: [302, "Found"], headers: {"Location"=>"/photo.gne?rb=1&short=DirectLinkErrorNotFound"}}],
1365
+ [:head, "https://www.flickr.com/photo.gne?rb=1&short=DirectLinkErrorNotFound", {status: [404, "Not Found"]}],
1366
+ ] ],
1367
+
1368
+ [1, "https://imgur.com/a/badlinkpattern", /\ANetHTTPUtils::Error: HTTP error #404 \n\z/, [
1369
+ [:head, "https://imgur.com/a/badlinkpattern", {status: [404, "Not Found"]}],
1370
+ ] ],
1371
+ # TODO: a test that it appends the `exception.cause`
1372
+ ].each do |expected_exit_code, input, expected_output, stubs|
1373
+ it "fails" do
1374
+ string, status = popen.call(input, stubs, true)
1375
+ assert_equal expected_exit_code, status.exitstatus, "for #{input}"
1376
+ assert string[expected_output], "for #{input}: string=#{string.inspect}"
1377
+ end
1378
+ end
1379
+
1380
+ valid_imgur_image_url1 = "https://goo.gl/ySqUb5"
1381
+ valid_imgur_image_url2 = "https://imgur.com/a/oacI3gl"
1382
+ stubs = [
1383
+ [:head, "https://goo.gl/ySqUb5", {status: [302, "Found"], headers: {"Location"=>"https://i.imgur.com/QpOBvRY.png"}}],
1384
+ [:head, "https://i.imgur.com/QpOBvRY.png"],
1385
+ [:head, "https://api.imgur.com/3/image/QpOBvRY/0.json"],
1386
+ [:get, "https://api.imgur.com/3/image/QpOBvRY/0.json", {body: <<~HEREDOC
1387
+ {
1388
+ "status" : 200,
1389
+ "success" : true,
1390
+ "data" : {
1391
+ "height" : 460,
1392
+ "link" : "https://i.imgur.com/QpOBvRY.png",
1393
+ "type" : "image/png",
1394
+ "width" : 460
1395
+ }
1396
+ }
1397
+ HEREDOC
1398
+ } ],
1399
+ [:head, "https://imgur.com/a/oacI3gl"],
1400
+ [:head, "https://api.imgur.com/3/album/oacI3gl/0.json"],
1401
+ [:get, "https://api.imgur.com/3/album/oacI3gl/0.json", {body: <<~HEREDOC
1402
+ {
1403
+ "status" : 200,
1404
+ "success" : true,
1405
+ "data" : {
1406
+ "id" : "oacI3gl",
1407
+ "link" : "https://imgur.com/a/oacI3gl",
1408
+ "images" : [
1409
+ {
1410
+ "height" : 100,
1411
+ "link" : "https://i.imgur.com/9j4KdkJ.png",
1412
+ "type" : "image/png",
1413
+ "width" : 100
1414
+ },
1415
+ {
1416
+ "height" : 460,
1417
+ "link" : "https://i.imgur.com/QpOBvRY.png",
1418
+ "type" : "image/png",
1419
+ "width" : 460
1420
+ }
1421
+ ]
1422
+ }
1423
+ }
1424
+ HEREDOC
1425
+ } ]
1426
+ ]
1427
+ [
1428
+ [stubs, <<~HEREDOC],
1429
+ <= #{valid_imgur_image_url1}
1430
+ => https://i.imgur.com/QpOBvRY.png
1431
+ image/png 460x460
1432
+ <= #{valid_imgur_image_url2}
1433
+ => https://i.imgur.com/QpOBvRY.png
1434
+ image/png 460x460
1435
+ => https://i.imgur.com/9j4KdkJ.png
1436
+ image/png 100x100
1437
+ HEREDOC
1438
+ [stubs, <<~HEREDOC, "json"]
1439
+ [
1440
+ {
1441
+ "url": "https://i.imgur.com/QpOBvRY.png",
1442
+ "width": 460,
1443
+ "height": 460,
1444
+ "type": "image/png"
1445
+ },
1446
+ [
1447
+ {
1448
+ "url": "https://i.imgur.com/QpOBvRY.png",
1449
+ "width": 460,
1450
+ "height": 460,
1451
+ "type": "image/png"
1452
+ },
1453
+ {
1454
+ "url": "https://i.imgur.com/9j4KdkJ.png",
1455
+ "width": 100,
1456
+ "height": 100,
1457
+ "type": "image/png"
1458
+ }
1459
+ ]
1460
+ ]
1461
+ HEREDOC
1462
+ ].each do |stubs, expected_output, param|
1463
+ it "#{param || "default"} output format" do
1464
+ string, status = popen.call("#{valid_imgur_image_url1} #{valid_imgur_image_url2}", stubs, true, param)
1465
+ assert_equal [0, expected_output], [status.exitstatus, string]
1466
+ end
1467
+ end
1468
+
1469
+ it "reddit_bot gem logger does not flood STDOUT" do
1470
+ string, status = popen.call("http://redd.it/123abc", [
1471
+ [:head, "http://redd.it/123abc", {status: [301, "Moved Permanently"], headers: {"Location"=>"https://redd.it/123abc"}}],
1472
+ [:head, "https://redd.it/123abc", {status: [302, "Temporarily Moved"], headers: {"Location"=>"https://www.reddit.com/comments/123abc"}}],
1473
+ [:head, "https://www.reddit.com/comments/123abc"],
1474
+ [:post, "https://www.reddit.com/api/v1/access_token", {body: {"access_token": "123456789268-NxVk35tst8DttE5uCSD8pPY00XeAXQ"}.to_json}],
1475
+ [:get, "https://oauth.reddit.com/by_id/t3_123abc?api_type=json", {body: <<~HEREDOC
1476
+ {
1477
+ "data" : {
1478
+ "children" : [
1479
+ {
1480
+ "data" : {
1481
+ "id" : "123abc",
1482
+ "is_self" : true,
1483
+ "media" : null,
1484
+ "name" : "t3_123abc",
1485
+ "permalink" : "/r/test___________/comments/123abc/for_the_httpsgithubcomnakilondirectlink_unit_tests/",
1486
+ "selftext" : "https://i.imgur.com/ABCabcd.jpg [test](https://goo.gl/ySqUb5)",
1487
+ "url" : "https://www.reddit.com/r/test___________/comments/123abc/for_the_httpsgithubcomnakilondirectlink_unit_tests/"
1488
+ }
1489
+ }
1490
+ ]
1491
+ }
1492
+ }
1493
+ HEREDOC
1494
+ } ],
1495
+ [:head, "https://goo.gl/ySqUb5", {status: [302, "Found"], headers: {"Location"=>"https://i.imgur.com/QpOBvRY.png"}}],
1496
+ [:head, "https://i.imgur.com/QpOBvRY.png"],
1497
+ [:head, "https://api.imgur.com/3/image/QpOBvRY/0.json"],
1498
+ [:get, "https://api.imgur.com/3/image/QpOBvRY/0.json", {body: <<~HEREDOC
1499
+ {
1500
+ "status" : 200,
1501
+ "success" : true,
1502
+ "data" : {
1503
+ "height" : 460,
1504
+ "width" : 460,
1505
+ "link" : "https://i.imgur.com/QpOBvRY.png",
1506
+ "type" : "image/png"
1507
+ }
1508
+ }
1509
+ HEREDOC
1510
+ } ],
1511
+ ] )
1512
+ assert_equal "<= http://redd.it/123abc\n=> https://i.imgur.com/QpOBvRY.png\n image/png 460x460\n", string
1513
+ end
1514
+
1515
+ # TODO: test about --json
1516
+ it "does not give up" do
1517
+ string, status = popen.call("https://www.kp.ru/daily/123/", [
1518
+ [:head, "https://www.kp.ru/daily/123/", {headers: {"Content-Type"=>"text/html"}}],
1519
+ [:get, "https://www.kp.ru/daily/123/", {body: <<~HEREDOC
1520
+ <!DOCTYPE html>
1521
+ <html xmlns="http://www.w3.org/1999/xhtml">
1522
+ <head>
1523
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1524
+ <link rel="icon" type="image/png" href="/favicon-16.png" sizes="16x16" />
1525
+ <link rel="icon" type="image/png" href="/favicon-32.png" sizes="32x32" />
1526
+ <link rel="icon" type="image/png" href="/favicon-96.png" sizes="96x96" />
1527
+ <link rel="icon" type="image/png" href="/favicon-128.png" sizes="128x128" />
1528
+ <meta data-react-helmet="true" property="og:image" content="https://s11.stc.all.kpcdn.net/share/20.jpg" />
1529
+ <meta data-react-helmet="true" name="twitter:image:src" content="https://s11.stc.all.kpcdn.net/share/20.jpg" />
1530
+ <link data-react-helmet="true" rel="image_src" href="https://s11.stc.all.kpcdn.net/share/20.jpg" />
1531
+ </head>
1532
+ <body>
1533
+ <div id="app">
1534
+ <div>
1535
+ <a href="/daily/author/1234">
1536
+ <img alt="Александра" src="https://s14.stc.all.kpcdn.net/share/i/3/1234567/avatar.jpg" data-show-on-desktop="false" data-show-on-mobile="false" />
1537
+ Ы
1538
+ </a>
1539
+ </div>
1540
+ </div>
1541
+ </body>
1542
+ </html>
1543
+ HEREDOC
1544
+ } ],
1545
+ [:head, "https://s11.stc.all.kpcdn.net/share/20.jpg"],
1546
+ [:get, "https://s11.stc.all.kpcdn.net/share/20.jpg", {body: "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC9\x00\v\b\x00\x01\x00\x01\x01\x01\x11\x00\xFF\xCC\x00\x06\x00\x10\x10\x05\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xD2\xCF \xFF\xD9"}],
1547
+ ], false, "json")
1548
+ assert_equal [0, "https://s11.stc.all.kpcdn.net/share/20.jpg"], [status.exitstatus, JSON.load(string).fetch("url")]
1549
+ end
1550
+
1551
+ end
1552
+
1553
+ end