Skip to content

Commit ca83796

Browse files
committed
Adds Request Spec for Beacons, and route for revoking a Beacon's API
token
1 parent ee1549b commit ca83796

File tree

5 files changed

+204
-11
lines changed

5 files changed

+204
-11
lines changed

app/controllers/beacons_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def new
1616

1717
def create
1818
success, @beacon, api_key = Beacons::Creator.new.call(beacon_params)
19-
19+
2020
if success
2121
flash[:notice] = "Beacon was successfully provisioned. API Key: #{api_key}"
2222
redirect_to @beacon
@@ -75,7 +75,7 @@ def revoke_key
7575
redirect_to @beacon
7676
end
7777
end
78-
78+
7979
private
8080

8181
def set_beacon

app/models/beacon.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ def revoked?
6464
# Get count of topics that match this beacon's configuration
6565
def document_count
6666
scope = Topic.active
67-
67+
6868
# Filter by beacon's language
6969
scope = scope.where(language_id: language_id) if language_id.present?
70-
70+
7171
# If beacon has specific providers selected, filter by those
7272
if providers.any?
7373
scope = scope.where(provider_id: providers.pluck(:id))
@@ -78,32 +78,32 @@ def document_count
7878
scope = scope.where(provider_id: provider_ids)
7979
end
8080
end
81-
81+
8282
# If beacon has specific topics selected, filter by those
8383
if topics.any?
8484
scope = scope.where(id: topics.pluck(:id))
8585
end
86-
86+
8787
scope.count
8888
end
8989

9090
# Get count of actual document files attached to matching topics
9191
def file_count
9292
scope = Topic.active
93-
93+
9494
scope = scope.where(language_id: language_id) if language_id.present?
95-
95+
9696
if providers.any?
9797
scope = scope.where(provider_id: providers.pluck(:id))
9898
elsif region.present?
9999
provider_ids = region.providers.pluck(:id)
100100
scope = scope.where(provider_id: provider_ids)
101101
end
102-
102+
103103
if topics.any?
104104
scope = scope.where(id: topics.pluck(:id))
105105
end
106-
106+
107107
# Count total attached documents
108108
scope.joins(:documents_attachments).count
109109
end

app/views/beacons/show.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
<span>Regenerate API Key</span>
195195
<% end %>
196196

197-
<%= button_to regenerate_key_beacon_path(@beacon), method: :post,
197+
<%= button_to revoke_key_beacon_path(@beacon), method: :post,
198198
class: "w-full bg-red-600 hover:bg-red-700 text-white font-semibold py-3 px-4 rounded-lg transition-colors inline-flex items-center justify-center gap-2",
199199
data: { turbo_confirm: "Are you sure? This will invalidate the current API key. Any beacons using the old key will stop working." } do %>
200200
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">

config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
resources :beacons, only: %i[index new create show edit update] do
2121
member do
2222
post :regenerate_key
23+
post :revoke_key
2324
end
2425
end
2526
resource :settings, only: [] do

