Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Test Subscriptions controller #64

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions app/controllers/api/concerns/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ module Api::Concerns::Errors
# more context such as the `title` and `detail`.
rescue_from VersionCake::UnsupportedVersionError, with: :unsupported_version
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActiveRecord::RecordInvalid, with: :invalid_record
rescue_from ActionController::ParameterMissing, with: :bad_request
end

private
Expand All @@ -37,6 +39,20 @@ def not_found(error)
api_error ::Api::NotFoundError.new(detail:, backtrace: error.backtrace)
end

def invalid_record(error)
api_error ::Api::BadRequestError.new(
detail: error.record&.errors&.full_messages&.join(", "),
backtrace: error.backtrace
)
end

def bad_request(error)
api_error ::Api::BadRequestError.new(
detail: error.message,
backtrace: error.backtrace
)
end

def server_error(error)
Rails.logger.error(error.inspect)
raise error if Rails.env.development?
Expand Down
13 changes: 13 additions & 0 deletions app/controllers/api/subscriptions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Api::SubscriptionsController < ApiController
def create
ActiveRecord::Base.transaction do
user = User.find_or_create_by!(email_address: params.require(:email))
@subscription = Hackathon::Subscription.create!(
location_input: params.require(:location),
subscriber: user
)
end

render partial: "api/subscriptions/subscription", locals: {subscription: @subscription}
end
end
4 changes: 4 additions & 0 deletions app/controllers/api_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
class ApiController < ActionController::Base
# Don't check CSRF token for API routes
skip_before_action :verify_authenticity_token

# Pagination
include Pagy::Backend
helper_method :pagy_metadata
after_action { pagy_headers_merge(@pagy) if @pagy }
Expand Down
6 changes: 5 additions & 1 deletion app/helpers/api_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ def obj(json, object)

json.created_at object.created_at if object.respond_to?(:created_at)
json.links do
json.self api_url_for(object)
api_url_for(object).tap do |url|
json.self url if url
end
end
end

# API URL for an object. By default, the api_version of the generated URL is
# the same as the current request's version.
def api_url_for(object, **options)
polymorphic_url([:api, object], api_version: @request_version, **options)
rescue NoMethodError
nil
end

# Permanent URL for an attached file or variant
Expand Down
11 changes: 11 additions & 0 deletions app/views/api/subscriptions/_subscription.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
obj json, subscription do
json.status subscription.status

json.location do
json.extract! subscription, :city, :province, :country_code, :postal_code
end

json.subscriber do
json.partial! "api/users/user", user: subscription.subscriber
end
end
3 changes: 3 additions & 0 deletions app/views/api/users/_user.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
obj json, user do
json.extract! user, :email_address
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace :api, defaults: {format: :json} do
scope "/v:api_version" do
resources :hackathons, only: [:index, :show]
resources :subscriptions, only: :create
end
end

Expand Down
54 changes: 54 additions & 0 deletions test/controllers/api/subscriptions_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require "test_helper"

class Api::SubscriptionsControllerTest < ActionDispatch::IntegrationTest
test "should create" do
assert_difference("Hackathon::Subscription.count", 1) do
post api_subscriptions_url api_version: 1,
params: {
email: "[email protected]",
location: "Seattle, WA"
},
as: :json
end

subscription = @response.parsed_body

assert_equal subscription["id"], Hackathon::Subscription.last.hashid
end

test "should not create with invalid email" do
assert_no_difference("Hackathon::Subscription.count") do
post api_subscriptions_url api_version: 1,
params: {
email: "gary",
location: "Seattle, WA"
},
as: :json
end

assert_response :bad_request

error = @response.parsed_body
assert_equal error["type"], "bad_request_error"
end

test "should not create with missing email" do
assert_no_difference("Hackathon::Subscription.count") do
post api_subscriptions_url api_version: 1,
params: {
location: "Seattle, WA"
},
as: :json
end
end

test "should not create with missing location" do
assert_no_difference("Hackathon::Subscription.count") do
post api_subscriptions_url api_version: 1,
params: {
email: "[email protected]"
},
as: :json
end
end
end