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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +51 -0
- data/app/assets/javascripts/cmis_server/application.js +13 -0
- data/app/assets/stylesheets/cmis_server/application.css +15 -0
- data/app/controllers/cmis_server/application_controller.rb +19 -0
- data/app/controllers/cmis_server/atom_pub/base_controller.rb +23 -0
- data/app/controllers/cmis_server/atom_pub/bulk_controller.rb +302 -0
- data/app/controllers/cmis_server/atom_pub/content_controller.rb +178 -0
- data/app/controllers/cmis_server/atom_pub/entries_controller.rb +41 -0
- data/app/controllers/cmis_server/atom_pub/folder_collection_controller.rb +70 -0
- data/app/controllers/cmis_server/atom_pub/query_controller.rb +138 -0
- data/app/controllers/cmis_server/atom_pub/repository_controller.rb +75 -0
- data/app/controllers/cmis_server/atom_pub/secondary_types_controller.rb +149 -0
- data/app/controllers/cmis_server/atom_pub/service_documents_controller.rb +34 -0
- data/app/controllers/cmis_server/atom_pub/types_controller.rb +229 -0
- data/app/controllers/cmis_server/atom_pub/uri_templates_controller.rb +58 -0
- data/app/controllers/concerns/cmis_server/atom_pub/repository_scopable.rb +18 -0
- data/app/helpers/cmis_server/application_helper.rb +31 -0
- data/app/models/cmis_server/application_record.rb +5 -0
- data/app/services/cmis_server/bulk_update_service.rb +69 -0
- data/app/services/cmis_server/content_stream_service.rb +75 -0
- data/app/services/cmis_server/discovery_service.rb +31 -0
- data/app/services/cmis_server/navigation_service.rb +43 -0
- data/app/services/cmis_server/object_service.rb +176 -0
- data/app/services/cmis_server/repository_service.rb +40 -0
- data/app/services/cmis_server/secondary_type_service.rb +120 -0
- data/app/services/cmis_server/type_management_service.rb +117 -0
- data/app/views/cmis_server/atom_pub/bulk_update_feed.atom.builder +47 -0
- data/app/views/cmis_server/atom_pub/entries/_cmis_document_links.atom_entry.builder +0 -0
- data/app/views/cmis_server/atom_pub/entries/_cmis_folder_links.atom_entry.builder +3 -0
- data/app/views/cmis_server/atom_pub/entries/_object_entry.atom_entry.builder +64 -0
- data/app/views/cmis_server/atom_pub/entries/_property.atom_entry.builder +8 -0
- data/app/views/cmis_server/atom_pub/entries/object_entry.atom_entry.builder +1 -0
- data/app/views/cmis_server/atom_pub/entries/type_entry.atom_entry.builder +59 -0
- data/app/views/cmis_server/atom_pub/feeds/_feed_entry.atom_feed.builder +1 -0
- data/app/views/cmis_server/atom_pub/feeds/feed.atom_feed.builder +30 -0
- data/app/views/cmis_server/atom_pub/service_documents/_uri_template.atom_service.builder +5 -0
- data/app/views/cmis_server/atom_pub/service_documents/_workspace.atom_service.builder +89 -0
- data/app/views/cmis_server/atom_pub/service_documents/service_document.atom_service.builder +1 -0
- data/app/views/cmis_server/atom_pub/shared/_collection.xml.builder +7 -0
- data/app/views/cmis_server/atom_pub/shared/atom_entry_layout.atom_entry.builder +0 -0
- data/app/views/cmis_server/atom_pub/type_entry.atom.builder +69 -0
- data/app/views/cmis_server/atom_pub/types_feed.atom.builder +91 -0
- data/app/views/layouts/cmis_server/application.atom_entry.builder +2 -0
- data/app/views/layouts/cmis_server/application.atom_feed.builder +3 -0
- data/app/views/layouts/cmis_server/application.atom_service.builder +10 -0
- data/app/views/layouts/cmis_server/application.html.erb +14 -0
- data/config/routes.rb +49 -0
- data/lib/cmis_server/atom_pub/entry_parser.rb +72 -0
- data/lib/cmis_server/base_objects/base_type.rb +128 -0
- data/lib/cmis_server/base_objects/document.rb +68 -0
- data/lib/cmis_server/base_objects/folder.rb +104 -0
- data/lib/cmis_server/base_objects/item.rb +25 -0
- data/lib/cmis_server/base_types.rb +123 -0
- data/lib/cmis_server/cmis_object.rb +190 -0
- data/lib/cmis_server/configuration.rb +43 -0
- data/lib/cmis_server/constants.rb +8 -0
- data/lib/cmis_server/content_stream.rb +52 -0
- data/lib/cmis_server/context.rb +11 -0
- data/lib/cmis_server/document_object.rb +12 -0
- data/lib/cmis_server/document_type.rb +67 -0
- data/lib/cmis_server/engine.rb +60 -0
- data/lib/cmis_server/exceptions.rb +185 -0
- data/lib/cmis_server/folder_object.rb +18 -0
- data/lib/cmis_server/folder_type.rb +34 -0
- data/lib/cmis_server/id.rb +18 -0
- data/lib/cmis_server/item_adapter.rb +26 -0
- data/lib/cmis_server/item_object.rb +15 -0
- data/lib/cmis_server/item_type.rb +7 -0
- data/lib/cmis_server/object_adapter.rb +79 -0
- data/lib/cmis_server/property.rb +29 -0
- data/lib/cmis_server/property_definition.rb +118 -0
- data/lib/cmis_server/query/parser.output +2250 -0
- data/lib/cmis_server/query/parser.racc +222 -0
- data/lib/cmis_server/query/parser.racc.rb +1039 -0
- data/lib/cmis_server/query/parser.rex +114 -0
- data/lib/cmis_server/query/parser.rex.rb +238 -0
- data/lib/cmis_server/query/statement.rb +395 -0
- data/lib/cmis_server/query.rb +2 -0
- data/lib/cmis_server/renderable_collection.rb +45 -0
- data/lib/cmis_server/renderable_object.rb +49 -0
- data/lib/cmis_server/repository.rb +91 -0
- data/lib/cmis_server/secondary_type.rb +11 -0
- data/lib/cmis_server/type.rb +62 -0
- data/lib/cmis_server/type_registry.rb +115 -0
- data/lib/cmis_server/version.rb +4 -0
- data/lib/cmis_server.rb +22 -0
- data/lib/tasks/cmis_server_tasks.rake +4 -0
- data/test/cmis_server_test.rb +7 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/integration/navigation_test.rb +8 -0
- data/test/services/bulk_update_service_test.rb +121 -0
- data/test/services/content_stream_service_test.rb +176 -0
- data/test/services/secondary_type_service_test.rb +174 -0
- data/test/services/type_management_service_test.rb +146 -0
- data/test/test_helper.rb +16 -0
- 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,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,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
|