Skip to content

Commit 2ff39da

Browse files
doublefacedoubleface
doubleface
authored andcommittedNov 5, 2021
feat: Display a message when running a konnector is not possible
When a konnector is clientSide and there is not launcher available in the environment, Harvest will now display a message and hide the "run" button. The same message is also displayed when trying to configure a new account.

File tree

11 files changed

+372
-142
lines changed

11 files changed

+372
-142
lines changed
 

‎packages/cozy-harvest-lib/src/components/AccountForm/__snapshots__/index.spec.jsx.snap

+147-80
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,36 @@ exports[`AccountForm should not render error 1`] = `
55
onFocusCapture={[Function]}
66
onKeyUp={[Function]}
77
>
8-
<AccountFields
9-
fields={
10-
Object {
11-
"passphrase": Object {
12-
"encrypted": true,
13-
"required": true,
14-
"type": "password",
15-
},
16-
"username": Object {
17-
"encrypted": false,
18-
"required": true,
19-
"role": "identifier",
20-
"type": "text",
21-
},
8+
<React.Fragment>
9+
<AccountFields
10+
fields={
11+
Object {
12+
"passphrase": Object {
13+
"encrypted": true,
14+
"required": true,
15+
"type": "password",
16+
},
17+
"username": Object {
18+
"encrypted": false,
19+
"required": true,
20+
"role": "identifier",
21+
"type": "text",
22+
},
23+
}
2224
}
23-
}
24-
hasError={false}
25-
initialValues={Object {}}
26-
inputRefByName={[Function]}
27-
t={[Function]}
28-
/>
29-
<DefaultButton
30-
className="u-mt-2 u-mb-1-half"
31-
disabled={false}
32-
extension="full"
33-
label="Connect"
34-
onClick={[Function]}
35-
/>
25+
hasError={false}
26+
initialValues={Object {}}
27+
inputRefByName={[Function]}
28+
t={[Function]}
29+
/>
30+
<DefaultButton
31+
className="u-mt-2 u-mb-1-half"
32+
disabled={false}
33+
extension="full"
34+
label="Connect"
35+
onClick={[Function]}
36+
/>
37+
</React.Fragment>
3638
</div>
3739
`;
3840

@@ -41,33 +43,35 @@ exports[`AccountForm should render 1`] = `
4143
onFocusCapture={[Function]}
4244
onKeyUp={[Function]}
4345
>
44-
<AccountFields
45-
fields={
46-
Object {
47-
"passphrase": Object {
48-
"encrypted": true,
49-
"required": true,
50-
"type": "password",
51-
},
52-
"username": Object {
53-
"encrypted": false,
54-
"required": true,
55-
"role": "identifier",
56-
"type": "text",
57-
},
46+
<React.Fragment>
47+
<AccountFields
48+
fields={
49+
Object {
50+
"passphrase": Object {
51+
"encrypted": true,
52+
"required": true,
53+
"type": "password",
54+
},
55+
"username": Object {
56+
"encrypted": false,
57+
"required": true,
58+
"role": "identifier",
59+
"type": "text",
60+
},
61+
}
5862
}
59-
}
60-
initialValues={Object {}}
61-
inputRefByName={[Function]}
62-
t={[Function]}
63-
/>
64-
<DefaultButton
65-
className="u-mt-2 u-mb-1-half"
66-
disabled={true}
67-
extension="full"
68-
label="Connect"
69-
onClick={[Function]}
70-
/>
63+
initialValues={Object {}}
64+
inputRefByName={[Function]}
65+
t={[Function]}
66+
/>
67+
<DefaultButton
68+
className="u-mt-2 u-mb-1-half"
69+
disabled={true}
70+
extension="full"
71+
label="Connect"
72+
onClick={[Function]}
73+
/>
74+
</React.Fragment>
7175
</div>
7276
`;
7377

