gestion 1.9.12

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.
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