Beispiel #1
0
        public async Task <Build> Save(AppDbContext dbContext, bool clearCache = true)
        {
            if (_owner == null && _ownerBuilder == null)
            {
                throw new Exception("Must set owner.");
            }
            if (_payload == null && _payloadBuilder == null)
            {
                throw new Exception("Must set payload.");
            }

            _owner ??= await _ownerBuilder !.Save(dbContext, clearCache: false);
            _payload ??= await _payloadBuilder !.Save(dbContext, clearCache: false);

            var request = new BuildService.CreateRequest(
                _owner.UserName,
                "simple-book",
                "Simple Blueprint Book",
                null,
                _tags,
                (_payload.Hash, null, null, Enumerable.Empty <GameIcon>()),
                null);

            var service = new BuildService(new NullLogger <BuildService>(), dbContext, TestUtils.Tags.Value);
            var result  = await service.CreateOrAddVersion(request, new NullTempCoverHandle(), _owner.ToClaimsPrincipal());

            result.Should().BeOfType <BuildService.CreateResult.Success>();

            if (clearCache)
            {
                dbContext.ClearCache();
            }

            return(((BuildService.CreateResult.Success)result).Build);
        }
Beispiel #2
0
        public async Task <IActionResult> CreateBuild([FromForm, Required] CreateBuildRequest request)
        {
            using var cover = await SaveTempCover(request.Cover);

            var result = await _buildService.CreateOrAddVersion(new BuildService.CreateRequest(
                                                                    User.GetUserName(),
                                                                    request.Slug,
                                                                    request.Title,
                                                                    request.Description,
                                                                    request.Tags,
                                                                    (request.Hash, request.Version.Name, request.Version.Description, request.Version.Icons),
                                                                    null),
                                                                cover, User);

            return(result switch
            {
                BuildService.CreateResult.Success success => Created(Url.ActionLink(nameof(GetDetails), "Build", new
                {
                    owner = success.Build.OwnerSlug,
                    slug = success.Build.Slug,
                }), success.Build.ToThinViewModel(Url)),
                BuildService.CreateResult.DuplicateHash error => Conflict(error.ToProblem()),
                BuildService.CreateResult.DuplicateSlug error => Conflict(error.ToProblem()),
                { } error => BadRequest(error.ToProblem()),
            });
        public async Task CreateOrAddVersion_ShouldSaveBlueprintGraph_WhenAddingANewBlueprint()
        {
            var owner   = await new UserBuilder().Save(_dbContext);
            var payload = await new PayloadBuilder().WithEncoded(TestData.SimpleBookEncoded).Save(_dbContext);
            var request = new BuildService.CreateRequest(
                owner.UserName,
                "test-1",
                "test blueprint 1",
                "the description",
                new[] { "/belt/balancer", "/state/early game" },
                (payload.Hash, null, null, Enumerable.Empty <GameIcon>()),
                null);

            var result = await _service.CreateOrAddVersion(request, new NullTempCoverHandle(), owner.ToClaimsPrincipal());

            result.Should().BeOfType <BuildService.CreateResult.Success>();

            _dbContext.Builds.Should().HaveCount(1);
            _dbContext.Payloads.Should().HaveCount(1);
            _dbContext.Versions.Should().HaveCount(1);

            var build = ((BuildService.CreateResult.Success)result).Build;

            build.Slug.Should().Be("test-1");
            build.Title.Should().Be("test blueprint 1");
            build.Description.Should().Be("the description");
            build.CreatedAt.ToDateTimeUtc().Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2));
            build.UpdatedAt.Should().Be(build.CreatedAt);
            build.Tags !.Should().BeEquivalentTo("/belt/balancer", "/state/early game");
        }
        public async Task CreateOrAddVersion_ShouldUpdateBlueprintMetadata_WhenAddingAVersion()
        {
            var owner           = await new UserBuilder().Save(_dbContext);
            var payload         = await new PayloadBuilder().WithEncoded(TestData.SimpleBookEncoded).Save(_dbContext);
            var existingPayload = await new PayloadBuilder().WithEncoded(TestData.SimpleBlueprintEncoded).Save(_dbContext);
            var existing        = await new BuildBuilder().WithPayload(existingPayload).WithOwner(owner).Save(_dbContext);

            var request = new BuildService.CreateRequest(
                owner.UserName,
                existing.Slug,
                "different title",
                "different description",
                new[] { "/belt/balancer", "/state/mid game", "/production/smelting" },
                (payload.Hash, null, null, Enumerable.Empty <GameIcon>()),
                existing.LatestVersionId);

            var result = await _service.CreateOrAddVersion(request, new NullTempCoverHandle(), owner.ToClaimsPrincipal());

            result.Should().BeOfType <BuildService.CreateResult.Success>();

            _dbContext.Builds.Should().HaveCount(1);
            _dbContext.Payloads.Should().HaveCount(2);
            _dbContext.Versions.Should().HaveCount(2);

            var build = ((BuildService.CreateResult.Success)result).Build;

            build.Slug.Should().Be(existing.Slug);
            build.Title.Should().Be("different title");
            build.Description.Should().Be("different description");
            build.UpdatedAt.ToDateTimeUtc().Should().BeAfter(existing.UpdatedAt.ToDateTimeUtc());
            build.Tags !.Should().BeEquivalentTo("/belt/balancer", "/state/mid game", "/production/smelting");
        }
