Ändern Sie zunächst spec / spec_helper.rb
wie folgt.
Wie in der Expertenformel angegeben, können Sie die rspec-Methode für Experten verwenden, indem Sie Folgendes hinzufügen.
spec/spec_helper.rb
RSpec.configure do |config|
...
+ require "pundit/rspec"
end
Als nächstes werden wir den Test in spec / Policies / post_policy_spec.rb
integrieren.
spec/policies/post_policy_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe PostPolicy, type: :policy do
let(:user) { create(:user) }
let(:post) { create(:post) }
subject { described_class }
permissions :index?, :show? do
it "Erlaubt, wenn nicht angemeldet" do
expect(subject).to permit(nil, post)
end
end
permissions :create? do
it "Nicht erlaubt, wenn nicht angemeldet" do
expect(subject).not_to permit(nil, post)
end
it "Zulassen, wenn Sie angemeldet sind" do
expect(subject).to permit(user, post)
end
end
permissions :update?, :destroy? do
it "Nicht erlaubt, wenn nicht angemeldet" do
expect(subject).not_to permit(nil, post)
end
it "Nicht erlaubt, wenn angemeldet, aber ein anderer Benutzer" do
expect(subject).not_to permit(user, post)
end
it "Erlaubt, wenn angemeldet und derselbe Benutzer" do
post.user = user
expect(subject).to permit(user, post)
end
end
end
Ich denke, Sie können es irgendwie lesen, aber für alle Fälle erklären Sie es bitte.
permissions :index?, :show? do
it "Erlaubt, wenn nicht angemeldet" do
expect(subject).to permit(nil, post)
end
end
Da Index "Und Show" die gleichen Bedingungen haben, werden sie zusammen getestet.
allow (nil, post)
gibt das Login-Benutzermodell im ersten Argument und das Zielmodell im zweiten Argument an.
Anschließend wird geprüft, ob der Benutzer des ersten Arguments über den Index verfügt oder ob die Berechtigung des Objekts des zweiten Arguments angezeigt wird.
permissions :update?, :destroy? do
...
it "Nicht erlaubt, wenn angemeldet, aber ein anderer Benutzer" do
expect(subject).not_to permit(user, post)
end
it "Erlaubt, wenn angemeldet und derselbe Benutzer" do
post.user = user
expect(subject).to permit(user, post)
end
end
Ich schaue immer noch auf not_to, aber es ist ein Test, nicht erlaubt zu sein. Und der letzte Test besteht, indem er dem Eigentümer des Beitrags entspricht.
Lassen Sie uns rspec einmal verschieben.
Dann wird spec / request / v1 / posts_request_spec.rb
ziemlich moosig sein.
Die Ursache ist dieselbe wie oben, denn wenn #update oder #destory nicht das Login des Benutzers ist, zu dem es gehört, ist es 403. Der in "posts_request_spec.rb" verwendete "autorisierte_Benutzer_Header" -Helfer "erstellt (: Benutzer)" jedoch intern, sodass der angemeldete Benutzer und der Beitragsbenutzer nicht übereinstimmen können.
Nehmen Sie daher die folgenden Änderungen vor.
spec/support/authorization_spec_helper.rb
module AuthorizationSpecHelper
- def authorized_user_headers
- user = create(:user)
+ def authorized_user_headers(user = nil)
+ user = create(:user) if user.nil?
post v1_user_session_url, params: { email: user.email, password: "password" }
Wenn Sie es nun ohne Argument an "authorized_user_headers" übergeben, wird ein Benutzer intern erstellt, und wenn Sie einen Benutzer als Argument übergeben, wird es verwendet.
Authorized_user_headers
wird jedoch etwas kompliziert und bleibt in AbcSize von Rubocop stecken, sodass wir die folgenden Maßnahmen ergreifen werden.
diff:.rubocop.yml
...
+
+#AbcSize Default 15 ist schwierig, erhöhen Sie es also auf 20
+Metrics/AbcSize:
+ Max: 20
Jetzt ist es endlich Zeit, die Anforderungsspezifikation zu korrigieren.
spec/requests/v1/posts_request_spec.rb
...
it "Der normale Antwortcode wird zurückgegeben" do
- put v1_post_url({ id: update_param[:id] }), params: update_param
+ post = Post.find(update_param[:id])
+ put v1_post_url({ id: update_param[:id] }), params: update_param, headers: authorized_user_headers(post.user)
expect(response.status).to eq 200
end
it "subject,Körper kehrt korrekt zurück" do
- put v1_post_url({ id: update_param[:id] }), params: update_param
+ post = Post.find(update_param[:id])
+ put v1_post_url({ id: update_param[:id] }), params: update_param, headers: authorized_user_headers(post.user)
json = JSON.parse(response.body)
expect(json["post"]["subject"]).to eq("update_Probandentest")
expect(json["post"]["body"]).to eq("update_Körpertest")
end
it "Fehler werden zurückgegeben, wenn der Parameter ungültig ist" do
- put v1_post_url({ id: update_param[:id] }), params: { subject: "" }
+ post = Post.find(update_param[:id])
+ put v1_post_url({ id: update_param[:id] }), params: { subject: "" }, headers: authorized_user_headers(post.user)
json = JSON.parse(response.body)
expect(json.key?("errors")).to be true
end
@@ -106,13 +109,13 @@ RSpec.describe "V1::Posts", type: :request do
create(:post)
end
it "Der normale Antwortcode wird zurückgegeben" do
- delete v1_post_url({ id: delete_post.id })
+ delete v1_post_url({ id: delete_post.id }), headers: authorized_user_headers(delete_post.user)
expect(response.status).to eq 200
end
it "Eins weniger und kehrt zurück" do
delete_post
expect do
- delete v1_post_url({ id: delete_post.id })
+ delete v1_post_url({ id: delete_post.id }), headers: authorized_user_headers(delete_post.user)
end.to change { Post.count }.by(-1)
end
Es gibt keine große Veränderung. Übergeben Sie die Autorisierung, indem Sie den Eigentümer des Beitrags an "authorized_user_headers" übergeben.
Ich werde das etwas intuitiver ändern. Der Prozess der Feststellung, ob es Ihnen gehört, ist nicht auf das Posten beschränkt, und es scheint, dass es in Zukunft auf verschiedene Modelle umgeleitet wird.
def update?
@record.user == @user
end
def destroy?
@record.user == @user
end
Erstellen Sie daher in application_policy.rb eine private Methode, um festzustellen, ob sie Ihnen gehört.
app/policies/application_policy.rb
class ApplicationPolicy
...
+ private
+
+ def mine?
+ @record.user == @user
+ end
#
# scope
#
class Scope
...
Ich werde es in post_policy reflektieren.
app/policies/post_policy.rb
def update?
- @record.user == @user
+ mine?
end
def destroy?
- @record.user == @user
+ mine?
end
Es war erfrischend. Von nun an besteht die Aktion, die nur ausgeführt werden soll, wenn das dem Benutzer zugeordnete Modell es besitzt, nur darin, eine Richtliniendatei zu erstellen und die Methode "Mine" zu platzieren. Es ist super einfach.
→ Erstellen einer Bulletin Board-API mit Authentifizierung und Autorisierung in Rails 6 # 17 Hinzufügen von Administratorrechten [Zur Serialisierungstabelle]
Recommended Posts