@dittowords/cli 4.4.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/.github/actions/install-node-dependencies/action.yml +24 -0
  2. package/.github/workflows/required-checks.yml +24 -0
  3. package/__mocks__/fs.js +2 -0
  4. package/bin/__mocks__/api.js +48 -0
  5. package/bin/__mocks__/api.js.map +1 -0
  6. package/bin/config.js +6 -4
  7. package/bin/config.js.map +1 -1
  8. package/bin/config.test.js +4 -3
  9. package/bin/config.test.js.map +1 -1
  10. package/bin/consts.js +19 -29
  11. package/bin/consts.js.map +1 -1
  12. package/bin/generate-suggestions.js +68 -58
  13. package/bin/generate-suggestions.js.map +1 -1
  14. package/bin/generate-suggestions.test.js +24 -13
  15. package/bin/generate-suggestions.test.js.map +1 -1
  16. package/bin/http/__mocks__/fetchComponentFolders.js +71 -0
  17. package/bin/http/__mocks__/fetchComponentFolders.js.map +1 -0
  18. package/bin/http/__mocks__/fetchComponents.js +73 -0
  19. package/bin/http/__mocks__/fetchComponents.js.map +1 -0
  20. package/bin/http/__mocks__/fetchVariants.js +71 -0
  21. package/bin/http/__mocks__/fetchVariants.js.map +1 -0
  22. package/bin/http/fetchComponentFolders.js +4 -4
  23. package/bin/http/fetchComponentFolders.js.map +1 -1
  24. package/bin/http/fetchComponents.js +4 -4
  25. package/bin/http/fetchComponents.js.map +1 -1
  26. package/bin/http/fetchVariants.js +2 -2
  27. package/bin/http/fetchVariants.js.map +1 -1
  28. package/bin/http/http.test.js +159 -0
  29. package/bin/http/http.test.js.map +1 -0
  30. package/bin/http/importComponents.js +9 -2
  31. package/bin/http/importComponents.js.map +1 -1
  32. package/bin/init/project.test.js +5 -28
  33. package/bin/init/project.test.js.map +1 -1
  34. package/bin/init/token.js +72 -27
  35. package/bin/init/token.js.map +1 -1
  36. package/bin/init/token.test.js +87 -9
  37. package/bin/init/token.test.js.map +1 -1
  38. package/bin/pull-lib.test.js +379 -0
  39. package/bin/pull-lib.test.js.map +1 -0
  40. package/bin/pull.js +13 -5
  41. package/bin/pull.js.map +1 -1
  42. package/bin/pull.test.js +100 -289
  43. package/bin/pull.test.js.map +1 -1
  44. package/bin/replace.js +22 -6
  45. package/bin/replace.js.map +1 -1
  46. package/bin/replace.test.js +53 -11
  47. package/bin/replace.test.js.map +1 -1
  48. package/bin/types.js +2 -2
  49. package/bin/types.js.map +1 -1
  50. package/bin/utils/determineModuleType.js +6 -7
  51. package/bin/utils/determineModuleType.js.map +1 -1
  52. package/bin/utils/determineModuleType.test.js +60 -0
  53. package/bin/utils/determineModuleType.test.js.map +1 -0
  54. package/bin/utils/getSelectedProjects.js +5 -5
  55. package/bin/utils/getSelectedProjects.js.map +1 -1
  56. package/bin/utils/quit.js +3 -3
  57. package/bin/utils/quit.js.map +1 -1
  58. package/jest.config.ts +16 -0
  59. package/lib/__mocks__/api.ts +12 -0
  60. package/lib/config.test.ts +3 -1
  61. package/lib/config.ts +4 -2
  62. package/lib/consts.ts +19 -17
  63. package/lib/generate-suggestions.test.ts +23 -11
  64. package/lib/generate-suggestions.ts +89 -79
  65. package/lib/http/__mocks__/fetchComponentFolders.ts +23 -0
  66. package/lib/http/__mocks__/fetchComponents.ts +24 -0
  67. package/lib/http/__mocks__/fetchVariants.ts +21 -0
  68. package/lib/http/fetchComponentFolders.ts +6 -4
  69. package/lib/http/fetchComponents.ts +5 -3
  70. package/lib/http/fetchVariants.ts +14 -3
  71. package/lib/http/http.test.ts +122 -0
  72. package/lib/http/importComponents.ts +8 -0
  73. package/lib/init/project.test.ts +4 -27
  74. package/lib/init/token.test.ts +55 -7
  75. package/lib/init/token.ts +76 -27
  76. package/lib/pull-lib.test.ts +367 -0
  77. package/lib/pull.test.ts +97 -310
  78. package/lib/pull.ts +11 -3
  79. package/lib/replace.test.ts +46 -10
  80. package/lib/replace.ts +20 -3
  81. package/lib/types.ts +5 -0
  82. package/lib/utils/determineModuleType.test.ts +48 -0
  83. package/lib/utils/determineModuleType.ts +4 -6
  84. package/lib/utils/getSelectedProjects.ts +3 -3
  85. package/lib/utils/quit.ts +1 -1
  86. package/package.json +4 -3
  87. package/jest.config.js +0 -6
