diff --git a/lib/entitlements/backend/github_team/provider.rb b/lib/entitlements/backend/github_team/provider.rb index 2fe1813..f979c1f 100644 --- a/lib/entitlements/backend/github_team/provider.rb +++ b/lib/entitlements/backend/github_team/provider.rb @@ -198,6 +198,23 @@ def diff_existing_updated_metadata(existing_group, group, base_diff) Entitlements.logger.info "CHANGE github_parent_team from #{existing_parent_team} to #{changed_parent_team} for #{existing_group.dn} in #{github.org}" end end + + existing_maintainers = existing_group.metadata_fetch_if_exists("team_maintainers") + changed_maintainers = group.metadata_fetch_if_exists("team_maintainers") + if existing_maintainers != changed_maintainers + base_diff[:metadata] ||= {} + if existing_maintainers.nil? && !changed_maintainers.nil? + base_diff[:metadata][:team_maintainers] = "add" + Entitlements.logger.info "ADD github_team_maintainers #{changed_maintainers} to #{existing_group.dn} in #{github.org}" + elsif !existing_maintainers.nil? && changed_maintainers.nil? + base_diff[:metadata][:team_maintainers] = "remove" + Entitlements.logger.info "REMOVE (NOOP) github_team_maintainers #{existing_maintainers} from #{existing_group.dn} in #{github.org}" + else + base_diff[:metadata][:team_maintainers] = "change" + Entitlements.logger.info "CHANGE github_team_maintainers from #{existing_maintainers} to #{changed_maintainers} for #{existing_group.dn} in #{github.org}" + end + end + base_diff end diff --git a/lib/entitlements/backend/github_team/service.rb b/lib/entitlements/backend/github_team/service.rb index e65b581..05dbc29 100644 --- a/lib/entitlements/backend/github_team/service.rb +++ b/lib/entitlements/backend/github_team/service.rb @@ -104,6 +104,10 @@ def read_team(entitlement_group) end end + maintainers = teamdata[:members].select { |u| teamdata[:roles][u] == "maintainer" } + team_metadata = team_metadata || {} + team_metadata = team_metadata.merge({"team_maintainers" => maintainers.any? ? maintainers.join(",") : nil}) + team = Entitlements::Backend::GitHubTeam::Models::Team.new( team_id: teamdata[:team_id], team_name: team_identifier, @@ -326,11 +330,12 @@ def team_by_name(org_name:, team_name:) # team_slug - Identifier of the team to retrieve. # # Returns a data structure with team data. - Contract String => { members: C::ArrayOf[String], team_id: Integer, parent_team_name: C::Or[String, nil] } + Contract String => { members: C::ArrayOf[String], team_id: Integer, parent_team_name: C::Or[String, nil], roles: C::HashOf[String => String] } def graphql_team_data(team_slug) cursor = nil team_id = nil result = [] + roles = {} sanity_counter = 0 while sanity_counter < 100 @@ -348,6 +353,7 @@ def graphql_team_data(team_slug) node { login } + role cursor } } @@ -375,12 +381,17 @@ def graphql_team_data(team_slug) buffer = edges.map { |e| e.fetch("node").fetch("login").downcase } result.concat buffer + edges.each do |e| + role = e.fetch("role").downcase + roles[e.fetch("node").fetch("login").downcase] = role + end + cursor = edges.last.fetch("cursor") next if cursor && buffer.size == max_graphql_results break end - { members: result, team_id:, parent_team_name: } + { members: result, team_id:, parent_team_name:, roles: } end # Ensure that the given team ID actually matches up to the team slug on GitHub. This is in place diff --git a/spec/acceptance/github-server/web.rb b/spec/acceptance/github-server/web.rb index cdb3414..7273f3b 100644 --- a/spec/acceptance/github-server/web.rb +++ b/spec/acceptance/github-server/web.rb @@ -73,7 +73,7 @@ def graphql_team_query(query) cursor_flag = cursor.nil? members.each do |m| next if !cursor_flag && Base64.strict_encode64(m) != cursor - edges << { "node" => { "login" => m }, "cursor" => Base64.strict_encode64(m) } if cursor_flag + edges << { "node" => { "login" => m }, "role" => "MEMBER", "cursor" => Base64.strict_encode64(m) } if cursor_flag cursor_flag = true break if edges.size >= first end diff --git a/spec/acceptance/tests/01_basic_webserver_github_connectivity_spec.rb b/spec/acceptance/tests/01_basic_webserver_github_connectivity_spec.rb index 0db62e2..ac97c5f 100644 --- a/spec/acceptance/tests/01_basic_webserver_github_connectivity_spec.rb +++ b/spec/acceptance/tests/01_basic_webserver_github_connectivity_spec.rb @@ -51,6 +51,7 @@ node { login } + role cursor } }, @@ -78,13 +79,13 @@ "databaseId" => 6, "members" => { "edges" => [ - { "node" => { "login" => "cheetoh" }, "cursor" => "Y2hlZXRvaA==" }, - { "node" => { "login" => "khaomanee" }, "cursor" => "a2hhb21hbmVl" }, - { "node" => { "login" => "nebelung" }, "cursor" => "bmViZWx1bmc=" }, - { "node" => { "login" => "ojosazules" }, "cursor" => "b2pvc2F6dWxlcw==" } + { "node" => { "login" => "cheetoh" }, "role" => "MEMBER", "cursor" => "Y2hlZXRvaA==" }, + { "node" => { "login" => "khaomanee" }, "role" => "MEMBER", "cursor" => "a2hhb21hbmVl" }, + { "node" => { "login" => "nebelung" }, "role" => "MEMBER", "cursor" => "bmViZWx1bmc=" }, + { "node" => { "login" => "ojosazules" }, "role" => "MEMBER", "cursor" => "b2pvc2F6dWxlcw==" } ] }, - "parentTeam" => { "slug" => nil } + "parentTeam" => { "slug" => nil }, } } } diff --git a/spec/unit/entitlements/backend/github_team/provider_spec.rb b/spec/unit/entitlements/backend/github_team/provider_spec.rb index e887163..e271a99 100644 --- a/spec/unit/entitlements/backend/github_team/provider_spec.rb +++ b/spec/unit/entitlements/backend/github_team/provider_spec.rb @@ -140,7 +140,7 @@ expect(logger).to receive(:debug).with("Loaded cn=grumpy-cats,ou=kittensinc,ou=GitHub,dc=github,dc=fake (id=1001) with 3 member(s)") allow(subject).to receive(:github).and_return(github) - expect(github).to receive(:graphql_team_data).with(team_identifier).and_return(members: old_members, team_id: 1001, parent_team_name: nil) + expect(github).to receive(:graphql_team_data).with(team_identifier).and_return(members: old_members, team_id: 1001, parent_team_name: nil, roles: Hash[*old_members.collect { |u| [u, "member"] }.flatten]) expect(subject.diff(group)).to eq(empty_result) end @@ -153,7 +153,7 @@ cache[:predictive_state] = { by_dn: { team_dn => { members: old_members, metadata: nil } }, invalid: Set.new } allow(subject).to receive(:github).and_return(github) - expect(github).to receive(:graphql_team_data).with(team_identifier).and_return(members: old_members, team_id: 1001, parent_team_name: nil) + expect(github).to receive(:graphql_team_data).with(team_identifier).and_return(members: old_members, team_id: 1001, parent_team_name: nil, roles: Hash[*old_members.collect { |u| [u, "member"] }.flatten]) expect(subject.diff(group)).to eq(added: Set.new(%w[mainecoon]), removed: Set.new(%w[russianblue])) end @@ -360,6 +360,75 @@ metadata: { parent_team: "remove" } ) end + + it "diffs team maintainers change" do + entitlements_group = Entitlements::Models::Group.new( + dn: "cn=diff-cats,ou=Github,dc=github,dc=fake", + members: Set.new(%w[cuddles fluffy morris WHISKERS].map { |u| "uid=#{u},ou=People,dc=kittens,dc=net" }), + metadata: { "team_maintainers" => "cuddles" } + ) + + github_team = Entitlements::Backend::GitHubTeam::Models::Team.new( + team_id: 2222, + team_name: "diff-cats", + members: Set.new(%w[cuddles fluffy morris WHISKERS].map { |u| "uid=#{u},ou=People,dc=kittens,dc=net" }), + ou: "ou=kittensinc,ou=GitHub,dc=github,dc=fake", + metadata: { "team_maintainers" => "cuddles,fluffy" } + ) + + result = subject.diff_existing_updated(entitlements_group, github_team) + expect(result).to eq( + added: Set.new, + removed: Set.new, + metadata: { team_maintainers: "change" } + ) + end + + it "diffs team maintainers add" do + entitlements_group = Entitlements::Models::Group.new( + dn: "cn=diff-cats,ou=Github,dc=github,dc=fake", + members: Set.new(%w[cuddles fluffy morris WHISKERS].map { |u| "uid=#{u},ou=People,dc=kittens,dc=net" }), + metadata: { } + ) + + github_team = Entitlements::Backend::GitHubTeam::Models::Team.new( + team_id: 2222, + team_name: "diff-cats", + members: Set.new(%w[cuddles fluffy morris WHISKERS].map { |u| "uid=#{u},ou=People,dc=kittens,dc=net" }), + ou: "ou=kittensinc,ou=GitHub,dc=github,dc=fake", + metadata: { "team_maintainers" => "cuddles,fluffy" } + ) + + result = subject.diff_existing_updated(entitlements_group, github_team) + expect(result).to eq( + added: Set.new, + removed: Set.new, + metadata: { team_maintainers: "add" } + ) + end + + it "diffs team maintainers removal" do + entitlements_group = Entitlements::Models::Group.new( + dn: "cn=diff-cats,ou=Github,dc=github,dc=fake", + members: Set.new(%w[cuddles fluffy morris WHISKERS].map { |u| "uid=#{u},ou=People,dc=kittens,dc=net" }), + metadata: { "team_maintainers" => "cuddles,fluffy" } + ) + + github_team = Entitlements::Backend::GitHubTeam::Models::Team.new( + team_id: 2222, + team_name: "diff-cats", + members: Set.new(%w[cuddles fluffy morris WHISKERS].map { |u| "uid=#{u},ou=People,dc=kittens,dc=net" }), + ou: "ou=kittensinc,ou=GitHub,dc=github,dc=fake", + metadata: { } + ) + + result = subject.diff_existing_updated(entitlements_group, github_team) + expect(result).to eq( + added: Set.new, + removed: Set.new, + metadata: { team_maintainers: "remove" } + ) + end end describe "#create_github_team_group" do diff --git a/spec/unit/entitlements/backend/github_team/service_spec.rb b/spec/unit/entitlements/backend/github_team/service_spec.rb index dda0339..a74df40 100644 --- a/spec/unit/entitlements/backend/github_team/service_spec.rb +++ b/spec/unit/entitlements/backend/github_team/service_spec.rb @@ -79,7 +79,7 @@ graphql_response = '{"data":{"organization":{"team":null}}}' stub_request(:post, "https://github.fake/api/v3/graphql"). with( - body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"team-does-not-exist\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" + body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"team-does-not-exist\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\nrole\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" ).to_return(status: 200, body: graphql_response) expect(logger).to receive(:debug).with("Setting up GitHub API connection to https://github.fake/api/v3/") @@ -92,7 +92,7 @@ it "returns a Entitlements::Backend::GitHubTeam::Models::Team object when the team exists" do stub_request(:post, "https://github.fake/api/v3/graphql"). with( - body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"cuddly-kittens\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" + body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"cuddly-kittens\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\nrole\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" ).to_return(status: 200, body: graphql_response(cuddly_kittens, 0, 100)) expect(logger).to receive(:debug).with("Setting up GitHub API connection to https://github.fake/api/v3/") @@ -109,7 +109,7 @@ it "returns a Entitlements::Backend::GitHubTeam::Models::Team object with parent team when the team exists" do stub_request(:post, "https://github.fake/api/v3/graphql"). with( - body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"cuddly-kittens\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" + body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"cuddly-kittens\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\nrole\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" ).to_return(status: 200, body: graphql_response(cuddly_kittens, 0, 100, parent_team: "parent-cats")) expect(logger).to receive(:debug).with("Setting up GitHub API connection to https://github.fake/api/v3/") @@ -128,7 +128,7 @@ it "returns a Entitlements::Backend::GitHubTeam::Models::Team object with parent team when the team exists but has empty entitlement metadata" do stub_request(:post, "https://github.fake/api/v3/graphql"). with( - body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"cuddly-kittens\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" + body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"cuddly-kittens\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\nrole\\ncursor\\n}\\n}\\n}\\n}\\n}\"}" ).to_return(status: 200, body: graphql_response(cuddly_kittens_no_metadata, 0, 100, parent_team: "parent-cats")) expect(logger).to receive(:debug).with("Setting up GitHub API connection to https://github.fake/api/v3/") @@ -225,7 +225,7 @@ it "returns false" do cache[:predictive_state] = { by_dn: {}, invalid: Set.new } - expect(subject).to receive(:graphql_team_data).and_return(members: people.to_a, team_id: 1234567) + expect(subject).to receive(:graphql_team_data).and_return(members: people.to_a, team_id: 1234567, roles: Hash[*people.collect { |u| [u, "member"] }.flatten]) expect(logger).to receive(:debug).with("members(#{team_dn}): DN does not exist in cache") expect(logger).to receive(:debug).with("Loading GitHub team github.fake:kittensinc/cuddly-kittens") @@ -256,7 +256,7 @@ # Invalidating cache should force a re-read. people_2 = Set.new(people + %w[peterbald]) - expect(subject).to receive(:graphql_team_data).with(team_identifier).and_return(members: people_2.to_a, team_id: 1234567) + expect(subject).to receive(:graphql_team_data).with(team_identifier).and_return(members: people_2.to_a, team_id: 1234567, roles: Hash[*people_2.collect { |u| [u, "member"] }.flatten]) expect(logger).to receive(:debug).with("Invalidating cache entry for #{team_dn}") expect(logger).to receive(:debug).with("members(#{team_dn}): DN has been marked invalid in cache") expect(logger).to receive(:debug).with("Loading GitHub team github.fake:kittensinc/cuddly-kittens") @@ -632,24 +632,26 @@ context "team found, single page of results" do let(:graphql_dotcom_response) do <<-EOF -{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"highlander"},"cursor":"Y3Vyc29yOnYyOpHNNS0="},{"node":{"login":"blackmanx"},"cursor":"Y3Vyc29yOnYyOpHNTkI="},{"node":{"login":"toyger"},"cursor":"Y3Vyc29yOnYyOpHOAARtag=="},{"node":{"login":"ocicat"},"cursor":"Y3Vyc29yOnYyOpHOAAVi0w=="},{"node":{"login":"hubot"},"cursor":"Y3Vyc29yOnYyOpHOAAdWqg=="},{"node":{"login":"korat"},"cursor":"Y3Vyc29yOnYyOpHOABODaQ=="},{"node":{"login":"MAINECOON"},"cursor":"Y3Vyc29yOnYyOpHOAEIdJg=="},{"node":{"login":"russianblue"},"cursor":"Y3Vyc29yOnYyOpHOAEqWvg=="},{"node":{"login":"ragamuffin"},"cursor":"Y3Vyc29yOnYyOpHOAHgBJQ=="},{"node":{"login":"minskin"},"cursor":"Y3Vyc29yOnYyOpHOALafPw=="}]}}}}} +{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"highlander"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHNNS0="},{"node":{"login":"blackmanx"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHNTkI="},{"node":{"login":"toyger"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAARtag=="},{"node":{"login":"ocicat"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAAVi0w=="},{"node":{"login":"hubot"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAAdWqg=="},{"node":{"login":"korat"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOABODaQ=="},{"node":{"login":"MAINECOON"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAEIdJg=="},{"node":{"login":"russianblue"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAEqWvg=="},{"node":{"login":"ragamuffin"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAHgBJQ=="},{"node":{"login":"minskin"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOALafPw=="}]}}}}} EOF end it "parses team data from a single page of results" do stub_request(:post, "https://github.fake/api/v3/graphql"). with( - body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"grumpy-cat\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\ncursor\\n}\\n}\\n}\\n}\\n}\"}", + body: "{\"query\":\"{\\norganization(login: \\\"kittensinc\\\") {\\nteam(slug: \\\"grumpy-cat\\\") {\\ndatabaseId\\nparentTeam {\\nslug\\n}\\nmembers(first: 100, membership: IMMEDIATE) {\\nedges {\\nnode {\\nlogin\\n}\\nrole\\ncursor\\n}\\n}\\n}\\n}\\n}\"}", headers: { "Authorization" => "bearer GoPackGo", "Content-Type" => "application/json", }).to_return(status: 200, body: graphql_dotcom_response) result = subject.send(:graphql_team_data, "grumpy-cat") + members = ["highlander", "blackmanx", "toyger", "ocicat", "hubot", "korat", "mainecoon", "russianblue", "ragamuffin", "minskin"] expect(result).to eq( - members: ["highlander", "blackmanx", "toyger", "ocicat", "hubot", "korat", "mainecoon", "russianblue", "ragamuffin", "minskin"], + members:, team_id: 593721, - parent_team_name: nil + parent_team_name: nil, + roles: Hash[*members.collect { |member| [member, "member"] }.flatten], ) end end @@ -659,19 +661,19 @@ let(:graphql_dotcom_response_1) do <<-EOF -{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"highlander"},"cursor":"Y3Vyc29yOnYyOpHNNS0="},{"node":{"login":"blackmanx"},"cursor":"Y3Vyc29yOnYyOpHNTkI="},{"node":{"login":"toyger"},"cursor":"Y3Vyc29yOnYyOpHOAARtag=="},{"node":{"login":"ocicat"},"cursor":"Y3Vyc29yOnYyOpHOAAVi0w=="}]}}}}} +{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"highlander"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHNNS0="},{"node":{"login":"blackmanx"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHNTkI="},{"node":{"login":"toyger"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAARtag=="},{"node":{"login":"ocicat"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAAVi0w=="}]}}}}} EOF end let(:graphql_dotcom_response_2) do <<-EOF -{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"hubot"},"cursor":"Y3Vyc29yOnYyOpHOAAdWqg=="},{"node":{"login":"korat"},"cursor":"Y3Vyc29yOnYyOpHOABODaQ=="},{"node":{"login":"MAINECOON"},"cursor":"Y3Vyc29yOnYyOpHOAEIdJg=="},{"node":{"login":"russianblue"},"cursor":"Y3Vyc29yOnYyOpHOAEqWvg=="}]}}}}} +{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"hubot"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAAdWqg=="},{"node":{"login":"korat"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOABODaQ=="},{"node":{"login":"MAINECOON"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAEIdJg=="},{"node":{"login":"russianblue"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAEqWvg=="}]}}}}} EOF end let(:graphql_dotcom_response_3) do <<-EOF -{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"ragamuffin"},"cursor":"Y3Vyc29yOnYyOpHOAHgBJQ=="},{"node":{"login":"minskin"},"cursor":"Y3Vyc29yOnYyOpHOALafPw=="}]}}}}} +{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"ragamuffin"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAHgBJQ=="},{"node":{"login":"minskin"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOALafPw=="}]}}}}} EOF end @@ -684,10 +686,12 @@ ) result = subject.send(:graphql_team_data, "grumpy-cat") + members = ["highlander", "blackmanx", "toyger", "ocicat", "hubot", "korat", "mainecoon", "russianblue", "ragamuffin", "minskin"] expect(result).to eq( - members: ["highlander", "blackmanx", "toyger", "ocicat", "hubot", "korat", "mainecoon", "russianblue", "ragamuffin", "minskin"], + members:, team_id: 593721, - parent_team_name: nil + parent_team_name: nil, + roles: Hash[*members.collect { |member| [member, "member"] }.flatten], ) end end @@ -697,13 +701,13 @@ let(:graphql_dotcom_response_1) do <<-EOF -{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"highlander"},"cursor":"Y3Vyc29yOnYyOpHNNS0="},{"node":{"login":"blackmanx"},"cursor":"Y3Vyc29yOnYyOpHNTkI="},{"node":{"login":"toyger"},"cursor":"Y3Vyc29yOnYyOpHOAARtag=="},{"node":{"login":"ocicat"},"cursor":"Y3Vyc29yOnYyOpHOAAVi0w=="},{"node":{"login":"hubot"},"cursor":"Y3Vyc29yOnYyOpHOAAdWqg=="}]}}}}} +{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"highlander"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHNNS0="},{"node":{"login":"blackmanx"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHNTkI="},{"node":{"login":"toyger"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAARtag=="},{"node":{"login":"ocicat"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAAVi0w=="},{"node":{"login":"hubot"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAAdWqg=="}]}}}}} EOF end let(:graphql_dotcom_response_2) do <<-EOF -{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"korat"},"cursor":"Y3Vyc29yOnYyOpHOABODaQ=="},{"node":{"login":"MAINECOON"},"cursor":"Y3Vyc29yOnYyOpHOAEIdJg=="},{"node":{"login":"russianblue"},"cursor":"Y3Vyc29yOnYyOpHOAEqWvg=="},{"node":{"login":"ragamuffin"},"cursor":"Y3Vyc29yOnYyOpHOAHgBJQ=="},{"node":{"login":"minskin"},"cursor":"Y3Vyc29yOnYyOpHOALafPw=="}]}}}}} +{"data":{"organization":{"team":{"databaseId":593721,"members":{"edges":[{"node":{"login":"korat"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOABODaQ=="},{"node":{"login":"MAINECOON"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAEIdJg=="},{"node":{"login":"russianblue"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAEqWvg=="},{"node":{"login":"ragamuffin"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOAHgBJQ=="},{"node":{"login":"minskin"},"role":"MEMBER","cursor":"Y3Vyc29yOnYyOpHOALafPw=="}]}}}}} EOF end @@ -722,10 +726,12 @@ ) result = subject.send(:graphql_team_data, "grumpy-cat") + members = ["highlander", "blackmanx", "toyger", "ocicat", "hubot", "korat", "mainecoon", "russianblue", "ragamuffin", "minskin"] expect(result).to eq( - members: ["highlander", "blackmanx", "toyger", "ocicat", "hubot", "korat", "mainecoon", "russianblue", "ragamuffin", "minskin"], + members:, team_id: 593721, - parent_team_name: nil + parent_team_name: nil, + roles: Hash[*members.collect { |member| [member, "member"] }.flatten], ) end end diff --git a/spec/unit/spec_helper.rb b/spec/unit/spec_helper.rb index 1cfbc32..0ed31ab 100644 --- a/spec/unit/spec_helper.rb +++ b/spec/unit/spec_helper.rb @@ -46,7 +46,7 @@ def default_filters def graphql_response(team, slice_start, slice_length, parent_team: nil) team_id = rand(1..10000) edges = team.member_strings.sort.to_a.slice(slice_start, slice_length).map do |m| - { "node" => { "login" => m }, "cursor" => Base64.encode64(m) } + { "node" => { "login" => m }, "role" => "MEMBER", "cursor" => Base64.encode64(m) } end struct = { "data" => {