diff --git a/components/measurement/MeasurementContainer.js b/components/measurement/MeasurementContainer.js
index 16049582c..6121f181c 100644
--- a/components/measurement/MeasurementContainer.js
+++ b/components/measurement/MeasurementContainer.js
@@ -39,7 +39,12 @@ const MeasurementContainer = ({ measurement, ...props }) => {
}
const TestDetails = mapTestDetails[measurement.test_name] || DefaultTestDetails
- return
+
+ return (
+
+
+
+ )
}
export default MeasurementContainer
diff --git a/components/measurement/PerformanceDetails.js b/components/measurement/PerformanceDetails.js
index 88bbcaebb..dd23bf182 100644
--- a/components/measurement/PerformanceDetails.js
+++ b/components/measurement/PerformanceDetails.js
@@ -13,40 +13,37 @@ const PerformanceDetails = ({
timeouts
}) => {
const intl = useIntl()
- let items = [
- {
- label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.AvgPing' }),
- value: averagePing.toString() + ' ms'
- },
- {
- label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.MaxPing' }),
- value: `${isNdt7 ? '~' : ''}${maxPing.toString()} ms`
- },
- {
- label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.MSS' }),
- value: mss.toString()
- },
- {
- label: isNdt7 ? intl.formatMessage({
- id: 'Measurement.Details.Performance.Label.RetransmitRate',
- defaultMessage: 'Retransmit Rate'
- }): intl.formatMessage({ id: 'Measurement.Details.Performance.Label.PktLoss' }),
- value: packetLoss.toString() + '%'
- },
- ]
+ let items = []
+ averagePing && items.push({
+ label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.AvgPing' }),
+ value: `${averagePing} ms`
+ })
+ maxPing && items.push({
+ label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.MaxPing' }),
+ value: `${isNdt7 ? '~' : ''}${maxPing} ms`
+ })
+ mss && items.push({
+ label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.MSS' }),
+ value: `${mss}`
+ })
+
+ packetLoss != undefined && items.push({
+ label: isNdt7 ? intl.formatMessage({
+ id: 'Measurement.Details.Performance.Label.RetransmitRate'
+ }): intl.formatMessage({ id: 'Measurement.Details.Performance.Label.PktLoss' }),
+ value: `${packetLoss}%`
+ })
//Only add outOfOrder and timeouts if NDT4/5 measurement
- if(!isNdt7){
- items = items.concat([
- {
- label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.OutOfOrder' }),
- value: outOfOrder.toString() + '%'
- },
- {
- label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.Timeouts' }),
- value: timeouts.toString()
- }
- ])
+ if(!isNdt7) {
+ outOfOrder != undefined && items.push({
+ label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.OutOfOrder' }),
+ value: outOfOrder.toString() + '%'
+ })
+ timeouts != undefined && items.push({
+ label: intl.formatMessage({ id: 'Measurement.Details.Performance.Label.Timeouts' }),
+ value: timeouts.toString()
+ })
}
return (
diff --git a/components/measurement/nettests/Dash.js b/components/measurement/nettests/Dash.js
index bc05bf199..406b1d363 100644
--- a/components/measurement/nettests/Dash.js
+++ b/components/measurement/nettests/Dash.js
@@ -1,24 +1,8 @@
-
import React from 'react'
import PropTypes from 'prop-types'
-import {
- Heading,
- Flex,
- Box,
- theme
-} from 'ooni-components'
-
+import { Flex, Box } from 'ooni-components'
import { Text } from 'rebass'
import { useIntl } from 'react-intl'
-
-import {
- VictoryChart,
- VictoryLine,
- VictoryTooltip,
- VictoryVoronoiContainer,
- VictoryAxis
-} from 'victory'
-
import MdFlashOn from 'react-icons/lib/md/flash-on'
const InfoBoxItem = ({
@@ -92,10 +76,9 @@ const getOptimalQualityForBitrate = (testKeys) => {
const DashDetails = ({ measurement, render }) => {
const intl = useIntl()
const testKeys = measurement.test_keys
- // const isFailed = testKeys.failure !== null
- // const failure = testKeys.failure
+ const failure = testKeys.failure
- if (typeof testKeys.simple === 'undefined' || typeof testKeys.receiver_data === 'undefined') {
+ if (failure === true || typeof testKeys.simple === 'undefined' || typeof testKeys.receiver_data === 'undefined') {
return render({
status: 'error'
})
@@ -105,13 +88,6 @@ const DashDetails = ({ measurement, render }) => {
const medianBitrate = (testKeys.simple.median_bitrate / 1000).toFixed(2)
const playoutDelay = (testKeys.simple.min_playout_delay).toFixed(2)
- // construct data for graph
- const clientData = testKeys.receiver_data
- const data = clientData.map(iteration => ({
- x: iteration.iteration,
- y: iteration.rate / 1000,
- }))
-
return (
render({
statusIcon: ,
@@ -134,55 +110,7 @@ const DashDetails = ({ measurement, render }) => {
),
- details: (
-
- {/*
- Video Quality by time
-
- `${d.y} Mb/s`}
- labelComponent={}
- />
- }
- >
- i.x + 's'))}
- style={{
- tickLabels: { fontSize: 10, padding: 5}
- }}
- />
-
-
-
-
- */}
-
- )
+ details: null
})
)
}
diff --git a/components/measurement/nettests/HTTPHeaderFieldManipulation.js b/components/measurement/nettests/HTTPHeaderFieldManipulation.js
index 8eb1b44af..2f03aa2b0 100644
--- a/components/measurement/nettests/HTTPHeaderFieldManipulation.js
+++ b/components/measurement/nettests/HTTPHeaderFieldManipulation.js
@@ -9,7 +9,7 @@ export const HttpHeaderFieldManipulationDetails = ({ measurement, render }) => {
const testKeys = measurement.test_keys
let isAnomaly = false
let isFailed = true
- const tampering = testKeys.tampering
+ const tampering = testKeys?.tampering || {}
Object.keys(tampering).forEach((key) => {
if (tampering[key] === true) {
isAnomaly = true
@@ -18,7 +18,6 @@ export const HttpHeaderFieldManipulationDetails = ({ measurement, render }) => {
isFailed = false
}
})
- const headerDiff = testKeys.tampering.header_name_diff
return (
render({
@@ -29,13 +28,6 @@ export const HttpHeaderFieldManipulationDetails = ({ measurement, render }) => {
summaryText: isAnomaly
? 'Measurement.HTTPHeaderManipulation.MiddleBoxesDetected.SummaryText'
: 'Measurement.HTTPHeaderManipulation.NoMiddleBoxes.SummaryText',
- details: (
-
- {/*isAnomaly: {isAnomaly.toString()}
- isFailed: {isFailed.toString()}
- headerDiff: {headerDiff.toString()}*/}
-
- )
})
)
}
diff --git a/components/measurement/nettests/Ndt.js b/components/measurement/nettests/Ndt.js
index 24c3b3a2f..f5b6d8c2b 100644
--- a/components/measurement/nettests/Ndt.js
+++ b/components/measurement/nettests/Ndt.js
@@ -26,7 +26,7 @@ const InfoBoxItem = ({
)
-const ServerLocation = ({ serverAddress, isNdt7 }) => {
+const ServerLocation = ({ serverAddress = '', isNdt7 }) => {
const server = mlabServerDetails(serverAddress, isNdt7)
return (
@@ -41,6 +41,7 @@ const ServerLocation = ({ serverAddress, isNdt7 }) => {
const NdtDetails = ({ measurement, render }) => {
const intl = useIntl()
const testKeys = measurement.test_keys
+
const isFailed = testKeys.failure !== null
const failure = testKeys.failure
const isNdt7 = testKeys.protocol === 7
@@ -55,27 +56,44 @@ const NdtDetails = ({ measurement, render }) => {
const uploadMbit = simple.upload && (simple.upload / 1000).toFixed(2)
const ping = simple.ping && (simple.ping).toFixed(1)
- if (isNdt7) {
- const summary = testKeys.summary || {}
-
- // Summary
- packetLoss = summary.retransmit_rate && (summary.retransmit_rate * 100).toFixed(3)
- minRTT = summary.min_rtt && (summary.min_rtt).toFixed(0)
- maxRTT = summary.max_rtt && (summary.max_rtt).toFixed(0)
- mss = summary.mss
- outOfOrder = null
- timeouts = null
- }
- else {
- const advanced = testKeys.advanced || {}
-
- // Advanced
- packetLoss = advanced.packet_loss && (advanced.packet_loss * 100).toFixed(3)
- outOfOrder = advanced.out_of_order && (advanced.out_of_order * 100).toFixed(1)
- minRTT = advanced.min_rtt && (advanced.min_rtt).toFixed(0)
- maxRTT = advanced.max_rtt && (advanced.max_rtt).toFixed(0)
- mss = advanced.mss
- timeouts = advanced.timeouts
+ let performanceDetails = null
+ try {
+ if (isNdt7) {
+ const summary = testKeys.summary || {}
+ // Summary
+ packetLoss = summary.retransmit_rate && (summary.retransmit_rate * 100).toFixed(3)
+ minRTT = summary.min_rtt && (summary.min_rtt).toFixed(0)
+ maxRTT = summary.max_rtt && (summary.max_rtt).toFixed(0)
+ mss = summary.mss
+ outOfOrder = null
+ timeouts = null
+ }
+ else {
+ const advanced = testKeys.advanced || null
+ // Advanced
+ delete advanced['out_of_order']
+ packetLoss = advanced.packet_loss && (advanced.packet_loss * 100).toFixed(3)
+ outOfOrder = advanced.out_of_order && (advanced.out_of_order * 100).toFixed(1)
+ minRTT = advanced.min_rtt && (advanced.min_rtt).toFixed(0)
+ maxRTT = advanced.max_rtt && (advanced.max_rtt).toFixed(0)
+ mss = advanced?.mss
+ timeouts = advanced?.timeouts
+ }
+ performanceDetails = (
+
+ )
+ } catch (e) {
+ console.error(`Error in parsing test_keys for ${measurement.test_name}`)
+ console.error(e)
+ // Leaves performanceDetails `null` and thus isn't rendered
}
// FIXME we need to style the failed test case properly
@@ -85,38 +103,30 @@ const NdtDetails = ({ measurement, render }) => {
statusLabel: intl.formatMessage({id: 'Measurement.Hero.Status.NDT.Title'}),
statusInfo: (
- {isFailed ?
+ {isFailed ? (
Failed Test
- :
+ ) : (
}
+ content={
+
+ }
/>
- }
+ )}
),
details: (
-
+ {!isFailed && performanceDetails}
)
})
)
diff --git a/components/measurement/nettests/WebConnectivity.js b/components/measurement/nettests/WebConnectivity.js
index 210ad2448..b4120f81f 100644
--- a/components/measurement/nettests/WebConnectivity.js
+++ b/components/measurement/nettests/WebConnectivity.js
@@ -150,6 +150,9 @@ const RequestResponseContainer = ({request}) => {
}
const FailureString = ({failure}) => {
+ if (typeof failure === 'undefined') {
+ return ()
+ }
if (!failure) {
return (
diff --git a/components/measurement/useTestKeyController.js b/components/measurement/useTestKeyController.js
new file mode 100644
index 000000000..16959facd
--- /dev/null
+++ b/components/measurement/useTestKeyController.js
@@ -0,0 +1,72 @@
+// This file contains a custom hook to render a toolbar
+// that can be used to enable/disable parts of `testKeys`
+// To use it, add the below code in components/measurement/MeasurementContainer.js
+/*
+import { useTestKeyController } from './useTestKeyController'
+...
+...
+const { testKeys, TestKeyController } = useTestKeyController(measurement.test_keys)
+const measurementMod = Object.assign({}, measurement, { test_keys: testKeys })
+
+return (
+
+
+
+
+)
+*/
+
+import React, { useState, useCallback } from 'react'
+import { Flex } from 'ooni-components'
+
+
+const setValues = (input, value = true) => {
+ // Maps each key in `test_keys` to a boolean value, by default true
+ return Object.keys(input).reduce((o, k) => {
+ o[k] = value
+ return o
+ }, {all: value})
+}
+
+export const useTestKeyController = (testKeysInitial) => {
+ const [testKeys, setTestKeys] = useState(testKeysInitial)
+ const [keysMap, setKeysMap] = useState(setValues(testKeysInitial))
+
+ const TestKeyController = () => {
+ const onChange = useCallback((event) => {
+ const {name, checked} = event.target
+
+ if (name === 'all') {
+ setTestKeys(checked ? testKeysInitial : {})
+ setKeysMap(setValues(testKeysInitial, checked))
+ } else {
+ const newTestKeys = {...testKeys}
+ // add or delete the original entry from `test_keys`
+ if (checked) {
+ newTestKeys[name] = testKeysInitial[name]
+ } else {
+ delete newTestKeys[name]
+ }
+ setTestKeys(newTestKeys)
+ setKeysMap(keysMap => {
+ const newKeysMap = {...keysMap}
+ newKeysMap[name] = checked
+ return newKeysMap
+ })
+ }
+ }, [keysMap, testKeys, setKeysMap, setTestKeys])
+
+ return (
+
+ {Object.keys(keysMap).map((k, i) =>
+
+
+
+
+ )}
+
+ )
+ }
+
+ return { testKeys, TestKeyController }
+}