rmega 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/TODO.md +3 -5
- data/bin/rmega-dl +47 -0
- data/bin/rmega-up +31 -0
- data/lib/rmega.rb +35 -3
- data/lib/rmega/api_response.rb +80 -0
- data/lib/rmega/cli.rb +121 -0
- data/lib/rmega/crypto.rb +20 -0
- data/lib/rmega/crypto/aes_cbc.rb +46 -0
- data/lib/rmega/crypto/aes_ctr.rb +15 -84
- data/lib/rmega/crypto/aes_ecb.rb +25 -0
- data/lib/rmega/crypto/rsa.rb +21 -12
- data/lib/rmega/errors.rb +3 -51
- data/lib/rmega/loggable.rb +0 -3
- data/lib/rmega/net.rb +56 -0
- data/lib/rmega/nodes/deletable.rb +0 -3
- data/lib/rmega/nodes/downloadable.rb +73 -30
- data/lib/rmega/nodes/expandable.rb +14 -10
- data/lib/rmega/nodes/factory.rb +30 -17
- data/lib/rmega/nodes/file.rb +0 -4
- data/lib/rmega/nodes/folder.rb +4 -14
- data/lib/rmega/nodes/inbox.rb +0 -2
- data/lib/rmega/nodes/node.rb +48 -25
- data/lib/rmega/nodes/node_key.rb +44 -0
- data/lib/rmega/nodes/root.rb +0 -4
- data/lib/rmega/nodes/trash.rb +0 -3
- data/lib/rmega/nodes/uploadable.rb +42 -33
- data/lib/rmega/not_inspectable.rb +10 -0
- data/lib/rmega/options.rb +22 -5
- data/lib/rmega/pool.rb +18 -7
- data/lib/rmega/progress.rb +53 -13
- data/lib/rmega/session.rb +125 -52
- data/lib/rmega/storage.rb +25 -21
- data/lib/rmega/utils.rb +23 -183
- data/lib/rmega/version.rb +2 -1
- data/rmega.gemspec +3 -5
- data/spec/integration/file_download_spec.rb +14 -32
- data/spec/integration/file_integrity_spec.rb +41 -0
- data/spec/integration/file_upload_spec.rb +11 -57
- data/spec/integration/folder_download_spec.rb +17 -0
- data/spec/integration/folder_operations_spec.rb +30 -30
- data/spec/integration/login_spec.rb +3 -3
- data/spec/integration/resume_download_spec.rb +53 -0
- data/spec/integration_spec_helper.rb +9 -4
- data/spec/rmega/lib/cli_spec.rb +12 -0
- data/spec/rmega/lib/session_spec.rb +31 -0
- data/spec/rmega/lib/storage_spec.rb +27 -0
- data/spec/rmega/lib/utils_spec.rb +16 -78
- data/spec/spec_helper.rb +1 -4
- metadata +30 -40
- data/lib/rmega/crypto/aes.rb +0 -35
- data/lib/rmega/crypto/crypto.rb +0 -107
- data/lib/rmega/crypto/rsa_mega.js +0 -455
- data/spec/rmega/lib/crypto/aes_spec.rb +0 -12
- data/spec/rmega/lib/crypto/crypto_spec.rb +0 -27
    
        data/lib/rmega/utils.rb
    CHANGED
    
    | @@ -2,203 +2,43 @@ module Rmega | |
| 2 2 | 
             
              module Utils
         | 
| 3 3 | 
             
                extend self
         | 
| 4 4 |  | 
| 5 | 
            -
                def str_to_a32(string)
         | 
| 6 | 
            -
                  size = (string.bytesize + 3) >> 2
         | 
| 7 | 
            -
                  string = string.ljust (string.bytesize + 3), "\x00"
         | 
| 8 | 
            -
                  string.unpack "l>#{size}"
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def a32_to_str(a32, len = nil)
         | 
| 12 | 
            -
                  if len
         | 
| 13 | 
            -
                    b = []
         | 
| 14 | 
            -
                    len.times do |i|
         | 
| 15 | 
            -
                      # TODO: should be ((a32[i>>2] >>> (24-(i & 3)*8)) & 255)
         | 
