diff --git a/package-lock.json b/package-lock.json index 7111213..a17cf02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -285,11 +285,11 @@ "dev": true }, "axios": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", - "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "1.5.10" } }, "balanced-match": { @@ -807,9 +807,27 @@ "dev": true }, "follow-redirects": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", - "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } }, "fs.realpath": { "version": "1.0.0", diff --git a/package.json b/package.json index b00e367..70aec81 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "lint": "eslint src --ext ts", "watch": "tsc -watch -p ./", "pretest": "npm run compile && npm run lint", - "test": "node ./out/test/runTest.js" + "core-test": "ts-node ./src/test.suite/coreTests.ts", + "extention-test": "node ./out/test/runTest.js" }, "devDependencies": { "@types/axios": "^0.14.0", @@ -44,6 +45,6 @@ "vscode-test": "^1.4.0" }, "dependencies": { - "axios": "^0.20.0" + "axios": "^0.19.0" } } diff --git a/src/Entities/Harvest.ts b/src/Entities/Harvest.ts index 6e4d66c..d2b9040 100644 --- a/src/Entities/Harvest.ts +++ b/src/Entities/Harvest.ts @@ -16,6 +16,10 @@ class Harvest { return instance } + destructor (): void { + instance = null + } + get headers () { return { 'Harvest-Account-ID': this.accountId, diff --git a/src/Entities/Interfaces/ProjectInterface.ts b/src/Entities/Interfaces/ProjectInterface.ts index 0ce5bcc..cf11747 100644 --- a/src/Entities/Interfaces/ProjectInterface.ts +++ b/src/Entities/Interfaces/ProjectInterface.ts @@ -1,7 +1,7 @@ import TaskInterface from "./TaskInterface"; interface ProjectInterface { - id: string, + id: number, name: string, tasks: TaskInterface[] } diff --git a/src/Entities/Interfaces/TaskInterface.ts b/src/Entities/Interfaces/TaskInterface.ts index 31b4281..6a5f1dc 100644 --- a/src/Entities/Interfaces/TaskInterface.ts +++ b/src/Entities/Interfaces/TaskInterface.ts @@ -1,5 +1,5 @@ interface TaskInterface { - id: string, + id: number, name: string } diff --git a/src/Entities/Project.ts b/src/Entities/Project.ts index d6f0421..6a36833 100644 --- a/src/Entities/Project.ts +++ b/src/Entities/Project.ts @@ -2,7 +2,7 @@ import ProjectInterface from './Interfaces/ProjectInterface' import TaskInterface from './Interfaces/TaskInterface' class Project { - public id: string + public id: number public name: string public tasks: TaskInterface[] diff --git a/src/Entities/ProjectCollection.ts b/src/Entities/ProjectCollection.ts index 89f5417..531b118 100644 --- a/src/Entities/ProjectCollection.ts +++ b/src/Entities/ProjectCollection.ts @@ -10,6 +10,10 @@ class ProjectCollection { return instance } + destructor (): void { + instance = null + } + addOne = (project: Project): void => { this.elements.push(project) } @@ -20,7 +24,7 @@ class ProjectCollection { }) } - findById = (id: string): Project | undefined => { + findById = (id: number): Project | undefined => { const project = this.elements.find((p: Project) => { return p.id === id }) diff --git a/src/Entities/User.ts b/src/Entities/User.ts index b147890..13e2319 100644 --- a/src/Entities/User.ts +++ b/src/Entities/User.ts @@ -8,18 +8,22 @@ class User { public readonly lastName: string public readonly email: string public readonly avatar: string - constructor (props: UserInterface) { + constructor (props?: UserInterface) { if (!instance) instance = this - this.id = props.id - this.firstName = props.firstName - this.lastName = props.lastName - this.email = props.email - this.avatar = props.avatar + this.id = props?.id || 0 + this.firstName = props?.firstName || '' + this.lastName = props?.lastName || '' + this.email = props?.email || '' + this.avatar = props?.avatar || '' return instance } + destructor (): void { + instance = null + } + get props (): UserInterface { return { id: this.id, diff --git a/src/UseCases/getProjects.ts b/src/UseCases/getProjects.ts index 1f44332..9066d04 100644 --- a/src/UseCases/getProjects.ts +++ b/src/UseCases/getProjects.ts @@ -2,10 +2,9 @@ import axios from 'axios' import Harvest from '../Entities/Harvest' import ErrorMessage from '../Constants/ErrorMessageInterface' import ErrorMessages from '../Constants/ErrorMessages' -import Project from '../Entities/Project' import ProjectInterface from '../Entities/Interfaces/ProjectInterface' -const getProjects = async (): Promise => { +const getProjects = async (): Promise => { const harvest = new Harvest() let projectsResponse: any try { @@ -18,7 +17,7 @@ const getProjects = async (): Promise => { return ErrorMessages[1] } - const projectData = projectsResponse.data.project_assignments.map((p: any) => { + const projects = projectsResponse.data.project_assignments.map((p: any) => { return { id: p.project.id, name: p.project.name, @@ -30,10 +29,7 @@ const getProjects = async (): Promise => { }) } }) - - const projects = projectData.map((p: ProjectInterface) => { - return new Project(p) - }) + return projects } diff --git a/src/UseCases/getUser.ts b/src/UseCases/getUser.ts index 3623ac6..8210260 100644 --- a/src/UseCases/getUser.ts +++ b/src/UseCases/getUser.ts @@ -2,9 +2,9 @@ import axios from 'axios' import Harvest from '../Entities/Harvest' import ErrorMessage from '../Constants/ErrorMessageInterface' import ErrorMessages from '../Constants/ErrorMessages' -import User from "../Entities/User" +import UserInterface from '../Entities/Interfaces/UserInterface' -const getUser = async (): Promise => { +const getUser = async (): Promise => { const harvest = new Harvest() let userResponse: any try { @@ -17,7 +17,7 @@ const getUser = async (): Promise => { return ErrorMessages[0] } - const userData = { + const user = { id: userResponse.data.id || '', firstName: userResponse.data.first_name || '', lastName: userResponse.data.last_name || '', @@ -25,7 +25,6 @@ const getUser = async (): Promise => { avatar: userResponse.data.avatar_url || '', } - const user = new User(userData) return user } diff --git a/src/test/UnitTestInterface.ts b/src/test/UnitTestInterface.ts new file mode 100644 index 0000000..0b33a80 --- /dev/null +++ b/src/test/UnitTestInterface.ts @@ -0,0 +1,6 @@ +interface UnitTest { + name: string, + test: Function +} + +export default UnitTest \ No newline at end of file diff --git a/src/test/core/HarvestTests.ts b/src/test/core/HarvestTests.ts new file mode 100644 index 0000000..6ea95ca --- /dev/null +++ b/src/test/core/HarvestTests.ts @@ -0,0 +1,27 @@ +import Harvest from '../../Entities/Harvest' +import UnitTest from '../UnitTestInterface' + +const harvestCreateInstance = (): boolean => { + const input = { + accountId: '123', + accessToken: 'XYZ', + organization: 'ABC' + } + + const expectedOutput = { + accountId: '123', + accessToken: 'XYZ', + organization: 'ABC' + } + + const harvest = new Harvest(input) + + if (JSON.stringify(harvest.props) === JSON.stringify(expectedOutput)) return true + else return false +} + +const unitTests: UnitTest[] = [ + { name: 'Entity | Harvest Create Instance', test: harvestCreateInstance } +] + +export default unitTests \ No newline at end of file diff --git a/src/test/core/ProjectsTests.ts b/src/test/core/ProjectsTests.ts new file mode 100644 index 0000000..5041ea4 --- /dev/null +++ b/src/test/core/ProjectsTests.ts @@ -0,0 +1,61 @@ +import ErrorMessage from "../../Constants/ErrorMessageInterface" +import Harvest from "../../Entities/Harvest" +import ProjectInterface from "../../Entities/Interfaces/ProjectInterface" +import Project from "../../Entities/Project" +import getProjects from '../../UseCases/getProjects' +import env from '../env' +import UnitTest from "../UnitTestInterface" + +const projectCreateInstance = async (): Promise => { + const input: ProjectInterface = { + id: 10203, + name: 'Test Project', + tasks: [{ + id: 123, + name: 'Test Task' + }] + } + + const expectedOutput: ProjectInterface = { + id: 10203, + name: 'Test Project', + tasks: [{ + id: 123, + name: 'Test Task' + }] + } + + const project = new Project(input) + if (JSON.stringify(project.props) === JSON.stringify(expectedOutput)) return true + else return false +} + + +const getProjectsFromApi = async (): Promise => { + new Harvest().destructor() + + new Harvest({ + accountId: env.accountId, + accessToken: env.accessToken, + organization: 'ABC' + }) + + const expectedOutput: ProjectInterface = env.firstProjectFromApi + + const projects: ProjectInterface[] | ErrorMessage = await getProjects() + + if (!Array.isArray(projects)) return false + + const project: ProjectInterface = projects[0] + + // based off my own user data + if (JSON.stringify(project) === JSON.stringify(expectedOutput)) return true + else return false +} + +const unitTests: UnitTest[] = [ + { name: 'Entity | Project Create Instance', test: projectCreateInstance }, + { name: 'Use Case | Get Projects From Api', test: getProjectsFromApi }, +] + +export default unitTests \ No newline at end of file diff --git a/src/test/core/UserTests.ts b/src/test/core/UserTests.ts new file mode 100644 index 0000000..388d063 --- /dev/null +++ b/src/test/core/UserTests.ts @@ -0,0 +1,57 @@ +import Harvest from "../../Entities/Harvest" +import UserInterface from "../../Entities/Interfaces/UserInterface" +import User from "../../Entities/User" +import getUser from '../../UseCases/getUser' +import env from '../env' +import UnitTest from "../UnitTestInterface" + +const userCreateInstance = (): boolean => { + new User().destructor() + + const input: UserInterface = { + id: 10203, + firstName: 'Joshua', + lastName: 'Sandler', + email: 'joshua@me.com', + avatar: 'link' + } + + const expectedOutput: UserInterface = { + id: 10203, + firstName: 'Joshua', + lastName: 'Sandler', + email: 'joshua@me.com', + avatar: 'link' + } + + const user = new User(input) + if(JSON.stringify(user.props) === JSON.stringify(expectedOutput)) return true + else return false +} + +const getUserFromApi = async (): Promise => { + new Harvest().destructor() + new User().destructor() + + + new Harvest({ + accountId: env.accountId, + accessToken: env.accessToken, + organization: 'ABC' + }) + + // this data is based off my own user + const expectedOutput: UserInterface = env.userFromApi + + const userData = await getUser() + + if (JSON.stringify(userData) === JSON.stringify(expectedOutput)) return true + else return false +} + +const unitTests: UnitTest[] = [ + { name: 'Entity | User Create Instance', test: userCreateInstance }, + { name: 'Use Case | Get User from Api', test: getUserFromApi } +] + +export default unitTests \ No newline at end of file diff --git a/src/test/coreTests.ts b/src/test/coreTests.ts new file mode 100644 index 0000000..a042bfd --- /dev/null +++ b/src/test/coreTests.ts @@ -0,0 +1,35 @@ +import HarvestTests from './core/HarvestTests' +import UserTests from './core/UserTests' +import ProjectsTests from './core/ProjectsTests' +import UnitTest from './UnitTestInterface' + +async function runTestsAndReturnFailures(tests: UnitTest[]): Promise { + const testTotalCount = tests.length + const testsFailed: string[] = [] + + for (let i = 0; i < testTotalCount; i++) { + const didPassTest = await tests[i].test() + if (!didPassTest) testsFailed.push(tests[i].name) + } + return testsFailed +} + +async function init(tests: UnitTest[]) { + const failedTestsResults = await runTestsAndReturnFailures(tests) + if (failedTestsResults.length === 0) { + console.log('\x1b[32m%s\x1b[0m', 'All Tests Passed!!') + } else { + console.log(`\x1b[31mFailed ${failedTestsResults.length} tests.\x1b[0m`) + failedTestsResults.forEach((test) => { + console.log(`\x1b[33m${test}\x1b[0m`) + }) + } +} + +const testsArray: any = [ + HarvestTests, + UserTests, + ProjectsTests +] + +init(testsArray.flat()) \ No newline at end of file diff --git a/src/test/entityTests/HarvestTests.ts b/src/test/entityTests/HarvestTests.ts deleted file mode 100644 index 6dfefc5..0000000 --- a/src/test/entityTests/HarvestTests.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Harvest from '../../Entities/Harvest' - -const harvest = new Harvest({ - accountId: '123', - accessToken: 'XYZ' -}) - -console.log(harvest.props) - -const harvest2 = new Harvest() - -harvest2.organization = 'ABC' - -console.log(harvest2.props) \ No newline at end of file diff --git a/src/test/useCaseTests/getProjectsTests.ts b/src/test/useCaseTests/getProjectsTests.ts deleted file mode 100644 index c617f5f..0000000 --- a/src/test/useCaseTests/getProjectsTests.ts +++ /dev/null @@ -1,23 +0,0 @@ -import ErrorMessage from "../../Constants/ErrorMessageInterface" -import Harvest from "../../Entities/Harvest" -import Project from "../../Entities/Project" -import getProjects from '../../UseCases/getProjects' -import env from '../env' - -async function test () { - new Harvest({ - accountId: env.accountId, - accessToken: env.accessToken, - organization: 'ABC' - }) - - const projects: Project[] | ErrorMessage = await getProjects() - - if (Array.isArray(projects)) { - console.log(projects[0]) - console.log(`${projects.length} Prpjects found`) - } - else console.log(projects) -} - -test() \ No newline at end of file diff --git a/src/test/useCaseTests/getUserTests.ts b/src/test/useCaseTests/getUserTests.ts deleted file mode 100644 index bec32db..0000000 --- a/src/test/useCaseTests/getUserTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Harvest from "../../Entities/Harvest" -import getUser from '../../UseCases/getUser' -import env from '../env' - -async function test () { - new Harvest({ - accountId: env.accountId, - accessToken: env.accessToken, - organization: 'ABC' - }) - - const user = await getUser() - console.log(user) -} - -test() \ No newline at end of file