* Test utility for requests initiated by the Next.js Router, such as * prefetches and navigations. Calls the given async function then intercepts * any router requests that are initiated as a result. It will then wait for * all the requests to complete before exiting. Inspired by the React
(
scope: () => Promise<T> | T,
config?: ActConfig
)
| 125 | * `act` API. |
| 126 | */ |
| 127 | async function act<T>( |
| 128 | scope: () => Promise<T> | T, |
| 129 | config?: ActConfig |
| 130 | ): Promise<T> { |
| 131 | // Capture a stack trace for better async error messages. |
| 132 | const error = new Error() |
| 133 | if (Error.captureStackTrace) { |
| 134 | Error.captureStackTrace(error, act) |
| 135 | } |
| 136 | |
| 137 | let expectedResponses: Array<ExpectedResponseConfig> | null |
| 138 | let forbiddenResponses: Array<ExpectedResponseConfig> | null = null |
| 139 | let shouldBlockAll = false |
| 140 | const allowStatuses = options?.allowErrorStatusCodes ?? null |
| 141 | |
| 142 | if (config === undefined || config === null) { |
| 143 | // Default. Expect at least one request, but don't assert on the response. |
| 144 | expectedResponses = [] |
| 145 | } else if (config === 'block') { |
| 146 | // Expect at least one request, and block them all from being fulfilled. |
| 147 | if (currentBatch === null) { |
| 148 | error.message = |
| 149 | '`block` option only supported when nested inside an outer ' + |
| 150 | '`act` scope.' |
| 151 | throw error |
| 152 | } |
| 153 | expectedResponses = [] |
| 154 | shouldBlockAll = true |
| 155 | } else if (config === 'no-requests') { |
| 156 | // Expect no requests to be initiated. |
| 157 | expectedResponses = null |
| 158 | } else if (!Array.isArray(config)) { |
| 159 | // Shortcut for a single expected response. |
| 160 | if (config.block === true && currentBatch === null) { |
| 161 | error.message = |
| 162 | '`block: true` option only supported when nested inside an outer ' + |
| 163 | '`act` scope.' |
| 164 | throw error |
| 165 | } |
| 166 | if (config.block !== 'reject') { |
| 167 | expectedResponses = [config] |
| 168 | } else { |
| 169 | expectedResponses = [] |
| 170 | forbiddenResponses = [config] |
| 171 | } |
| 172 | } else { |
| 173 | expectedResponses = [] |
| 174 | for (const item of config) { |
| 175 | if (item.block === true && currentBatch === null) { |
| 176 | error.message = |
| 177 | '`block: true` option only supported when nested inside an outer ' + |
| 178 | '`act` scope.' |
| 179 | throw error |
| 180 | } |
| 181 | if (item.block !== 'reject') { |
| 182 | expectedResponses.push(item) |
| 183 | } else { |
| 184 | if (forbiddenResponses === null) { |