cozy-sharing 12.1.0 → 12.2.0

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.
@@ -1,19 +1,16 @@
1
- import { mount } from 'enzyme'
1
+ import { render, screen } from '@testing-library/react'
2
2
  import React from 'react'
3
3
 
4
4
  import { ContactSuggestion } from './ContactSuggestion'
5
5
  import AppLike from '../../test/AppLike'
6
6
 
7
- const WrappingComponent = ({ children }) => <AppLike>{children}</AppLike>
8
-
9
7
  describe('ContactSuggestion component', () => {
10
- const fakeT = jest.fn((s, args) => {
11
- if (s === 'Share.members.count') {
12
- return `${args.smart_count} members`
13
- }
8
+ const setup = ({ contactOrGroup }) => {
9
+ return render(<ContactSuggestion contactOrGroup={contactOrGroup} />, {
10
+ wrapper: AppLike
11
+ })
12
+ }
14
13
 
15
- return s
16
- })
17
14
  it('should display contact suggestion for a contact', () => {
18
15
  const jonSnow = {
19
16
  _id: 'f3a4e501-abbd',
@@ -36,17 +33,9 @@ describe('ContactSuggestion component', () => {
36
33
  ],
37
34
  _type: 'io.cozy.contacts'
38
35
  }
39
- const contacts = [jonSnow]
40
- const props = {
41
- contactOrGroup: jonSnow,
42
- contacts,
43
- t: fakeT
44
- }
45
- const jsx = <ContactSuggestion {...props} />
46
- const wrapper = mount(jsx, {
47
- wrappingComponent: WrappingComponent
48
- })
49
- expect(wrapper).toMatchSnapshot()
36
+ setup({ contactOrGroup: jonSnow })
37
+ expect(screen.getByText('Jon Snow')).toBeInTheDocument()
38
+ expect(screen.getByText('https://jonsnow.mycozy.cloud')).toBeInTheDocument()
50
39
  })
51
40
 
52
41
  it('should display contact suggestion for a contact without fullname (for example created by a share modal)', () => {
@@ -62,91 +51,19 @@ describe('ContactSuggestion component', () => {
62
51
  name: undefined,
63
52
  _type: 'io.cozy.contacts'
64
53
  }
65
- const contacts = [jonSnow]
66
- const props = {
67
- contactOrGroup: jonSnow,
68
- contacts,
69
- t: fakeT
70
- }
71
- const jsx = <ContactSuggestion {...props} />
72
- const wrapper = mount(jsx, {
73
- wrappingComponent: WrappingComponent
74
- })
75
- expect(wrapper).toMatchSnapshot()
54
+ setup({ contactOrGroup: jonSnow })
55
+ expect(screen.getByText('jon.snow@email.com')).toBeInTheDocument()
76
56
  })
77
57
 
78
58
  it('should display contact suggestion for a group', () => {
79
- const jon = {
80
- _id: 'f3a4e501-abbd',
81
- fullname: 'Jon Snow',
82
- name: {
83
- givenName: 'Jon',
84
- familyName: 'Snow'
85
- },
86
- email: [
87
- {
88
- address: 'jon.snow@email.com',
89
- type: 'primary'
90
- }
91
- ],
92
- _type: 'io.cozy.contacts',
93
- relationships: {
94
- groups: {
95
- data: [{ _id: '610718e6-2d7a', _type: 'io.cozy.contacts.groups' }]
96
- }
97
- }
98
- }
99
- const cersei = {
100
- _id: '42dc490a-7878',
101
- fullname: 'Cersei Lannister',
102
- name: {
103
- givenName: 'Cersei',
104
- familyName: 'Lannister'
105
- },
106
- email: [
107
- {
108
- address: 'cersei@email.com',
109
- type: 'primary'
110
- }
111
- ],
112
- _type: 'io.cozy.contacts',
113
- relationships: { groups: { data: [] } }
114
- }
115
- const sam = {
116
- _id: 'b5bed853-93da',
117
- fullname: 'Samwell Tarly',
118
- name: {
119
- givenName: 'Samwell',
120
- familyName: 'Tarly'
121
- },
122
- email: [
123
- {
124
- address: 'samwell@email.com',
125
- type: 'primary'
126
- }
127
- ],
128
- _type: 'io.cozy.contacts',
129
- relationships: {
130
- groups: {
131
- data: [{ _id: '610718e6-2d7a', _type: 'io.cozy.contacts.groups' }]
132
- }
133
- }
134
- }
135
- const contacts = [jon, cersei, sam]
136
59
  const theNightsWatch = {
137
60
  _id: '610718e6-2d7a',
138
61
  name: "The Night's Watch",
139
- _type: 'io.cozy.contacts.groups'
62
+ _type: 'io.cozy.contacts.groups',
63
+ membersCount: 2
140
64
  }
141
- const props = {
142
- contactOrGroup: theNightsWatch,
143
- contacts,
144
- t: fakeT
145
- }
146
- const jsx = <ContactSuggestion {...props} />
147
- const wrapper = mount(jsx, {
148
- wrappingComponent: WrappingComponent
149
- })
150
- expect(wrapper).toMatchSnapshot()
65
+ setup({ contactOrGroup: theNightsWatch })
66
+ expect(screen.getByText("The Night's Watch")).toBeInTheDocument()
67
+ expect(screen.getByText('2 members')).toBeInTheDocument()
151
68
  })
152
69
  })
@@ -165,12 +165,7 @@ const ShareAutocomplete = ({
165
165
  )
166
166
 
167
167
  const renderSuggestion = contactOrGroup => (
168
- <ContactSuggestion
169
- contacts={contactsAndGroups.filter(
170
- item => item._type === Contact.doctype
171
- )}
172
- contactOrGroup={contactOrGroup}
173
- />
168
+ <ContactSuggestion contactOrGroup={contactOrGroup} />
174
169
  )
175
170
 
176
171
  return (
@@ -1,3 +1,4 @@
1
+ import get from 'lodash/get'
1
2
  import PropTypes from 'prop-types'
2
3
  import React, { useState, useEffect } from 'react'
3
4
 
@@ -42,7 +43,24 @@ const ShareRecipientsInput = ({
42
43
  if (contacts.hasMore || contacts.fetchStatus === 'loading') {
43
44
  return contacts.data
44
45
  } else {
45
- return [...contacts.data, ...contactGroups.data]
46
+ const contactGroupsWithCount = contactGroups.data
47
+ .map(contactGroup => ({
48
+ ...contactGroup,
49
+ membersCount: contacts.data.reduce((total, contact) => {
50
+ if (
51
+ get(contact, 'relationships.groups.data', [])
52
+ .map(group => group._id)
53
+ .includes(contactGroup._id)
54
+ ) {
55
+ return total + 1
56
+ }
57
+
58
+ return total
59
+ }, 0)
60
+ }))
61
+ .filter(contactGroup => contactGroup.membersCount > 0)
62
+
63
+ return [...contacts.data, ...contactGroupsWithCount]
46
64
  }
47
65
  }
48
66
 
@@ -1,138 +1,200 @@
1
- import { shallow } from 'enzyme'
1
+ import { render, screen } from '@testing-library/react'
2
2
  import React from 'react'
3
3
 
4
4
  import ShareRecipientsInput from './ShareRecipientsInput'
5
5
 
6
- describe('ShareRecipientsInput component', () => {
7
- it('should match snapshot', () => {
8
- const props = {
9
- client: '',
10
- label: 'Recipients',
11
- contacts: {
12
- id: 'contacts',
13
- fetchStatus: 'loaded',
14
- hasMore: false,
15
- data: [
16
- {
17
- id: 'df563cc4-6440',
18
- _id: 'df563cc4-6440',
19
- _type: 'io.cozy.contacts',
20
- name: {
21
- givenName: 'Michale',
22
- familyName: 'Russel'
23
- }
24
- },
25
- {
26
- id: '5a3b4ccf-c257',
27
- _id: '5a3b4ccf-c257',
28
- _type: 'io.cozy.contacts',
29
- name: {
30
- givenName: 'Teagan',
31
- familyName: 'Wolf'
32
- }
6
+ jest.mock('./ShareAutosuggest', () => ({
7
+ __esModule: true,
8
+ default: ({ contactsAndGroups }) => {
9
+ return (
10
+ <ul>
11
+ {contactsAndGroups.map(contactOrGroup => {
12
+ if (contactOrGroup._type === 'io.cozy.contacts') {
13
+ return (
14
+ <li key={contactOrGroup.id}>
15
+ {contactOrGroup.name.givenName} {contactOrGroup.name.familyName}
16
+ </li>
17
+ )
18
+ } else {
19
+ return <li key={contactOrGroup.id}>{contactOrGroup.name}</li>
33
20
  }
34
- ]
35
- },
36
- contactGroups: {
37
- id: 'groups',
38
- fetchStatus: 'loaded',
39
- hasMore: false,
40
- data: [
41
- {
42
- id: 'fe86af20-c6c5',
43
- name: "The Night's Watch",
44
- _id: 'fe86af20-c6c5',
45
- _type: 'io.cozy.contacts.groups'
46
- },
47
- {
48
- id: '3d8193ab-2ce4',
49
- name: 'The North',
50
- _id: '3d8193ab-2ce4',
51
- _type: 'io.cozy.contacts.groups'
21
+ })}
22
+ </ul>
23
+ )
24
+ }
25
+ }))
26
+
27
+ describe('ShareRecipientsInput component', () => {
28
+ const setup = ({ contacts, contactGroups }) => {
29
+ render(
30
+ <ShareRecipientsInput
31
+ contacts={contacts}
32
+ contactGroups={contactGroups}
33
+ onPick={() => {}}
34
+ onRemove={() => {}}
35
+ placeholder="Enter recipients here"
36
+ />
37
+ )
38
+ }
39
+
40
+ it('should include groups and contacts when are loaded', async () => {
41
+ const contacts = {
42
+ id: 'contacts',
43
+ fetchStatus: 'loaded',
44
+ hasMore: false,
45
+ data: [
46
+ {
47
+ id: 'df563cc4-6440',
48
+ _id: 'df563cc4-6440',
49
+ _type: 'io.cozy.contacts',
50
+ name: {
51
+ givenName: 'Michale',
52
+ familyName: 'Russel'
52
53
  }
53
- ]
54
- },
55
- recipients: [
54
+ },
56
55
  {
57
56
  id: '5a3b4ccf-c257',
57
+ _id: '5a3b4ccf-c257',
58
+ _type: 'io.cozy.contacts',
58
59
  name: {
59
60
  givenName: 'Teagan',
60
61
  familyName: 'Wolf'
62
+ },
63
+ relationships: {
64
+ groups: {
65
+ data: [
66
+ {
67
+ _id: 'fe86af20-c6c5',
68
+ _type: 'io.cozy.contacts.groups'
69
+ }
70
+ ]
71
+ }
61
72
  }
62
73
  }
63
- ],
64
- onPick: jest.fn().mockName('onPick'),
65
- onRemove: jest.fn().mockName('onRemove'),
66
- placeholder: 'Enter recipients here'
74
+ ]
75
+ }
76
+ const contactGroups = {
77
+ id: 'groups',
78
+ fetchStatus: 'loaded',
79
+ hasMore: false,
80
+ data: [
81
+ {
82
+ id: 'fe86af20-c6c5',
83
+ name: "The Night's Watch",
84
+ _id: 'fe86af20-c6c5',
85
+ _type: 'io.cozy.contacts.groups'
86
+ }
87
+ ]
67
88
  }
68
- const jsx = <ShareRecipientsInput {...props} />
69
- const wrapper = shallow(jsx)
70
- expect(wrapper).toMatchSnapshot()
89
+
90
+ setup({ contacts, contactGroups })
91
+
92
+ expect(screen.getByText('Michale Russel')).toBeInTheDocument()
93
+ expect(screen.getByText('Teagan Wolf')).toBeInTheDocument()
94
+ expect(screen.getByText("The Night's Watch")).toBeInTheDocument()
71
95
  })
72
96
 
73
- it('should include groups only if all contacts are loaded', () => {
74
- const props = {
75
- client: '',
76
- label: 'Recipients',
77
- contacts: {
78
- id: 'contacts',
79
- fetchStatus: 'loading',
80
- hasMore: false,
81
- data: [
82
- {
83
- id: 'df563cc4-6440',
84
- _id: 'df563cc4-6440',
85
- _type: 'io.cozy.contacts',
86
- name: {
87
- givenName: 'Michale',
88
- familyName: 'Russel'
89
- }
97
+ it('should include groups only if all contacts are loaded', async () => {
98
+ const contacts = {
99
+ id: 'contacts',
100
+ fetchStatus: 'loading',
101
+ hasMore: false,
102
+ data: [
103
+ {
104
+ id: 'df563cc4-6440',
105
+ _id: 'df563cc4-6440',
106
+ _type: 'io.cozy.contacts',
107
+ name: {
108
+ givenName: 'Michale',
109
+ familyName: 'Russel'
110
+ }
111
+ },
112
+ {
113
+ id: '5a3b4ccf-c257',
114
+ _id: '5a3b4ccf-c257',
115
+ _type: 'io.cozy.contacts',
116
+ name: {
117
+ givenName: 'Teagan',
118
+ familyName: 'Wolf'
90
119
  },
91
- {
92
- id: '5a3b4ccf-c257',
93
- _id: '5a3b4ccf-c257',
94
- _type: 'io.cozy.contacts',
95
- name: {
96
- givenName: 'Teagan',
97
- familyName: 'Wolf'
120
+ relationships: {
121
+ groups: {
122
+ data: [
123
+ {
124
+ _id: 'fe86af20-c6c5',
125
+ _type: 'io.cozy.contacts.groups'
126
+ }
127
+ ]
98
128
  }
99
129
  }
100
- ]
101
- },
102
- contactGroups: {
103
- id: 'groups',
104
- fetchStatus: 'loaded',
105
- hasMore: false,
106
- data: [
107
- {
108
- id: 'fe86af20-c6c5',
109
- name: "The Night's Watch",
110
- _id: 'fe86af20-c6c5',
111
- _type: 'io.cozy.contacts.groups'
112
- },
113
- {
114
- id: '3d8193ab-2ce4',
115
- name: 'The North',
116
- _id: '3d8193ab-2ce4',
117
- _type: 'io.cozy.contacts.groups'
130
+ }
131
+ ]
132
+ }
133
+ const contactGroups = {
134
+ id: 'groups',
135
+ fetchStatus: 'loaded',
136
+ hasMore: false,
137
+ data: [
138
+ {
139
+ id: 'fe86af20-c6c5',
140
+ name: "The Night's Watch",
141
+ _id: 'fe86af20-c6c5',
142
+ _type: 'io.cozy.contacts.groups'
143
+ }
144
+ ]
145
+ }
146
+
147
+ setup({ contacts, contactGroups })
148
+
149
+ expect(screen.getByText('Michale Russel')).toBeInTheDocument()
150
+ expect(screen.getByText('Teagan Wolf')).toBeInTheDocument()
151
+ expect(screen.queryByText("The Night's Watch")).toBeNull()
152
+ })
153
+
154
+ it('should include groups only if they have more than one member', async () => {
155
+ const contacts = {
156
+ id: 'contacts',
157
+ fetchStatus: 'loaded',
158
+ hasMore: false,
159
+ data: [
160
+ {
161
+ id: 'df563cc4-6440',
162
+ _id: 'df563cc4-6440',
163
+ _type: 'io.cozy.contacts',
164
+ name: {
165
+ givenName: 'Michale',
166
+ familyName: 'Russel'
118
167
  }
119
- ]
120
- },
121
- recipients: [
168
+ },
122
169
  {
123
170
  id: '5a3b4ccf-c257',
171
+ _id: '5a3b4ccf-c257',
172
+ _type: 'io.cozy.contacts',
124
173
  name: {
125
174
  givenName: 'Teagan',
126
175
  familyName: 'Wolf'
127
176
  }
128
177
  }
129
- ],
130
- onPick: jest.fn().mockName('onPick'),
131
- onRemove: jest.fn().mockName('onRemove'),
132
- placeholder: 'Enter recipients here'
178
+ ]
133
179
  }
134
- const jsx = <ShareRecipientsInput {...props} />
135
- const wrapper = shallow(jsx)
136
- expect(wrapper).toMatchSnapshot()
180
+ const contactGroups = {
181
+ id: 'groups',
182
+ fetchStatus: 'loaded',
183
+ hasMore: false,
184
+ data: [
185
+ {
186
+ id: 'fe86af20-c6c5',
187
+ name: "The Night's Watch",
188
+ _id: 'fe86af20-c6c5',
189
+ _type: 'io.cozy.contacts.groups'
190
+ }
191
+ ]
192
+ }
193
+
194
+ setup({ contacts, contactGroups })
195
+
196
+ expect(screen.getByText('Michale Russel')).toBeInTheDocument()
197
+ expect(screen.getByText('Teagan Wolf')).toBeInTheDocument()
198
+ expect(screen.queryByText("The Night's Watch")).toBeNull()
137
199
  })
138
200
  })