public void Reset_scores_for_unmatched_cfs_if_enabled()
    {
        const string radarrQualityProfileData = @"[{
  'name': 'profile1',
  'formatItems': [{
      'format': 1,
      'name': 'cf1',
      'score': 1
    },
    {
      'format': 2,
      'name': 'cf2',
      'score': 50
    },
    {
      'format': 3,
      'name': 'cf3',
      'score': 3
    }
  ],
  'id': 1
}]";

        var api = Substitute.For <IQualityProfileService>();

        api.GetQualityProfiles() !.Returns(JsonConvert.DeserializeObject <List <JObject> >(radarrQualityProfileData));

        var cfScores = new Dictionary <string, QualityProfileCustomFormatScoreMapping>
        {
            {
                "profile1", CfTestUtils.NewMappingWithReset(
                    new FormatMappingEntry(new ProcessedCustomFormatData("", "", new JObject())
                {
                    CacheEntry = new TrashIdMapping("", "", 2)
                }, 100))
            }
        };

        var processor = new QualityProfileApiPersistenceStep();

        processor.Process(api, cfScores);

        processor.InvalidProfileNames.Should().BeEmpty();
        processor.UpdatedScores.Should()
        .ContainKey("profile1").WhoseValue.Should()
        .BeEquivalentTo(new List <UpdatedFormatScore>
        {
            new("cf1", 0, FormatScoreUpdateReason.Reset),
            new("cf2", 100, FormatScoreUpdateReason.Updated),
            new("cf3", 0, FormatScoreUpdateReason.Reset)
        });
    public void Do_not_invoke_api_if_no_scores_to_update()
    {
        const string radarrQualityProfileData = @"[{
  'name': 'profile1',
  'formatItems': [{
      'format': 1,
      'name': 'cf1',
      'score': 1
    },
    {
      'format': 2,
      'name': 'cf2',
      'score': 0
    },
    {
      'format': 3,
      'name': 'cf3',
      'score': 3
    }
  ],
  'id': 1
}]";

        var api = Substitute.For <IQualityProfileService>();

        api.GetQualityProfiles() !.Returns(JsonConvert.DeserializeObject <List <JObject> >(radarrQualityProfileData));

        var cfScores = new Dictionary <string, QualityProfileCustomFormatScoreMapping>
        {
            {
                "profile1", CfTestUtils.NewMapping(
                    new FormatMappingEntry(new ProcessedCustomFormatData("", "", new JObject())
                {
                    CacheEntry = new TrashIdMapping("", "")
                    {
                        CustomFormatId = 4
                    }
                }, 100))
            }
        };

        var processor = new QualityProfileApiPersistenceStep();

        processor.Process(api, cfScores);

        api.DidNotReceive().UpdateQualityProfile(Arg.Any <JObject>(), Arg.Any <int>());
    }
    public async Task Invalid_quality_profile_names_are_reported()
    {
        const string radarrQualityProfileData = @"[{'name': 'profile1'}]";

        var api = Substitute.For <IQualityProfileService>();

        api.GetQualityProfiles() !.Returns(JsonConvert.DeserializeObject <List <JObject> >(radarrQualityProfileData));

        var cfScores = new Dictionary <string, QualityProfileCustomFormatScoreMapping>
        {
            { "wrong_profile_name", CfTestUtils.NewMapping() }
        };

        var processor = new QualityProfileApiPersistenceStep();
        await processor.Process(api, cfScores);

        processor.InvalidProfileNames.Should().Equal("wrong_profile_name");
        processor.UpdatedScores.Should().BeEmpty();
    }