• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MarkUsProject / Markus / 24058740316

07 Apr 2026 12:52AM UTC coverage: 91.71% (+0.001%) from 91.709%
24058740316

Pull #7897

github

web-flow
Merge 08a9736c1 into b080f6e15
Pull Request #7897: TICKET-599: Use pluck and remove unnecessary ActiveRecord object instantiations

950 of 1844 branches covered (51.52%)

Branch coverage included in aggregate %.

6 of 6 new or added lines in 2 files covered. (100.0%)

11 existing lines in 1 file now uncovered.

45180 of 48456 relevant lines covered (93.24%)

130.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.33
/app/controllers/api/users_controller.rb
1
module Api
1✔
2
  # Allows for adding, modifying and showing Markus users.
3
  # Uses Rails' RESTful routes (check 'rake routes' for the configured routes)
4
  class UsersController < MainApiController
1✔
5
    # Define default fields to display for index and show methods
6
    DEFAULT_FIELDS = [:id, :user_name, :email, :id_number, :type, :first_name, :last_name].freeze
1✔
7

8
    # Returns users and their attributes
9
    # Optional: filter, fields
10
    def index
1✔
11
      users = get_collection(visible_users) || return
8✔
12

13
      respond_to do |format|
8✔
14
        format.xml { render xml: users.to_xml(only: DEFAULT_FIELDS, root: :users, skip_types: true) }
12✔
15
        format.json do
8✔
16
          rows = users.pluck(*DEFAULT_FIELDS)
4✔
17
          render json: rows.map { |r| DEFAULT_FIELDS.zip(r).to_h }
17✔
18
        end
19
      end
20
    end
21

22
    # Creates a new user
23
    # Requires: user_name, type, first_name, last_name
24
    # Optional: section_name, grace_credits
25
    def create
1✔
26
      if has_missing_params?([:user_name, :type, :first_name, :last_name])
7✔
27
        # incomplete/invalid HTTP params
UNCOV
28
        render 'shared/http_status', locals: { code: '422', message:
×
29
          HttpStatusHelper::ERROR_CODE['message']['422'] }, status: :unprocessable_content
UNCOV
30
        return
×
31
      end
32

33
      # Check if that user_name is taken
34
      user = User.find_by(user_name: params[:user_name])
7✔
35
      unless user.nil?
7✔
36
        render 'shared/http_status', locals: { code: '409', message:
1✔
37
          'User already exists' }, status: :conflict
38
        return
1✔
39
      end
40

41
      # No conflict found, so create new user
42
      param_user_type = params[:type].camelize.downcase
6✔
43
      params.delete(:type)
6✔
44

45
      begin
46
        case param_user_type
6✔
47
        when 'enduser'
48
          EndUser.create!(params.permit(*DEFAULT_FIELDS))
3✔
49
        when 'adminuser'
50
          AdminUser.create!(params.permit(*DEFAULT_FIELDS))
2✔
51
        else
52
          render 'shared/http_status', locals: { code: '422', message: 'Unknown user type' },
1✔
53
                                       status: :unprocessable_content
54
          return
1✔
55
        end
56
      rescue ActiveRecord::SubclassNotFound, ActiveRecord::RecordInvalid => e
57
        render 'shared/http_status', locals: { code: '422', message: e.to_s }, status: :unprocessable_content
1✔
58
      else
59
        render 'shared/http_status',
4✔
60
               locals: { code: '201', message: HttpStatusHelper::ERROR_CODE['message']['201'] }, status: :created
61
      end
62
    end
63

64
    # Returns a user and its attributes
65
    # Requires: id
66
    # Optional: filter, fields
67
    def show
1✔
68
      user = visible_users.find_by(id: params[:id])
6✔
69
      if user.nil?
6✔
70
        # No user with that id
UNCOV
71
        render 'shared/http_status', locals: { code: '404', message:
×
72
          'No user exists with that id' }, status: :not_found
73
      else
74
        respond_to do |format|
6✔
75
          format.xml { render xml: user.to_xml(only: DEFAULT_FIELDS, root: :user, skip_types: true) }
9✔
76
          format.json { render json: user.to_json(only: DEFAULT_FIELDS) }
9✔
77
        end
78
      end
79
    end
80

81
    # Requires: id
82
    # Optional: first_name, last_name, user_name
83
    def update
1✔
84
      user = visible_users.find_by(id: params[:id])
3✔
85
      if user.nil?
3✔
86
        render 'shared/http_status', locals: { code: '404', message: 'User was not found' }, status: :not_found
×
UNCOV
87
        return
×
88
      end
89
      user.update!(user_params)
3✔
90
    rescue ActiveRecord::SubclassNotFound, ActiveRecord::RecordInvalid => e
UNCOV
91
      render 'shared/http_status', locals: { code: '422', message: e.to_s }, status: :unprocessable_content
×
92
    rescue StandardError
UNCOV
93
      render 'shared/http_status', locals: { code: '500', message:
×
94
        HttpStatusHelper::ERROR_CODE['message']['500'] }, status: :internal_server_error
95
    else
96
      render 'shared/http_status', locals: { code: '200', message:
3✔
97
        HttpStatusHelper::ERROR_CODE['message']['200'] }, status: :ok
98
    end
99

100
    # Update a user's attributes based on their user_name as opposed
101
    # to their id (use the regular update method instead)
102
    # Requires: user_name
103
    def update_by_username
1✔
104
      if has_missing_params?([:user_name])
2✔
105
        # incomplete/invalid HTTP params
UNCOV
106
        render 'shared/http_status',
×
107
               locals: { code: '422', message: HttpStatusHelper::ERROR_CODE['message']['422'] },
108
               status: :unprocessable_content
UNCOV
109
        return
×
110
      end
111

112
      user = User.find_by(user_name: params[:user_name])
2✔
113
      if user.nil?
2✔
114
        render 'shared/http_status', locals: { code: '404', message: 'User was not found' }, status: :not_found
×
UNCOV
115
        return
×
116
      end
117
      user.update!(user_params)
2✔
118
    rescue ActiveRecord::SubclassNotFound, ActiveRecord::RecordInvalid => e
UNCOV
119
      render 'shared/http_status', locals: { code: '422', message: e.to_s }, status: :unprocessable_content
×
120
    rescue StandardError
UNCOV
121
      render 'shared/http_status', locals: { code: '500', message:
×
122
        HttpStatusHelper::ERROR_CODE['message']['500'] }, status: :internal_server_error
123
    else
124
      render 'shared/http_status', locals: { code: '200', message:
2✔
125
        HttpStatusHelper::ERROR_CODE['message']['200'] }, status: :ok
126
    end
127

128
    private
1✔
129

130
    # Do not make AutotestUser users visible
131
    def visible_users
1✔
132
      User.where.not(type: :AutotestUser)
17✔
133
    end
134

135
    def user_params
1✔
136
      params.permit(:user_name, :email, :id_number, :first_name, :last_name)
5✔
137
    end
138
  end
139
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc