gestion 1.9.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +48 -0
  3. data/.project +14 -0
  4. data/Binaries/adduser_to_buzz +15 -0
  5. data/Binaries/backup +7 -0
  6. data/Binaries/check_gestion +8 -0
  7. data/Binaries/gestion.gnumail +22 -0
  8. data/Binaries/gestion.logrotate +34 -0
  9. data/Binaries/gestion.service +12 -0
  10. data/Binaries/gestion_update.rb +183 -0
  11. data/Binaries/gestion_update.service +10 -0
  12. data/Binaries/get_compta +11 -0
  13. data/Binaries/kill_gestion +16 -0
  14. data/Binaries/ldap/add_indexes +51 -0
  15. data/Binaries/ldap/backup +2 -0
  16. data/Binaries/ldap/install_ldap +92 -0
  17. data/Binaries/ldap/restore +7 -0
  18. data/Binaries/lib_backup +5 -0
  19. data/Binaries/log_scan_errors +8 -0
  20. data/Binaries/loop_gestion +64 -0
  21. data/Binaries/onetimers/sync_courses_from_compta.rb +74 -0
  22. data/Binaries/onetimers/transfer_cash_from_ldap_to_csv +26 -0
  23. data/Binaries/reboot +5 -0
  24. data/Binaries/restore +3 -0
  25. data/Binaries/restore_do +22 -0
  26. data/Binaries/sort_events +31 -0
  27. data/Binaries/start_gestion +18 -0
  28. data/Binaries/swipe_gestion +18 -0
  29. data/Binaries/update_africompta +21 -0
  30. data/Binaries/update_users +3 -0
  31. data/Diplomas.src/accredited.odg +0 -0
  32. data/Diplomas.src/diploma.odg +0 -0
  33. data/Diplomas.src/label.odg +0 -0
  34. data/Diplomas.src/presence_sheet.ods +0 -0
  35. data/Diplomas.src/presence_sheet_small.ods +0 -0
  36. data/Diplomas.src/student_card.odg +0 -0
  37. data/Doc/130514-it-ideas.odt +0 -0
  38. data/Doc/Compta-cash.mm +179 -0
  39. data/Doc/General.odt +0 -0
  40. data/Entities/AccessGroups.rb +117 -0
  41. data/Entities/Activity.rb +178 -0
  42. data/Entities/ChatMsg.rb +142 -0
  43. data/Entities/Classroom.rb +11 -0
  44. data/Entities/Client.rb +19 -0
  45. data/Entities/Computer.rb +21 -0
  46. data/Entities/ConfigBase.rb +280 -0
  47. data/Entities/Course.rb +1588 -0
  48. data/Entities/CourseType.rb +171 -0
  49. data/Entities/DFiles.rb +466 -0
  50. data/Entities/FilesManage.rb +226 -0
  51. data/Entities/Grade.rb +186 -0
  52. data/Entities/Internet.rb +300 -0
  53. data/Entities/Netdev.rb +10 -0
  54. data/Entities/Person.rb +1175 -0
  55. data/Entities/Plug.rb +98 -0
  56. data/Entities/Quiz.rb +33 -0
  57. data/Entities/Recharges.rb +37 -0
  58. data/Entities/Report.rb +136 -0
  59. data/Entities/Room.rb +12 -0
  60. data/Entities/SMS.rb +30 -0
  61. data/Entities/ScheduleType.rb +33 -0
  62. data/Entities/Share.rb +120 -0
  63. data/Entities/Task.rb +51 -0
  64. data/Entities/Ticket.rb +72 -0
  65. data/Entities/Usage.rb +143 -0
  66. data/Entities/Worker.rb +29 -0
  67. data/Files/apache-profeda.conf +36 -0
  68. data/Files/label.erb +121 -0
  69. data/Files/label_notfound.erb +64 -0
  70. data/Files/label_notpassed.erb +84 -0
  71. data/Files/mobileinfo.erb +115 -0
  72. data/Files/smb.conf +333 -0
  73. data/Files/timetable.html +36 -0
  74. data/Files/timetable.js +239 -0
  75. data/Gemfile +12 -0
  76. data/Gemfile.dev +12 -0
  77. data/Gemfile.dev.lock +127 -0
  78. data/Gemfile.lock +127 -0
  79. data/Gemfile.prod +8 -0
  80. data/Gestion +35 -0
  81. data/Gestion.rb +220 -0
  82. data/INSTALL +40 -0
  83. data/Images/connection.xcf +0 -0
  84. data/Images/connection_no.png +0 -0
  85. data/Images/connection_wait.png +0 -0
  86. data/Images/connection_yes.png +0 -0
  87. data/Paths/Exas.rb +13 -0
  88. data/Paths/Files.rb +19 -0
  89. data/Paths/GetDiplomas.rb +20 -0
  90. data/Paths/Info.rb +114 -0
  91. data/Paths/Label.rb +187 -0
  92. data/Paths/MobileInfo.rb +19 -0
  93. data/Paths/internetCash.rb +34 -0
  94. data/Paths/internetWifi.rb +54 -0
  95. data/README.md +60 -0
  96. data/Rakefile +13 -0
  97. data/TODO +1391 -0
  98. data/Test/.gitignore +3 -0
  99. data/Test/Diplomas/base_gestion.odt +0 -0
  100. data/Test/Diplomas/base_report.odt +0 -0
  101. data/Test/Diplomas/carte_etudiant.odg +0 -0
  102. data/Test/Diplomas/exam_language.odt +0 -0
  103. data/Test/Diplomas/label.odg +0 -0
  104. data/Test/Diplomas/presence_sheet.ods +0 -0
  105. data/Test/Diplomas/presence_sheet_small.ods +0 -0
  106. data/Test/Diplomas/student_card.odg +0 -0
  107. data/Test/Manual/testMerge +18 -0
  108. data/Test/config_test.yaml +26 -0
  109. data/Test/db.testGestion +0 -0
  110. data/Test/dfiles/descs/avg-rescue.desc +10 -0
  111. data/Test/dfiles/descs/avg.desc +8 -0
  112. data/Test/dfiles/descs/driver.desc +8 -0
  113. data/Test/dfiles/descs/linuxmint.desc +7 -0
  114. data/Test/dfiles/files/avg-160203.exe +1 -0
  115. data/Test/dfiles/files/avg.iso +1 -0
  116. data/Test/dfiles/files/driver.exe +1 -0
  117. data/Test/dfiles/index_post.html +3 -0
  118. data/Test/dfiles/index_pre.html +8 -0
  119. data/Test/dfiles/priorities +5 -0
  120. data/Test/ge_activity.rb +124 -0
  121. data/Test/ge_chat.rb +106 -0
  122. data/Test/ge_compta.rb +67 -0
  123. data/Test/ge_configbase.rb +54 -0
  124. data/Test/ge_course.rb +1114 -0
  125. data/Test/ge_dfiles.rb +121 -0
  126. data/Test/ge_filesmanage.rb +180 -0
  127. data/Test/ge_info.rb +27 -0
  128. data/Test/ge_internet.rb +246 -0
  129. data/Test/ge_login.rb +55 -0
  130. data/Test/ge_person.rb +373 -0
  131. data/Test/ge_qvinfo.rb +28 -0
  132. data/Test/ge_report.rb +97 -0
  133. data/Test/ge_share.rb +27 -0
  134. data/Test/ge_sms.rb +34 -0
  135. data/Test/ge_tasks.rb +19 -0
  136. data/Test/ge_usage.rb +168 -0
  137. data/Test/ge_view.rb +46 -0
  138. data/Test/multiconf-captive +29 -0
  139. data/Test/test.conf +7 -0
  140. data/Test/test.rb +49 -0
  141. data/Test/test_bytes.png +0 -0
  142. data/VERSION +140 -0
  143. data/Views/Admin/Backup.rb +91 -0
  144. data/Views/Admin/Configuration.rb +44 -0
  145. data/Views/Admin/Credit.rb +32 -0
  146. data/Views/Admin/FilesManage.rb +219 -0
  147. data/Views/Admin/Function.rb +39 -0
  148. data/Views/Admin/Power.rb +49 -0
  149. data/Views/Admin/Printer.rb +37 -0
  150. data/Views/Admin/Server.rb +252 -0
  151. data/Views/Admin/Tabs.rb +5 -0
  152. data/Views/Admin/Update.rb +73 -0
  153. data/Views/Admin/UpdateSystem.rb +26 -0
  154. data/Views/Cashbox/Activity.rb +191 -0
  155. data/Views/Cashbox/Course.rb +141 -0
  156. data/Views/Cashbox/Credit.rb +79 -0
  157. data/Views/Cashbox/Report.rb +115 -0
  158. data/Views/Cashbox/Service.rb +105 -0
  159. data/Views/Cashbox/Tabs.rb +10 -0
  160. data/Views/Compta/Accounts.rb +36 -0
  161. data/Views/Compta/Course.rb +96 -0
  162. data/Views/Compta/Show.rb +6 -0
  163. data/Views/Compta/Transfer.rb +66 -0
  164. data/Views/Course/Diploma.rb +203 -0
  165. data/Views/Course/Grade.rb +401 -0
  166. data/Views/Course/Modify.rb +447 -0
  167. data/Views/Course/Print.rb +94 -0
  168. data/Views/Course/Responsible.rb +44 -0
  169. data/Views/Course/Stats.rb +76 -0
  170. data/Views/Course/Students.rb +92 -0
  171. data/Views/Course/Tabs.rb +220 -0
  172. data/Views/Internet/Access.rb +134 -0
  173. data/Views/Internet/ClassEdit.rb +24 -0
  174. data/Views/Internet/ClassUsers.rb +81 -0
  175. data/Views/Internet/Config.rb +32 -0
  176. data/Views/Internet/Mobile.rb +213 -0
  177. data/Views/Internet/Recharges.rb +49 -0
  178. data/Views/Internet/Tabs.rb +6 -0
  179. data/Views/Inventory/Computer.rb +24 -0
  180. data/Views/Inventory/Room.rb +18 -0
  181. data/Views/Inventory/Tabs.rb +9 -0
  182. data/Views/Inventory/TicketClosed.rb +7 -0
  183. data/Views/Inventory/TicketOpen.rb +23 -0
  184. data/Views/Library/Person.rb +36 -0
  185. data/Views/Library/Tabs.rb +7 -0
  186. data/Views/Network/Block.rb +87 -0
  187. data/Views/Network/Netdevs.rb +21 -0
  188. data/Views/Network/Restriction.rb +37 -0
  189. data/Views/Network/Share.rb +167 -0
  190. data/Views/Network/Tables.rb +28 -0
  191. data/Views/Network/Tabs.rb +6 -0
  192. data/Views/Person/Admin.rb +99 -0
  193. data/Views/Person/Center.rb +48 -0
  194. data/Views/Person/Course.rb +72 -0
  195. data/Views/Person/Modify.rb +153 -0
  196. data/Views/Person/Tabs.rb +162 -0
  197. data/Views/Report/ComptaExecutive.rb +221 -0
  198. data/Views/Report/ComptaFlat.rb +79 -0
  199. data/Views/Report/ReportCourse.rb +47 -0
  200. data/Views/Report/Tabs.rb +8 -0
  201. data/Views/Report/Usage.rb +52 -0
  202. data/Views/Report/UsageCases.rb +59 -0
  203. data/Views/Self/Cash.rb +67 -0
  204. data/Views/Self/Chat.rb +55 -0
  205. data/Views/Self/Concours.rb +109 -0
  206. data/Views/Self/Email.rb +34 -0
  207. data/Views/Self/Internet.rb +255 -0
  208. data/Views/Self/Results.rb +17 -0
  209. data/Views/Self/Services.rb +85 -0
  210. data/Views/Self/Show.rb +47 -0
  211. data/Views/Self/Tabs.rb +5 -0
  212. data/Views/Special/DFileEdit.rb +13 -0
  213. data/Views/Special/PlugEdit.rb +56 -0
  214. data/Views/Special/Tabs.rb +6 -0
  215. data/Views/Special/Vnc.rb +39 -0
  216. data/Views/Task/Client.rb +21 -0
  217. data/Views/Task/Edit.rb +33 -0
  218. data/Views/Task/List.rb +55 -0
  219. data/Views/Task/Tabs.rb +9 -0
  220. data/Views/Task/Worker.rb +30 -0
  221. data/Views/Template/Activity.rb +33 -0
  222. data/Views/Template/CourseType.rb +63 -0
  223. data/Views/Template/ScheduleType.rb +29 -0
  224. data/Views/Template/Tabs.rb +5 -0
  225. data/Views/Welcome.rb +121 -0
  226. data/config.yaml.default +36 -0
  227. data/po/Gestion-ar.po +2356 -0
  228. data/po/Gestion-en.mo +0 -0
  229. data/po/Gestion-en.po +4363 -0
  230. data/po/Gestion-fr.mo +0 -0
  231. data/po/Gestion-fr.po +4345 -0
  232. data/po/traduction-ar.rtf +76 -0
  233. metadata +381 -0
