Skip to content

Commit

Permalink
feat: add new label api (#703)
Browse files Browse the repository at this point in the history
* chore: wip/adding a new labels resource to list all labels

* chore: wip/added pagination to labels response and refactored the response

* chore: missed a file

* chore: updated the spec

* chore: updated the decorator and wrote a spec for repository

* chore: added labels decorator spec

* fix: rubocop failure

* fix: fixed the failing test

* fix: fixed the wrong syntax

* test: fixed another failing test

* chore: added test for service layer of Label service

* chore: added spacing

* chore: added spec for paginated response
  • Loading branch information
Saup21 authored Jul 3, 2024
1 parent 8cd9697 commit ff3f84e
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 14 deletions.
3 changes: 3 additions & 0 deletions lib/pact_broker/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ def self.build_api(application_context = PactBroker::ApplicationContext.default_
add ["pacticipants", :pacticipant_name], Api::Resources::Pacticipant, {resource_name: "pacticipant"}
add ["pacticipants", :pacticipant_name, "labels", :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"}

# Labels
add ["labels"], Api::Resources::Labels, {resource_name: "labels"}

# Versions
add ["pacticipants", :pacticipant_name, "versions"], Api::Resources::Versions, {resource_name: "pacticipant_versions"}
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions"], Api::Resources::BranchVersions, {resource_name: "pacticipant_branch_versions"}
Expand Down
32 changes: 19 additions & 13 deletions lib/pact_broker/api/decorators/label_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,26 @@ class LabelDecorator < BaseDecorator

include Timestamps

link :self do | options |
{
title: "Label",
name: represented.name,
href: label_url(represented, options[:base_url])
}
end
# This method is overridden to conditionally render the links based on the user_options
def to_hash(options)
hash = super

unless options.dig(:user_options, :hide_label_decorator_links)
hash[:_links] = {
self: {
title: "Label",
name: represented.name,
href: label_url(represented, options.dig(:user_options, :base_url))
},
pacticipant: {
title: "Pacticipant",
name: represented.pacticipant.name,
href: pacticipant_url(options.dig(:user_options, :base_url), represented.pacticipant)
}
}
end

link :pacticipant do | options |
{
title: "Pacticipant",
name: represented.pacticipant.name,
href: pacticipant_url(options.fetch(:base_url), represented.pacticipant)
}
hash
end
end
end
Expand Down
23 changes: 23 additions & 0 deletions lib/pact_broker/api/decorators/labels_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require_relative "base_decorator"
require_relative "pagination_links"
require_relative "label_decorator"
require "pact_broker/domain/label"

module PactBroker
module Api
module Decorators
class LabelsDecorator < BaseDecorator
collection :entries, :as => :labels, :class => PactBroker::Domain::Label, :extend => PactBroker::Api::Decorators::LabelDecorator, embedded: true

include PaginationLinks

link :self do | options |
{
title: "Labels",
href: options.fetch(:resource_url)
}
end
end
end
end
end
37 changes: 37 additions & 0 deletions lib/pact_broker/api/resources/labels.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require "pact_broker/api/resources/base_resource"
require "pact_broker/api/decorators/labels_decorator"
require "pact_broker/api/resources/pagination_methods"

module PactBroker
module Api
module Resources
class Labels < BaseResource
include PaginationMethods

def content_types_provided
[["application/hal+json", :to_json]]
end

def allowed_methods
["GET", "OPTIONS"]
end

def policy_name
:'labels::labels'
end

def to_json
decorator_class(:labels_decorator).new(labels).to_json(
**decorator_options(
hide_label_decorator_links: true,
)
)
end

def labels
label_service.get_all_unique_labels(pagination_options)
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/pact_broker/labels/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
module PactBroker
module Labels
class Repository

def get_all_unique_labels pagination_options = {}
PactBroker::Domain::Label.distinct.select(:name).all_with_pagination_options(pagination_options)
end

def create args
Domain::Label.new(name: args.fetch(:name), pacticipant: args.fetch(:pacticipant)).save
end
Expand Down
4 changes: 4 additions & 0 deletions lib/pact_broker/labels/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ module Service

extend PactBroker::Repositories

def get_all_unique_labels pagination_options = {}
label_repository.get_all_unique_labels(pagination_options)
end

def create args
pacticipant = pacticipant_repository.find_by_name_or_create args.fetch(:pacticipant_name)
label_repository.create pacticipant: pacticipant, name: args.fetch(:label_name)
Expand Down
36 changes: 36 additions & 0 deletions spec/features/get_labels_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
describe "Get labels" do

let(:path) { "/labels" }
let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) }

subject { get(path) }

context "when labels exists" do
before do
td.create_pacticipant("foo")
.create_label("ios")
.create_label("consumer")
.create_pacticipant("bar")
.create_label("ios")
.create_label("consumer")
end

it "returns a 200 OK" do
expect(subject).to be_a_hal_json_success_response
end

it "returns the labels in the body" do
expect(response_body_hash[:_embedded][:labels].map { |label| label[:name] }).to contain_exactly("ios", "consumer")
end

context "with pagination options" do
subject { get(path, { "size" => "1", "page" => "1" }) }

it "only returns the number of items specified in the page" do
expect(response_body_hash[:_embedded][:labels].size).to eq 1
end

it_behaves_like "a paginated response"
end
end
end
43 changes: 43 additions & 0 deletions spec/lib/pact_broker/api/decorators/labels_decorator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require "pact_broker/api/decorators/labels_decorator"
require "pact_broker/labels/service"

module PactBroker
module Api
module Decorators

describe LabelsDecorator do
before do
td.create_consumer("Foo")
.create_label("consumer")
.create_consumer("Bar")
.create_label("provider")
.create_consumer("Wiffle")
.create_label("provider")
end

let(:label) do
PactBroker::Labels::Service.get_all_unique_labels
end

let(:options) { { user_options: { resource_url: "http://example.org/labels", hide_label_decorator_links: true } } }
subject { JSON.parse LabelsDecorator.new(label).to_json(options), symbolize_names: true }

it "includes the label names" do
expect(subject[:_embedded][:labels].map { |label| label[:name] }).to contain_exactly("provider", "consumer")
end

it "includes the resource url" do
expect(subject[:_links][:self][:href]).to eq "http://example.org/labels"
end

it "labels field doest not include any links" do
expect(subject[:_embedded][:labels][0][:_links]).to be_nil
end

it "doest not include createdAt" do
expect(subject[:_embedded][:labels][0][:createdAt]).to be_nil
end
end
end
end
end
35 changes: 35 additions & 0 deletions spec/lib/pact_broker/labels/repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,41 @@ module PactBroker
module Labels
describe Repository do

describe ".get_all_unique_labels" do
before do
td.create_pacticipant("bar")
.create_label("ios")
.create_pacticipant("foo")
.create_label("android")
.create_pacticipant("wiffle")
.create_label("ios")
end

let(:labels_repository) { Repository.new }

context "when there are no pagination options" do
subject { labels_repository.get_all_unique_labels }

it "returns all the unique labels" do
expect(subject.collect(&:name)).to contain_exactly("ios", "android")
end
end

context "when there are pagination options" do
let(:pagination_options) do
{
:page_number => 1,
:page_size => 1
}
end
subject { labels_repository.get_all_unique_labels pagination_options }

it "returns paginated unique labels" do
expect(subject.collect(&:name)).to contain_exactly("ios")
end
end
end

describe ".find" do

let(:pacticipant_name) { "foo" }
Expand Down
12 changes: 11 additions & 1 deletion spec/lib/pact_broker/labels/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ module Labels
describe Service do
let(:pacticipant_name) { "foo" }
let(:label_name) { "ios" }
let(:options) { {pacticipant_name: pacticipant_name, label_name: label_name}}
let(:options) { { pacticipant_name: pacticipant_name, label_name: label_name } }
let(:pagination_options) { { page_number: 1, page_size: 1 } }

describe ".get_all_unique_labels" do
subject { Service.get_all_unique_labels(pagination_options) }

it "calls the labels repository" do
expect_any_instance_of(Labels::Repository).to receive(:get_all_unique_labels).with(pagination_options)
subject
end
end

describe ".create" do
subject { Service.create(options) }
Expand Down
1 change: 1 addition & 0 deletions spec/support/all_routes_spec_support.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ requests_which_are_exected_to_have_no_policy_record_or_pacticipant:
- environment DELETE
- integrations GET
- integrations DELETE
- labels GET
- matrix GET
- metrics GET
- pacticipants GET
Expand Down

0 comments on commit ff3f84e

Please sign in to comment.