alchemy_crm 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +22 -0
- data/.travis.yml +12 -0
- data/Gemfile +21 -0
- data/Guardfile +13 -0
- data/LICENSE +24 -0
- data/README.md +82 -0
- data/Rakefile +27 -0
- data/alchemy_crm.gemspec +31 -0
- data/app/assets/images/.DS_Store +0 -0
- data/app/assets/images/alchemy_crm/.DS_Store +0 -0
- data/app/assets/images/alchemy_crm/contact-icons.png +0 -0
- data/app/assets/images/alchemy_crm/fill_content.gif +0 -0
- data/app/assets/images/alchemy_crm/group-icons.png +0 -0
- data/app/assets/images/alchemy_crm/mailing-icons.png +0 -0
- data/app/assets/images/alchemy_crm/module_icon.png +0 -0
- data/app/assets/images/alchemy_crm/newsletter-icons.png +0 -0
- data/app/assets/images/alchemy_crm/statistic.png +0 -0
- data/app/assets/images/alchemy_crm/tag-icons.png +0 -0
- data/app/assets/javascripts/alchemy_crm/alchemy_crm.base.js +65 -0
- data/app/assets/javascripts/alchemy_crm/scripts.js +2 -0
- data/app/assets/stylesheets/alchemy_crm/base.css.scss +473 -0
- data/app/assets/stylesheets/alchemy_crm/styles.css +3 -0
- data/app/controllers/alchemy_crm/admin/base_controller.rb +7 -0
- data/app/controllers/alchemy_crm/admin/contact_groups_controller.rb +23 -0
- data/app/controllers/alchemy_crm/admin/contacts_controller.rb +112 -0
- data/app/controllers/alchemy_crm/admin/deliveries_controller.rb +80 -0
- data/app/controllers/alchemy_crm/admin/elements_controller_extension.rb +32 -0
- data/app/controllers/alchemy_crm/admin/mailings_controller.rb +47 -0
- data/app/controllers/alchemy_crm/admin/newsletters_controller.rb +24 -0
- data/app/controllers/alchemy_crm/admin/tags_controller.rb +62 -0
- data/app/controllers/alchemy_crm/base_controller.rb +5 -0
- data/app/controllers/alchemy_crm/contacts_controller.rb +103 -0
- data/app/controllers/alchemy_crm/mailings_controller.rb +20 -0
- data/app/controllers/alchemy_crm/recipients_controller.rb +35 -0
- data/app/controllers/alchemy_crm/subscriptions_controller.rb +57 -0
- data/app/helpers/alchemy/pages_helper_extension.rb +18 -0
- data/app/helpers/alchemy_crm/admin/base_helper.rb +12 -0
- data/app/helpers/alchemy_crm/mailings_helper.rb +190 -0
- data/app/mailers/alchemy_crm/bounce_receiver.rb +13 -0
- data/app/mailers/alchemy_crm/contacts_mailer.rb +26 -0
- data/app/mailers/alchemy_crm/mailings_mailer.rb +48 -0
- data/app/mailers/alchemy_crm/subscriptions_mailer.rb +17 -0
- data/app/models/alchemy/essence_element_teaser.rb +19 -0
- data/app/models/alchemy_crm/contact.rb +264 -0
- data/app/models/alchemy_crm/contact_group.rb +26 -0
- data/app/models/alchemy_crm/contact_group_filter.rb +26 -0
- data/app/models/alchemy_crm/delivery.rb +57 -0
- data/app/models/alchemy_crm/element_extension.rb +28 -0
- data/app/models/alchemy_crm/mailing.rb +93 -0
- data/app/models/alchemy_crm/newsletter.rb +48 -0
- data/app/models/alchemy_crm/reaction.rb +9 -0
- data/app/models/alchemy_crm/recipient.rb +48 -0
- data/app/models/alchemy_crm/subscription.rb +8 -0
- data/app/views/alchemy/admin/elements/_view_not_found.text.erb +0 -0
- data/app/views/alchemy/admin/elements/fill.js.erb +13 -0
- data/app/views/alchemy/admin/elements/link.js.erb +1 -0
- data/app/views/alchemy/elements/_newsletter_article_editor.html.erb +4 -0
- data/app/views/alchemy/elements/_newsletter_article_view.html.erb +16 -0
- data/app/views/alchemy/elements/_newsletter_article_view.text.erb +5 -0
- data/app/views/alchemy/elements/_newsletter_greeting_editor.html.erb +3 -0
- data/app/views/alchemy/elements/_newsletter_greeting_view.html.erb +11 -0
- data/app/views/alchemy/elements/_newsletter_greeting_view.text.erb +6 -0
- data/app/views/alchemy/elements/_newsletter_signout_form_editor.html.erb +3 -0
- data/app/views/alchemy/elements/_newsletter_signout_form_view.html.erb +32 -0
- data/app/views/alchemy/elements/_newsletter_signout_mail_editor.html.erb +4 -0
- data/app/views/alchemy/elements/_newsletter_signup_form_editor.html.erb +6 -0
- data/app/views/alchemy/elements/_newsletter_signup_form_view.html.erb +78 -0
- data/app/views/alchemy/elements/_newsletter_signup_mail_editor.html.erb +4 -0
- data/app/views/alchemy/essences/_essence_date_view.text.erb +3 -0
- data/app/views/alchemy/essences/_essence_element_teaser_editor.html.erb +31 -0
- data/app/views/alchemy/essences/_essence_element_teaser_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_element_teaser_view.text.erb +3 -0
- data/app/views/alchemy/essences/_essence_richtext_view.text.erb +1 -0
- data/app/views/alchemy/essences/_essence_text_view.text.erb +1 -0
- data/app/views/alchemy/newsletter_layouts/_standard.html.erb +39 -0
- data/app/views/alchemy/newsletter_layouts/_standard.text.erb +5 -0
- data/app/views/alchemy_crm/admin/contact_groups/_contact_group.html.erb +32 -0
- data/app/views/alchemy_crm/admin/contact_groups/_filter.html.erb +30 -0
- data/app/views/alchemy_crm/admin/contact_groups/_form.html.erb +47 -0
- data/app/views/alchemy_crm/admin/contact_groups/_tag.html.erb +6 -0
- data/app/views/alchemy_crm/admin/contact_groups/add_filter.js.erb +9 -0
- data/app/views/alchemy_crm/admin/contact_groups/destroy.rjs +1 -0
- data/app/views/alchemy_crm/admin/contact_groups/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contact_groups/index.html.erb +41 -0
- data/app/views/alchemy_crm/admin/contact_groups/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contacts/_contact.html.erb +44 -0
- data/app/views/alchemy_crm/admin/contacts/_form.html.erb +86 -0
- data/app/views/alchemy_crm/admin/contacts/destroy.rjs +1 -0
- data/app/views/alchemy_crm/admin/contacts/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contacts/import.html.erb +33 -0
- data/app/views/alchemy_crm/admin/contacts/import.js.erb +2 -0
- data/app/views/alchemy_crm/admin/contacts/index.html.erb +51 -0
- data/app/views/alchemy_crm/admin/contacts/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contacts/vcf_import_result.html.erb +49 -0
- data/app/views/alchemy_crm/admin/deliveries/_delivery.html.erb +41 -0
- data/app/views/alchemy_crm/admin/deliveries/_form.html.erb +65 -0
- data/app/views/alchemy_crm/admin/deliveries/_recipient.html.erb +40 -0
- data/app/views/alchemy_crm/admin/deliveries/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/deliveries/index.html.erb +29 -0
- data/app/views/alchemy_crm/admin/deliveries/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/deliveries/show.html.erb +66 -0
- data/app/views/alchemy_crm/admin/elements/link.rjs +4 -0
- data/app/views/alchemy_crm/admin/elements/teasables.html.erb +57 -0
- data/app/views/alchemy_crm/admin/mailings/_form.html.erb +43 -0
- data/app/views/alchemy_crm/admin/mailings/_mailing.html.erb +75 -0
- data/app/views/alchemy_crm/admin/mailings/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/mailings/edit_content.html.erb +194 -0
- data/app/views/alchemy_crm/admin/mailings/import_result.html.erb +37 -0
- data/app/views/alchemy_crm/admin/mailings/index.html.erb +39 -0
- data/app/views/alchemy_crm/admin/mailings/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/mailings/show.html.erb +1 -0
- data/app/views/alchemy_crm/admin/mailings/show.text.erb +1 -0
- data/app/views/alchemy_crm/admin/newsletters/_form.html.erb +54 -0
- data/app/views/alchemy_crm/admin/newsletters/_newsletter.html.erb +42 -0
- data/app/views/alchemy_crm/admin/newsletters/_tag_with_radiobutton.html.erb +7 -0
- data/app/views/alchemy_crm/admin/newsletters/destroy.rjs +1 -0
- data/app/views/alchemy_crm/admin/newsletters/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/newsletters/index.html.erb +42 -0
- data/app/views/alchemy_crm/admin/newsletters/new.html.erb +10 -0
- data/app/views/alchemy_crm/admin/tags/_radio_tag.html.erb +6 -0
- data/app/views/alchemy_crm/admin/tags/_tag.html.erb +32 -0
- data/app/views/alchemy_crm/admin/tags/edit.html.erb +40 -0
- data/app/views/alchemy_crm/admin/tags/index.html.erb +35 -0
- data/app/views/alchemy_crm/admin/tags/new.html.erb +16 -0
- data/app/views/alchemy_crm/contacts_mailer/signout_mail.html.erb +8 -0
- data/app/views/alchemy_crm/contacts_mailer/signout_mail.text.erb +4 -0
- data/app/views/alchemy_crm/contacts_mailer/signup_mail.html.erb +11 -0
- data/app/views/alchemy_crm/contacts_mailer/signup_mail.text.erb +4 -0
- data/app/views/alchemy_crm/mailings/show.html.erb +1 -0
- data/app/views/alchemy_crm/mailings_mailer/verification_mail.html.erb +11 -0
- data/app/views/alchemy_crm/subscriptions/index.html.erb +23 -0
- data/app/views/alchemy_crm/subscriptions_mailer/overview_mail.html.erb +27 -0
- data/app/views/alchemy_crm/subscriptions_mailer/overview_mail.text.erb +19 -0
- data/app/views/csv_magic/import_errors.html.erb +44 -0
- data/app/views/csv_magic/mapper.html.erb +62 -0
- data/app/views/layouts/alchemy_crm/mailings.html.erb +212 -0
- data/app/views/layouts/alchemy_crm/mailings.text.erb +3 -0
- data/config/alchemy_crm.config.yml +21 -0
- data/config/authorization_rules.rb +37 -0
- data/config/initializers/assets.rb +4 -0
- data/config/initializers/delayed_job.rb +6 -0
- data/config/locales/alchemy.de.yml +55 -0
- data/config/locales/alchemy.en.yml +52 -0
- data/config/locales/alchemy_crm.de.yml +196 -0
- data/config/locales/alchemy_crm.en.yml +53 -0
- data/config/locales/localized_country_select.de.rb +268 -0
- data/config/locales/localized_country_select.en.rb +282 -0
- data/config/module_definition.yml +30 -0
- data/config/routes.rb +71 -0
- data/db/migrate/20100708220434_create_mailings.rb +19 -0
- data/db/migrate/20100708220534_create_contacts.rb +27 -0
- data/db/migrate/20100708220812_create_contact_groups.rb +13 -0
- data/db/migrate/20100708221009_create_newsletters.rb +15 -0
- data/db/migrate/20100708221319_create_sent_mailings.rb +15 -0
- data/db/migrate/20100708221529_create_recipients.rb +21 -0
- data/db/migrate/20100708222620_acts_as_taggable_migration.rb +28 -0
- data/db/migrate/20100708223324_create_contact_group_filters.rb +17 -0
- data/db/migrate/20100708223727_create_newsletter_subscriptions.rb +14 -0
- data/db/migrate/20100708223922_create_essence_element_teasers.rb +15 -0
- data/db/migrate/20100714172207_create_contact_groups_newsletters.rb +12 -0
- data/db/migrate/20100927152601_create_reactions.rb +14 -0
- data/db/migrate/20111028091722_acts_as_taggable_on_migration.rb +15 -0
- data/db/migrate/20111028200710_add_counter_cache_columns_for_tags.rb +11 -0
- data/db/migrate/20111030204931_create_delayed_jobs.rb +21 -0
- data/db/migrate/20111104105854_add_deliver_at_to_sent_mailings.rb +9 -0
- data/db/migrate/20111104125306_remove_sent_mailing_pdf_id_from_sent_mailings.rb +9 -0
- data/db/migrate/20111104131912_add_delivered_at_to_sent_mailings.rb +9 -0
- data/db/migrate/20111124145923_namespace_alchemy_crm_models.rb +17 -0
- data/db/migrate/20120306115555_add_disabled_to_alchemy_crm_contacts.rb +5 -0
- data/db/migrate/20120307160721_rename_alchemy_crm_recipients_sent_mailing_id.rb +5 -0
- data/db/migrate/20120315113522_add_url_to_alchemy_crm_reactions.rb +5 -0
- data/db/migrate/20120316161333_add_sha1_and_salt_to_alchemy_crm_recipients.rb +6 -0
- data/db/migrate/20120320103412_add_indexes_to_alchemy_crm_sha1_columns.rb +7 -0
- data/db/migrate/20120321105455_add_queue_to_delayed_jobs.rb +9 -0
- data/db/migrate/20120327174301_add_more_indexes_to_alchemy_crm_tables.rb +12 -0
- data/lib/alchemy_crm.rb +18 -0
- data/lib/alchemy_crm/bounced_delivery.rb +46 -0
- data/lib/alchemy_crm/config.rb +28 -0
- data/lib/alchemy_crm/engine.rb +40 -0
- data/lib/alchemy_crm/i18n_helpers.rb +35 -0
- data/lib/alchemy_crm/newsletter_layout.rb +40 -0
- data/lib/alchemy_crm/seeder.rb +30 -0
- data/lib/alchemy_crm/version.rb +3 -0
- data/lib/generators/alchemy_crm/scaffold/files/_standard.html.erb +1 -0
- data/lib/generators/alchemy_crm/scaffold/files/_standard.text.erb +1 -0
- data/lib/generators/alchemy_crm/scaffold/files/elements.yml +51 -0
- data/lib/generators/alchemy_crm/scaffold/files/newsletter_layouts.yml +3 -0
- data/lib/generators/alchemy_crm/scaffold/files/newsletters.html.erb +22 -0
- data/lib/generators/alchemy_crm/scaffold/files/newsletters.text.erb +4 -0
- data/lib/generators/alchemy_crm/scaffold/files/page_layouts.yml +19 -0
- data/lib/generators/alchemy_crm/scaffold/scaffold_generator.rb +26 -0
- data/lib/tasks/alchemy_crm.rake +28 -0
- data/lib/tasks/routes.rake +29 -0
- data/rails/init.rb +1 -0
- data/recipes/alchemy-mailings-capistrano-tasks.rb +12 -0
- data/spec/alchemy_mailings_spec.rb +7 -0
- data/spec/config_spec.rb +28 -0
- data/spec/controllers/alchemy_crm/contacts_controller_spec.rb +210 -0
- data/spec/controllers/alchemy_crm/mailings_controller_spec.rb +89 -0
- data/spec/controllers/alchemy_crm/recipients_controller_spec.rb +155 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/alchemy/config.yml +142 -0
- data/spec/dummy/config/alchemy/elements.yml +79 -0
- data/spec/dummy/config/alchemy/newsletter_layouts.yml +4 -0
- data/spec/dummy/config/alchemy/page_layouts.yml +55 -0
- data/spec/dummy/config/application.rb +43 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/schema.rb +452 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/helpers/alchemy_crm/mailings_helper_spec.rb +169 -0
- data/spec/mailers/alchemy_crm/contacts_mailer_spec.rb +88 -0
- data/spec/mailers/alchemy_crm/mailings_mailer_spec.rb +42 -0
- data/spec/models/alchemy_crm/contact_group_spec.rb +41 -0
- data/spec/models/alchemy_crm/contact_spec.rb +108 -0
- data/spec/models/alchemy_crm/delivery_spec.rb +55 -0
- data/spec/models/alchemy_crm/mailing_spec.rb +63 -0
- data/spec/models/alchemy_crm/newsletter_spec.rb +45 -0
- data/spec/spec_helper.rb +58 -0
- data/vendor/assets/javascripts/autocomplete-rails.js +16 -0
- metadata +438 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/404.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/422.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/500.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
23
|
+
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
|
6
|
+
require 'rails/commands'
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module AlchemyCrm
|
|
4
|
+
describe MailingsHelper do
|
|
5
|
+
|
|
6
|
+
include AlchemyCrm::Engine.routes.url_helpers
|
|
7
|
+
|
|
8
|
+
let(:recipient) { mock_model('Recipient', :email => 'foo@bar.org', :sha1 => 'kjhgfdfgh') }
|
|
9
|
+
|
|
10
|
+
describe '#render_newsletter_layout' do
|
|
11
|
+
|
|
12
|
+
before(:each) do
|
|
13
|
+
@page = Alchemy::Page.new(:name => 'Mailing page', :page_layout => 'newsletter_layout_standard')
|
|
14
|
+
language_root = Alchemy::Page.create!(:name => 'Language Root', :page_layout => 'standard', :language => Alchemy::Language.get_default, :parent_id => Alchemy::Page.root.id)
|
|
15
|
+
@unsubscribe_page = Alchemy::Page.create!(:name => 'Unsubscribe Page', :page_layout => 'newsletter_signout', :parent_id => language_root.id, :language => Alchemy::Language.get_default)
|
|
16
|
+
@mailing = mock_model('Mailing', :name => 'News 01/2012')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should render the newsletter layout" do
|
|
20
|
+
helper.stub!(:render_elements).and_return("")
|
|
21
|
+
helper.stub!(:configuration).and_return(true)
|
|
22
|
+
helper.stub!(:current_server).and_return('http://example.com')
|
|
23
|
+
helper.stub!(:current_language).and_return(mock_model('Language', :name => 'English'))
|
|
24
|
+
helper.render_newsletter_layout.should =~ /<h1>Newsletter/
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should render the newsletter layout in plain text" do
|
|
28
|
+
helper.stub!(:render_elements).and_return("")
|
|
29
|
+
helper.stub!(:configuration).and_return(true)
|
|
30
|
+
helper.request.format = :text
|
|
31
|
+
helper.render_newsletter_layout(:format => :text).should_not =~ /<h1>Newsletter/
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe '#render_tracking_image' do
|
|
37
|
+
it "should render a tracking image with recipient_reads_url as source." do
|
|
38
|
+
helper.stub!(:current_host).and_return('example.com')
|
|
39
|
+
@recipient = recipient
|
|
40
|
+
helper.render_tracking_image.should match /<img.+src=.#{recipient_reads_url(:h => recipient.sha1, :host => 'example.com')}/
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe '#link_to_unsubscribe_page' do
|
|
45
|
+
|
|
46
|
+
before(:each) do
|
|
47
|
+
unsubscribe_page = mock_model('Page', {:urlname => 'unsubscribe'})
|
|
48
|
+
Alchemy::Page.stub!(:find_by_page_layout).and_return(unsubscribe_page)
|
|
49
|
+
helper.stub!(:multi_language?).and_return(false)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should render a link to the unsubscribe page." do
|
|
53
|
+
helper.stub!(:current_host).and_return('example.com')
|
|
54
|
+
helper.link_to_unsubscribe_page.should match /<a.+href=.+example.com\/unsubscribe/
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#read_in_browser_notice' do
|
|
60
|
+
it "should render a notice with a link to read the mailing in a browser." do
|
|
61
|
+
@recipient = recipient
|
|
62
|
+
@mailing = mock_model('Mailing', :sha1 => 'lkjhvghfcdfjgkh')
|
|
63
|
+
helper.stub!(:current_host).and_return('example.com')
|
|
64
|
+
helper.read_in_browser_notice.should match /If the newsletter does not displays correctly, click <a.+href=.#{show_mailing_url(:m => @mailing.sha1, :r => @recipient.sha1, :host => 'example.com')}/
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe '#image_from_server_tag' do
|
|
69
|
+
it "should render an image with full url to server." do
|
|
70
|
+
Rails.application.config.assets.prefix = 'images'
|
|
71
|
+
helper.stub!(:current_server).and_return('https://example.com')
|
|
72
|
+
helper.image_from_server_tag('logo.png').should match /<img.+src=.https:\/\/example.com\/images\/logo.png/
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '#tracked_link_tag' do
|
|
77
|
+
it "should render a link with tracking url." do
|
|
78
|
+
@recipient = recipient
|
|
79
|
+
helper.stub!(:current_host).and_return('example.com')
|
|
80
|
+
helper.tracked_link_tag('read more', '/de/my-article', :style => 'color: black').should match /<a.+href=.#{Regexp.escape(recipient_reacts_url({:h => recipient.sha1, :r => '/de/my-article', :host => 'example.com'}))}.+style=.color: black.+read more/
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe '#current_host' do
|
|
85
|
+
it "should return the host from request." do
|
|
86
|
+
helper.stub!(:request).and_return(OpenStruct.new({:host => 'example.com'}))
|
|
87
|
+
helper.current_host.should match /^example.com$/
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should return the host from options[:host] if no request is present." do
|
|
91
|
+
helper.stub!(:request).and_return(nil)
|
|
92
|
+
helper.instance_variable_set('@options', {:host => 'example.com'})
|
|
93
|
+
helper.current_host.should match /^example.com$/
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe '#current_server' do
|
|
98
|
+
|
|
99
|
+
context "if no request given" do
|
|
100
|
+
it "should return the full server url from options." do
|
|
101
|
+
helper.stub!(:request).and_return(nil)
|
|
102
|
+
helper.instance_variable_set('@options', {
|
|
103
|
+
:port => 80,
|
|
104
|
+
:host => 'example.com'
|
|
105
|
+
})
|
|
106
|
+
helper.current_server.should match /^http:\/\/example.com$/
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "if request given" do
|
|
111
|
+
it "should return the full server url from request." do
|
|
112
|
+
helper.current_server.should match /^http:\/\/test.host$/
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "given a port different from 80 with options present" do
|
|
117
|
+
it "should return the full server url with port." do
|
|
118
|
+
helper.stub!(:request).and_return(nil)
|
|
119
|
+
helper.instance_variable_set('@options', {
|
|
120
|
+
:port => 3000,
|
|
121
|
+
:host => 'localhost'
|
|
122
|
+
})
|
|
123
|
+
helper.current_server.should match /^http:\/\/localhost:3000$/
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "given port 80 with options present" do
|
|
128
|
+
it "should return the full server url without port." do
|
|
129
|
+
helper.stub!(:request).and_return(nil)
|
|
130
|
+
helper.instance_variable_set('@options', {
|
|
131
|
+
:port => 80,
|
|
132
|
+
:host => 'example.com'
|
|
133
|
+
})
|
|
134
|
+
helper.current_server.should match /^http:\/\/example.com$/
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
context "given a port different from 80 with request present" do
|
|
139
|
+
it "should return the full server url with port." do
|
|
140
|
+
helper.stub!(:request).and_return(OpenStruct.new({:host => 'localhost', :port => 3000, :protocol => 'http://'}))
|
|
141
|
+
helper.current_server.should match /^http:\/\/localhost:3000$/
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context "given port 80 with request present" do
|
|
146
|
+
it "should return the full server url without port." do
|
|
147
|
+
helper.current_server.should match /^http:\/\/test.host$/
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe '#current_language' do
|
|
154
|
+
it "should return the language from session[:language_id]." do
|
|
155
|
+
helper.current_language.should be_an_instance_of(Alchemy::Language)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should return the language from options[:language_id] if no session is present." do
|
|
159
|
+
helper.instance_variable_set('@options', {:language_id => Alchemy::Language.get_default.id})
|
|
160
|
+
helper.current_language.should be_an_instance_of(Alchemy::Language)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "should return the default language if no session or options[:language_id] is present." do
|
|
164
|
+
helper.current_language.should be_an_instance_of(Alchemy::Language)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module AlchemyCrm
|
|
4
|
+
describe ContactsMailer do
|
|
5
|
+
|
|
6
|
+
include AlchemyCrm::Engine.routes.url_helpers
|
|
7
|
+
|
|
8
|
+
before(:all) do
|
|
9
|
+
Alchemy::PageLayout.add({"name" => 'newsletter_mails', "elements" => ['newsletter_signup_mail'], "autogenerate" => ["newsletter_signup_mail"]})
|
|
10
|
+
@language_root = Alchemy::Page.create!(:name => 'Language Root', :page_layout => 'standard', :parent_id => Alchemy::Page.root.id, :language => Alchemy::Language.get_default)
|
|
11
|
+
@page = Alchemy::Page.create!(:name => 'Newsletter Mails', :page_layout => 'newsletter_mails', :parent_id => @language_root.id, :language => @language_root.language)
|
|
12
|
+
@contact = Contact.create!(:email => 'jon@doe.com', :firstname => 'Jon', :lastname => 'Doe', :salutation => 'mr')
|
|
13
|
+
@newsletter = Newsletter.create!(:name => 'Newsletter', :layout => 'standard')
|
|
14
|
+
@subscription = Subscription.create!(:contact => @contact, :newsletter => @newsletter, :verified => true, :wants => true)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '#signup_mail' do
|
|
18
|
+
|
|
19
|
+
before(:all) do
|
|
20
|
+
@element = @page.elements.find_by_name(:newsletter_signup_mail)
|
|
21
|
+
@element.content_by_name('mail_from').essence.update_attribute(:body, 'frank@dank.com')
|
|
22
|
+
@element.content_by_name('subject').essence.update_attribute(:body, 'Welcome, please confirm')
|
|
23
|
+
@element.content_by_name('text').essence.update_attribute(:body, 'Hello %{name}, please click %{link}')
|
|
24
|
+
@email = ContactsMailer.signup_mail(@contact, @page).deliver
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should deliver to the contact's email address" do
|
|
28
|
+
@email.should deliver_to(@contact.email)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should have correct delivered from" do
|
|
32
|
+
@email.should deliver_from(@element.ingredient('mail_from'))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should contain a link to the confirmation link" do
|
|
36
|
+
url_regexp = Regexp.new(Regexp.escape(verify_contact_url(:token => @contact.email_sha1, :host => ActionMailer::Base.default_url_options[:host], :newsletter_ids => @contact.subscriptions.collect(&:newsletter_id))))
|
|
37
|
+
@email.should have_body_text(url_regexp)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should contain the correct greeting" do
|
|
41
|
+
@email.should have_body_text(/#{@contact.fullname}/)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should have the correct subject" do
|
|
45
|
+
@email.should have_subject(@element.ingredient('subject'))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe '#signout_mail' do
|
|
51
|
+
|
|
52
|
+
before(:all) do
|
|
53
|
+
@element = @page.elements.find_by_name(:newsletter_signout_mail)
|
|
54
|
+
@element.content_by_name('mail_from').essence.update_attribute(:body, 'frank@dank.com')
|
|
55
|
+
@element.content_by_name('subject').essence.update_attribute(:body, 'Byebye, please confirm')
|
|
56
|
+
@element.content_by_name('text').essence.update_attribute(:body, 'Hello %{name}, please click %{link}')
|
|
57
|
+
@email = ContactsMailer.signout_mail(@contact, @page).deliver
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should deliver to the contact's email address" do
|
|
61
|
+
@email.should deliver_to(@contact.email)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should have correct delivered from" do
|
|
65
|
+
@email.should deliver_from(@element.ingredient('mail_from'))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should contain a link to the confirmation link" do
|
|
69
|
+
@email.should have_body_text(/#{disable_contact_url(:token => @contact.email_sha1, :host => ActionMailer::Base.default_url_options[:host])}/)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should contain the correct greeting" do
|
|
73
|
+
@email.should have_body_text(/#{@contact.fullname}/)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should have the correct subject" do
|
|
77
|
+
@email.should have_subject(@element.ingredient('subject'))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
after(:all) do
|
|
83
|
+
@language_root.destroy
|
|
84
|
+
@contact.destroy
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module AlchemyCrm
|
|
4
|
+
describe MailingsMailer do
|
|
5
|
+
|
|
6
|
+
describe '#build' do
|
|
7
|
+
|
|
8
|
+
before(:all) do
|
|
9
|
+
@mailing = Mailing.create!(:name => 'Mailing', :subject => 'News Mailing', :additional_email_addresses => "jim@family.com, jon@doe.com, jane@family.com, \n", :newsletter => Newsletter.create!(:name => 'Newsletter', :layout => 'newsletter_layout_standard'))
|
|
10
|
+
@mailing.deliveries.create!
|
|
11
|
+
@element = @mailing.page.elements.first
|
|
12
|
+
@element.content_by_name('text').essence.update_attribute(:body, "<h2>Hello World</h2>")
|
|
13
|
+
@recipient = @mailing.recipients.first
|
|
14
|
+
@language_root = Alchemy::Page.create!(:name => 'Language Root', :page_layout => 'standard', :language => Alchemy::Language.get_default, :parent_id => Alchemy::Page.root.id)
|
|
15
|
+
@unsubscribe_page = Alchemy::Page.create!(:name => 'Unsubscribe Page', :page_layout => 'newsletter_signout', :parent_id => @language_root.id, :language => Alchemy::Language.get_default)
|
|
16
|
+
@email = MailingsMailer.build(@mailing, @recipient, {:host => ActionMailer::Base.default_url_options[:host], :language_id => Alchemy::Language.get_default.id}).deliver
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should render the mailings body." do
|
|
20
|
+
@email.should have_body_text(/#{Regexp.escape(@element.ingredient('text'))}/)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should render a plain text version of mailings body." do
|
|
24
|
+
@email.text_part.should_not have_body_text(/<h2>/)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should deliver to recipient's email." do
|
|
28
|
+
@email.should deliver_to(@recipient.email)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should have mailing's subject." do
|
|
32
|
+
@email.should have_subject(@mailing.subject)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
after(:all) do
|
|
36
|
+
@language_root.destroy
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module AlchemyCrm
|
|
4
|
+
describe ContactGroup do
|
|
5
|
+
|
|
6
|
+
describe "#contacts" do
|
|
7
|
+
|
|
8
|
+
before(:each) do
|
|
9
|
+
@verified_contact = Contact.create!({:email => 'jon@doe.com', :firstname => 'Jon', :lastname => 'Doe', :salutation => 'mr', :tag_list => 'father', :verified => true}, :as => :admin)
|
|
10
|
+
@contact = Contact.create!({:email => 'jane@smith.com', :firstname => 'Jane', :lastname => 'Smith', :salutation => 'ms', :tag_list => 'mother'}, :as => :admin)
|
|
11
|
+
@contact_group = ContactGroup.create!(:name => 'Family', :contact_tag_list => 'father, mother, son')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "with filter" do
|
|
15
|
+
|
|
16
|
+
before(:each) do
|
|
17
|
+
@contact_group.filters.create!(:column => 'lastname', :operator => 'IS', :value => 'Doe', :contact_group => @contact_group)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should return correct list of contacts" do
|
|
21
|
+
@contact_group.contacts.collect(&:email).should == ["jon@doe.com"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "without filter" do
|
|
27
|
+
|
|
28
|
+
before(:each) do
|
|
29
|
+
@contact_group.filters.delete_all
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should return all contacts with tag" do
|
|
33
|
+
@contact_group.contacts.collect(&:email).should == ["jon@doe.com", "jane@smith.com"]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module AlchemyCrm
|
|
4
|
+
describe Contact do
|
|
5
|
+
|
|
6
|
+
before(:all) do
|
|
7
|
+
@contact = Contact.create!({:email => 'jon@doe.com', :title => 'Dr.', :firstname => 'Jon', :lastname => 'Doe', :salutation => 'mr', :verified => true}, :as => :admin)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '.create' do
|
|
11
|
+
|
|
12
|
+
it "should set email_salt and email_sha1 for new records" do
|
|
13
|
+
@contact.email_sha1.should_not be_nil
|
|
14
|
+
@contact.email_salt.should_not be_nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#save' do
|
|
20
|
+
|
|
21
|
+
context "a contact with new email address" do
|
|
22
|
+
|
|
23
|
+
before(:each) do
|
|
24
|
+
@sha1 = @contact.email_sha1
|
|
25
|
+
@salt = @contact.email_salt
|
|
26
|
+
@contact.update_attributes!(:email => 'jane@doe.com')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should update email_sha1" do
|
|
30
|
+
@contact.email_sha1.should_not == @sha1
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should not update salt" do
|
|
34
|
+
@contact.email_salt.should == @salt
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "a contact with same email address" do
|
|
40
|
+
|
|
41
|
+
before(:each) do
|
|
42
|
+
@sha1 = @contact.email_sha1
|
|
43
|
+
@salt = @contact.email_salt
|
|
44
|
+
@contact.update_attributes!(:firstname => 'jane')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should not update email_sha1" do
|
|
48
|
+
@contact.email_sha1.should == @sha1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should not update salt" do
|
|
52
|
+
@contact.email_salt.should == @salt
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#interpolation_name_value' do
|
|
60
|
+
|
|
61
|
+
before(:each) do
|
|
62
|
+
@contact.update_attributes!(:firstname => 'Jon')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "not given a name_with_title value in the config" do
|
|
66
|
+
|
|
67
|
+
before(:each) do
|
|
68
|
+
Config.stub!(:get).and_return(nil)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should return the default value." do
|
|
72
|
+
@contact.interpolation_name_value.should == "Mr Dr. Jon Doe"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context "given a valid method name in the config" do
|
|
78
|
+
|
|
79
|
+
before(:each) do
|
|
80
|
+
Config.stub!(:get).and_return('name_with_title')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should return the correct value." do
|
|
84
|
+
@contact.interpolation_name_value.should == "Dr. Jon Doe"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "given not a valid method name in the config" do
|
|
90
|
+
|
|
91
|
+
before(:each) do
|
|
92
|
+
Config.stub!(:get).and_return('password')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should return the default value." do
|
|
96
|
+
@contact.interpolation_name_value.should == "Mr Dr. Jon Doe"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
after(:all) do
|
|
104
|
+
@contact.destroy
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
end
|