Skip to content
Snippets Groups Projects
Commit 2ab65def authored by Bastien DUMONT's avatar Bastien DUMONT :angel: Committed by Hugo SUBTIL
Browse files

feat(core): add user contract verification/activation and onDelete job for...

feat(core): add user contract verification/activation and onDelete job for removing consent. Addition of backoffice handling
parent e18c9587
No related branches found
No related tags found
1 merge request!12Feat/donnes tech debut contrat
Showing
with 1421 additions and 79 deletions
......@@ -4,6 +4,7 @@
konnector-dev-config.json*
fixtures/*
data/*
.importedData.json
# NPM
node_modules/
......
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#65c89b",
"activityBar.activeBorder": "#945bc4",
"activityBar.background": "#65c89b",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#945bc4",
"activityBarBadge.foreground": "#e7e7e7",
"sash.hoverBorder": "#65c89b",
"statusBar.background": "#42b883",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#359268",
"statusBarItem.remoteBackground": "#42b883",
"statusBarItem.remoteForeground": "#15202b",
"titleBar.activeBackground": "#42b883",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#42b88399",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.color": "#42b883"
"peacock.color": "#42b883"
}
const xml2js = require('xml2js')
const { errors } = require('cozy-konnector-libs')
const { activateContract } = require('../../src/core/contractActivation')
const mockSoapRequest = jest.fn()
jest.mock('easy-soap-request', () => async () => mockSoapRequest())
const mockParseServiceId = jest.fn()
jest.mock('../../src/helpers/parsing', () => ({
parseServiceId: () => mockParseServiceId(),
}))
const responseMock = {
response: {
body: 'mockedBody',
},
}
describe('activateContract', () => {
it('should return last contract if there is multiple contract ✅', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
mockParseServiceId.mockReturnValue(78232791)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({})
try {
const serviceId = await activateContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'POUET',
'1111111111111',
'01/01/2022',
'01/01/2023'
)
expect(serviceId).toBe(78232791)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
mockParseServiceId.mockRestore()
})
it('should throw LOGIN_FAILED when request fail 🚫', async () => {
mockSoapRequest.mockRejectedValueOnce('reject')
try {
await activateContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'POUET',
'1111111111111',
'01/01/2022',
'01/01/2023'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
mockParseServiceId.mockRestore()
})
it('should throw LOGIN_FAILED when failing parsing 🚫', async () => {
mockSoapRequest.mockResolvedValueOnce(responseMock)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
mockParseServiceId.mockImplementationOnce(() => {
throw new Error('error')
})
try {
await activateContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'POUET',
'1111111111111',
'01/01/2022',
'01/01/2023'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
mockParseServiceId.mockRestore()
})
})
const { errors } = require('cozy-konnector-libs')
const { getContractStartDate } = require('../../src/core/contractStartDate')
const xml2js = require('xml2js')
const mockSoapRequest = jest.fn()
jest.mock('easy-soap-request', () => async () => mockSoapRequest())
const responseMock = {
response: {
body: `<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns7:consulterDonneesTechniquesContractuellesResponse xmlns:ns0="http://www.erdf.fr/tube/exposition/finalisation" xmlns:ns7="http://www.enedis.fr/sge/b2b/services/consulterdonneestechniquescontractuelles/v1.0">
<point id="19160781274487">
<donneesGenerales>
<dateDerniereModificationFormuleTarifaireAcheminement>2021-08-01+02:00</dateDerniereModificationFormuleTarifaireAcheminement>
<niveauOuvertureServices>2</niveauOuvertureServices>
</donneesGenerales>
</point>
</ns7:consulterDonneesTechniquesContractuellesResponse>
</soap:Body>
</soapenv:Envelope>`,
},
}
const responseIssueMock = {
response: {
body: `<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns7:consulterDonneesTechniquesContractuellesResponse xmlns:ns0="http://www.erdf.fr/tube/exposition/finalisation" xmlns:ns7="http://www.enedis.fr/sge/b2b/services/consulterdonneestechniquescontractuelles/v1.0">
<point id="19160781274487">
</point>
</ns7:consulterDonneesTechniquesContractuellesResponse>
</soap:Body>
</soapenv:Envelope>`,
},
}
describe('getContractStartDate', () => {
it('should return void when successfully got contract start date ✅', async () => {
mockSoapRequest.mockResolvedValueOnce(responseMock)
expect.assertions(1)
try {
await getContractStartDate(
'http://pouet.com',
'apiAuthKey',
'pouet@pouet.com',
'1111111111'
)
expect(true).toBeTruthy()
} catch (error) {
expect(true).toBe(false)
}
})
it('should throw VENDOR_DOWN when failing request 🚫', async () => {
mockSoapRequest.mockRejectedValueOnce('error')
try {
await getContractStartDate()
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.VENDOR_DOWN)
}
})
it('should throw NOT_EXISTING_DIRECTORY when failing parsing 🚫', async () => {
mockSoapRequest.mockResolvedValueOnce(responseIssueMock)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
try {
await getContractStartDate(
'http://pouet.com',
'apiAuthKey',
'pouet@pouet.com',
'1111111111'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.NOT_EXISTING_DIRECTORY)
}
})
})
const xml2js = require('xml2js')
const { errors } = require('cozy-konnector-libs')
const { terminateContract } = require('../../src/core/contractTermination')
const mockSoapRequest = jest.fn()
jest.mock('easy-soap-request', () => async () => mockSoapRequest())
const responseMock = {
response: {
body: 'mockedBody',
},
}
describe('terminateContract', () => {
it('should terminate contract ✅', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
try {
const serviceId = await terminateContract(
'http://test.com',
'111',
'login@log.com',
'1111111111111',
'1234567'
)
expect(serviceId).toEqual({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
} catch (error) {
expect(error).toBe(errors.VENDOR_DOWN)
}
})
it('should throw VENDOR_DOWN on bad request🚫', async () => {
mockSoapRequest.mockRejectedValueOnce('reject')
try {
await terminateContract(
'http://test.com',
'111',
'login@log.com',
'1111111111111',
'1234567'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.VENDOR_DOWN)
}
})
it('should throw VENDOR_DOWN 🚫', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
Envelope: {
Body: {
Fault: {},
},
},
})
try {
await terminateContract(
'http://test.com',
'111',
'login@log.com',
'1111111111111',
'1234567'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.VENDOR_DOWN)
}
})
})
const xml2js = require('xml2js')
const { errors } = require('cozy-konnector-libs')
const { verifyContract } = require('../../src/core/contractVerification')
const mockSoapRequest = jest.fn()
jest.mock('easy-soap-request', () => async () => mockSoapRequest())
const mockParseContracts = jest.fn()
jest.mock('../../src/helpers/parsing', () => ({
parseContracts: () => mockParseContracts(),
}))
const responseMock = {
response: {
body: 'mockedBody',
},
}
describe('verifyContract', () => {
it('should return last contract if there is multiple contract ✅', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
mockParseContracts.mockReturnValue([
{
serviceSouscritId: 78232791,
etatCode: 'ACTIF',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
])
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue(
{
Envelope: {
Body: {
rechercherServicesSouscritsMesuresResponse: {
servicesSouscritsMesures: {
serviceSouscritMesures: [
{
serviceSouscritId: 78232791,
etatCode: 'ACTIF',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
],
},
},
},
},
}.toString()
)
try {
const serviceId = await verifyContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'1111111111111'
)
expect(serviceId).toBe(78232791)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
mockParseContracts.mockRestore()
})
it('should return last contract if there is one contract ✅', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
mockParseContracts.mockReturnValue({
serviceSouscritId: 78232791,
etatCode: 'ACTIF',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
})
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue(
{
Envelope: {
Body: {
rechercherServicesSouscritsMesuresResponse: {
servicesSouscritsMesures: {
serviceSouscritMesures: [
{
serviceSouscritId: 78232791,
etatCode: 'ACTIF',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
],
},
},
},
},
}.toString()
)
try {
const serviceId = await verifyContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'1111111111111'
)
expect(serviceId).toBe(78232791)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
mockParseContracts.mockRestore()
})
it('should return null if last contract is TERMINE 🚫', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
mockParseContracts.mockReturnValue([
{
serviceSouscritId: 78232791,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
])
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue(
{
Envelope: {
Body: {
rechercherServicesSouscritsMesuresResponse: {
servicesSouscritsMesures: {
serviceSouscritMesures: [
{
serviceSouscritId: 78232791,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
],
},
},
},
},
}.toString()
)
try {
const serviceId = await verifyContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'1111111111111'
)
expect(serviceId).toBe(null)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
mockParseContracts.mockRestore()
})
it('should return LOGIN_FAILED if issue in request 🚫', async () => {
mockSoapRequest.mockRejectedValueOnce('reject')
try {
await verifyContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'1111111111111'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
})
it('should return LOGIN_FAILED if issue in parsing 🚫', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
try {
await verifyContract(
'http://test.com',
'111',
'login@log.com',
'1234567',
'1111111111111'
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.LOGIN_FAILED)
}
})
})
const xml2js = require('xml2js')
const { errors } = require('cozy-konnector-libs')
const { findUserPdl } = require('../src/findUserPdl')
const { findUserPdl } = require('../../src/core/findUserPdl')
const mockSoapRequest = jest.fn()
jest.mock('easy-soap-request', () => async () => mockSoapRequest())
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue('response')
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
const mockParseUserPdl = jest.fn()
jest.mock('../src/parsing', () => ({
jest.mock('../../src/helpers/parsing', () => ({
parseUserPdl: () => mockParseUserPdl(),
}))
......@@ -22,7 +29,7 @@ describe('recherchePoint', () => {
it('should throw LOGIN_FAILED for too many responses', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
mockParseUserPdl.mockImplementationOnce(() => {
throw new Error('fail')
throw new Error('Error')
})
try {
......@@ -46,6 +53,7 @@ describe('recherchePoint', () => {
it('should return a correct pdl number', async () => {
mockSoapRequest.mockResolvedValue(responseMock)
mockParseUserPdl.mockResolvedValue('12345')
expect(await findUserPdl()).toBe('12345')
})
})
const { errors } = require('cozy-konnector-libs')
const { verifyUserIdentity } = require('../src/verifyUserIdentity')
const { verifyUserIdentity } = require('../../src/core/verifyUserIdentity')
jest.mock('../src/requests/insee', () => ({
jest.mock('../../src/requests/insee', () => ({
getInseeCode: jest.fn().mockResolvedValue(69),
}))
jest.mock('../src/findUserPdl', () => ({
jest.mock('../../src/core/findUserPdl', () => ({
findUserPdl: jest.fn().mockResolvedValue('12345'),
}))
jest.mock('../src/index', () => ({
jest.mock('../../src/index', () => ({
start: jest.fn(),
}))
describe('verifyUserIdentity', () => {
it('should throw LOGIN_FAILED when pdl give and recieved are NOT matching 🚫', async () => {
it('should throw LOGIN_FAILED when pdl given and recieved are NOT matching 🚫', async () => {
try {
await verifyUserIdentity(
{
......@@ -32,6 +32,25 @@ describe('verifyUserIdentity', () => {
expect(error).toBe(errors.LOGIN_FAILED)
}
})
it('should throw TERMS_VERSION_MISMATCH when pdl give and recieved are NOT matching on alternate start 🚫', async () => {
try {
await verifyUserIdentity(
{
name: 'John',
address: '1 street',
pointId: 987654321,
postalCode: '69069',
},
'azertyuiop',
'apiKey',
'login@user.com',
true
)
expect(true).toBe(false)
} catch (error) {
expect(error).toBe(errors.TERMS_VERSION_MISMATCH)
}
})
it('should return void when pdl give and recieved are matching ✅', async () => {
expect.assertions(1)
......
const { buildAgregatedData } = require('../src/aggregate')
const { buildAgregatedData } = require('../../src/helpers/aggregate')
const { cozyClient } = require('cozy-konnector-libs')
describe('buildAgregatedData', () => {
......
const {
parseUserPdl,
parseContractStartDate,
parseContracts,
parseServiceId,
parseSgeXmlData,
formateDataForDoctype,
parseTags,
parseValue,
} = require('../../src/helpers/parsing')
describe('parsing', () => {
it('should parse userPdl', () => {
const result = {
Envelope: {
Body: {
rechercherPointResponse: { points: { point: { $: { id: 1 } } } },
},
},
}
const reply = parseUserPdl(result)
expect(reply).toEqual(1)
})
it('should parse contract start date', () => {
const result = {
Envelope: {
Body: {
consulterDonneesTechniquesContractuellesResponse: {
point: {
donneesGenerales: {
dateDerniereModificationFormuleTarifaireAcheminement:
'01/01/2022',
},
},
},
},
},
}
const reply = parseContractStartDate(result)
expect(reply).toEqual('01/01/2022')
})
it('should parse contract', () => {
const result = {
Envelope: {
Body: {
rechercherServicesSouscritsMesuresResponse: {
servicesSouscritsMesures: {
serviceSouscritMesures: [
{
serviceSouscritId: 78232791,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
],
},
},
},
},
}
const reply = parseContracts(result)
expect(reply).toEqual([
{
serviceSouscritId: 78232791,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
{
serviceSouscritId: 78232793,
etatCode: 'TERMINE',
serviceSouscritLibelle:
'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
},
])
})
it('should parse service id', () => {
const result = {
Envelope: {
Body: {
commanderCollectePublicationMesuresResponse: {
serviceSouscritId: 12,
},
},
},
}
const reply = parseServiceId(result)
expect(reply).toEqual(12)
})
it('should parse consumption data', () => {
const result = {
Envelope: {
Body: {
consulterMesuresDetailleesResponse: {
grandeur: {
mesure: {
v: 14361,
d: '2021-08-01T00:00:00.000+02:00',
},
},
},
},
},
}
const reply = parseSgeXmlData(result)
expect(reply).toEqual({
v: 14361,
d: '2021-08-01T00:00:00.000+02:00',
})
})
it('should format data for doctype', async () => {
const data = [
{
v: 14361,
d: '2021-08-01T00:00:00.000+02:00',
},
{
v: 11,
d: '2021-08-02T00:00:00.000+02:00',
},
]
const reply = await formateDataForDoctype(data)
expect(reply).toEqual([
{ day: 1, hour: 0, load: 14361, minute: 0, month: 8, year: 2021 },
{ day: 2, hour: 0, load: 11, minute: 0, month: 8, year: 2021 },
])
})
it('should parseTag with :', () => {
const reply = parseTags('test:tag')
expect(reply).toBe('tag')
})
it('should parseTag', () => {
const reply = parseTags('testtag')
expect(reply).toBe('testtag')
})
it('should parse value from Wh to KWh', () => {
const reply = parseValue(14361, 'v')
expect(reply).toBe(14.36)
})
it('should not parse value', () => {
const reply = parseValue(14361, 'w')
expect(reply).toBe(14361)
})
})
const { createBoConsent, getBoConsent } = require('../../src/requests/bo')
const { default: axios } = require('axios')
const {
createBoConsent,
getBoConsent,
updateBoConsent,
deleteBoConsent,
} = require('../../src/requests/bo')
const axios = require('axios')
const { errors } = require('cozy-konnector-libs')
jest.mock('axios')
describe('Backoffice routes', () => {
describe('createBoConsent', () => {
it('should send consent to BO', async () => {
axios.post.mockResolvedValueOnce({ id: 1 })
const consent = await createBoConsent({
pdl: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
axios.post.mockImplementationOnce(() => {
return {
data: {
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
},
}
})
const consent = await createBoConsent(
'http://test.com',
'token',
11111111111111,
'POUET',
'mr',
'20 rue du lac',
'69003',
'69383'
)
expect(consent).toEqual({
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
})
expect(consent).toBe({ id: 1 })
})
it('should handle unavailable BO', async () => {
axios.post.mockImplementationOnce(() =>
Promise.reject(errors.MAINTENANCE)
)
axios.post.mockImplementationOnce(() => Promise.reject('fail'))
try {
await createBoConsent({
pdl: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
postalCode: '69003',
inseeCode: '69383',
})
await createBoConsent(
'http://test.com',
'token',
11111111111111,
'POUET',
'mr',
'20 rue du lac',
'69003',
'69383'
)
expect(true).toBe(false)
} catch (e) {
expect(e).toBe(errors.MAINTENANCE)
}
})
})
describe('getBoConsent', () => {
it('should get consent from BO', async () => {
axios.get.mockResolvedValueOnce({
id: 1,
pointId: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
postalCode: '69003',
inseeCode: '69383',
describe('updateBoConsent', () => {
it('should update consent to BO', async () => {
axios.put.mockImplementationOnce(() => {
return {
data: {
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
serviceId: '123456',
},
}
})
const consent = await getBoConsent(1)
expect(consent).toBe({
const consent = await updateBoConsent(
'http://test.com',
'token',
{
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
},
'123456'
)
expect(consent).toEqual({
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
serviceId: '123456',
})
})
it('should get consent from BO with service id', async () => {
axios.get.mockResolvedValueOnce({
id: 1,
it('should handle unavailable BO', async () => {
axios.put.mockImplementationOnce(() => Promise.reject('fail'))
try {
await updateBoConsent(
'http://test.com',
'token',
{
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
},
'123456'
)
expect(true).toBe(false)
} catch (e) {
expect(e).toBe(errors.MAINTENANCE)
}
})
})
describe('deleteBoConsent', () => {
it('should delete consent to BO', async () => {
axios.delete.mockImplementationOnce(() => {
return {
data: {
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
serviceId: '123456',
},
}
})
const consent = await deleteBoConsent('http://test.com', 'token', 1)
expect(consent).toEqual({
ID: 1,
firstname: 'mr',
lastname: 'POUET',
pointId: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
postalCode: '69003',
address: '20 rue du lac',
inseeCode: '69383',
serviceId: 'abcde',
serviceId: '123456',
})
})
it('should handle unavailable BO', async () => {
axios.put.mockImplementationOnce(() => Promise.reject('fail'))
try {
await deleteBoConsent('http://test.com', 'token', 1)
expect(true).toBe(false)
} catch (e) {
expect(e).toBe(errors.MAINTENANCE)
}
})
})
describe('getBoConsent', () => {
it('should get consent from BO', async () => {
axios.get.mockImplementationOnce(() => {
return {
data: {
ID: 1,
pointId: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
postalCode: '69003',
inseeCode: '69383',
},
}
})
const consent = await getBoConsent(1)
expect(consent.serviceId).toBeTruthy()
expect(consent).toBe({
const consent = await getBoConsent('http://test.com', 'token', 1)
expect(consent).toEqual({
ID: 1,
pointId: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
postalCode: '69003',
inseeCode: '69383',
serviceId: 'abcde',
})
})
it('should handle unavailable BO', async () => {
axios.get.mockImplementationOnce(() => Promise.reject(errors.MAINTENANCE))
try {
await createBoConsent({
await getBoConsent({
pointId: 11111111111111,
name: 'POUET',
adresse: '20 rue du lac',
......
const { cozyClient } = require('cozy-konnector-libs')
const { getAccount, saveAccountData } = require('../../src/requests/cozy')
const mockUpdateOrCreate = jest.fn()
describe('getAccount', () => {
it('should find account with provided ID', async () => {
const spy = jest.spyOn(cozyClient.data, 'findAll')
spy.mockResolvedValueOnce([
{
_id: '123456',
account_type: '123456',
auth: {
address: '12 rue du pouet',
city: 'Lyon',
firstname: 'Jean',
lastname: 'POUET',
pointId: '1234567891234567',
postalCode: '69007',
},
},
{ _id: '1111111', account_type: '1111111' },
])
const account = await getAccount('123456')
expect(account).toEqual({
_id: '123456',
account_type: '123456',
auth: {
address: '12 rue du pouet',
city: 'Lyon',
firstname: 'Jean',
lastname: 'POUET',
pointId: '1234567891234567',
postalCode: '69007',
},
})
})
})
describe('saveAccountData', () => {
jest.mock('cozy-konnector-libs', () => ({
updateOrCreate: () => mockUpdateOrCreate(),
}))
it('should save data to account', async () => {
const spy = jest.spyOn(cozyClient.data, 'findAll')
spy.mockResolvedValueOnce([
{
_id: '123456',
account_type: '123456',
auth: {
address: '12 rue du pouet',
city: 'Lyon',
firstname: 'Jean',
lastname: 'POUET',
pointId: '1234567891234567',
postalCode: '69007',
},
},
{ _id: '1111111', account_type: '1111111' },
])
mockUpdateOrCreate.mockResolvedValueOnce({
_id: '1111111',
account_type: '1111111',
data: { name: 'pouet' },
})
const account = await saveAccountData('1111111', { name: 'pouet' })
expect(account[0].data).toEqual({ name: 'pouet' })
})
})
const xml2js = require('xml2js')
const { parseTags, parseValue } = require('../../src/helpers/parsing')
const {
consultationMesuresDetaillees,
consultationMesuresDetailleesMaxPower,
consulterDonneesTechniquesContractuelles,
rechercherPoint,
rechercherServicesSouscritsMesures,
commanderCollectePublicationMesures,
commanderArretServiceSouscritMesures,
} = require('../../src/requests/sge')
describe('Sge routes', () => {
//TODO: write TU
it('should be true', () => {
expect(true).toBe(true)
describe('consultationMesuresDetaillees', () => {
it('should format request with default params', async () => {
const reply = consultationMesuresDetaillees(
1111,
'test@grandlyon.com',
'2022-08-01',
'2022-08-20'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body.consulterMesuresDetaillees.demande
expect(Object.keys(data).length).toEqual(10)
expect(data.mesuresTypeCode).toEqual('ENERGIE')
expect(data.grandeurPhysique).toEqual('EA')
})
it('should format request with given mesure type and unit', async () => {
const reply = consultationMesuresDetaillees(
1111,
'test@grandlyon.com',
'2022-08-01',
'2022-08-20',
'mesurePouet',
'POUET'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body.consulterMesuresDetaillees.demande
expect(Object.keys(data).length).toEqual(10)
expect(data.mesuresTypeCode).toEqual('mesurePouet')
expect(data.grandeurPhysique).toEqual('POUET')
})
})
describe('consultationMesuresDetailleesMaxPower', () => {
it('should format request with default params', async () => {
const reply = consultationMesuresDetailleesMaxPower(
1111,
'test@grandlyon.com',
'2022-08-01',
'2022-08-20'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body.consulterMesuresDetaillees.demande
expect(Object.keys(data).length).toEqual(11)
expect(data.mesuresPas).toEqual('P1D')
expect(data.mesuresTypeCode).toEqual('PMAX')
expect(data.grandeurPhysique).toEqual('PMA')
})
it('should format request with given mesure type and unit', async () => {
const reply = consultationMesuresDetailleesMaxPower(
1111,
'test@grandlyon.com',
'2022-08-01',
'2022-08-20',
'mesurePouet',
'POUET'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body.consulterMesuresDetaillees.demande
expect(Object.keys(data).length).toEqual(11)
expect(data.mesuresTypeCode).toEqual('mesurePouet')
expect(data.grandeurPhysique).toEqual('POUET')
})
})
describe('consulterDonneesTechniquesContractuelles', () => {
it('should format request', async () => {
const reply = consulterDonneesTechniquesContractuelles(
1111,
'test@grandlyon.com'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data =
parsedReply.Envelope.Body.consulterDonneesTechniquesContractuelles
expect(Object.keys(data).length).toEqual(3)
expect(data.autorisationClient).toEqual('true')
})
})
describe('rechercherPoint', () => {
it('should format request', async () => {
const reply = rechercherPoint(
'test@grandlyon.com',
'toto',
'69007',
'69387',
'20 rue du lac'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body
expect(Object.keys(data.rechercherPoint).length).toEqual(2)
expect(Object.keys(data.rechercherPoint.criteres).length).toEqual(3)
expect(
Object.keys(data.rechercherPoint.criteres.adresseInstallation).length
).toEqual(3)
expect(data.rechercherPoint.criteres.rechercheHorsPerimetre).toEqual(
'true'
)
})
})
describe('rechercherServicesSouscritsMesures', () => {
it('should format request', async () => {
const reply = rechercherServicesSouscritsMesures(
'test@grandlyon.com',
'69007',
1111233
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body
expect(
Object.keys(data.rechercherServicesSouscritsMesures).length
).toEqual(2)
expect(
Object.keys(data.rechercherServicesSouscritsMesures.criteres).length
).toEqual(2)
})
})
describe('commanderCollectePublicationMesures', () => {
it('should format request', async () => {
const reply = commanderCollectePublicationMesures(
'test@grandlyon.com',
'12345',
'1111233',
'toto',
'2021-08-01',
'2021-08-02'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body
expect(
Object.keys(data.commanderCollectePublicationMesures.demande).length
).toEqual(2)
expect(
Object.keys(
data.commanderCollectePublicationMesures.demande.donneesGenerales
).length
).toEqual(4)
expect(
Object.keys(
data.commanderCollectePublicationMesures.demande.accesMesures
).length
).toEqual(10)
expect(
Object.keys(
data.commanderCollectePublicationMesures.demande.accesMesures
.declarationAccordClient
).length
).toEqual(2)
})
})
describe('commanderArretServiceSouscritMesures', () => {
it('should format request', async () => {
const reply = commanderArretServiceSouscritMesures(
'test@grandlyon.com',
'12345',
'1111233',
'3654'
)
const parsedReply = await xml2js.parseStringPromise(reply, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
const data = parsedReply.Envelope.Body
expect(
Object.keys(data.commanderArretServiceSouscritMesures.demande).length
).toEqual(2)
expect(
Object.keys(
data.commanderArretServiceSouscritMesures.demande.donneesGenerales
).length
).toEqual(4)
expect(
Object.keys(
data.commanderArretServiceSouscritMesures.demande.arretServiceSouscrit
).length
).toEqual(1)
})
})
})
......@@ -11,8 +11,23 @@
"categories": ["energy"],
"frequency": "daily",
"fields": {
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
},
"address": {
"type": "string"
},
"postalCode": {
"type": "string"
},
"city": {
"type": "string"
},
"pointId": {
"type": "text"
"type": "string"
}
},
"data_types": [
......@@ -20,8 +35,7 @@
"screenshots": [],
"permissions": {
"accounts": {
"type": "io.cozy.accounts",
"verbs": ["GET"]
"type": "io.cozy.accounts"
},
"files": {
"type": "io.cozy.files"
......@@ -67,5 +81,6 @@
}
}
},
"manifest_version": "2"
"manifest_version": "2",
"on_delete_account": "onDeleteAccount.js"
}
......@@ -24,10 +24,15 @@
"pre-commit": "yarn lint"
}
},
"jest": {
"setupFiles": ["./setupTests.js"]
},
"scripts": {
"start": "node ./src/index.js",
"dev": "cozy-konnector-dev",
"standalone": "cozy-konnector-standalone",
"onDeleteAccount:standalone": "cozy-konnector-standalone src/onDeleteAccount.js",
"onDeleteAccount": "cozy-konnector-dev src/onDeleteAccount.js",
"test": "jest",
"test:cov": "jest --coverage",
"pretest": "npm run clean",
......
// Disable cozy logger
const cozyKonnectorsLib = require('cozy-konnector-libs')
jest.spyOn(cozyKonnectorsLib, 'log').mockImplementation(() => {})
// @ts-check
const { log, errors } = require('cozy-konnector-libs')
const soapRequest = require('easy-soap-request')
const { parseTags, parseValue, parseServiceId } = require('../helpers/parsing')
const { commanderCollectePublicationMesures } = require('../requests/sge')
const xml2js = require('xml2js')
/**
* @param {string} url
* @param {string} apiAuthKey
* @param {string} appLogin
* @param {string} name
* @param {number} pointId
* @param {string} startDate
* @param {string} endDate
* @return {Promise<number>} User contractId
*/
async function activateContract(
url,
apiAuthKey,
appLogin,
contractId,
name,
pointId,
startDate,
endDate
) {
log('info', 'activateContract')
const sgeHeaders = {
'Content-Type': 'text/xml;charset=UTF-8',
apikey: apiAuthKey,
}
const { response } = await soapRequest({
url: `${url}/enedis_SGE_CommandeCollectePublicationMesures/1.0`,
headers: sgeHeaders,
xml: commanderCollectePublicationMesures(
appLogin,
contractId,
pointId,
name,
startDate,
endDate
),
}).catch(err => {
log('error', 'commanderCollectePublicationMesures')
log('error', err)
throw errors.LOGIN_FAILED
})
const parsedReply = await xml2js.parseStringPromise(response.body, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
try {
return parseServiceId(parsedReply)
} catch (error) {
log('error', 'Error while activating contract: ' + error)
log(
'error',
`Enedis issue ${parsedReply.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${parsedReply.Envelope.Body.Fault.faultstring}`
)
//TODO: handle SGT4B8: Il existe déjà plusieurs demandes en cours sur le point ?
throw errors.LOGIN_FAILED
}
}
module.exports = { activateContract }
// @ts-check
const { log, errors } = require('cozy-konnector-libs')
const soapRequest = require('easy-soap-request')
const {
parseTags,
parseValue,
parseContractStartDate,
} = require('../helpers/parsing')
const xml2js = require('xml2js')
const { consulterDonneesTechniquesContractuelles } = require('../requests/sge')
/**
* Get user contract start date
* @param {string} url
* @param {string} apiAuthKey
* @param {string} userLogin
* @param {number} pointId
* @returns {Promise<string>}
*/
async function getContractStartDate(url, apiAuthKey, userLogin, pointId) {
log('info', 'Fetching data start date')
const sgeHeaders = {
'Content-Type': 'text/xml;charset=UTF-8',
apikey: apiAuthKey,
}
const { response } = await soapRequest({
url: `${url}/enedis_SGE_ConsultationDonneesTechniquesContractuelles/1.0`,
headers: sgeHeaders,
xml: consulterDonneesTechniquesContractuelles(pointId, userLogin),
}).catch(err => {
log('error', 'Error while fetching contract start date : ' + err)
throw errors.VENDOR_DOWN
})
const result = await xml2js.parseStringPromise(response.body, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
try {
return parseContractStartDate(result)
} catch (error) {
log('error', 'Error while processing contract start date: ' + error)
log(
'error',
`Enedis issue ${result.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${result.Envelope.Body.Fault.faultstring}`
)
throw errors.NOT_EXISTING_DIRECTORY
}
}
module.exports = { getContractStartDate }
// @ts-check
const { log, errors } = require('cozy-konnector-libs')
const soapRequest = require('easy-soap-request')
const { parseTags, parseValue } = require('../helpers/parsing')
const { commanderArretServiceSouscritMesures } = require('../requests/sge')
const xml2js = require('xml2js')
/**
* @param {string} url
* @param {string} apiAuthKey
* @param {string} appLogin
* @param {number} pointId
* @param {number} serviceId
* @return {Promise<string>} User contractId
*/
async function terminateContract(
url,
apiAuthKey,
appLogin,
contractId,
pointId,
serviceId
) {
log('info', 'terminateContract')
const sgeHeaders = {
'Content-Type': 'text/xml;charset=UTF-8',
apikey: apiAuthKey,
}
const { response } = await soapRequest({
url: `${url}/enedis_SGE_CommandeArretServiceSouscritMesures/1.0`,
headers: sgeHeaders,
xml: commanderArretServiceSouscritMesures(
appLogin,
contractId,
pointId,
serviceId
),
}).catch(err => {
log('error', 'commanderArretServiceSouscritMesures')
log('error', err)
throw errors.VENDOR_DOWN
})
const parsedReply = await xml2js.parseStringPromise(response.body, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
try {
// We don't need any action on reply for now
if (parsedReply.Envelope.Body.Fault) {
log(
'error',
`Enedis issue ${parsedReply.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${parsedReply.Envelope.Body.Fault.faultstring}`
)
}
return parsedReply
} catch (error) {
log('error', 'Error while parsing user contract termination: ' + error)
log('error', `Enedis issue ${JSON.stringify(parsedReply.Envelope.Body)}`)
throw errors.VENDOR_DOWN
}
}
module.exports = { terminateContract }
// @ts-check
const { log, errors } = require('cozy-konnector-libs')
const soapRequest = require('easy-soap-request')
const { parseTags, parseValue, parseContracts } = require('../helpers/parsing')
const { rechercherServicesSouscritsMesures } = require('../requests/sge')
const xml2js = require('xml2js')
const { contractState, contractLibelle } = require('./types/enum')
/**
* @param {string} url
* @param {string} apiAuthKey
* @param {string} appLogin
* @param {number} pointId
* @return {Promise<number | null>} User contractId
*/
async function verifyContract(url, apiAuthKey, appLogin, contractId, pointId) {
log('info', 'verifyContract')
const sgeHeaders = {
'Content-Type': 'text/xml;charset=UTF-8',
apikey: apiAuthKey,
}
const { response } = await soapRequest({
url: `${url}/enedis_SGE_RechercheServicesMesures/1.0`,
headers: sgeHeaders,
xml: rechercherServicesSouscritsMesures(appLogin, contractId, pointId),
}).catch(err => {
log('error', 'rechercherServicesSouscritsMesures')
log('error', err)
throw errors.LOGIN_FAILED
})
const parsedReply = await xml2js.parseStringPromise(response.body, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
try {
const currentContracts = parseContracts(parsedReply)
let currentContract = null
if (Array.isArray(currentContracts)) {
currentContract = parseContracts(parsedReply)[0]
} else {
currentContract = parseContracts(parsedReply)
}
if (
(currentContract.etatCode === contractState.ACTIF ||
currentContract.etatCode === contractState.DEMANDE) &&
currentContract.serviceSouscritLibelle === contractLibelle.ACTIF
)
return currentContract.serviceSouscritId
return null
} catch (error) {
log('error', 'Error while parsing user contract: ' + error)
log(
'error',
`Enedis issue ${parsedReply.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${parsedReply.Envelope.Body.Fault.faultstring}`
)
throw errors.LOGIN_FAILED
}
}
module.exports = { verifyContract }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment