From 24641d537a2573d8a295c1c577e401d7ed7539ab Mon Sep 17 00:00:00 2001 From: Dana Scheider Date: Sat, 19 Sep 2020 07:28:42 +1000 Subject: [PATCH] API: Add route for fetching a user's followed tags (#9108) * Add route for fetching a user's followed tags * Move followed tags route to FollowsController instead of TagsController and add JSON view * Add missing new line * Change the dots for our linter Co-authored-by: rhymes Co-authored-by: Molly Struve --- app/controllers/api/v0/follows_controller.rb | 9 +++++- app/views/api/v0/follows/tags.json.jbuilder | 4 +++ config/routes.rb | 6 +++- spec/requests/api/v0/follows_spec.rb | 29 ++++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 app/views/api/v0/follows/tags.json.jbuilder diff --git a/app/controllers/api/v0/follows_controller.rb b/app/controllers/api/v0/follows_controller.rb index 6c0ea6122..8644856e9 100644 --- a/app/controllers/api/v0/follows_controller.rb +++ b/app/controllers/api/v0/follows_controller.rb @@ -1,7 +1,7 @@ module Api module V0 class FollowsController < ApiController - before_action :authenticate_with_api_key_or_current_user!, only: [:create] + before_action :authenticate_with_api_key_or_current_user! def create user_ids = params[:users].map { |h| h["id"] } @@ -10,6 +10,13 @@ module Api end render json: { outcome: "followed #{user_ids.count} users" } end + + def tags + @follows = @user.follows_by_type("ActsAsTaggableOn::Tag") + .select(%i[id followable_id followable_type points]) + .includes(:followable) + .order(points: :desc) + end end end end diff --git a/app/views/api/v0/follows/tags.json.jbuilder b/app/views/api/v0/follows/tags.json.jbuilder new file mode 100644 index 000000000..26ad9ea8d --- /dev/null +++ b/app/views/api/v0/follows/tags.json.jbuilder @@ -0,0 +1,4 @@ +json.array! @follows.each do |follow| + json.extract!(follow.followable, :id, :name) + json.extract!(follow, :points) +end diff --git a/config/routes.rb b/config/routes.rb index 41a007ba5..a9fc8c0f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -162,7 +162,11 @@ Rails.application.routes.draw do end end resources :tags, only: [:index] - resources :follows, only: [:create] + resources :follows, only: [:create] do + collection do + get :tags + end + end namespace :followers do get :users get :organizations diff --git a/spec/requests/api/v0/follows_spec.rb b/spec/requests/api/v0/follows_spec.rb index 78c44a9ca..58c130f9f 100644 --- a/spec/requests/api/v0/follows_spec.rb +++ b/spec/requests/api/v0/follows_spec.rb @@ -30,4 +30,33 @@ RSpec.describe "Api::V0::FollowsController", type: :request do end end end + + describe "GET /api/follows/tags" do + it "returns unauthorized if user is not signed in" do + get "/api/follows/tags" + expect(response).to have_http_status(:unauthorized) + end + + context "when user is authorized" do + let!(:user) { create(:user) } + let(:tag1) { create(:tag) } + let(:tag2) { create(:tag) } + let(:tag3) { create(:tag) } + + let(:tag1_json) { { id: tag1.id, name: tag1.name, points: 1.0 } } + let(:tag2_json) { { id: tag2.id, name: tag2.name, points: 1.0 } } + + before do + sign_in user + [tag1, tag2].each { |tag| user.follow(tag) } + end + + it "returns only the tags the user follows", aggregate_failures: true do + get "/api/follows/tags" + body = JSON.parse(response.body, symbolize_names: true) + expect(body).to include(tag1_json) + expect(body).to include(tag2_json) + end + end + end end