Beispiel #5
0
        private async Task SeedBuilds(IReadOnlyCollection <SeedBlueprint> blueprints)
        {
            _logger.LogInformation("Seeding {TotalCount} builds", blueprints.Count);
            var createdCount = 0;
            var skippedCount = 0;
            var errorCount   = 0;

            foreach (var blueprint in blueprints)
            {
                var slug     = blueprint.Title.ToSlug();
                var username = blueprint.Owner.ToSlug();

                var existing = await _dbContext.Builds.FirstOrDefaultAsync(bp => bp.OwnerSlug == username && bp.Slug == slug);

                if (existing != null)
                {
                    skippedCount++;
                    _logger.LogInformation("Blueprint {Title} by {Owner} already exists", blueprint.Title, blueprint.Owner);
                    continue;
                }

                var owner = await _dbContext.Users.FirstOrDefaultAsync(u => u.UserName == username);

                if (owner == null)
                {
                    var email = Guid.NewGuid() + "@test.local.factorio.tech";

                    _logger.LogInformation("Creating user {DisplayName} / {UserName} / {Email}",
                                           blueprint.Owner, username, email);

                    owner = new User
                    {
                        DisplayName        = blueprint.Owner,
                        UserName           = username,
                        NormalizedUserName = username.ToUpperInvariant(),
                        Email           = email,
                        NormalizedEmail = email.ToUpperInvariant(),
                        EmailConfirmed  = true,
                        RegisteredAt    = SystemClock.Instance.GetCurrentInstant(),
                    };

                    _dbContext.Add(owner);
                    await _dbContext.SaveChangesAsync();
                }

                var envelope = await _blueprintConverter.Decode(blueprint.Encoded);

                var payload = new Payload(
                    Hash.Compute(blueprint.Encoded),
                    _blueprintConverter.ParseType(envelope.Entity.Item),
                    _blueprintConverter.DecodeGameVersion(envelope.Entity.Version),
                    blueprint.Encoded);

                var cache = new PayloadCache();
                cache.TryAdd(envelope, payload);

                await cache.EnsureInitializedGraph(envelope);

                await _buildService.SavePayloadGraph(payload.Hash, cache.Values);

                var tags = blueprint.Tags
                           .Select(t => t.TrimEnd('/'))
                           .Where(_buildTags.Contains)
                           .ToArray();

                var request = new BuildService.CreateRequest(
                    username,
                    slug,
                    blueprint.Title,
                    blueprint.Description,
                    tags.Any() ? tags : GetSomeRandomTags(),
                    (payload.Hash, null, null, envelope.Entity.Icons.ToGameIcons()),
                    null);

                var principal = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
                {
                    new(ClaimTypes.NameIdentifier, owner.Id.ToString()),
                }));