@insignia-education/api-sdk-js 0.15.60 → 0.15.62

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 (86) hide show
  1. package/.github/workflows/npm-publish-github-packages.yml +95 -12
  2. package/coverage/clover.xml +578 -566
  3. package/coverage/coverage-final.json +45 -47
  4. package/coverage/lcov-report/Client.js.html +463 -0
  5. package/coverage/lcov-report/index.html +33 -33
  6. package/coverage/lcov-report/src/Client.js.html +141 -132
  7. package/coverage/lcov-report/src/api/index.html +1 -1
  8. package/coverage/lcov-report/src/api/index.js.html +8 -8
  9. package/coverage/lcov-report/src/api/v1/Accounts.js.html +3 -3
  10. package/coverage/lcov-report/src/api/v1/Admin.js.html +3 -3
  11. package/coverage/lcov-report/src/api/v1/Auth.js.html +7 -7
  12. package/coverage/lcov-report/src/api/v1/Categories.js.html +8 -8
  13. package/coverage/lcov-report/src/api/v1/Changelogs.js.html +8 -8
  14. package/coverage/lcov-report/src/api/v1/Configs.js.html +8 -8
  15. package/coverage/lcov-report/src/api/v1/ContactForms.js.html +8 -8
  16. package/coverage/lcov-report/src/api/v1/ConversationalTopics.js.html +8 -8
  17. package/coverage/lcov-report/src/api/v1/Countries.js.html +8 -8
  18. package/coverage/lcov-report/src/api/v1/Coupons.js.html +16 -16
  19. package/coverage/lcov-report/src/api/v1/Courses.js.html +27 -27
  20. package/coverage/lcov-report/src/api/v1/Currencies.js.html +10 -10
  21. package/coverage/lcov-report/src/api/v1/Dashboard.js.html +3 -3
  22. package/coverage/lcov-report/src/api/v1/EducationCenter.js.html +3 -3
  23. package/coverage/lcov-report/src/api/v1/Employee.js.html +5 -5
  24. package/coverage/lcov-report/src/api/v1/Files.js.html +8 -8
  25. package/coverage/lcov-report/src/api/v1/Forums.js.html +8 -8
  26. package/coverage/lcov-report/src/api/v1/Hashes.js.html +16 -13
  27. package/coverage/lcov-report/src/api/v1/Insignias.js.html +8 -8
  28. package/coverage/lcov-report/src/api/v1/Languages.js.html +8 -8
  29. package/coverage/lcov-report/src/api/v1/MailBlacklist.js.html +8 -8
  30. package/coverage/lcov-report/src/api/v1/MailingLists.js.html +3 -3
  31. package/coverage/lcov-report/src/api/v1/Offers.js.html +16 -16
  32. package/coverage/lcov-report/src/api/v1/Organizations.js.html +52 -52
  33. package/coverage/lcov-report/src/api/v1/PaymentMethods.js.html +7 -7
  34. package/coverage/lcov-report/src/api/v1/Payments.js.html +3 -3
  35. package/coverage/lcov-report/src/api/v1/Premiums.js.html +3 -3
  36. package/coverage/lcov-report/src/api/v1/Quizzes.js.html +42 -42
  37. package/coverage/lcov-report/src/api/v1/Sales.js.html +3 -3
  38. package/coverage/lcov-report/src/api/v1/Search.js.html +3 -3
  39. package/coverage/lcov-report/src/api/v1/ShortLinks.js.html +8 -8
  40. package/coverage/lcov-report/src/api/v1/Surveys.js.html +8 -8
  41. package/coverage/lcov-report/src/api/v1/Taxes.js.html +8 -8
  42. package/coverage/lcov-report/src/api/v1/Teacher.js.html +100 -70
  43. package/coverage/lcov-report/src/api/v1/Telegram.js.html +3 -3
  44. package/coverage/lcov-report/src/api/v1/TwoFactor.js.html +3 -3
  45. package/coverage/lcov-report/src/api/v1/UserSessionTypes.js.html +3 -3
  46. package/coverage/lcov-report/src/api/v1/UserTypes.js.html +8 -8
  47. package/coverage/lcov-report/src/api/v1/Users.js.html +112 -16
  48. package/coverage/lcov-report/src/api/v1/Utm.js.html +3 -3
  49. package/coverage/lcov-report/src/api/v1/Webauthn.js.html +3 -3
  50. package/coverage/lcov-report/src/api/v1/Zoom.js.html +19 -19
  51. package/coverage/lcov-report/src/api/v1/index.html +154 -184
  52. package/coverage/lcov-report/src/api/v1/index.js.html +52 -64
  53. package/coverage/lcov-report/src/index.html +21 -21
  54. package/coverage/lcov-report/src/index.js.html +3 -3
  55. package/coverage/lcov-report/tests/helpers.js.html +11 -11
  56. package/coverage/lcov-report/tests/index.html +7 -7
  57. package/coverage/lcov.info +990 -879
  58. package/coverage/test-report.html +586 -10
  59. package/jest.config.mjs +12 -1
  60. package/package.json +2 -2
  61. package/src/Client.js +4 -1
  62. package/src/api/v1/Coupons.js +11 -0
  63. package/src/api/v1/Hashes.js +3 -2
  64. package/src/api/v1/index.js +0 -4
  65. package/tests/integration/api/v1/accounts.test.js +5 -11
  66. package/tests/integration/api/v1/auth/login.test.js +18 -34
  67. package/tests/integration/api/v1/conversational-topics.test.js +3 -5
  68. package/tests/integration/api/v1/countries.test.js +1 -1
  69. package/tests/integration/api/v1/coupons.test.js +2 -9
  70. package/tests/integration/api/v1/currencies/index.test.js +1 -1
  71. package/tests/integration/api/v1/files.test.js +18 -15
  72. package/tests/integration/api/v1/hashes.test.js +2 -10
  73. package/tests/integration/api/v1/mail-blacklist.test.js +2 -9
  74. package/tests/integration/api/v1/offers.test.js +2 -9
  75. package/tests/integration/api/v1/organizations.test.js +8 -8
  76. package/tests/integration/api/v1/quizzes/index.test.js +0 -2
  77. package/tests/integration/api/v1/short-links.test.js +2 -9
  78. package/tests/integration/api/v1/taxes.test.js +2 -3
  79. package/tests/integration/api/v1/teacher/index.test.js +1 -1
  80. package/tests/integration/api/v1/user-types.test.js +2 -4
  81. package/tests/integration/api/v1/users/index.test.js +10 -13
  82. package/tests/integration/api/v1/zoom.test.js +2 -9
  83. package/src/api/v1/Categories.js +0 -12
  84. package/src/api/v1/Configs.js +0 -12
  85. package/tests/integration/api/v1/categories.test.js +0 -19
  86. package/tests/integration/api/v1/configs.test.js +0 -20