| 16 | 
            -
                      b << (((a32[i>>2] || 0) >> (24-(i & 3)*8)) & 255)
         | 
| 17 | 
            -
                    end
         | 
| 18 | 
            -
                    b.pack 'C*'
         | 
| 19 | 
            -
                  else
         | 
| 20 | 
            -
                    a32.pack 'l>*'
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
                end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                def b64a
         | 
| 25 | 
            -
                  @b64a ||= ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ["-", "_", "="]
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                def a32_to_base64(a32)
         | 
| 29 | 
            -
                  base64urlencode a32_to_str(a32)
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                def base64_to_a32(base64)
         | 
| 33 | 
            -
                  str_to_a32 base64urldecode(base64)
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 5 | 
             
                def base64urlencode(string)
         | 
| 37 | 
            -
                  i = 0
         | 
| 38 | 
            -
                  tmp_arr = []
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                  while i < string.size + 1
         | 
| 41 | 
            -
                    o1 = string[i].ord rescue 0
         | 
| 42 | 
            -
                    i += 1
         | 
| 43 | 
            -
                    o2 = string[i].ord rescue 0
         | 
| 44 | 
            -
                    i += 1
         | 
| 45 | 
            -
                    o3 = string[i].ord rescue 0
         | 
| 46 | 
            -
                    i += 1
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                    bits = o1 << 16 | o2 << 8 | o3
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                    h1 = bits >> 18 & 0x3f
         | 
| 51 | 
            -
                    h2 = bits >> 12 & 0x3f
         | 
| 52 | 
            -
                    h3 = bits >> 6 & 0x3f
         | 
| 53 | 
            -
                    h4 = bits & 0x3f
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                    tmp_arr.push b64a[h1] + b64a[h2] + b64a[h3] + b64a[h4]
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                  enc = tmp_arr.join ''
         | 
| 59 6 | 
             
                  r = string.size % 3
         | 
| 60 | 
            -
                   | 
| 7 | 
            +
                  encoded = Base64.urlsafe_encode64(string)
         | 
| 8 | 
            +
                  return (r != 0) ? encoded[0..r - 4] : encoded
         | 
| 61 9 | 
             
                end
         | 
| 62 10 |  | 
| 63 11 | 
             
                def base64urldecode(data)
         | 
| 64 | 
            -
                   | 
| 65 | 
            -
             | 
| 66 | 
            -
                  i = 0
         | 
| 67 | 
            -
                  ac = 0
         | 
| 68 | 
            -
                  dec = ""
         | 
| 69 | 
            -
                  tmp_arr = []
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                  return data unless data
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                  while i < data.size
         | 
| 74 | 
            -
                    h1 = b64a.index(data[i]) || -1
         | 
| 75 | 
            -
                    i += 1
         | 
| 76 | 
            -
                    h2 = b64a.index(data[i]) || -1
         | 
| 77 | 
            -
                    i += 1
         | 
| 78 | 
            -
                    h3 = b64a.index(data[i]) || -1
         | 
| 79 | 
            -
                    i += 1
         | 
| 80 | 
            -
                    h4 = b64a.index(data[i]) || -1
         | 
| 81 | 
            -
                    i += 1
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                    bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                    o1 = bits >> 16 & 0xff
         | 
| 86 | 
            -
                    o2 = bits >> 8 & 0xff
         | 
| 87 | 
            -
                    o3 = bits & 0xff
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                    if h3 == 64
         | 
| 90 | 
            -
                      tmp_arr[ac] = o1.chr
         | 
| 91 | 
            -
                    elsif h4 == 64
         | 
| 92 | 
            -
                      tmp_arr[ac] = o1.chr + o2.chr
         | 
| 93 | 
            -
                    else
         | 
| 94 | 
            -
                      tmp_arr[ac] = o1.chr + o2.chr + o3.chr
         | 
| 95 | 
            -
                    end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                    ac += 1
         | 
| 98 | 
            -
                  end
         | 
| 99 | 
            -
             | 
| 100 | 
            -
                  tmp_arr.join ''
         | 
| 12 | 
            +
                  fix_for_decoding = '=='[((2-data.length*3)&3)..-1]
         | 
| 13 | 
            +
                  return Base64.urlsafe_decode64("#{data}#{fix_for_decoding}")
         | 
