diff --git a/webapp/components/Button/JoinLeaveButton.spec.js b/webapp/components/Button/JoinLeaveButton.spec.js
new file mode 100755
index 000000000..d0d7968fc
--- /dev/null
+++ b/webapp/components/Button/JoinLeaveButton.spec.js
@@ -0,0 +1,38 @@
+import { shallowMount } from '@vue/test-utils'
+
+import Component from './JoinLeaveButton.vue'
+
+const localVue = global.localVue
+
+describe('JoinLeaveButton.vue', () => {
+ let propsData, wrapper, mocks
+
+ beforeEach(() => {
+ propsData = {
+ group: {
+ id: 'g-1',
+ name: 'Group 1',
+ },
+ userId: 'u1',
+ isMember: false,
+ isNonePendingMember: false,
+ }
+ mocks = {
+ $t: jest.fn((t) => t),
+ }
+ })
+
+ const Wrapper = () => {
+ return shallowMount(Component, { propsData, localVue, mocks })
+ }
+
+ describe('shallowMount', () => {
+ beforeEach(() => {
+ wrapper = Wrapper()
+ })
+
+ it('renders', () => {
+ expect(wrapper).toMatchSnapshot()
+ })
+ })
+})
diff --git a/webapp/components/Button/JoinLeaveButton.vue b/webapp/components/Button/JoinLeaveButton.vue
index f4cc2c009..1035ee3c6 100644
--- a/webapp/components/Button/JoinLeaveButton.vue
+++ b/webapp/components/Button/JoinLeaveButton.vue
@@ -4,7 +4,7 @@
:disabled="disabled"
:loading="localLoading"
:icon="icon"
- :filled="isMember && !hovered"
+ :filled="filled || (isMember && !hovered)"
:danger="isMember && hovered"
v-tooltip="tooltip"
@mouseenter.native="onHover"
@@ -26,6 +26,7 @@ export default {
userId: { type: String, required: true },
isMember: { type: Boolean, required: true },
isNonePendingMember: { type: Boolean, required: true },
+ filled: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
loading: { type: Boolean, default: false },
},
diff --git a/webapp/components/Button/__snapshots__/JoinLeaveButton.spec.js.snap b/webapp/components/Button/__snapshots__/JoinLeaveButton.spec.js.snap
new file mode 100755
index 000000000..1cd5db0a4
--- /dev/null
+++ b/webapp/components/Button/__snapshots__/JoinLeaveButton.spec.js.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`JoinLeaveButton.vue shallowMount renders 1`] = `
+
+ group.joinLeaveButton.join
+
+`;
diff --git a/webapp/components/Empty/CallToAction/CtaJoinLeaveGroup.spec.js b/webapp/components/Empty/CallToAction/CtaJoinLeaveGroup.spec.js
new file mode 100755
index 000000000..f0a1026a5
--- /dev/null
+++ b/webapp/components/Empty/CallToAction/CtaJoinLeaveGroup.spec.js
@@ -0,0 +1,79 @@
+import { mount, RouterLinkStub } from '@vue/test-utils'
+
+import Component from './CtaJoinLeaveGroup.vue'
+
+const localVue = global.localVue
+
+describe('CtaJoinLeaveGroup.vue', () => {
+ let propsData, wrapper, mocks, stubs
+
+ beforeEach(() => {
+ propsData = {
+ group: {
+ id: 'g-123',
+ slug: 'group-123',
+ name: 'Group 123',
+ myRole: null,
+ },
+ }
+ mocks = {
+ $t: jest.fn((t) => t),
+ $store: {
+ getters: {
+ 'auth/user': {
+ id: 'u-1',
+ },
+ },
+ },
+ $apollo: {
+ mutate: jest.fn(),
+ },
+ }
+ stubs = {
+ NuxtLink: RouterLinkStub,
+ }
+ })
+
+ const Wrapper = () => {
+ return mount(Component, { propsData, localVue, mocks, stubs })
+ }
+
+ describe('mount', () => {
+ beforeEach(() => {
+ wrapper = Wrapper()
+ })
+
+ it('renders', () => {
+ expect(wrapper).toMatchSnapshot()
+ })
+
+ describe('clicking on button', () => {
+ beforeEach(async () => {
+ mocks.$apollo.mutate = jest.fn().mockResolvedValue({
+ data: {
+ JoinGroup: {
+ id: 'g-123',
+ slug: 'group-123',
+ name: 'Group 123',
+ myRoleInGroup: 'usual',
+ },
+ },
+ })
+ wrapper.find('.base-button').trigger('click')
+ await wrapper.vm.$nextTick()
+ })
+ it('emits update event', async () => {
+ expect(wrapper.emitted().update).toEqual([
+ [
+ {
+ id: 'g-123',
+ slug: 'group-123',
+ name: 'Group 123',
+ myRoleInGroup: 'usual',
+ },
+ ],
+ ])
+ })
+ })
+ })
+})
diff --git a/webapp/components/Empty/CallToAction/CtaJoinLeaveGroup.vue b/webapp/components/Empty/CallToAction/CtaJoinLeaveGroup.vue
new file mode 100644
index 000000000..e0ec24dfe
--- /dev/null
+++ b/webapp/components/Empty/CallToAction/CtaJoinLeaveGroup.vue
@@ -0,0 +1,64 @@
+
+
+
+
+ {{ $t('contribution.comment.commenting-disabled.no-group-member.reason') }}
+
+ {{ group.name }}
+
+
+
+ {{ $t('contribution.comment.commenting-disabled.no-group-member.call-to-action') }}
+
+
+
+
+
+
+
+
diff --git a/webapp/components/Empty/CallToAction/CtaUnblockAuthor.spec.js b/webapp/components/Empty/CallToAction/CtaUnblockAuthor.spec.js
new file mode 100755
index 000000000..66e46b4b5
--- /dev/null
+++ b/webapp/components/Empty/CallToAction/CtaUnblockAuthor.spec.js
@@ -0,0 +1,36 @@
+import { shallowMount } from '@vue/test-utils'
+
+import Component from './CtaUnblockAuthor.vue'
+
+const localVue = global.localVue
+
+describe('CtaUnblockAuthor.vue', () => {
+ let propsData, wrapper, mocks
+
+ beforeEach(() => {
+ propsData = {
+ author: {
+ id: 'u-123',
+ slug: 'user-123',
+ name: 'User 123',
+ },
+ }
+ mocks = {
+ $t: jest.fn((t) => t),
+ }
+ })
+
+ const Wrapper = () => {
+ return shallowMount(Component, { propsData, localVue, mocks })
+ }
+
+ describe('shallowMount', () => {
+ beforeEach(() => {
+ wrapper = Wrapper()
+ })
+
+ it('renders', () => {
+ expect(wrapper).toMatchSnapshot()
+ })
+ })
+})
diff --git a/webapp/components/Empty/CallToAction/CtaUnblockAuthor.vue b/webapp/components/Empty/CallToAction/CtaUnblockAuthor.vue
new file mode 100644
index 000000000..aa6d39335
--- /dev/null
+++ b/webapp/components/Empty/CallToAction/CtaUnblockAuthor.vue
@@ -0,0 +1,38 @@
+
+
+
+
+ {{ $t('contribution.comment.commenting-disabled.blocked-author.reason') }}
+
+
+ {{ $t('contribution.comment.commenting-disabled.blocked-author.call-to-action') }}
+
+
+
+ {{
+ $t('contribution.comment.commenting-disabled.blocked-author.button-label', {
+ name: author.name,
+ })
+ }}
+
+
+
+
+
+
diff --git a/webapp/components/Empty/CallToAction/__snapshots__/CtaJoinLeaveGroup.spec.js.snap b/webapp/components/Empty/CallToAction/__snapshots__/CtaJoinLeaveGroup.spec.js.snap
new file mode 100644
index 000000000..671f16eb4
--- /dev/null
+++ b/webapp/components/Empty/CallToAction/__snapshots__/CtaJoinLeaveGroup.spec.js.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CtaJoinLeaveGroup.vue mount renders 1`] = `
+
+
+
+ contribution.comment.commenting-disabled.no-group-member.reason
+
+ Group 123
+
+
+
+ contribution.comment.commenting-disabled.no-group-member.call-to-action
+
+
+`;
diff --git a/webapp/components/Empty/CallToAction/__snapshots__/CtaUnblockAuthor.spec.js.snap b/webapp/components/Empty/CallToAction/__snapshots__/CtaUnblockAuthor.spec.js.snap
new file mode 100755
index 000000000..d3b8ad797
--- /dev/null
+++ b/webapp/components/Empty/CallToAction/__snapshots__/CtaUnblockAuthor.spec.js.snap
@@ -0,0 +1,18 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CtaUnblockAuthor.vue shallowMount renders 1`] = `
+
+
+
+ contribution.comment.commenting-disabled.blocked-author.reason
+
+
+ contribution.comment.commenting-disabled.blocked-author.call-to-action
+
+
+
+ contribution.comment.commenting-disabled.blocked-author.button-label
+
+
+
+`;
diff --git a/webapp/components/Empty/Empty.vue b/webapp/components/Empty/Empty.vue
index 9d5e075fe..1f4c6a441 100644
--- a/webapp/components/Empty/Empty.vue
+++ b/webapp/components/Empty/Empty.vue
@@ -1,19 +1,22 @@
-
-
-
-
-
- {{ message }}
+
+
+
+
+
+
+ {{ message }}
+
-
-
+
+
+