module GdsApi::TestHelpers::PublishingApiV2

def assert_publishing_api(verb, url, attributes_or_matcher = nil, times = 1)

def assert_publishing_api(verb, url, attributes_or_matcher = nil, times = 1)
  if attributes_or_matcher.is_a?(Hash)
    matcher = request_json_matches(attributes_or_matcher)
  else
    matcher = attributes_or_matcher
  end
  if matcher
    assert_requested(verb, url, times: times, &matcher)
  else
    assert_requested(verb, url, times: times)
  end
end

def assert_publishing_api_discard_draft(content_id, attributes_or_matcher = nil, times = 1)

def assert_publishing_api_discard_draft(content_id, attributes_or_matcher = nil, times = 1)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/#{content_id}/discard-draft"
  assert_publishing_api(:post, url, attributes_or_matcher, times)
end

def assert_publishing_api_patch_links(content_id, attributes_or_matcher = nil, times = 1)

def assert_publishing_api_patch_links(content_id, attributes_or_matcher = nil, times = 1)
  url = PUBLISHING_API_V2_ENDPOINT + "/links/" + content_id
  assert_publishing_api(:patch, url, attributes_or_matcher, times)
end

def assert_publishing_api_publish(content_id, attributes_or_matcher = nil, times = 1)

def assert_publishing_api_publish(content_id, attributes_or_matcher = nil, times = 1)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/#{content_id}/publish"
  assert_publishing_api(:post, url, attributes_or_matcher, times)
end

def assert_publishing_api_put_content(content_id, attributes_or_matcher = nil, times = 1)

def assert_publishing_api_put_content(content_id, attributes_or_matcher = nil, times = 1)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/" + content_id
  assert_publishing_api(:put, url, attributes_or_matcher, times)
end

def assert_publishing_api_put_content_links_and_publish(body, content_id = nil, publish_body = nil)

def assert_publishing_api_put_content_links_and_publish(body, content_id = nil, publish_body = nil)
  content_id ||= body[:content_id]
  if publish_body.nil?
    publish_body = { update_type: body.fetch(:update_type) }
    publish_body[:locale] = body[:locale] if body[:locale]
  end
  assert_publishing_api_put_content(content_id, body.except(:links))
  assert_publishing_api_patch_links(content_id, body.slice(:links)) unless body.slice(:links).empty?
  assert_publishing_api_publish(content_id, publish_body)
end

def assert_publishing_api_unpublish(content_id, attributes_or_matcher = nil, times = 1)

def assert_publishing_api_unpublish(content_id, attributes_or_matcher = nil, times = 1)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/#{content_id}/unpublish"
  assert_publishing_api(:post, url, attributes_or_matcher, times)
end

def deep_stringify_keys(hash)

def deep_stringify_keys(hash)
  deep_transform_keys(hash) { |key| key.to_s }
end

def deep_transform_keys(object, &block)

def deep_transform_keys(object, &block)
  case object
  when Hash
    object.each_with_object({}) do |(key, value), result|
      result[yield(key)] = deep_transform_keys(value, &block)
    end
  when Array
    object.map{ |item| deep_transform_keys(item, &block) }
  else
    object
  end
end

def publishing_api_does_not_have_item(content_id)

def publishing_api_does_not_have_item(content_id)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/" + content_id
  stub_request(:get, url).to_return(status: 404, body: resource_not_found(content_id, "content item").to_json, headers: {})
end

def publishing_api_does_not_have_links(content_id)

def publishing_api_does_not_have_links(content_id)
  url = PUBLISHING_API_V2_ENDPOINT + "/links/" + content_id
  stub_request(:get, url).to_return(status: 404, body: resource_not_found(content_id, "link set").to_json, headers: {})
end