@@ -92,33 +96,96 @@ exports[`AccountForm should render error 1`] = `
9296
}
9397
}
9498
/>
95-
<AccountFields
96-
fields={
97-
Object {
98-
"passphrase": Object {
99-
"encrypted": true,
100-
"required": true,
101-
"type": "password",
102-
},
103-
"username": Object {
104-
"encrypted": false,
105-
"required": true,
106-
"role": "identifier",
107-
"type": "text",
108-
},
99+
<React.Fragment>
100+
<AccountFields
101+
fields={
102+
Object {
103+
"passphrase": Object {
104+
"encrypted": true,
105+
"required": true,
106+
"type": "password",
107+
},
108+
"username": Object {
109+
"encrypted": false,
110+
"required": true,
111+
"role": "identifier",
112+
"type": "text",
113+
},
114+
}
109115
}
110-
}
111-
hasError={false}
112-
initialValues={Object {}}
113-
inputRefByName={[Function]}
114-
t={[Function]}
115-
/>
116-
<DefaultButton
117-
className="u-mt-2 u-mb-1-half"
118-
disabled={false}
119-
extension="full"
120-
label="Connect"
121-
onClick={[Function]}
122-
/>
116+
hasError={false}
117+
initialValues={Object {}}
118+
inputRefByName={[Function]}
119+
t={[Function]}
120+
/>
121+
<DefaultButton
122+
className="u-mt-2 u-mb-1-half"
123+
disabled={false}
124+
extension="full"
125+
label="Connect"
126+
onClick={[Function]}
127+
/>
128+
</React.Fragment>
129+
</div>
130+
`;
131+
132+
exports[`AccountForm should render normally when client side konnector with launcher 1`] = `
133+
<div
134+
onFocusCapture={[Function]}
135+
onKeyUp={[Function]}
136+
>
137+
<React.Fragment>
138+
<AccountFields
139+
fields={Object {}}
140+
initialValues={Object {}}
141+
inputRefByName={[Function]}
142+
t={[Function]}
143+
/>
144+
<DefaultButton
145+
className="u-mt-2 u-mb-1-half"
146+
disabled={false}
147+
extension="full"
148+
label="Connect"
149+
onClick={[Function]}
150+
/>
151+
</React.Fragment>
152+
</div>
153+
`;
154+
155+
exports[`AccountForm should render with specific message when client side konnector without launcher 1`] = `
156+
<div
157+
onFocusCapture={[Function]}
158+
onKeyUp={[Function]}
159+
>
160+
<React.Fragment>
161+
<Media
162+
align="top"
163+
>
164+
<Img
165+
className="u-m-1"
166+
>
167+
<Icon
168+
icon={[Function]}
169+
spin={false}
170+
/>
171+
</Img>
172+
<Bd
173+
className="u-m-1"
174+
>
175+
<ForwardRef(WithStyles)
176+
variant="body1"
177+
>
178+
The testkonnector application uses a brand-new and efficient system for retrieving your data from your Cozy. This action is only accessible from the Cozy mobile app.
179+
</ForwardRef(WithStyles)>
180+
</Bd>
181+
</Media>
182+
<ButtonLink
183+
className="u-mt-2 u-mb-1-half"
184+
extension="full"
185+
href="#"
186+
label="Install Cozy on mobile"
187+
tag="a"
188+
/>
189+
</React.Fragment>
123190
</div>
124191
`;

‎packages/cozy-harvest-lib/src/components/AccountForm/index.jsx

+49-22
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ import get from 'lodash/get'
55
import compose from 'lodash/flowRight'
66

77
import { isMobile } from 'cozy-device-helper'
8-
import Button from 'cozy-ui/transpiled/react/Button'
8+
import Button, { ButtonLink } from 'cozy-ui/transpiled/react/Button'
9+
import Icon from 'cozy-ui/transpiled/react/Icon'
10+
import Info from 'cozy-ui/transpiled/react/Icons/Info'
11+
import { Media, Img, Bd } from 'cozy-ui/transpiled/react/Media'
12+
import Typography from 'cozy-ui/transpiled/react/Typography'
913
import withLocales from '../hoc/withLocales'
1014
import AccountFields from './AccountFields'
1115