| 101 14 | 
             
                end
         | 
| 102 15 |  | 
| 103 | 
            -
                def  | 
| 104 | 
            -
                   | 
| 105 | 
            -
                   | 
| 106 | 
            -
                   | 
| 107 | 
            -
                  sb = 256
         | 
| 108 | 
            -
                  sn = s.size
         | 
| 109 | 
            -
                  bm = 268435455
         | 
| 110 | 
            -
                  c = nil
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                  return 0 if sn < 2
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                  len = (sn - 2) * 8
         | 
| 115 | 
            -
                  bits = s[0].ord * 256 + s[1].ord
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                  return 0 if bits > len or bits < len - 8
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                  len.times do |n|
         | 
| 120 | 
            -
                    sb = sb << 1
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                    if sb > 255
         | 
| 123 | 
            -
                      sb = 1
         | 
| 124 | 
            -
                      c = s[sn -= 1].ord
         | 
| 125 | 
            -
                    end
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                    if bn > bm
         | 
| 128 | 
            -
                      bn = 1
         | 
| 129 | 
            -
                      r[rn += 1] = 0
         | 
| 130 | 
            -
                    end
         | 
| 131 | 
            -
             | 
| 132 | 
            -
                    if (c & sb) and (c & sb != 0)
         | 
| 133 | 
            -
                      r[rn] = r[rn] ? (r[rn] | bn) : bn
         | 
| 134 | 
            -
                    end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                    bn = bn << 1
         | 
| 137 | 
            -
                  end
         | 
| 138 | 
            -
                  r
         | 
| 16 | 
            +
                def hexstr_to_bstr(h)
         | 
| 17 | 
            +
                  bstr = ''
         | 
| 18 | 
            +
                  (0..h.length-1).step(2) {|n| bstr << h[n,2].to_i(16).chr }
         | 
| 19 | 
            +
                  bstr
         | 
| 139 20 | 
             
                end
         | 
| 140 21 |  | 
| 141 | 
            -
                def  | 
| 142 | 
            -
                   | 
| 143 | 
            -
                  bm = 268435455
         | 
| 144 | 
            -
                  bn = 1; bc = 0; r = [0]; rb = 1; rn = 0
         | 
| 145 | 
            -
                  bits = b.length * bs
         | 
| 146 | 
            -
                  rr = ''
         | 
| 147 | 
            -
             | 
| 148 | 
            -
                  bits.times do |n|
         | 
| 149 | 
            -
                    if (b[bc] & bn) and (b[bc] & bn) != 0
         | 
| 150 | 
            -
                      r[rn] = r[rn] ? (r[rn] | rb) : rb
         | 
| 151 | 
            -
                    end
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                    rb = rb << 1
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                    if rb > 255
         | 
| 156 | 
            -
                      rb = 1
         | 
| 157 | 
            -
                      r[rn += 1] = 0
         | 
| 158 | 
            -
                    end
         | 
| 159 | 
            -
             | 
| 160 | 
            -
                    bn = bn << 1
         | 
| 161 | 
            -
             | 
| 162 | 
            -
                    if bn > bm
         | 
| 163 | 
            -
                      bn = 1
         | 
| 164 | 
            -
                      bc += 1
         | 
| 165 | 
            -
                    end
         | 
| 166 | 
            -
                  end
         | 
| 167 | 
            -
             | 
| 168 | 
            -
                  while rn >= 0 && r[rn] == 0
         | 
| 169 | 
            -
                    rn -= 1
         | 
| 170 | 
            -
                  end
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                  (rn + 1).times do |n|
         | 
| 173 | 
            -
                    rr = r[n].chr + rr
         | 
| 174 | 
            -
                  end
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                  rr
         | 
| 22 | 
            +
                def string_to_bignum(string)
         | 
| 23 | 
            +
                  string.bytes.inject { |a, b| (a << 8) + b }
         | 
| 177 24 | 
             
                end
         | 
| 178 25 |  | 
| 179 | 
            -
                def  | 
| 180 | 
            -
                   | 
| 181 | 
            -
                   | 
| 182 | 
            -
                   | 
| 183 | 
            -
             | 
| 26 | 
            +
                def base64_mpi_to_bn(s)
         | 
