-
Notifications
You must be signed in to change notification settings - Fork 15
Adds specs for ApiLoginManager, User model and Post model #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,8 @@ | ||
| FactoryBot.define do | ||
| # Implementar factory | ||
| factory :post do | ||
| title { Faker::Lorem.sentence } | ||
| body { Faker::Lorem.paragraph } | ||
| user | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,4 +3,30 @@ | |
| RSpec.describe Post, type: :model do | ||
| # En base al modelo de test propuesto para el modelo User, | ||
| # implementar los tests para el modelo Post. | ||
| describe 'Factory' do | ||
| it 'has a valid factory' do | ||
| # Testear que el factory definido es válido. | ||
| expect(FactoryBot.create(:post)).to be_valid | ||
| end | ||
| end | ||
|
|
||
| describe 'Associations' do | ||
| # Testear asociaciones (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activerecord-matchers | ||
| it { is_expected.to belong_to(:user) } | ||
| end | ||
|
|
||
| describe 'Presence validations' do | ||
| # Testear validaciones de presencia (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activemodel-matchers | ||
| it { is_expected.to validate_presence_of(:title) } | ||
| it { is_expected.to validate_presence_of(:body) } | ||
| end | ||
|
|
||
| describe 'Uniqueness validations' do | ||
| # Testear validaciones de unicidad (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activemodel-matchers | ||
| let!(:subject) { FactoryBot.create(:post) } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alternativamente podemos usar subject { create(:post) } |
||
| it { is_expected.to validate_uniqueness_of(:title) } | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,31 +4,40 @@ | |
| describe 'Factory' do | ||
| it 'has a valid factory' do | ||
| # Testear que el factory definido es válido. | ||
| expect(FactoryBot.create(:user)).to be_valid | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Misma consideración para el test de factory del modelo |
||
| end | ||
| end | ||
|
|
||
| describe 'Associations' do | ||
| # Testear asociaciones (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activerecord-matchers | ||
| it { is_expected.to have_many(:posts).dependent(:destroy) } | ||
| end | ||
|
|
||
| describe 'Presence validations' do | ||
| # Testear validaciones de presencia (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activemodel-matchers | ||
| it { is_expected.to validate_presence_of(:email) } | ||
| it { is_expected.to validate_presence_of(:password) } | ||
| it { is_expected.to validate_presence_of(:role) } | ||
| end | ||
|
|
||
| describe 'Uniqueness validations' do | ||
| # Testear validaciones de unicidad (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activemodel-matchers | ||
| let!(:subject) { FactoryBot.create(:user) } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Misma consideración para el test similar del modelo |
||
| it { is_expected.to validate_uniqueness_of(:email) } | ||
| end | ||
|
|
||
| describe 'Length validations' do | ||
| # Testear validaciones de longitud (shoulda-matchers). | ||
| # https://github.com/thoughtbot/shoulda-matchers#activemodel-matchers | ||
| it { is_expected.to validate_length_of(:password).is_at_least(8) } | ||
| end | ||
|
|
||
| describe 'Enumeratives' do | ||
| # Testear definición de enumerativos (shoulda-matchers). | ||
| it { is_expected.to define_enum_for(:role).with([:admin, :regular])} | ||
| end | ||
|
|
||
| # Testear métodos de instancia y de clase como para el caso de cualquier | ||
|
|
@@ -37,5 +46,20 @@ | |
| # Testear funcionamiento de método. Podemos definir dos contexts: | ||
| # - 'when given value is different from password' | ||
| # - 'when given value is equal to password' | ||
| context 'when given value is different from password' do | ||
| let!(:subject) { FactoryBot.create(:user, password: 'password') } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tanto para este caso como para el del siguiente Podría ser de la siguiente forma: context 'when given value is different from password' do
subject { create(:user, password: 'password') }
...
end |
||
|
|
||
| it 'returns false' do | ||
| expect(subject.valid_password?('passw0rd')).to be false | ||
| end | ||
| end | ||
|
|
||
| context 'when given value is equal to password' do | ||
| let!(:subject) { FactoryBot.create(:user, password: 'password') } | ||
|
|
||
| it 'returns true' do | ||
| expect(subject.valid_password?('password')).to be true | ||
| end | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,79 +9,111 @@ | |
| # utilizarla. Es por eso que conviene usarla desde una variable con | ||
| # let!(:password) { SecureRandom.hex }. Al crear el usuario, | ||
| # en let!(:user) { ... }, usar esta variable. | ||
| EMPTY_EMAIL = 'El email no puede estar en blanco.'.freeze | ||
| EMPTY_PASSWORD = 'La contraseña no puede estar en blanco.'.freeze | ||
| USER_NOT_FOUND = 'El usuario no existe'.freeze | ||
| WRONG_PASSWORD = 'La contraseña es incorrecta'.freeze | ||
| EXTERNAL_VALIDATOR = 'El usuario ya no tiene cuota disponible'.freeze | ||
|
|
||
| let!(:password) { SecureRandom.hex } | ||
|
|
||
| let!(:user) { } # -- crear usuario con FactoryBot -- # | ||
| let!(:user) { FactoryBot.create(:user, password: password) } # -- crear usuario con FactoryBot -- # | ||
|
|
||
| describe '#call' do | ||
| context 'when user provided data is valid' do | ||
| before do | ||
| # Realizar un stub del ExternalValidator para que se ejecuta realmente | ||
| allow(ExternalValidator).to receive(:call).and_return(true) | ||
| end | ||
|
|
||
| subject do | ||
| described_class.new(email: user.email, password: password).call | ||
| end | ||
|
|
||
| it "update user's auth_token" do | ||
| skip 'Una vez que definan a user, este test va a fallar. ¿Por qué?' | ||
| expect { subject }.to change { user.auth_token } | ||
| # skip 'Una vez que definan a user, este test va a fallar. ¿Por qué?' | ||
| # Por dos cosas: primero, un usuario creado sin parámetros recibirá una password | ||
| # generada que nunca sabremos cuál es, por lo que hay que crearlo con una pass | ||
| # conocida (la definida al comienzo del test). Segundo, si no se recarga el | ||
| # registro desde la base de datos, el cambio no se verá reflejado. | ||
| expect { subject }.to change { user.reload.auth_token } | ||
| end | ||
|
|
||
| it 'returns the auth_token' do | ||
| skip 'Implementar' | ||
| expect(subject).to eq(user.reload.auth_token) | ||
| end | ||
| end | ||
|
|
||
| context 'when no email is provided' do | ||
| subject { } # implementar | ||
| subject { described_class.new(password: password) } | ||
|
|
||
| it 'returns false' do | ||
| skip 'Implementar' | ||
| expect(subject.call).to eq(false) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. En el ejemplo de arriba el |
||
| end | ||
|
|
||
| it 'returns EMPTY_EMAIL error with a reader' do | ||
| skip 'Implementar' | ||
| subject.call | ||
| expect(subject.error).to eq(EMPTY_EMAIL) | ||
| end | ||
| end | ||
|
|
||
| context 'when no password is provided' do | ||
| subject { } # implementar | ||
| subject { described_class.new(email: user.email) } | ||
|
|
||
| it 'returns false' do | ||
| skip 'Implementar' | ||
| expect(subject.call).to eq(false) | ||
| end | ||
|
|
||
| it 'returns EMPTY_PASSWORD error with a reader' do | ||
| skip 'Implementar' | ||
| subject.call | ||
| expect(subject.error).to eq(EMPTY_PASSWORD) | ||
| end | ||
| end | ||
|
|
||
| context 'when the email is incorrect' do | ||
| subject { } # implementar | ||
| subject { described_class.new(email: 'wrong@email.com', password: password) } | ||
|
|
||
| it 'returns false' do | ||
| skip 'Implementar' | ||
| expect(subject.call).to eq(false) | ||
| end | ||
|
|
||
| it 'returns USER_NOT_FOUND error with a reader' do | ||
| skip 'Implementar' | ||
| subject.call | ||
| expect(subject.error).to eq(USER_NOT_FOUND) | ||
| end | ||
| end | ||
|
|
||
| context 'when the password is incorrect' do | ||
| subject { } # implementar | ||
| subject { described_class.new(email: user.email, password: 'wrong_pass') } | ||
|
|
||
| it 'returns false' do | ||
| skip 'Implementar' | ||
| expect(subject.call).to eq(false) | ||
| end | ||
|
|
||
| it 'returns WRONG_PASSWORD error with a reader' do | ||
| skip 'Implementar' | ||
| subject.call | ||
| expect(subject.error).to eq(WRONG_PASSWORD) | ||
| end | ||
| end | ||
|
|
||
| # Definir un nuevo context para cuando la conexión | ||
| # con ExternalValidator falla. Acá los quiero ver... | ||
|
|
||
| context 'when ExternalValidator fails' do | ||
| subject { described_class.new(email: user.email, password: password) } | ||
|
|
||
| before do | ||
| allow(ExternalValidator).to receive(:call).and_return(false) | ||
| end | ||
|
|
||
| it 'returns false' do | ||
| expect(subject.call).to eq(false) | ||
| end | ||
|
|
||
| it 'returns WRONG_PASSWORD error with a reader' do | ||
| subject.call | ||
| expect(subject.error).to eq(EXTERNAL_VALIDATOR) | ||
| end | ||
| end | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Podemos aprovechar una configuración que agregamos en
spec/rails_helper.rbpor la cual no hace falta agregar elFactoryBot.a estos métodos.La línea en cuestión es la siguiente:
Además, pese a que el test pasa y está bien, podemos usar un
buildpara no persistir alPosten la base de datos (para mejorar la performance). De todas formas, elbuildpersiste aquellas asociaciones que tenga definido el factory, por lo cual podemos usar uno mejor:build_stubbed. En la próxima clase lo vemos.