Class: Flunk

Inherits:
ActionDispatch::IntegrationTest
  • Object
show all
Defined in:
lib/flunk.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.configObject

global



238
239
240
# File 'lib/flunk.rb', line 238

def self.config
  @@config ||= self.new "FlunkConfig"
end

.flunk(resource, action, failure_reason, &block) ⇒ Object



24
25
26
27
# File 'lib/flunk.rb', line 24

def self.flunk(resource, action, failure_reason, &block)
  name = "Flunked #{resource}: #{action} (#{failure_reason})"
  test(resource, { action: action, name: name }, &block)
end

.test(resource, action, &block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/flunk.rb', line 5

def self.test(resource, action, &block)

  if action.class == Hash
    name          = action[:name]
    action        = action[:action]
  end

  new_proc = Proc.new do
    @resource ||= resource
    @action   ||= action
    instance_eval(&block)
    result
    instance_eval(&@after) unless @after.nil?
  end

  name = resource + ": " + action if name.nil?
  super name, &new_proc
end

Instance Method Details

#after(&block) ⇒ Object



230
231
232
# File 'lib/flunk.rb', line 230

def after(&block)
  @after = block
end

#auth_token(auth_token) ⇒ Object



141
142
143
# File 'lib/flunk.rb', line 141

def auth_token(auth_token)
  @auth_token = auth_token
end

#base_url(base_url) ⇒ Object



98
99
100
# File 'lib/flunk.rb', line 98

def base_url(base_url)
  @base_url
end

#before(&block) ⇒ Object

before/after blocks



225
226
227
228
# File 'lib/flunk.rb', line 225

def before(&block)
  @before = block
  instance_eval(&@before)
end

#body(body) ⇒ Object



157
158
159
# File 'lib/flunk.rb', line 157

def body(body)
  @body = body
end

#desc(desc) ⇒ Object



90
91
92
# File 'lib/flunk.rb', line 90

def desc(desc)
  @desc = desc
end

#doc_base_url(doc_base_url) ⇒ Object



208
209
210
# File 'lib/flunk.rb', line 208

def doc_base_url(doc_base_url)
  @doc_base_url = doc_base_url
end

#doc_directory(doc_directory) ⇒ Object



192
193
194
195
196
# File 'lib/flunk.rb', line 192

def doc_directory(doc_directory)
  FileUtils.rm_r(doc_directory) if File.exists?(doc_directory)
  FileUtils.mkdir_p(doc_directory)
  @doc_directory = doc_directory
end

#header(key, value) ⇒ Object



173
174
175
176
177
# File 'lib/flunk.rb', line 173

def header(key, value)
  @headers ||= {}
  @headers = self.class.config.read_headers.merge @headers if self.class.config.read_headers
  @headers[key] = value
end

#make_custom_doc(resource, action, desc, custom_attributes) ⇒ Object

custom attributes must follow this form: customer_attributes =

key:
  kind: [text | code]
  content: [text]


327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/flunk.rb', line 327

def make_custom_doc resource, action, desc, custom_attributes
  contents = ""
  contents += "# #{action.humanize}\n\n"
  contents += "#{desc.humanize}\n\n"

  custom_attributes.each do |key, value|
    if value[:kind] == :text
      contents += "- **#{key.to_s.humanize}:** #{value[:content]}\n"
    elsif value[:kind] == :code
      contents += "- **#{key.to_s.humanize}:**\n\n```\n#{value[:content]}\n```\n\n"
    end
  end

  save_doc resource, action, contents
end

#make_doc(resource, action, desc, path, method, auth_token, headers, body, status, response) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/flunk.rb', line 256

def make_doc resource, action, desc, path, method, auth_token, headers, body, status, response
  body = body.class == String ? JSON.parse(body) : body
  url = File.join(@@config.read_base_url.to_s, path.to_s)

  headers ||= {}
  headers["Content-Type"] = "application/json"
  headers["Accept"]       = "application/json"

  contents = ""

  contents += "# #{action.humanize}\n\n"

  contents += "#{desc.humanize}\n\n"

  contents += "## Request\n\n"

  if not auth_token.nil?
    contents += "- **Requires Authentication**\n"
  end

  contents += "- **Method:** #{method.to_s.upcase}\n"

  # if not headers.nil?
  #   headers_strings = headers.map {|k,v| "  - #{k}: #{v}" }
  #   contents += "- **Headers:**\n#{headers_strings.join("\n")}\n"
  # end

  contents += "- **URL:** #{url}\n"

  if not body.nil?
    contents += "- **Body:**\n\n```json\n#{pretty(body)}\n```\n\n"
  else
    contents += "\n"
  end

  contents += "## Response\n\n"

  contents += "- **Status:** #{Rack::Utils::SYMBOL_TO_STATUS_CODE[status]} #{status.to_s.humanize}\n"

  if not response.nil?
    contents += "- **Body:**\n\n```json\n#{pretty(response)}\n```\n\n"
  else
    contents += "\n"
  end

  contents += "## Example\n\n"

  contents +=
"```bash
curl -X #{method.to_s.upcase} \\\n"
  headers.to_h.each do |key, value|
    contents +=
"     -H \'#{key}: #{value}\' \\\n"
  end
  if not body.nil?
    contents +=
"     -d '#{pretty(body).gsub /\n/, "\n         "}' \\\n"
  end
  contents +=
"     \"#{ URI::join(read_doc_base_url, url) }\"
```"

  save_doc resource, action, contents
end

#method(method) ⇒ Object



117
118
119
# File 'lib/flunk.rb', line 117

def method(method)
  @method = method
end

#param(key, value) ⇒ Object



183
184
185
186
# File 'lib/flunk.rb', line 183

def param(key, value)
  @params ||= {}
  @params[key] = value
end

#password(password) ⇒ Object



133
134
135
# File 'lib/flunk.rb', line 133

def password(password)
  @password = password
end

#path(path) ⇒ Object



106
107
108
109
110
111
# File 'lib/flunk.rb', line 106

def path(path)
  uri = URI.parse path
  uri.path = uri.path[0] == "/" ? uri.path : "/#{uri.path}"
  uri.path = uri.path[-5..-1] == ".json" ? uri.path : "#{uri.path}.json"
  @path = uri.to_s
end

#pretty(json) ⇒ Object



351
352
353
354
355
356
357
# File 'lib/flunk.rb', line 351

def pretty json
  begin
    pretty_json = JSON.pretty_generate(json)
  rescue => e
    pretty_json = json
  end
end

#read_auth_tokenObject



145
146
147
# File 'lib/flunk.rb', line 145

def read_auth_token
  @auth_token
end

#read_base_urlObject



102
103
104
# File 'lib/flunk.rb', line 102

def read_base_url
  @base_url
end

#read_bodyObject



161
162
163
# File 'lib/flunk.rb', line 161

def read_body
  @body
end

#read_config_doc_base_urlObject



212
213
214
# File 'lib/flunk.rb', line 212

def read_config_doc_base_url
  @doc_base_url
end

#read_config_doc_directoryObject



198
199
200
# File 'lib/flunk.rb', line 198

def read_config_doc_directory
  @doc_directory
end

#read_descObject



94
95
96
# File 'lib/flunk.rb', line 94

def read_desc
  @desc
end

#read_doc_base_urlObject



216
217
218
# File 'lib/flunk.rb', line 216

def read_doc_base_url
  self.class.config.read_config_doc_base_url || "http://www.example.com/"
end

#read_doc_directoryObject



202
203
204
205
206
# File 'lib/flunk.rb', line 202

def read_doc_directory
  @doc_directory = self.class.config.read_config_doc_directory || "docs/flunk"
  FileUtils.mkdir_p(@doc_directory) unless File.exists?(@doc_directory)
  @doc_directory
end

#read_headersObject



179
180
181
# File 'lib/flunk.rb', line 179

def read_headers
  @headers
end

#read_methodObject



121
122
123
# File 'lib/flunk.rb', line 121

def read_method
  @method
end

#read_paramsObject



188
189
190
# File 'lib/flunk.rb', line 188

def read_params
  @params
end

#read_passwordObject



137
138
139
# File 'lib/flunk.rb', line 137

def read_password
  @password
end

#read_pathObject



113
114
115
# File 'lib/flunk.rb', line 113

def read_path
  @path
end

#read_sslObject



153
154
155
# File 'lib/flunk.rb', line 153

def read_ssl
  @ssl
end

#read_statusObject



169
170
171
# File 'lib/flunk.rb', line 169

def read_status
  @status
end

#read_usernameObject



129
130
131
# File 'lib/flunk.rb', line 129

def read_username
  @username
end

#rec_symbolize(obj) ⇒ Object

helpers



246
247
248
249
250
251
252
253
254
# File 'lib/flunk.rb', line 246

def rec_symbolize(obj)
  if obj.class == Hash
    obj.symbolize_keys!
    obj.map {|k,v| rec_symbolize(v) }
  elsif obj.class == Array
    obj.map {|v| rec_symbolize(v) }
  end
  nil
end

#resultObject



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
# File 'lib/flunk.rb', line 30

def result
  if !@result_fetched
    @result_fetched = true

    @username   ||= self.class.config.read_username
    @password   ||= self.class.config.read_password
    @auth_token ||= self.class.config.read_auth_token
    @headers    ||= self.class.config.read_headers
    @method     ||= self.class.config.read_method
    @ssl        ||= self.class.config.read_ssl

    @headers ||= {}

    if @username || @password
      @headers["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64(@username.to_s + ":" + @password.to_s)}".strip
    elsif @auth_token
      @headers["HTTP_AUTHORIZATION"] = "Token token=\"#{@auth_token}\"".strip
    end

    send @method, @path, @body, @headers

    @response = response

    expected_status_code = Rack::Utils::SYMBOL_TO_STATUS_CODE[@status]

    if response.status == 422 and expected_status_code != 422
      puts "VALIDATION ERRORS:"
      puts JSON.pretty_generate(JSON.parse(response.body))
    end

    if response.status.to_i != expected_status_code
      puts "STATUS MISMATCH:"
      puts "path: #{@path}"
      puts "headers: #{@headers.to_json}"
      puts "body: #{@body}"
    end

    assert_response @status

    unless response.body.blank?
      @result = response.body
      if response.content_type == 'application/json'
        begin
          json = ActiveSupport::JSON.decode(response.body)
          rec_symbolize( json )
          @result = json
        rescue => e
        end
      end
    end

    if not @desc.nil?
      make_doc @resource, @action, @desc, @path, @method, @auth_token, @headers, @body, @status, @result
    end

  end

  @result
end

#save_doc(resource, action, contents) ⇒ Object



344
345
346
347
348
349
# File 'lib/flunk.rb', line 344

def save_doc resource, action, contents
  resource_directory = File.join( read_doc_directory, resource.pluralize.capitalize )
  FileUtils.mkdir_p(resource_directory) unless File.exists?( resource_directory )
  file_path = File.join( resource_directory, "#{action.capitalize}.md" )
  File.open(file_path, 'w') {|f| f.write(contents) }
end

#ssl(ssl) ⇒ Object



149
150
151
# File 'lib/flunk.rb', line 149

def ssl(ssl)
  @ssl = ssl
end

#status(status) ⇒ Object



165
166
167
# File 'lib/flunk.rb', line 165

def status(status)
  @status = status
end

#username(username) ⇒ Object



125
126
127
# File 'lib/flunk.rb', line 125

def username(username)
  @username = username
end