fat_free_crm 0.11.1 → 0.11.2

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.

Potentially problematic release.


This version of fat_free_crm might be problematic. Click here for more details.

Files changed (179) hide show
  1. data/Gemfile +30 -12
  2. data/Gemfile.lock +131 -119
  3. data/Procfile +1 -1
  4. data/README.md +1 -1
  5. data/app/assets/images/notifications.png +0 -0
  6. data/app/assets/javascripts/application.js.erb +3 -0
  7. data/app/assets/javascripts/crm_textarea_autocomplete.js +44 -0
  8. data/app/assets/stylesheets/application.css.erb +2 -0
  9. data/app/assets/stylesheets/common.scss +7 -11
  10. data/app/assets/stylesheets/textarea_autocomplete.scss +42 -0
  11. data/app/controllers/admin/application_controller.rb +5 -5
  12. data/app/controllers/admin/field_groups_controller.rb +11 -51
  13. data/app/controllers/admin/fields_controller.rb +13 -59
  14. data/app/controllers/admin/plugins_controller.rb +1 -4
  15. data/app/controllers/admin/settings_controller.rb +0 -4
  16. data/app/controllers/admin/tags_controller.rb +11 -66
  17. data/app/controllers/admin/users_controller.rb +20 -83
  18. data/app/controllers/application_controller.rb +83 -69
  19. data/app/controllers/comments_controller.rb +12 -29
  20. data/app/controllers/emails_controller.rb +1 -5
  21. data/app/controllers/entities/accounts_controller.rb +13 -32
  22. data/app/controllers/entities/campaigns_controller.rb +17 -32
  23. data/app/controllers/entities/contacts_controller.rb +20 -38
  24. data/app/controllers/entities/leads_controller.rb +33 -55
  25. data/app/controllers/entities/opportunities_controller.rb +26 -42
  26. data/app/controllers/entities_controller.rb +92 -83
  27. data/app/controllers/home_controller.rb +1 -10
  28. data/app/controllers/lists_controller.rb +1 -4
  29. data/app/controllers/{entities/tasks_controller.rb → tasks_controller.rb} +21 -32
  30. data/app/controllers/users_controller.rb +6 -5
  31. data/app/helpers/accounts_helper.rb +32 -9
  32. data/app/helpers/application_helper.rb +15 -1
  33. data/app/helpers/campaigns_helper.rb +1 -1
  34. data/app/helpers/comments_helper.rb +11 -1
  35. data/app/helpers/leads_helper.rb +1 -1
  36. data/app/helpers/opportunities_helper.rb +1 -1
  37. data/app/{models/mailers/notifier.rb → mailers/dropbox_mailer.rb} +5 -16
  38. data/app/mailers/subscription_mailer.rb +37 -0
  39. data/{lib/tasks/dropbox.rake → app/mailers/user_mailer.rb} +11 -13
  40. data/app/models/entities/account.rb +3 -1
  41. data/app/models/entities/campaign.rb +3 -1
  42. data/app/models/entities/contact.rb +3 -1
  43. data/app/models/entities/lead.rb +6 -5
  44. data/app/models/entities/opportunity.rb +3 -1
  45. data/app/models/fields/field.rb +1 -1
  46. data/app/models/polymorphic/comment.rb +34 -0
  47. data/app/models/{entities → polymorphic}/task.rb +16 -3
  48. data/app/models/setting.rb +15 -15
  49. data/app/models/users/ability.rb +12 -5
  50. data/app/models/users/user.rb +7 -2
  51. data/app/views/accounts/index.html.haml +1 -1
  52. data/app/views/accounts/index.js.rjs +1 -1
  53. data/app/views/admin/plugins/index.html.haml +1 -7
  54. data/app/views/{shared/auto_complete.html.haml → application/_auto_complete.html.haml} +0 -0
  55. data/app/views/{shared → application}/index.atom.builder +1 -1
  56. data/app/views/{shared → application}/index.rss.builder +1 -1
  57. data/app/views/campaigns/index.html.haml +1 -1
  58. data/app/views/campaigns/index.js.rjs +1 -1
  59. data/app/views/comments/_new.html.haml +6 -0
  60. data/app/views/comments/_subscription_links.html.haml +13 -0
  61. data/app/views/comments/new.js.rjs +2 -0
  62. data/app/views/contacts/_top_section.html.haml +3 -13
  63. data/app/views/contacts/index.html.haml +1 -1
  64. data/app/views/contacts/index.js.rjs +1 -1
  65. data/app/views/{notifier/dropbox_ack_notification.html.haml → dropbox_mailer/dropbox_notification.html.haml} +2 -2
  66. data/app/views/{shared → entities}/attach.js.rjs +1 -1
  67. data/app/views/entities/contacts.js.rjs +1 -1
  68. data/app/views/{shared/discard.rjs → entities/discard.js.rjs} +0 -0
  69. data/app/views/entities/leads.js.rjs +1 -1
  70. data/app/views/entities/opportunities.js.rjs +1 -1
  71. data/app/views/entities/subscription_update.js.rjs +4 -0
  72. data/app/views/entities/versions.js.rjs +1 -1
  73. data/app/views/layouts/_footer.html.haml +1 -1
  74. data/app/views/layouts/application.html.haml +3 -0
  75. data/app/views/leads/_contact.html.haml +1 -0
  76. data/app/views/leads/index.html.haml +1 -1
  77. data/app/views/leads/index.js.rjs +1 -1
  78. data/app/views/opportunities/_top_section.html.haml +4 -14
  79. data/app/views/opportunities/index.html.haml +1 -1
  80. data/app/views/opportunities/index.js.rjs +1 -1
  81. data/app/views/subscription_mailer/comment_notification.text.erb +7 -0
  82. data/app/views/{notifier → user_mailer}/password_reset_instructions.html.haml +0 -0
  83. data/config/application.rb +3 -1
  84. data/config/environments/development.rb +1 -1
  85. data/config/environments/test.rb +3 -0
  86. data/config/initializers/action_mailer.rb +8 -5
  87. data/config/initializers/cancan.rb +151 -0
  88. data/config/initializers/constants.rb +1 -0
  89. data/config/initializers/locale.rb +20 -0
  90. data/config/initializers/paper_trail.rb +4 -5
  91. data/config/initializers/relative_url_root.rb +0 -1
  92. data/config/initializers/squeel.rb +5 -0
  93. data/config/locales/cz_fat_free_crm.yml +3 -3
  94. data/config/locales/de.yml +2 -2
  95. data/config/locales/de_fat_free_crm.yml +651 -596
  96. data/config/locales/en-GB_fat_free_crm.yml +3 -3
  97. data/config/locales/en-US_fat_free_crm.yml +13 -3
  98. data/config/locales/es_fat_free_crm.yml +3 -3
  99. data/config/locales/fr-CA_fat_free_crm.yml +3 -3
  100. data/config/locales/fr_fat_free_crm.yml +3 -3
  101. data/config/locales/it_fat_free_crm.yml +3 -3
  102. data/config/locales/pl_fat_free_crm.yml +3 -3
  103. data/config/locales/pt-BR_fat_free_crm.yml +3 -3
  104. data/config/locales/ru_fat_free_crm.yml +3 -3
  105. data/config/locales/sv-SE_fat_free_crm.yml +3 -3
  106. data/config/locales/th_fat_free_crm.yml +3 -3
  107. data/config/routes.rb +10 -0
  108. data/config/settings.default.yml +29 -10
  109. data/config/unicorn.rb +4 -0
  110. data/db/migrate/20111201030535_add_field_groups_klass_name.rb +3 -1
  111. data/db/migrate/20120314080441_add_subscribed_users_to_entities.rb +23 -0
  112. data/db/migrate/20120405080727_change_subscribed_users_to_set.rb +24 -0
  113. data/db/migrate/20120405080742_change_further_subscribed_users_to_set.rb +27 -0
  114. data/db/migrate/20120413034923_add_index_on_versions_item_type.rb +5 -0
  115. data/db/schema.rb +109 -126
  116. data/fat_free_crm.gemspec +12 -18
  117. data/lib/fat_free_crm.rb +0 -1
  118. data/lib/fat_free_crm/core_ext/array.rb +1 -0
  119. data/lib/fat_free_crm/gem_dependencies.rb +1 -0
  120. data/lib/fat_free_crm/mail_processor/base.rb +226 -0
  121. data/lib/fat_free_crm/mail_processor/comment_replies.rb +86 -0
  122. data/lib/fat_free_crm/mail_processor/dropbox.rb +288 -0
  123. data/lib/fat_free_crm/permissions.rb +6 -19
  124. data/lib/fat_free_crm/renderers.rb +0 -8
  125. data/lib/fat_free_crm/tabs.rb +1 -1
  126. data/lib/fat_free_crm/version.rb +1 -1
  127. data/lib/plugins/country_select/lib/country_select.rb +2 -2
  128. data/lib/tasks/mail_processing.rake +60 -0
  129. data/spec/controllers/admin/users_controller_spec.rb +0 -2
  130. data/spec/controllers/{accounts_controller_spec.rb → entities/accounts_controller_spec.rb} +7 -9
  131. data/spec/controllers/{campaigns_controller_spec.rb → entities/campaigns_controller_spec.rb} +7 -7
  132. data/spec/controllers/{contacts_controller_spec.rb → entities/contacts_controller_spec.rb} +5 -9
  133. data/spec/controllers/{leads_controller_spec.rb → entities/leads_controller_spec.rb} +7 -9
  134. data/spec/controllers/{opportunities_controller_spec.rb → entities/opportunities_controller_spec.rb} +8 -15
  135. data/spec/controllers/tasks_controller_spec.rb +1 -5
  136. data/spec/controllers/users_controller_spec.rb +5 -9
  137. data/spec/factories/subscription_factories.rb +6 -0
  138. data/spec/lib/mail_processor/base_spec.rb +164 -0
  139. data/spec/lib/mail_processor/comment_replies_spec.rb +63 -0
  140. data/spec/lib/{dropbox_spec.rb → mail_processor/dropbox_spec.rb} +73 -181
  141. data/spec/lib/mail_processor/sample_emails/dropbox.rb +167 -0
  142. data/spec/mailers/subscription_mailer_spec.rb +17 -0
  143. data/spec/models/{base → entities}/account_contact_spec.rb +0 -0
  144. data/spec/models/{base → entities}/account_opportunity_spec.rb +0 -0
  145. data/spec/models/{base → entities}/account_spec.rb +4 -0
  146. data/spec/models/{base → entities}/campaign_spec.rb +4 -0
  147. data/spec/models/{base → entities}/contact_opportunity_spec.rb +0 -0
  148. data/spec/models/{base → entities}/contact_spec.rb +4 -0
  149. data/spec/models/{base → entities}/lead_spec.rb +4 -0
  150. data/spec/models/{base → entities}/opportunity_spec.rb +4 -0
  151. data/spec/models/polymorphic/comment_spec.rb +15 -0
  152. data/spec/models/{base → polymorphic}/task_spec.rb +124 -30
  153. data/spec/models/polymorphic/version_spec.rb +1 -1
  154. data/spec/shared/controllers.rb +5 -7
  155. data/spec/shared/models.rb +46 -0
  156. data/spec/spec_helper.rb +3 -4
  157. data/spec/support/mail_processor_mocks.rb +30 -0
  158. data/spec/support/uploaded_file.rb +3 -0
  159. data/spec/views/{common → application}/auto_complete.haml_spec.rb +1 -1
  160. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  161. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  162. data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  163. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  164. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  165. data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  166. data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  167. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  168. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  169. data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
  170. data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  171. data/vendor/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  172. data/vendor/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  173. data/vendor/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  174. data/vendor/assets/javascripts/textarea_autocomplete.js +605 -0
  175. data/vendor/assets/stylesheets/jquery-ui.custom.css.erb +565 -0
  176. metadata +234 -154
  177. data/config/locales/simple_form.en.yml +0 -24
  178. data/lib/fat_free_crm/dropbox.rb +0 -439
  179. data/spec/lib/dropbox/email_samples.rb +0 -77