@@ -1,4 +1,4 @@
1
- import fs from "fs-extra";
1
+ import fs from "fs";
2
2
  import glob from "glob";
3
3
  import { parse } from "@babel/parser";
4
4
  import traverse from "@babel/traverse";
@@ -43,11 +43,14 @@ async function generateSuggestions(flags: {
43
43
  console.log(JSON.stringify(results, null, 2));
44
44
  }
45
45
 
46
- async function findComponentsInJSXFiles(params: {
47
- directory: string;
48
- files?: string[];
49
- components: FetchComponentResponse;
50
- }): Promise<{ [apiId: string]: Result }> {
46
+ async function findComponentsInJSXFiles(
47
+ params: (
48
+ | { directory: string; files?: string[] }
49
+ | { files: string[]; directory?: string }
50
+ ) & {
51
+ components: FetchComponentResponse;
52
+ }
53
+ ): Promise<{ [apiId: string]: Result }> {
51
54
  const result: { [apiId: string]: Result } = {};
52
55
  const files =
53
56
  params.files ||
@@ -57,83 +60,90 @@ async function findComponentsInJSXFiles(params: {
57
60
 
58
61
  const promises: Promise<any>[] = [];
59
62
 
60
- for (const file of files) {
61
- promises.push(
62
- fs.readFile(file, "utf-8").then((code) => {
63
- const ast = parse(code, {
64
- sourceType: "module",
65
- plugins: ["jsx", "typescript"],
66
- });
67
-
68
- traverse(ast, {
69
- JSXText(path) {
70
- for (const [compApiId, component] of Object.entries(
71
- params.components,
72
- )) {
73
- // If we haven't seen this component before, add it to the result
74
- if (!result[compApiId]) {
75
- result[compApiId] = {
76
- apiId: compApiId,
77
- ...component,
78
- occurrences: {},
79
- };
80
- }
63
+ async function handleFile(file: string) {
64
+ const code = await new Promise<string>((resolve, reject) =>
65
+ fs.readFile(file, "utf-8", (err, data) => {
66
+ if (err) {
67
+ reject(err);
68
+ } else {
69
+ resolve(data);
70
+ }
71
+ })
72
+ );
73
+
74
+ const ast = parse(code, {
75
+ sourceType: "module",
76
+ plugins: ["jsx", "typescript"],
77
+ });
81
78
 
82
- if (
83
- // Skip white space lines
84
- !/^\s*$/.test(path.node.value) &&
85
- !/^\s*$/.test(component.text) &&
86
- path.node.value.includes(component.text)
87
- ) {
88
- // Escape all special characters from the text so we can use it in a regex
89
- const escapedText = component.text.replace(
90
- /[.*+?^${}()|[\]\\]/g,
91
- "\\$&",
92
- );
93
- const regex = new RegExp(escapedText, "g");
94
- let match;
95
- while ((match = regex.exec(path.node.value)) !== null) {
96
- const lines = path.node.value
97
- .slice(0, match.index)
98
- .split("\n");
99
-
100
- if (!path.node.loc) {
101
- continue;
102
- }
103
-
104
- const lineNumber =
105
- path.node.loc.start.line + lines.length - 1;
106
-
107
- const codeLines = code.split("\n");
108
- const line = codeLines[lineNumber - 1];
109
- const preview = replaceAt(
110
- line,
111
- match.index,
112
- component.text,
113
- `${component.text}`,
114
- );
115
-
116
- // Initialize the occurrences array if it doesn't exist
117
- if (!result[compApiId]["occurrences"][file]) {
118
- result[compApiId]["occurrences"][file] = [];
119
- }
120
-
121
- result[compApiId]["occurrences"][file].push({
122
- lineNumber,
123
- preview,
124
- });
125
- }
79
+ traverse(ast, {
80
+ JSXText(path) {
81
+ for (const [compApiId, component] of Object.entries(
82
+ params.components
83
+ )) {
84
+ // If we haven't seen this component before, add it to the result
85
+ if (!result[compApiId]) {
86
+ result[compApiId] = {
87
+ apiId: compApiId,
88
+ ...component,
89
+ occurrences: {},
90
+ };
91
+ }
92
+
93
+ if (
94
+ // Skip white space lines
95
+ !/^\s*$/.test(path.node.value) &&
96
+ !/^\s*$/.test(component.text) &&
97
+ path.node.value.includes(component.text)
98
+ ) {
99
+ // Escape all special characters from the text so we can use it in a regex
100
+ const escapedText = component.text.replace(
101
+ /[.*+?^${}()|[\]\\]/g,
102
+ "\\$&"
103
+ );
104
+ const regex = new RegExp(escapedText, "g");
105
+ let match;
106
+ while ((match = regex.exec(path.node.value)) !== null) {
107
+ const lines = path.node.value.slice(0, match.index).split("\n");
108
+
109
+ if (!path.node.loc) {
110
+ continue;
126
111
  }
127
112
 
128
- // Remove from result if no occurrences were found
129
- if (Object.keys(result[compApiId]["occurrences"]).length === 0) {
130
- delete result[compApiId];
113
+ const lineNumber = path.node.loc.start.line + lines.length - 1;
114
+
115
+ const codeLines = code.split("\n");
116
+ const line = codeLines[lineNumber - 1];
117
+ const preview = replaceAt(
118
+ line,
119
+ match.index,
120
+ component.text,
121
+ `${component.text}`
122
+ );
123
+
124
+ // Initialize the occurrences array if it doesn't exist
125
+ if (!result[compApiId]["occurrences"][file]) {
126
+ result[compApiId]["occurrences"][file] = [];
131
127
  }
128
+
129
+ result[compApiId]["occurrences"][file].push({
130
+ lineNumber,
131
+ preview,
132
+ });
132
133
  }
133
- },
134
- });
135
- }),
136
- );
134
+ }
135
+
136
+ // Remove from result if no occurrences were found
137
+ if (Object.keys(result[compApiId]["occurrences"]).length === 0) {
138
+ delete result[compApiId];
139
+ }
140
+ }
141
+ },
142
+ });
143
+ }
144
+
145
+ for (const file of files) {
146
+ promises.push(handleFile(file));
137
147
  }
138
148
 
139
149
  await Promise.all(promises);
@@ -145,7 +155,7 @@ function replaceAt(
145
155
  str: string,
146
156
  index: number,
147
157
  searchString: string,
148
- replacement: string,
158
+ replacement: string
149
159
  ) {
150
160
  return (
151
161
  str.substring(0, index) +
@@ -0,0 +1,23 @@
1
+ import type { FetchComponentFoldersResponse } from "../fetchComponentFolders";
2
+
3
+ export const MOCK_COMPONENT_FOLDERS: FetchComponentFoldersResponse = {
4
+ example_folder: "Example Folder",
5
+ };
6
+
7
+ export const MOCK_COMPONENT_FOLDERS_WITH_SAMPLE_DATA: FetchComponentFoldersResponse =
8
+ {
9
+ example_folder: "Example Folder",
10
+ example_folder_sample: "Sample Example Folder",
11
+ };
12
+
13
+ export async function fetchComponentFolders(
14
+ _options: {
15
+ showSampleData?: boolean;
16
+ } = {}
17
+ ): Promise<FetchComponentFoldersResponse> {
18
+ if (_options.showSampleData) {
19
+ return MOCK_COMPONENT_FOLDERS_WITH_SAMPLE_DATA;
20
+ }
21
+
22
+ return MOCK_COMPONENT_FOLDERS;
23
+ }
@@ -0,0 +1,24 @@
1
+ import { FetchComponentResponse } from "../fetchComponents";
2
+
3
+ export const MOCK_COMPONENTS_RESPONSE: FetchComponentResponse = {
4
+ "component-1": {
5
+ name: "Example Component 1",
6
+ text: "This is example component text.",
7
+ status: "NONE",
8
+ folder: null,
9
+ },
10
+ "component-2": {
11
+ name: "Example Component 2",
12
+ text: "This is example component text.",
13
+ status: "NONE",
14
+ folder: null,
15
+ },
16
+ };
17
+
18
+ export async function fetchComponents(
19
+ _options: {
20
+ componentFolder?: string;
21
+ } = {}
22
+ ): Promise<FetchComponentResponse> {
23
+ return MOCK_COMPONENTS_RESPONSE;
24
+ }
@@ -0,0 +1,21 @@
1
+ import { IVariant } from "../fetchVariants";
2
+
3
+ export const MOCK_VARIANTS_RESPONSE: IVariant[] = [
4
+ {
5
+ name: "Example Variant 1",
6
+ description: "This is example variant 1.",
7
+ apiID: "example-variant-1",
8
+ },
9
+ {
10
+ name: "Example Variant 2",
11
+ description: "This is example variant 2.",
12
+ apiID: "example-variant-2",
13
+ },
14
+ ];
15
+
16
+ export async function fetchVariants(
17
+ _source: any,
18
+ _options: any = {}
19
+ ): Promise<IVariant[] | null> {
20
+ return MOCK_VARIANTS_RESPONSE;
21
+ }
@@ -1,12 +1,14 @@
1
1
  import { createApiClient } from "../api";
2
2
 
3
- interface FetchComponentFoldersResponse {
3
+ export interface FetchComponentFoldersResponse {
4
4
  [id: string]: string;
5
5
  }
6
6
 
7
- export async function fetchComponentFolders(options: {
8
- showSampleData?: boolean;
9
- }): Promise<FetchComponentFoldersResponse> {
7
+ export async function fetchComponentFolders(
8
+ options: {
9
+ showSampleData?: boolean;
10
+ } = {}
11
+ ): Promise<FetchComponentFoldersResponse> {
10
12
  const api = createApiClient();
11
13
 
12
14
  let url = "/v1/component-folders";
@@ -11,9 +11,11 @@ export interface FetchComponentResponse {
11
11
  [compApiId: string]: FetchComponentResponseComponent;
12
12
  }
13
13
 
14
- export async function fetchComponents(options: {
15
- componentFolder?: string;
16
- }): Promise<FetchComponentResponse> {
14
+ export async function fetchComponents(
15
+ options: {
16
+ componentFolder?: string;
17
+ } = {}
18
+ ): Promise<FetchComponentResponse> {
17
19
  const api = createApiClient();
18
20
 
19
21
  if (options.componentFolder) {
@@ -3,10 +3,21 @@ import { createApiClient } from "../api";
3
3
  import { PullOptions } from "../pull";
4
4
  import { SourceInformation } from "../types";
5
5
 
6
+ export interface IVariant {
7
+ name: string;
8
+ description: string;
9
+ apiID: string;
10
+ }
11
+
12
+ type SourceArg = Pick<
13
+ SourceInformation,
14
+ "shouldFetchComponentLibrary" | "validProjects" | "variants"
15
+ >;
16
+
6
17
  export async function fetchVariants(
7
- source: SourceInformation,
18
+ source: SourceArg,
8
19
  options: PullOptions = {}
9
- ) {
20
+ ): Promise<IVariant[] | null> {
10
21
  const api = createApiClient();
11
22
  if (!source.variants) {
12
23
  return null;
@@ -25,7 +36,7 @@ export async function fetchVariants(
25
36
  config.params.projectIds = validProjects.map(({ id }) => id);
26
37
  }
27
38
 
28
- const { data } = await api.get<{ apiID: string }[]>("/v1/variants", config);
39
+ const { data } = await api.get<IVariant[]>("/v1/variants", config);
29
40
 
30
41
  return data;
31
42
  }
@@ -0,0 +1,122 @@
1
+ import { fetchComponentFolders } from "./fetchComponentFolders";
2
+ import { fetchComponents } from "./fetchComponents";
3
+ import { fetchVariants } from "./fetchVariants";
4
+ import { importComponents } from "./importComponents";
5
+ import { jest } from "@jest/globals";
6
+ import axios from "axios";
7
+ import { vol } from "memfs";
8
+
9
+ jest.mock("../api");
10
+ jest.mock("fs");
11
+
12
+ const axiosMocked = jest.mocked(axios);
13
+
14
+ describe("fetchComponentFolders", () => {
15
+ it("fetches component folders without error", async () => {
16
+ axiosMocked.get.mockResolvedValueOnce({
17
+ data: { "folder-id": "folder-name" },
18
+ });
19
+ const result = await fetchComponentFolders();
20
+ expect(result["folder-id"]).toBe("folder-name");
21
+ });
22
+ it("supports showSampleData option", async () => {
23
+ axiosMocked.get.mockResolvedValueOnce({
24
+ data: { "folder-id": "folder-name" },
25
+ });
26
+ const result = await fetchComponentFolders({ showSampleData: true });
27
+ expect(result["folder-id"]).toBe("folder-name");
28
+ });
29
+ });
30
+
31
+ describe("fetchComponents", () => {
32
+ it("fetches components without error", async () => {
33
+ axiosMocked.get.mockResolvedValueOnce({
34
+ data: {
35
+ "component-id": {
36
+ name: "component-name",
37
+ text: "component-text",
38
+ status: "NONE",
39
+ folder: null,
40
+ },
41
+ },
42
+ });
43
+ const result = await fetchComponents();
44
+ expect(result["component-id"]).toBeDefined();
45
+ expect(result["component-id"].name).toBe("component-name");
46
+ expect(result["component-id"].text).toBe("component-text");
47
+ });
48
+ });
49
+
50
+ describe("fetchVariants", () => {
51
+ it("fetches variants without error", async () => {
52
+ axiosMocked.get.mockResolvedValueOnce({
53
+ data: [
54
+ {
55
+ name: "variant-name",
56
+ description: "variant-description",
57
+ apiID: "variant-api-id",
58
+ },
59
+ ],
60
+ });
61
+ const result = await fetchVariants({
62
+ shouldFetchComponentLibrary: true,
63
+ validProjects: [],
64
+ variants: true,
65
+ });
66
+ expect(result).toBeTruthy();
67
+ expect(result![0]).toBeDefined();
68
+ expect(result![0].name).toBe("variant-name");
69
+ expect(result![0].description).toBe("variant-description");
70
+ expect(result![0].apiID).toBe("variant-api-id");
71
+ });
72
+ it("returns null if `variants` isn't in config", async () => {
73
+ const result = await fetchVariants({
74
+ shouldFetchComponentLibrary: true,
75
+ validProjects: [],
76
+ variants: false,
77
+ });
78
+ expect(result).toBe(null);
79
+ });
80
+ });
81
+
82
+ describe("importComponents", () => {
83
+ beforeEach(() => {
84
+ vol.reset();
85
+ });
86
+ it("imports components from existing file without error", async () => {
87
+ vol.fromJSON({
88
+ "/file.csv": "id,name,text\n1,one1,not empty\n2,two1,empty",
89
+ });
90
+
91
+ axiosMocked.mockResolvedValueOnce({
92
+ data: {
93
+ componentsInserted: 2,
94
+ firstImportedId: "1",
95
+ },
96
+ });
97
+
98
+ const result = await importComponents("/file.csv", {
99
+ csvColumnMapping: {
100
+ name: "name",
101
+ text: 2,
102
+ componentId: 0,
103
+ },
104
+ });
105
+
106
+ expect(result.componentsInserted).toBe(2);
107
+ expect(result.firstImportedId).toBe("1");
108
+ });
109
+
110
+ it("returns null firstImportedId if file doesn't exist", async () => {
111
+ const result = await importComponents("/file.csv", {
112
+ csvColumnMapping: {
113
+ name: "name",
114
+ text: 2,
115
+ componentId: 0,
116
+ },
117
+ });
118
+
119
+ expect(result.componentsInserted).toBe(0);
120
+ expect(result.firstImportedId).toBe("null");
121
+ });
122
+ });
@@ -24,6 +24,14 @@ export async function importComponents(
24
24
  ): Promise<ImportComponentResponse> {
25
25
  const api = createApiClient();
26
26
 
27
+ if (!fs.existsSync(path)) {
28
+ console.error("Failed to import file: couldn't find file at path " + path);
29
+ return {
30
+ componentsInserted: 0,
31
+ firstImportedId: "null",
32
+ };
33
+ }
34
+
27
35
  const form = new FormData();
28
36
  form.append("import", fs.createReadStream(path));
29
37
 
@@ -1,44 +1,21 @@
1
1
  const fs = require("fs");
2
- const path = require("path");
3
-
4
2
  const yaml = require("js-yaml");
5
- const { createFileIfMissing } = require("../config");
6
3
 
7
4
  import { _testing } from "./project";
8
5
 
9
- const fakeProjectDir = path.join(__dirname, "../../testing/tmp");
10
- const badYaml = path.join(__dirname, "../../testing/fixtures/bad-yaml.yml");
11
- const configEmptyProjects = path.join(
12
- __dirname,
13
- "../../testing/fixtures/bad-yaml.yml"
14
- );
15
- const configMissingName = path.join(
16
- __dirname,
17
- "../../testing/fixtures/project-config-no-name.yml"
18
- );
19
- const configMissingId = path.join(
20
- __dirname,
21
- "../../testing/fixtures/project-config-no-id.yml"
22
- );
23
- const configLegit = path.join(
24
- __dirname,
25
- "../../testing/fixtures/project-config-working.yml"
26
- );
6
+ const fakeProjectDir = "/";
7
+
8
+ jest.mock("fs");
27
9
 
28
10
  describe("saveProject", () => {
29
- const configFile = path.join(fakeProjectDir, "ditto/config.yml");
11
+ const configFile = "/ditto/config.yml";
30
12
  const projectName = "My Amazing Project";
31
13
  const projectId = "5f284259ce1d451b2eb2e23c";
32
14
 
33
15
  beforeEach(() => {
34
- if (!fs.existsSync(fakeProjectDir)) fs.mkdirSync(fakeProjectDir);
35
16
  _testing.saveProject(configFile, projectName, projectId);
36
17
  });
37
18
 
38
- afterEach(() => {
39
- fs.rmdirSync(fakeProjectDir, { recursive: true });
40
- });
41
-
42
19
  it("creates a config file with config data", () => {
43
20
  const fileContents = fs.readFileSync(configFile, "utf8");
44
21
  const data = yaml.load(fileContents);
@@ -1,22 +1,51 @@
1
- import tempy from "tempy";
2
-
1
+ import fs from "fs";
3
2
  import config from "../config";
3
+ import { randomUUID } from "crypto";
4
4
  import { needsToken } from "./token";
5
+ import { _test } from "./token";
6
+ import { vol } from "memfs";
7
+ import { jest } from "@jest/globals";
8
+ import axios from "axios";
9
+
10
+ jest.mock("fs");
11
+ jest.mock("../api");
12
+
13
+ const axiosMocked = jest.mocked(axios);
14
+
15
+ const defaultEnv = { ...process.env };
5
16
 
6
- describe("needsToken()", () => {
17
+ beforeEach(() => {
18
+ vol.reset();
19
+ process.env = { ...defaultEnv };
20
+ });
21
+
22
+ describe("needsToken", () => {
7
23
  it("is true if there is no config file", () => {
8
- expect(needsToken(tempy.file())).toBeTruthy();
24
+ expect(needsToken(randomUUID())).toBeTruthy();
25
+ });
26
+
27
+ it("is false if there is a token in the environment", () => {
28
+ process.env.DITTO_API_KEY = "xxx-xxx-xxx";
29
+ expect(needsToken(randomUUID())).toBe(false);
9
30
  });
10
31
 
11
32
  describe("with a config file", () => {
12
33
  let configFile = "";
13
34
 
14
- beforeEach(() => {
15
- configFile = tempy.writeSync("");
35
+ beforeEach(async () => {
36
+ configFile = `/${randomUUID()}`;
37
+ await new Promise((resolve, reject) =>
38
+ fs.writeFile(configFile, "", (err) => {
39
+ if (err) reject(err);
40
+ else {
41
+ resolve(null);
42
+ }
43
+ })
44
+ );
16
45
  });
17
46
 
18
47
  it("returns true if empty", () => {
19
- expect(needsToken(configFile, "testing.dittowrods.com")).toBeTruthy();
48
+ expect(needsToken(configFile, "testing.dittowords.com")).toBeTruthy();
20
49
  });
21
50
 
22
51
  describe("with some data", () => {
@@ -49,3 +78,22 @@ describe("needsToken()", () => {
49
78
  });
50
79
  });
51
80
  });
81
+
82
+ const { verifyTokenUsingTokenCheck } = _test;
83
+ describe("verifyTokenUsingTokenCheck", () => {
84
+ it("returns success: true for api success response", async () => {
85
+ axiosMocked.get.mockResolvedValueOnce({ status: 200 });
86
+ const result = await verifyTokenUsingTokenCheck("xxx-xxx");
87
+ expect(result.success).toBe(true);
88
+ });
89
+ it("returns success: false for api unauthorized response", async () => {
90
+ axiosMocked.get.mockResolvedValueOnce({ status: 401 });
91
+ const result = await verifyTokenUsingTokenCheck("xxx-xxx");
92
+ expect(result.success).toBe(false);
93
+ });
94
+ it("returns success: false for api invalid response", async () => {
95
+ axiosMocked.get.mockResolvedValueOnce("error");
96
+ const result = await verifyTokenUsingTokenCheck("xxx-xxx");
97
+ expect(result.success).toBe(false);
98
+ });
99
+ });