it('decrements loading count when requests fail', async () => { fetchMock.once('*', { body: { settings: {} }, }); fetchMock.once('*', { status: 400, body: 'invalid', }); const { uiSettingsApi } = setup(); const done$ = new Rx.Subject(); const promise = uiSettingsApi .getLoadingCount$() .pipe( takeUntil(done$), toArray() ) .toPromise(); await uiSettingsApi.batchSet('foo', 'bar'); await expect(uiSettingsApi.batchSet('foo', 'bar')).rejects.toThrowError(); done$.next(); await expect(promise).resolves.toEqual([0, 1, 0, 1, 0]); });
it('rejects all promises for batched requests that fail', async () => { fetchMock.once('*', { body: { settings: {} }, }); fetchMock.once('*', { status: 400, body: 'invalid', }); const { uiSettingsApi } = setup(); // trigger the initial sync request, which enabled buffering uiSettingsApi.batchSet('foo', 'bar'); // buffer some requests so they will be sent together await expect( Promise.all([ settlePromise(uiSettingsApi.batchSet('foo', 'a')), settlePromise(uiSettingsApi.batchSet('bar', 'b')), settlePromise(uiSettingsApi.batchSet('baz', 'c')), ]) ).resolves.toMatchSnapshot('promise rejections'); // ensure only two requests were sent expect(fetchMock.calls().matched).toHaveLength(2); });
test('Schema migration displaying data loss', async t => { // configure HTTP mocks fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPullProjectResponse1)) fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPushSchema1ResponseError)) // dummy migration data const projectFile = 'project.graphcool' const env = testEnvironment({}) env.resolver.write(projectFile, mockModifiedProjectFile1) env.resolver.write(graphcoolConfigFilePath, '{"token": ""}') const props = { force: true } env.out.prefix((t as any)._test.title, `$ graphcool push`) await t.notThrows( push(props, env) ) t.is(env.resolver.read(projectFile), mockModifiedProjectFile1) })
test('Succeeding schema migration using --force without specified project file (fallback to default)', async t => { // configure HTTP mocks fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPullProjectResponse1)) fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPushSchemaResponse)) // dummy migration data const env = testEnvironment({}) env.resolver.write(graphcoolProjectFileName, mockModifiedProjectFile1) env.resolver.write(graphcoolConfigFilePath, '{"token": ""}') const props = { force: true } env.out.prefix((t as any)._test.title, `$ graphcool push --force`) await t.notThrows( push(props, env) ) const expectedProjectFileContent = mockProjectFile3 const result = env.resolver.read(`./${graphcoolProjectFileName}`) t.is(result, expectedProjectFileContent) })
test('Failing schema migration because of multiple project files', async t => { // configure HTTP mocks fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPullProjectResponse1)) fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPushSchemaResponse)) // dummy migration data const projectFile1 = 'example.graphcool' const projectFile2 = 'project.graphcool' const env = testEnvironment({}) env.resolver.write(projectFile1, mockProjectFile2) env.resolver.write(projectFile2, mockProjectFile2) env.resolver.write(graphcoolConfigFilePath, '{"token": ""}') const props = { force: true } env.out.prefix((t as any)._test.title, `$ graphcool push`) await t.throws( push(props, env) ) t.is(env.resolver.read(projectFile1), mockProjectFile2) t.is(env.resolver.read(projectFile2), mockProjectFile2) })
test('Status with potential data loss', async t => { // configure HTTP mocks fetchMock.once(systemAPIEndpoint, JSON.parse(mockedPushSchemaResponseError)) // dummy migration data const projectFile = 'project.graphcool' const env = testEnvironment({}) env.resolver.write(projectFile, mockProjectFile2) env.resolver.write(graphcoolConfigFilePath, '{"token": ""}') const props = { } env.out.prefix((t as any)._test.title, `$ graphcool status`) await t.notThrows( statusCommand(props, env) ) t.is(env.resolver.read(projectFile), mockProjectFile2) })
it('emits the current number of active requests', async () => { fetchMock.once('*', { body: { settings: {} }, }); const { uiSettingsApi } = setup(); const done$ = new Rx.Subject(); const promise = uiSettingsApi .getLoadingCount$() .pipe( takeUntil(done$), toArray() ) .toPromise(); await uiSettingsApi.batchSet('foo', 'bar'); done$.next(); await expect(promise).resolves.toEqual([0, 1, 0]); });
it('completes any loading count observables', async () => { fetchMock.once('*', { body: { settings: {} }, }); const { uiSettingsApi } = setup(); const promise = Promise.all([ uiSettingsApi .getLoadingCount$() .pipe(toArray()) .toPromise(), uiSettingsApi .getLoadingCount$() .pipe(toArray()) .toPromise(), ]); const batchSetPromise = uiSettingsApi.batchSet('foo', 'bar'); uiSettingsApi.stop(); // both observables should emit the same values, and complete before the request is done loading await expect(promise).resolves.toEqual([[0, 1], [0, 1]]); await batchSetPromise; });
headers: { test: "header" } }); fetchMock.mock("http//test.com", 200, { query: { searchValue: "apples" } }); fetchMock.mock("http://test.com", 200, { repeat: 2 }); fetchMock.mock(/test\.com/, 200); fetchMock.mock(() => true, 200); fetchMock.mock((url, opts) => true, 200); fetchMock.once("http://test.com", 200); fetchMock.mock(/test/, "test").mock(/test/, { a: "b" }); fetchMock.mock(/test/, { status: 200, headers: { test: "test" }, body: { a: "b" } }); fetchMock.restore().reset(); (fetchMock.calls().matched[0][1] as RequestInit).body;