1216
import ReadOnlyIdentifier from './ReadOnlyIdentifier'
1317
import TriggerErrorInfo from '../infos/TriggerErrorInfo'
1418
import { getEncryptedFieldName } from '../../helpers/fields'
15-
import { KonnectorJobError } from '../../helpers/konnectors'
19+
import { KonnectorJobError, isRunnable } from '../../helpers/konnectors'
1620
import manifest from '../../helpers/manifest'
1721
import fieldHelpers, { SECRET } from '../../helpers/fields'
1822
import withKonnectorLocales from '../hoc/withKonnectorLocales'
@@ -212,7 +216,7 @@ export class AccountForm extends PureComponent {
212216
const submitting = flowState.running
213217
const error = flowState.error
214218

215-
const { fields } = konnector
219+
const { fields, name } = konnector
216220
const sanitizedFields = manifest.sanitizeFields(fields)
217221
fieldHelpers.addForceEncryptedPlaceholder(sanitizedFields, fieldOptions)
218222

@@ -268,25 +272,48 @@ export class AccountForm extends PureComponent {
268272
)}
269273
/>
270274
)}
271-
<AccountFields
272-
disabled={submitting}
273-
fields={sanitizedFields}
274-
hasError={error && isLoginError}
275-
initialValues={values}
276-
inputRefByName={this.inputRefByName}
277-
t={t}
278-
/>
279-
<Button
280-
busy={submitting}
281-
className="u-mt-2 u-mb-1-half"
282-
disabled={
283-
submitting ||
284-
!this.isSubmittable({ dirty, error, initialValues, valid })
285-
}
286-
extension="full"
287-
label={t('accountForm.submit.label')}
288-
onClick={() => this.handleSubmit(values, form)}
289-
/>
275+
{isRunnable({ win: window, konnector }) ? (
276+
<>
277+
<AccountFields
278+
disabled={submitting}
279+
fields={sanitizedFields}
280+
hasError={error && isLoginError}
281+
initialValues={values}
282+
inputRefByName={this.inputRefByName}
283+
t={t}
284+
/>
285+
<Button
286+
busy={submitting}
287+
className="u-mt-2 u-mb-1-half"
288+
disabled={
289+
submitting ||
290+
!this.isSubmittable({ dirty, error, initialValues, valid })
291+
}
292+
extension="full"
293+
label={t('accountForm.submit.label')}
294+
onClick={() => this.handleSubmit(values, form)}
295+
/>
296+
</>
297+
) : (
298+
<>
299+
<Media align="top">
300+
<Img className="u-m-1">
301+
<Icon icon={Info} />
302+
</Img>
303+
<Bd className="u-m-1">
304+
<Typography variant="body1">
305+
{t('accountForm.notClientSide', { name })}
306+
</Typography>
307+
</Bd>
308+
</Media>
309+
<ButtonLink
310+
className="u-mt-2 u-mb-1-half"
311+
extension="full"
312+
label={t('accountForm.installFlagship.label')}
313+
href="#"
314+
/>
315+
</>
316+
)}
290317
{this.state.showConfirmationModal && (
291318
<Dialog
292319
title={t('triggerManager.confirmationModal.title')}

‎packages/cozy-harvest-lib/src/components/AccountForm/index.spec.jsx

+24
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ const fixtures = {
2626
}
2727
}
2828
},
29+
clientSideKonnector: {
30+
clientSide: true,
31+
name: 'testkonnector',
32+
fields: {}
33+
},
2934
konnectorWithOptionalFields: {
3035
fields: {
3136
test: {
@@ -100,6 +105,25 @@ describe('AccountForm', () => {
100105
expect(component).toMatchSnapshot()
101106
})
102107

108+
it('should render with specific message when client side konnector without launcher', () => {
109+
const { wrapper } = setup({ konnector: fixtures.clientSideKonnector })
110+
const component = wrapper.dive().getElement()
111+
expect(component).toMatchSnapshot()
112+
})
113+
114+
it('should render normally when client side konnector with launcher', () => {
115+
const windowSpy = jest.spyOn(window, 'window', 'get')
116+
windowSpy.mockImplementation(() => ({
117+
cozy: {
118+
ClientConnectorLauncher: 'react-native'
119+
}
120+
}))
121+
const { wrapper } = setup({ konnector: fixtures.clientSideKonnector })
122+
const component = wrapper.dive().getElement()
123+
expect(component).toMatchSnapshot()
124+
windowSpy.mockRestore()
125+
})
126+
103127
it('should render error', () => {
104128
const { wrapper } = setup({
105129
error: new Error('Test error')

‎packages/cozy-harvest-lib/src/components/cards/LaunchTriggerCard.jsx

+54-34
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ import React from 'react'
22
import PropTypes from 'prop-types'
33

44
import Button from 'cozy-ui/transpiled/react/Button'
5+
import { Media, Img, Bd } from 'cozy-ui/transpiled/react/Media'
56
import Card from 'cozy-ui/transpiled/react/Card'
67
import { translate } from 'cozy-ui/transpiled/react/I18n'
78
import Icon from 'cozy-ui/transpiled/react/Icon'
9+
import Info from 'cozy-ui/transpiled/react/Icons/Info'
810
import Typography from 'cozy-ui/transpiled/react/Typography'
911
import SyncIcon from 'cozy-ui/transpiled/react/Icons/Sync'
1012

1113
import * as triggers from '../../helpers/triggers'
14+
import { isRunnable } from '../../helpers/konnectors'
1215
import FlowProvider from '../FlowProvider'
1316
import { useFlowState } from '../../models/withConnectionFlow'
1417

@@ -18,8 +21,10 @@ export const DumbLaunchTriggerCard = ({ flow, className, f, t, disabled }) => {
1821
const launch = flow.launch
1922
const flowState = useFlowState(flow)
2023
const trigger = flowState.trigger
24+
const konnector = flow.konnector
2125
const running = flowState.running
2226
const lastSuccessDate = triggers.getLastSuccessDate(trigger)
27+
const isKonnectorRunnable = isRunnable({ win: window, konnector })
2328

2429
return (
2530
<Card className={className}>
@@ -47,42 +52,57 @@ export const DumbLaunchTriggerCard = ({ flow, className, f, t, disabled }) => {
4752
: t('card.launchTrigger.lastSync.unknown')}
4853
</Typography>
4954
</li>
50-
<li className="u-mb-half">
51-
<Typography
52-
variant="caption"
53-
component="span"
54-
style={inlineStyle}
55-
className="u-mr-half"
56-
>
57-
{t('card.launchTrigger.frequency.label')}
58-
</Typography>
59-
<Typography
60-
variant="caption"
61-
color="textPrimary"
62-
component="span"
63-
style={inlineStyle}
64-
>
65-
{t(
66-
`card.launchTrigger.frequency.${triggers.getFrequency(
67-
trigger
68-
) || 'undefined'}`
69-
)}
70-
</Typography>
71-
</li>
55+
{isKonnectorRunnable ? (
56+
<li className="u-mb-half">
57+
<Typography
58+
variant="caption"
59+
component="span"
60+
style={inlineStyle}
61+
className="u-mr-half"
62+
>
63+
{t('card.launchTrigger.frequency.label')}
64+
</Typography>
65+
<Typography
66+
variant="caption"
67+
color="textPrimary"
68+
component="span"
69+
style={inlineStyle}
70+
>
71+
{t(
72+
`card.launchTrigger.frequency.${triggers.getFrequency(
73+
trigger
74+
) || 'undefined'}`
75+
)}
76+
</Typography>
77+
</li>
78+
) : (
79+
<Media align="top">
80+
<Img className="u-m-1">
81+
<Icon icon={Info} />
82+
</Img>
83+
<Bd className="u-m-1">
84+
<Typography variant="body1">
85+
{t('accountForm.notClientSide', { name: konnector.name })}
86+
</Typography>
87+
</Bd>
88+
</Media>
89+
)}
7290
</ul>
73-
<div>
74-
{/* TODO: Extract this directly in Cozy-UI
91+
{isKonnectorRunnable && (
92+
<div>
93+
{/* TODO: Extract this directly in Cozy-UI
7594
(either with an utility class or a Button prop) */}
76-
<Button
77-
label={t('card.launchTrigger.button.label')}
78-
icon={<Icon focusable="false" icon={SyncIcon} spin={running} />}
79-
className="u-mh-0 u-mv-0"
80-
disabled={running || disabled}
81-
onClick={() => launch({ autoSuccessTimer: false })}
82-
subtle
83-
style={{ lineHeight: '1.4' }}
84-
/>
85-
</div>
95+
<Button
96+
label={t('card.launchTrigger.button.label')}
97+
icon={<Icon focusable="false" icon={SyncIcon} spin={running} />}
98+
className="u-mh-0 u-mv-0"
99+
disabled={running || disabled}
100+
onClick={() => launch({ autoSuccessTimer: false })}
101+
subtle
102+
style={{ lineHeight: '1.4' }}
103+
/>
104+
</div>
105+
)}
86106
</div>
87107
</Card>
88108
)

‎packages/cozy-harvest-lib/src/components/cards/LaunchTriggerCard.spec.jsx

+25
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,29 @@ describe('LaunchTriggerCard', () => {
5353
triggerFixture
5454
)
5555
})
56+
57+
it('should render impossible to run message when konnector is clientSide without an accessible launcher', () => {
58+
const { root } = setup({
59+
props: {
60+
flow: new ConnectionFlow(client, triggerFixture, {
61+
slug: 'test',
62+
name: 'testname',
63+
clientSide: true
64+
})
65+
}
66+
})
67+
expect(root.html()).toMatchSnapshot()
68+
})
69+
70+
it('should render normally when konnector is not clientSide', () => {
71+
const { root } = setup({
72+
props: {
73+
flow: new ConnectionFlow(client, triggerFixture, {
74+
slug: 'test',
75+
name: 'testname'
76+
})
77+
}
78+
})
79+
expect(root.html()).toMatchSnapshot()
80+
})
5681
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`LaunchTriggerCard should render impossible to run message when konnector is clientSide without an accessible launcher 1`] = `"<div class=\\"styles__c-card___YgP7B\\"><div class=\\"u-flex u-flex-column-s\\"><ul class=\\"u-nolist u-m-0 u-mr-1 u-pl-0 u-flex-grow-1\\"><li class=\\"u-mb-half\\"><span class=\\"MuiTypography-root u-mr-half MuiTypography-caption\\" style=\\"display: inline-block;\\">Update:</span><span class=\\"MuiTypography-root MuiTypography-caption MuiTypography-colorTextPrimary\\" style=\\"display: inline-block;\\">Unknown</span></li><div class=\\"styles__media___cSJMp styles__media--top___K9w0I\\"><div class=\\"styles__img___3SHpG u-m-1\\"><svg viewBox=\\"0 0 16 16\\" class=\\"styles__icon___23x3R\\" width=\\"16\\" height=\\"16\\"><defs><path id=\\"info_svg__a\\" d=\\"M8 16A8 8 0 118 0a8 8 0 010 16zM7 4a1 1 0 102 0 1 1 0 10-2 0zm1 2H6v2h1v4a1 1 0 001 1h2v-2H9V7a1 1 0 00-1-1z\\"></path></defs><use fill-rule=\\"evenodd\\" xlink:href=\\"#info_svg__a\\"></use></svg></div><div class=\\"styles__bd___1Uv-F u-m-1\\"><p class=\\"MuiTypography-root MuiTypography-body1\\">The testname application uses a brand-new and efficient system for retrieving your data from your Cozy. This action is only accessible from the Cozy mobile app.</p></div></div></ul></div></div>"`;
4+
5+
exports[`LaunchTriggerCard should render normally when konnector is not clientSide 1`] = `"<div class=\\"styles__c-card___YgP7B\\"><div class=\\"u-flex u-flex-column-s\\"><ul class=\\"u-nolist u-m-0 u-mr-1 u-pl-0 u-flex-grow-1\\"><li class=\\"u-mb-half\\"><span class=\\"MuiTypography-root u-mr-half MuiTypography-caption\\" style=\\"display: inline-block;\\">Update:</span><span class=\\"MuiTypography-root MuiTypography-caption MuiTypography-colorTextPrimary\\" style=\\"display: inline-block;\\">Unknown</span></li><li class=\\"u-mb-half\\"><span class=\\"MuiTypography-root u-mr-half MuiTypography-caption\\" style=\\"display: inline-block;\\">Frequency:</span><span class=\\"MuiTypography-root MuiTypography-caption MuiTypography-colorTextPrimary\\" style=\\"display: inline-block;\\">Once a week</span></li></ul><div><button style=\\"line-height: 1.4;\\" type=\\"submit\\" class=\\"styles__c-btn___-2Vnj styles__c-btn--subtle___OknKf styles__c-btn--center___16_Xh u-mh-0 u-mv-0\\"><span><svg viewBox=\\"0 0 16 16\\" class=\\"styles__icon___23x3R\\" width=\\"16\\" height=\\"16\\" focusable=\\"false\\"><path fill-rule=\\"evenodd\\" d=\\"M16 7.2V3c0-.6-.4-1-1-1-.5 0-.8.3-.9.7A8.09 8.09 0 008 0C4.9 0 2 1.8.7 4.6c-.2.5 0 1.1.5 1.3.5.2 1.1 0 1.3-.5C3.5 3.4 5.6 2 8 2c1.5 0 3 .6 4 1.5-.3 0-.6.1-.8.3-.4.4-.3 1.1.1 1.4l3 2.5h.1c.1.1.2.1.3.1h.4c.1 0 .2-.1.3-.1h.1c.1-.1.2-.1.2-.2.2 0 .2-.1.3-.3 0 .1 0 0 0 0m-1.2 2.9c-.5-.2-1.1 0-1.3.5A6 6 0 018 14c-1.5 0-2.9-.6-4-1.5.3 0 .5-.1.7-.4.4-.4.3-1.1-.1-1.4l-3-2.5h-.1L1.3 8h-.1c-.2 0-.5 0-.7.1H.4c-.1.1-.1.2-.2.3-.1.1-.1.2-.2.3V13c0 .6.4 1 1 1 .5 0 .9-.3 1-.8C3.5 14.9 5.6 16 8 16c3.1 0 5.9-1.8 7.3-4.5.2-.5 0-1.1-.5-1.4\\"></path></svg><span>Run again now</span></span></button></div></div></div>"`;

‎packages/cozy-harvest-lib/src/helpers/konnectors.js

+23
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,34 @@ export const buildFolderPermission = folder => {
335335
}
336336
}
337337

338+
/**
339+
* Get's the launcher in the current environment if any
340+
*
341+
* @param {Object} win The window object in the current environment
342+
* @returns {Object}
343+
*/
344+
export const getLauncher = ({ win }) => {
345+
return get(win, 'cozy.ClientConnectorLauncher', null)
346+
}
347+
348+
/**
349+
* Define if it is possible to run a konnector in the current environment
350+
*
351+
* @param {Object} win The window object in the current environment
352+
* @param {Object} konnector The io.cozy.konnectors object for the current konnector
353+
* @returns {Boolean}
354+
*/
355+
export const isRunnable = ({ win, konnector = {} }) => {
356+
return Boolean(!konnector.clientSide || getLauncher({ win }))
357+
}
358+
338359
export default {
339360
KonnectorJobError,
340361
buildFolderPath,
341362
buildFolderPermission,
342363
getAccountType,
364+
getLauncher,
365+
isRunnable,
343366
hasNewVersionAvailable,
344367
needsFolder
345368
}

‎packages/cozy-harvest-lib/src/helpers/konnectors.spec.js

+30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
KonnectorJobError,
77
needsFolder,
88
getErrorLocale,
9+
getLauncher,
10+
isRunnable,
911
getErrorLocaleBound
1012
} from 'helpers/konnectors'
1113

@@ -267,6 +269,34 @@ describe('Konnectors Helpers', () => {
267269
expect(error.type).toBe('UNKNOWN_ERROR')
268270
})
269271
})
272+
273+
describe('getLauncher', () => {
274+
it('should get the current Launcher from the given window object', () => {
275+
const cozy = {
276+
ClientConnectorLauncher: 'test-react-native'
277+
}
278+
expect(getLauncher({ win: { cozy } })).toEqual('test-react-native')
279+
})
280+
it('should should return null if no launcher is available', () => {
281+
expect(getLauncher({ win: {} })).toBe(null)
282+
})
283+
})
284+
285+
describe('isRunnable', () => {
286+
const cozy = {
287+
ClientConnectorLauncher: 'test-react-native'
288+
}
289+
const konnector = { clientSide: true }
290+
it('should return true if konnector is clientSide and a launcher is available', () => {
291+
expect(isRunnable({ win: { cozy }, konnector })).toBe(true)
292+
})
293+
it('should should return true if not ClientSide', () => {
294+
expect(isRunnable({ win: {}, konnector: {} })).toBe(true)
295+
})
296+
it('should should return false in other case', () => {
297+
expect(isRunnable({ win: {}, konnector })).toBe(false)
298+
})
299+
})
270300
})
271301

