From 6357a3ce337bdf59c7a6a0f362897a46ffbd6304 Mon Sep 17 00:00:00 2001 From: Andrei Prigorshnev Date: Thu, 24 Nov 2022 19:16:28 +0400 Subject: [PATCH] FEATURE: User Status API (#19149) This adds API scope for the user status. This also adds a get method to the user status controller. We didn't need a dedicated method that returns status before because the server returns status with user objects, but I think we need to provide this method for API clients. --- app/controllers/user_status_controller.rb | 7 ++++ app/models/api_key_scope.rb | 4 ++ config/locales/client.en.yml | 3 ++ config/routes.rb | 1 + spec/requests/admin/api_controller_spec.rb | 1 + spec/requests/user_status_controller_spec.rb | 40 ++++++++++++++++++++ 6 files changed, 56 insertions(+) diff --git a/app/controllers/user_status_controller.rb b/app/controllers/user_status_controller.rb index 5d7d05858f0..14016bd22e9 100644 --- a/app/controllers/user_status_controller.rb +++ b/app/controllers/user_status_controller.rb @@ -3,6 +3,13 @@ class UserStatusController < ApplicationController requires_login + def get + ensure_feature_enabled + respond_to do |format| + format.json { render json: UserStatusSerializer.new(current_user.user_status, root: false) } + end + end + def set ensure_feature_enabled description = params.require(:description) diff --git a/app/models/api_key_scope.rb b/app/models/api_key_scope.rb index 1cc804fecfb..18db82addd7 100644 --- a/app/models/api_key_scope.rb +++ b/app/models/api_key_scope.rb @@ -63,6 +63,10 @@ class ApiKeyScope < ActiveRecord::Base delete: { actions: %w[admin/users#destroy] }, list: { actions: %w[admin/users#index] }, }, + user_status: { + read: { actions: %w[user_status#get] }, + update: { actions: %w[user_status#set user_status#clear] }, + }, email: { receive_emails: { actions: %w[admin/email#handle_mail admin/email#smtp_should_reject] } }, diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 96521f563f7..975f116aa50 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -4518,6 +4518,9 @@ en: anonymize: Anonymize user accounts. delete: Delete user accounts. list: Get a list of users. + user_status: + read: Read user status. + update: Update user status. email: receive_emails: Combine this scope with the mail-receiver to process incoming emails. badges: diff --git a/config/routes.rb b/config/routes.rb index 44c1570c882..6bb1a357a59 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1037,6 +1037,7 @@ Discourse::Application.routes.draw do post "/presence/update" => "presence#update" get "/presence/get" => "presence#get" + get "user-status" => "user_status#get" put "user-status" => "user_status#set" delete "user-status" => "user_status#clear" diff --git a/spec/requests/admin/api_controller_spec.rb b/spec/requests/admin/api_controller_spec.rb index ccc4db57410..9fbc4f0c8d8 100644 --- a/spec/requests/admin/api_controller_spec.rb +++ b/spec/requests/admin/api_controller_spec.rb @@ -421,6 +421,7 @@ RSpec.describe Admin::ApiController do "email", "posts", "uploads", + "user_status", "global", "badges", "categories", diff --git a/spec/requests/user_status_controller_spec.rb b/spec/requests/user_status_controller_spec.rb index e16dbd1be93..bac9878f810 100644 --- a/spec/requests/user_status_controller_spec.rb +++ b/spec/requests/user_status_controller_spec.rb @@ -1,6 +1,46 @@ # frozen_string_literal: true RSpec.describe UserStatusController do + describe '#get' do + it 'requires user to be logged in' do + get "/user-status.json" + expect(response.status).to eq(403) + end + + it "returns 404 if the feature is disabled" do + user = Fabricate(:user) + sign_in(user) + SiteSetting.enable_user_status = false + + get "/user-status.json" + + expect(response.status).to eq(404) + end + + describe 'when feature is enabled and a user is logged in' do + fab!(:user) { Fabricate(:user) } + + before do + sign_in(user) + SiteSetting.enable_user_status = true + end + + it "returns user status" do + status = "off to dentist" + status_emoji = "tooth" + ends_at = "2100-01-01T18:00:00.000Z" + user.set_status!(status, status_emoji, DateTime.parse(ends_at)) + + get "/user-status.json" + + expect(response.status).to eq(200) + expect(response.parsed_body["description"]).to eq(status) + expect(response.parsed_body["emoji"]).to eq(status_emoji) + expect(response.parsed_body["ends_at"]).to eq(ends_at) + end + end + end + describe '#set' do it 'requires user to be logged in' do put "/user-status.json", params: { description: "off to dentist" }