package/jest.config.mjs CHANGED
@@ -14,6 +14,14 @@ const config = {
14
14
  }],
15
15
  ],
16
16
 
17
+ // Run via `npm test`, which invokes unit and integration as two separate
18
+ // `jest --selectProjects` calls (integration also with --runInBand)
19
+ // rather than one combined parallel run: Jest has a multi-project quirk
20
+ // where a later project's tests can silently fall back to the global
21
+ // 5000ms default instead of this project's own testTimeout when both
22
+ // projects run together in one process, and integration tests hit a
23
+ // single-threaded `php artisan serve` backend that serializes requests
24
+ // anyway — parallel workers just queue up and time out against it.
17
25
  projects: [
18
26
  {
19
27
  displayName: 'unit',
@@ -28,7 +36,10 @@ const config = {
28
36
  testMatch: ['<rootDir>/tests/integration/**/*.test.js'],
29
37
  transform: { '^.+\\.(js|jsx)$': 'babel-jest' },
30
38
  setupFiles: ['<rootDir>/tests/integration/loadEnv.js'],
31
- testTimeout: 30000,
39
+ // Generous — amd64 emulation (api-sdk-js's Docker test env on
40
+ // Apple Silicon) occasionally makes an individual request take
41
+ // 10-20s+ under CPU contention.
42
+ testTimeout: 60000,
32
43
  },
33
44
  ],
34
45
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insignia-education/api-sdk-js",
3
- "version": "0.15.60",
3
+ "version": "0.15.62",
4
4
  "description": "JavaScript SDK for the Insignia Education API",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -10,7 +10,7 @@
10
10
  "./api/v1": "./src/api/v1/index.js"
11
11
  },