272302
describe('locales', () => {

‎packages/cozy-harvest-lib/src/locales/en.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
},
1818
"disconnect": {
1919
"button": "Disconnect this account"
20-
}
20+
},
21+
"installFlagship": {
22+
"label": "Install Cozy on mobile"
23+
},
24+
"notClientSide": "The %{name} application uses a brand-new and efficient system for retrieving your data from your Cozy. This action is only accessible from the Cozy mobile app."
2125
},
2226
"contracts": {
2327
"headers": {

‎packages/cozy-harvest-lib/src/locales/fr.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
},
1818
"disconnect": {
1919
"button": "Déconnecter le compte"
20-
}
20+
},
21+
"installFlagship": {
22+
"label": "Install Cozy on mobile"
23+
},
24+
"notClientSide": "L'application %{name} utilise un nouveau système plus efficace pour la récupération de vos données dans votre Cozy. Cette action est uniquement accessible depuis l’application mobile Cozy."
2125
},
2226
"contracts": {
2327
"headers": {

‎packages/cozy-harvest-lib/src/models/ConnectionFlow.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ import {
99
ACCOUNTS_DOCTYPE
1010
} from '../connections/accounts'
1111
import clone from 'lodash/clone'
12-
import get from 'lodash/get'
1312
import {
1413
launchTrigger,
1514
prepareTriggerAccount,
1615
fetchTrigger,
1716
ensureTrigger
1817
} from '../connections/triggers'
19-
import { KonnectorJobError } from '../helpers/konnectors'
18+
import { KonnectorJobError, getLauncher } from '../helpers/konnectors'
2019
import { watchKonnectorJob } from '../models/konnector/KonnectorJobWatcher'
2120
import logger from '../logger'
2221
import { findKonnectorPolicy } from '../konnector-policies'
@@ -507,8 +506,10 @@ export class ConnectionFlow {
507506
'This connector can be run by the launcher',
508507
this.konnector.slug
509508
)
510-
const launcher = get(window, 'cozy.ClientConnectorLauncher')
511-
logger.info('Found a launcher', launcher)
509+
const launcher = getLauncher({ win: window })
510+
if (launcher) {
511+
logger.info('Found a launcher', launcher)
512+
}
512513
if (launcher === 'react-native') {
513514
window.ReactNativeWebView.postMessage(
514515
JSON.stringify({

0 commit comments

Comments
 (0)
Please sign in to comment.