File: migrator_spec.rb

package info (click to toggle)
ruby-vcr 6.0.0%2Breally5.0.0-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,320 kB
  • sloc: ruby: 8,456; sh: 177; makefile: 7
file content (204 lines) | stat: -rw-r--r-- 5,508 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
require 'tmpdir'
require 'vcr/cassette/migrator'
require 'yaml'

describe VCR::Cassette::Migrator do
  let(:original_contents) { <<-EOF
---
- !ruby/struct:VCR::HTTPInteraction
  request: !ruby/struct:VCR::Request
    method: :get
    uri: http://example.com:80/foo
    body:
    headers:
  response: !ruby/struct:VCR::Response
    status: !ruby/struct:VCR::ResponseStatus
      code: 200
      message: OK
    headers:
      content-type:
      - text/html;charset=utf-8
      content-length:
      - "9"
    body: Hello foo
    http_version: "1.1"
- !ruby/struct:VCR::HTTPInteraction
  request: !ruby/struct:VCR::Request
    method: :get
    uri: http://localhost:7777/bar
    body:
    headers:
  response: !ruby/struct:VCR::Response
    status: !ruby/struct:VCR::ResponseStatus
      code: 200
      message: OK
    headers:
      content-type:
      - text/html;charset=utf-8
      content-length:
      - "9"
    body: Hello bar
    http_version: "1.1"
EOF
  }

  let(:updated_contents) { <<-EOF
---
http_interactions:
- request:
    method: get
    uri: http://example.com/foo
    body:
      encoding: US-ASCII
      string: ""
    headers: {}

  response:
    status:
      code: 200
      message: OK
    headers:
      Content-Type:
      - text/html;charset=utf-8
      Content-Length:
      - "9"
    body:
      encoding: UTF-8
      string: Hello foo
    http_version: "1.1"
  recorded_at: Wed, 04 May 2011 12:30:00 GMT
- request:
    method: get
    uri: http://localhost:7777/bar
    body:
      encoding: US-ASCII
      string: ""
    headers: {}

  response:
    status:
      code: 200
      message: OK
    headers:
      Content-Type:
      - text/html;charset=utf-8
      Content-Length:
      - "9"
    body:
      encoding: UTF-8
      string: Hello bar
    http_version: "1.1"
  recorded_at: Wed, 04 May 2011 12:30:00 GMT
recorded_with: VCR #{VCR.version}
EOF
  }

  let(:dir) { './tmp/migrator' }

  before(:each) do
    # ensure the directory is empty
    FileUtils.rm_rf dir
    FileUtils.mkdir_p dir
  end

  before(:each) do
    # the encoding won't be set on rubies that don't support it
    updated_contents.gsub!(/^\s+encoding:.*$/, '')
  end unless ''.respond_to?(:encoding)

  # JRuby serializes YAML with some slightly different whitespace.
  before(:each) do
    [original_contents, updated_contents].each do |contents|
      contents.gsub!(/^(\s+)-/, '\1  -')
    end
    updated_contents.gsub!(/^(- |  )/, '  \1')
  end if RUBY_PLATFORM == 'java'

  # Use syck on all rubies for consistent results...
  around(:each) do |example|
    YAML::ENGINE.yamler = 'syck'
    begin
      example.call
    ensure
      YAML::ENGINE.yamler = 'psych'
    end
  end if defined?(YAML::ENGINE) && RUBY_VERSION.to_f < 2.0

  let(:filemtime) { Time.utc(2011, 5, 4, 12, 30) }
  let(:out_io)    { StringIO.new }
  let(:file_name) { File.join(dir, "example.yml") }
  let(:output)    { out_io.rewind; out_io.read }

  subject { described_class.new(dir, out_io) }

  before(:each) do
    allow(File).to receive(:mtime).with(file_name).and_return(filemtime)
  end

  def load_file(file_name)
    if ::YAML.respond_to?(:unsafe_load_file)
      ::YAML.unsafe_load_file(file_name)
    else
      ::YAML.load_file(file_name)
    end
  end

  it 'migrates a cassette from the 1.x to 2.x format' do
    File.open(file_name, 'w') { |f| f.write(original_contents) }
    subject.migrate!
    expect(load_file(file_name)).to eq(YAML.load(updated_contents))
    expect(output).to match(/Migrated example.yml/)
  end

  it 'ignores files that do not contain arrays' do
    File.open(file_name, 'w') { |f| f.write(true.to_yaml) }
    subject.migrate!
    expect(File.read(file_name)).to eq(true.to_yaml)
    expect(output).to match(/Ignored example.yml since it does not appear to be a valid VCR 1.x cassette/)
  end

  it 'ignores files that contain YAML arrays of other things' do
    File.open(file_name, 'w') { |f| f.write([{}, {}].to_yaml) }
    subject.migrate!
    expect(File.read(file_name)).to eq([{}, {}].to_yaml)
    expect(output).to match(/Ignored example.yml since it does not appear to be a valid VCR 1.x cassette/)
  end

  it 'ignores URIs that have sensitive data substitutions' do
    modified_contents = original_contents.gsub('example.com', '<HOST>')
    File.open(file_name, 'w') { |f| f.write(modified_contents) }
    subject.migrate!
    expect(load_file(file_name)).to eq(YAML.load(updated_contents.gsub('example.com', '<HOST>:80')))
  end

  it 'ignores files that are empty' do
    File.open(file_name, 'w') { |f| f.write('') }
    subject.migrate!
    expect(File.read(file_name)).to eq('')
    expect(output).to match(/Ignored example.yml since it could not be parsed as YAML/)
  end

  shared_examples_for "ignoring invalid YAML" do
    it 'ignores files that cannot be parsed as valid YAML (such as ERB cassettes)' do
      modified_contents = original_contents.gsub(/\A---/, "---\n<% 3.times do %>")
      modified_contents = modified_contents.gsub(/\z/, "<% end %>")
      File.open(file_name, 'w') { |f| f.write(modified_contents) }
      subject.migrate!
      expect(File.read(file_name)).to eq(modified_contents)
      expect(output).to match(/Ignored example.yml since it could not be parsed as YAML/)
    end
  end

  context 'with syck' do
    it_behaves_like "ignoring invalid YAML"
  end

  context 'with psych' do
    before(:each) do
      YAML::ENGINE.yamler = 'psych'
    end

    it_behaves_like "ignoring invalid YAML"
  end if defined?(YAML::ENGINE)
end