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