finish implementing the authenticate command (+ specs) + refactor the other specs to match the new rspec syntax
did
committed Apr 08, 2015
commit 3538424449745978644e2e6df769f88198226984
Showing 10
changed files with
392 additions
and 63 deletions
.rspec
+0
-1
| @@ | @@ -1,2 +1 @@ |
| --colour | |
| - | --backtrace |
locomotive/wagon/commands/authenticate_command.rb b/lib/locomotive/wagon/commands/authenticate_command.rb
+63
-44
| @@ | @@ -1,3 +1,6 @@ |
| + | require 'locomotive/coal' |
| + | require 'netrc' |
| + | |
| module Locomotive::Wagon | |
| class AuthenticateCommand < Struct.new(:platform_url, :email, :password, :shell) | |
| @@ | @@ -7,54 +10,70 @@ module Locomotive::Wagon |
| end | |
| def authenticate | |
| - | puts "[auth] #{platform_url.inspect} / #{email.inspect} / #{password.inspect}" |
| - | puts 'YOUPI' |
| - | |
| - | # require 'locomotive/wagon/misc/hosting_api' |
| - | # require 'locomotive/coal' |
| - | # require 'netrc' |
| - | |
| - | # api_key = nil |
| - | # api = Locomotive::HostingAPI.new(email: email, password: password) |
| - | |
| - | # if api.authenticated? |
| - | # # existing account |
| - | # api_key = api.api_key |
| - | # shell.say "You have been successfully authenticated.", :green |
| - | # else |
| - | # # new account? |
| - | # shell.say "No account found for #{email} or invalid credentials", :yellow |
| - | |
| - | # if shell.yes?('Do you want to create a new account? [Y/N]') |
| - | # name = shell.ask 'What is your name?' |
| - | |
| - | # account = api.create_account(name: name, email: email, password: password) |
| - | |
| - | # if account.success? |
| - | # shell.say "Your account has been successfully created.", :green |
| - | # api_key = account['api_key'] |
| - | # else |
| - | # shell.say "We were unable to create your account, reason(s): #{account.error_messages.join(', ')}", :red |
| - | # end |
| - | # end |
| - | # end |
| - | |
| - | # if api_key |
| - | # # record the credentials |
| - | # netrc = Netrc.read |
| - | # netrc[api.domain_with_port] = email, api_key |
| - | # netrc.save |
| - | # else |
| - | # shell.say "We were unable to authenticate you on our platform.", :red |
| - | # end |
| - | |
| - | true |
| + | if api_key = fetch_api_key |
| + | record_credentials(api_key) |
| + | else |
| + | shell.say "Sorry, we were unable to authenticate you on \"#{platform_url}\"", :red |
| + | end |
| + | |
| + | !api_key.nil? |
| + | end |
| + | |
| + | def fetch_api_key |
| + | if my_account |
| + | my_account.api_key |
| + | else |
| + | shell.say "No account found for #{email} or invalid credentials", :yellow |
| + | |
| + | # shall we create a new account? |
| + | if shell.yes?('Do you want to create a new account? [Y/N]') |
| + | create_account |
| + | else |
| + | false |
| + | end |
| + | end |
| + | end |
| + | |
| + | def create_account |
| + | name = shell.ask 'What is your name?' |
| + | |
| + | begin |
| + | account = client.my_account.create(name: name, email: email, password: password) |
| + | shell.say "Your account has been successfully created.", :green |
| + | account.api_key |
| + | rescue Locomotive::Coal::Error => e |
| + | shell.say "We were unable to create your account, reason(s): #{e.message}", :red |
| + | false |
| + | end |
| + | end |
| + | |
| + | def record_credentials(api_key) |
| + | uri = URI(platform_url) |
| + | key = "#{uri.host}:#{uri.port}" |
| + | |
| + | netrc = Netrc.read |
| + | netrc[key] = email, api_key |
| + | netrc.save |
| end | |
| private | |
| - | def api_key_from_credentials |
| - | # client = Locomotive::Coal::Client.new('http://www.myengine.dev/locomotive/api', { email: <EMAIL>, api_key: <API KEY> }) |
| + | def my_account |
| + | begin |
| + | client.my_account.get |
| + | rescue Locomotive::Coal::UnauthorizedError |
| + | nil |
| + | end |
| + | end |
| + | |
| + | def client |
| + | @client ||= Locomotive::Coal::Client.new(api_url, email: email, password: password) |
| + | end |
| + | |
| + | def api_url |
| + | uri = URI(platform_url) |
| + | uri.merge!('/locomotive/api/v3') if uri.path == '/' || uri.path == '' |
| + | uri.to_s |
| end | |
| end | |
spec/fixtures/cassettes/authenticate.yml
+212
-0
| @@ | @@ -0,0 +1,212 @@ |
| + | --- |
| + | http_interactions: |
| + | - request: |
| + | method: post |
| + | uri: http://localhost:3000/locomotive/api/v3/tokens.json?email=john@doe.net&password=asimplepassword |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | Content-Length: |
| + | - '0' |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 401 |
| + | message: Unauthorized |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | X-Error-Detail: |
| + | - Invalid email or password. |
| + | Content-Length: |
| + | - '40' |
| + | Cache-Control: |
| + | - no-cache |
| + | X-Request-Id: |
| + | - fb0a7852-232e-4c8b-8ab3-456cfbab2078 |
| + | X-Runtime: |
| + | - '0.664468' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"message":"Invalid email or password."}' |
| + | http_version: |
| + | recorded_at: Wed, 08 Apr 2015 09:48:56 GMT |
| + | - request: |
| + | method: post |
| + | uri: http://localhost:3000/locomotive/api/v3/my_account.json?account%5Bemail%5D=john@doe.net&account%5Bname%5D=John&account%5Bpassword%5D=asimplepassword |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | Content-Length: |
| + | - '0' |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 201 |
| + | message: Created |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '411' |
| + | Etag: |
| + | - W/"d5f22e786ad106187b381c8d685a3e92" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - aee412b7-82df-4978-bd1f-f8f3314ead2d |
| + | X-Runtime: |
| + | - '0.061719' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"_id":"5524f98864696407ae100000","created_at":"2015-04-08T09:48:56Z","updated_at":"2015-04-08T09:48:56Z","name":"John","email":"john@doe.net","locale":"en","encrypted_password":"39f8358678144ef6715b9420a7a65706552272fb","password_salt":"sV9PWhfxDRy4b1pj6jLd","api_key":"8e5586fe34c5628d8e1ace2a8a750ae922ae2884","super_admin":false,"password":"asimplepassword","password_confirmation":null,"local_admin":false}' |
| + | http_version: |
| + | recorded_at: Wed, 08 Apr 2015 09:48:56 GMT |
| + | - request: |
| + | method: post |
| + | uri: http://localhost:3000/locomotive/api/v3/tokens.json?email=admin@locomotivecms.com&password=locomotive |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | Content-Length: |
| + | - '0' |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 201 |
| + | message: Created |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '32' |
| + | Etag: |
| + | - W/"333586de1d24c181814b7fd1fc093943" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - 7b0c6596-42b7-4466-94a3-5347b7fc9234 |
| + | X-Runtime: |
| + | - '0.019200' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"token":"by7uUTBWyg5LzGTfyykK"}' |
| + | http_version: |
| + | recorded_at: Wed, 08 Apr 2015 10:50:39 GMT |
| + | - request: |
| + | method: get |
| + | uri: http://localhost:3000/locomotive/api/v3/my_account.json?auth_token=by7uUTBWyg5LzGTfyykK |
| + | body: |
| + | encoding: US-ASCII |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | X-Locomotive-Account-Email: |
| + | - admin@locomotivecms.com |
| + | X-Locomotive-Account-Token: |
| + | - by7uUTBWyg5LzGTfyykK |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 200 |
| + | message: OK |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '409' |
| + | Etag: |
| + | - W/"de9362bbb5bdda2f08c588cb8bccc53e" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - 38706597-257a-401c-9769-c8b9d27c237a |
| + | X-Runtime: |
| + | - '0.036344' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"_id":"5524f99e646964184d000000","created_at":"2015-04-08T09:49:18Z","updated_at":"2015-04-08T09:49:18Z","name":"Admin","email":"admin@locomotivecms.com","locale":"en","encrypted_password":"a8f4f98e0c5a2578d750112f3df78338fa97e198","password_salt":"bQipQKDzKFhXnpXEYxoh","api_key":"d49cd50f6f0d2b163f48fc73cb249f0244c37074","super_admin":false,"password":null,"password_confirmation":null,"local_admin":true}' |
| + | http_version: |
| + | recorded_at: Wed, 08 Apr 2015 10:50:39 GMT |
| + | - request: |
| + | method: get |
| + | uri: http://localhost:3000/locomotive/api/v3/my_account.json?auth_token=by7uUTBWyg5LzGTfyykK |
| + | body: |
| + | encoding: US-ASCII |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | X-Locomotive-Account-Email: |
| + | - admin@locomotivecms.com |
| + | X-Locomotive-Account-Token: |
| + | - by7uUTBWyg5LzGTfyykK |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 200 |
| + | message: OK |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '409' |
| + | Etag: |
| + | - W/"de9362bbb5bdda2f08c588cb8bccc53e" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - 92225521-e544-4a18-a1b5-7f0c45177ad0 |
| + | X-Runtime: |
| + | - '0.017949' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"_id":"5524f99e646964184d000000","created_at":"2015-04-08T09:49:18Z","updated_at":"2015-04-08T09:49:18Z","name":"Admin","email":"admin@locomotivecms.com","locale":"en","encrypted_password":"a8f4f98e0c5a2578d750112f3df78338fa97e198","password_salt":"bQipQKDzKFhXnpXEYxoh","api_key":"d49cd50f6f0d2b163f48fc73cb249f0244c37074","super_admin":false,"password":null,"password_confirmation":null,"local_admin":true}' |
| + | http_version: |
| + | recorded_at: Wed, 08 Apr 2015 10:50:39 GMT |
| + | recorded_with: VCR 2.9.3 |
spec/integration/commands/authenticate_command_spec.rb
+43
-5
| @@ | @@ -2,20 +2,58 @@ |
| require File.dirname(__FILE__) + '/../integration_helper' | |
| require 'locomotive/wagon/commands/authenticate_command' | |
| + | require 'thor' |
| describe Locomotive::Wagon::AuthenticateCommand do | |
| - | let(:platform_url) {} |
| - | let(:email) {} |
| - | let(:password) {} |
| - | let(:shell) { nil } |
| + | before { VCR.insert_cassette 'authenticate', record: :new_episodes, match_requests_on: [:method, :query, :body] } |
| + | after { VCR.eject_cassette } |
| + | |
| + | let(:platform_url) { TEST_PLATFORM_URL } |
| + | let(:shell) { Thor::Shell::Color.new } |
| let(:command) { described_class.new(platform_url, email, password, shell) } | |
| describe '#authenticate' do | |
| + | let(:netrc) { instance_double('netrc', save: true) } |
| + | |
| + | before { allow(Netrc).to receive(:read).and_return(netrc) } |
| + | |
| subject { command.authenticate } | |
| - | it { is_expected.to eq(true) } |
| + | context 'new account' do |
| + | |
| + | let(:email) { 'john@doe.net' } |
| + | let(:password) { 'asimplepassword' } |
| + | |
| + | before do |
| + | allow_any_instance_of(Locomotive::Coal::Resource).to receive(:api_key).and_return('42') |
| + | allow(Thor::LineEditor).to receive(:readline).and_return('Y', 'John') |
| + | end |
| + | |
| + | it 'creates a new account and puts the auto-login information in the .netrc file' do |
| + | expect(netrc).to receive(:[]=).with('localhost:3000', ['john@doe.net', '42']) |
| + | is_expected.to eq(true) |
| + | end |
| + | |
| + | end |
| + | |
| + | context 'existing account' do |
| + | |
| + | let(:email) { TEST_API_EMAIL } |
| + | let(:password) { TEST_API_PASSWORD } |
| + | let(:netrc) { instance_double('netrc', save: true) } |
| + | |
| + | before do |
| + | allow_any_instance_of(Locomotive::Coal::Resource).to receive(:api_key).and_return('42') |
| + | end |
| + | |
| + | it 'only puts the auto-login information in the .netrc file' do |
| + | expect(netrc).to receive(:[]=).with('localhost:3000', ['admin@locomotivecms.com', '42']) |
| + | is_expected.to eq(true) |
| + | end |
| + | |
| + | end |
| end | |
spec/integration/generators/page_spec.rb
+7
-7
| @@ | @@ -25,7 +25,7 @@ describe 'Locomotive::Wagon::Generators::Page' do |
| let(:locales) { '' } | |
| - | it { lambda { subject }.should_not raise_error } |
| + | it { expect { subject }.not_to raise_error } |
| end | |
| @@ | @@ -36,11 +36,11 @@ describe 'Locomotive::Wagon::Generators::Page' do |
| before { subject } | |
| it 'creates the page in the FS' do | |
| - | File.exists?(page_path('new-page')).should be_true |
| + | expect(File).to exist(page_path('new-page')) |
| end | |
| it 'generates an header in YAML' do | |
| - | read_page('new-page').should include <<-EXPECTED |
| + | expect(read_page('new-page')).to include <<-EXPECTED |
| --- | |
| title: New-page | |
| EXPECTED | |
| @@ | @@ -51,11 +51,11 @@ EXPECTED |
| let(:locales) { 'en fr' } | |
| it 'creates the EN page in the FS' do | |
| - | File.exists?(page_path('new-page')).should be_true |
| + | expect(File).to exist(page_path('new-page')) |
| end | |
| it 'creates the FR page in the FS' do | |
| - | File.exists?(page_path('new-page.fr')).should be_true |
| + | expect(File).to exist(page_path('new-page.fr')) |
| end | |
| describe 'separated by a comma' do | |
| @@ | @@ -63,11 +63,11 @@ EXPECTED |
| let(:locales) { 'en,fr' } | |
| it 'creates the EN page in the FS' do | |
| - | File.exists?(page_path('new-page')).should be_true |
| + | expect(File).to exist(page_path('new-page')) |
| end | |
| it 'creates the FR page in the FS' do | |
| - | File.exists?(page_path('new-page.fr')).should be_true |
| + | expect(File).to exist(page_path('new-page.fr')) |
| end | |
| end | |
spec/integration/generators/relationship_spec.rb
+6
-6
| @@ | @@ -24,7 +24,7 @@ describe 'Locomotive::Wagon::Generators::Relationship' do |
| let(:source_slug) { 'authors' } | |
| - | it { lambda { subject }.should raise_error 'The authors content type does not exist' } |
| + | it { expect { subject }.to raise_error 'The authors content type does not exist' } |
| end | |
| @@ | @@ -32,7 +32,7 @@ describe 'Locomotive::Wagon::Generators::Relationship' do |
| let(:type) { 'has_one' } | |
| - | it { lambda { subject }.should raise_error 'has_one is an unknown relationship type' } |
| + | it { expect { subject }.to raise_error 'has_one is an unknown relationship type' } |
| end | |
| @@ | @@ -43,7 +43,7 @@ describe 'Locomotive::Wagon::Generators::Relationship' do |
| before { subject } | |
| it 'adds code to the source content type' do | |
| - | read_content_type(:comments).should include <<-EXPECTED |
| + | expect(read_content_type(:comments)).to include <<-EXPECTED |
| - post: | |
| label: Post | |
| hint: A description of the relationship for the editors | |
| @@ | @@ -53,7 +53,7 @@ EXPECTED |
| end | |
| it 'adds code the target content type' do | |
| - | read_content_type(:posts).should include <<-EXPECTED |
| + | expect(read_content_type(:posts)).to include <<-EXPECTED |
| - comments: | |
| label: Comments | |
| hint: A description of the relationship for the editors | |
| @@ | @@ -72,7 +72,7 @@ EXPECTED |
| let(:type) { 'many_to_many' } | |
| it 'adds code to the source content type' do | |
| - | read_content_type(:comments).should include <<-EXPECTED |
| + | expect(read_content_type(:comments)).to include <<-EXPECTED |
| - posts: | |
| label: Posts | |
| hint: A description of the relationship for the editors | |
| @@ | @@ -83,7 +83,7 @@ EXPECTED |
| end | |
| it 'adds code the target content type' do | |
| - | read_content_type(:posts).should include <<-EXPECTED |
| + | expect(read_content_type(:posts)).to include <<-EXPECTED |
| - comments: | |
| label: Comments | |
| hint: A description of the relationship for the editors | |
spec/support/api_settings.rb
+3
-0
| @@ | @@ -0,0 +1,3 @@ |
| + | TEST_PLATFORM_URL = 'http://localhost:3000'.freeze |
| + | TEST_API_EMAIL = 'admin@locomotivecms.com'.freeze |
| + | TEST_API_PASSWORD = 'locomotive'.freeze |
spec/support/pry.rb
+4
-0
| @@ | @@ -0,0 +1,4 @@ |
| + | begin |
| + | require 'pry' |
| + | rescue LoadError |
| + | end |
spec/support/vcr.rb
+10
-0
| @@ | @@ -0,0 +1,10 @@ |
| + | require 'webmock/rspec' |
| + | require 'vcr' |
| + | |
| + | # VCR config |
| + | VCR.configure do |c| |
| + | c.cassette_library_dir = 'spec/fixtures/cassettes' |
| + | c.hook_into :webmock |
| + | c.ignore_hosts 'codeclimate.com' |
| + | c.configure_rspec_metadata! |
| + | end |
spec/unit/commands/authenticate_command_spec.rb
+44
-0
| @@ | @@ -0,0 +1,44 @@ |
| + | # encoding: utf-8 |
| + | |
| + | require 'spec_helper' |
| + | require 'locomotive/wagon/commands/authenticate_command' |
| + | |
| + | describe Locomotive::Wagon::AuthenticateCommand do |
| + | |
| + | let(:platform_url) { nil } |
| + | let(:email) { nil } |
| + | let(:password) { nil } |
| + | let(:shell) { nil } |
| + | let(:command) { described_class.new(platform_url, email, password, shell) } |
| + | |
| + | describe '#api_url' do |
| + | |
| + | subject { command.send(:api_url) } |
| + | |
| + | context 'naked domain' do |
| + | let(:platform_url) { 'http://www.myengine.com:3000/' } |
| + | it { is_expected.to eq('http://www.myengine.com:3000/locomotive/api/v3') } |
| + | end |
| + | |
| + | context 'localhost' do |
| + | let(:platform_url) { 'http://localhost:3000' } |
| + | it { is_expected.to eq('http://localhost:3000/locomotive/api/v3') } |
| + | end |
| + | |
| + | context 'including the official route to the API' do |
| + | |
| + | let(:platform_url) { 'http://www.myengine.com:3000/locomotive/api/v3' } |
| + | it { is_expected.to eq('http://www.myengine.com:3000/locomotive/api') } |
| + | |
| + | end |
| + | |
| + | context 'including another route to the API' do |
| + | |
| + | let(:platform_url) { 'http://www.myengine.com/admin/api' } |
| + | it { is_expected.to eq('http://www.myengine.com/admin/api') } |
| + | |
| + | end |
| + | |
| + | end |
| + | |
| + | end |