cmis_server 1.0.3

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 (133) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +51 -0
  5. data/app/assets/javascripts/cmis_server/application.js +13 -0
  6. data/app/assets/stylesheets/cmis_server/application.css +15 -0
  7. data/app/controllers/cmis_server/application_controller.rb +19 -0
  8. data/app/controllers/cmis_server/atom_pub/base_controller.rb +23 -0
  9. data/app/controllers/cmis_server/atom_pub/bulk_controller.rb +302 -0
  10. data/app/controllers/cmis_server/atom_pub/content_controller.rb +178 -0
  11. data/app/controllers/cmis_server/atom_pub/entries_controller.rb +41 -0
  12. data/app/controllers/cmis_server/atom_pub/folder_collection_controller.rb +70 -0
  13. data/app/controllers/cmis_server/atom_pub/query_controller.rb +138 -0
  14. data/app/controllers/cmis_server/atom_pub/repository_controller.rb +75 -0
  15. data/app/controllers/cmis_server/atom_pub/secondary_types_controller.rb +149 -0
  16. data/app/controllers/cmis_server/atom_pub/service_documents_controller.rb +34 -0
  17. data/app/controllers/cmis_server/atom_pub/types_controller.rb +229 -0
  18. data/app/controllers/cmis_server/atom_pub/uri_templates_controller.rb +58 -0
  19. data/app/controllers/concerns/cmis_server/atom_pub/repository_scopable.rb +18 -0
  20. data/app/helpers/cmis_server/application_helper.rb +31 -0
  21. data/app/models/cmis_server/application_record.rb +5 -0
  22. data/app/services/cmis_server/bulk_update_service.rb +69 -0
  23. data/app/services/cmis_server/content_stream_service.rb +75 -0
  24. data/app/services/cmis_server/discovery_service.rb +31 -0
  25. data/app/services/cmis_server/navigation_service.rb +43 -0
  26. data/app/services/cmis_server/object_service.rb +176 -0
  27. data/app/services/cmis_server/repository_service.rb +40 -0
  28. data/app/services/cmis_server/secondary_type_service.rb +120 -0
  29. data/app/services/cmis_server/type_management_service.rb +117 -0
  30. data/app/views/cmis_server/atom_pub/bulk_update_feed.atom.builder +47 -0
  31. data/app/views/cmis_server/atom_pub/entries/_cmis_document_links.atom_entry.builder +0 -0
  32. data/app/views/cmis_server/atom_pub/entries/_cmis_folder_links.atom_entry.builder +3 -0
  33. data/app/views/cmis_server/atom_pub/entries/_object_entry.atom_entry.builder +64 -0
  34. data/app/views/cmis_server/atom_pub/entries/_property.atom_entry.builder +8 -0
  35. data/app/views/cmis_server/atom_pub/entries/object_entry.atom_entry.builder +1 -0
  36. data/app/views/cmis_server/atom_pub/entries/type_entry.atom_entry.builder +59 -0
  37. data/app/views/cmis_server/atom_pub/feeds/_feed_entry.atom_feed.builder +1 -0
  38. data/app/views/cmis_server/atom_pub/feeds/feed.atom_feed.builder +30 -0
  39. data/app/views/cmis_server/atom_pub/service_documents/_uri_template.atom_service.builder +5 -0
  40. data/app/views/cmis_server/atom_pub/service_documents/_workspace.atom_service.builder +89 -0
  41. data/app/views/cmis_server/atom_pub/service_documents/service_document.atom_service.builder +1 -0
  42. data/app/views/cmis_server/atom_pub/shared/_collection.xml.builder +7 -0
  43. data/app/views/cmis_server/atom_pub/shared/atom_entry_layout.atom_entry.builder +0 -0
  44. data/app/views/cmis_server/atom_pub/type_entry.atom.builder +69 -0
  45. data/app/views/cmis_server/atom_pub/types_feed.atom.builder +91 -0
  46. data/app/views/layouts/cmis_server/application.atom_entry.builder +2 -0
  47. data/app/views/layouts/cmis_server/application.atom_feed.builder +3 -0
  48. data/app/views/layouts/cmis_server/application.atom_service.builder +10 -0
  49. data/app/views/layouts/cmis_server/application.html.erb +14 -0
  50. data/config/routes.rb +49 -0
  51. data/lib/cmis_server/atom_pub/entry_parser.rb +72 -0
  52. data/lib/cmis_server/base_objects/base_type.rb +128 -0
  53. data/lib/cmis_server/base_objects/document.rb +68 -0
  54. data/lib/cmis_server/base_objects/folder.rb +104 -0
  55. data/lib/cmis_server/base_objects/item.rb +25 -0
  56. data/lib/cmis_server/base_types.rb +123 -0
  57. data/lib/cmis_server/cmis_object.rb +190 -0
  58. data/lib/cmis_server/configuration.rb +43 -0
  59. data/lib/cmis_server/constants.rb +8 -0
  60. data/lib/cmis_server/content_stream.rb +52 -0
  61. data/lib/cmis_server/context.rb +11 -0
  62. data/lib/cmis_server/document_object.rb +12 -0
  63. data/lib/cmis_server/document_type.rb +67 -0
  64. data/lib/cmis_server/engine.rb +60 -0
  65. data/lib/cmis_server/exceptions.rb +185 -0
  66. data/lib/cmis_server/folder_object.rb +18 -0
  67. data/lib/cmis_server/folder_type.rb +34 -0
  68. data/lib/cmis_server/id.rb +18 -0
  69. data/lib/cmis_server/item_adapter.rb +26 -0
  70. data/lib/cmis_server/item_object.rb +15 -0
  71. data/lib/cmis_server/item_type.rb +7 -0
  72. data/lib/cmis_server/object_adapter.rb +79 -0
  73. data/lib/cmis_server/property.rb +29 -0
  74. data/lib/cmis_server/property_definition.rb +118 -0
  75. data/lib/cmis_server/query/parser.output +2250 -0
  76. data/lib/cmis_server/query/parser.racc +222 -0
  77. data/lib/cmis_server/query/parser.racc.rb +1039 -0
  78. data/lib/cmis_server/query/parser.rex +114 -0
  79. data/lib/cmis_server/query/parser.rex.rb +238 -0
  80. data/lib/cmis_server/query/statement.rb +395 -0
  81. data/lib/cmis_server/query.rb +2 -0
  82. data/lib/cmis_server/renderable_collection.rb +45 -0
  83. data/lib/cmis_server/renderable_object.rb +49 -0
  84. data/lib/cmis_server/repository.rb +91 -0
  85. data/lib/cmis_server/secondary_type.rb +11 -0
  86. data/lib/cmis_server/type.rb +62 -0
  87. data/lib/cmis_server/type_registry.rb +115 -0
  88. data/lib/cmis_server/version.rb +4 -0
  89. data/lib/cmis_server.rb +22 -0
  90. data/lib/tasks/cmis_server_tasks.rake +4 -0
  91. data/test/cmis_server_test.rb +7 -0
  92. data/test/dummy/README.rdoc +28 -0
  93. data/test/dummy/Rakefile +6 -0
  94. data/test/dummy/app/assets/javascripts/application.js +13 -0
  95. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  96. data/test/dummy/app/controllers/application_controller.rb +5 -0
  97. data/test/dummy/app/helpers/application_helper.rb +2 -0
  98. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  99. data/test/dummy/bin/bundle +3 -0
  100. data/test/dummy/bin/rails +4 -0
  101. data/test/dummy/bin/rake +4 -0
  102. data/test/dummy/bin/setup +29 -0
  103. data/test/dummy/config/application.rb +26 -0
  104. data/test/dummy/config/boot.rb +5 -0
  105. data/test/dummy/config/database.yml +25 -0
  106. data/test/dummy/config/environment.rb +5 -0
  107. data/test/dummy/config/environments/development.rb +41 -0
  108. data/test/dummy/config/environments/production.rb +79 -0
  109. data/test/dummy/config/environments/test.rb +42 -0
  110. data/test/dummy/config/initializers/assets.rb +11 -0
  111. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  112. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  113. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  114. data/test/dummy/config/initializers/inflections.rb +16 -0
  115. data/test/dummy/config/initializers/mime_types.rb +4 -0
  116. data/test/dummy/config/initializers/session_store.rb +3 -0
  117. data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
  118. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  119. data/test/dummy/config/locales/en.yml +23 -0
  120. data/test/dummy/config/routes.rb +4 -0
  121. data/test/dummy/config/secrets.yml +22 -0
  122. data/test/dummy/config.ru +4 -0
  123. data/test/dummy/public/404.html +67 -0
  124. data/test/dummy/public/422.html +67 -0
  125. data/test/dummy/public/500.html +66 -0
  126. data/test/dummy/public/favicon.ico +0 -0
  127. data/test/integration/navigation_test.rb +8 -0
  128. data/test/services/bulk_update_service_test.rb +121 -0
  129. data/test/services/content_stream_service_test.rb +176 -0
  130. data/test/services/secondary_type_service_test.rb +174 -0
  131. data/test/services/type_management_service_test.rb +146 -0
  132. data/test/test_helper.rb +16 -0
  133. metadata +326 -0
