Adding some polls API endpoints for PR to discourse_api, which work fine. Now I’m trying to understand how to create tests before submitting the PR, e.g.:
require 'spec_helper'
describe DiscourseApi::API::Polls do
subject { DiscourseApi::Client.new("http://localhost:3000", "test_d7fd0429940", "test_user" )}
describe "#polls" do
before do
stub_get("http://localhost:3000/polls/voters.json").to_return(body: fixture("voters.json"), headers: { content_type: "application/json" })
end
it "requests the correct resource" do
subject.voters :post_id => 27885, :poll_name => 'poll'
expect(a_get("http://localhost:3000/polls/voters.json")).to have_been_made
end
end
end
But am getting the error:
Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)
# ./lib/discourse_api/client.rb:141:in `rescue in request'
# ./lib/discourse_api/client.rb:132:in `request'
# ./lib/discourse_api/client.rb:85:in `get'
# ./lib/discourse_api/api/polls.rb:22:in `voters'
# ./spec/discourse_api/api/polls_spec.rb:12:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# Errno::ECONNREFUSED:
# Connection refused - connect(2) for "localhost" port 3000
# /Users/kimardenmiller/.rbenv/versions/2.5.3/gemsets/d_api/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/net_http.rb:109:in `request'
All the existing tests pass fine for me, and I’m trying to copy the format of those existing tests, but cannot for the life of me figure out what I’m doing wrong.
Here’s the (new) endpoint being tested:
module DiscourseApi
module API
module Polls
def poll_voters(args)
args = API.params(args) # post_id, poll_name, user, opts = {}
.required(:post_id, :poll_name)
.optional(:opts, :api_username)
response = get("/polls/voters.json", args)
response[:body]
end
end
end
end
Have working tests, though my gut tells me I could use tips on making those urls more elegant.
require 'spec_helper'
describe DiscourseApi::API::Polls do
subject { DiscourseApi::Client.new("http://localhost:3000", "test_d7fd0429940", "test_user" )}
describe "#polls" do
before do
stub_get("http://localhost:3000/polls/voters.json?post_id=27885&poll_name=poll").to_return(body: fixture("polls_voters.json"), headers: { content_type: "application/json" })
end
it "requests the correct resource" do
subject.poll_voters post_id: 27885, poll_name: 'poll'
expect(a_get("http://localhost:3000/polls/voters.json?post_id=27885&poll_name=poll")).to have_been_made
end
it "returns the expected votes" do
voters = subject.poll_voters post_id: 27885, poll_name: 'poll'
expect(voters).to be_a Hash
voters.each { |g| expect(g).to be_an Array }
expect(voters['voters']['e539a9df8700d0d05c69356a07b768cf']).to be_an Array
expect(voters['voters']['e539a9df8700d0d05c69356a07b768cf'][0]['id']).to eq(356)
end
end
end
Glad you got the tests working. They can be tricky sometimes because if the request doesn’t match exactly it will try and create an actual request rather that using the stubbed request.
I think the urls are okay. It would be nice not to use such a high post_id, but I’m not concerned about that. And ALL the tests need to have http://localhost:3000 extracted out into a common variable, but that should probably be done in a separate commit. Whenever you are ready you can go ahead and submit a pr and I can review it.
One thing I did notice though is I that passing in the api_username as a parameter is no longer supported.
This is because the discourse_api gem now only passes in the auth via the headers, and discourse core ignores any auth credentials in the body if the header is already being used for auth.
Dividiamo pure le PR. Concentriamoci prima su quella relativa alla specifica e spostiamo la variabile comune nella cartella della specifica. Dovremmo poter aggiungerla al file helper della specifica.
Poiché questo riguarda solo gli esempi, dovremmo includere tutto ciò che ne è correlato all’interno della directory examples, senza modificare alcuna funzionalità esistente nella directory lib. Anche il file config.yml dovrebbe essere posizionato all’interno della directory examples. Il caricamento del file YAML è molto leggero; possiamo aggiungerlo all’inizio di ogni file di esempio, ma sarebbe meglio inserirlo in un file comune all’interno della directory examples da cui tutti possano leggerlo.
# host, ad esempio localhost:3000 o discourse.my_domain.com
host: NOME_TUO_HOST
# utente API (può influenzare i risultati restituiti, ad esempio il metodo .categories restituisce solo le categorie visibili al tuo api_username)
# crea un nuovo client quando cambi l'utente API
api_username: LA_TUA_API_KEY
# chiave API dal pannello di amministrazione di Discourse /admin/api/keys
api_key: LA_TUA_API_KEY
examples/badges.rb
require_relative 'example_helper'
# ottieni i badge
puts client.badges
Opinioni? Sicuramente abbiamo bisogno del file yml ora, dato l’example_helper.rb?
Sembra tutto a posto. Aggiorniamo l’esempio di helper con i valori predefiniti in modo che funzioni senza il file yml. Poi aggiorniamo il readme con le istruzioni per copiare il file yml di esempio in examples/config.yml. E assicuriamoci di aggiungere examples/config.yml a .gitignore.
Questa è una convenzione piuttosto standard per evitare che sia facile inviare un file config.yml con le credenziali di produzione. Inoltre, puoi modificare il file senza che git lo rilevi come una modifica.
Penso che quell’errore sia accettabile, poiché è così che funzionano attualmente gli esempi e, comunque, si tratta solo di esempi. Se lo desideri, ora o in seguito, possiamo sempre intercettare l’eccezione e fornire un messaggio utile.
La nostra sezione Testing attuale è un po’ confusa, in quanto mescola attività relative a discourse_api con l’installazione di Discourse stesso. Ad esempio, se hai un server di staging nel cloud, non hai affatto bisogno di installare Discourse in locale. Cosa ne pensi di:
Esempi e Testing
Per provare gli esempi o eseguire i test avrai bisogno di un’istanza di Discourse attiva e funzionante, installata sia in locale che nel cloud.
Esempi
Per eseguire gli esempi in /examples:
Specifica il tuo ambiente creando una copia di config-example.yml per generare un file chiamato config.yml con le impostazioni del tuo ambiente.
In un file di esempio, commenta tutto tranne gli esempi che desideri eseguire.
Modifica il file di esempio con eventuali parametri richiesti, ad esempio username.
L’esecuzione del file utilizzerà quindi il tuo config.yml per eseguire un determinato metodo client (ad esempio client.badges) contro la tua istanza di Discourse.
Testing
Per eseguire i test di discourse_api in spec:
Installa bundler nella directory discourse_api, eseguendo gem install bundler.
All’interno della tua directory discourse_api, esegui: bundle exec rspec spec/.
Suona bene, il readme potrebbe aver bisogno di qualche aggiornamento
Per eseguire i test in realtà non è necessaria un’istanza di Discourse attiva e funzionante. Tutte le richieste di spec dovrebbero essere mockate e non serve un server.