add tests and refactor it