diff --git a/Gemfile b/Gemfile index 8f35f2f..a17aa63 100644 --- a/Gemfile +++ b/Gemfile @@ -40,6 +40,9 @@ group :development, :test do end group :development do - gem 'web-console' gem 'annotate' + gem 'rspec' + gem 'rspec-rails' + gem "factory_girl_rails", "~> 4.0" + gem "database_cleaner" end diff --git a/Gemfile.lock b/Gemfile.lock index b5faef1..a86f3da 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,12 +88,18 @@ GEM hashie (~> 3.0) httparty (~> 0.10) json (~> 1.0) - debug_inspector (0.0.2) + database_cleaner (1.5.3) deep_merge (1.1.1) + diff-lcs (1.3) dynamic_form (1.1.4) encrypto_signo (1.0.0) erubis (2.7.0) execjs (2.7.0) + factory_girl (4.8.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) + railties (>= 3.0.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) foreman (0.82.0) @@ -168,6 +174,27 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rake (11.3.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.4) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-mocks (3.5.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.5.0) + rspec-rails (3.5.2) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) sass (3.4.22) sass-rails (5.0.6) railties (>= 4.0.0, < 6) @@ -197,11 +224,6 @@ GEM uglifier (3.0.2) execjs (>= 0.3.0, < 3) useragent (0.16.8) - web-console (3.3.1) - actionview (>= 5.0) - activemodel (>= 5.0) - debug_inspector - railties (>= 5.0) websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) @@ -223,8 +245,10 @@ DEPENDENCIES clockwork coffee-rails (~> 4.2) createsend (~> 4.0) + database_cleaner dynamic_form encrypto_signo + factory_girl_rails (~> 4.0) foreman gelf haml @@ -242,12 +266,13 @@ DEPENDENCIES nio4r puma (~> 3.0) rails (= 5.0.2) + rspec + rspec-rails sass-rails (~> 5.0) secure_headers sentry-raven turbolinks (~> 5) uglifier (>= 1.3.0) - web-console BUNDLED WITH 1.14.6 diff --git a/spec/app/models/organization_spec.rb b/spec/app/models/organization_spec.rb new file mode 100644 index 0000000..7e9f814 --- /dev/null +++ b/spec/app/models/organization_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +describe Organization do + + context "model" do + subject(:organization) { create(:organization) } + + it "should have a UUID" do + expect(organization.uuid).to be_a String + expect(organization.uuid.length).to eq 36 + end + end + +end diff --git a/spec/app/models/user_spec.rb b/spec/app/models/user_spec.rb new file mode 100644 index 0000000..5b365ef --- /dev/null +++ b/spec/app/models/user_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +describe User do + + context "model" do + subject(:user) { create(:user) } + + it "should have a UUID" do + expect(user.uuid).to be_a String + expect(user.uuid.length).to eq 36 + end + end + + context ".authenticate" do + it "should not authenticate users with invalid emails" do + expect { User.authenticate('nothing@nothing.com', 'hello') }.to raise_error(Postal::Errors::AuthenticationError) do |e| + expect(e.error).to eq 'InvalidEmailAddress' + end + end + + it "should not authenticate users with invalid passwords" do + user = create(:user) + expect { User.authenticate(user.email_address, 'hello') }.to raise_error(Postal::Errors::AuthenticationError) do |e| + expect(e.error).to eq 'InvalidPassword' + end + end + + it "should authenticate valid users" do + user = create(:user) + auth_user = nil + expect { auth_user = User.authenticate(user.email_address, 'passw0rd') }.to_not raise_error + expect(auth_user).to eq user + end + end + +end diff --git a/spec/config/fast_server.cert b/spec/config/fast_server.cert new file mode 100644 index 0000000..dd04406 --- /dev/null +++ b/spec/config/fast_server.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIBADANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJHQjEQ +MA4GA1UECgwHRGVmYXVsdDEQMA4GA1UECwwHRGVmYXVsdDEQMA4GA1UEAwwHZGVm +YXVsdDAeFw0xNzA1MDgxMzM2MDBaFw0yNzA1MDYxMzM2MDBaMEMxCzAJBgNVBAYT +AkdCMRAwDgYDVQQKDAdEZWZhdWx0MRAwDgYDVQQLDAdEZWZhdWx0MRAwDgYDVQQD +DAdkZWZhdWx0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA18zeoKrM +m9dlvu5l3k57ocbtB5PKm1fWcUg6XSl4Wtk+Tf9TQx8wuwjEwRvqGdgP9KWtazdW +2eN9z9lmHd3GnC3inmw7UcSkGkeEUQrwbkjihoKAgEpLBNmJoaMWatbdvcgkBvKs +WUg8J4g7yRdX5jWGa0f9Ok0jfYYNQwPZ1iugD9ayBcovvvCX3Xm2oeKCjBeqjejS +wlv1KdYmHQ2AduIx/s9+vxdWtnllqbJ+v60+WqVzwxxJWE4P+kJb+vNbgZ01xFGX +vljT/DzosDVR4OYBI5IumOYwuDz91FY/K9Yi+7QKfI7tq7y9ZKYJQSqZxpnOw2gn +qZuC/ReCBw/wlwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDHEE35sCpFivcVFoVC +Y7q7u2PhHofjhi1pqPRnZOtiVIYr9xXAe+pTlcv+K9Kc0IenaADEnra0wM0i5imp +b3ObQ0CyRCyKKVbU8t74RYo6K3klZnru61YWte0MdsBFYwYTSAZzK9l+5EICyX1l +KYcXIGgdZJddU7GQ4EASh1BTB7qDQ7GOQRlY1uTyVd+74WdfUez8A6FgRGnx/RRD +0u/l+K8+JIaqgSU1+ZlxPw+KpHUPJhoTikZapyKgaINBoLfyuVd4svf4HsJzjwcj +w8CL5sPAdN8iLeDVkHemX/Tcl4CdWVBodb3Wiqcq7DgTVY2alDNMjCo9YvzuAPVL +99W3 +-----END CERTIFICATE----- diff --git a/spec/config/fast_server.key b/spec/config/fast_server.key new file mode 100644 index 0000000..c9f1691 --- /dev/null +++ b/spec/config/fast_server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA18zeoKrMm9dlvu5l3k57ocbtB5PKm1fWcUg6XSl4Wtk+Tf9T +Qx8wuwjEwRvqGdgP9KWtazdW2eN9z9lmHd3GnC3inmw7UcSkGkeEUQrwbkjihoKA +gEpLBNmJoaMWatbdvcgkBvKsWUg8J4g7yRdX5jWGa0f9Ok0jfYYNQwPZ1iugD9ay +BcovvvCX3Xm2oeKCjBeqjejSwlv1KdYmHQ2AduIx/s9+vxdWtnllqbJ+v60+WqVz +wxxJWE4P+kJb+vNbgZ01xFGXvljT/DzosDVR4OYBI5IumOYwuDz91FY/K9Yi+7QK +fI7tq7y9ZKYJQSqZxpnOw2gnqZuC/ReCBw/wlwIDAQABAoIBADj2T/GTBA1Czw2V ++fezObkbPCfa4AkfJ3Chgx5iOu2oGGUYN08pZYCJMP5UMvf9a0DFlsANTHSZMvVx +Sh4qEynYhtAQe5v6zuJM7GVEAPDrdjfRLMAwXBr8nPK4jMtIyiE1OiVHWyz5/z7k +G/vZmI8go8mfp/0CrZKNluSQmKiKQPS1rkDXiVBkF7ifFO6j34IjnihgWsc2W/CL +Wvehfe6RmCK+KfEDREpTSw2/VFuqn4j2FYK8PpweAAJwVWtGGuDB9QSPkKT8WSgK +yZFVW3d+aouBfduHKcja/ccmrGhmBhni80lTjUxakzK7Hw4SKmNTV1FPNfJsE1ez +zPqs8tkCgYEA/a0yBSFuwaLGuwpmchjH32bcq+TR7qNaCAfv07pL7aQXd7nSjDuU +Lz/ohveubizhdsl32kJQBuPNuYeLXxhsulxCumS3tfN31/J4IYU2BXNB20mhKSkP +APneQfc5SS2T3cOdd5hUgsFlSAU2KtWC/qSrXSpR0kEyCGLbOrctJnUCgYEA2cbd +R8QOFzMBpz5Dl3DtFc3qzAyw2lS1m6Nlus3zMxNwX0Diaw9eyiZKOxjNBwN8uQa6 +hOf944go2MmEmdRILWiV7lXt1ML5/fD/Kf2n15TI+xl4maETNGtxPMlZs158xsRR +g4qUvRufZp03V3Cu1e9HrypElw9D6K1lv7DvkVsCgYAvxM53gt0tX26WyBWUhLAW +lHMXd2ZEzsPkYUI7F4i2vkChDf/k4k88OoeZ6sgQ/SiTyspj8jrJoVobBrgq9xl6 +WmdCXDbv72Hw6zrN7RzIF/Udyxaq/o1RvLuqplhGPGvsxapAXBIF8U8WKc0ScdRS +CUYvrAluU1KNm7f2rYm2BQKBgEEliUqPrrtn6cWzDZs/D91m9SdHYJxfnNhLQAJq +26ba2NHV4iWuumd0nt4g5CyF8YiUJ7XchInNUJLRbdZqt5DF6ZwbnoL4NLqvnlVc +aRpHivv6uaYTlmAnB//sJ+ZNjLwVPGFCUo5jtgKHY2fH8LVU2DfhSBV8Xo87V+XJ +M1FjAoGAEIkg3M/rRku0SMaT0LofchABhW1RXYwBUqUsb4TUF2fdm5iESRg1wP2g +kvMe6394KFseK4/OG2SZf69bMeUbdwi+LA8krIKj4CFhgjdG0Xs4j/POWqCExNDC +pAwJbJcn3o/RSGwIl4fO0o0JwJe8//269pklRQ5CrZt3+LSxy/E= +-----END RSA PRIVATE KEY----- diff --git a/spec/config/lets_encrypt.pem b/spec/config/lets_encrypt.pem new file mode 100644 index 0000000..a356326 --- /dev/null +++ b/spec/config/lets_encrypt.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvbtEZ/TZPqMZmbNJH8trasoYkuzkLSsiGBAmKWDw/V3xVkMX +JSY+MYRv6NlKKXZg6SYoZVU8DvxCvUQstJDU+CYHUfQtBthQaWGzh5XdAmjTtb+6 +UTyI5UtrwbzWHPgUrwHtN/QpBGsan6A2ASbP5R+HxuUTjzvkMc6otyvdjO+86jSt +mFxGoJXmQSyyGATjMBnhTCPUNjqOI13qgwWgh0beCY2+m78URbJ60NHg+UOBOIUx +Z1e0jY0YCRxb+CuTiBgbBCS3JNlze7JTwLXDgXunV2OPUBA5qd2+4eGsaSzeGxMi +HZaat/Pcn11PEZBEYMuEr2bGb9ANxSzzN4+NKwIDAQABAoIBAQCTH1qdDfVDp++b +CrZCTFfgOBQ0IjORfufyJtugrIZSwfz5Og8BhJUnip3Ivm3Olvfw8uDSKvTmXeBW +qT3NSp2KStrURvZ/X0+DV/qBwcjeLHE2dxTAF6PDwecuFQMm9Yv8ZQ8Qm2kO/wpn +CzG1VOZSsk90AIBZSkTaBnk3iHFE7e66Ru3AVNdFOkn45W459IeZRsh7FnrLG4r4 +3ko/07+e1Eb82mgnan3iyMrHYW+PACzcP/GjIJ2Xh3e39IexXeEsp8qkAbUsv0xx +lt1QL22Xi6gRc2GMv+GNIi84FfnJ6P/ju3dVuHiShFncM2zM5cc9snOHaayePyT6 +HVVySp0JAoGBAPDJmdd/01W91KcmzZ59N7+uhSMhfvxvZE/fpq1dEwtTIREUW6sL +J7yfJA9KSm+SsOpy6NOG/caWACz+lPZX67Ju4eIO6aiIV5Tj3g8SvdMNvj4a6gfz +lMg7eDtiuk4AeFQroPqmo+IPMd2ia4N6OOIOt5XzaoTHl7wdIrMTFbb/AoGBAMm3 +6E7DMR/dcUpe9bOrOtPA8MtGVxhMhR6AR7fpQtFRcjmpOnQnio5EASvOM4tAN/H0 +DB5tyuQ9JzHmvH5tENdwXZLnPBvnKl4OobZqaX7SWQA1inb71fr1pjp8rzceABjZ +pFJ3/esN5VJw+f3DTjw8HbBkHZBtvbNNPin/5LXVAoGBAKq698dSjoHcQR1oKSG4 +vb+/Og3H4WeSgDkWZvPD7A36mpamrbzhAwL+gC4LSi5EgActBSN/MxANKgC9Xtgx +TSFO+AE2+7yRODCNRdXAPzKYKw2UPd73esZjTIQnI9zM/oUIDnPLlqZiicQSN1OZ +ZR38u3WqjBur/k3XBtScsqf3AoGAGA3VJudByWH3q32tYPJvPmcIj8Tgh+ZADYYQ +h07Kh/llXJjgfo9kh1h2p0mcfeN3iGOoukwvYI4mSV4RZiYNVxNwJR9r3IvxUmv+ +Pqlr0RK2SD8aNtwLBTUb0Gej4TeznUL+xFLItanfibgtJ2SNxMMKa0lU+S8M6v+w +BQQdus0CgYBu+21HRlcgTr47TtNlCUP1fCPgkpJXj72P8WBVvJnVi8JjIX++PtcR +QwxJpPxX9MsQiD/2oziEb/pXDrNytuezDwGsNrRmrVpgorL3lXaLi571AjY7urrq +/0ZT4OPIP+Em1F9ugh+u/XxOedLwmcwzz3VmKCYfSJzcQQ3jU8njjA== +-----END RSA PRIVATE KEY----- diff --git a/spec/config/postal.yml b/spec/config/postal.yml new file mode 100644 index 0000000..c8acfb3 --- /dev/null +++ b/spec/config/postal.yml @@ -0,0 +1,49 @@ +web: + host: postal.example.com + protocol: https + +fast_server: + enabled: false + bind_address: + +general: + use_ip_pools: false + +main_db: + host: 127.0.0.1 + username: root + password: + database: postal_test + +message_db: + host: 127.0.0.1 + username: root + password: + prefix: postal_test + +rabbitmq: + host: 127.0.0.1 + username: guest + password: guest + vhost: + +dns: + mx_records: + - mx.postal.example.com + smtp_server_hostname: postal.example.com + spf_include: spf.postal.example.com + return_path: rp.postal.example.com + route_domain: routes.postal.example.com + track_domain: track.postal.example.com + +smtp: + host: 127.0.0.1 + port: 2525 + username: + password: + from_name: Postal + from_address: postal@yourdomain.com + +rails: + environment: test + secret_key: c3ed0d4723a5d08f8cdb03571ddec8366da74db114f5419187343632e9c0c0110da177c0cf79e6605a4ccfff6f2d9e716d99b6525401ad9c181466b57a1901ffeacb023d05c9ce69838dd826f54e29c846e9e3231697c6749648a9c706df20b50bec1d7ef81b0dbd91410b314c44a4c0cf74741df2de9f5bb144026a6f99954c diff --git a/spec/config/signing.key b/spec/config/signing.key new file mode 100644 index 0000000..02a4261 --- /dev/null +++ b/spec/config/signing.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQC/Af1LGsg/xdpdLjIaxVhQm3qjKNrWQh+divUV9eLCFta/s5Qs +Axs2+jf40IjpORn9507mtFwNPcauNyfUH7/bNxfAb65L3c2GWxVu/Cp4tg9yYVpz +9vvNEsQh/AWrhjrFcc1DpyWUFeY80ASBHGAJQe1y+iFMQVQAJzXcyUNwJwIDAQAB +AoGAMcDj6J9WT/5KjgENfhmvknedb0iiEDNzJsdeZdUBtwrZ719oljpM6XouADrZ +nt6H3bJVxBRw8eYIjbLCRifrAkv0dmFOPbrZBd8q7bFSRlyc5OeD6aKLW95szrpx +AnAEPb1ojfvOAyAA2407GZjuPQrRjncT1tZx56xwIU2n0DECQQD6b1wtad+akE0k +ry54Wd/iaaM/pguh2dUyphDrCKzQ3fFeLw0WPe/j+f5hLcXaWNJWiOwa+MPUpEnE +B1SCA7O/AkEAw0CRZp+smFD2clPDiGtNbXW1ZF2TzLZhHzntYv3KpCqzJna8vx+I +gwXCUrnleMRJdDV+mWvlptDDJOAi2Oe9mQJBAMjTwpyceXbOXz6ayO40TGiZhBNH +ia56LBDYwVppc4RvZt67Zog+lQBB+q9dcHtfnRVN6eDbOtdsA8eShT9ZzqsCQQCe +uTJ6FnucJtTxA58EmxYKUZHv0RKBbBFv7QtJWb8NzZhtQEEXrW6v9FKQJYahsg90 +ZLhRyCCch0DcDUjGwzyhAkEAh8CC37iLLBCHpxxrsQ/l+/c9TX0c+PbcZSRrZ54X +l3yZis66MmhaOaeKVQ7rY+hS9/v+PHBY4HCpCkqjYV/bIQ== +-----END RSA PRIVATE KEY----- diff --git a/spec/factories/organization_factory.rb b/spec/factories/organization_factory.rb new file mode 100644 index 0000000..fd130c6 --- /dev/null +++ b/spec/factories/organization_factory.rb @@ -0,0 +1,32 @@ +# == Schema Information +# +# Table name: organizations +# +# id :integer not null, primary key +# uuid :string(255) +# name :string(255) +# permalink :string(255) +# time_zone :string(255) +# created_at :datetime +# updated_at :datetime +# ip_pool_id :integer +# owner_id :integer +# deleted_at :datetime +# suspended_at :datetime +# suspension_reason :string(255) +# +# Indexes +# +# index_organizations_on_permalink (permalink) +# index_organizations_on_uuid (uuid) +# + +FactoryGirl.define do + + factory :organization do + name "Acme Inc" + sequence(:permalink) { |n| "org#{n}" } + association :owner, :factory => :user + end + +end diff --git a/spec/factories/user_factory.rb b/spec/factories/user_factory.rb new file mode 100644 index 0000000..cdde493 --- /dev/null +++ b/spec/factories/user_factory.rb @@ -0,0 +1,36 @@ +# == Schema Information +# +# Table name: users +# +# id :integer not null, primary key +# uuid :string(255) +# first_name :string(255) +# last_name :string(255) +# email_address :string(255) +# password_digest :string(255) +# time_zone :string(255) +# email_verification_token :string(255) +# email_verified_at :datetime +# created_at :datetime +# updated_at :datetime +# password_reset_token :string(255) +# password_reset_token_valid_until :datetime +# admin :boolean default(FALSE) +# +# Indexes +# +# index_users_on_email_address (email_address) +# index_users_on_uuid (uuid) +# + +FactoryGirl.define do + + factory :user do + first_name "John" + last_name "Doe" + password "passw0rd" + email_verified_at Time.now + sequence(:email_address) { |n| "user#{n}@example.com" } + end + +end diff --git a/spec/lib/postal/message_parser_spec.rb b/spec/lib/postal/message_parser_spec.rb new file mode 100644 index 0000000..25e240a --- /dev/null +++ b/spec/lib/postal/message_parser_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +describe Postal::MessageParser do + it "should be true" do + expect(Rails.env).to eq 'test' + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..b9f2b47 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,26 @@ +ENV['POSTAL_CONFIG_ROOT'] = File.expand_path('../config', __FILE__) + +require File.expand_path('../../config/environment', __FILE__) +require 'rspec/rails' +require 'spec_helper' +require 'factory_girl' +require 'database_cleaner' + +FACTORIES_EXCLUDED_FROM_LINT = [] +Dir[File.expand_path('../factories/*.rb', __FILE__)].each { |f| require f } + +ActiveRecord::Migration.maintain_test_schema! +RSpec.configure do |config| + config.use_transactional_fixtures = true + config.infer_spec_type_from_file_location! + config.include FactoryGirl::Syntax::Methods + + config.before(:suite) do + begin + DatabaseCleaner.start + FactoryGirl.lint(FactoryGirl.factories.select { |f| !FACTORIES_EXCLUDED_FROM_LINT.include?(f.name.to_sym) }) + ensure + DatabaseCleaner.clean + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..a4e3954 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,11 @@ +RSpec.configure do |config| + config.color = true + + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end +end