From c2bba48a3a2b7d7c73408076097218e4f37ec646 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 4 Oct 2020 22:18:12 +0530 Subject: [PATCH] Adds updateHosts (without maintain old rules) --- tests/domain-service.test.js | 70 +++++++++++++++++++++++++++++------- utils/domain-service.js | 40 ++++++++++----------- 2 files changed, 77 insertions(+), 33 deletions(-) diff --git a/tests/domain-service.test.js b/tests/domain-service.test.js index 90a73bba4..c9280df13 100644 --- a/tests/domain-service.test.js +++ b/tests/domain-service.test.js @@ -44,8 +44,8 @@ describe('Domain service', () => { describe('updateHosts', () => { it('should append new hosts with existing ones and set it', async () => { const records = [ - { HostId: 1, HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostId: 2, HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, + { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, + { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, ]; const onGet = () => Promise.resolve({ hosts: records }); @@ -58,13 +58,19 @@ describe('Domain service', () => { { HostName: 'c', RecordType: 'A', Address: '12.131321.213' }, ]); - console.log(onSet.mock.calls); - //expect(onSet).toBeCalledTimes(1); + const [hosts] = onSet.mock.calls[0]; + + expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ + { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, + { HostName: 'c', RecordType: 'A', Address: '12.131321.213' }, + ]); }); + it('should update matching host and set it', async () => { const records = [ - { HostId: 1, HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostId: 2, HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, + { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, + { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, ]; const onGet = () => Promise.resolve({ hosts: records }); @@ -76,14 +82,45 @@ describe('Domain service', () => { { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, ]); - console.log(onSet.mock.calls); - //expect(onSet).toBeCalledTimes(1); + const [hosts] = onSet.mock.calls[0]; + + expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ + { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, + ]); }); - it('should maintain existing entries on the server', async () => { + + it('should update matching host and set it', async () => { const records = [ - { HostId: 1, HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, - { HostId: 2, HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, - { HostId: 3, HostName: 'c', RecordType: 'A', Address: '12.131321.213' }, + { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, + { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, + { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'xaa' }, + ]; + + const onGet = () => Promise.resolve({ hosts: records }); + const onSet = jest.fn(async () => ({})); + + const mockDomainService = getDomainService({ Namecheap: getNcClass({ onSet, onGet }) }); + await mockDomainService.updateHosts([ + { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'farboo' }, + ]); + + const [hosts] = onSet.mock.calls[0]; + + expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ + { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'googoogaga' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'farboo' }, + ]); + }); + + xit('should maintain existing entries on the server', async () => { + const records = [ + { HostId: 1, Name: 'a', Type: 'CNAME', Address: 'boo' }, + { HostId: 2, Name: 'b', Type: 'CNAME', Address: 'goo' }, + { HostId: 3, Name: 'c', Type: 'A', Address: '12.131321.213' }, ]; const onGet = () => Promise.resolve({ hosts: records }); @@ -95,7 +132,14 @@ describe('Domain service', () => { { HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, ]); - console.log(onSet.mock.calls); + const [hosts] = onSet.mock.calls[0]; + + expect(hosts.map(R.pick(['HostName', 'RecordType', 'Address']))).toEqual([ + { HostName: 'a', RecordType: 'CNAME', Address: 'boo' }, + { HostName: 'b', RecordType: 'CNAME', Address: 'goo' }, + { HostName: 'c', RecordType: 'A', Address: '12.131321.213' }, + ]); + expect(); // expect(onSet).toBeCalledTimes(1); }); }); diff --git a/utils/domain-service.js b/utils/domain-service.js index 031e12b47..1cda12989 100644 --- a/utils/domain-service.js +++ b/utils/domain-service.js @@ -23,16 +23,13 @@ const getDomainService = ({ Namecheap }) => { const list = await nc.dns.getHosts(NC_DOMAIN) .then(R.propOr([], 'hosts')) - .then(R.map(host => ({ + .then(R.map(host => R.omit(['Name', 'Type'], { ...host, HostName: host.Name, RecordType: host.Type, Address: `${host.Address}`.replace(/\.$/g, ''), - Name: undefined, - Type: undefined, }))); - //console.log(list); hostList = list; return list; }; @@ -41,24 +38,27 @@ const getDomainService = ({ Namecheap }) => { return nc.dns.setHosts(NC_DOMAIN, hosts); }; - const findIndexHost = async host => { - const list = await getHosts(); - return list.findIndex(R.whereEq({ - RecordType: host.RecordType, - HostName: host.HostName, - Address: host.Address, - // MXPref: host.MXPref, - TTL: host.TTL || TTL, - })); - }; - + const getHostKey = host => `${host.HostName}--${host.RecordType}`; + const toHostMap = hosts => hosts.reduce((acc, host) => { + const key = getHostKey(host); + return { ...acc, [key]: [ ...(acc[key] || []), host ] }; + }, {}); const updateHosts = async hosts => { const hostList = await getHosts(); - hosts.map(host => { - // - }); - // If source is bigger, merge all matching items and add new ones - // If dest is bigger, merge all matching items and add missing ones + const remoteHostMap = toHostMap(hostList); + const localHostMap = toHostMap(hosts); + + const newHostList = R.toPairs(localHostMap).reduce((acc, [key, local]) => { + const remote = remoteHostMap[key]; + + if (remote) { + return acc.concat(local.map((localItem, index) => R.merge(remote[index], localItem))); + } + + return [...acc, ...local]; + }, []); + + await setHosts(newHostList); }; return { getHosts, setHosts, updateHosts };