| 27 | 
            +
                  data = ::Rmega::Utils.base64urldecode(s)
         | 
| 28 | 
            +
                  len = ((data[0].ord * 256 + data[1].ord + 7) / 8) + 2
         | 
| 29 | 
            +
                  data[2,len+2].unpack('H*').first.to_i(16)
         | 
| 30 | 
            +
                end
         | 
| 184 31 |  | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
                    pp = p
         | 
| 188 | 
            -
                    p += list[p]
         | 
| 189 | 
            -
                    i += 1
         | 
| 190 | 
            -
                  end
         | 
| 32 | 
            +
                def compact_to_8_bytes(string)
         | 
| 33 | 
            +
                  raise("Invalid data length") if string.size != 16
         | 
| 191 34 |  | 
| 192 | 
            -
                   | 
| 193 | 
            -
                    list[p] = 0x100000
         | 
| 194 | 
            -
                    pp = p
         | 
| 195 | 
            -
                    p += list[p]
         | 
| 196 | 
            -
                  end
         | 
| 35 | 
            +
                  bytes = string.bytes.to_a
         | 
| 197 36 |  | 
| 198 | 
            -
                   | 
| 199 | 
            -
                     | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 37 | 
            +
                  return 8.times.inject([]) do |ary, i|
         | 
| 38 | 
            +
                    n = i < 4 ? 0 : 4
         | 
| 39 | 
            +
                    ary[i] = bytes[i+n] ^ bytes[i+n+4]
         | 
| 40 | 
            +
                    ary
         | 
| 41 | 
            +
                  end.map(&:chr).join
         | 
| 202 42 | 
             
                end
         | 
| 203 43 | 
             
              end
         | 
| 204 44 | 
             
            end
         | 
    
        data/lib/rmega/version.rb
    CHANGED
    
    
    
        data/rmega.gemspec
    CHANGED
    
    | @@ -2,11 +2,11 @@ | |
| 2 2 | 
             
            require File.expand_path('../lib/rmega/version', __FILE__)
         | 
| 3 3 |  | 
| 4 4 | 
             
            Gem::Specification.new do |gem|
         | 
