decidim 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.eslintrc.json +2 -5
- data/.mention-bot +2 -1
- data/.yardopts +8 -0
- data/Gemfile.lock +64 -62
- data/README.md +11 -9
- data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +3 -3
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_email_preview.scss +5 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +1 -0
- data/decidim-admin/app/commands/decidim/admin/create_newsletter.rb +30 -0
- data/decidim-admin/app/commands/decidim/admin/deliver_newsletter.rb +29 -0
- data/decidim-admin/app/commands/decidim/admin/destroy_participatory_process_step.rb +9 -0
- data/decidim-admin/app/commands/decidim/admin/update_newsletter.rb +33 -0
- data/decidim-admin/app/constraints/decidim/admin/organization_dashboard_constraint.rb +1 -1
- data/decidim-admin/app/controllers/decidim/admin/features_controller.rb +2 -2
- data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +115 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +4 -4
- data/decidim-admin/app/forms/decidim/admin/newsletter_form.rb +15 -0
- data/decidim-admin/app/jobs/decidim/admin/newsletter_delivery_job.rb +18 -0
- data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +32 -0
- data/decidim-admin/app/models/decidim/admin/abilities/admin_user.rb +4 -0
- data/decidim-admin/app/models/decidim/admin/abilities/base.rb +4 -0
- data/decidim-admin/app/models/decidim/admin/abilities/collaborator_user.rb +19 -0
- data/decidim-admin/app/models/decidim/admin/abilities/participatory_process_admin.rb +1 -1
- data/decidim-admin/app/queries/decidim/admin/manageable_participatory_processes_for_user.rb +1 -1
- data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +5 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +47 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +14 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +1 -1
- data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +1 -1
- data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
- data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +1 -0
- data/decidim-admin/config/locales/ca.yml +40 -0
- data/decidim-admin/config/locales/en.yml +40 -0
- data/decidim-admin/config/locales/es.yml +40 -0
- data/decidim-admin/config/routes.rb +7 -0
- data/decidim-admin/decidim-admin.gemspec +0 -1
- data/decidim-admin/lib/decidim/admin/engine.rb +1 -0
- data/decidim-admin/lib/decidim/admin/features/base_controller.rb +5 -1
- data/decidim-admin/spec/commands/create_newsletter_spec.rb +62 -0
- data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +45 -0
- data/decidim-admin/spec/commands/destroy_participatory_process_step_spec.rb +12 -0
- data/decidim-admin/spec/commands/update_newsletter_spec.rb +64 -0
- data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +147 -0
- data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +1 -5
- data/decidim-admin/spec/features/static_pages_spec.rb +16 -0
- data/decidim-admin/spec/forms/newsletter_form_spec.rb +47 -0
- data/decidim-admin/spec/jobs/newsletter_delivery_job_spec.rb +25 -0
- data/decidim-admin/spec/jobs/newsletter_job_spec.rb +29 -0
- data/decidim-admin/spec/models/abilities/collaborator_user_spec.rb +66 -0
- data/decidim-admin/spec/organization_dashboard_constraint_spec.rb +55 -0
- data/decidim-admin/spec/queries/manageable_participatory_processes_for_user_spec.rb +8 -0
- data/decidim-admin/spec/shared/manage_processes_examples.rb +1 -5
- data/decidim-api/lib/decidim/api.rb +2 -7
- data/decidim-api/lib/decidim/api/{types/mutation.rb → mutation_type.rb} +0 -0
- data/decidim-api/lib/decidim/api/{types/query.rb → query_type.rb} +0 -0
- data/decidim-budgets/app/assets/javascripts/decidim/budgets/projects.js.es6 +4 -4
- data/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb +4 -2
- data/decidim-budgets/app/commands/decidim/budgets/checkout.rb +7 -3
- data/decidim-budgets/app/models/decidim/budgets/order.rb +16 -1
- data/decidim-budgets/app/models/decidim/budgets/project.rb +16 -0
- data/decidim-budgets/app/views/decidim/budgets/line_items/update_budget.js.erb +7 -7
- data/decidim-budgets/app/views/decidim/budgets/projects/_budget_confirm.html.erb +27 -25
- data/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb +4 -13
- data/decidim-budgets/app/views/decidim/budgets/projects/_order_progress.html.erb +23 -21
- data/decidim-budgets/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +25 -23
- data/decidim-budgets/app/views/decidim/budgets/projects/_order_total_budget.html.erb +3 -1
- data/decidim-budgets/app/views/decidim/budgets/projects/_project.html.erb +32 -30
- data/decidim-budgets/app/views/decidim/budgets/projects/_projects.html.erb +1 -3
- data/decidim-budgets/app/views/decidim/budgets/projects/index.html.erb +0 -4
- data/decidim-budgets/app/views/decidim/budgets/projects/show.html.erb +5 -6
- data/decidim-budgets/config/i18n-tasks.yml +1 -0
- data/decidim-budgets/config/locales/ca.yml +7 -2
- data/decidim-budgets/config/locales/en.yml +17 -6
- data/decidim-budgets/config/locales/es.yml +7 -2
- data/decidim-budgets/lib/decidim/budgets/feature.rb +2 -2
- data/decidim-budgets/spec/commands/add_line_item_spec.rb +16 -3
- data/decidim-budgets/spec/commands/cancel_order_spec.rb +7 -1
- data/decidim-budgets/spec/commands/checkout_spec.rb +9 -2
- data/decidim-budgets/spec/commands/remove_line_item_spec.rb +16 -5
- data/decidim-budgets/spec/features/orders_spec.rb +8 -2
- data/decidim-budgets/spec/models/order_spec.rb +31 -2
- data/decidim-budgets/spec/shared/admin_shared_context.rb +1 -1
- data/decidim-comments/README.md +1 -1
- data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
- data/decidim-comments/app/frontend/comments/add_comment_form.component.jsx +156 -93
- data/decidim-comments/app/frontend/comments/add_comment_form.component.test.jsx +36 -23
- data/decidim-comments/app/frontend/comments/add_comment_form.mutation.graphql +5 -3
- data/decidim-comments/app/frontend/comments/add_comment_form_commentable.fragment.graphql +4 -0
- data/decidim-comments/app/frontend/comments/add_comment_form_session.fragment.graphql +6 -0
- data/decidim-comments/app/frontend/comments/comment.component.jsx +11 -13
- data/decidim-comments/app/frontend/comments/comment.component.test.jsx +22 -21
- data/decidim-comments/app/frontend/comments/comment.fragment.graphql +4 -4
- data/decidim-comments/app/frontend/comments/comment_data.fragment.graphql +4 -3
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +1 -1
- data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +3 -3
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +3 -3
- data/decidim-comments/app/frontend/comments/comment_thread.fragment.graphql +1 -1
- data/decidim-comments/app/frontend/comments/comments.component.jsx +47 -39
- data/decidim-comments/app/frontend/comments/comments.component.test.jsx +51 -38
- data/decidim-comments/app/frontend/comments/comments.query.graphql +10 -4
- data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +6 -3
- data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +7 -4
- data/decidim-comments/app/frontend/support/generate_comments_data.js +4 -4
- data/decidim-comments/app/models/decidim/comments/comment.rb +7 -9
- data/decidim-comments/app/queries/decidim/comments/{comments_with_replies.rb → sorted_comments.rb} +3 -8
- data/decidim-comments/app/types/decidim/comments/commentable_interface.rb +44 -0
- data/decidim-comments/app/types/decidim/comments/commentable_mutation_type.rb +29 -0
- data/decidim-comments/app/types/decidim/comments/commentable_type.rb +14 -0
- data/decidim-comments/config/locales/ca.yml +3 -1
- data/decidim-comments/config/locales/en.yml +5 -2
- data/decidim-comments/config/locales/es.yml +3 -1
- data/decidim-comments/lib/decidim/comments.rb +4 -0
- data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/add_comment_type.rb +0 -0
- data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_mutation_type.rb +0 -0
- data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_type.rb +11 -17
- data/decidim-comments/lib/decidim/comments/commentable.rb +45 -0
- data/decidim-comments/lib/decidim/comments/comments_helper.rb +15 -10
- data/decidim-comments/lib/decidim/comments/mutation_extensions.rb +8 -16
- data/decidim-comments/lib/decidim/comments/query_extensions.rb +5 -8
- data/decidim-comments/lib/decidim/comments/test/factories.rb +3 -3
- data/decidim-comments/spec/commands/vote_comment_spec.rb +3 -1
- data/decidim-comments/spec/features/comments_spec.rb +28 -14
- data/decidim-comments/spec/features/notifications_spec.rb +1 -1
- data/decidim-comments/spec/helpers/comments_helper_spec.rb +4 -27
- data/decidim-comments/spec/models/comment_spec.rb +7 -11
- data/decidim-comments/spec/models/comment_vote_spec.rb +3 -1
- data/decidim-comments/spec/models/seed_spec.rb +3 -4
- data/decidim-comments/spec/queries/{comments_with_replies_spec.rb → sorted_comments_spec.rb} +12 -29
- data/decidim-comments/spec/types/comment_type_spec.rb +23 -17
- data/decidim-comments/spec/types/commentable_mutation_type_spec.rb +34 -0
- data/decidim-comments/spec/types/commentable_type_spec.rb +48 -0
- data/decidim-comments/spec/types/mutation_type_spec.rb +5 -22
- data/decidim-comments/spec/types/query_type_spec.rb +0 -24
- data/decidim-dev/config/i18n-tasks.yml +4 -0
- data/decidim-dev/decidim-dev.gemspec +1 -1
- data/decidim-dev/lib/decidim/dev/test/rspec_support/action_mailer.rb +10 -4
- data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +6 -5
- data/decidim-dev/lib/decidim/dev/test/rspec_support/i18n.rb +0 -1
- data/decidim-meetings/app/assets/javascripts/decidim/meetings/map.js.es6.erb +8 -3
- data/decidim-meetings/app/assets/stylesheets/decidim/meetings/map.css +3 -1
- data/decidim-meetings/app/controllers/decidim/meetings/meetings_controller.rb +2 -2
- data/decidim-meetings/app/forms/decidim/meetings/admin/close_meeting_form.rb +2 -1
- data/decidim-meetings/app/helpers/decidim/meetings/map_helper.rb +1 -0
- data/decidim-meetings/app/services/decidim/meetings/meeting_search.rb +7 -3
- data/decidim-meetings/app/views/decidim/meetings/meetings/_datetime.html.erb +1 -1
- data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +5 -5
- data/decidim-meetings/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
- data/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb +1 -5
- data/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb +16 -9
- data/decidim-meetings/config/locales/ca.yml +2 -3
- data/decidim-meetings/config/locales/en.yml +2 -3
- data/decidim-meetings/config/locales/es.yml +2 -3
- data/decidim-meetings/spec/features/explore_meetings_spec.rb +75 -24
- data/decidim-meetings/spec/forms/close_meeting_form_spec.rb +1 -1
- data/decidim-meetings/spec/services/meeting_search_spec.rb +15 -12
- data/decidim-meetings/vendor/assets/javascripts/leaflet.markercluster.js +7 -0
- data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.Default.css +60 -0
- data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.css +14 -0
- data/decidim-pages/app/models/decidim/pages/page.rb +22 -0
- data/decidim-pages/app/views/decidim/pages/application/show.html.erb +2 -6
- data/decidim-pages/config/locales/ca.yml +2 -2
- data/decidim-pages/config/locales/en.yml +2 -2
- data/decidim-pages/config/locales/es.yml +2 -2
- data/decidim-pages/lib/decidim/pages/feature.rb +2 -2
- data/decidim-pages/spec/features/page_show_spec.rb +0 -33
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +2 -0
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -0
- data/decidim-proposals/app/models/decidim/proposals/abilities/admin_user.rb +45 -0
- data/decidim-proposals/app/models/decidim/proposals/abilities/process_admin_user.rb +57 -0
- data/decidim-proposals/app/models/decidim/proposals/proposal.rb +21 -0
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +16 -10
- data/decidim-proposals/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +4 -4
- data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +7 -3
- data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +2 -6
- data/decidim-proposals/app/views/decidim/proposals/proposals/_remaining_votes_count.html.erb +3 -1
- data/decidim-proposals/app/views/decidim/proposals/proposals/_tags.html.erb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/proposals/_vote_button.html.erb +23 -21
- data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_count.html.erb +9 -6
- data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_limit.html.erb +1 -3
- data/decidim-proposals/app/views/decidim/proposals/proposals/index.html.erb +0 -4
- data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +2 -6
- data/decidim-proposals/config/locales/ca.yml +8 -1
- data/decidim-proposals/config/locales/en.yml +8 -1
- data/decidim-proposals/config/locales/es.yml +8 -1
- data/decidim-proposals/lib/decidim/proposals/admin_engine.rb +7 -0
- data/decidim-proposals/lib/decidim/proposals/feature.rb +6 -2
- data/decidim-proposals/spec/features/proposals_spec.rb +226 -40
- data/decidim-proposals/spec/models/decidim/proposals/abilities/admin_user_spec.rb +62 -0
- data/decidim-proposals/spec/models/decidim/proposals/abilities/process_admin_user_spec.rb +63 -0
- data/decidim-proposals/spec/shared/manage_proposals_examples.rb +161 -50
- data/decidim-results/app/models/decidim/results/result.rb +21 -0
- data/decidim-results/app/views/decidim/results/results/index.html.erb +0 -4
- data/decidim-results/app/views/decidim/results/results/show.html.erb +2 -8
- data/decidim-results/config/i18n-tasks.yml +1 -0
- data/decidim-results/config/locales/ca.yml +5 -2
- data/decidim-results/config/locales/en.yml +5 -2
- data/decidim-results/config/locales/es.yml +5 -2
- data/decidim-results/lib/decidim/results/feature.rb +2 -2
- data/decidim-results/spec/services/result_stats_calculator_spec.rb +2 -2
- data/decidim-results/spec/shared/admin_shared_context.rb +1 -1
- data/decidim-system/config/i18n-tasks.yml +1 -1
- data/package.json +50 -51
- data/yarn.lock +198 -151
- metadata +69 -36
- data/decidim-admin/spec/features/admin_access_control.rb +0 -52
- data/decidim-api/lib/decidim/api/types/author_interface.rb +0 -13
- data/decidim-api/lib/decidim/api/types/localized_string.rb +0 -13
- data/decidim-api/lib/decidim/api/types/translated_field.rb +0 -44
- data/decidim-api/spec/types/localized_string_type_spec.rb +0 -31
- data/decidim-api/spec/types/translated_field_type_spec.rb +0 -69
- data/decidim-comments/app/frontend/comments/add_comment_form.fragment.graphql +0 -6
@@ -8,8 +8,10 @@ import generateUserGroupData from '../support/generate_user_group_data';
|
|
8
8
|
|
9
9
|
describe("<AddCommentForm />", () => {
|
10
10
|
let session = null;
|
11
|
-
const
|
12
|
-
|
11
|
+
const commentable = {
|
12
|
+
id: "1",
|
13
|
+
type: "Decidim::DummyResource"
|
14
|
+
};
|
13
15
|
const addCommentStub = () => {
|
14
16
|
return null;
|
15
17
|
}
|
@@ -22,50 +24,50 @@ describe("<AddCommentForm />", () => {
|
|
22
24
|
});
|
23
25
|
|
24
26
|
it("should render a div with class add-comment", () => {
|
25
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
27
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
26
28
|
expect(wrapper.find('div.add-comment')).to.present();
|
27
29
|
});
|
28
30
|
|
29
31
|
it("should have a reference to body textarea", () => {
|
30
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
32
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
31
33
|
expect(wrapper.instance().bodyTextArea).to.be.ok;
|
32
34
|
});
|
33
35
|
|
34
36
|
it("should initialize with a state property disabled as true", () => {
|
35
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
37
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
36
38
|
expect(wrapper).to.have.state('disabled', true);
|
37
39
|
});
|
38
40
|
|
39
41
|
it("should have a default prop showTitle as true", () => {
|
40
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
42
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
41
43
|
expect(wrapper).to.have.prop('showTitle').equal(true);
|
42
44
|
});
|
43
45
|
|
44
46
|
it("should not render the title if prop showTitle is false", () => {
|
45
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
47
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} showTitle={false} />);
|
46
48
|
expect(wrapper.find('h5.section-heading')).not.to.be.present();
|
47
49
|
});
|
48
50
|
|
49
51
|
it("should have a default prop submitButtonClassName as 'button button--sc'", () => {
|
50
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
52
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
51
53
|
expect(wrapper).to.have.prop('submitButtonClassName').equal('button button--sc');
|
52
54
|
});
|
53
55
|
|
54
56
|
it("should have a default prop maxLength of 1000", () => {
|
55
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
57
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
56
58
|
expect(wrapper).to.have.prop('maxLength').equal(1000);
|
57
59
|
});
|
58
60
|
|
59
61
|
|
60
62
|
it("should use prop submitButtonClassName as a className prop for submit button", () => {
|
61
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
63
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} submitButtonClassName="button small hollow" />);
|
62
64
|
expect(wrapper.find('input[type="submit"]')).to.have.className('button');
|
63
65
|
expect(wrapper.find('input[type="submit"]')).to.have.className('small');
|
64
66
|
expect(wrapper.find('input[type="submit"]')).to.have.className('hollow');
|
65
67
|
});
|
66
68
|
|
67
69
|
it("should enable the submit button if textarea is not blank", () => {
|
68
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
70
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
69
71
|
wrapper.find('textarea').simulate('change', {
|
70
72
|
target: {
|
71
73
|
value: 'This is a comment'
|
@@ -75,7 +77,7 @@ describe("<AddCommentForm />", () => {
|
|
75
77
|
});
|
76
78
|
|
77
79
|
it("should disable the submit button if textarea is blank", () => {
|
78
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
80
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
79
81
|
wrapper.find('textarea').simulate('change', {
|
80
82
|
target: {
|
81
83
|
value: 'This will be deleted'
|
@@ -90,7 +92,7 @@ describe("<AddCommentForm />", () => {
|
|
90
92
|
});
|
91
93
|
|
92
94
|
it("should not render a div with class 'opinion-toggle'", () => {
|
93
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
95
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
94
96
|
expect(wrapper.find('.opinion-toggle')).not.to.be.present();
|
95
97
|
});
|
96
98
|
|
@@ -103,7 +105,7 @@ describe("<AddCommentForm />", () => {
|
|
103
105
|
beforeEach(() => {
|
104
106
|
addComment = sinon.spy();
|
105
107
|
onCommentAdded = sinon.spy();
|
106
|
-
wrapper = mount(<AddCommentForm addComment={addComment} session={session}
|
108
|
+
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} onCommentAdded={onCommentAdded} />);
|
107
109
|
message = 'This will be submitted';
|
108
110
|
wrapper.instance().bodyTextArea.value = message;
|
109
111
|
});
|
@@ -131,25 +133,25 @@ describe("<AddCommentForm />", () => {
|
|
131
133
|
});
|
132
134
|
|
133
135
|
it("should initialize state with a property alignment and value 0", () => {
|
134
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
136
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
135
137
|
expect(wrapper).to.have.state('alignment').equal(0);
|
136
138
|
});
|
137
139
|
|
138
140
|
describe("when receiving an optional prop arguable with value true", () => {
|
139
141
|
it("should render a div with class 'opinion-toggle'", () => {
|
140
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
142
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
141
143
|
expect(wrapper.find('.opinion-toggle')).to.be.present();
|
142
144
|
});
|
143
145
|
|
144
146
|
it("should set state alignment to 1 if user clicks ok button and change its class", () => {
|
145
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
147
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
146
148
|
wrapper.find('.opinion-toggle--ok').simulate('click');
|
147
149
|
expect(wrapper.find('.opinion-toggle--ok')).to.have.className('is-active');
|
148
150
|
expect(wrapper).to.have.state('alignment').equal(1);
|
149
151
|
});
|
150
152
|
|
151
153
|
it("should set state alignment to -11 if user clicks ko button and change its class", () => {
|
152
|
-
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session}
|
154
|
+
const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable />);
|
153
155
|
wrapper.find('.opinion-toggle--ko').simulate('click');
|
154
156
|
expect(wrapper.find('.opinion-toggle--ko')).to.have.className('is-active');
|
155
157
|
expect(wrapper).to.have.state('alignment').equal(-1);
|
@@ -162,7 +164,7 @@ describe("<AddCommentForm />", () => {
|
|
162
164
|
|
163
165
|
beforeEach(() => {
|
164
166
|
addComment = sinon.spy();
|
165
|
-
wrapper = mount(<AddCommentForm addComment={addComment} session={session}
|
167
|
+
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} arguable />);
|
166
168
|
message = 'This will be submitted';
|
167
169
|
wrapper.instance().bodyTextArea.value = message;
|
168
170
|
});
|
@@ -190,12 +192,12 @@ describe("<AddCommentForm />", () => {
|
|
190
192
|
});
|
191
193
|
|
192
194
|
it("should have a reference to user_group_id select", () => {
|
193
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
195
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
194
196
|
expect(wrapper.instance().userGroupIdSelect).to.be.ok;
|
195
197
|
});
|
196
198
|
|
197
199
|
it("should render a select with option tags for each verified user group", () => {
|
198
|
-
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session}
|
200
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
199
201
|
expect(wrapper.find('select')).to.have.exactly(3).descendants('option');
|
200
202
|
});
|
201
203
|
|
@@ -207,7 +209,7 @@ describe("<AddCommentForm />", () => {
|
|
207
209
|
|
208
210
|
beforeEach(() => {
|
209
211
|
addComment = sinon.spy();
|
210
|
-
wrapper = mount(<AddCommentForm addComment={addComment} session={session}
|
212
|
+
wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} />);
|
211
213
|
message = 'This will be submitted';
|
212
214
|
userGroupId = session.verifiedUserGroups[1].id;
|
213
215
|
wrapper.instance().bodyTextArea.value = message;
|
@@ -230,5 +232,16 @@ describe("<AddCommentForm />", () => {
|
|
230
232
|
});
|
231
233
|
});
|
232
234
|
});
|
233
|
-
})
|
235
|
+
});
|
236
|
+
|
237
|
+
describe("when session is null", () => {
|
238
|
+
beforeEach(() => {
|
239
|
+
session = null;
|
240
|
+
});
|
241
|
+
|
242
|
+
it("display a message to sign in or sign up", () => {
|
243
|
+
const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} />);
|
244
|
+
expect(wrapper.find('span')).to.include.text("sign up");
|
245
|
+
});
|
246
|
+
});
|
234
247
|
});
|
@@ -1,5 +1,7 @@
|
|
1
1
|
mutation addComment($commentableId: String!, $commentableType: String!, $body: String!, $alignment: Int, $userGroupId: ID) {
|
2
|
-
|
3
|
-
|
2
|
+
commentable(id: $commentableId, type: $commentableType) {
|
3
|
+
addComment(body: $body, alignment: $alignment, userGroupId: $userGroupId) {
|
4
|
+
...CommentThread
|
5
|
+
}
|
4
6
|
}
|
5
|
-
}
|
7
|
+
}
|
@@ -68,10 +68,10 @@ class Comment extends Component {
|
|
68
68
|
* @returns {Void|DOMElement} - Render the reply button or not if user can reply
|
69
69
|
*/
|
70
70
|
_renderReplyButton() {
|
71
|
-
const { comment: {
|
71
|
+
const { comment: { acceptsNewComments }, session } = this.props;
|
72
72
|
const { showReplyForm } = this.state;
|
73
73
|
|
74
|
-
if (session &&
|
74
|
+
if (session && acceptsNewComments) {
|
75
75
|
return (
|
76
76
|
<button
|
77
77
|
className="comment__reply muted-link"
|
@@ -92,12 +92,11 @@ class Comment extends Component {
|
|
92
92
|
* @returns {Void|DOMElement} - Render the reply button or not if user can reply
|
93
93
|
*/
|
94
94
|
_renderAdditionalReplyButton() {
|
95
|
-
const { comment: {
|
95
|
+
const { comment: { acceptsNewComments, hasComments }, session, isRootComment } = this.props;
|
96
96
|
const { showReplyForm } = this.state;
|
97
97
|
|
98
|
-
if (session &&
|
99
|
-
if (
|
100
|
-
|
98
|
+
if (session && acceptsNewComments) {
|
99
|
+
if (hasComments && isRootComment) {
|
101
100
|
return (
|
102
101
|
<div className="comment__additionalreply">
|
103
102
|
<button
|
@@ -135,23 +134,23 @@ class Comment extends Component {
|
|
135
134
|
}
|
136
135
|
|
137
136
|
/**
|
138
|
-
* Render comment
|
137
|
+
* Render comment's comments alternating the css class
|
139
138
|
* @private
|
140
|
-
* @returns {Void|DomElement} - A wrapper element with comment
|
139
|
+
* @returns {Void|DomElement} - A wrapper element with comment's comments inside
|
141
140
|
*/
|
142
141
|
_renderReplies() {
|
143
|
-
const { comment: { id,
|
142
|
+
const { comment: { id, hasComments, comments }, session, votable, articleClassName } = this.props;
|
144
143
|
let replyArticleClassName = 'comment comment--nested';
|
145
144
|
|
146
145
|
if (articleClassName === 'comment comment--nested') {
|
147
146
|
replyArticleClassName = `${replyArticleClassName} comment--nested--alt`;
|
148
147
|
}
|
149
148
|
|
150
|
-
if (
|
149
|
+
if (hasComments) {
|
151
150
|
return (
|
152
151
|
<div>
|
153
152
|
{
|
154
|
-
|
153
|
+
comments.map((reply) => (
|
155
154
|
<Comment
|
156
155
|
key={`comment_${id}_reply_${reply.id}`}
|
157
156
|
comment={reply}
|
@@ -180,9 +179,8 @@ class Comment extends Component {
|
|
180
179
|
if (showReplyForm) {
|
181
180
|
return (
|
182
181
|
<AddCommentForm
|
183
|
-
commentableId={comment.id}
|
184
|
-
commentableType="Decidim::Comments::Comment"
|
185
182
|
session={session}
|
183
|
+
commentable={comment}
|
186
184
|
showTitle={false}
|
187
185
|
submitButtonClassName="button small hollow"
|
188
186
|
onCommentAdded={() => this.setState({ showReplyForm: false })}
|
@@ -27,7 +27,7 @@ describe("<Comment />", () => {
|
|
27
27
|
|
28
28
|
beforeEach(() => {
|
29
29
|
let commentsData = generateCommentsData(1);
|
30
|
-
commentsData[0].
|
30
|
+
commentsData[0].comments = generateCommentsData(3);
|
31
31
|
|
32
32
|
const fragment = gql`
|
33
33
|
${commentFragment}
|
@@ -77,50 +77,40 @@ describe("<Comment />", () => {
|
|
77
77
|
expect(wrapper.find(AddCommentForm)).not.to.be.present();
|
78
78
|
wrapper.find('button.comment__reply').simulate('click');
|
79
79
|
expect(wrapper.find(AddCommentForm)).to.have.prop('session').deep.equal(session);
|
80
|
-
expect(wrapper.find(AddCommentForm)).to.have.prop('
|
81
|
-
expect(wrapper.find(AddCommentForm)).to.have.prop('commentableType').equal("Decidim::Comments::Comment");
|
80
|
+
expect(wrapper.find(AddCommentForm)).to.have.prop('commentable').deep.equal(comment);
|
82
81
|
expect(wrapper.find(AddCommentForm)).to.have.prop('showTitle').equal(false);
|
83
82
|
expect(wrapper.find(AddCommentForm)).to.have.prop('submitButtonClassName').equal('button small hollow');
|
84
83
|
});
|
85
84
|
|
86
|
-
it("should not render the reply button if the comment
|
87
|
-
comment.
|
88
|
-
const wrapper = shallow(<Comment comment={comment} session={session} />);
|
89
|
-
expect(wrapper.find('button.comment__reply')).not.to.be.present();
|
90
|
-
});
|
91
|
-
|
92
|
-
it("should not render the additional reply button if the parent comment has no replies and isRootcomment", () => {
|
93
|
-
comment.canHaveReplies = true;
|
94
|
-
comment.hasReplies = false;
|
85
|
+
it("should not render the additional reply button if the parent comment has no comments and isRootcomment", () => {
|
86
|
+
comment.hasComments = false;
|
95
87
|
const wrapper = shallow(<Comment comment={comment} session={session} isRootComment />);
|
96
88
|
expect(wrapper.find('div.comment__additionalreply')).not.to.be.present();
|
97
89
|
});
|
98
90
|
|
99
|
-
it("should not render the additional reply button if the parent comment has
|
100
|
-
comment.
|
101
|
-
comment.hasReplies = true;
|
91
|
+
it("should not render the additional reply button if the parent comment has comments and not isRootcomment", () => {
|
92
|
+
comment.hasComments = true;
|
102
93
|
const wrapper = shallow(<Comment comment={comment} session={session} />);
|
103
94
|
expect(wrapper.find('div.comment__additionalreply')).not.to.be.present();
|
104
95
|
});
|
105
96
|
|
106
|
-
it("should render the additional reply button if the parent comment has
|
107
|
-
comment.
|
108
|
-
comment.hasReplies = true;
|
97
|
+
it("should render the additional reply button if the parent comment has comments and isRootcomment", () => {
|
98
|
+
comment.hasComments = true;
|
109
99
|
const wrapper = shallow(<Comment comment={comment} session={session} isRootComment />);
|
110
100
|
expect(wrapper.find('div.comment__additionalreply')).to.be.present();
|
111
101
|
});
|
112
102
|
|
113
|
-
it("should render comment
|
103
|
+
it("should render comment's comments as a separate Comment components", () => {
|
114
104
|
const wrapper = shallow(<Comment comment={comment} session={session} votable />);
|
115
105
|
wrapper.find(Comment).forEach((node, idx) => {
|
116
|
-
expect(node).to.have.prop("comment").deep.equal(comment.
|
106
|
+
expect(node).to.have.prop("comment").deep.equal(comment.comments[idx]);
|
117
107
|
expect(node).to.have.prop("session").deep.equal(session);
|
118
108
|
expect(node).to.have.prop("articleClassName").equal("comment comment--nested")
|
119
109
|
expect(node).to.have.prop("votable").equal(true);
|
120
110
|
});
|
121
111
|
});
|
122
112
|
|
123
|
-
it("should render comment
|
113
|
+
it("should render comment's comments with articleClassName as 'comment comment--nested comment--nested--alt' when articleClassName is 'comment comment--nested'", () => {
|
124
114
|
const wrapper = shallow(<Comment comment={comment} session={session} articleClassName="comment comment--nested" />);
|
125
115
|
wrapper.find(Comment).forEach((node) => {
|
126
116
|
expect(node).to.have.prop("articleClassName").equal("comment comment--nested comment--nested--alt")
|
@@ -137,6 +127,17 @@ describe("<Comment />", () => {
|
|
137
127
|
expect(wrapper).to.have.prop("isRootComment").equal(false);
|
138
128
|
});
|
139
129
|
|
130
|
+
describe("when the comment cannot accept new comments", () => {
|
131
|
+
beforeEach(() => {
|
132
|
+
comment.acceptsNewComments = false;
|
133
|
+
});
|
134
|
+
|
135
|
+
it("should not render the reply button", () => {
|
136
|
+
const wrapper = shallow(<Comment comment={comment} session={session} />);
|
137
|
+
expect(wrapper.find('button.comment__reply')).not.to.be.present();
|
138
|
+
});
|
139
|
+
})
|
140
|
+
|
140
141
|
describe("when user is not logged in", () => {
|
141
142
|
beforeEach(() => {
|
142
143
|
session = null;
|
@@ -26,7 +26,7 @@ class CommentOrderSelector extends Component {
|
|
26
26
|
return (
|
27
27
|
<div className="order-by__dropdown order-by__dropdown--right">
|
28
28
|
<span className="order-by__text">{ I18n.t("components.comment_order_selector.title") }</span>
|
29
|
-
<ul className="dropdown menu" data-dropdown-menu>
|
29
|
+
<ul className="dropdown menu" data-dropdown-menu data-close-on-click-inside="false">
|
30
30
|
<li>
|
31
31
|
<a>{ I18n.t(`components.comment_order_selector.order.${orderBy}`) }</a>
|
32
32
|
<ul className="menu">
|
@@ -33,14 +33,14 @@ class CommentThread extends Component {
|
|
33
33
|
}
|
34
34
|
|
35
35
|
/**
|
36
|
-
* Render conversation title if comment has
|
36
|
+
* Render conversation title if comment has commments
|
37
37
|
* @private
|
38
38
|
* @returns {Void|DOMElement} - The conversation's title
|
39
39
|
*/
|
40
40
|
_renderTitle() {
|
41
|
-
const { comment: { author,
|
41
|
+
const { comment: { author, hasComments } } = this.props;
|
42
42
|
|
43
|
-
if (
|
43
|
+
if (hasComments) {
|
44
44
|
return (
|
45
45
|
<h6 className="comment-thread__title">
|
46
46
|
{ I18n.t("components.comment_thread.title", { authorName: author.name }) }
|
@@ -41,16 +41,16 @@ describe('<CommentThread />', () => {
|
|
41
41
|
comment = filter(fragment, commentsData[0]);
|
42
42
|
});
|
43
43
|
|
44
|
-
describe("when comment doesn't have
|
44
|
+
describe("when comment doesn't have comments", () => {
|
45
45
|
it("should not render a title with author name", () => {
|
46
46
|
const wrapper = shallow(<CommentThread comment={comment} session={session} />);
|
47
47
|
expect(wrapper.find('h6.comment-thread__title')).not.to.present();
|
48
48
|
});
|
49
49
|
});
|
50
50
|
|
51
|
-
describe("when comment does
|
51
|
+
describe("when comment does has comments", () => {
|
52
52
|
beforeEach(() => {
|
53
|
-
comment.
|
53
|
+
comment.hasComments = true;
|
54
54
|
});
|
55
55
|
|
56
56
|
it("should render a h6 comment-thread__title with author name", () => {
|