diff --git a/hyperglass/ui/hooks/use-dns-query.test.tsx b/hyperglass/ui/hooks/use-dns-query.test.tsx new file mode 100644 index 0000000..b94106f --- /dev/null +++ b/hyperglass/ui/hooks/use-dns-query.test.tsx @@ -0,0 +1,73 @@ +import 'isomorphic-fetch'; +import '@testing-library/jest-dom'; +import { renderHook } from '@testing-library/react-hooks'; +import { QueryClientProvider, QueryClient } from 'react-query'; +import { HyperglassContext } from '~/context'; +import { useDNSQuery } from './use-dns-query'; + +import type { Config } from '~/types'; + +const queryClient = new QueryClient({ + defaultOptions: { queries: { retry: false, cacheTime: Infinity } }, +}); + +const CloudflareWrapper = (props: React.PropsWithChildren>) => { + const config = { + cache: { timeout: 120 }, + + web: { dnsProvider: { url: 'https://cloudflare-dns.com/dns-query' } }, + } as jest.Mocked; + return ( + + + + ); +}; + +const GoogleWrapper = (props: React.PropsWithChildren>) => { + const config = { + cache: { timeout: 120 }, + web: { dnsProvider: { url: 'https://dns.google/resolve' } }, + } as jest.Mocked; + return ( + + + + ); +}; + +describe('useDNSQuery Cloudflare', () => { + it('Test Cloudflare DNS over HTTPS (IPv4)', async () => { + const { result, waitFor } = renderHook(() => useDNSQuery('one.one.one.one', 4), { + wrapper: CloudflareWrapper, + }); + await waitFor(() => result.current.isSuccess, { timeout: 5_000 }); + expect(result.current.data?.Answer.map(a => a.data)).toContain('1.1.1.1'); + }); + + it('Test Cloudflare DNS over HTTPS (IPv6)', async () => { + const { result, waitFor } = renderHook(() => useDNSQuery('one.one.one.one', 6), { + wrapper: CloudflareWrapper, + }); + await waitFor(() => result.current.isSuccess, { timeout: 5_000 }); + expect(result.current.data?.Answer.map(a => a.data)).toContain('2606:4700:4700::1111'); + }); +}); + +describe('useDNSQuery Google', () => { + it('Test Google DNS over HTTPS (IPv4)', async () => { + const { result, waitFor } = renderHook(() => useDNSQuery('one.one.one.one', 4), { + wrapper: GoogleWrapper, + }); + await waitFor(() => result.current.isSuccess, { timeout: 5_000 }); + expect(result.current.data?.Answer.map(a => a.data)).toContain('1.1.1.1'); + }); + + it('Test Google DNS over HTTPS (IPv6)', async () => { + const { result, waitFor } = renderHook(() => useDNSQuery('one.one.one.one', 6), { + wrapper: GoogleWrapper, + }); + await waitFor(() => result.current.isSuccess, { timeout: 5_000 }); + expect(result.current.data?.Answer.map(a => a.data)).toContain('2606:4700:4700::1111'); + }); +}); diff --git a/hyperglass/ui/hooks/use-dns-query.ts b/hyperglass/ui/hooks/use-dns-query.ts index c100592..716dd73 100644 --- a/hyperglass/ui/hooks/use-dns-query.ts +++ b/hyperglass/ui/hooks/use-dns-query.ts @@ -42,13 +42,9 @@ const query: QueryFunction = async ( * an A record will be queried. If `family` is `6`, only a AAAA record will be queried. */ export function useDNSQuery( - /** - * Hostname for DNS query. - */ + /** Hostname for DNS query. */ target: string | null, - /** - * Address family, e.g. IPv4 or IPv6. - */ + /** Address family, e.g. IPv4 or IPv6. */ family: 4 | 6, ): QueryObserverResult { const { cache, web } = useConfig(); diff --git a/hyperglass/ui/package.json b/hyperglass/ui/package.json index 3ad637b..3fe29f2 100644 --- a/hyperglass/ui/package.json +++ b/hyperglass/ui/package.json @@ -55,7 +55,8 @@ }, "devDependencies": { "@testing-library/jest-dom": "^5.14.1", - "@testing-library/react": "^12.1.0", + "@testing-library/react": "^12.1.2", + "@testing-library/react-hooks": "^7.0.2", "@testing-library/user-event": "^13.5.0", "@types/dagre": "^0.7.44", "@types/express": "^4.17.13", @@ -80,6 +81,7 @@ "express": "^4.17.1", "http-proxy-middleware": "0.20.0", "identity-obj-proxy": "^3.0.0", + "isomorphic-fetch": "^3.0.0", "jest": "^27.2.1", "prettier": "^2.3.2", "prettier-eslint": "^13.0.0", diff --git a/hyperglass/ui/yarn.lock b/hyperglass/ui/yarn.lock index ad1752a..e7950b5 100644 --- a/hyperglass/ui/yarn.lock +++ b/hyperglass/ui/yarn.lock @@ -1649,10 +1649,21 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react@^12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.0.tgz#3e9a4002b0b8f986a738a2f88fc458b5af319f35" - integrity sha512-Ge3Ht3qXE82Yv9lyPpQ7ZWgzo/HgOcHu569Y4ZGWcZME38iOFiOg87qnu6hTEa8jTJVL7zYovnvD3GE2nsNIoQ== +"@testing-library/react-hooks@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" + integrity sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg== + dependencies: + "@babel/runtime" "^7.12.5" + "@types/react" ">=16.9.0" + "@types/react-dom" ">=16.9.0" + "@types/react-test-renderer" ">=16.9.0" + react-error-boundary "^3.1.0" + +"@testing-library/react@^12.1.2": + version "12.1.2" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.2.tgz#f1bc9a45943461fa2a598bb4597df1ae044cfc76" + integrity sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^8.0.0" @@ -2087,6 +2098,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/react-dom@>=16.9.0": + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.11.tgz#e1eadc3c5e86bdb5f7684e00274ae228e7bcc466" + integrity sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q== + dependencies: + "@types/react" "*" + "@types/react-redux@^7.1.16": version "7.1.16" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" @@ -2104,6 +2122,13 @@ dependencies: "@types/react" "*" +"@types/react-test-renderer@>=16.9.0": + version "17.0.1" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" + integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw== + dependencies: + "@types/react" "*" + "@types/react-transition-group@^4.4.0": version "4.4.4" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e" @@ -2119,6 +2144,15 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/react@>=16.9.0": + version "17.0.37" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.37.tgz#6884d0aa402605935c397ae689deed115caad959" + integrity sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/react@^17.0.3": version "17.0.3" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79" @@ -5048,6 +5082,14 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +isomorphic-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" + integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== + dependencies: + node-fetch "^2.6.1" + whatwg-fetch "^3.4.1" + istanbul-lib-coverage@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" @@ -6203,6 +6245,13 @@ node-fetch@2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@^2.6.1: + version "2.6.6" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" + integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== + dependencies: + whatwg-url "^5.0.0" + node-html-parser@1.4.9: version "1.4.9" resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-1.4.9.tgz#3c8f6cac46479fae5800725edb532e9ae8fd816c" @@ -6860,6 +6909,13 @@ react-draggable@^4.4.3: classnames "^2.2.5" prop-types "^15.6.0" +react-error-boundary@^3.1.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + react-fast-compare@3.2.0, react-fast-compare@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" @@ -7818,6 +7874,11 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + trough@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" @@ -8226,6 +8287,11 @@ watchpack@2.3.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -8248,11 +8314,24 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@^3.4.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"