[RUBY] Créer une API de tableau d'affichage avec autorisation de certification dans Rails 6 # 13 Accorder l'en-tête d'authentification

Création d'une API de tableau d'affichage avec autorisation de certification dans Rails 6 # 12 Association de l'utilisateur et de la publication

correction d'usine

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.

Modifier la spécification de la demande et le contrôleur

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.

Contrôleur fixe

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é.

Déplacement du processus d'acquisition d'en-tête authentifié de rspec vers helper

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.

A continué

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

Créer une API de tableau d'affichage avec autorisation de certification dans Rails 6 # 13 Accorder l'en-tête d'authentification
Créez une API de tableau d'affichage avec certification et autorisation dans Rails 6 # 17 Ajoutez des privilèges d'administrateur
Construire une API de tableau d'affichage avec certification et autorisation dans le contrôleur Rails 6 # 5, implémentation des routes
Introduction de # 10 devise_token_auth pour créer une API de tableau d'affichage avec autorisation d'authentification dans Rails 6
Introduction de l'expert n ° 15 pour créer une API de tableau d'affichage avec certification et autorisation dans Rails 6
Construire une API de tableau d'affichage avec certification et autorisation dans Rails 6 # 14 Seed Affichage du temps d'exécution
# 16 paramètre de stratégie pour créer une API de tableau d'affichage avec autorisation de certification dans Rails 6
Implémentation n ° 8 pour créer une API de tableau d'affichage avec autorisation de certification dans Rails 6
Présentation du sérialiseur n ° 9 pour créer une API de tableau d'affichage avec certification et autorisation dans Rails 6
Créer une API de tableau d'affichage avec autorisation dans Rails 6 # 12 Association d'utilisateur et de publication
Créez une API de tableau d'affichage avec certification et autorisation dans Rails 6 # 6 show, créez une implémentation
Présentation de # 2 git et rubocop pour créer une API de tableau d'affichage avec autorisation d'authentification dans Rails
Créer une API de tableau d'affichage avec autorisation de certification dans la mise à jour Rails 6 # 7, détruire l'implémentation
Créer une API de tableau d'affichage avec autorisation de certification dans Rails 6 # 11 Test et validation du modèle utilisateur ajoutés
Construire une API de tableau d'affichage avec certification et autorisation avec Rails 6 # 18 ・ Implémentation du contrôleur de l'utilisateur final
Créez une API de tableau d'affichage avec certification et autorisation avec Rails 6 # 3 RSpec, FactoryBot introduit et post-modèle
# 4 post-validation et mise en œuvre de test pour créer une API de tableau d'affichage avec certification et autorisation dans Rails 6
Ajoutez une fonction de recherche dans Rails.
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
Essayez de créer un babillard en Java
Ajouter un projet dans n'importe quel dossier avec Gradle
Comment créer une API avec GraphQL et Rails
[Note] Créez un environnement Python3 avec Docker dans EC2
[Comment insérer une vidéo dans un hameau avec Rails]
Environnement Build Rails (API) x MySQL x Nuxt.js avec Docker
[Ruby on Rails] Ajouter une colonne avec des contraintes de clé externe
Créer un SlackBot avec AWS lambda et API Gateway en Java
Je suis tombé sur un gars avec deux points dans les rails
Comment configurer un proxy avec authentification dans Feign
Japaneseize en utilisant i18n avec Rails
Implémenter l'authentification LTI dans Rails
[Procédure d'implémentation] Créer une fonction d'authentification utilisateur à l'aide de sorcellerie dans Rails
J'ai essayé d'implémenter l'API Rails avec TDD par RSpec. part2 -authentification de l'utilisateur-
Comment renommer un modèle avec des contraintes de clé externes dans Rails
J'ai essayé d'implémenter l'API Rails avec TDD par RSpec. part3-Implémentation d'action avec authentification-
Étapes pour créer un environnement de développement Ruby on Rails avec Vagrant