1import { ExportedConfig, Mod } from '../../Plugin.types';
2import { evalModsAsync } from '../mod-compiler';
3import { withBaseMod, withMod } from '../withMod';
4
5describe(withMod, () => {
6  it('compiles mods', async () => {
7    // A basic plugin exported from an app.json
8    const exportedConfig: ExportedConfig = { name: 'app', slug: '', mods: null };
9
10    const action: Mod<any> = jest.fn((props) => {
11      // Capitalize app name
12      props.name = (props.name as string).toUpperCase();
13      return props;
14    });
15    // Apply mod
16    let config = withBaseMod<any>(exportedConfig, {
17      platform: 'android',
18      mod: 'custom',
19      isProvider: true,
20      action,
21    });
22
23    // Compile plugins generically
24    config = await evalModsAsync(config, { projectRoot: '/' });
25
26    // Plugins should all be functions
27    expect(Object.values(config.mods.android).every((value) => typeof value === 'function')).toBe(
28      true
29    );
30
31    delete config.mods;
32
33    // App config should have been modified
34    expect(config).toStrictEqual({
35      name: 'APP',
36      slug: '',
37    });
38
39    expect(action).toBeCalledWith(config);
40  });
41  it('asserts multiple providers added', async () => {
42    // Apply a provider mod.
43    const config = withBaseMod<any>(
44      { name: 'app', slug: '', mods: null },
45      {
46        platform: 'android',
47        mod: 'custom',
48        isProvider: true,
49        action(props) {
50          // Capitalize app name
51          props.name = (props.name as string).toUpperCase();
52          return props;
53        },
54      }
55    );
56
57    expect(() =>
58      withBaseMod<any>(config, {
59        platform: 'android',
60        mod: 'custom',
61        isProvider: true,
62        action(props) {
63          // Capitalize app name
64          props.name = (props.name as string).toUpperCase();
65          return props;
66        },
67      })
68    ).toThrow(
69      'Cannot set provider mod for "android.custom" because another is already being used.'
70    );
71  });
72  it('throws when attempting to add a mod as the parent of a provider', async () => {
73    // Apply a provider mod.
74    const config = withBaseMod<any>(
75      { name: 'app', slug: '' },
76      {
77        platform: 'android',
78        mod: 'custom',
79        isProvider: true,
80        action(props) {
81          // Capitalize app name
82          props.name = (props.name as string).toUpperCase();
83          return props;
84        },
85      }
86    );
87
88    expect(() =>
89      withMod<any>(config, {
90        platform: 'android',
91        mod: 'custom',
92        action(props) {
93          // Capitalize app name
94          props.name = (props.name as string).toUpperCase();
95          return props;
96        },
97      })
98    ).toThrow(
99      'Cannot add mod to "android.custom" because the provider has already been added. Provider must be the last mod added.'
100    );
101  });
102});
103