@@ -0,0 +1,22 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key is used for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+
6
+ # Make sure the secret is at least 30 characters and all random,
7
+ # no regular words or you'll be exposed to dictionary attacks.
8
+ # You can use `rake secret` to generate a secure secret key.
9
+
10
+ # Make sure the secrets in this file are kept private
11
+ # if you're sharing your code publicly.
12
+
13
+ development:
14
+ secret_key_base: a09b8ab8174f16ab62a594541596003e1a9a1cbe4722f1e0d48ab3c446db4ea3194be60d316eaeddb5fb8f382f50103a5a245b0f15c05017b6865d8a0ea2e16a
15
+
16
+ test:
17
+ secret_key_base: b1b33c9ed2b8a614c140382cb8031c46390b382d04e2187540ab7944d97756172e40d27bad356dd4d05cb30bc31195b01de5f42a6f330465cf3fcb3c2fd5159e
18
+
19
+ # Do not keep production secrets in the repository,
20
+ # instead read values from the environment.
21
+ production:
22
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class NavigationTest < ActionDispatch::IntegrationTest
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ end
8
+
@@ -0,0 +1,121 @@
1
+ require 'test_helper'
2
+
3
+ module CmisServer
4
+ class BulkUpdateServiceTest < ActiveSupport::TestCase
5
+ setup do
6
+ # Configuration du repository avec les capacités CMIS 1.1
7
+ @repository = Repository.new(
8
+ id: "test_repo",
9
+ name: "Test Repository",
10
+ description: "Test repository for CMIS 1.1 features",
11
+ capabilities: {
12
+ bulk_update: true
13
+ }
14
+ )
15
+
16
+ # Créer un contexte avec le repository
17
+ @context = { repository: @repository }
18
+
19
+ # Service de mise à jour en masse
20
+ @service = BulkUpdateService.new(@context)
21
+
22
+ # Créer plusieurs documents pour les tests
23
+ @documents = []
24
+ 5.times do |i|
25
+ doc = DocumentObject.new(
26
+ type: DocumentType.base,
27
+ properties: {
28
+ cmis_object_id: "doc-#{i}",
29
+ cmis_name: "Document #{i}",
30
+ cmis_description: "Description originale #{i}"
31
+ }
32
+ )
33
+ @repository.add_object(doc)
34
+ @documents << doc
35
+ end
36
+ end
37
+
38
+ test "bulk update multiple objects with properties" do
39
+ # IDs des documents à mettre à jour
40
+ doc_ids = @documents.map { |doc| doc.cmis_object_id }
41
+
42
+ # Propriétés à mettre à jour
43
+ properties = {
44
+ "cmis:description" => "Nouvelle description commune"
45
+ }
46
+
47
+ # Effectuer la mise à jour en masse
48
+ result = @service.bulk_update(doc_ids, properties)
49
+
50
+ # Vérifier que tous les documents ont été mis à jour
51
+ assert_equal doc_ids.length, result[:succeeded].length, "Tous les documents devraient être mis à jour avec succès"
52
+ assert_empty result[:failed], "Aucun document ne devrait échouer à la mise à jour"
53
+
54
+ # Vérifier que les propriétés ont été mises à jour
55
+ @documents.each do |doc|
56
+ updated_doc = @repository.object(doc.cmis_object_id)
57
+ assert_equal "Nouvelle description commune", updated_doc.cmis_description,
58
+ "La description devrait être mise à jour pour le document #{doc.cmis_object_id}"
59
+ end
60
+ end
61
+
62
+ test "bulk update with some failures" do
63
+ # Prendre les IDs des documents existants
64
+ doc_ids = @documents.map { |doc| doc.cmis_object_id }
65
+
66
+ # Ajouter un ID qui n'existe pas
67
+ doc_ids << "doc-inexistant"
68
+
69
+ # Propriétés à mettre à jour
70
+ properties = {
71
+ "cmis:description" => "Nouvelle description après erreur"
72
+ }
73
+
74
+ # Effectuer la mise à jour en masse
75
+ result = @service.bulk_update(doc_ids, properties)
76
+
77
+ # Vérifier que les documents existants ont été mis à jour
78
+ assert_equal @documents.length, result[:succeeded].length,
79
+ "Les documents existants devraient être mis à jour avec succès"
80
+
81
+ # Vérifier que le document inexistant a échoué
82
+ assert_equal 1, result[:failed].length, "Le document inexistant devrait échouer à la mise à jour"
83
+ assert_equal "doc-inexistant", result[:failed].first[:id],
84
+ "L'ID du document en échec devrait être celui du document inexistant"
85
+
86
+ # Vérifier que les propriétés ont été mises à jour pour les documents existants
87
+ @documents.each do |doc|
88
+ updated_doc = @repository.object(doc.cmis_object_id)
89
+ assert_equal "Nouvelle description après erreur", updated_doc.cmis_description,
90
+ "La description devrait être mise à jour pour le document #{doc.cmis_object_id}"
91
+ end
92
+ end
93
+
94
+ test "bulk update with property validation errors" do
95
+ # IDs des documents à mettre à jour
96
+ doc_ids = @documents.map { |doc| doc.cmis_object_id }
97
+
98
+ # Propriétés invalides (supposons qu'un nom ne peut pas être vide)
99
+ properties = {
100
+ "cmis:name" => ""
101
+ }
102
+
103
+ # Configurer la validation pour échouer sur un nom vide
104
+ DocumentObject.any_instance.stubs(:valid?).returns(false)
105
+ DocumentObject.any_instance.stubs(:errors).returns(ActiveModel::Errors.new(nil).tap { |e| e.add(:cmis_name, "ne peut pas être vide") })
106
+
107
+ # Effectuer la mise à jour en masse
108
+ result = @service.bulk_update(doc_ids, properties)
109
+
110
+ # Vérifier que tous les documents ont échoué à la mise à jour
111
+ assert_empty result[:succeeded], "Aucun document ne devrait être mis à jour avec succès"
112
+ assert_equal doc_ids.length, result[:failed].length, "Tous les documents devraient échouer à la mise à jour"
113
+
114
+ # Vérifier que les erreurs sont enregistrées
115
+ result[:failed].each do |failure|
116
+ assert failure.has_key?(:message), "Chaque échec devrait avoir un message d'erreur"
117
+ assert_match /ne peut pas être vide/, failure[:message], "Le message d'erreur devrait indiquer la raison"
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,176 @@
1
+ require 'test_helper'
2
+
3
+ module CmisServer
4
+ class ContentStreamServiceTest < ActiveSupport::TestCase
5
+ setup do
6
+ # Configuration du repository avec les capacités CMIS 1.1
7
+ @repository = Repository.new(
8
+ id: "test_repo",
9
+ name: "Test Repository",
10
+ description: "Test repository for CMIS 1.1 features",
11
+ capabilities: {
12
+ append_content_stream: true
13
+ }
14
+ )
15
+
16
+ # Créer un contexte avec le repository
17
+ @context = { repository: @repository }
18
+
19
+ # Service de gestion des content streams
20
+ @service = ContentStreamService.new(@context)
21
+
22
+ # Créer un document avec un contenu initial
23
+ @document = DocumentObject.new(
24
+ type: DocumentType.base,
25
+ properties: {
26
+ cmis_object_id: "doc-with-content",
27
+ cmis_name: "Document avec contenu",
28
+ cmis_description: "Document pour tester AppendContentStream"
29
+ }
30
+ )
31
+
32
+ # Ajouter un contenu initial
33
+ @initial_content = "Contenu initial du document.\n"
34
+ @document.content_stream = ContentStream.new(
35
+ id: "cs_doc-with-content",
36
+ media_type: "text/plain",
37
+ stream: StringIO.new(@initial_content),
38
+ filename: "document.txt"
39
+ )
40
+
41
+ @repository.add_object(@document)
42
+ end
43
+
44
+ test "append content to existing document" do
45
+ # Contenu à ajouter
46
+ additional_content = "Contenu supplémentaire ajouté via AppendContentStream.\n"
47
+ content_stream = ContentStream.new(
48
+ id: "cs_append",
49
+ media_type: "text/plain",
50
+ stream: StringIO.new(additional_content),
51
+ filename: "appendix.txt"
52
+ )
53
+
54
+ # Ajouter le contenu au document existant
55
+ result = @service.append_content_stream("doc-with-content", content_stream, true)
56
+
57
+ # Vérifier que l'ajout a réussi
58
+ assert result, "L'ajout de contenu devrait réussir"
59
+
60
+ # Récupérer le document mis à jour
61
+ updated_document = @repository.object("doc-with-content")
62
+
63
+ # Vérifier que le contenu a été ajouté
64
+ content = updated_document.content_stream.stream.read
65
+ assert_equal @initial_content + additional_content, content, "Le contenu devrait être la combinaison des deux"
66
+
67
+ # Vérifier que le type MIME est préservé
68
+ assert_equal "text/plain", updated_document.content_stream.media_type, "Le type MIME devrait être préservé"
69
+ end
70
+
71
+ test "append content with isLastChunk=false" do
72
+ # Premier morceau de contenu
73
+ chunk1 = "Premier morceau ajouté.\n"
74
+ content_stream1 = ContentStream.new(
75
+ id: "cs_chunk1",
76
+ media_type: "text/plain",
77
+ stream: StringIO.new(chunk1),
78
+ filename: "chunk1.txt"
79
+ )
80
+
81
+ # Ajouter le premier morceau avec isLastChunk=false
82
+ result1 = @service.append_content_stream("doc-with-content", content_stream1, false)
83
+
84
+ # Vérifier que l'ajout a réussi
85
+ assert result1, "L'ajout du premier morceau devrait réussir"
86
+
87
+ # Deuxième morceau de contenu
88
+ chunk2 = "Dernier morceau ajouté.\n"
89
+ content_stream2 = ContentStream.new(
90
+ id: "cs_chunk2",
91
+ media_type: "text/plain",
92
+ stream: StringIO.new(chunk2),
93
+ filename: "chunk2.txt"
94
+ )
95
+
96
+ # Ajouter le deuxième morceau avec isLastChunk=true
97
+ result2 = @service.append_content_stream("doc-with-content", content_stream2, true)
98
+
99
+ # Vérifier que l'ajout a réussi
100
+ assert result2, "L'ajout du dernier morceau devrait réussir"
101
+
102
+ # Récupérer le document mis à jour
103
+ updated_document = @repository.object("doc-with-content")
104
+
105
+ # Vérifier que tous les morceaux ont été ajoutés
106
+ content = updated_document.content_stream.stream.read
107
+ expected_content = @initial_content + chunk1 + chunk2
108
+ assert_equal expected_content, content, "Le contenu final devrait inclure tous les morceaux"
109
+ end
110
+
111
+ test "append content with different mime type" do
112
+ # Contenu HTML à ajouter à un document texte
113
+ html_content = "<p>Contenu HTML ajouté à un document texte.</p>"
114
+ content_stream = ContentStream.new(
115
+ id: "cs_html",
116
+ media_type: "text/html",
117
+ stream: StringIO.new(html_content),
118
+ filename: "content.html"
119
+ )
120
+
121
+ # Ajouter le contenu au document existant
122
+ result = @service.append_content_stream("doc-with-content", content_stream, true)
123
+
124
+ # Vérifier que l'ajout a réussi
125
+ assert result, "L'ajout de contenu devrait réussir malgré la différence de type MIME"
126
+
127
+ # Récupérer le document mis à jour
128
+ updated_document = @repository.object("doc-with-content")
129
+
130
+ # Vérifier que le contenu a été ajouté
131
+ content = updated_document.content_stream.stream.read
132
+ assert_equal @initial_content + html_content, content, "Le contenu devrait être la combinaison des deux"
133
+
134
+ # Le type MIME devrait rester celui du document original
135
+ assert_equal "text/plain", updated_document.content_stream.media_type,
136
+ "Le type MIME du document original devrait être préservé"
137
+ end
138
+
139
+ test "append content to document without content" do
140
+ # Créer un document sans contenu
141
+ empty_doc = DocumentObject.new(
142
+ type: DocumentType.base,
143
+ properties: {
144
+ cmis_object_id: "empty-doc",
145
+ cmis_name: "Document sans contenu",
146
+ }
147
+ )
148
+ @repository.add_object(empty_doc)
149
+
150
+ # Contenu à ajouter
151
+ new_content = "Premier contenu pour un document vide.\n"
152
+ content_stream = ContentStream.new(
153
+ id: "cs_new",
154
+ media_type: "text/plain",
155
+ stream: StringIO.new(new_content),
156
+ filename: "firstcontent.txt"
157
+ )
158
+
159
+ # Ajouter le contenu au document
160
+ result = @service.append_content_stream("empty-doc", content_stream, true)
161
+
162
+ # Vérifier que l'ajout a réussi
163
+ assert result, "L'ajout de contenu à un document vide devrait réussir"
164
+
165
+ # Récupérer le document mis à jour
166
+ updated_document = @repository.object("empty-doc")
167
+
168
+ # Vérifier que le contenu a été ajouté
169
+ content = updated_document.content_stream.stream.read
170
+ assert_equal new_content, content, "Le contenu devrait être celui qui a été ajouté"
171
+
172
+ # Vérifier le type MIME
173
+ assert_equal "text/plain", updated_document.content_stream.media_type, "Le type MIME devrait être celui du contenu ajouté"
174
+ end
175
+ end
176
+ end