parent
b796dab689
commit
990ffb8886
@ -0,0 +1,307 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
|
||||
/**
|
||||
* Mock Service Worker.
|
||||
* @see https://github.com/mswjs/msw
|
||||
* - Please do NOT modify this file.
|
||||
* - Please do NOT serve this file on production.
|
||||
*/
|
||||
|
||||
const PACKAGE_VERSION = '2.8.6'
|
||||
const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
|
||||
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
|
||||
const activeClientIds = new Set()
|
||||
|
||||
self.addEventListener('install', function () {
|
||||
self.skipWaiting()
|
||||
})
|
||||
|
||||
self.addEventListener('activate', function (event) {
|
||||
event.waitUntil(self.clients.claim())
|
||||
})
|
||||
|
||||
self.addEventListener('message', async function (event) {
|
||||
const clientId = event.source.id
|
||||
|
||||
if (!clientId || !self.clients) {
|
||||
return
|
||||
}
|
||||
|
||||
const client = await self.clients.get(clientId)
|
||||
|
||||
if (!client) {
|
||||
return
|
||||
}
|
||||
|
||||
const allClients = await self.clients.matchAll({
|
||||
type: 'window',
|
||||
})
|
||||
|
||||
switch (event.data) {
|
||||
case 'KEEPALIVE_REQUEST': {
|
||||
sendToClient(client, {
|
||||
type: 'KEEPALIVE_RESPONSE',
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
case 'INTEGRITY_CHECK_REQUEST': {
|
||||
sendToClient(client, {
|
||||
type: 'INTEGRITY_CHECK_RESPONSE',
|
||||
payload: {
|
||||
packageVersion: PACKAGE_VERSION,
|
||||
checksum: INTEGRITY_CHECKSUM,
|
||||
},
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
case 'MOCK_ACTIVATE': {
|
||||
activeClientIds.add(clientId)
|
||||
|
||||
sendToClient(client, {
|
||||
type: 'MOCKING_ENABLED',
|
||||
payload: {
|
||||
client: {
|
||||
id: client.id,
|
||||
frameType: client.frameType,
|
||||
},
|
||||
},
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
case 'MOCK_DEACTIVATE': {
|
||||
activeClientIds.delete(clientId)
|
||||
break
|
||||
}
|
||||
|
||||
case 'CLIENT_CLOSED': {
|
||||
activeClientIds.delete(clientId)
|
||||
|
||||
const remainingClients = allClients.filter((client) => {
|
||||
return client.id !== clientId
|
||||
})
|
||||
|
||||
// Unregister itself when there are no more clients
|
||||
if (remainingClients.length === 0) {
|
||||
self.registration.unregister()
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.addEventListener('fetch', function (event) {
|
||||
const { request } = event
|
||||
|
||||
// Bypass navigation requests.
|
||||
if (request.mode === 'navigate') {
|
||||
return
|
||||
}
|
||||
|
||||
// Opening the DevTools triggers the "only-if-cached" request
|
||||
// that cannot be handled by the worker. Bypass such requests.
|
||||
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
|
||||
return
|
||||
}
|
||||
|
||||
// Bypass all requests when there are no active clients.
|
||||
// Prevents the self-unregistered worked from handling requests
|
||||
// after it's been deleted (still remains active until the next reload).
|
||||
if (activeClientIds.size === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// Generate unique request ID.
|
||||
const requestId = crypto.randomUUID()
|
||||
event.respondWith(handleRequest(event, requestId))
|
||||
})
|
||||
|
||||
async function handleRequest(event, requestId) {
|
||||
const client = await resolveMainClient(event)
|
||||
const response = await getResponse(event, client, requestId)
|
||||
|
||||
// Send back the response clone for the "response:*" life-cycle events.
|
||||
// Ensure MSW is active and ready to handle the message, otherwise
|
||||
// this message will pend indefinitely.
|
||||
if (client && activeClientIds.has(client.id)) {
|
||||
;(async function () {
|
||||
const responseClone = response.clone()
|
||||
|
||||
sendToClient(
|
||||
client,
|
||||
{
|
||||
type: 'RESPONSE',
|
||||
payload: {
|
||||
requestId,
|
||||
isMockedResponse: IS_MOCKED_RESPONSE in response,
|
||||
type: responseClone.type,
|
||||
status: responseClone.status,
|
||||
statusText: responseClone.statusText,
|
||||
body: responseClone.body,
|
||||
headers: Object.fromEntries(responseClone.headers.entries()),
|
||||
},
|
||||
},
|
||||
[responseClone.body],
|
||||
)
|
||||
})()
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
// Resolve the main client for the given event.
|
||||
// Client that issues a request doesn't necessarily equal the client
|
||||
// that registered the worker. It's with the latter the worker should
|
||||
// communicate with during the response resolving phase.
|
||||
async function resolveMainClient(event) {
|
||||
const client = await self.clients.get(event.clientId)
|
||||
|
||||
if (activeClientIds.has(event.clientId)) {
|
||||
return client
|
||||
}
|
||||
|
||||
if (client?.frameType === 'top-level') {
|
||||
return client
|
||||
}
|
||||
|
||||
const allClients = await self.clients.matchAll({
|
||||
type: 'window',
|
||||
})
|
||||
|
||||
return allClients
|
||||
.filter((client) => {
|
||||
// Get only those clients that are currently visible.
|
||||
return client.visibilityState === 'visible'
|
||||
})
|
||||
.find((client) => {
|
||||
// Find the client ID that's recorded in the
|
||||
// set of clients that have registered the worker.
|
||||
return activeClientIds.has(client.id)
|
||||
})
|
||||
}
|
||||
|
||||
async function getResponse(event, client, requestId) {
|
||||
const { request } = event
|
||||
|
||||
// Clone the request because it might've been already used
|
||||
// (i.e. its body has been read and sent to the client).
|
||||
const requestClone = request.clone()
|
||||
|
||||
function passthrough() {
|
||||
// Cast the request headers to a new Headers instance
|
||||
// so the headers can be manipulated with.
|
||||
const headers = new Headers(requestClone.headers)
|
||||
|
||||
// Remove the "accept" header value that marked this request as passthrough.
|
||||
// This prevents request alteration and also keeps it compliant with the
|
||||
// user-defined CORS policies.
|
||||
const acceptHeader = headers.get('accept')
|
||||
if (acceptHeader) {
|
||||
const values = acceptHeader.split(',').map((value) => value.trim())
|
||||
const filteredValues = values.filter(
|
||||
(value) => value !== 'msw/passthrough',
|
||||
)
|
||||
|
||||
if (filteredValues.length > 0) {
|
||||
headers.set('accept', filteredValues.join(', '))
|
||||
} else {
|
||||
headers.delete('accept')
|
||||
}
|
||||
}
|
||||
|
||||
return fetch(requestClone, { headers })
|
||||
}
|
||||
|
||||
// Bypass mocking when the client is not active.
|
||||
if (!client) {
|
||||
return passthrough()
|
||||
}
|
||||
|
||||
// Bypass initial page load requests (i.e. static assets).
|
||||
// The absence of the immediate/parent client in the map of the active clients
|
||||
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
|
||||
// and is not ready to handle requests.
|
||||
if (!activeClientIds.has(client.id)) {
|
||||
return passthrough()
|
||||
}
|
||||
|
||||
// Notify the client that a request has been intercepted.
|
||||
const requestBuffer = await request.arrayBuffer()
|
||||
const clientMessage = await sendToClient(
|
||||
client,
|
||||
{
|
||||
type: 'REQUEST',
|
||||
payload: {
|
||||
id: requestId,
|
||||
url: request.url,
|
||||
mode: request.mode,
|
||||
method: request.method,
|
||||
headers: Object.fromEntries(request.headers.entries()),
|
||||
cache: request.cache,
|
||||
credentials: request.credentials,
|
||||
destination: request.destination,
|
||||
integrity: request.integrity,
|
||||
redirect: request.redirect,
|
||||
referrer: request.referrer,
|
||||
referrerPolicy: request.referrerPolicy,
|
||||
body: requestBuffer,
|
||||
keepalive: request.keepalive,
|
||||
},
|
||||
},
|
||||
[requestBuffer],
|
||||
)
|
||||
|
||||
switch (clientMessage.type) {
|
||||
case 'MOCK_RESPONSE': {
|
||||
return respondWithMock(clientMessage.data)
|
||||
}
|
||||
|
||||
case 'PASSTHROUGH': {
|
||||
return passthrough()
|
||||
}
|
||||
}
|
||||
|
||||
return passthrough()
|
||||
}
|
||||
|
||||
function sendToClient(client, message, transferrables = []) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const channel = new MessageChannel()
|
||||
|
||||
channel.port1.onmessage = (event) => {
|
||||
if (event.data && event.data.error) {
|
||||
return reject(event.data.error)
|
||||
}
|
||||
|
||||
resolve(event.data)
|
||||
}
|
||||
|
||||
client.postMessage(
|
||||
message,
|
||||
[channel.port2].concat(transferrables.filter(Boolean)),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async function respondWithMock(response) {
|
||||
// Setting response status code to 0 is a no-op.
|
||||
// However, when responding with a "Response.error()", the produced Response
|
||||
// instance will have status code set to 0. Since it's not possible to create
|
||||
// a Response instance with status code 0, handle that use-case separately.
|
||||
if (response.status === 0) {
|
||||
return Response.error()
|
||||
}
|
||||
|
||||
const mockedResponse = new Response(response.body, response)
|
||||
|
||||
Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
|
||||
value: true,
|
||||
enumerable: true,
|
||||
})
|
||||
|
||||
return mockedResponse
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
import { setupWorker } from 'msw/browser';
|
||||
import { handlers } from './handlers.ts';
|
||||
|
||||
export const worker = setupWorker(...handlers);
|
@ -0,0 +1,116 @@
|
||||
import { http,HttpResponse } from 'msw';
|
||||
import Avatar from '@/assets/images/默认头像.jpg'
|
||||
import { Briefcase } from '@element-plus/icons-vue';
|
||||
|
||||
let mockUserData = {
|
||||
userId: 1,
|
||||
username: '测试员',
|
||||
email: "test@example.com",
|
||||
nickname: '测试员',
|
||||
avatar: Avatar,
|
||||
bio:"只要不出bug一切都好QAQ",
|
||||
gender:'1',
|
||||
birthday: '2000-01-01',
|
||||
studentId:20220101001,
|
||||
department: "计算机学院",
|
||||
major: "软件工程",
|
||||
grade: "2023级",
|
||||
points: 100,
|
||||
role: 0,
|
||||
status:1,
|
||||
isVerified: true,
|
||||
};
|
||||
|
||||
export const handlers = [
|
||||
http.post('/users/login', async ({request}) => {
|
||||
|
||||
const body = await request.json() as { data: { username: string; password: string } };
|
||||
|
||||
if (body.data.username === 'test@example.com' && body.data.password === '123456') {
|
||||
return HttpResponse.json({
|
||||
code: 200,
|
||||
message: '登录成功',
|
||||
data: {
|
||||
token: 'mock-jwt-token-123',
|
||||
userInfo: {
|
||||
userId: mockUserData.userId,
|
||||
username: mockUserData.username,
|
||||
nickname: mockUserData.nickname,
|
||||
avatar: mockUserData.avatar,
|
||||
role: mockUserData.role,
|
||||
isVerified: mockUserData.isVerified,
|
||||
status: mockUserData.status,
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return HttpResponse.json({ message: '用户名或密码错误' }, { status: 401 });
|
||||
}),
|
||||
|
||||
//3.1获取用户个人信息
|
||||
http.get('/users/info', async ({ request }) => {
|
||||
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
|
||||
if (token === 'mock-jwt-token-123') {
|
||||
return HttpResponse.json({
|
||||
code: 200,
|
||||
message: '获取用户信息成功',
|
||||
data: mockUserData,
|
||||
});
|
||||
}
|
||||
return HttpResponse.json({ message: '未授权' }, { status: 401 });
|
||||
}),
|
||||
|
||||
//3.2更新用户个人信息
|
||||
http.put('/users/profile', async ({ request }) => {
|
||||
|
||||
const body = await request.json() as typeof mockUserData;
|
||||
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
|
||||
|
||||
if (token === 'mock-jwt-token-123') {
|
||||
// 更新 mock 数据
|
||||
mockUserData = {
|
||||
...mockUserData,
|
||||
...body,
|
||||
};
|
||||
return HttpResponse.json({
|
||||
code: 200,
|
||||
message: '更新成功',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
return HttpResponse.json({ code: 401, message: '未授权' }, { status: 401 });
|
||||
}),
|
||||
|
||||
//3.3修改用户密码
|
||||
http.put('/users/password', async ({ request }) => {
|
||||
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
|
||||
|
||||
if (token === 'mock-jwt-token-123') {
|
||||
return HttpResponse.json({
|
||||
code: 200,
|
||||
message: '密码修改成功',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
return HttpResponse.json({ code: 401, message: '未授权' }, { status: 401 });
|
||||
}),
|
||||
|
||||
//3.4上传用户头像
|
||||
http.post('/users/avatar', async ({ request }) => {
|
||||
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
|
||||
const body = await request.json() as { avatar: string };
|
||||
|
||||
if (token === 'mock-jwt-token-123') {
|
||||
mockUserData.avatar = body.avatar;
|
||||
// 模拟头像上传成功;
|
||||
return HttpResponse.json({
|
||||
code: 200,
|
||||
message: '头像上传成功',
|
||||
data: {
|
||||
avatar: mockUserData.avatar,
|
||||
},
|
||||
});
|
||||
}
|
||||
return HttpResponse.json({ code: 401, message: '未授权' }, { status: 401 });
|
||||
}),
|
||||
];
|
Loading…
Reference in new issue