Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ignore_while_pending_spec.js « utils « lib « frontend « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b68ba936ddee45865a3b42ee6f6210946a2e105a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import waitForPromises from 'helpers/wait_for_promises';
import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';

const TEST_ARGS = [123, { foo: 'bar' }];

describe('~/lib/utils/ignore_while_pending', () => {
  let spyResolve;
  let spyReject;
  let spy;
  let subject;

  beforeEach(() => {
    spy = jest.fn().mockImplementation(
      // NOTE: We can't pass an arrow function here...
      function foo() {
        return new Promise((resolve, reject) => {
          spyResolve = resolve;
          spyReject = reject;
        });
      },
    );
  });

  describe('with non-instance method', () => {
    beforeEach(() => {
      subject = ignoreWhilePending(spy);
    });

    it('while pending, will ignore subsequent calls', () => {
      subject(...TEST_ARGS);
      subject();
      subject();
      subject();

      expect(spy).toHaveBeenCalledTimes(1);
      expect(spy).toHaveBeenCalledWith(...TEST_ARGS);
    });

    it.each`
      desc               | act
      ${'when resolved'} | ${() => spyResolve()}
      ${'when rejected'} | ${() => spyReject(new Error('foo'))}
    `('$desc, can be triggered again', async ({ act }) => {
      // We need the empty catch(), since we are testing rejecting the promise,
      // which would otherwise cause the test to fail.
      subject(...TEST_ARGS).catch(() => {});
      subject();
      subject();
      subject();

      act();
      // We need waitForPromises, so that the underlying finally() runs.
      await waitForPromises();

      subject({ again: 'foo' });

      expect(spy).toHaveBeenCalledTimes(2);
      expect(spy).toHaveBeenCalledWith(...TEST_ARGS);
      expect(spy).toHaveBeenCalledWith({ again: 'foo' });
    });

    it('while pending, returns empty resolutions for ignored calls', async () => {
      subject(...TEST_ARGS);

      await expect(subject(...TEST_ARGS)).resolves.toBeUndefined();
      await expect(subject(...TEST_ARGS)).resolves.toBeUndefined();
    });

    it('when resolved, returns resolution for origin call', async () => {
      const resolveValue = { original: 1 };
      const result = subject(...TEST_ARGS);

      spyResolve(resolveValue);

      await expect(result).resolves.toEqual(resolveValue);
    });

    it('when rejected, returns rejection for original call', async () => {
      const rejectedErr = new Error('original');
      const result = subject(...TEST_ARGS);

      spyReject(rejectedErr);

      await expect(result).rejects.toEqual(rejectedErr);
    });
  });

  describe('with instance method', () => {
    let instance1;
    let instance2;

    beforeEach(() => {
      // Let's capture the "this" for tests
      subject = ignoreWhilePending(function instanceMethod(...args) {
        return spy(this, ...args);
      });

      instance1 = {};
      instance2 = {};
    });

    it('will not ignore calls across instances', () => {
      subject.call(instance1, { context: 1 });
      subject.call(instance1, {});
      subject.call(instance1, {});
      subject.call(instance2, { context: 2 });
      subject.call(instance2, {});

      expect(spy.mock.calls).toEqual([
        [instance1, { context: 1 }],
        [instance2, { context: 2 }],
      ]);
    });

    it('resolving one instance does not resolve other instances', async () => {
      subject.call(instance1, { context: 1 });

      // We need to save off spyResolve so it's not overwritten by next call
      const instance1Resolve = spyResolve;

      subject.call(instance2, { context: 2 });

      instance1Resolve();
      await waitForPromises();

      subject.call(instance1, { context: 1 });
      subject.call(instance2, { context: 2 });

      expect(spy.mock.calls).toEqual([
        [instance1, { context: 1 }],
        [instance2, { context: 2 }],
        [instance1, { context: 1 }],
      ]);
    });
  });
});