@instructure/platform-mock-canvas-api 0.1.1

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.
package/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # @instructure/platform-mock-canvas-api
2
+
3
+ Mock Canvas API handlers using MSW (Mock Service Worker) for development and testing.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add -D @instructure/platform-mock-canvas-api msw
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### In Browser (Demo App, Storybook)
14
+
15
+ ```typescript
16
+ import { setupWorker } from 'msw/browser'
17
+ import { handlers } from '@instructure/platform-mock-canvas-api'
18
+
19
+ const worker = setupWorker(...handlers)
20
+ worker.start()
21
+ ```
22
+
23
+ ### In Tests (Vitest, Jest)
24
+
25
+ ```typescript
26
+ import { setupServer } from 'msw/node'
27
+ import { handlers } from '@instructure/platform-mock-canvas-api'
28
+
29
+ const server = setupServer(...handlers)
30
+
31
+ beforeAll(() => server.listen())
32
+ afterEach(() => server.resetHandlers())
33
+ afterAll(() => server.close())
34
+ ```
35
+
36
+ ### Using Individual Handler Groups
37
+
38
+ ```typescript
39
+ import { courseHandlers, submissionHandlers } from '@instructure/platform-mock-canvas-api'
40
+
41
+ // Use only course handlers
42
+ const worker = setupWorker(...courseHandlers)
43
+
44
+ // Or combine with your own handlers
45
+ const worker = setupWorker(...courseHandlers, ...myCustomHandlers)
46
+ ```
47
+
48
+ ### Using Fixtures
49
+
50
+ ```typescript
51
+ import { courses, submissions, stickerDescriptions } from '@instructure/platform-mock-canvas-api/fixtures'
52
+
53
+ // Access mock data directly
54
+ console.log(courses) // Array of 5 courses
55
+ console.log(submissions) // Array of 5 submissions
56
+ ```
57
+
58
+ ## Included Endpoints
59
+
60
+ ### Courses
61
+ - `GET /api/v1/courses` - List all courses
62
+ - `GET /api/v1/courses/:courseId` - Get single course
63
+
64
+ ### Submissions
65
+ - `GET /api/v1/courses/:courseId/assignments/:assignmentId/submissions/:submissionId`
66
+ - `PATCH /api/v1/courses/:courseId/assignments/:assignmentId/submissions/:submissionId`
67
+ - `GET /api/v1/courses/:courseId/assignments/:assignmentId/submissions`
68
+
69
+ ## Mock Data
70
+
71
+ - **5 Courses**: CS 101, MATH 201, ENG 150, BIO 110, HIST 100
72
+ - **5 Submissions**: With various stickers and grades
73
+ - **51 Sticker Descriptions**: Full i18n support
74
+ - **Sticker Translations**: UI text translations
75
+
76
+ ## Development
77
+
78
+ ```bash
79
+ # Build the package
80
+ pnpm build
81
+
82
+ # Type check
83
+ pnpm type-check
84
+ ```
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Mock Canvas API constants
3
+ */
4
+ /**
5
+ * Simulated network delay for API requests in milliseconds
6
+ */
7
+ export declare const MOCK_API_DELAY_MS = 300;
8
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { Course } from '../types';
2
+
3
+ export declare const courses: Course[];
4
+ //# sourceMappingURL=courses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"courses.d.ts","sourceRoot":"","sources":["../../src/fixtures/courses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,eAAO,MAAM,OAAO,EAAE,MAAM,EAoC3B,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { courses } from './courses';
2
+ export { stickerDescriptions } from './stickerDescriptions';
3
+ export { stickerTranslations } from './stickerTranslations';
4
+ export { submissions, submissionsStore } from './submissions';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { StickerDescriptions } from '../types';
2
+
3
+ export declare const stickerDescriptions: StickerDescriptions;
4
+ //# sourceMappingURL=stickerDescriptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stickerDescriptions.d.ts","sourceRoot":"","sources":["../../src/fixtures/stickerDescriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEnD,eAAO,MAAM,mBAAmB,EAAE,mBAoDjC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { StickerTranslations } from '../types';
2
+
3
+ export declare const stickerTranslations: StickerTranslations;
4
+ //# sourceMappingURL=stickerTranslations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stickerTranslations.d.ts","sourceRoot":"","sources":["../../src/fixtures/stickerTranslations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEnD,eAAO,MAAM,mBAAmB,EAAE,mBAMjC,CAAA"}
@@ -0,0 +1,151 @@
1
+ const t = [
2
+ {
3
+ id: "1",
4
+ name: "Introduction to Computer Science",
5
+ course_code: "CS 101",
6
+ enrollment_term_id: "1",
7
+ term: { id: "1", name: "Fall 2024" }
8
+ },
9
+ {
10
+ id: "2",
11
+ name: "Advanced Mathematics",
12
+ course_code: "MATH 201",
13
+ enrollment_term_id: "1",
14
+ term: { id: "1", name: "Fall 2024" }
15
+ },
16
+ {
17
+ id: "3",
18
+ name: "English Literature",
19
+ course_code: "ENG 150",
20
+ enrollment_term_id: "1",
21
+ term: { id: "1", name: "Fall 2024" }
22
+ },
23
+ {
24
+ id: "4",
25
+ name: "Biology Fundamentals",
26
+ course_code: "BIO 110",
27
+ enrollment_term_id: "2",
28
+ term: { id: "2", name: "Spring 2025" }
29
+ },
30
+ {
31
+ id: "5",
32
+ name: "World History",
33
+ course_code: "HIST 100",
34
+ enrollment_term_id: "2",
35
+ term: { id: "2", name: "Spring 2025" }
36
+ }
37
+ ], a = {
38
+ default: "A placeholder sticker with a smiley face and a plus sign.",
39
+ star: "A sticker with a picture of a smiling star.",
40
+ trophy: "A sticker with a picture of a golden trophy.",
41
+ target: "A sticker with a picture of an archery target with an arrow in the center.",
42
+ apple: "A sticker with a picture of an apple.",
43
+ paintbrush: "A sticker with a picture of a paint brush.",
44
+ pencil: "A sticker with a picture of a pencil.",
45
+ design: "A sticker with a picture of a fountain pen nib.",
46
+ pen: "A sticker with a picture of a pen.",
47
+ science2: "A sticker with a picture of an atom.",
48
+ microscope: "A sticker with a picture of a microscope.",
49
+ telescope: "A sticker with a picture of a telescope.",
50
+ beaker: "A sticker with a picture of a triangular lab beaker with a narrow neck.",
51
+ chem: "A sticker with a picture of a circular lab beaker with a narrow neck.",
52
+ science: "A sticker with a picture of a molecule.",
53
+ basketball: "A sticker with a picture of a basketball.",
54
+ gym: "A sticker with a picture of a jumping rope.",
55
+ book: "A sticker with a picture of a book.",
56
+ composite_notebook: "A sticker with a picture of a composite notebook.",
57
+ notebook: "A sticker with a picture of a spiral-bound notebook.",
58
+ page: "A sticker with a picture of a piece of paper.",
59
+ mail: "A sticker with a picture of an envelope.",
60
+ music: "A sticker with a picture of a musical note.",
61
+ globe: "A sticker with a picture of a globe.",
62
+ computer: "A sticker with a picture of a computer.",
63
+ tablet: "A sticker with a picture of a tablet computer.",
64
+ calculator: "A sticker with a picture of a calculator.",
65
+ mouse: "A sticker with a picture of a computer mouse.",
66
+ panda1: "A sticker with a picture of an open-mouth smiling panda crying tears of joy.",
67
+ panda2: "A sticker with a picture of an open-mouth smiling panda with hearts in its eyes.",
68
+ panda3: "A sticker with a picture of a closed-mouth panda smiling.",
69
+ panda4: "A sticker with a picture of an open-mouth panda making a surprised face.",
70
+ panda5: "A sticker with a picture of an open-mouth panda smiling.",
71
+ panda6: "A sticker with a picture of a panda with a half-open mouth, smiling.",
72
+ panda7: "A sticker with a picture of a panda grinning.",
73
+ panda8: "A sticker with a picture of a panda smiling.",
74
+ panda9: "A sticker with a picture of a panda grinning.",
75
+ bookbag: "A sticker with a picture of a bookbag.",
76
+ briefcase: "A sticker with a picture of a briefcase.",
77
+ grad: "A sticker with a picture of a graduation cap.",
78
+ bus: "A sticker with a picture of a school bus.",
79
+ bell: "A sticker with a picture of a bell.",
80
+ clock: "A sticker with a picture of a wall clock.",
81
+ calendar: "A sticker with a picture of a calendar.",
82
+ paperclip: "A sticker with a picture of a paperclip.",
83
+ scissors: "A sticker with a picture of scissors.",
84
+ ruler: "A sticker with a picture of a ruler.",
85
+ tape: "A sticker with a picture of a tape roll dispenser.",
86
+ tag: "A sticker with a picture of a clip-on identification tag.",
87
+ presentation: "A sticker with a picture of a projector screen with presentation content on it.",
88
+ column: "A sticker with a picture of a roman column."
89
+ }, r = {
90
+ chooseASticker: "Choose a sticker",
91
+ close: "Close",
92
+ removeSticker: "Remove sticker",
93
+ removedSticker: "Removed sticker",
94
+ selectedSticker: "Selected sticker"
95
+ }, i = [
96
+ {
97
+ id: "1",
98
+ course_id: "1",
99
+ assignment_id: "100",
100
+ user_id: "10",
101
+ sticker: "grad",
102
+ submitted_at: "2024-11-15T10:30:00Z",
103
+ grade: "A",
104
+ score: 95
105
+ },
106
+ {
107
+ id: "2",
108
+ course_id: "1",
109
+ assignment_id: "100",
110
+ user_id: "11",
111
+ sticker: "star",
112
+ submitted_at: "2024-11-15T11:00:00Z",
113
+ grade: "B+",
114
+ score: 88
115
+ },
116
+ {
117
+ id: "3",
118
+ course_id: "1",
119
+ assignment_id: "100",
120
+ user_id: "12",
121
+ sticker: null,
122
+ submitted_at: "2024-11-15T12:00:00Z"
123
+ },
124
+ {
125
+ id: "4",
126
+ course_id: "1",
127
+ assignment_id: "100",
128
+ user_id: "13",
129
+ sticker: "panda5",
130
+ submitted_at: "2024-11-15T14:30:00Z",
131
+ grade: "A-",
132
+ score: 92
133
+ },
134
+ {
135
+ id: "5",
136
+ course_id: "1",
137
+ assignment_id: "100",
138
+ user_id: "14",
139
+ sticker: "trophy",
140
+ submitted_at: "2024-11-15T15:00:00Z",
141
+ grade: "A+",
142
+ score: 98
143
+ }
144
+ ], c = new Map(i.map((e) => [e.id, { ...e }]));
145
+ export {
146
+ t as courses,
147
+ a as stickerDescriptions,
148
+ r as stickerTranslations,
149
+ i as submissions,
150
+ c as submissionsStore
151
+ };
@@ -0,0 +1,4 @@
1
+ export * from './fixtures';
2
+ export { courseHandlers, handlers, submissionHandlers } from './handlers';
3
+ export type * from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACzE,mBAAmB,SAAS,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ import { courses as m, submissionsStore as u } from "./fixtures.js";
2
+ import { stickerDescriptions as v, stickerTranslations as k, submissions as l } from "./fixtures.js";
3
+ import { http as e, HttpResponse as n } from "msw";
4
+ const a = [
5
+ // GET /api/v1/courses
6
+ e.get("/api/v1/courses", () => n.json(m)),
7
+ // GET /api/v1/courses/:courseId
8
+ e.get("/api/v1/courses/:courseId", ({ params: o }) => {
9
+ const s = m.find((i) => i.id === o.courseId);
10
+ return s ? n.json(s) : n.json({ errors: [{ message: "Course not found" }] }, { status: 404 });
11
+ })
12
+ ], d = 300, b = [
13
+ // GET submission
14
+ e.get(
15
+ "/api/v1/courses/:courseId/assignments/:assignmentId/submissions/:submissionId",
16
+ ({ params: o }) => {
17
+ const s = u.get(o.submissionId);
18
+ return s ? n.json(s) : n.json({ errors: [{ message: "Submission not found" }] }, { status: 404 });
19
+ }
20
+ ),
21
+ // PATCH submission (update sticker)
22
+ e.patch(
23
+ "/api/v1/courses/:courseId/assignments/:assignmentId/submissions/:submissionId",
24
+ async ({ params: o, request: s }) => {
25
+ const { submissionId: i } = o, r = await s.json(), t = u.get(i);
26
+ return t ? (r.submission && "sticker" in r.submission && r.submission.sticker !== void 0 && (t.sticker = r.submission.sticker, u.set(i, t)), await new Promise((c) => setTimeout(c, d)), n.json(t)) : n.json({ errors: [{ message: "Submission not found" }] }, { status: 404 });
27
+ }
28
+ ),
29
+ // GET all submissions for an assignment
30
+ e.get("/api/v1/courses/:courseId/assignments/:assignmentId/submissions", ({ params: o }) => {
31
+ const s = Array.from(u.values()).filter(
32
+ (i) => i.course_id === o.courseId && i.assignment_id === o.assignmentId
33
+ );
34
+ return n.json(s);
35
+ })
36
+ ], f = [...a, ...b];
37
+ export {
38
+ a as courseHandlers,
39
+ m as courses,
40
+ f as handlers,
41
+ v as stickerDescriptions,
42
+ k as stickerTranslations,
43
+ b as submissionHandlers,
44
+ l as submissions,
45
+ u as submissionsStore
46
+ };
@@ -0,0 +1,32 @@
1
+ export interface Course {
2
+ id: string;
3
+ name: string;
4
+ course_code: string;
5
+ enrollment_term_id: string;
6
+ term?: {
7
+ id: string;
8
+ name: string;
9
+ };
10
+ }
11
+ export type StickerTitle = 'star' | 'trophy' | 'target' | 'apple' | 'paintbrush' | 'pencil' | 'design' | 'pen' | 'science2' | 'microscope' | 'telescope' | 'beaker' | 'chem' | 'science' | 'basketball' | 'gym' | 'book' | 'composite_notebook' | 'notebook' | 'page' | 'mail' | 'music' | 'globe' | 'computer' | 'tablet' | 'calculator' | 'mouse' | 'panda1' | 'panda2' | 'panda3' | 'panda4' | 'panda5' | 'panda6' | 'panda7' | 'panda8' | 'panda9' | 'bookbag' | 'briefcase' | 'grad' | 'bus' | 'bell' | 'clock' | 'calendar' | 'paperclip' | 'scissors' | 'ruler' | 'tape' | 'tag' | 'presentation' | 'column';
12
+ export interface Submission {
13
+ id: string;
14
+ course_id: string;
15
+ assignment_id: string;
16
+ user_id?: string;
17
+ sticker: StickerTitle | null;
18
+ submitted_at?: string;
19
+ grade?: string;
20
+ score?: number;
21
+ }
22
+ export type StickerDescriptions = {
23
+ [key in StickerTitle | 'default']: string;
24
+ };
25
+ export interface StickerTranslations {
26
+ chooseASticker: string;
27
+ removeSticker: string;
28
+ removedSticker: string;
29
+ selectedSticker: string;
30
+ close: string;
31
+ }
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;CACF;AAED,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,UAAU,GACV,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,MAAM,GACN,SAAS,GACT,YAAY,GACZ,KAAK,GACL,MAAM,GACN,oBAAoB,GACpB,UAAU,GACV,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,GACP,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,MAAM,GACN,KAAK,GACL,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,UAAU,GACV,OAAO,GACP,MAAM,GACN,KAAK,GACL,cAAc,GACd,QAAQ,CAAA;AAEZ,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,mBAAmB,GAAG;KAC/B,GAAG,IAAI,YAAY,GAAG,SAAS,GAAG,MAAM;CAC1C,CAAA;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;CACd"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@instructure/platform-mock-canvas-api",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./fixtures": {
14
+ "types": "./dist/fixtures/index.d.ts",
15
+ "import": "./dist/fixtures/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "peerDependencies": {
22
+ "msw": "^2.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^20.0.0",
26
+ "msw": "^2.0.0",
27
+ "typescript": "^5.3.0",
28
+ "vite": "^5.0.0",
29
+ "vite-plugin-dts": "^3.7.0"
30
+ },
31
+ "scripts": {
32
+ "build": "vite build",
33
+ "dev": "vite build --watch",
34
+ "type-check": "tsc --noEmit"
35
+ }
36
+ }