spec/requests/beacons_spec.rb

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
require "rails_helper"
2+
3+
RSpec.describe "/beacons", type: :request do
4+
let(:user) { create(:user, :admin) }
5+
let(:region) { create(:region) }
6+
let(:language) { create(:language) }
7+
let(:valid_attributes) do
8+
{ name: "New Beacon",
9+
language_id: language.id,
10+
region_id: region.id,
11+
}
12+
end
13+
let(:invalid_attributes) { { name: "" } }
14+
15+
before do
16+
sign_in(user)
17+
end
18+
19+
describe "GET /index" do
20+
it "renders a successful response" do
21+
create(:beacon)
22+
23+
get beacons_url
24+
25+
expect(response).to be_successful
26+
end
27+
end
28+
29+
describe "GET /show" do
30+
it "renders a successful response" do
31+
beacon = create(:beacon)
32+
33+
get beacon_url(beacon)
34+
35+
expect(response).to be_successful
36+
end
37+
end
38+
39+
describe "GET /new" do
40+
it "renders a successful response" do
41+
get new_beacon_url
42+
43+
expect(response).to be_successful
44+
end
45+
end
46+
47+
describe "GET /edit" do
48+
let(:beacon) { create(:beacon) }
49+
50+
it "renders a successful response" do
51+
get edit_beacon_url(beacon)
52+
53+
expect(response).to be_successful
54+
end
55+
end
56+
57+
describe "POST /create" do
58+
context "with valid parameters" do
59+
it "creates a new beacon" do
60+
expect {
61+
post beacons_url, params: { beacon: valid_attributes }
62+
}.to change(Beacon, :count).by(1)
63+
end
64+
65+
it "redirects to the created beacon" do
66+
post beacons_url, params: { beacon: valid_attributes }
67+
68+
expect(response).to redirect_to(beacon_url(Beacon.last))
69+
end
70+
end
71+
72+
context "with invalid parameters" do
73+
it "does not create a new beacon" do
74+
expect {
75+
post beacons_url, params: { beacon: invalid_attributes }
76+
}.to change(Beacon, :count).by(0)
77+
end
78+
79+
it "renders a response with 422 status (i.e. to display the 'new' template)" do
80+
post beacons_url, params: { beacon: invalid_attributes }
81+
82+
expect(response).to have_http_status(:unprocessable_content)
83+
end
84+
end
85+
end
86+
87+
describe "PATCH /update" do
88+
context "with valid parameters" do
89+
let(:updated_region) { create(:region) }
90+
let(:updated_language) { create(:language) }
91+
let(:new_attributes) do
92+
{ name: "Updated Beacon",
93+
language_id: updated_language.id,
94+
region_id: updated_region.id,
95+
}
96+
end
97+
98+
it "updates the requested beacon" do
99+
beacon = create(:beacon)
100+
101+
patch beacon_url(beacon), params: { beacon: new_attributes }
102+
beacon.reload
103+
104+
expect(beacon.name).to eq("Updated Beacon")
105+
expect(beacon.language).to eq(updated_language)
106+
expect(beacon.region).to eq(updated_region)
107+
end
108+
109+
it "redirects to the beacon" do
110+
beacon = create(:beacon)
111+
112+
patch beacon_url(beacon), params: { beacon: new_attributes }
113+
beacon.reload
114+
115+
expect(response).to redirect_to(beacon_url(beacon))
116+
end
117+
end
118+
119+
context "with invalid parameters" do
120+
it "renders a response with 422 status (i.e. to display the 'edit' template)" do
121+
beacon = create(:beacon)
122+
123+
patch beacon_url(beacon), params: { beacon: invalid_attributes }
124+
125+
expect(response).to have_http_status(:unprocessable_content)
126+
end
127+
end
128+
end
129+
130+
describe "POST /regenerate_key" do
131+
subject { post regenerate_key_beacon_url(beacon) }
132+
133+
it "regenerates the API key for the requested beacon" do
134+
beacon = create(:beacon)
135+
136+
expect { subject }.to change { beacon.api_key_digest }
137+
.and change { beacon.api_key_prefix }
138+
end
139+
140+
it "redirects to the beacon" do
141+
beacon = create(:beacon)
142+
143+
subject
144+
145+
expect(response).to redirect_to(beacon_url(beacon))
146+
end
147+
148+
context "when there is an error" do
149+
allow(Beacon).to receive(:regenerate).raise_error
150+
151+
it "does not regenerate the API key for the requested beacon" do
152+
beacon = create(:beacon)
153+
154+
expect { subject }.not_to change { beacon.api_key_digest }
155+
.and change { beacon.api_key_prefix }
156+
end
157+
158+
it "redirects to the beacon" do
159+
beacon = create(:beacon)
160+
161+
subject
162+
163+
expect(response).to redirect_to(beacon_url(beacon))
164+
end
165+
end
166+
end
167+
168+
describe "POST /revoke_key" do
169+
include ActiveSupport::Testing::TimeHelpers
170+
subject { post revoke_key_beacon_url(beacon) }
171+
172+
it "redirects to the beacon" do
173+
beacon = create(:beacon)
174+
175+
subject
176+
177+
expect(response).to redirect_to(beacon_url(beacon))
178+
end
179+
180+
context "when there is an error" do
181+
allow(Beacon).to receive(:regenerate).raise_error
182+
183+
it "redirects to the beacon" do
184+
beacon = create(:beacon)
185+
186+
subject
187+
188+
expect(response).to redirect_to(beacon_url(beacon))
189+
end
190+
end
191+
end
192+
end

0 commit comments

Comments
 (0)