-
Notifications
You must be signed in to change notification settings - Fork 10
msw: add policy mock handlers #1199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
91e86b5
fac3371
1e57ddd
66370a5
de51e27
9cd23e6
7c9fdc1
b553dda
cdef995
ea156d7
43d67df
ad97409
05e073a
de0e487
77bb18a
0e20438
643823a
4930074
7d8696f
108889c
132b2e9
eca0ae4
e965bba
b1bb6e0
4d9a0d1
9aa1799
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,371 @@ | ||
| // import { http, HttpResponse } from 'msw' | ||
| import { http } from 'msw' | ||
|
|
||
| // implementations for msw v2 handlers go in this file | ||
| // see old.default_handlers.js for reference | ||
| // this note can get removed after migration | ||
| const myWikis = JSON.parse(localStorage.getItem('msw-myWikis')) || [] | ||
| let lastWikiId = (myWikis.length && myWikis[myWikis.length - 1].id) || 0 | ||
| let user = makeUser() | ||
| let getEntityImportCalledTimes = 0 | ||
|
|
||
| function makeUser (email = 'test@local') { | ||
| return { | ||
| id: 1, | ||
| email, | ||
| verified: true, | ||
| created_at: '2020-01-01', | ||
| updated_at: '2020-01-01', | ||
| } | ||
| } | ||
|
|
||
| const makeNewWiki = ({ domain, sitename }) => { | ||
| const newWiki = { | ||
| id: ++lastWikiId, | ||
| domain, | ||
| sitename, | ||
| deleted_at: null, | ||
| created_at: '2020-01-01', | ||
| updated_at: '2020-01-01', | ||
| pivot: { | ||
| user_id: user.id, | ||
| wiki_id: lastWikiId, | ||
| }, | ||
| wiki_managers: [{ | ||
| email: user.email, | ||
| pivot: { | ||
| user_id: user.id, | ||
| wiki_id: lastWikiId, | ||
| }, | ||
| }], | ||
| wiki_db_version: { | ||
| id: 101, | ||
| wiki_id: lastWikiId, | ||
| version: 'mw1.33-wbs1', | ||
| }, | ||
| public_settings: [], | ||
| } | ||
|
|
||
| myWikis.push(newWiki) | ||
| localStorage.setItem('msw-myWikis', JSON.stringify(myWikis)) | ||
|
|
||
| return newWiki | ||
| } | ||
|
|
||
| const removeWiki = wikiIndex => { | ||
| myWikis.splice(wikiIndex, 1) | ||
| localStorage.setItem('msw-myWikis', JSON.stringify(myWikis)) | ||
| } | ||
|
|
||
| const wikiDiscovery = (referrer, params) => { | ||
| const pseudorandom = { | ||
| seed: 1, | ||
| next: function () { | ||
| const x = Math.sin(this.seed++) * 10000 | ||
| return x - Math.floor(x) | ||
| }, | ||
| } | ||
|
|
||
| const names = [ | ||
| 'Wikibase Name', | ||
| 'A Very Long Wikibase Name', | ||
| ] | ||
|
|
||
| let wikis = [...Array(75).keys()].map((id) => { | ||
| const wiki = { | ||
| id, | ||
| domain: id + '-wikibase.wbaas.localhost', | ||
| sitename: id + ' - ' + names[id % names.length], | ||
| wiki_site_stats: null, | ||
| logo_url: null, | ||
| } | ||
|
|
||
| if (pseudorandom.next() >= 0.1) { | ||
| wiki.wiki_site_stats = { | ||
| pages: Math.ceil(pseudorandom.next() * 250), | ||
| } | ||
| } | ||
|
|
||
| if (pseudorandom.next() >= 0.5) { | ||
| wiki.logo_url = new URL(referrer).origin + '/favicon.ico' | ||
| } | ||
| return wiki | ||
| }) | ||
|
|
||
| if (parseInt(params.get('is_active'))) { | ||
| wikis = wikis.filter((wiki) => { | ||
| const stats = wiki.wiki_site_stats | ||
| return stats && stats.pages > 1 | ||
| }) | ||
| } | ||
|
|
||
| if (params.get('sort') === 'sitename') { | ||
| wikis = wikis.sort((a, b) => { | ||
| let sort = a.sitename.localeCompare(b.sitename, 'en', { numeric: true }) | ||
| if (params.get('direction') === 'desc') { | ||
| sort *= -1 | ||
| } | ||
| return sort | ||
| }) | ||
| } | ||
|
|
||
| if (params.get('sort') === 'pages') { | ||
| wikis = wikis.sort((a, b) => { | ||
| const aPages = a.wiki_site_stats ? a.wiki_site_stats.pages : 0 | ||
| const bPages = b.wiki_site_stats ? b.wiki_site_stats.pages : 0 | ||
| if (params.get('direction') === 'desc') { | ||
| return bPages - aPages | ||
| } | ||
| return aPages - bPages | ||
| }) | ||
| } | ||
|
|
||
| const currentPage = parseInt(params.get('page')) | ||
| const resultsPerPage = parseInt(params.get('per_page')) | ||
| const start = (currentPage - 1) * resultsPerPage | ||
| const end = start + resultsPerPage | ||
|
|
||
| return { | ||
| data: wikis.slice(start, end), | ||
| meta: { | ||
| last_page: Math.ceil(wikis.length / resultsPerPage), | ||
| total: wikis.length, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| export const handlers = [ | ||
| http.get('/api/auth/login', ({ cookies }) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit confused here. This block of code resets the authenticated user on successful
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit confused here. This bloack of code resets the authenticated user on every successful GET login check by calling |
||
| const { authToken } = cookies | ||
| if (authToken !== 'token_value') { | ||
| return Response.json('Unauthorized', { | ||
| status: 401, | ||
| }) | ||
| } | ||
|
|
||
| user = makeUser() | ||
| return Response.json({ user }) | ||
| }), | ||
|
|
||
| http.post('/api/auth/login', async ({ request }) => { | ||
| const body = await request.json() | ||
| user = makeUser(body.email) | ||
|
|
||
| return Response.json({ user }, { | ||
| headers: { 'set-cookie': 'authToken=token_value' }, | ||
| }) | ||
| }), | ||
|
|
||
| http.delete('/api/auth/login', () => { | ||
| return new Response(null, { status: 204 }) | ||
| }), | ||
|
|
||
| http.post('/api/user/forgotPassword', () => { | ||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post('/api/user/resetPassword', () => { | ||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post('/api/user/sendVerifyEmail', () => { | ||
| return new Response('Already verified') | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looking at api.js:45. Under MSW, that makes
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That mismatch is outside this mock file, but it means fixing the mock alone would still leave a real API/UI contract bug. |
||
| }), | ||
|
|
||
| http.post('/api/user/verifyEmail', () => { | ||
| return new Response('Already verified') | ||
| }), | ||
|
|
||
| http.post('/api/complaint/sendMessage', () => { | ||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post('/api/contact/sendMessage', async ({ request }) => { | ||
| const body = await request.json() | ||
|
|
||
| if (body.name === '' || body.message === '' || body.subject === '') { | ||
| return new Response(null, { status: 400 }) | ||
| } | ||
|
|
||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post('/api/wiki/mine', () => { | ||
| const data = { wikis: myWikis, count: myWikis.length, limit: false } | ||
| return Response.json(data) | ||
| }), | ||
|
|
||
| http.post('/api/wiki/entityImport', () => { | ||
| const data = { status: 'pending', payload: {}, started_at: new Date().toJSON() } | ||
| return Response.json(data) | ||
| }), | ||
|
|
||
| http.get('/api/wiki/entityImport', () => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you made entity-import polling depend on one global counter shared across the entire module? I think there is a chance that later polls for other wikis might drift and start in the wrong state after a test or something changes the value of the counter.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the entire module shares 1 global counter? I think later polls might drift and start in the wrong state if a test or something messes up the counter. |
||
| getEntityImportCalledTimes++ | ||
| switch (getEntityImportCalledTimes) { | ||
| case 1: | ||
| return Response.json({ data: [] }) | ||
| case 2: | ||
| return Response.json({ data: [{ status: 'pending' }] }) | ||
| default: | ||
| return Response.json({ data: [{ status: 'success' }] }) | ||
| } | ||
| }), | ||
|
|
||
| http.post('/api/wiki/create', async ({ request }) => { | ||
| const body = await request.json() | ||
| const newWiki = makeNewWiki(body) | ||
| return Response.json({ | ||
| success: true, | ||
| data: newWiki, | ||
| }) | ||
| }), | ||
|
|
||
| http.post('/api/wiki/delete', async ({ request }) => { | ||
| const body = await request.json() | ||
| const wikiId = body.wiki | ||
| const wikiIndex = myWikis.findIndex(w => w.id === Number(wikiId)) | ||
|
|
||
| if (wikiIndex < 0) { | ||
| return new Response(null, { status: 404 }) | ||
| } | ||
|
|
||
| removeWiki(wikiIndex) | ||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post('/api/wiki/logo/update', () => { | ||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post(/\/api\/wiki\/setting\/.*?\/update$/, () => { | ||
| return new Response('Success') | ||
| }), | ||
|
|
||
| http.post('/api/wiki/details', async ({ request }) => { | ||
| const body = await request.json() | ||
| const wikiId = body.wiki | ||
| const wikiDetails = myWikis.find(w => w.id === Number(wikiId)) | ||
|
|
||
| if (!wikiDetails) { | ||
| return new Response(null, { status: 404 }) | ||
| } | ||
|
|
||
| return Response.json({ | ||
| success: true, | ||
| data: wikiDetails, | ||
| }) | ||
| }), | ||
|
|
||
| http.get('/api/wiki', async ({ request }) => { | ||
| const referrer = await request.referrer | ||
| const url = new URL(await request.url) | ||
|
|
||
| return Response.json(wikiDiscovery(referrer, url.searchParams)) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/missing', () => { | ||
| const items = [] | ||
| return Response.json({ items }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/current', () => { | ||
| const items = [ | ||
| { | ||
| metadata: { | ||
| policy_id: 2, | ||
| type: 'terms-of-use', | ||
| active_from: '2026-08-27', | ||
| content_vue_file: 'terms-of-use/version-2.vue', | ||
| }, | ||
| }, | ||
| { | ||
| metadata: { | ||
| policy_id: 3, | ||
| type: 'hosting-policy', | ||
| active_from: '2026-08-27', | ||
| content_vue_file: 'hosting-policy/version-1.vue', | ||
| }, | ||
| }, | ||
| ] | ||
|
|
||
| return Response.json({ items }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/terms-of-use', () => { | ||
| const items = [ | ||
| { | ||
| metadata: { | ||
| policy_id: 1, | ||
| type: 'terms-of-use', | ||
| active_from: '2022-01-01', | ||
| content_vue_file: 'terms-of-use/version-1.vue', | ||
| }, | ||
| }, | ||
| { | ||
| metadata: { | ||
| policy_id: 2, | ||
| type: 'terms-of-use', | ||
| active_from: '2026-08-27', | ||
| content_vue_file: 'terms-of-use/version-2.vue', | ||
| }, | ||
| }, | ||
| ] | ||
|
|
||
| return Response.json({ items }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/terms-of-use/by_active_from/2022-01-01', () => { | ||
| const metadata = { | ||
| policy_id: 1, | ||
| type: 'terms-of-use', | ||
| active_from: '2022-01-01', | ||
| content_vue_file: 'terms-of-use/version-1.vue', | ||
| } | ||
|
|
||
| return Response.json({ metadata }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/terms-of-use/current', () => { | ||
| const metadata = { | ||
| policy_id: 2, | ||
| type: 'terms-of-use', | ||
| active_from: '2026-08-27', | ||
| content_vue_file: 'terms-of-use/version-2.vue', | ||
| } | ||
|
|
||
| return Response.json({ metadata }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/terms-of-use/upcoming', () => { | ||
| const message = 'Policy not found.' | ||
| return Response.json({ message }, { status: 404 }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/hosting-policy', () => { | ||
| const items = [ | ||
| { | ||
| metadata: { | ||
| policy_id: 3, | ||
| type: 'hosting-policy', | ||
| active_from: '2026-08-27', | ||
| content_vue_file: 'hosting-policy/version-1.vue', | ||
| }, | ||
| }, | ||
| ] | ||
|
|
||
| return Response.json({ items }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/hosting-policy/current', () => { | ||
| const metadata = { | ||
| policy_id: 3, | ||
| type: 'hosting-policy', | ||
| active_from: '2026-08-27', | ||
| content_vue_file: 'hosting-policy/version-1.vue', | ||
| } | ||
|
|
||
| return Response.json({ metadata }) | ||
| }), | ||
|
|
||
| http.get('/api/v1/policies/hosting-policy/upcoming', () => { | ||
| const message = 'Policy not found.' | ||
| return Response.json({ message }, { status: 404 }) | ||
| }), | ||
| ] | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you also need to register a handler for the account-creation request. That route is called in api.js:19-27
It's not important right now because the task is focusing on policy functionalities. Ignore if you find it unnecessary