| 5 | 
            -
              gem.authors       = [" | 
| 5 | 
            +
              gem.authors       = ["topac"]
         | 
| 6 6 | 
             
              gem.email         = ["dani.m.mobile@gmail.com"]
         | 
| 7 7 | 
             
              gem.description   = %q{mega.co.nz ruby api}
         | 
| 8 8 | 
             
              gem.summary       = %q{mega.co.nz ruby api}
         | 
| 9 | 
            -
              gem.homepage      =  | 
| 9 | 
            +
              gem.homepage      = Rmega::HOMEPAGE
         | 
| 10 10 |  | 
| 11 11 | 
             
              gem.files         = `git ls-files`.split($\)
         | 
| 12 12 | 
             
              gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
         | 
| @@ -21,7 +21,5 @@ Gem::Specification.new do |gem| | |
| 21 21 | 
             
              gem.add_development_dependency "rspec"
         | 
| 22 22 | 
             
              gem.add_development_dependency "rake"
         | 
| 23 23 |  | 
| 24 | 
            -
              gem.add_dependency " | 
| 25 | 
            -
              gem.add_dependency 'activesupport'
         | 
| 26 | 
            -
              gem.add_dependency "execjs"
         | 
| 24 | 
            +
              gem.add_dependency "activesupport"
         | 
| 27 25 | 
             
            end
         | 
| @@ -1,45 +1,27 @@ | |
| 1 1 | 
             
            require 'integration_spec_helper'
         | 
| 2 | 
            -
            require 'fileutils'
         | 
| 3 2 |  | 
| 4 3 | 
             
            describe 'File download' do
         | 
| 5 4 |  | 
| 6 | 
            -
               | 
| 5 | 
            +
              context 'given a public mega url (a small file)' do
         | 
| 7 6 |  | 
| 8 | 
            -
                let(: | 
| 7 | 
            +
                let(:url) { 'https://mega.co.nz/#!MAkg2Iab!bc9Y2U6d93IlRRKVYpcC9hLZjS4G278OPdH6nTFPDNQ' }
         | 
| 9 8 |  | 
| 10 | 
            -
                 | 
| 11 | 
            -
             | 
| 12 | 
            -
                   | 
| 13 | 
            -
                   | 
| 14 | 
            -
             | 
| 15 | 
            -
                  it 'downloads the related file' do
         | 
| 16 | 
            -
                    storage.download(url, temp_folder)
         | 
| 17 | 
            -
                    related_file = File.join(temp_folder, 'testfile.txt')
         | 
| 18 | 
            -
                    expect(File.read(related_file)).to eq "helloworld!\n"
         | 
| 19 | 
            -
                  end
         | 
| 9 | 
            +
                it 'downloads the related file' do
         | 
| 10 | 
            +
                  Rmega.download(url, temp_folder)
         | 
| 11 | 
            +
                  related_file = File.join(temp_folder, 'testfile.txt')
         | 
| 12 | 
            +
                  expect(File.read(related_file)).to eq "helloworld!\n"
         | 
| 20 13 | 
             
                end
         | 
| 14 | 
            +
              end
         | 
| 21 15 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                  # A file called testfile_big_15mb.txt containting the word "topac" repeated 3145728 times (~ 15mb)
         | 
| 25 | 
            -
                  let(:url) { 'https://mega.co.nz/#!NYVkDaLD!BKyN5SRpOaEtGnTcwiAqcxmJc7p-k0IPWKAW-471KRE' }
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                  it 'downloads the related file' do
         | 
| 28 | 
            -
                    storage.download(url, temp_folder)
         | 
| 29 | 
            -
                    related_file = File.join(temp_folder, 'testfile_big_15mb.txt')
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                    expect(File.size(related_file)).to eql 15_728_640
         | 
| 16 | 
            +
              context 'given a public mega url (a big file)' do
         | 
| 32 17 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
                    File.open(related_file, 'rb') do |f|
         | 
| 35 | 
            -
                      while (word = f.read(3840))
         | 
| 36 | 
            -
                        break if word != "topac"*768
         | 
| 37 | 
            -
                        count += 768
         | 
| 38 | 
            -
                      end
         | 
| 39 | 
            -
                    end
         | 
| 18 | 
            +
                let(:url) { 'https://mega.co.nz/#!NYVkDaLD!BKyN5SRpOaEtGnTcwiAqcxmJc7p-k0IPWKAW-471KRE' }
         | 
| 40 19 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
                   | 
| 20 | 
            +
                it 'downloads the related file' do
         | 
| 21 | 
            +
                  Rmega.download(url, temp_folder)
         | 
| 22 | 
            +
                  related_file = File.join(temp_folder, 'testfile_big_15mb.txt')
         | 
| 23 | 
            +
                  md5 = Digest::MD5.file(related_file).hexdigest
         | 
| 24 | 
            +
                  expect(md5).to eq("0451dc82ac003dbef703342e40a1b8f6")
         | 
| 43 25 | 
             
                end
         | 
| 44 26 | 
             
              end
         | 
| 45 27 | 
             
            end
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'integration_spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe 'File integrity over upload/download operations' do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              if account_file_exists?
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                before(:all) do
         | 
| 8 | 
            +
                  @storage = login
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                let(:name) { "test_file" }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                let(:path) { File.join(temp_folder, name)}
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                [12, 1_024_000].each do |size|
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  context "when a file (#{size} bytes) is uploaded and then downloaded" do
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    let(:content) { OpenSSL::Random.random_bytes(size) }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    let(:content_hash) { Digest::MD5.hexdigest(content) }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    before do
         | 
| 24 | 
            +
                      File.open(path, 'wb') { |f| f.write(content) }
         | 
| 25 | 
            +
                      file = @storage.root.upload(path)
         | 
| 26 | 
            +
                      @file = @storage.nodes.find { |n| n.handle == file.handle }
         | 
| 27 | 
            +
                      expect(@file.name).to eq(name)
         | 
| 28 | 
            +
                      @file.download(path+".downloaded")
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    it 'it does not get corrupted' do
         | 
| 32 | 
            +
                      expect(Digest::MD5.file(path+".downloaded").hexdigest).to eq(content_hash)
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    after do
         | 
| 36 | 
            +
                      @file.delete if @file
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            require 'integration_spec_helper'
         | 
| 2 | 
            -
            require 'fileutils'
         | 
| 3 2 |  | 
| 4 3 | 
             
            describe 'File upload' do
         | 
| 5 4 |  | 
| @@ -7,72 +6,27 @@ describe 'File upload' do | |
| 7 6 |  | 
| 8 7 | 
             
                before(:all) { @storage = login }
         | 
| 9 8 |  | 
| 10 | 
            -
                 | 
| 9 | 
            +
                let(:name) { "test_file" }
         | 
| 11 10 |  | 
| 12 | 
            -
             | 
| 13 | 
            -
                    @name = "i_like_trains_#{rand(1E20)}"
         | 
| 14 | 
            -
                    @content = @name
         | 
| 15 | 
            -
                  end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  def find_file
         | 
| 18 | 
            -
                    @storage.root.files.find { |f| f.name == @name }
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  let(:path) { File.join(temp_folder, @name) }
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                  before do
         | 
| 24 | 
            -
                    File.open(path, 'wb') { |f| f.write(@content) }
         | 
| 25 | 
            -
                    @storage.root.upload(path)
         | 
| 26 | 
            -
                  end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                  it 'finds the uploaded file' do
         | 
| 29 | 
            -
                    file = find_file
         | 
| 30 | 
            -
                    file.delete
         | 
| 31 | 
            -
                    expect(file).not_to be_nil
         | 
| 32 | 
            -
                  end
         | 
| 11 | 
            +
                let(:path) { File.join(temp_folder, name)}
         | 
| 33 12 |  | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
                    let(:download_path) { "#{path}.downloaded" }
         | 
| 13 | 
            +
                [12, 1_024_000].each do |size|
         | 
| 14 | 
            +
                  context "when a file (#{size} bytes) is uploaded" do
         | 
| 37 15 |  | 
| 38 16 | 
             
                    before do
         | 
| 39 | 
            -
                       | 
| 40 | 
            -
                      file. | 
| 41 | 
            -
                      file.delete
         | 
| 17 | 
            +
                      File.open(path, 'wb') { |f| f.write(OpenSSL::Random.random_bytes(size)) }
         | 
| 18 | 
            +
                      @file = @storage.root.upload(path)
         | 
| 42 19 | 
             
                    end
         | 
| 43 20 |  | 
| 44 | 
            -
                    it ' | 
| 45 | 
            -
                       | 
| 21 | 
            +
                    it 'it can be found as a file node' do
         | 
| 22 | 
            +
                      found_node = @storage.root.files.find { |f| f.handle == @file.handle }
         | 
| 23 | 
            +
                      expect(found_node).not_to be_nil
         | 
| 46 24 | 
             
                    end
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
                end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                context 'upload a big file to a specific folder' do
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  before(:all) do
         | 
| 53 | 
            -
                    @name = "mine_turtles_#{rand(1E20)}"
         | 
| 54 | 
            -
                    @path = File.join(temp_folder, @name)
         | 
| 55 | 
            -
                    @buffer = "rofl" * 1024
         | 
| 56 25 |  | 
| 57 | 
            -
                     | 
| 58 | 
            -
                       | 
| 26 | 
            +
                    after do
         | 
| 27 | 
            +
                      @file.delete if @file
         | 
| 59 28 | 
             
                    end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                    @folder = @storage.root.create_folder(@name)
         | 
| 62 | 
            -
                    @folder.upload(@path)
         | 
| 63 29 | 
             
                  end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  it 'finds the uploaded file and verify its content' do
         | 
| 66 | 
            -
                    file = @folder.files.find { |f| f.name == @name }
         | 
| 67 | 
            -
                    download_path = "#{@path}.downloaded"
         | 
| 68 | 
            -
                    file.download(download_path)
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                    File.open(download_path, 'rb') do |f|
         | 
| 71 | 
            -
                      512.times { expect(f.read(@buffer.size)).to eq(@buffer) }
         | 
| 72 | 
            -
                    end
         | 
| 73 | 
            -
                  end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  after { @folder.delete if @folder }
         | 
| 76 30 | 
             
                end
         | 
| 77 31 | 
             
              end
         | 
| 78 32 | 
             
            end
         |