directlink 0.0.9.1 → 0.0.11.1

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