def publishing_api_has_content(items, params = {})

)
per_page: 50
page: 1,
fields: fields, #example: let(:fields) { %i[base_path content_id public_updated_at title publication_state] }
document_type: described_class.publishing_api_document_type, #example of a document_type: "vehicle_recalls_and_faults_alert"
vehicle_recalls_and_faults, # this is a variable containing an array of content items
publishing_api_has_content(
def publishing_api_has_content(items, params = {})
  url = PUBLISHING_API_V2_ENDPOINT + "/content"
  if params.respond_to? :fetch
    per_page = params.fetch(:per_page, 50)
    page = params.fetch(:page, 1)
  else
    per_page = 50
    page = 1
  end
  start_position = (page-1) * per_page
  page_items = items.slice(start_position, per_page) || []
  number_of_pages =
    if items.count < per_page
      1
    else
      (items.count / per_page.to_f).ceil
    end
  body = {
    results: page_items,
    total: items.count,
    pages: number_of_pages,
    current_page: page
  }
  stub_request(:get, url)
    .with(query: params)
    .to_return(status: 200, body: body.to_json, headers: {})
end

def publishing_api_has_expanded_links(links)

Parameters:
  • links (Hash) -- the structure of the links hash
def publishing_api_has_expanded_links(links)
  url = PUBLISHING_API_V2_ENDPOINT + "/expanded-links/" + links[:content_id]
  stub_request(:get, url).to_return(status: 200, body: links.to_json, headers: {})
end

def publishing_api_has_fields_for_document(format, items, fields)

publishing_api_has_content allows for flexible passing in of arguments, please use instead
This method has been refactored into publishing_api_has_content (above)
def publishing_api_has_fields_for_document(format, items, fields)
  body = Array(items).map { |item|
    item.with_indifferent_access.slice(*fields)
  }
  query_params = fields.map { |f|
    "&fields%5B%5D=#{f}"
  }
  url = PUBLISHING_API_V2_ENDPOINT + "/content?document_type=#{format}#{query_params.join('')}"
  stub_request(:get, url).to_return(:status => 200, :body => { results: body }.to_json, :headers => {})
end

def publishing_api_has_item(item)

def publishing_api_has_item(item)
  item = item.with_indifferent_access
  url = PUBLISHING_API_V2_ENDPOINT + "/content/" + item[:content_id]
  stub_request(:get, url).to_return(status: 200, body: item.to_json, headers: {})
end

def publishing_api_has_item_in_sequence(content_id, items)

def publishing_api_has_item_in_sequence(content_id, items)
  items = items.map(&:with_indifferent_access)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/" + content_id
  calls = -1
  stub_request(:get, url).to_return do |request|
    calls += 1
    item = items[calls] || items.last
    { status: 200, body: item.to_json, headers: {} }
  end
end

def publishing_api_has_linkables(linkables, document_type:)

def publishing_api_has_linkables(linkables, document_type:)
  url = PUBLISHING_API_V2_ENDPOINT + "/linkables?document_type=#{document_type}"
  stub_request(:get, url).to_return(:status => 200, :body => linkables.to_json, :headers => {})
end

def publishing_api_has_linked_items(items, params = {})

Parameters:
  • params (Hash) -- A hash of parameters
  • items (Array) -- The linked items we wish to return
def publishing_api_has_linked_items(items, params = {})
  content_id = params.fetch(:content_id)
  link_type = params.fetch(:link_type)
  fields = params.fetch(:fields, %w(base_path content_id document_type title))
  url = Plek.current.find('publishing-api') + "/v2/linked/#{content_id}"
  request_parmeters = {
    "fields" => fields,
    "link_type" => link_type,
  }
  stub_request(:get, url)
    .with(query: request_parmeters)
    .and_return(
      body: items.to_json,
      status: 200
    )
end

def publishing_api_has_links(links)

Parameters:
  • links (Hash) -- the structure of the links hash
def publishing_api_has_links(links)
  links = links.with_indifferent_access
  url = PUBLISHING_API_V2_ENDPOINT + "/links/" + links[:content_id]
  stub_request(:get, url).to_return(status: 200, body: links.to_json, headers: {})
end

def publishing_api_has_lookups(lookup_hash)

Parameters:
  • lookup_hash (Hash) -- Hash with base_path as key, content_id as value.
def publishing_api_has_lookups(lookup_hash)
  url = Plek.current.find('publishing-api') + '/lookup-by-base-path'
  stub_request(:post, url).to_return(body: lookup_hash.to_json)
end

def publishing_api_isnt_available

def publishing_api_isnt_available
  stub_request(:any, /#{PUBLISHING_API_V2_ENDPOINT}\/.*/).to_return(status: 503)
end

def request_json_includes(required_attributes)

def request_json_includes(required_attributes)
  ->(request) do
    data = JSON.parse(request.body)
    deep_stringify_keys(required_attributes).
      to_a.all? { |key, value| data[key] == value }
  end
end

def request_json_matches(required_attributes)

def request_json_matches(required_attributes)
  ->(request) do
    data = JSON.parse(request.body)
    deep_stringify_keys(required_attributes) == data
  end
end

def resource_not_found(content_id, type)

def resource_not_found(content_id, type)
  {
    error: {
      code: 404,
      message: "Could not find #{type} with content_id: #{content_id}",
    }
  }
end

def stub_any_publishing_api_call

def stub_any_publishing_api_call
  stub_request(:any, %r{\A#{PUBLISHING_API_V2_ENDPOINT}})
end

def stub_any_publishing_api_call_to_return_not_found

def stub_any_publishing_api_call_to_return_not_found
  stub_request(:any, %r{\A#{PUBLISHING_API_V2_ENDPOINT}})
    .to_return(status: 404, headers: {"Content-Type" => "application/json; charset=utf-8"})
end

def stub_any_publishing_api_discard_draft

def stub_any_publishing_api_discard_draft
  stub_request(:post, %r{\A#{PUBLISHING_API_V2_ENDPOINT}/content/.*/discard-draft})
end

def stub_any_publishing_api_patch_links

def stub_any_publishing_api_patch_links
  stub_request(:patch, %r{\A#{PUBLISHING_API_V2_ENDPOINT}/links/})
end

def stub_any_publishing_api_publish

def stub_any_publishing_api_publish
  stub_request(:post, %r{\A#{PUBLISHING_API_V2_ENDPOINT}/content/.*/publish})
end

def stub_any_publishing_api_put_content

def stub_any_publishing_api_put_content
  stub_request(:put, %r{\A#{PUBLISHING_API_V2_ENDPOINT}/content/})
end

def stub_any_publishing_api_unpublish

def stub_any_publishing_api_unpublish
  stub_request(:post, %r{\A#{PUBLISHING_API_V2_ENDPOINT}/content/.*/unpublish})
end

def stub_publishing_api_discard_draft(content_id)

def stub_publishing_api_discard_draft(content_id)
  url = PUBLISHING_API_V2_ENDPOINT + "/content/#{content_id}/discard-draft"
  stub_request(:post, url).to_return(status: 200, headers: {"Content-Type" => "application/json; charset=utf-8"})
end

def stub_publishing_api_patch(*args)

def stub_publishing_api_patch(*args)
  stub_publishing_api_postlike_call(:patch, *args)
end

def stub_publishing_api_patch_links(content_id, body)

def stub_publishing_api_patch_links(content_id, body)
  stub_publishing_api_patch(content_id, body, '/links')
end

def stub_publishing_api_postlike_call(method, content_id, body, resource_path, override_response_hash = {})

def stub_publishing_api_postlike_call(method, content_id, body, resource_path, override_response_hash = {})
  response_hash = {status: 200, body: '{}', headers: {"Content-Type" => "application/json; charset=utf-8"}}
  response_hash.merge!(override_response_hash)
  response_hash[:body] = response_hash[:body].to_json if response_hash[:body].is_a?(Hash)
  url = PUBLISHING_API_V2_ENDPOINT + resource_path + "/" + content_id
  stub_request(method, url).with(body: body).to_return(response_hash)
end

def stub_publishing_api_publish(content_id, body, response_hash = {})

def stub_publishing_api_publish(content_id, body, response_hash = {})
  url = PUBLISHING_API_V2_ENDPOINT + "/content/#{content_id}/publish"
  response = {
    status: 200,
    body: '{}',
    headers: {"Content-Type" => "application/json; charset=utf-8"}
  }.merge(response_hash)
  stub_request(:post, url).with(body: body).to_return(response)
end

def stub_publishing_api_put(*args)

def stub_publishing_api_put(*args)
  stub_publishing_api_postlike_call(:put, *args)
end

def stub_publishing_api_put_content(content_id, body, response_hash = {})


* stub_publishing_api_put_content(my_content_id, my_request_body, { status: 201, body: {version: 33} })
* stub_publishing_api_put_content(my_content_id, my_request_body, { status: 201, body: {version: 33}.to_json })

e.g. The following two examples are equivalent:

if the given parameter for the response body is a Hash, it will be converted to JSON.
if a response is given, then it will be merged with the default response.

{status: 200, body: '{}', headers: {"Content-Type" => "application/json; charset=utf-8"}}
if no response_hash is given, a default response as follows is created:
stubs a PUT /v2/content/:content_id request with the given content id and request body.
def stub_publishing_api_put_content(content_id, body, response_hash = {})
  stub_publishing_api_put(content_id, body, '/content', response_hash)
end

def stub_publishing_api_put_content_links_and_publish(body, content_id = nil, publish_body = nil)

def stub_publishing_api_put_content_links_and_publish(body, content_id = nil, publish_body = nil)
  content_id ||= body[:content_id]
  if publish_body.nil?
    publish_body = { update_type: body.fetch(:update_type) }
    publish_body[:locale] = body[:locale] if body[:locale]
  end
  stubs = []
  stubs << stub_publishing_api_put_content(content_id, body.except(:links))
  stubs << stub_publishing_api_patch_links(content_id, body.slice(:links)) unless body.slice(:links).empty?
  stubs << stub_publishing_api_publish(content_id, publish_body)
  stubs
end

def stub_publishing_api_unpublish(content_id, params, response_hash = {})

def stub_publishing_api_unpublish(content_id, params, response_hash = {})
  url = PUBLISHING_API_V2_ENDPOINT + "/content/#{content_id}/unpublish"
  response = {
    status: 200,
    body: '{}',
    headers: {"Content-Type" => "application/json; charset=utf-8"}
  }.merge(response_hash)
  stub_request(:post, url).with(params).to_return(response)
end