Je vais le réparer de l'usine.
Celui qui vole le plus
ActiveRecord::RecordInvalid:
Validation failed: User must exist
Voilà l'erreur.
Cela se produit parce que le user_id devient nul lorsque create (: post)
est terminé.
Écrasons-le en modifiant l'usine.
spec/factories/posts.rb
factory :post do
subject { "MyString" }
body { "MyText" }
+
+ after(:build) do |obj|
+ obj.user = build(:user) if obj.user.nil?
+ end
end
ʻAfter (: build) `est exécuté après build ou create. Vous pouvez éliminer l'erreur L'utilisateur doit exister en plaçant l'utilisateur intégré dans post.user.
De plus, en faisant ʻif obj.user.nil? , Lorsqu'un utilisateur spécifique est passé et créé comme
create (: post, user: user) `, il est empêché d'être écrasé par un traitement interne. Je vais.
En fait, de manière plus simple, la plupart d'entre eux peuvent être écrasés pour le moment.
spec/factories/posts.rb
factory :post do
subject { "MyString" }
body { "MyText" }
+ user
end
Cependant, cette méthode est bonne lorsque create (: post)
est terminé, mais comme l'utilisateur retourne avec nil lorsque build (: post)
est terminé, la première est prise en charge.
spec/requests/v1/posts_request_spec.rb
describe "POST /v1/posts#create" do
+ let(:authorized_headers) do
+ user = create(:user)
+ post v1_user_session_url, params: { email: user.email, password: "password" }
+ headers = {}
+ headers["access-token"] = response.header["access-token"]
+ headers["client"] = response.header["client"]
+ headers["uid"] = response.header["uid"]
+ headers
+ end
let(:new_post) do
attributes_for(:post, subject: "create_test du sujet", body: "create_test corporel")
end
it "Le code de réponse normal est renvoyé" do
- post v1_posts_url, params: new_post
+ post v1_posts_url, params: new_post, headers: authorized_headers
expect(response.status).to eq 200
end
it "Un autre cas sera retourné" do
expect do
- post v1_posts_url, params: new_post
+ post v1_posts_url, params: new_post, headers: authorized_headers
end.to change { Post.count }.by(1)
end
it "subject,le corps revient correctement" do
- post v1_posts_url, params: new_post
+ post v1_posts_url, params: new_post, headers: authorized_headers
json = JSON.parse(response.body)
expect(json["post"]["subject"]).to eq("create_test du sujet")
expect(json["post"]["body"]).to eq("create_test corporel")
end
it "Des erreurs sont renvoyées lorsque le paramètre n'est pas valide" do
- post v1_posts_url, params: {}
+ post v1_posts_url, params: {}, headers: authorized_headers
json = JSON.parse(response.body)
expect(json.key?("errors")).to be true
end
end
Générez un utilisateur et connectez-vous en fonction de ces informations utilisateur.
En ajoutant les 3 clés d'authentification dans l'en-tête de réponse aux en-têtes et à la publication, vous pouvez y accéder en étant authentifié en tant qu'utilisateur create (: user)
.
Cependant, comme le côté contrôleur n'a pas encore été corrigé, cela reste une erreur.
app/controllers/v1/posts_controller.rb
def create
- post = Post.new(post_params)
+ post = current_v1_user.posts.new(post_params)
if post.save
Le correctif ci-dessus devrait réussir le test.
Pour expliquer le comportement, tout d'abord, puisque les informations d'authentification sont passées par des en-têtes, le contrôleur peut utiliser la méthode current_v1_user
. Cela renverra l'instance de l'utilisateur connecté.
En d'autres termes, current_v1_user.posts.new
instancie la publication associée à l'utilisateur connecté.
Cela créera un message pour l'utilisateur connecté.
Le test a réussi, mais lors de l'implémentation de l'autorisation avec Pundit à l'avenir, si vous écrivez le processus pour acquérir l'en-tête authentifié à chaque fois, la maintenabilité diminuera, alors passez à l'assistant pour les spécifications. Je vais.
L'assistant pour spec est généralement placé dans spec / support, donc créez un répertoire.
$ mkdir spec/support
$ touch spec/support/authorization_spec_helper.rb
J'apporterai le traitement qui convenait à rspec à cet endroit.
spec/support/authorization_spec_helper.rb
# frozen_string_literal: true
#
#Aide à l'authentification
#
module AuthorizationSpecHelper
def authorized_user_headers
user = create(:user)
post v1_user_session_url, params: { email: user.email, password: "password" }
headers = {}
headers["access-token"] = response.header["access-token"]
headers["client"] = response.header["client"]
headers["uid"] = response.header["uid"]
headers
end
end
Si vous le placez simplement sous spec / support, il ne sera pas lu par lui-même, alors modifiez spec / rails_helper.rb.
spec/rails_helper.rb
-# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
+Dir[Rails.root.join("spec", "support", "**", "*.rb")].sort.each { |f| require f }
...
RSpec.configure do |config|
...
+ config.include(AuthorizationSpecHelper, type: :request)
end
Activez le processus de lecture sous spec / support qui a été commenté et incluez AuthorizationSpecHelper. En écrivant comme ci-dessus, seule la spécification de la demande sera valide.
spec/requests/v1/posts_request_spec.rb
...
require "rails_helper"
RSpec.describe "V1::Posts", type: :request do
+ let(:authorized_headers) do
+ authorized_user_headers
+ end
...
describe "POST /v1/posts#create" do
- let(:authorized_headers) do
- user = create(:user)
- post v1_user_session_url, params: { email: user.email, password: "password" }
- headers = {}
- headers["access-token"] = response.header["access-token"]
- headers["client"] = response.header["client"]
- headers["uid"] = response.header["uid"]
- headers
- end
...
Le reste est complété par la correspondance ci-dessus. Si le résultat du test reste vert, c'est OK pour le moment.
Tous les tests réussissent, mais le code de test est inadéquat en premier lieu. Si vous cliquez sur #create alors que vous n'êtes pas authentifié, vous obtiendrez une erreur 500, et les spécifications actuelles selon lesquelles vous pouvez mettre à jour ou supprimer des messages autres que vous-même sont gênantes, donc j'ajouterai enfin l'autorisation la prochaine fois.
La prochaine fois, nous maintiendrons la graine. C'est tout pour aujourd'hui.
→ Création d'une API de tableau d'affichage avec certification et autorisation dans Rails 6 # 14 Affichage de l'heure d'exécution [Vers la table de sérialisation]
Recommended Posts