In foo | bar foo and bar run simultaneously. Your code displays done: because the final echo does not read its stdin and it does not wait for anything piped via its stdin. It does its job right away.
Additionally ${TEST} after | has nothing to do with the variable your read sets before |. When building a pipeline, Bash runs each command in a separate subshell (the last one may or may not be executed in the context of the main shell).
This is what I think you want:
echo -n 'input data: '; read TEST
echo "done: ${TEST}"
(in Bash read -p 'input data: ' TEST will also work).
There is no need to pipe anything to anything here.
In general, in case you need to interact with the user from within a pipe (I mean from within a genuinely needed pipe), /dev/tty may be useful. Artificial example:
echo foo | ( read -p 'i: ' var </dev/tty; echo "d: $var" >/dev/tty; cat ) | nl
Here read does not read from the first echo, it reads form /dev/tty. Neither read nor the second echo prints to nl: read -p prints its prompt to stderr by default, echo prints to /dev/tty because we redirected. In effect the data (foo+newline) goes from echo to cat to nl as if nothing else was there.
It may look like a trick, but's it's a legitimate use case. E.g. see How/why does ssh output to tty when both stdout and stderr are redirected? and my answer there.