data/Test/ge_course.rb ADDED
@@ -0,0 +1,1114 @@
1
+ require 'test/unit'
2
+ require 'iconv'
3
+ require 'base64'
4
+ #require 'ftools'
5
+
6
+
7
+ class TC_Course < Test::Unit::TestCase
8
+
9
+ def setup
10
+ # Permission.add( 'default', '.*' )
11
+ Permission.add('student', '.*')
12
+ Permission.add('teacher', '.*')
13
+ Entities.delete_all_data()
14
+
15
+ dputs(3) { 'Resetting SQLite' }
16
+ SQLite.dbs_close_all
17
+ FileUtils.cp('db.testGestion', 'data/compta.db')
18
+ SQLite.dbs_open_load_migrate
19
+ ConfigBase.server_url = 'http://localhost:3302/icc'
20
+ ConfigBase.block_size = 8192
21
+ ConfigBase.label_url = 'http://localhost:3302/label'
22
+ ConfigBases.init_load
23
+
24
+ @admin = Entities.Persons.create(:login_name => 'admin', :password => 'super123',
25
+ :permissions => %w(default teacher), :first_name => 'Admin', :family_name => 'The')
26
+ @admin2 = Entities.Persons.create(:login_name => 'admin2', :password => 'super123',
27
+ :permissions => %w(default teacher), :first_name => 'Admin', :family_name => 'The')
28
+ @secretaire = Entities.Persons.create(:login_name => 'secretaire', :password => 'super',
29
+ :permissions => %w(default teacher secretaire), :first_name => 'Le', :family_name => 'Secretaire')
30
+ @surf = Entities.Persons.create(:login_name => 'surf', :password => 'super',
31
+ :permissions => ['default'], :first_name => 'Internet', :family_name => 'Surfer')
32
+ @surf2 = Entities.Persons.create(:login_name => 'surf2', :password => 'super',
33
+ :permissions => ['default'], :first_name => 'Internet', :family_name => 'Surfer')
34
+ @stud1 = Entities.Persons.create(:login_name => 'stud1', :password => 'super',
35
+ :permissions => ['default'], :first_name => 'Internet', :family_name => 'Student 1')
36
+ @stud2 = Entities.Persons.create(:login_name => 'stud2', :password => 'super',
37
+ :permissions => ['default'], :first_name => 'Internet', :family_name => 'Student 2')
38
+ @maint_t = Entities.CourseTypes.create(:name => 'maint', :duration => 72,
39
+ :desciption => 'maintenance', :contents => 'lots of work',
40
+ :file_diploma => ['base_gestion.odt'], :output => 'certificate',
41
+ :diploma_type => ['simple'],
42
+ :account_base => Accounts.create_path('Root::Income::Courses'))
43
+ @maint_2 = Courses.create(:name => 'maint_1210', :start => '1.10.2012',
44
+ :end => '1.1.2013', :sign => '2.1.2012', :teacher => @secretaire,
45
+ :contents => 'lots of work', :description => 'maintenance',
46
+ :duration => 72, :responsible => @secretaire,
47
+ :ctype => @maint_t)
48
+
49
+ @it_101_t = CourseTypes.create(:name => 'it-101', :diploma_type => ['accredited'],
50
+ :output => %w( label ), :file_diploma => %w( label.odg ),
51
+ :contents => 'it-101', :description => 'windows, word, excel')
52
+ @it_101 = Courses.create_ctype(@it_101_t, '1203')
53
+ @it_101.data_set_hash(:responsible => @secretaire, :teacher => @surf,
54
+ :start => '1.11.2012', :end => '1.2.2013', :sign => '10.2.2013',
55
+ :students => %w( secretaire surf ))
56
+
57
+ @net_t = CourseTypes.create(:name => 'it-301', :description => 'Networking')
58
+ @net = Entities.Courses.create(:name => 'net_1001',
59
+ :ctype => @net_t)
60
+
61
+ @base = Entities.Courses.create(:name => 'base_1004', :ctype => @it_101_t)
62
+
63
+ @maint = Entities.Courses.create(:name => 'maint_1204', :start => '19.01.2012', :end => '18.02.2012',
64
+ :dow => 'lu-ve', :teacher => @secretaire, :ctype => @maint_t)
65
+ @maint.students = %w( admin surf )
66
+ @base.students = %w( admin2 surf )
67
+
68
+
69
+ @center = Persons.create(:login_name => 'foo', :permissions => ['center'],
70
+ :address => 'B.P. 1234', :town => 'Sansibar',
71
+ :phone => '+23599999999', :email => 'profeda@gmail.com')
72
+ @center.password = @center.password_plain = '1234'
73
+
74
+ @admin_session = Sessions.create(@admin, 'default')
75
+
76
+ @accountant = Persons.create(:login_name => 'accountant',
77
+ :permissions => ['accountant'])
78
+ end
79
+
80
+ def teardown
81
+ permissions_init
82
+ #Entities.delete_all_data()
83
+
84
+ #dputs(1){"Resetting SQLite"}
85
+ #SQLite.dbs_close_all
86
+ #FileUtils.cp( "db.testGestion", "data/compta.db" )
87
+ #SQLite.dbs_open_load_migrate
88
+ #Entities.Persons.save
89
+ #Entities.LogActions.save
90
+ end
91
+
92
+ def test_add_student
93
+ assert_equal %w( secretaire surf ), @it_101.students.sort
94
+ assert_equal %w( admin surf ), @maint.students.sort
95
+ assert_equal %w( admin2 surf ), @base.students.sort
96
+
97
+ @maint.students_add @surf2
98
+ assert_equal %w( admin surf surf2 ), @maint.students.sort
99
+
100
+ @maint.students_add @stud1.login_name
101
+ assert_equal %w( admin stud1 surf surf2 ), @maint.students.sort
102
+
103
+ @base.students_add [@stud1, @stud2]
104
+ assert_equal %w( admin2 stud1 stud2 surf ), @base.students.sort
105
+
106
+ @base.students_del [@stud1, @stud2]
107
+ assert_equal %w( admin2 surf ), @base.students.sort
108
+
109
+ @base.students_add [@stud1.login_name, @stud2]
110
+ assert_equal %w( admin2 stud1 stud2 surf ), @base.students.sort
111
+ end
112
+
113
+ def test_print
114
+ View.CourseModify.rpc_button_print_student(@admin_session,
115
+ {'name' => @it_101.name})
116
+ end
117
+
118
+ def test_search
119
+ courses_admin2 = Courses.search_by_students('^admin2$')
120
+ assert_equal 1, courses_admin2.length
121
+ Entities.save_all
122
+ Entities.delete_all_data(true)
123
+ Entities.load_all
124
+ ConfigBases.init_load
125
+ #dp Courses.search_all_.inspect
126
+ courses_admin2 = Courses.search_by_students('^admin2$')
127
+ assert_equal 1, courses_admin2.length
128
+
129
+ RPCQooxdooHandler.request(1, 'View.CourseModify', 'button', [['default', 'bulk_students',
130
+ {'name' => 'net_1001', 'names' => 'Dmin A'}]])
131
+ RPCQooxdooHandler.request(1, 'View.CourseModify', 'button', [['default', 'create_new',
132
+ {'name' => 'net_1001', 'double_name' => 'Dmin A'}]])
133
+ courses_admin2 = Courses.search_by_students('admin2')
134
+ courses_admin3 = Courses.search_by_students('admin3')
135
+ courses_surf = Courses.search_by_students('surf')
136
+ assert_equal 1, courses_admin2.length, Courses.search_all.inspect
137
+ assert_equal 1, courses_admin3.length, Courses.search_all.inspect
138
+ assert_equal 3, courses_surf.length
139
+ end
140
+
141
+ COURSE_STR = "base_gestion\nAdmin The\n Le Secretaire\n 72\n Cours de base\n Word\nExcel\nLinux\n\n 1er février 03\n 4 mai 03\n 4 juin 03\nP Admin The\n\nNP Internet Surfer\nhttp://ndjair.net\n"
142
+
143
+ # Check different assertions of missing stuff and students
144
+ def test_diploma_export
145
+ assert_equal %w( start end sign duration teacher responsible description contents ),
146
+ @net.export_check
147
+
148
+ @net.start = '01.02.03'
149
+ @net.end = '04.05.03'
150
+ @net.sign = '04.06.03'
151
+ @net.duration = 72
152
+ @net.teacher = @admin
153
+ @net.responsible = @secretaire
154
+ @net.description = 'Cours de base'
155
+ @net.contents = "Word\nExcel\nLinux"
156
+
157
+ assert_nil @net.export_check
158
+
159
+ assert_equal "base_gestion\nAdmin The\n Le Secretaire\n 72\n Cours de base\n Word\nExcel\nLinux\n\n 1er février 03\n 4 mai 03\n 4 juin 03\n",
160
+ @net.export_diploma
161
+
162
+ @net.students = %w( admin surf )
163
+
164
+ Entities.Grades.save_data({:student => @admin,
165
+ :course => @net, :means => [11]})
166
+ Entities.Grades.save_data({:student => @surf,
167
+ :course => @net, :means => [9], :remark => 'http://ndjair.net'})
168
+
169
+ assert_equal COURSE_STR, @net.export_diploma
170
+ end
171
+
172
+ def notest_diploma_import
173
+ # TODO:
174
+ # As soon as value_entity are known to work OK, one has to replace
175
+ # Course.teacher and Course.responsible with value_entity_person
176
+ course = Courses.from_diploma('net_1001', COURSE_STR)
177
+ @grade_admin = Entities.Grades.match_by_course_person(@net, @admin)
178
+ assert_not_nil @grade_admin
179
+ assert_equal 10, @grade_admin.mean
180
+ assert_equal %w( 01.02.2003 04.05.2003 04.06.2003 72 admin secretaire ),
181
+ course.data_get(%w( start end sign duration teacher responsible ))
182
+ dputs(1) { @course.inspect }
183
+ end
184
+
185
+ def test_print_presence
186
+ assert_equal '/tmp/0-presence_sheet_small.pdf', @maint.print_presence
187
+ end
188
+
189
+ def test_person_courses
190
+ courses = Entities.Courses.list_courses_for_person(@admin)
191
+ assert_equal [[@maint.id, 'maint_1204']], courses
192
+
193
+ courses = Entities.Courses.list_courses_for_person(@admin.login_name)
194
+ assert_equal [[@maint.id, 'maint_1204']], courses
195
+ end
196
+
197
+ def test_new_course
198
+ nmaint = Courses.create_ctype(@maint_t, '1201')
199
+ assert_equal({:duration => 72, :course_id => 6, :contents => 'lots of work',
200
+ :students => [], :name => 'maint_1201', :ctype => [1],
201
+ :salary_teacher => nil, :cost_student => nil},
202
+ nmaint.to_hash)
203
+
204
+ nmaint2 = Courses.create_ctype(@maint_t, '1201')
205
+ assert_equal 'maint_1201-2', nmaint2.name
206
+
207
+ ConfigBase.add_function(:course_server)
208
+ it_101 = Courses.create_ctype(@it_101_t, '1202', @surf)
209
+ assert_equal({:ctype => [2],
210
+ :course_id => 8,
211
+ :students => [],
212
+ :name => 'it-101_1202',
213
+ :contents => 'it-101',
214
+ :description => 'windows, word, excel',
215
+ :salary_teacher => nil, :cost_student => nil}, it_101.to_hash)
216
+
217
+ it_101 = Courses.create_ctype(@it_101_t, '1202', @center)
218
+ assert_equal({:ctype => [2],
219
+ :course_id => 9,
220
+ :students => [],
221
+ :center => [@center.id],
222
+ :name => 'foo_it-101_1202',
223
+ :contents => 'it-101',
224
+ :description => 'windows, word, excel',
225
+ :salary_teacher => nil, :cost_student => nil}, it_101.to_hash)
226
+ end
227
+
228
+ def test_create_account
229
+ ConfigBase.add_function :accounting_courses
230
+ nmaint = Courses.create_ctype(@maint_t, '1201')
231
+
232
+ assert_equal 'Root::Income::Courses::maint_1201', nmaint.entries.get_path
233
+ end
234
+
235
+ def test_prepare_diplomas
236
+ dputs(1) { "Checking for diplomas in #{@maint_2.dir_diplomas}" }
237
+ dputs(5) { @maint_2.inspect }
238
+ dputs(5) { Grades.search_all.inspect }
239
+ @maint_2.prepare_diplomas(false)
240
+ @maint_2.thread.join
241
+ assert_equal 0, Dir.glob("#{@maint_2.dir_diplomas}/*").count
242
+
243
+ @maint_2.students_add 'secretaire'
244
+ @maint_2.prepare_diplomas(false)
245
+ @maint_2.thread.join
246
+ assert_equal 0, Dir.glob("#{@maint_2.dir_diplomas}/*").count
247
+
248
+ @grade0 = Grades.save_data({:student => @secretaire,
249
+ :course => @maint_2, :means => [9]})
250
+ @maint_2.prepare_diplomas(false)
251
+ @maint_2.thread.join
252
+ assert_equal 0, Dir.glob("#{@maint_2.dir_diplomas}/*").count
253
+
254
+
255
+ @grade0 = Grades.save_data({:student => @secretaire,
256
+ :course => @maint_2, :means => [11]})
257
+ @secretaire.role_diploma = 'Director'
258
+ assert @secretaire, @maint_2.teacher.inspect
259
+ @maint_2.prepare_diplomas(false)
260
+ @maint_2.thread.join
261
+ assert_equal 1, Dir.glob("#{@maint_2.dir_diplomas}/*odt").count
262
+ end
263
+
264
+ def test_print_diplomas
265
+ ConfigBase.add_function :course_server
266
+
267
+ @maint_2.students_add 'secretaire'
268
+ Grades.search_all.each { |g|
269
+ dputs(1) { g.inspect }
270
+ }
271
+ @grade0 = Grades.save_data({:student => @secretaire,
272
+ :course => @maint_2, :means => [11]})
273
+ Grades.search_all.each { |g|
274
+ dputs(1) { g.inspect }
275
+ dputs(1) { "Grade #{g.grade_id}: #{g.course.name} - #{g.student.login_name}" }
276
+ }
277
+ @maint_2.prepare_diplomas
278
+
279
+ while (files = Dir.glob("#{@maint_2.dir_diplomas}/*{png,zip}")).count != 2 do
280
+ dputs(1) { "Waiting for diplomas: #{files.inspect}" }
281
+ sleep 1
282
+ end
283
+ end
284
+
285
+ def test_print_reports
286
+ ConfigBase.add_function :course_server
287
+
288
+ @maint_t.diploma_type = [:report]
289
+ @maint_t.tests_str = %w( one two three ).join("\n")
290
+ @maint_t.file_diploma = %w(base_report.odt)
291
+ assert_equal 3, @maint_t.tests_nbr
292
+ assert_equal %w(one two three), @maint_t.tests_arr
293
+
294
+ @maint_2.students_add 'secretaire'
295
+ Grades.search_all.each { |g|
296
+ dputs(1) { g.inspect }
297
+ }
298
+ @grade0 = Grades.save_data({:student => @secretaire,
299
+ :course => @maint_2, :means => [11, 12, 13]})
300
+ Grades.search_all.each { |g|
301
+ dputs(1) { g.inspect }
302
+ dputs(1) { "Grade #{g.grade_id}: #{g.course.name} - #{g.student.login_name}" }
303
+ }
304
+ @maint_2.prepare_diplomas
305
+
306
+ while Dir.glob("#{@maint_2.dir_diplomas}/*{png,zip}").count != 2 do
307
+ dputs(1) { 'Waiting for diplomas' }
308
+ sleep 1
309
+ end
310
+ end
311
+
312
+ def test_print_exam_file
313
+ ConfigBase.template_dir = 'Diplomas'
314
+ english_t = CourseTypes.create(name: 'english', diploma_lang: ['en'],
315
+ tests_str: "Oral\nWritten\nExpression",
316
+ tests_nbr: 3, file_exam: ['exam_language.odt'])
317
+ english = Courses.create_ctype(english_t, '1502')
318
+ students = (1..7).collect { %w(stud1 stud2) }.flatten
319
+ english.data_set_hash(students: students, start: '1.1.2015', end: '28.2.2015',
320
+ teacher: @surf, responsible: @secretaire)
321
+
322
+ assert english.print_exam_file
323
+ end
324
+
325
+ def test_migration_2
326
+ Entities.delete_all_data()
327
+
328
+ dputs(1) { 'Resetting SQLite' }
329
+ SQLite.dbs_close_all
330
+ FileUtils.cp('db.testGestion', 'data/compta.db')
331
+ SQLite.dbs_open_load_migrate
332
+ ConfigBases.init_load
333
+
334
+ @admin = Entities.Persons.create(:login_name => 'admin', :password => 'super123',
335
+ :permissions => %w(default teacher), :first_name => 'Admin', :family_name => 'The')
336
+ @linus = Entities.Persons.create(:login_name => 'linus', :password => 'super123',
337
+ :permissions => %w(default teacher), :first_name => 'Linus', :family_name => 'Torvalds')
338
+ @maint = Entities.Courses.create(:name => 'maint_1204', :start => '19.01.2012', :end => '18.02.2012',
339
+ :teacher => @admin, :assistant => 0,
340
+ :responsible => @linus)
341
+ @maint2 = Entities.Courses.create(:name => 'maint_1208', :start => '19.01.2012', :end => '18.02.2012',
342
+ :teacher => @admin, :assistant => @linus,
343
+ :responsible => @linus)
344
+
345
+ dputs(1) { "Courses are #{Courses.search_all.inspect}" }
346
+ Courses.migrate
347
+ dputs(1) { "Courses are #{Courses.search_all.inspect}" }
348
+
349
+ @maint = Courses.match_by_name('maint_1204')
350
+ assert_equal @admin, @maint.teacher
351
+ assert_equal nil, @maint.assistant
352
+ assert_equal @linus, @maint.responsible
353
+
354
+ @maint2 = Courses.match_by_name('maint_1208')
355
+ assert_equal @admin, @maint2.teacher
356
+ assert_equal @linus, @maint2.assistant
357
+ assert_equal @linus, @maint2.responsible
358
+ end
359
+
360
+ def test_spaces
361
+ @ct = CourseTypes.create(:name => 'base arabe 1')
362
+ assert_equal 'base_arabe_1', @ct.name
363
+
364
+ @c1 = Courses.create(:name => 'base_arabe 1201', :ctype => @ct)
365
+ assert_equal 'base_arabe_1201', @c1.name
366
+ end
367
+
368
+ def test_duration_adds
369
+ dputs(1) { "@maint is #{@maint.inspect}" }
370
+ @maint.dow = ['lu-me-ve']
371
+ @maint.end = '30.01.2012'
372
+ assert_equal [6, [[/1001/, 0], [/1002/, 2], [/1003/, 4], [/1004/, 7],
373
+ [/1005/, 9], [/1006/, 11]]],
374
+ @maint.get_duration_adds
375
+
376
+ @maint.dow = ['lu-ve']
377
+ @maint.end = '30.01.2012'
378
+ assert_equal [10,
379
+ [[/1001/, 0], [/1002/, 1], [/1003/, 2], [/1004/, 3], [/1005/, 4],
380
+ [/1006/, 7], [/1007/, 8], [/1008/, 9], [/1009/, 10], [/1010/, 11]]],
381
+ @maint.get_duration_adds
382
+ end
383
+
384
+ def test_zip
385
+ center = @center.login_name
386
+ @maint_2.students = %w( admin surf secretaire )
387
+ @maint_2.center = @center
388
+ @maint_t.diploma_type = [:'files']
389
+
390
+ FileUtils.rm_rf 'Exams'
391
+ FileUtils.mkdir 'Exams'
392
+
393
+ file = @maint_2.zip_create(for_server: false)
394
+ file_tmp = "/tmp/#{file}"
395
+ file_exa_tmp = "/tmp/exa-#{file}"
396
+ assert_not_nil file
397
+
398
+ FileUtils.copy(file_tmp, file_exa_tmp)
399
+ @maint_2.zip_read
400
+
401
+ assert File.exists?("Exams/#{@maint_2.name}")
402
+ assert(!File.exists?("Exams/#{@maint_2.name}/#{center}-admin"))
403
+
404
+ FileUtils.copy(file_tmp, file_exa_tmp)
405
+ Zip::File.open(file_exa_tmp) { |z|
406
+ %w( admin surf ).each { |s|
407
+ p = "exa-#{@maint_2.name}/#{s}"
408
+ z.file.open("#{p}/first.doc", 'w') { |f| f.puts 'Hello world' }
409
+ }
410
+ }
411
+
412
+ @maint_2.zip_read
413
+ %w( admin surf ).each { |s|
414
+ dir = "Exams/#{@maint_2.name}/#{s}"
415
+ assert File.exists? dir
416
+ assert File.exists? "#{dir}/first.doc"
417
+ }
418
+ dir = "Exams/#{@maint_2.name}/secretaire"
419
+ assert File.exists?(dir)
420
+ assert !File.exists?("#{dir}/first.doc")
421
+
422
+ assert ['first.doc'], @maint_2.exam_files('admin').join(':')
423
+ assert [], @maint_2.exam_files('secretaire').join(':')
424
+ end
425
+
426
+ def test_label
427
+ ConfigBase.add_function :course_server
428
+
429
+ @it_101_t.diploma_type = %w( accredited )
430
+ dputs(1) { "it_101 is #{@it_101.class}" }
431
+ @grade0 = Grades.save_data({:student => @secretaire,
432
+ :course => @it_101, :mean => 11, :means => [11]})
433
+ @it_101.prepare_diplomas(true)
434
+
435
+ while (files = Dir.glob("#{@it_101.dir_diplomas}/*{png,zip}")).count != 2 do
436
+ dputs(1) { "Waiting for diplomas - #{files.inspect}" }
437
+ sleep 1
438
+ end
439
+ end
440
+
441
+ def test_get_url_label
442
+ ConfigBase.add_function :course_server
443
+
444
+ @grade0 = Grades.create({:student => @secretaire,
445
+ :course => @maint_2, :mean => 11, :means => [11]})
446
+
447
+ dputs(1) { "grade0 is #{@grade0.inspect}" }
448
+ assert @grade0.random
449
+ assert @grade0.get_url_label =~ /^http:\/\//
450
+ dputs(1) { "URL-label is #{@grade0.get_url_label}" }
451
+ assert @grade0.random
452
+
453
+ ConfigBase.label_url = 'profeda.org'
454
+ assert @grade0.get_url_label =~ /^http:\/\/profeda.org/
455
+ ConfigBase.label_url = 'http://profeda.org'
456
+ assert @grade0.get_url_label =~ /^http:\/\/profeda.org/
457
+ end
458
+
459
+ def test_random_match
460
+ ConfigBase.add_function :course_server
461
+
462
+ @grade0 = Grades.create({:student => @secretaire,
463
+ :course => @maint_2, :mean => 11, :means => [11]})
464
+
465
+ assert @grade0.random
466
+ assert_equal @grade0, Grades.match_by_random(@grade0.random)
467
+ end
468
+
469
+ def test_print_label
470
+ ConfigBase.add_function :course_server
471
+ @grade0 = Grades.create({:student => @secretaire,
472
+ :course => @maint_2, :mean => 11, :means => [11]})
473
+ @maint_t.data_set_hash({:output => ['label'], :central_name => 'foo',
474
+ :file_diploma => ['label.odg'],
475
+ :diploma_type => ['simple']})
476
+ @maint_2.students_add 'secretaire'
477
+ Grades.search_all.each { |g|
478
+ dputs(1) { "Grade #{g.grade_id}: #{g.course.name} - #{g.student.login_name}" }
479
+ }
480
+ @maint_2.prepare_diplomas
481
+
482
+ while (files = Dir.glob("#{@maint_2.dir_diplomas}/*{png,zip}")).count != 2 do
483
+ dputs(1) { "Waiting for diplomas - #{files.inspect}" }
484
+ sleep 1
485
+ end
486
+ end
487
+
488
+ def test_files_move
489
+ @maint_t.data_set_hash({:output => ['label'], :central_name => 'foo',
490
+ :file_diploma => ['label.odg'],
491
+ :diploma_type => ['simple']})
492
+ students = %w( secretaire admin surf )
493
+ @maint_2.students.concat students
494
+
495
+ FileUtils.rm_rf(@maint_2.dir_exams)
496
+ FileUtils.rm_rf(@maint_2.dir_exams_share)
497
+
498
+ @maint_2.exas_prepare_files
499
+ assert !File.exists?(@maint_2.dir_exams)
500
+ assert File.exists?(@maint_2.dir_exams_share)
501
+ students.each { |s|
502
+ student_dir = "#{@maint_2.dir_exams_share}/#{s}"
503
+ assert File.exists?(student_dir)
504
+ FileUtils.touch "#{student_dir}/exa.doc"
505
+ }
506
+
507
+ @maint_2.exas_fetch_files
508
+ assert File.exists?(@maint_2.dir_exams)
509
+ assert !File.exists?(@maint_2.dir_exams_share)
510
+ students.each { |s|
511
+ student_dir = "#{@maint_2.dir_exams}/#{s}"
512
+ assert File.exists?(student_dir)
513
+ assert File.exists?("#{student_dir}/exa.doc")
514
+ }
515
+ end
516
+
517
+ def test_sync
518
+ @port = 3302
519
+ main = Thread.new {
520
+ QooxView::startWeb(@port)
521
+ }
522
+ dputs(1) { "Starting at port #{@port}" }
523
+ sleep 1
524
+ cname = "#{@center.login_name}_"
525
+
526
+ @maint_t.data_set_hash({:output => ['label'],
527
+ :file_diploma => ['label.odg'],
528
+ :name => 'it-101',
529
+ :diploma_type => ['accredited']})
530
+
531
+ students = %w( secretaire admin surf )
532
+ @maint_2.students.concat students
533
+ @grade0 = Grades.create({:student => @secretaire,
534
+ :course => @maint_2, :mean => 11, :means => [11]})
535
+
536
+ @maint_2.exas_prepare_files
537
+ @maint_2.exas_fetch_files
538
+ students[0..1].each { |s|
539
+ student_dir = "#{@maint_2.dir_exams}/#{s}"
540
+ FileUtils.touch("#{student_dir}/exa.doc")
541
+ }
542
+
543
+ assert_equal [], Persons.search_by_login_name("^#{cname}")
544
+ assert_equal nil, Courses.find_by_name("^#{cname}")
545
+
546
+ @maint_2.sync_do
547
+
548
+ main.kill.join
549
+
550
+ foo_maint = Courses.find_by_name("^#{cname}")
551
+ names = Persons.search_by_login_name("^#{cname}").collect { |p|
552
+ p.login_name
553
+ }
554
+ assert_equal %w(foo_secretaire foo_admin foo_surf), names
555
+ assert_equal 'foo_maint_1210', foo_maint.name
556
+ assert_equal 'foo', foo_maint._center.login_name
557
+
558
+ dputs(1) { "Diploma-dir is #{foo_maint.dir_exas}" }
559
+
560
+ assert File.exists? foo_maint.dir_exams
561
+ end
562
+
563
+ # Syncs, aborts and sends again, checking if only new files are transmitted
564
+ def test_resync_files
565
+ students = %w( secretaire admin surf )
566
+ @maint_2.students = students
567
+
568
+ @maint_2.name = "foo_#{@maint_2.name}"
569
+ dputs(3) { "Clearing directory #{@maint_2.dir_exams}" }
570
+ FileUtils.rm_rf @maint_2.dir_exams
571
+ @maint_2.check_students_dir
572
+ students[0..1].each { |s|
573
+ student_dir = "#{@maint_2.dir_exams}/#{s}"
574
+ dputs(2) { "Adding a simple doc to #{student_dir}" }
575
+ FileUtils.touch("#{student_dir}/exa.doc")
576
+ }
577
+
578
+ # Test md5-sums
579
+ files_hash = @maint_2.md5_exams
580
+ assert_equal files_hash,
581
+ Courses.icc_exams_here({user: 'foo', data: @maint_2.name})
582
+ assert_equal({'secretaire' => [%w(exa.doc d41d8cd98f00b204e9800998ecf8427e)],
583
+ 'admin' => [%w(exa.doc d41d8cd98f00b204e9800998ecf8427e)],
584
+ 'surf' => []}, files_hash)
585
+
586
+ # Test normal creation of zip-file
587
+ @maint_2.name = @maint_2.name.sub(/^foo_/, '')
588
+ dputs(3) { "Clearing directory #{@maint_2.dir_exams}" }
589
+ FileUtils.rm_rf @maint_2.dir_exams
590
+ @maint_2.check_students_dir
591
+ students[0..1].each { |s|
592
+ student_dir = "#{@maint_2.dir_exams}/#{s}"
593
+ dputs(2) { "Adding a simple doc to #{student_dir}" }
594
+ FileUtils.touch("#{student_dir}/exa.doc")
595
+ }
596
+ zip = @maint_2.zip_create
597
+ Zip::File.open("/tmp/#{zip}") { |f|
598
+ assert_nothing_raised {
599
+ f.read('exa-foo_maint_1210/foo_secretaire/exa.doc')
600
+ f.read('exa-foo_maint_1210/foo_admin/exa.doc')
601
+ }
602
+ assert_equal [], JSON.parse(f.read('exa-foo_maint_1210/files_excluded'))
603
+ }
604
+
605
+ # Test ignoring files already there
606
+ FileUtils.touch("#{@maint_2.dir_exams}/surf/exa.doc")
607
+ FileUtils.touch("#{@maint_2.dir_exams}/secretaire/exa2.doc")
608
+ zip = @maint_2.zip_create(md5sums: files_hash)
609
+ exams = []
610
+ Zip::File.open("/tmp/#{zip}") { |zf|
611
+ zf.each { |f|
612
+ f.name =~ /\.doc$/ and exams.push f.name
613
+ }
614
+ assert_equal %w(admin/exa.doc secretaire/exa.doc),
615
+ JSON.parse(zf.read('exa-foo_maint_1210/files_excluded'))
616
+ }
617
+ assert_equal %w(exa-foo_maint_1210/foo_secretaire/exa2.doc exa-foo_maint_1210/foo_surf/exa.doc),
618
+ exams
619
+
620
+ # Test adding files already there but with other md5sum
621
+ files_hash = @maint_2.md5_exams
622
+ File.open("#{@maint_2.dir_exams}/surf/exa.doc", 'w') { |f| f.write('hello') }
623
+ zip = @maint_2.zip_create(md5sums: files_hash)
624
+ exams = []
625
+ Zip::File.open("/tmp/#{zip}") { |zf|
626
+ zf.each { |f|
627
+ f.name =~ /\.doc$/ and exams.push f.name
628
+ }
629
+ assert_equal %w( admin/exa.doc secretaire/exa.doc secretaire/exa2.doc),
630
+ JSON.parse(zf.read('exa-foo_maint_1210/files_excluded'))
631
+ }
632
+ assert_equal %w(exa-foo_maint_1210/foo_surf/exa.doc), exams
633
+
634
+ # Test merging of directory with additional (to-be-deleted) files and
635
+ # copying of files not transferred but locally available
636
+ files_hash = @maint_2.md5_exams
637
+ FileUtils.touch("#{@maint_2.dir_exams}/secretaire/exa3.doc")
638
+ FileUtils.touch("#{@maint_2.dir_exams}/secretaire/exa5.doc")
639
+ zip = @maint_2.zip_create(for_server: false, md5sums: files_hash)
640
+ FileUtils.touch("#{@maint_2.dir_exams}/secretaire/exa4.doc")
641
+ FileUtils.rm("#{@maint_2.dir_exams}/secretaire/exa5.doc")
642
+ @maint_2.zip_read("/tmp/#{zip}")
643
+ assert File.exists?("#{@maint_2.dir_exams}/surf/exa.doc"),
644
+ "Didn't restore non-transferred file"
645
+ assert File.exists?("#{@maint_2.dir_exams}/secretaire/exa3.doc"),
646
+ "Didn't add transferred file"
647
+ assert File.exists?("#{@maint_2.dir_exams}/secretaire/exa5.doc"),
648
+ "Didn't add transferred but deleted file"
649
+ assert !File.exists?("#{@maint_2.dir_exams}/secretaire/exa4.doc"),
650
+ "Didn't delete additional file"
651
+ end
652
+
653
+ def write_file(name, str = 'Hello world, how are you?')
654
+ File.open(name, 'w') { |f|
655
+ f.write(str)
656
+ }
657
+ end
658
+
659
+ def test_sync_exams
660
+ students = %w( admin secretaire surf )
661
+ @maint_2.students = students
662
+
663
+ # Test normal creation of zip-file
664
+ @maint_2.name = @maint_2.name.sub(/^foo_/, '')
665
+ dputs(3) { "Clearing directory #{@maint_2.dir_exams}" }
666
+ FileUtils.rm_rf @maint_2.dir_exams
667
+ @maint_2.check_students_dir
668
+ students[0..1].each { |s|
669
+ student_dir = "#{@maint_2.dir_exams}/#{s}"
670
+ dputs(2) { "Adding a simple doc to #{student_dir}" }
671
+ write_file("#{student_dir}/exa.doc")
672
+ }
673
+ write_file("#{@maint_2.dir_exams}/secretaire/exa2.doc", 'hi')
674
+ write_file("#{@maint_2.dir_exams}/surf/exa.doc")
675
+ write_file("#{@maint_2.dir_exams}/surf/zpresentation.doc")
676
+
677
+ ConfigBase.max_upload_size = 10
678
+ zips = @maint_2.zip_create_chunks(@maint_2.md5_exams, {})
679
+ assert_equal 4, zips.length
680
+
681
+ files = %w( exa-foo_maint_1210/foo_admin/exa.doc exa-foo_maint_1210/foo_secretaire/exa.doc
682
+ exa-foo_maint_1210/foo_secretaire/exa2.doc,exa-foo_maint_1210/foo_surf/exa.doc
683
+ exa-foo_maint_1210/foo_surf/zpresentation.doc )
684
+ files_server = []
685
+ zips.each { |zip|
686
+ dputs(2) { "Working with #{zip}" }
687
+ exams = []
688
+ excluded = ''
689
+ Zip::File.open("/tmp/#{zip}") { |zf|
690
+ zf.each { |f|
691
+ f.name =~ /\.doc$/ and exams.push f.name
692
+ }
693
+ excluded = JSON.parse(zf.read('exa-foo_maint_1210/files_excluded'))
694
+ }
695
+ assert_equal files.first, exams.join(',')
696
+ assert_equal files_server.join(','), excluded.join(',')
697
+ files_server.push files.shift.gsub(/exa-foo_maint_1210.foo_/, '')
698
+ }
699
+ end
700
+
701
+ def test_random_id
702
+ @port = 3302
703
+ main = Thread.new {
704
+ QooxView::startWeb(@port)
705
+ }
706
+ dputs(1) { "Starting at port #{@port}" }
707
+ sleep 1
708
+ cname = "#{@center.login_name}_"
709
+
710
+ @maint_t.data_set_hash({:output => ['label'],
711
+ :file_diploma => ['label.odg'],
712
+ :name => 'it-101',
713
+ :diploma_type => ['accredited']})
714
+
715
+ students = %w( secretaire admin surf )
716
+ @maint_2.students.concat students
717
+ @grade0 = Grades.create({:student => @secretaire,
718
+ :course => @maint_2, :mean => 11, :means => [11]})
719
+ @grade1 = Grades.create({:student => @admin,
720
+ :course => @maint_2, :mean => 15, :means => [15]})
721
+
722
+ @maint_2.exas_prepare_files
723
+ @maint_2.exas_fetch_files
724
+ students[0..1].each { |s|
725
+ student_dir = "#{@maint_2.dir_exams}/#{s}"
726
+ FileUtils.touch("#{student_dir}/exa.doc")
727
+ }
728
+
729
+ assert_equal nil, @grade0.random
730
+ assert_equal [], Persons.search_by_login_name("^#{cname}")
731
+ assert_equal nil, Courses.find_by_name("^#{cname}")
732
+
733
+ ConfigBase.add_function :course_server
734
+ @maint_2.sync_do
735
+
736
+ foo_maint = Courses.find_by_name("^#{cname}")
737
+ foo_grade = Grades.match_by_course_person(foo_maint, 'foo_secretaire')
738
+ names = Persons.search_by_login_name("^#{cname}").collect { |p|
739
+ p.login_name
740
+ }
741
+ assert_equal %w(foo_secretaire foo_admin foo_surf), names
742
+ assert_equal 'foo_maint_1210', foo_maint.name
743
+ assert_equal 'foo', foo_maint._center.login_name
744
+ Grades.search_all.each { |g|
745
+ dputs(1) { "Grade #{g.grade_id}: #{g.course.name}-#{g.student.login_name}-#{g.random}" }
746
+ }
747
+ assert foo_grade.random
748
+ assert @grade0.random
749
+ assert_equal foo_grade.random, @grade0.random
750
+
751
+ random = foo_grade.random
752
+
753
+ ConfigBase.add_function :course_client
754
+ @grade0.means = [11]
755
+ assert_equal random, @grade0.random
756
+ @grade0.means = [14]
757
+ assert_equal nil, @grade0.random
758
+
759
+ ConfigBase.add_function :course_server
760
+ dputs(1) { "ConfigBase has #{ConfigBase.get_functions.inspect}" }
761
+ @maint_2.sync_do
762
+ assert_equal random, @grade0.random
763
+
764
+ @grade0.remark = 'foo'
765
+ assert_equal random, @grade0.random
766
+ ConfigBase.add_function :course_client
767
+ @grade0.remark = 'foo'
768
+ assert_equal random, @grade0.random
769
+ @grade0.remark = 'foo bar'
770
+ assert_equal nil, @grade0.random
771
+
772
+ ConfigBase.add_function :course_server
773
+ dputs(1) { "ConfigBase has #{ConfigBase.get_functions.inspect}" }
774
+ @maint_2.sync_do
775
+ assert_equal random, @grade0.random
776
+
777
+ main.kill
778
+ end
779
+
780
+ def test_wrong_password
781
+ @port = 3302
782
+ main = Thread.new {
783
+ QooxView::startWeb(@port)
784
+ }
785
+ dputs(1) { "Starting at port #{@port}" }
786
+ sleep 1
787
+ ConfigBase.server_url = "http://localhost:#{@port}/icc"
788
+
789
+ dputs(1) { @center.inspect }
790
+ dputs(1) { Persons.find_by_permissions(:center).inspect }
791
+ assert @it_101.sync_do
792
+ assert_equal('<li>Transferring responsibles: OK</li><li>Transferring users: OK</li>' +
793
+ '<li>Transferring course: OK</li><li>Demander ce qui existe déjà: OK</li>' +
794
+ '<li>Transferring exams: OK</li>It is finished!',
795
+ @it_101.sync_state)
796
+
797
+ @center.password_plain = ''
798
+
799
+ assert !@it_101.sync_do
800
+ assert_equal(
801
+ '<li>Transferring responsibles: Error: authentication',
802
+ @it_101.sync_state)
803
+
804
+ @center.password = ''
805
+ assert @it_101.sync_do
806
+ assert_equal('<li>Transferring responsibles: OK</li><li>Transferring users: OK</li>' +
807
+ '<li>Transferring course: OK</li><li>Demander ce qui existe déjà: OK</li>' +
808
+ '<li>Transferring exams: OK</li>It is finished!',
809
+ @it_101.sync_state)
810
+
811
+ main.kill
812
+ end
813
+
814
+ def test_update_grade
815
+ @port = 3302
816
+ main = Thread.new {
817
+ QooxView::startWeb(@port)
818
+ }
819
+ dputs(1) { "Starting at port #{@port}" }
820
+ sleep 1
821
+ ConfigBase.server_url = "http://localhost:#{@port}/icc"
822
+
823
+ grade = Grades.create({:student => @surf,
824
+ :course => @it_101, :means => [11]})
825
+ assert !Courses.find_by_name('foo_')
826
+ assert !Persons.match_by_login_name('foo_secretaire')
827
+
828
+ @it_101.sync_do
829
+
830
+ foo = Courses.find_by_name('foo_')
831
+ foo_surf = Persons.match_by_login_name('foo_surf')
832
+ foo_grade = Grades.match_by_course_person(foo, foo_surf)
833
+
834
+ assert_equal [11], foo_grade.means
835
+ grade.means = [12]
836
+
837
+ @it_101.sync_do
838
+ assert_equal [12], foo_grade.means
839
+
840
+ a = {center:Persons.center._login_name, course:@it_101._name}
841
+ # dp ICC.get(:Courses, :grades_get, args: a).inspect
842
+
843
+ main.kill
844
+ end
845
+
846
+ def test_bulk
847
+ names = ['Dmin A', 'Zero', 'One Two', 'Ten Eleven Twelve', 'A B C D',
848
+ 'Hélène Méyère', 'Ñeri Soustroup']
849
+ reply = ''
850
+ while names.length > 0
851
+ dputs(4) { "Doing #{names.inspect}" }
852
+ reply = RPCQooxdooHandler.request(1, 'View.CourseModify', 'button', [['default', 'bulk_students',
853
+ {'name' => 'net_1001', 'names' => names.join("\n")}]])
854
+ assert_not_nil reply
855
+ names.shift
856
+ end
857
+ bulk = [['zero', 'Zero', ''], %w( tone One Two ), ['eten', 'Ten', 'Eleven Twelve'],
858
+ ['ca', 'A B', 'C D'], %w( mhelene Hélène Méyère )]
859
+ bulk.each { |b|
860
+ login, first, family = b
861
+ dputs(1) { "Doing #{b.inspect}" }
862
+ p = Persons.match_by_login_name(login)
863
+ dputs(5) { "p is #{p.inspect} - login is #{login.inspect}" }
864
+ assert_not_nil p, login.inspect
865
+ assert_equal login, p.login_name
866
+ assert_equal first, p.first_name
867
+ assert_equal family, p.family_name
868
+ assert_equal %w( student ), p.permissions
869
+ }
870
+
871
+ students = Courses.match_by_name('net_1001').students
872
+ assert_equal %w( ca eten mhelene s_eri tone zero ), students.sort
873
+ end
874
+
875
+ def test_add_double
876
+ RPCQooxdooHandler.request(1, 'View.CourseModify', 'button', [['default', 'create_new',
877
+ {'name' => 'net_1001', 'double_name' => 'Dmin A'}]])
878
+ RPCQooxdooHandler.request(1, 'View.CourseModify', 'button', [['default', 'accept',
879
+ {'name' => 'net_1001', 'double_proposition' => [@admin.person_id]}]])
880
+
881
+ assert_equal %w( admin admin3 ), @net.students.sort
882
+ end
883
+
884
+ def test_grade
885
+ @grade0 = Grades.save_data({:student => @secretaire,
886
+ :course => @net, :means => [11]})
887
+ assert_equal 11, @grade0[:mean]
888
+ @grade1 = Grades.save_data({:student => @surf,
889
+ :course => @net, :means => [12]})
890
+ assert_equal 12, @grade1[:mean]
891
+ @grade2 = Grades.save_data({:student => @surf,
892
+ :course => @net, :means => [13]})
893
+ assert_equal 13, @grade2[:mean]
894
+ assert_equal @grade1[:grade_id], @grade2[:grade_id]
895
+ end
896
+
897
+ def test_list_students
898
+ assert_equal [['admin2', 'Admin The - admin2:super123'],
899
+ ['surf', 'Internet Surfer - surf:super']], @base.list_students
900
+ assert_equal [[2, 'Admin The - admin2:super123'],
901
+ [4, 'Internet Surfer - surf:super']], @base.list_students(true)
902
+ end
903
+
904
+ def test_report_pdf
905
+ ConfigBase.add_function(:accounting_courses)
906
+ assert @secretaire.account_due
907
+
908
+ ctype = CourseTypes.create(:name => 'base',
909
+ :account_base => Accounts.create_path('Root::Income::Courses'))
910
+ course = Courses.create_ctype(ctype, '1404')
911
+ course.teacher = @admin
912
+ course.cost_student = 50000
913
+ stu1 = Persons.create(:login_name => 'stu1', :first_name => 'Student 1')
914
+ stu2 = Persons.create(:login_name => 'stu2', :first_name => 'Student 2')
915
+ course.students = %w(stu1 stu2)
916
+ assert course.entries
917
+
918
+ date = Date.new(2014, 4, 10)
919
+ Movements.create('For student stu1:', date - 1, 10, course.entries, @secretaire.account_due)
920
+ Movements.create('For student stu2:', date, 20.1, course.entries, @secretaire.account_due)
921
+ Movements.create('For student stu1:', date - 2, 30, course.entries, @secretaire.account_due)
922
+
923
+ file = course.report_pdf
924
+
925
+ assert file
926
+ end
927
+
928
+ def test_payment
929
+ ConfigBase.add_function(:accounting_courses)
930
+ course = Courses.create_ctype(@maint_t, '1312')
931
+ assert_equal 0, @secretaire.account_due.total
932
+
933
+ course.payment(@secretaire, @surf, 10000, Date.today)
934
+ assert_equal 10, @secretaire.account_due.total
935
+
936
+ course.payment(@secretaire, @surf, 10000, Date.today, true)
937
+ assert_equal 10, @secretaire.account_due.total
938
+ end
939
+
940
+ def test_report_list_archive
941
+ ConfigBase.add_function(:accounting_courses)
942
+ @course_acc = Courses.create_ctype(@maint_t, '1312')
943
+ @course_acc.students = ['surf']
944
+
945
+ @course_acc.payment(@secretaire, @surf, 10000, Date.new(2013))
946
+ @course_acc.payment(@secretaire, @surf, 10000, Date.new(2014))
947
+ assert_equal 20, @secretaire.account_due.total
948
+ assert_equal 20, @course_acc.entries.total
949
+ list = @course_acc.report_list
950
+ assert_equal 3, list.length
951
+
952
+ Accounts.archive(1, 2014)
953
+ assert_equal 20, @secretaire.account_due.total
954
+ assert_equal 10, @course_acc.entries.total
955
+ list = @course_acc.report_list
956
+ assert_equal 3, list.length
957
+ end
958
+
959
+ def test_transfer_student
960
+ ConfigBase.add_function(:accounting_courses)
961
+ @course_acc = Courses.create_ctype(@maint_t, '1312')
962
+ @course_acc2 = Courses.create_ctype(@maint_t, '1401')
963
+ @course_acc.students = ['surf']
964
+
965
+ @course_acc.payment(@secretaire, @surf, 10000, Date.new(2014, 1))
966
+
967
+ assert_equal 10, @secretaire.account_due.total
968
+ assert_equal 10, @course_acc.entries.total
969
+ @course_acc.transfer_student('surfs', @course_acc2)
970
+ assert_equal 10, @course_acc.entries.total
971
+ @course_acc.transfer_student('surf', @course_acc2)
972
+ assert(!@course_acc.students.index('surf'))
973
+ assert(@course_acc2.students.index('surf'))
974
+ assert_equal 0, @course_acc.entries.total
975
+ assert_equal 10, @course_acc2.entries.total
976
+ assert_equal 0, @course_acc.entries.movements.size
977
+ assert_equal 1, @course_acc2.entries.movements.size
978
+
979
+ Accounts.find_by_path('Root::Income::Courses').dump_rec(true)
980
+
981
+ @accountant.get_all_due(@secretaire)
982
+ @course_acc2.payment(@secretaire, @surf, 10000, Date.new(2014, 1, 2))
983
+ @course_acc2.transfer_student('surf', @course_acc)
984
+ assert_equal 20, @course_acc.entries.total
985
+ assert_equal 0, @course_acc2.entries.total
986
+ assert_equal 2, @course_acc.entries.movements.size
987
+ assert_equal 2, @course_acc2.entries.movements.size
988
+
989
+ Accounts.find_by_path('Root::Income::Courses').dump_rec(true)
990
+
991
+ @course_acc2.students = ['surf']
992
+ @course_acc2.payment(@secretaire, @surf, 10000, Date.new(2014, 1, 2))
993
+ @course_acc2.transfer_student('surf', @course_acc)
994
+ assert_equal 1, @course_acc2.students.size
995
+ assert_equal 10, @course_acc2.entries.total
996
+ assert_equal 1, @course_acc.students.size
997
+ assert_equal 20, @course_acc.entries.total
998
+ end
999
+
1000
+ def test_grades
1001
+ grade = Grades.create({:student => @secretaire, :course => @maint_2})
1002
+
1003
+ grade = Grades.create({:student => @secretaire, :course => @maint_2,
1004
+ :means => [11]})
1005
+ assert_equal 11.0, grade.mean
1006
+
1007
+ grade = Grades.create({:student => @secretaire, :course => @maint_2,
1008
+ :means => [21]})
1009
+ assert_equal 20.0, grade.mean
1010
+ assert_equal [20.0], grade.means
1011
+
1012
+ grade.means = [10, 30]
1013
+ assert_equal [10.0, 20.0], grade.means
1014
+ assert_equal 15.0, grade.mean
1015
+
1016
+ grade = Grades.create({:student => @secretaire, :course => @maint_2,
1017
+ :means => [10, 30]})
1018
+ assert_equal 15.0, grade.mean
1019
+ assert_equal [10.0, 20.0], grade.means
1020
+ end
1021
+
1022
+ def test_move_student
1023
+ ConfigBase.captive_dev = false
1024
+ ConfigBase.add_function(:accounting_courses)
1025
+ @accountant.update_accounts
1026
+ @course_acc = Courses.create_ctype(@maint_t, '1312')
1027
+ @course_acc.students = %w(surf surf2)
1028
+
1029
+ @course_acc.payment(@secretaire, @surf, 10000, Date.new(2013, 1))
1030
+
1031
+ assert_equal 10, @secretaire.account_due.total
1032
+ assert_equal 10, @course_acc.entries.total
1033
+ assert_equal 10, @course_acc.student_paid('surf').first.value
1034
+ assert_equal 0, @course_acc.student_paid('surf2').length
1035
+
1036
+ @course_acc.move_payment('surf', 'surf2')
1037
+
1038
+ assert_equal 10, @secretaire.account_due.total
1039
+ assert_equal 10, @course_acc.entries.total
1040
+ assert_equal 10, @course_acc.student_paid('surf2').first.value
1041
+ assert_equal 0, @course_acc.student_paid('surf').length
1042
+
1043
+ @accountant.get_all_due(@secretaire)
1044
+
1045
+ assert_equal 0, @secretaire.account_due.total
1046
+ assert_equal 10, @course_acc.entries.total
1047
+ assert_equal 10, @course_acc.student_paid('surf2').first.value
1048
+ assert_equal 0, @course_acc.student_paid('surf').length
1049
+
1050
+ @course_acc.move_payment('surf2', 'surf')
1051
+
1052
+ assert_equal 10, @course_acc.entries.total
1053
+ assert_equal 1, @course_acc.student_paid('surf').length
1054
+ assert_equal 10, @course_acc.student_paid('surf').first.value
1055
+ assert_equal 0, @course_acc.student_paid('surf2').length
1056
+
1057
+ Accounts.archive(1, 2014)
1058
+
1059
+ assert_equal 10, @course_acc.entries.total
1060
+ assert_equal 10, @course_acc.student_paid('surf').first.value
1061
+ assert_equal 0, @course_acc.student_paid('surf2').length
1062
+
1063
+ @course_acc.move_payment('surf', 'surf2')
1064
+
1065
+ assert_equal 10, @course_acc.entries.total
1066
+ assert_equal 10, @course_acc.student_paid('surf2').first.value
1067
+ assert_equal 0, @course_acc.student_paid('surf').length
1068
+
1069
+ #puts AccountRoot.archive.dump_rec( true ).join("\n")
1070
+ end
1071
+
1072
+ def test_ct_fetch
1073
+ assert_equal 'Error: no course_type_name given', CourseTypes.icc_fetch({})
1074
+ assert_equal "Error: CourseType 123 doesn't exist",
1075
+ CourseTypes.icc_fetch({course_type_names: %w( 123 )})
1076
+
1077
+ assert_equal 'it-101',
1078
+ CourseTypes.icc_fetch({course_type_names: %w( it-101 )}).
1079
+ first._name
1080
+
1081
+ assert_equal 'it-101:it-301',
1082
+ CourseTypes.icc_fetch({course_type_names: %w( it-101 it-301)}).
1083
+ map { |ct| ct._name }.join(':')
1084
+ end
1085
+
1086
+ def test_json_byte
1087
+ a = {cmd: 'hi', data: "bad\x92 value"}
1088
+ b = JSON.parse({cmd: a._cmd, data: Base64.encode64(a._data)}.to_json).to_sym
1089
+ b._data = Base64.decode64(b._data)
1090
+ assert_equal a.to_s, b.to_s
1091
+
1092
+ f = File.open('test_bytes.png') { |f| f.read }.force_encoding(Encoding::ASCII_8BIT)
1093
+ assert_equal f, f
1094
+ assert_equal f, Base64.decode64(Base64.encode64(f))
1095
+
1096
+ a = {cmd: 'hi', data: File.open('test_bytes.png') { |f| f.read }.
1097
+ force_encoding(Encoding::ASCII_8BIT)}
1098
+ b = JSON.parse({cmd: a._cmd, data: Base64.encode64(a._data)}.to_json).to_sym
1099
+ b._data = Base64.decode64(b._data)
1100
+ assert_equal a._data, b._data, 'Not the same with Base64'
1101
+
1102
+ end
1103
+
1104
+ def test_delete_ctype
1105
+ assert !@maint_t.delete
1106
+ @maint_2.delete
1107
+ @maint.delete
1108
+ assert @maint_t.delete
1109
+ end
1110
+
1111
+ def test_center
1112
+ assert_equal Persons.center, @maint.center
1113
+ end
1114
+ end