12
12
  "scripts": {
13
- "test": "jest",
13
+ "test": "jest --selectProjects unit && jest --selectProjects integration --runInBand --testTimeout=60000",
14
14
  "lint": "eslint src/"
15
15
  },
16
16
  "repository": {
package/src/Client.js CHANGED
@@ -93,8 +93,11 @@ export default class InsigniaClient {
93
93
  if (this.#baseUrl.includes('ngrok')) headers['ngrok-skip-browser-warning'] = 'true';
94
94
  const cookie = this.#cookieHeader();
95
95
  if (cookie) headers.Cookie = cookie;
96
+ // POST, not PUT: PHP only parses multipart/form-data bodies into $_FILES for
97
+ // POST requests — a PUT with the exact same body leaves $_FILES empty and the
98
+ // raw body unread, so `$request->file(...)` is always null server-side.
96
99
  const response = await fetch(`${this.#baseUrl}${path}`, {
97
- method: 'PUT', headers, credentials: 'include', body: formData,
100
+ method: 'POST', headers, credentials: 'include', body: formData,
98
101
  });
99
102
  this.#storeCookies(response);
100
103
  if (!response.ok) {
@@ -16,4 +16,15 @@ export default class Coupons {
16
16
 
17
17
  /** Employee/sales-only: usage stats + full redemption history for one coupon. */
18
18
  stats(id) { return this.#client.get(`/coupons/${id}/stats`); }
19
+
20
+ /** Users explicitly granted access to redeem this coupon. */
21
+ users(id) {
22
+ const base = `/coupons/${id}/users`;
23
+ const client = this.#client;
24
+ return {
25
+ get: () => client.get(base),
26
+ add: ({ email, reason }) => client.put(base, { email, reason }),
27
+ remove: (userId) => client.del(`${base}/${userId}`),
28
+ };
29
+ }
19
30
  }
@@ -1,3 +1,6 @@
1
+ // Read-only — hashes (password-reset/verify/phantom-login tokens etc.) are
2
+ // created and deleted exclusively by their owning flows (forgot-password,
3
+ // email-verify, admin phantom-login), never through a generic public API.
1
4
  export default class Hashes {
2
5
  #client;
3
6
 
@@ -6,6 +9,4 @@ export default class Hashes {
6
9
  }
7
10
 
8
11
  get(id = null) { return id ? this.#client.get(`/hashes/${id}`) : this.#client.get('/hashes'); }
9
- generate(data) { return this.#client.put('/hashes/generate', data); }
10
- delete(id) { return this.#client.del(`/hashes/${id}`); }
11
12
  }
@@ -2,9 +2,7 @@ import InsigniaApi from '../index.js';
2
2
  import Admin from './Admin.js';
3
3
  import Auth from './Auth.js';
4
4
  import Accounts from './Accounts.js';
5
- import Categories from './Categories.js';
6
5
  import Changelogs from './Changelogs.js';
7
- import Configs from './Configs.js';
8
6
  import ContactForms from './ContactForms.js';
9
7
  import ConversationalTopics from './ConversationalTopics.js';
10
8
  import Countries from './Countries.js';
@@ -57,9 +55,7 @@ export default class InsigniaApiV1 extends InsigniaApi {
57
55
  this.admin = new Admin(this);
58
56
  this.auth = new Auth(this);
59
57
  this.accounts = new Accounts(this);
60
- this.categories = new Categories(this);
61
58
  this.changelogs = new Changelogs(this);
62
- this.configs = new Configs(this);
63
59
  this.contactForms = new ContactForms(this);
64
60
  this.conversationalTopics = new ConversationalTopics(this);
65
61
  this.countries = new Countries(this);
@@ -5,21 +5,15 @@ import {
5
5
  } from '../../../helpers.js';
6
6
 
7
7
  describe('api/v1/accounts', () => {
8
+ // Client#request() throws on non-2xx (err.status, err.data) rather than
9
+ // resolving — assert against a rejected promise, not a resolved
10
+ // {success, status}.
8
11
  test('get | unauthenticated', async () => {
9
- await api.accounts.get()
10
- .then(response => {
11
- expect(response.success).toBe(false);
12
- expect(response.status).toBe(401);
13
- });
12
+ await expect(api.accounts.get()).rejects.toMatchObject({ status: 401 });
14
13
  });
15
14
  test('get | authenticated but other type', async () => {
16
15
  await loginCustomer();
17
- await api.accounts.get()
18
- .then(response => {
19
- console.log(response);
20
- expect(response.success).toBe(false);
21
- expect(response.status).toBe(403);
22
- });
16
+ await expect(api.accounts.get()).rejects.toMatchObject({ status: 403 });
23
17
  });
24
18
  test('get | authenticated', async () => {
25
19
  await loginAdmin();
@@ -1,56 +1,40 @@
1
- import {
2
- api,
3
- loginCustomer,
1
+ import {
2
+ api,
4
3
  loginAdmin,
5
- logout,
6
4
  } from '../../../../helpers.js';
7
5
 
8
-
9
-
10
-
11
6
  describe('api/v1/auth/login', () => {
7
+ // Client#request() throws on non-2xx (err.status, err.data) rather than
8
+ // resolving — assert against a rejected promise, not a resolved
9
+ // {success, status, errors}. Also no logout() before these — a fresh
10
+ // `api` client (one per test file) starts out unauthenticated, and
11
+ // logout() itself throws 401 when there's no session to clear.
12
12
  test('POST | failure | no email validation', async () => {
13
13
  const password = process.env.TEST_PASSWORD;
14
- logout()
15
- .then(() => api.auth.login({ password })
16
- .then(response => {
17
- // here we have more info of the request because we have the errors
18
- expect(response["success"]).toBeDefined();
19
- expect(response["status"]).toBeDefined();
20
- expect(response["status"]).toBe(422);
21
- expect(response["errors"]).toBeDefined();
22
- expect(Object.values(response["errors"]).length > 0).toBe(true);
23
- expect(response["errors"]["email"]).toBeDefined();
24
- }));
14
+ await expect(api.auth.login({ password })).rejects.toMatchObject({
15
+ status: 422,
16
+ data: { errors: expect.objectContaining({ email: expect.anything() }) },
17
+ });
25
18
  });
26
19
 
27
20
  test('POST | failure | no password validation', async () => {
28
21
  const email = process.env.TEST_EMAIL;
29
- logout()
30
- .then(() => api.auth.login({ email })
31
- .then(response => {
32
- // here we have more info of the request because we have the errors
33
- expect(response["success"]).toBeDefined();
34
- expect(response["errors"]).toBeDefined();
35
- expect(response["status"]).toBeDefined();
36
- expect(response["status"]).toBe(422);
37
- expect(Object.values(response["errors"]).length > 0).toBe(true);
38
- expect(response["errors"]["password"]).toBeDefined();
39
- }));
40
-
22
+ await expect(api.auth.login({ email })).rejects.toMatchObject({
23
+ status: 422,
24
+ data: { errors: expect.objectContaining({ password: expect.anything() }) },
25
+ });
41
26
  });
42
27
 
43
28
  test('POST | success', async () => {
44
- logout()
45
- .then(() => loginAdmin()
29
+ await loginAdmin()
46
30
  .then(response => {
47
31
  expect(response["success"]).toBeDefined();
48
32
  expect(response["success"]).toBe("ok");
49
- }));
33
+ });
50
34
  });
51
35
 
52
36
  test('POST | double login', async () => {
53
- loginAdmin()
37
+ await loginAdmin()
54
38
  .then(() => loginAdmin()
55
39
  .then(response => {
56
40
  expect(response["success"]).toBeDefined();
@@ -1,18 +1,16 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
1
+ import { api, loginAdmin } from '../../../helpers.js';
4
2
 
5
3
  describe('api/v1/conversational-topics', () => {
6
4
  test('get', async () => {
5
+ await loginAdmin();
7
6
  await api.conversationalTopics.get()
8
7
  .then(response => {
9
8
  response = Object.values(response);
10
9
  expect(response.length > 0).toBe(true);
11
10
  response.forEach(topic => {
12
11
  expect(topic["id"]).toBeDefined();
13
- expect(topic["cod"]).toBeDefined();
14
12
  expect(topic["title"]).toBeDefined();
15
- expect(topic["enabled"]).toBeDefined();
13
+ expect(topic["date"]).toBeDefined();
16
14
  });
17
15
  });
18
16
  });
@@ -5,7 +5,7 @@ const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
5
5
 
6
6
  describe('api/v1/countries', () => {
7
7
  test('get', async () => {
8
- api.countries.get()
8
+ await api.countries.get()
9
9
  .then(response => {
10
10
  response = Object.values(response);
11
11
  expect(response.length > 0).toBe(true);
@@ -1,15 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
4
-
5
- const login = () => api.auth.login({
6
- email: process.env.TEST_EMAIL,
7
- password: process.env.TEST_PASSWORD,
8
- });
1
+ import { api, loginAdmin } from '../../../helpers.js';
9
2
 
10
3
  describe('api/v1/coupons', () => {
11
4
  test('get | authenticated', async () => {
12
- await login();
5
+ await loginAdmin();
13
6
  await api.coupons.get()
14
7
  .then(response => {
15
8
  response = Object.values(response);
@@ -6,7 +6,7 @@ import {
6
6
 
7
7
  describe('api/v1/currencies', () => {
8
8
  test('get', async () => {
9
- api.currencies.get()
9
+ await api.currencies.get()
10
10
  .then(response => {
11
11
  expect(response["1"]).toBeDefined();
12
12
  expect(response["1"]["id"]).toBeDefined();
@@ -1,21 +1,24 @@
1
1
  import { Blob } from 'buffer';
2
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
+ import { api, loginAdmin } from '../../../helpers.js';
3
3
 
4
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
5
-
6
- const login = () => api.auth.login({
7
- email: process.env.TEST_EMAIL,
8
- password: process.env.TEST_PASSWORD,
9
- });
4
+ // A real 1x1 transparent PNG (67 bytes) — the upload endpoint sniffs actual
5
+ // file content, not just the claimed Content-Type, so arbitrary text with an
6
+ // 'image/png' MIME hint gets rejected with "Unsupported file type".
7
+ const PNG_1X1 = Buffer.from(
8
+ 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=',
9
+ 'base64'
10
+ );
10
11
 
11
12
  describe('api/v1/files', () => {
12
- test('get | authenticated', async () => {
13
- await login();
14
- await api.files.get()
13
+ // list() (paginated), not get() — get(id) requires an id and hits
14
+ // /files/{id}, unlike most other resources' get(id = null).
15
+ test('list | authenticated', async () => {
16
+ await loginAdmin();
17
+ await api.files.list()
15
18
  .then(response => {
16
- response = Object.values(response);
17
- expect(Array.isArray(response)).toBe(true);
18
- response.forEach(file => {
19
+ const files = response["data"];
20
+ expect(Array.isArray(files)).toBe(true);
21
+ files.forEach(file => {
19
22
  expect(file["id"]).toBeDefined();
20
23
  expect(file["created_at"]).toBeDefined();
21
24
  expect(file["updated_at"]).toBeDefined();
@@ -24,8 +27,8 @@ describe('api/v1/files', () => {
24
27
  });
25
28
 
26
29
  test('upload | authenticated', async () => {
27
- await login();
28
- const blob = new Blob(['test'], { type: 'image/png' });
30
+ await loginAdmin();
31
+ const blob = new Blob([PNG_1X1], { type: 'image/png' });
29
32
  const fd = new FormData();
30
33
  fd.append('file', blob, 'test.png');
31
34
  fd.append('type', 'uploads');
@@ -1,15 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
4
-
5
- const login = () => api.auth.login({
6
- email: process.env.TEST_EMAIL,
7
- password: process.env.TEST_PASSWORD,
8
- });
1
+ import { api, loginAdmin } from '../../../helpers.js';
9
2
 
10
3
  describe('api/v1/hashes', () => {
11
4
  test('get | authenticated', async () => {
12
- await login();
5
+ await loginAdmin();
13
6
  await api.hashes.get()
14
7
  .then(response => {
15
8
  response = Object.values(response);
@@ -17,7 +10,6 @@ describe('api/v1/hashes', () => {
17
10
  response.forEach(hash => {
18
11
  expect(hash["id"]).toBeDefined();
19
12
  expect(hash["hash"]).toBeDefined();
20
- expect(hash["purpose_id"]).toBeDefined();
21
13
  expect(hash["created_at"]).toBeDefined();
22
14
  expect(hash["updated_at"]).toBeDefined();
23
15
  });
@@ -1,15 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
4
-
5
- const login = () => api.auth.login({
6
- email: process.env.TEST_EMAIL,
7
- password: process.env.TEST_PASSWORD,
8
- });
1
+ import { api, loginAdmin } from '../../../helpers.js';
9
2
 
10
3
  describe('api/v1/mail-blacklist', () => {
11
4
  test('get | authenticated', async () => {
12
- await login();
5
+ await loginAdmin();
13
6
  await api.mailBlacklist.get()
14
7
  .then(response => {
15
8
  response = Object.values(response);
@@ -1,15 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
4
-
5
- const login = () => api.auth.login({
6
- email: process.env.TEST_EMAIL,
7
- password: process.env.TEST_PASSWORD,
8
- });
1
+ import { api, loginAdmin } from '../../../helpers.js';
9
2
 
10
3
  describe('api/v1/offers', () => {
11
4
  test('get | authenticated', async () => {
12
- await login();
5
+ await loginAdmin();
13
6
  await api.offers.get()
14
7
  .then(response => {
15
8
  response = Object.values(response);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  api,
3
- loginCustomer,
3
+ loginAdmin,
4
4
  logout,
5
5
  } from '../../../helpers.js';
6
6
 
@@ -17,7 +17,7 @@ describe('api/v1/organizations', () => {
17
17
  });
18
18
 
19
19
  test('create | employee-and-above', async () => {
20
- await loginCustomer();
20
+ await loginAdmin();
21
21
  const response = await api.organizations.create({ nice_name: 'SDK Test Org' });
22
22
  expect(response["id"]).toBeDefined();
23
23
  expect(response["nice_name"]).toBe('SDK Test Org');
@@ -25,7 +25,7 @@ describe('api/v1/organizations', () => {
25
25
  });
26
26
 
27
27
  test('get(id) | shape', async () => {
28
- await loginCustomer();
28
+ await loginAdmin();
29
29
  const created = await api.organizations.create({ nice_name: 'SDK Test Org 2' });
30
30
  const response = await api.organizations.get(created.id);
31
31
  expect(response["id"]).toBe(created.id);
@@ -38,28 +38,28 @@ describe('api/v1/organizations', () => {
38
38
  });
39
39
 
40
40
  test('edit', async () => {
41
- await loginCustomer();
41
+ await loginAdmin();
42
42
  const created = await api.organizations.create({ nice_name: 'SDK Test Org 3' });
43
43
  const response = await api.organizations.edit(created.id, { nice_name: 'SDK Test Org 3 Edited' });
44
44
  expect(response["nice_name"]).toBe('SDK Test Org 3 Edited');
45
45
  });
46
46
 
47
47
  test('members(id).get() | empty for a freshly created organization', async () => {
48
- await loginCustomer();
48
+ await loginAdmin();
49
49
  const created = await api.organizations.create({ nice_name: 'SDK Test Org 4' });
50
50
  const response = await api.organizations.members(created.id).get();
51
51
  expect(Object.values(response)).toEqual([]);
52
52
  });
53
53
 
54
54
  test('members(id).courses(userId) | rejects a non-member user_id', async () => {
55
- await loginCustomer();
55
+ await loginAdmin();
56
56
  const created = await api.organizations.create({ nice_name: 'SDK Test Org 5' });
57
57
  await expect(api.organizations.members(created.id).courses(created.user_id))
58
58
  .rejects.toMatchObject({ status: 422 });
59
59
  });
60
60
 
61
61
  test('members(id).createPayment(userId, data) | reaches validation, not the OwnerOrStaff 403', async () => {
62
- await loginCustomer();
62
+ await loginAdmin();
63
63
  const created = await api.organizations.create({ nice_name: 'SDK Test Org 6' });
64
64
  // Empty payload — asserts the route/method wiring bypasses OwnerOrStaff and lands
65
65
  // in UserPaymentCreateRequest validation (422), never a 403.
@@ -77,7 +77,7 @@ describe('api/v1/users/organization-owners', () => {
77
77
  });
78
78
 
79
79
  test('get | employee-and-above', async () => {
80
- await loginCustomer();
80
+ await loginAdmin();
81
81
  const response = Object.values(await api.users.organizationOwners());
82
82
  expect(Array.isArray(response)).toBe(true);
83
83
  response.forEach(user => {
@@ -12,8 +12,6 @@ describe('api/v1/quizzes', () => {
12
12
  expect(Array.isArray(response)).toBe(true);
13
13
  response.forEach(quiz => {
14
14
  expect(quiz["id"]).toBeDefined();
15
- expect(quiz["cod"]).toBeDefined();
16
- expect(quiz["enabled"]).toBeDefined();
17
15
  expect(quiz["created_at"]).toBeDefined();
18
16
  expect(quiz["updated_at"]).toBeDefined();
19
17
  });
@@ -1,15 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
4
-
5
- const login = () => api.auth.login({
6
- email: process.env.TEST_EMAIL,
7
- password: process.env.TEST_PASSWORD,
8
- });
1
+ import { api, loginAdmin } from '../../../helpers.js';
9
2
 
10
3
  describe('api/v1/short-links', () => {
11
4
  test('get | authenticated', async () => {
12
- await login();
5
+ await loginAdmin();
13
6
  await api.shortLinks.get()
14
7
  .then(response => {
15
8
  response = Object.values(response);
@@ -1,9 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
1
+ import { api, loginAdmin } from '../../../helpers.js';
4
2
 
5
3
  describe('api/v1/taxes', () => {
6
4
  test('get', async () => {
5
+ await loginAdmin();
7
6
  await api.taxes.get()
8
7
  .then(response => {
9
8
  response = Object.values(response);
@@ -38,7 +38,7 @@ describe('api/v1/teacher/config-sets', () => {
38
38
 
39
39
  describe('api/v1/teacher/configs', () => {
40
40
  test('get | authenticated', async () => {
41
- await login();
41
+ await loginAdmin();
42
42
  await api.teacher.configs().get()
43
43
  .then(response => {
44
44
  response = Object.values(response);
@@ -1,9 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
1
+ import { api, loginAdmin } from '../../../helpers.js';
4
2
 
5
3
  describe('api/v1/user-types', () => {
6
4
  test('get', async () => {
5
+ await loginAdmin();
7
6
  await api.userTypes.get()
8
7
  .then(response => {
9
8
  response = Object.values(response);
@@ -12,7 +11,6 @@ describe('api/v1/user-types', () => {
12
11
  expect(userType["id"]).toBeDefined();
13
12
  expect(userType["cod"]).toBeDefined();
14
13
  expect(userType["title"]).toBeDefined();
15
- expect(userType["enabled"]).toBeDefined();
16
14
  });
17
15
  });
18
16
  });
@@ -5,29 +5,26 @@ import {
5
5
  } from '../../../../helpers.js';
6
6
 
7
7
  describe('api/v1/users', () => {
8
+ // get(id = null) with no id returns the authenticated user's own
9
+ // profile (UserController::get() -> auth()->user()), not a list.
8
10
  test('get | authenticated', async () => {
9
11
  await loginAdmin();
10
12
  await api.users.get()
11
13
  .then(response => {
12
- response = Object.values(response);
13
- expect(response.length > 0).toBe(true);
14
- response.forEach(user => {
15
- expect(user["id"]).toBeDefined();
16
- expect(user["name"]).toBeDefined();
17
- expect(user["email"]).toBeDefined();
18
- expect(user["created_at"]).toBeDefined();
19
- expect(user["updated_at"]).toBeDefined();
20
- });
14
+ expect(response["id"]).toBeDefined();
15
+ expect(response["name"]).toBeDefined();
16
+ expect(response["email"]).toBeDefined();
17
+ expect(response["created_at"]).toBeDefined();
18
+ expect(response["updated_at"]).toBeDefined();
21
19
  });
22
20
  });
23
21
 
24
22
  test('get by id | authenticated', async () => {
25
23
  await loginAdmin();
26
- const users = await api.users.get().then(r => Object.values(r));
27
- const id = users[0]["id"];
28
- await api.users.get(id)
24
+ const me = await api.users.get();
25
+ await api.users.get(me["id"])
29
26
  .then(response => {
30
- expect(response["id"]).toBe(id);
27
+ expect(response["id"]).toBe(me["id"]);
31
28
  expect(response["name"]).toBeDefined();
32
29
  expect(response["email"]).toBeDefined();
33
30
  });
@@ -1,15 +1,8 @@
1
- import InsigniaApiV1 from '../../../../src/api/v1/index.js';
2
-
3
- const api = new InsigniaApiV1(process.env.INSIGNIA_EDUCATION_API_BASE_URL);
4
-
5
- const login = () => api.auth.login({
6
- email: process.env.TEST_EMAIL,
7
- password: process.env.TEST_PASSWORD,
8
- });
1
+ import { api, loginAdmin } from '../../../helpers.js';
9
2
 
10
3
  describe('api/v1/zoom/meetings', () => {
11
4
  test('get | authenticated', async () => {
12
- await login();
5
+ await loginAdmin();
13
6
  await api.zoom.meetings().get()
14
7
  .then(response => {
15
8
  response = Object.values(response);
@@ -1,12 +0,0 @@
1
- export default class Categories {
2
- #client;
3
-
4
- constructor(client) {
5
- this.#client = client;
6
- }
7
-
8
- get(id = null) { return id ? this.#client.get(`/categories/${id}`) : this.#client.get('/categories'); }
9
- create(data) { return this.#client.put('/categories', data); }
10
- edit(id, data) { return this.#client.patch(`/categories/${id}`, data); }
11
- delete(id) { return this.#client.del(`/categories/${id}`); }
12
- }
@@ -1,12 +0,0 @@
1
- export default class Configs {
2
- #client;
3
-
4
- constructor(client) {
5
- this.#client = client;
6
- }
7
-
8
- get(id = null) { return id ? this.#client.get(`/configs/${id}`) : this.#client.get('/configs'); }
9
- create(data) { return this.#client.put('/configs', data); }
10
- edit(id, data) { return this.#client.patch(`/configs/${id}`, data); }
11
- delete(id) { return this.#client.del(`/configs/${id}`); }
12
- }
@@ -1,19 +0,0 @@
1
- import {
2
- api
3
- } from '../../../helpers.js';
4
-
5
- describe('api/v1/categories', () => {
6
- test('get', async () => {
7
- await api.categories.get()
8
- .then(response => {
9
- response = Object.values(response);
10
- expect(response.length > 0).toBe(true);
11
- response.forEach(category => {
12
- expect(category["id"]).toBeDefined();
13
- expect(category["cod"]).toBeDefined();
14
- expect(category["title"]).toBeDefined();
15
- expect(category["enabled"]).toBeDefined();
16
- });
17
- });
18
- });
19
- });