add unit tests and refactored