@@ -0,0 +1,167 @@
1
+ DROPBOX_EMAILS = {
2
+ :plain => <<-END,
3
+ From: Aaron Assembler <aaron@example.com>
4
+ To: Ben Bootloader <ben@example.com>
5
+ Subject: Hi there
6
+ Date: Mon, 26 May 2003 11:22:33 -0600
7
+ Message-ID: <1234@local.machine.example>
8
+ Content-Type: text/plain
9
+
10
+ #{Faker::Lorem.paragraph}
11
+
12
+ Aaron
13
+ END
14
+
15
+ :html => <<-END,
16
+ From: Aaron Assembler <aaron@example.com>
17
+ To: Ben Bootloader <ben@example.com>
18
+ Subject: Hi there
19
+ Date: Mon, 26 May 2003 11:22:33 -0600
20
+ Message-ID: <1234@local.machine.example>
21
+ Content-Type: text/html
22
+
23
+ <html>
24
+ <head></head>
25
+ <body>
26
+ <p>#{Faker::Lorem.paragraph}</p>
27
+ <p>Aaron</p>
28
+ </body>
29
+ </html>
30
+ END
31
+
32
+ :first_line => <<-END,
33
+ From: Aaron Assembler <aaron@example.com>
34
+ To: Ben Bootloader <ben@example.com>
35
+ Subject: Hi there
36
+ Date: Mon, 26 May 2003 11:22:33 -0600
37
+ Message-ID: <1234@local.machine.example>
38
+ Content-Type: text/plain
39
+
40
+ .campaign Got milk
41
+ #{Faker::Lorem.paragraph}
42
+
43
+ Aaron
44
+ END
45
+
46
+ :first_line_lead => <<-END,
47
+ From: Aaron Assembler <aaron@example.com>
48
+ To: Ben Bootloader <ben@example.com>
49
+ Subject: Hi there
50
+ Date: Mon, 26 May 2003 11:22:33 -0600
51
+ Message-ID: <1234@local.machine.example>
52
+ Content-Type: text/plain
53
+
54
+ .lead Cindy Cluster
55
+ #{Faker::Lorem.paragraph}
56
+
57
+ Aaron
58
+ END
59
+
60
+ :first_line_contact => <<-END,
61
+ From: Aaron Assembler <aaron@example.com>
62
+ To: Ben Bootloader <ben@example.com>
63
+ Subject: Hi there
64
+ Date: Mon, 26 May 2003 11:22:33 -0600
65
+ Message-ID: <1234@local.machine.example>
66
+ Content-Type: text/plain
67
+
68
+ .contact Cindy Cluster
69
+ #{Faker::Lorem.paragraph}
70
+
71
+ Aaron
72
+ END
73
+
74
+ :forwarded => <<-END,
75
+ From: Aaron Assembler <aaron@example.com>
76
+ To: dropbox@example.com
77
+ Subject: Hi there
78
+ Date: Mon, 26 May 2003 11:22:33 -0600
79
+ Message-ID: <1234@local.machine.example>
80
+ Content-Type: text/plain
81
+
82
+ ---------- Forwarded message ----------
83
+ From: Ben Bootloader <ben@example.com>
84
+ Date: Sun, Mar 22, 2009 at 3:28 PM
85
+ Subject: Fwd:
86
+ To: Cindy Cluster <cindy@example.com>
87
+
88
+ #{Faker::Lorem.paragraph}
89
+
90
+ Ben
91
+ END
92
+
93
+ :multipart => <<-END,
94
+ From: Aaron Assembler <aaron@example.com>
95
+ To: Ben Bootloader <ben@example.com>
96
+ Subject: Hi there
97
+ Date: Fri, 30 Mar 2012 15:04:05 +0800
98
+ Message-ID: <1234@local.machine.example>
99
+ Content-Type: multipart/related;
100
+ boundary="_006_200DA2FF7EAFC04BAD979DB9CF293BB365151E88CLEARWATERtesta_";
101
+ type="text/html"
102
+
103
+ --_006_200DA2FF7EAFC04BAD979DB9CF293BB365151E88CLEARWATERtesta_
104
+ Content-Type: text/html; charset="iso-8859-1"
105
+ Content-Transfer-Encoding: quoted-printable
106
+
107
+ <html>
108
+ <head>
109
+ <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
110
+ 1">
111
+ <meta name=3D"Generator" content=3D"Microsoft Word 14 (filtered medium)">
112
+ <!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
113
+ o\:* {behavior:url(#default#VML);}
114
+ w\:* {behavior:url(#default#VML);}
115
+ .shape {behavior:url(#default#VML);}
116
+ </style><![endif]--><style><!--
117
+ /* Font Definitions */
118
+ @font-face
119
+ {font-family:Calibri;
120
+ panose-1:2 15 5 2 2 2 4 3 2 4;}
121
+ /* Style Definitions */
122
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
123
+ {margin:0in;
124
+ margin-bottom:.0001pt;
125
+ font-size:11.0pt;
126
+ font-family:"Calibri","sans-serif";}
127
+ div.WordSection1
128
+ {page:WordSection1;}
129
+ --></style><!--[if gte mso 9]><xml>
130
+ <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
131
+ </xml><![endif]--><!--[if gte mso 9]><xml>
132
+ <o:shapelayout v:ext=3D"edit">
133
+ <o:idmap v:ext=3D"edit" data=3D"1" />
134
+ </o:shapelayout></xml><![endif]-->
135
+ </head>
136
+ <body lang=3D"EN-US" link=3D"blue" vlink=3D"purple">
137
+ <div class=3D"WordSection1">
138
+ <p class=3D"MsoNormal"><span style=3D"color:#1F497D"><o:p>Hello,</o:p></spa=
139
+ n></p>
140
+ </div>
141
+ </body>
142
+ </html>
143
+
144
+ --_006_200DA2FF7EAFC04BAD979DB9CF293BB365151E88CLEARWATERtesta_
145
+ Content-Type: image/gif; name="image007.gif"
146
+ Content-Description: image007.gif
147
+ Content-Disposition: inline; filename="image007.gif"; size=633;
148
+ creation-date="Fri, 30 Mar 2012 07:04:05 GMT";
149
+ modification-date="Fri, 30 Mar 2012 07:04:05 GMT"
150
+ Content-ID:<image007.gif@01CD0DBA.FB4A2170>
151
+ Content-Transfer-Encoding: base64
152
+
153
+ R0lGODlhXQASALMAAIiIiBESESIjIt3d3VVWVURFRLu7u2ZnZpmZmaqqqjM0M3d4d+7u7gABAMzM
154
+ zP///yH5BAAAAAAALAAAAABdABIAAAT/8MlJ63Q2683tAAvTjdKwAFqyJBLQoGQsP0MgKGy3PuDi
155
+ /4tHotHAWASN4MNRGMyeHYKAkshZGMnHQcFt3LhCr5IqhppH4IliXMGy3eRFQEQpELIS+oRR9Rgl
156
+ VU4VBgmCFwkGFAxcdIshent4eZJhBi8Ulgh4QzkMd0QBElwLRCJyRA0HewqoiUsFqAIYQ6g4qKVt
157
+ lHATQ55TEwQFu5wSBQEADB+iATgIWscMDC6qDwWyDAhONQUODA4KAQN8XIjjBH25b5S9mRIOL8MN
158
+ LC5WanPulxOkGAIEFVJ6GATw9yCNKDaKdK1rIKJAAQkHpsRjISWDQReGHliiCG+CAGoTzAooEDVS
159
+ DcJI6tj0CtPt2IOJBUtWMEgKEhYUnhq43KUvVEwKazTwfLmQTj8A92CKtCgTIyZ5F+6gCACyWEmD
160
+ BU9OSkmGDlIF1GC6cAVUpiUYEkhlfCAgiLWAVEkCJXhFoUqGEwIU2QoI6qIACJIpwXoAmrQASg50
161
+ G4LCQQBu3gjc+6lGwIA/KBPe1bOALkwasIj8wqoFFWKPqEA6QEKEmxqZQvTi1UxbEQebFRwkwJxh
162
+ ADpMhSwQ4p2Bz9o8V84oX868ufPn0KNLn64hAgA7
163
+
164
+ --_006_200DA2FF7EAFC04BAD979DB9CF293BB365151E88CLEARWATERtesta_--
165
+ END
166
+ }
167
+
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SubscriptionMailer do
4
+
5
+ describe "comment notification" do
6
+ let(:user) { FactoryGirl.create(:user) }
7
+ let(:commentable) { FactoryGirl.create(:opportunity, :id => 47, :name => 'Opportunity name') }
8
+ let(:comment) { FactoryGirl.create(:comment, :commentable => commentable) }
9
+ let(:mail) { SubscriptionMailer.comment_notification(user, comment) }
10
+
11
+ it "send user password reset url" do
12
+ mail.subject.should eq("RE: [opportunity:47] Opportunity name")
13
+ mail.to.should eq([user.email])
14
+ mail.body.encoded.should match(polymorphic_url(commentable))
15
+ end
16
+ end
17
+ end
@@ -132,5 +132,9 @@ describe Account do
132
132
  account.category.should == nil
133
133
  end
134
134
  end
135
+
136
+ describe "permissions" do
137
+ it_should_behave_like Ability, Account
138
+ end
135
139
  end
136
140
 
@@ -131,5 +131,9 @@ describe Campaign do
131
131
  end
132
132
  end
133
133
  end
134
+
135
+ describe "permissions" do
136
+ it_should_behave_like Ability, Campaign
137
+ end
134
138
  end
135
139
 
@@ -156,5 +156,9 @@ describe Contact do
156
156
  end
157
157
  end
158
158
  end
159
+
160
+ describe "permissions" do
161
+ it_should_behave_like Ability, Contact
162
+ end
159
163
  end
160
164
 
@@ -97,5 +97,9 @@ describe Lead do
97
97
  end
98
98
  end
99
99
  end
100
+
101
+ describe "permissions" do
102
+ it_should_behave_like Ability, Lead
103
+ end
100
104
  end
101
105
 
@@ -169,5 +169,9 @@ describe Opportunity do
169
169
  end
170
170
  end
171
171
  end
172
+
173
+ describe "permissions" do
174
+ it_should_behave_like Ability, Opportunity
175
+ end
172
176
  end
173
177
 
@@ -25,5 +25,20 @@ describe Comment do
25
25
  it "should create a new instance given valid attributes" do
26
26
  Comment.create!(:comment => "Hello", :user => FactoryGirl.create(:user), :commentable => FactoryGirl.create(:lead))
27
27
  end
28
+
29
+ it "should subscribe users mentioned in the comment to the entity, and notify them via email" do
30
+ expected_users = [
31
+ FactoryGirl.create(:user, :username => "test_user"),
32
+ FactoryGirl.create(:user, :username => "another_user")
33
+ ]
34
+ entity = FactoryGirl.create(:lead)
35
+ Comment.create!(:comment => "Hey @test_user, take a look at this. Also show @another_user",
36
+ :user => FactoryGirl.create(:user),
37
+ :commentable => entity)
38
+
39
+ expected_users.each do |user|
40
+ entity.subscribed_users.should include(user.id)
41
+ end
42
+ end
28
43
  end
29
44
 
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  # == Schema Information
2
3
  #
3
4
  # Table name: tasks
@@ -32,19 +33,19 @@ describe Task do
32
33
  task.should be_valid
33
34
  task.errors.should be_empty
34
35
  end
35
-
36
+
36
37
  [ nil, Time.now.utc_offset + 3600 ].each do |offset|
37
38
  before do
38
39
  adjust_timezone(offset)
39
40
  end
40
-
41
+
41
42
  it "should create a task with due date selected from dropdown within #{offset ? 'different' : 'current'} timezone" do
42
43
  task = FactoryGirl.create(:task, :due_at => Time.now.end_of_week, :bucket => "due_this_week")
43
44
  task.errors.should be_empty
44
45
  task.bucket.should == "due_this_week"
45
46
  task.due_at.should == Time.zone.now.end_of_week
46
47
  end
47
-
48
+
48
49
  it "should create a task with due date selected from the calendar within #{offset ? 'different' : 'current'} timezone" do
49
50
  task = FactoryGirl.create(:task, :bucket => "specific_time", :calendar => "5/5/2020 12:00 AM")
50
51
  task.errors.should be_empty
@@ -53,7 +54,7 @@ describe Task do
53
54
  end
54
55
  end
55
56
  end
56
-
57
+
57
58
  describe "Task/Update" do
58
59
  it "should update task name" do
59
60
  task = FactoryGirl.create(:task, :name => "Hello")
@@ -61,14 +62,14 @@ describe Task do
61
62
  task.errors.should be_empty
62
63
  task.name.should == "World"
63
64
  end
64
-
65
+
65
66
  it "should update task category" do
66
67
  task = FactoryGirl.create(:task, :category => "call")
67
68
  task.update_attributes({ :category => "email" })
68
69
  task.errors.should be_empty
69
70
  task.category.should == "email"
70
71
  end
71
-
72
+
72
73
  it "should reassign the task to another person" do
73
74
  him = FactoryGirl.create(:user)
74
75
  her = FactoryGirl.create(:user)
@@ -78,7 +79,7 @@ describe Task do
78
79
  task.assigned_to.should == her.id
79
80
  task.assignee.should == her
80
81
  end
81
-
82
+
82
83
  it "should reassign the task from another person to myself" do
83
84
  him = FactoryGirl.create(:user)
84
85
  task = FactoryGirl.create(:task, :assigned_to => him.id)
@@ -87,12 +88,12 @@ describe Task do
87
88
  task.assigned_to.should == nil
88
89
  task.assignee.should == nil
89
90
  end
90
-
91
+
91
92
  [ nil, Time.now.utc_offset + 3600 ].each do |offset|
92
93
  before do
93
94
  adjust_timezone(offset)
94
95
  end
95
-
96
+
96
97
  it "should update due date based on selected bucket within #{offset ? 'different' : 'current'} timezone" do
97
98
  task = FactoryGirl.create(:task, :due_at => Time.now.midnight.tomorrow, :bucket => "due_tomorrow")
98
99
  task.update_attributes( { :bucket => "due_this_week" } )
@@ -100,7 +101,7 @@ describe Task do
100
101
  task.bucket.should == "due_this_week"
101
102
  task.due_at.should == Time.zone.now.end_of_week
102
103
  end
103
-
104
+
104
105
  it "should update due date if specific calendar date selected within #{offset ? 'different' : 'current'} timezone" do
105
106
  task = FactoryGirl.create(:task, :due_at => Time.now.midnight.tomorrow, :bucket => "due_tomorrow")
106
107
  task.update_attributes( { :bucket => "specific_time", :calendar => "05/05/2020 12:00 AM" } )
@@ -109,9 +110,9 @@ describe Task do
109
110
  task.due_at.should == DateTime.parse("2020-05-05")
110
111
  end
111
112
  end
112
-
113
+
113
114
  end
114
-
115
+
115
116
  describe "Task/Complete" do
116
117
  it "should comlete a task that is overdue" do
117
118
  task = FactoryGirl.create(:task, :due_at => 2.days.ago, :bucket => "overdue")
@@ -120,7 +121,7 @@ describe Task do
120
121
  task.completed_at.should_not == nil
121
122
  task.completor.should == @current_user
122
123
  end
123
-
124
+
124
125
  it "should complete a task due sometime in the future" do
125
126
  task = FactoryGirl.create(:task, :due_at => Time.now.midnight.tomorrow, :bucket => "due_tomorrow")
126
127
  task.update_attributes(:completed_at => Time.now, :completed_by => @current_user.id)
@@ -128,7 +129,7 @@ describe Task do
128
129
  task.completed_at.should_not == nil
129
130
  task.completor.should == @current_user
130
131
  end
131
-
132
+
132
133
  it "should complete a task that is due on specific date in the future" do
133
134
  task = FactoryGirl.create(:task, :calendar => "10/10/2022 12:00 AM", :bucket => "specific_time")
134
135
  task.calendar = nil # Calendar is not saved in the database; we need it only to set the :due_at.
@@ -137,7 +138,7 @@ describe Task do
137
138
  task.completed_at.should_not == nil
138
139
  task.completor.should == @current_user
139
140
  end
140
-
141
+
141
142
  it "should complete a task that is due on specific date in the past" do
142
143
  task = FactoryGirl.create(:task, :calendar => "10/10/1992 12:00 AM", :bucket => "specific_time")
143
144
  task.calendar = nil # Calendar is not saved in the database; we need it only to set the :due_at.
@@ -146,7 +147,7 @@ describe Task do
146
147
  task.completed_at.should_not == nil
147
148
  task.completor.should == @current_user
148
149
  end
149
-
150
+
150
151
  it "completion should preserve original due date" do
151
152
  due_at = 42.days.ago
152
153
  time_format = I18n.t(Setting.task_calendar_with_time ?
@@ -160,71 +161,71 @@ describe Task do
160
161
  task.due_at.to_i.should == parsed_time.to_i
161
162
  end
162
163
  end
163
-
164
+
164
165
  # named_scope :my, lambda { |user| { :conditions => [ "(user_id = ? AND assigned_to IS NULL) OR assigned_to = ?", user.id, user.id ], :include => :assignee } }
165
166
  describe "task.my?" do
166
167
  it "should match a task created by the user" do
167
168
  task = FactoryGirl.create(:task, :user => @current_user, :assignee => nil)
168
169
  task.my?(@current_user).should == true
169
170
  end
170
-
171
+
171
172
  it "should match a task assigned to the user" do
172
173
  task = FactoryGirl.create(:task, :user => FactoryGirl.create(:user), :assignee => @current_user)
173
174
  task.my?(@current_user).should == true
174
175
  end
175
-
176
+
176
177
  it "should Not match a task not created by the user" do
177
178
  task = FactoryGirl.create(:task, :user => FactoryGirl.create(:user))
178
179
  task.my?(@current_user).should == false
179
180
  end
180
-
181
+
181
182
  it "should Not match a task created by the user but assigned to somebody else" do
182
183
  task = FactoryGirl.create(:task, :user => @current_user, :assignee => FactoryGirl.create(:user))
183
184
  task.my?(@current_user).should == false
184
185
  end
185
186
  end
186
-
187
+
187
188
  # named_scope :assigned_by, lambda { |user| { :conditions => [ "user_id = ? AND assigned_to IS NOT NULL AND assigned_to != ?", user.id, user.id ], :include => :assignee } }
188
189
  describe "task.assigned_by?" do
189
190
  it "should match a task assigned by the user to somebody else" do
190
191
  task = FactoryGirl.create(:task, :user => @current_user, :assignee => FactoryGirl.create(:user))
191
192
  task.assigned_by?(@current_user).should == true
192
193
  end
193
-
194
+
194
195
  it "should Not match a task not created by the user" do
195
196
  task = FactoryGirl.create(:task, :user => FactoryGirl.create(:user))
196
197
  task.assigned_by?(@current_user).should == false
197
198
  end
198
-
199
+
199
200
  it "should Not match a task not assigned to anybody" do
200
201
  task = FactoryGirl.create(:task, :assignee => nil)
201
202
  task.assigned_by?(@current_user).should == false
202
203
  end
203
-
204
+
204
205
  it "should Not match a task assigned to the user" do
205
206
  task = FactoryGirl.create(:task, :assignee => @current_user)
206
207
  task.assigned_by?(@current_user).should == false
207
208
  end
208
209
  end
209
-
210
+
210
211
  # named_scope :tracked_by, lambda { |user| { :conditions => [ "user_id = ? OR assigned_to = ?", user.id, user.id ], :include => :assignee } }
211
212
  describe "task.tracked_by?" do
212
213
  it "should match a task created by the user" do
213
214
  task = FactoryGirl.create(:task, :user => @current_user)
214
215
  task.tracked_by?(@current_user).should == true
215
216
  end
216
-
217
+
217
218
  it "should match a task assigned to the user" do
218
219
  task = FactoryGirl.create(:task, :assignee => @current_user)
219
220
  task.tracked_by?(@current_user).should == true
220
221
  end
221
-
222
+
222
223
  it "should Not match a task that is neither created nor assigned to the user" do
223
224
  task = FactoryGirl.create(:task, :user => FactoryGirl.create(:user), :assignee => FactoryGirl.create(:user))
224
225
  task.tracked_by?(@current_user).should == false
225
226
  end
226
227
  end
227
-
228
+
228
229
  describe "Exportable" do
229
230
  describe "unassigned tasks" do
230
231
  before do
@@ -236,7 +237,7 @@ describe Task do
236
237
  let(:exported) { Task.all }
237
238
  end
238
239
  end
239
-
240
+
240
241
  describe "assigned tasks" do
241
242
  before do
242
243
  Task.delete_all
@@ -247,7 +248,7 @@ describe Task do
247
248
  let(:exported) { Task.all }
248
249
  end
249
250
  end
250
-
251
+
251
252
  describe "completed tasks" do
252
253
  before do
253
254
  Task.delete_all
@@ -259,5 +260,98 @@ describe Task do
259
260
  end
260
261
  end
261
262
  end
263
+
264
+ describe "#parse_calendar_date" do
265
+ before :each do
266
+ I18n.locale = "de"
267
+ @task = Task.new
268
+ @task.bucket = "specific_time"
269
+ @backup_with_time = Setting.task_calendar_with_time
270
+ end
271
+
272
+ after :each do
273
+ I18n.locale = "en-Us"
274
+ Setting.task_calendar_with_time = @backup_with_time
275
+ end
276
+
277
+ context "german" do
278
+ context "date" do
279
+ before :each do
280
+ Setting.task_calendar_with_time = false
281
+ end
282
+
283
+ it "should translate: \"20 Jänner 2012\" to \"20 January 2012\"" do
284
+ @task.calendar = "20 Jänner 2012"
285
+ @task.send(:parse_calendar_date).should == "20 January 2012"
286
+ end
287
+
288
+ it "should translate: \"20 Februar 2012\" to \"20 February 2012\"" do
289
+ @task.calendar = "20 Februar 2012"
290
+ @task.send(:parse_calendar_date).should == "20 February 2012"
291
+ end
292
+
293
+ it "should translate: \"20 März 2012\" to \"20 March 2012\"" do
294
+ @task.calendar = "20 März 2012"
295
+ @task.send(:parse_calendar_date).should == "20 March 2012"
296
+ end
297
+
298
+ it "should translate: \"20 April 2012\" to \"20 April 2012\"" do
299
+ @task.calendar = "20 April 2012"
300
+ @task.send(:parse_calendar_date).should == "20 April 2012"
301
+ end
302
+
303
+ it "should translate: \"20 Mai 2012\" to \"20 May 2012\"" do
304
+ @task.calendar = "20 Mai 2012"
305
+ @task.send(:parse_calendar_date).should == "20 May 2012"
306
+ end
307
+
308
+ it "should translate: \"20 Juni 2012\" to \"20 June 2012\"" do
309
+ @task.calendar = "20 Juni 2012"
310
+ @task.send(:parse_calendar_date).should == "20 June 2012"
311
+ end
312
+
313
+ it "should translate: \"20 Juli 2012\" to \"20 July 2012\"" do
314
+ @task.calendar = "20 Juli 2012"
315
+ @task.send(:parse_calendar_date).should == "20 July 2012"
316
+ end
317
+
318
+ it "should translate: \"20 August 2012\" to \"20 August 2012\"" do
319
+ @task.calendar = "20 August 2012"
320
+ @task.send(:parse_calendar_date).should == "20 August 2012"
321
+ end
322
+
323
+ it "should translate: \"20 September 2012\" to \"20 September 2012\"" do
324
+ @task.calendar = "20 September 2012"
325
+ @task.send(:parse_calendar_date).should == "20 September 2012"
326
+ end
327
+
328
+ it "should translate: \"20 Oktober 2012\" to \"20 October 2012\"" do
329
+ @task.calendar = "20 Oktober 2012"
330
+ @task.send(:parse_calendar_date).should == "20 October 2012"
331
+ end
332
+
333
+ it "should translate: \"20 November 2012\" to \"20 November 2012\"" do
334
+ @task.calendar = "20 November 2012"
335
+ @task.send(:parse_calendar_date).should == "20 November 2012"
336
+ end
337
+
338
+ it "should translate: \"20 Dezember 2012\" to \"20 December 2012\"" do
339
+ @task.calendar = "20 Dezember 2012"
340
+ @task.send(:parse_calendar_date).should == "20 December 2012"
341
+ end
342
+ end
343
+
344
+ context 'datetime' do
345
+ before :each do
346
+ Setting.task_calendar_with_time = true
347
+ end
348
+
349
+ it "should translate: \"20 Jänner 2012 12:27\" to \"20 January 2012 12:27\"" do
350
+ @task.calendar = "20 Jänner 2012 12:27"
351
+ @task.send(:parse_calendar_date).should == "20 January 2012 12:27"
352
+ end
353
+ end
354
+ end
355
+ end
262
356
  end
263
357