Commit 677d7f9f authored by Guilhem CARRON's avatar Guilhem CARRON
Browse files

Merge branch 'feat/us675-matomo' into 'dev'

Feat/us675 matomo

See merge request web-et-numerique/llle_project/ecolyo!515
parents b1696d7a 8781e065
......@@ -17,6 +17,8 @@ module.exports = {
__DEVELOPMENT__: false,
__DEVTOOLS__: false,
__STACK_ASSETS__: target !== 'mobile',
__PIWIK_TRACKER_URL__: JSON.stringify('https://statweb.grandlyon.com/'),
__PIWIK_SITEID__: 117,
}),
],
optimization: {
......
......@@ -20,6 +20,8 @@ const stackProvidedLibsConfig = {
'process.env.NODE_ENV': JSON.stringify('development'),
__IS_ALPHA__: true,
__STACK_ASSETS__: true,
__PIWIK_TRACKER_URL__: JSON.stringify('http://localhost:9800/'),
__PIWIK_SITEID__: 1,
}),
],
module: {
......
......@@ -17,6 +17,8 @@ module.exports = {
__DEVELOPMENT__: false,
__DEVTOOLS__: false,
__STACK_ASSETS__: target !== 'mobile',
__PIWIK_TRACKER_URL__: JSON.stringify('https://statweb.grandlyon.com/'),
__PIWIK_SITEID__: 118,
}),
],
optimization: {
......
version: '3.8'
services:
db:
image: mariadb
command: --max-allowed-packet=64MB
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=matomo
- MYSQL_USER=matomo
volumes:
- db:/var/lib/mysql
app:
image: matomo:latest
restart: always
depends_on:
- db
environment:
- MATOMO_DATABASE_HOST=db
- MATOMO_DATABASE_ADAPTER=mysql
- MATOMO_DATABASE_TABLES_PREFIX=matomo_
- MATOMO_DATABASE_USERNAME=matomo
- MATOMO_DATABASE_PASSWORD=password
- MATOMO_DATABASE_DBNAME=matomo
- PHP_MEMORY_LIMIT=2048M
volumes:
# - ./config:/var/www/html/config:rw
# - ./logs:/var/www/html/logs
- matomo:/var/www/html
ports:
- 9800:80
volumes:
db:
matomo:
......@@ -21,6 +21,9 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
}),
}
})
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
const mockStore = configureStore([])
describe('ActionView component', () => {
......@@ -34,7 +37,7 @@ describe('ActionView component', () => {
}
const store = mockStore({
ecolyo: {
challenge: userChallenge,
challenge: { currentChallenge: userChallenge },
global: { ...globalStateData, fluidTypes: [0, 1, 2] },
profile: profileData,
modal: modalStateData,
......@@ -45,7 +48,7 @@ describe('ActionView component', () => {
<ActionView />
</Provider>
)
expect(wrapper.find(ActionChoose).exists())
expect(wrapper.find(ActionChoose).exists()).toBeTruthy()
expect(wrapper).toMatchSnapshot()
})
it('should render ActionDone component', () => {
......@@ -58,7 +61,7 @@ describe('ActionView component', () => {
}
const store = mockStore({
ecolyo: {
challenge: userChallenge,
challenge: { currentChallenge: userChallenge },
global: { ...globalStateData, fluidTypes: [0, 1, 2] },
profile: profileData,
modal: modalStateData,
......@@ -69,7 +72,7 @@ describe('ActionView component', () => {
<ActionView />
</Provider>
)
expect(wrapper.find(ActionDone).exists())
expect(wrapper.find(ActionDone).exists()).toBeTruthy()
})
it('should render ActionOnGoing component', () => {
const userChallenge = {
......@@ -81,7 +84,7 @@ describe('ActionView component', () => {
}
const store = mockStore({
ecolyo: {
challenge: userChallenge,
challenge: { currentChallenge: userChallenge },
global: { ...globalStateData, fluidTypes: [0, 1, 2] },
modal: modalStateData,
profile: profileData,
......@@ -92,6 +95,6 @@ describe('ActionView component', () => {
<ActionView />
</Provider>
)
expect(wrapper.find(ActionOnGoing).exists())
expect(wrapper.find(ActionOnGoing).exists()).toBeTruthy()
})
})
/* eslint-disable react/display-name */
import React from 'react'
import { mount } from 'enzyme'
import * as reactRedux from 'react-redux'
......
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react'
import React, { useEffect } from 'react'
import { HashRouter } from 'react-router-dom'
import { createBrowserHistory } from 'history'
import { Layout, Main, Content } from 'cozy-ui/transpiled/react/Layout'
import { useSelector } from 'react-redux'
import { AppStore } from 'store'
......@@ -12,14 +11,30 @@ import SplashRoot from 'components/Splash/SplashRoot'
import SplashScreen from 'components/Splash/SplashScreen'
import SplashScreenError from 'components/Splash/SplashScreenError'
import WelcomeModal from 'components/Onboarding/WelcomeModal'
import MatomoTracker from 'utils/matomoTracker'
import EnvironmentService from 'services/environment.service'
export const history = createBrowserHistory()
interface AppProps {
tracker: MatomoTracker
}
export const App = () => {
export const App = ({ tracker }: AppProps) => {
const { onboarding, isProfileEcogestureCompleted } = useSelector(
(state: AppStore) => state.ecolyo.profile
)
const { termsStatus } = useSelector((state: AppStore) => state.ecolyo.global)
const isDev = new EnvironmentService().isDev()
useEffect(() => {
if (tracker && !isDev) {
if (termsStatus.accepted) {
tracker.connectToHistory()
}
return () => {
tracker.disconnectFromHistory()
}
}
}, [termsStatus.accepted, tracker])
return (
<HashRouter {...history}>
......
import React from 'react'
import { shallow } from 'enzyme'
import { mount } from 'enzyme'
import toJson from 'enzyme-to-json'
import ChallengeView from 'components/Challenge/ChallengeView'
import * as reactRedux from 'react-redux'
import { challengeStateDataFull } from '../../../tests/__mocks__/challengeStateData.mock'
import {
createMockStore,
mockInitialEcolyoState,
} from '../../../tests/__mocks__/store'
const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
......@@ -16,10 +21,28 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
}
})
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
jest.mock('components/Challenge/ChallengeCard', () => 'mock-challengecard')
const useSelectorSpy = jest.spyOn(reactRedux, 'useSelector')
describe('ChallengeView component', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let store: any
beforeEach(() => {
store = createMockStore(mockInitialEcolyoState)
useSelectorSpy.mockClear()
})
it('should be rendered correctly', () => {
mockUseSelector.mockReturnValue(challengeStateDataFull)
const component = shallow(<ChallengeView />).getElement()
expect(component).toMatchSnapshot()
const wrapper = mount(
<reactRedux.Provider store={store}>
<ChallengeView />
</reactRedux.Provider>
)
expect(toJson(wrapper)).toMatchSnapshot()
})
})
import React, { useCallback, useEffect } from 'react'
import './content.scss'
import { history } from 'components/App'
import { useSelector, useDispatch } from 'react-redux'
import { AppStore } from 'store'
import { changeScreenType } from 'store/global/global.actions'
import { updateModalIsFeedbacksOpen } from 'store/modal/modal.actions'
import { ScreenType } from 'enum/screen.enum'
import FeedbackModal from 'components/Feedback/FeedbackModal'
import { useHistory } from 'react-router-dom'
interface ContentProps {
children?: React.ReactNode
height?: number
......@@ -20,6 +19,7 @@ const Content: React.FC<ContentProps> = ({
background = 'inherit',
}: ContentProps) => {
const dispatch = useDispatch()
const history = useHistory()
const { screenType } = useSelector((state: AppStore) => state.ecolyo.global)
const { isFeedbacksOpen } = useSelector(
(state: AppStore) => state.ecolyo.modal
......@@ -38,10 +38,10 @@ const Content: React.FC<ContentProps> = ({
/**
* Handle Desktop scroll
*/
const handleWindowScroll = () => {
const handleWindowScroll = useCallback(() => {
app && app.scrollTo(0, 0)
window.scrollTo(0, 0)
}
}, [app])
// Set listners for scroll
useEffect(() => {
......@@ -50,7 +50,7 @@ const Content: React.FC<ContentProps> = ({
// remove listner subscription
listner()
}
}, [])
}, [handleWindowScroll, history])
useEffect(() => {
function handleResize() {
......
......@@ -10,6 +10,10 @@ import DuelUnlocked from './DuelUnlocked'
import DuelOngoing from './DuelOngoing'
import { UserDuelState } from 'enum/userDuel.enum'
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
describe('DuelView component', () => {
......
/* eslint-disable react/display-name */
import React from 'react'
import { mount } from 'enzyme'
import { Provider } from 'react-redux'
......
......@@ -8,19 +8,39 @@ import { challengeStateData } from '../../../tests/__mocks__/challengeStateData.
import ExplorationFinished from './ExplorationFinished'
import ExplorationError from './ExplorationError'
import ExplorationOngoing from './ExplorationOngoing'
import { UserExplorationState } from 'enum/userExploration.enum'
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
describe('ExplorationView', () => {
it('should be rendered with ExplorationView component when no exploration state', () => {
mockUseSelector.mockReturnValue(challengeStateData)
it('should be rendered with ExplorationError component when unknown exploration state', () => {
const updatedUserChallenge = {
...userChallengeData[0],
exploration: {
...userChallengeData[0].exploration,
state: 99,
},
}
const updatedChallengeState = {
...challengeStateData,
currentChallenge: updatedUserChallenge,
}
mockUseSelector.mockReturnValue(updatedChallengeState)
const wrapper = shallow(<ExplorationView />)
expect(wrapper.find(ExplorationError).exists())
expect(wrapper.find(ExplorationError).exists()).toBeTruthy()
})
it('should be rendered with ExplorationView component when exploration state = unlocked', () => {
it('should be rendered with ExplorationOngoing component when exploration state = unlocked', () => {
const updatedUserChallenge = {
...userChallengeData[0],
quiz: { ...userChallengeData[0].quiz, state: UserQuizState.UNLOCKED },
exploration: {
...userChallengeData[0].exploration,
state: UserExplorationState.UNLOCKED,
},
}
const updatedChallengeState = {
...challengeStateData,
......@@ -28,12 +48,16 @@ describe('ExplorationView', () => {
}
mockUseSelector.mockReturnValue(updatedChallengeState)
const wrapper = shallow(<ExplorationView />)
expect(wrapper.find(ExplorationOngoing).exists())
expect(wrapper.find(ExplorationOngoing).exists()).toBeTruthy()
})
it('should be rendered with ExplorationView component when exploration state = ongoing', () => {
it('should be rendered with ExplorationOngoing component when exploration state = ongoing', () => {
const updatedUserChallenge = {
...userChallengeData[0],
quiz: { ...userChallengeData[0].quiz, state: UserQuizState.ONGOING },
exploration: {
...userChallengeData[0].exploration,
state: UserExplorationState.ONGOING,
},
}
const updatedChallengeState = {
...challengeStateData,
......@@ -41,12 +65,16 @@ describe('ExplorationView', () => {
}
mockUseSelector.mockReturnValue(updatedChallengeState)
const wrapper = shallow(<ExplorationView />)
expect(wrapper.find(ExplorationOngoing).exists())
expect(wrapper.find(ExplorationOngoing).exists()).toBeTruthy()
})
it('should be rendered with ExplorationView component when exploration state = Done', () => {
it('should be rendered with ExplorationFinished component when exploration state = Done', () => {
const updatedUserChallenge = {
...userChallengeData[0],
quiz: { ...userChallengeData[0].quiz, state: UserQuizState.DONE },
exploration: {
...userChallengeData[0].exploration,
state: UserExplorationState.DONE,
},
}
const updatedChallengeState = {
...challengeStateData,
......@@ -54,6 +82,6 @@ describe('ExplorationView', () => {
}
mockUseSelector.mockReturnValue(updatedChallengeState)
const wrapper = shallow(<ExplorationView />)
expect(wrapper.find(ExplorationFinished).exists())
expect(wrapper.find(ExplorationFinished).exists()).toBeTruthy()
})
})
......@@ -11,6 +11,9 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
}),
}
})
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
describe('FAQView component', () => {
it('should render only the parent component', () => {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FAQView component should render only the parent component 1`] = `
<React.Fragment>
<CozyBar
displayBackArrow={true}
titleKey="common.title_faq"
/>
<Header
desktopTitleKey="common.title_faq"
displayBackArrow={true}
setHeaderHeight={[Function]}
/>
<Content
height={0}
>
<FAQContent />
</Content>
</React.Fragment>
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FAQView component should render only the parent component 1`] = `
<React.Fragment>
<mock-cozybar
displayBackArrow={true}
titleKey="common.title_faq"
/>
<mock-header
desktopTitleKey="common.title_faq"
displayBackArrow={true}
setHeaderHeight={[Function]}
/>
<mock-content
height={0}
>
<FAQContent />
</mock-content>
</React.Fragment>
`;
......@@ -2,6 +2,10 @@ import React from 'react'
import { shallow } from 'enzyme'
import GCUView from 'components/GCU/GCUView'
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
describe('GCUView component', () => {
it('should be rendered correctly', () => {
const component = shallow(<GCUView />).getElement()
......
......@@ -2,19 +2,19 @@
exports[`GCUView component should be rendered correctly 1`] = `
<React.Fragment>
<CozyBar
<mock-cozybar
displayBackArrow={true}
titleKey="common.title_gcu"
/>
<Header
<mock-header
desktopTitleKey="common.title_gcu"
displayBackArrow={true}
setHeaderHeight={[Function]}
/>
<Content
<mock-content
height={0}
>
<GCUContent />
</Content>
</mock-content>
</React.Fragment>
`;
/* eslint-disable react/display-name */
import React from 'react'
import { mount } from 'enzyme'
import { Provider } from 'react-redux'
......@@ -12,6 +11,8 @@ import * as chartActions from 'store/chart/chart.actions'
import { FluidState, FluidType } from 'enum/fluid.enum'
import { TimeStep } from 'enum/timeStep.enum'
import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner'
import FluidButtons from 'components/Home/FluidButtons'
import KonnectorViewerList from 'components/Konnector/KonnectorViewerList'
import ConsumptionView from './ConsumptionView'
import { FluidStatus } from 'models'
import { mockTestProfile1 } from '../../../tests/__mocks__/profileType.mock'
......@@ -77,6 +78,7 @@ describe('ConsumptionView component', () => {
loading: false,
fluidStatus: mockFluidStatus,
releaseNotes: mockInitialEcolyoState.global.releaseNotes,
openPartnersIssueModal: false,
})
const wrapper = mount(
<Provider store={store}>
......@@ -100,6 +102,7 @@ describe('ConsumptionView component', () => {
loading: true,
fluidStatus: mockFluidStatus,
releaseNotes: mockInitialEcolyoState.global.releaseNotes,
openPartnersIssueModal: false,
})
const wrapper = mount(
<Provider store={store}>
......@@ -118,6 +121,7 @@ describe('ConsumptionView component', () => {
loading: true,
fluidStatus: mockInitialEcolyoState.global.fluidStatus,
releaseNotes: mockInitialEcolyoState.global.releaseNotes,
openPartnersIssueModal: false,
})
mount(
<Provider store={store}>
......@@ -127,12 +131,14 @@ describe('ConsumptionView component', () => {
expect(setCurrentTimeStepSpy).toBeCalledTimes(1)
expect(setCurrentTimeStepSpy).toHaveBeenCalledWith(TimeStep.WEEK)
})
it('should render konnector list when no fluid is connected', () => {
useSelectorSpy.mockReturnValue({
currentTimeStep: TimeStep.WEEK,
loading: true,
fluidStatus: mockInitialEcolyoState.global.fluidStatus,
releaseNotes: mockInitialEcolyoState.global.releaseNotes,
openPartnersIssueModal: false,
})
const wrapper = mount(
<Provider store={store}>
......@@ -141,6 +147,7 @@ describe('ConsumptionView component', () => {
)
expect(wrapper.find('mock-consumptiondetails').exists()).toBeTruthy()
})
it('should render mutlifluid consumption if at least one fluid is connected', () => {
const updatedStatus: FluidStatus[] =
mockInitialEcolyoState.global.fluidStatus
......@@ -151,6 +158,7 @@ describe('ConsumptionView component', () => {
loading: true,
fluidStatus: updatedStatus,
releaseNotes: mockInitialEcolyoState.global.releaseNotes,
openPartnersIssueModal: false,
})
const wrapper = mount(
<Provider store={store}>
......@@ -159,6 +167,7 @@ describe('ConsumptionView component', () => {
)
expect(wrapper.find('.consumptionview-content').exists()).toBeTruthy()
})
it('should render Electricity when elec is connected', () => {
const updatedStatus: FluidStatus[] =
mockInitialEcolyoState.global.fluidStatus
......@@ -168,6 +177,7 @@ describe('ConsumptionView component', () => {
loading: true,
fluidStatus: updatedStatus,
releaseNotes: mockInitialEcolyoState.global.releaseNotes,
openPartnersIssueModal: false,
})
const wrapper = mount(
<Provider store={store}>
......
......@@ -2,6 +2,10 @@ import React from 'react'
import { shallow } from 'enzyme'
import LegalNoticeView from 'components/LegalNotice/LegalNoticeView'
jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
jest.mock('components/Header/Header', () => 'mock-header')
jest.mock('components/Content/Content', () => 'mock-content')
describe('LegalNoticeView component', () => {
it('should be rendered correctly', () => {
const component = shallow(<LegalNoticeView />).getElement()
......
......@@ -2,19 +2,19 @@
exports[`LegalNoticeView component should be rendered correctly 1`] = `
<React.Fragment>
<CozyBar
<mock-cozybar
displayBackArrow={true}
titleKey="common.title_legal_notice"
/>
<Header
<mock-header
desktopTitleKey="common.title_legal_notice"
displayBackArrow={true}
setHeaderHeight={[Function]}
/>
<Content
<mock-content
height={0}
>
<LegalNoticeContent />
</Content>
</mock-content>
</React.Fragment>
`;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment